Class#newInstance in GWT - gwt

I know that GWT doesn't emulate this method, but I need smth that provide its functionality.
I have tried next approach:
private static <T extends Widget> T createWidget(Class<T> widgetClass) {
return GWT.create(widgetClass);
}
But when I try to compile it I get an error:
Only class literals may be used as arguments to GWT.create()
So, how can I write a foresaid method that will emulate Class#newInstance?

GWT.create() always needs the class literal as argument, which means that you has to pass this: GWT.create(MyClass.class) and no other thing.
This is so because the gwt compiler has to decide which class to pick up in compile time, note that in your code the class is passed in runtime.
If you are planing to use GWT.create for a reduced and well known set of classes you can do something like that:
private static <T extends Widget> T createWidget(Class<T> widgetClass) {
if (ClassA.class.equals(widgetClass)) {
return GWT.create(ClassA.class);
} else if (ClassA.class.equals(widgetClass)) {
return GWT.create(ClassB.class);
}
return null;
}

Related

How to define a class that is exactly the same as another class in Dart/Flutter

I'm defining some custom Exceptions in Dart.
I want in my logic to check the type of exception and base my processing on that, so I want to create distinct classes for each, for example like this :
class FailedToLoadCriticalDataException implements Exception { } // app cannot continue
class FailedToLoadNonCriticalDataException implements Exception { } // app can continue
However I also want to pass 2 parameters when I create these types of exceptions, the type of API call, and the API url, and the definition for that would look like this :
class UrlCallFailedException implements Exception {
String _dataTypeName;
String _urlEndpoint;
UrlCallFailedException([this._dataTypeName, this._urlEndpoint]);
#override
String toString() {
return "(${this.runtimeType.toString()}) Failed to fetch $_dataTypeName ($_urlEndpoint)";
}
}
Now what I want to do is (replace the initial definitions I made earlier and re)define my FailedToLoadCriticalDataException and FailedToLoadNonCriticalDataException classes so that they are exactly the code that is in the UrlCallFailedException class.
Is there any way to simply say something like class FailedToLoadCriticalDataException **is** UrlCallFailedException; and not need to duplicate the code that defines UrlCallFailedException ?
class FailedToLoadCriticalDataException implements UrlCallFailedException{ } is wrong because it is "Missing concrete implementations of 'getter UrlCallFailedException._dataTypeName',.."
class FailedToLoadCriticalDataException extends UrlCallFailedException{ } is wrong because when I got to throw FailedToLoadNonCriticalDataException("Foo", url); it's expectation is that there are no params ("Too many positional arguments: 0 expected, but 2 found.").
Is there a way to create multiple classes that behave exactly the same as another type and differ only in their class, without duplicating all the code ?
I've come up with this as a decent compromise :
class FailedToLoadCriticalDataException extends UrlCallFailedException {
FailedToLoadCriticalDataException([dataTypeName, urlEndpoint]) {
super._dataTypeName = dataTypeName;
super._urlEndpoint = urlEndpoint;
}
}
class FailedToLoadNonCriticalDataException extends UrlCallFailedException {
FailedToLoadNonCriticalDataException([dataTypeName, urlEndpoint]) {
super._dataTypeName = dataTypeName;
super._urlEndpoint = urlEndpoint;
}
}
Some, but minimal, code duplication, and I can now call throw FailedToLoadNonCriticalDataException("Foo", url); in my code later.

How to set a custom property for conditional import in Dart?

Dart allows to use the standard library names for conditional import/export, like this:
export 'src/hw_none.dart' // Stub implementation
if (dart.library.io) 'src/hw_io.dart' // dart:io implementation
if (dart.library.html) 'src/hw_html.dart'; // dart:html implementation
Is it possible to define a custom property/condition? For example, pass it when compiling.
I have a project that I would like to split into two variants: Flutter variant and pure Dart variant. The choice of the variant depends at compile time, and the necessary implements of abstract classes defines at compile time.
Custom properties where an experimental feature in Dart 1. With Dart 2 there is no longer any support for user defined custom conditions in compile time.
Here is the discussion referencing your question.
All you can do is, switch between implementations on run time:
abstract class SomeFactory {
String get message;
factory SomeFactory() {
if(Platform.environment['SOME_VAR'] != null)
return new _SomeImplementation();
return new _SomeOtherImplementation();
}
}
class _SomeImplementation implements SomeFactory {
#override
String get message => 'SomeImplementation';
}
class _SomeOtherImplementation implements SomeFactory {
#override
String get message => "OtherImplementation";
}
Check this blog entry for more details.

How can an abstract implement an interface?

I have a common interface that describes access to the output stream like this:
interface IOutput {
function writeInteger(aValue:Int):Void;
}
And I have an abstract implementation of this interface based on standard haxe.io.BytesOutput class:
abstract COutput(BytesOutput) from BytesOutput {
public inline function new(aData:BytesOutput) {
this = aData;
}
public inline function writeInteger(aValue:Int):Void {
this.writeInt32(aValue);
}
}
Though this abstract is truly implementing interface described above there's no direct reference to interface and when I'm trying to use it like this:
class Main {
public static function out(aOutput:IOutput) {
aOutput.writeInteger(0);
}
public static function main() {
var output:COutput = new BytesOutput();
out(output); // type error
}
}
Compiler throws an error: COutput should be IOutput. I can solve this problem only through using common class that wraps BytesOutput and implements IOutput.
My question is how to show the Haxe compiler that the abstract implements the interface.
Abstracts can't implement interfaces because they're a compile-time feature and don't exist at runtime. This conflicts with interfaces, they do exist at runtime and dynamic runtime checks like Std.is(something, IOutput) have to work.
Haxe also has a mechanism called structural subtyping that can be used as an alternative to interfaces. With this approach, there's no need for an explicit implements declaration, it's good enough if something unifies with a structure:
typedef IOutput = {
function writeInteger(aValue:Int):Void;
}
Unfortunately, abstracts aren't compatible with structural subtyping either due to the way they're implemented.
Have you considered using static extensions instead? At least for your simple example, that seems like the perfect solution for making a writeInteger() method available for any haxe.io.Output:
import haxe.io.Output;
import haxe.io.BytesOutput;
using Main.OutputExtensions;
class Main {
static function main() {
var output = new BytesOutput();
output.writeInteger(0);
}
}
class OutputExtensions {
public static function writeInteger(output:Output, value:Int):Void {
output.writeInt32(value);
}
}
You could even combine this with structural subtyping so writeInteger() becomes available on anything that has a writeInt32() method (try.haxe link):
typedef Int32Writable = {
function writeInt32(value:Int):Void;
}
As #Gama11 states, abstracts cannot implement interfaces. In Haxe, for type to implement an interface, it must be able to be compiled to something class-like that can be called using the interface’s methods without any magic happening. That is, to use a type as its interface, there needs to be a “real” class implementing that type. Abstracts in Haxe compile down to their base type—the abstract itself is entirely invisible after compilation happens. Thus, at runtime, there is no instance of a class with the methods defined in your abstract which implement the interface.
However, you can make your abstract appear to implement an interface by defining an implicit conversion to the interface you are trying to implement. For your example, the following might work:
interface IOutput {
function writeInteger(aValue:Int):Void;
}
abstract COutput(BytesOutput) from BytesOutput {
public inline function new(aData:BytesOutput) {
this = aData;
}
#:to()
public inline function toIOutput():IOutput {
return new COutputWrapper((cast this : COutput));
}
public inline function writeInteger(aValue:Int):Void {
this.writeInt32(aValue);
}
}
class COutputWrapper implements IOutput {
var cOutput(default, null):COutput;
public function new(cOutput) {
this.cOutput = cOutput;
}
public function writeInteger(aValue:Int) {
cOutput.writeInteger(aValue);
}
}
class Main {
public static function out(aOutput:IOutput) {
aOutput.writeInteger(0);
}
public static function main() {
var output:COutput = new BytesOutput();
out(output);
out(output);
}
}
Run on try.haxe.org
Note that, each time an implicit conversion happens, a new instance of the wrapper will be constructed. This may have performance implications. If you only access your value through its interface, consider setting the type of your variable to the interface rather than the abstract.
This is similar to “boxing” a primitive/value type in C#. In C#, value types, defined using the struct keyword, are allowed to implement interfaces. Like an abstract in Haxe, a value type in C# is compiled (by the JITter) into untyped code which simply directly accesses and manipulates the value for certain operations. However, C# allows structs to implement interfaces. The C# compiler will translate any attempt to implicitly cast a struct to an implemented interface into the construction of a wrapper class which stores a copy of the value and implements the interface—similar to our manually authored wrapper class (this wrapper class is actually generated by the runtime as part of JITing and is performed by the IL box instruction. See M() in this example). It is conceivable that Haxe could add a feature to automatically generate such a wrapper class for you like C# does for struct types, but that is not currently a feature. You may, however, do it yourself, as exemplified above.

Xtext: JvmModelInferrer initialize field

I'd like to generate a List field into my class generated from my DSL and initialize it like this:
private List<MyObject> myObjects= Lists.newArrayList();
The only way I know for this, is to append some text to the initializer:
members += appRule.toField("myObjects", appRule.newTypeRef(List, it.newTypeRef(MyObject))) [
initializer = [append('''Lists.newArrayList()''')]
]
However, using this approach the JvmModelInferrer won't import the Guava Strings library, thus will raise compilation issues. Is there any way to overcome this obstacle?
If I understand your issue (as you are referring to the Guava Strings library that is not used in the code :) ), your problem is, that the class reference Lists is not imported.
For such constructs, we have a helper method in EMF-IncQuery that serializes a type reference the same way parameters are serialized. This functionality relies on the injectable TypeReferenceSerializer class.
def referClass(ITreeAppendable appendable, EObject ctx, Class<?> clazz, JvmTypeReference... typeArgs) {
val ref = ctx.newTypeRef(clazz, typeArgs)
if (ref != null) {
appendable.serialize(ref, ctx)
} else {
//Class resolution error - error handling required here
//A fallback to writing out the fqn of the class
appendable.append(clazz.canonicalName)
}
}
def serialize(ITreeAppendable appendable, JvmTypeReference ref, EObject ctx) {
typeReferenceSerializer.serialize(ref, ctx, appendable)
}

Is it possible to find all classes annotated with #MyAnnotation using a GWT GeneratorContext?

While creating classes using Generators, it's possible to discover all subclasses of a type. You can find this technique for example in the GWT Showcase source (see full code):
JClassType cwType = null;
try {
cwType = context.getTypeOracle().getType(ContentWidget.class.getName());
} catch (NotFoundException e) {
logger.log(TreeLogger.ERROR, "Cannot find ContentWidget class", e);
throw new UnableToCompleteException();
}
JClassType[] types = cwType.getSubtypes();
I would like to do something similar, but instead of extending a class (or implementing an interface)
public class SomeWidget extends ContentWidget { ... }
, could I also do this by annotating Widgets?
#MyAnnotation(...)
public class SomeWidget extends Widget { ... }
And then finding all Widgets that are annotated with #MyAnnotation? I couldn't find a method like JAnnotationType.getAnnotatedTypes(), but maybe I'm just blind?
Note: I was able to make it work with the Google Reflections library, using reflections.getTypesAnnotatedWith(SomeAnnotation.class), but I'd prefer using the GeneratorContext instead, especially because this works a lot better when reloading the app in DevMode.
Yes - easiest way is to iterate through all types, and check them for the annotation. You might have other rules too (is public, is non-abstract) that should also be done at that time.
for (JClassType type : oracle.getTypes()) {
MyAnnotation annotation = type.getAnnotation(MyAnnotation.class);
if (annotation != null && ...) {
// handle this type
}
}
The TypeOracle instance can be obtained from the GeneratorContext using context.getTypeOracle().
Note that this will only give you access to types on the source path. That is, only types currently available based on the modules being inherited and <source> tags in use.