Add async support in Class.newInstance()
This commit is contained in:
Alexey Andreev 2015-02-24 15:51:27 +04:00
parent 7a573efde1
commit 4908293e50
3 changed files with 65 additions and 17 deletions

View File

@ -1955,8 +1955,10 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
private Injector getInjector(MethodReference ref) { private Injector getInjector(MethodReference ref) {
InjectorHolder holder = injectorMap.get(ref); InjectorHolder holder = injectorMap.get(ref);
if (holder == null) { if (holder == null) {
MethodHolder method = classSource.get(ref.getClassName()).getMethod(ref.getDescriptor());
holder = new InjectorHolder(null); holder = new InjectorHolder(null);
ClassHolder cls = classSource.get(ref.getClassName());
if (cls != null) {
MethodHolder method = cls.getMethod(ref.getDescriptor());
if (method != null) { if (method != null) {
AnnotationHolder injectedByAnnot = method.getAnnotations().get(InjectedBy.class.getName()); AnnotationHolder injectedByAnnot = method.getAnnotations().get(InjectedBy.class.getName());
if (injectedByAnnot != null) { if (injectedByAnnot != null) {
@ -1964,6 +1966,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
holder = new InjectorHolder(instantiateInjector(((ValueType.Object)type).getClassName())); holder = new InjectorHolder(instantiateInjector(((ValueType.Object)type).getClassName()));
} }
} }
}
injectorMap.put(ref, holder); injectorMap.put(ref, holder);
} }
return holder.injector; return holder.injector;

View File

@ -47,13 +47,14 @@ public class NewInstanceDependencySupport implements DependencyListener {
} }
@Override @Override
public void methodAchieved(final DependencyAgent agent, MethodDependency method, final CallLocation location) { public void methodAchieved(final DependencyAgent agent, MethodDependency method, CallLocation location) {
MethodReader reader = method.getMethod(); MethodReader reader = method.getMethod();
if (reader.getOwnerName().equals(Platform.class.getName()) && reader.getName().equals("newInstance")) { if (reader.getOwnerName().equals(Platform.class.getName()) && reader.getName().equals("newInstance")) {
allClassesNode.connect(method.getResult()); allClassesNode.connect(method.getResult());
final MethodReference methodRef = reader.getReference();
method.getResult().addConsumer(new DependencyConsumer() { method.getResult().addConsumer(new DependencyConsumer() {
@Override public void consume(DependencyAgentType type) { @Override public void consume(DependencyAgentType type) {
attachConstructor(agent, type.getName(), location); attachConstructor(agent, type.getName(), new CallLocation(methodRef));
} }
}); });
} }

View File

@ -91,24 +91,68 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
private void generateNewInstance(GeneratorContext context, SourceWriter writer, MethodReference methodRef) private void generateNewInstance(GeneratorContext context, SourceWriter writer, MethodReference methodRef)
throws IOException { throws IOException {
writer.append("var c").ws().append("=").ws().append("'$$constructor$$';").softNewLine(); writer.append("var c").ws().append("=").ws().append("'$$constructor$$';").softNewLine();
if (context.isAsync()) {
writer.append("function async(cls, init) {").indent().softNewLine();
writer.append("return function($return) {").indent().softNewLine();
writer.append("var r = new cls;").softNewLine();
writer.append("init(r, $rt_guardAsync(function($restore) {").indent().softNewLine();
writer.append("$restore();").softNewLine();
writer.append("$return($rt_asyncResult(r))").softNewLine();
writer.outdent().append("}));").softNewLine();
writer.outdent().append("};").softNewLine();
writer.outdent().append("}").softNewLine();
writer.append("function sync(cls, init) {").indent().softNewLine();
writer.append("return function($return) {").indent().softNewLine();
writer.append("var r = new cls;").softNewLine();
writer.append("try {").indent().softNewLine();
writer.append("init(r);").softNewLine();
writer.append("$return($rt_asyncResult(r));").softNewLine();
writer.outdent().append("} catch (e) {").indent().softNewLine();
writer.append("$return($rt_asyncError(e));").softNewLine();
writer.outdent().append("}").softNewLine();
writer.outdent().append("};").softNewLine();
writer.outdent().append("}").softNewLine();
}
for (String clsName : context.getClassSource().getClassNames()) { for (String clsName : context.getClassSource().getClassNames()) {
ClassReader cls = context.getClassSource().get(clsName); ClassReader cls = context.getClassSource().get(clsName);
MethodReader method = cls.getMethod(new MethodDescriptor("<init>", void.class)); MethodReader method = cls.getMethod(new MethodDescriptor("<init>", void.class));
if (method != null) { if (method != null) {
writer.appendClass(clsName).append("[c]").ws().append("=").ws() writer.appendClass(clsName).append("[c]").ws().append("=").ws();
.append(writer.getNaming().getNameForInit(method.getReference())) if (!context.isAsync()) {
.append(";").softNewLine(); writer.append(writer.getNaming().getNameForInit(method.getReference()));
} else {
String function = context.isAsync(method.getReference()) ? "async" : "sync";
writer.append(function).append("(").appendClass(clsName).append(',').ws()
.appendMethodBody(method.getReference()).append(")");
}
writer.append(";").softNewLine();
} }
} }
writer.appendMethodBody(methodRef).ws().append("=").ws().append("function(cls)").ws().append("{") writer.appendMethodBody(methodRef).ws().append("=").ws().append("function(cls");
.softNewLine().indent(); if (context.isAsync()) {
writer.append(',').ws().append("$return");
}
writer.append(")").ws().append("{").softNewLine().indent();
writer.append("if").ws().append("(!cls.hasOwnProperty(c))").ws().append("{").indent().softNewLine(); writer.append("if").ws().append("(!cls.hasOwnProperty(c))").ws().append("{").indent().softNewLine();
if (!context.isAsync()) {
writer.append("return null;").softNewLine(); writer.append("return null;").softNewLine();
} else {
writer.append("return $return($rt_asyncResult(null));").softNewLine();
}
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();
if (!context.isAsync()) {
writer.append("return cls[c]();").softNewLine(); writer.append("return cls[c]();").softNewLine();
} else {
writer.append("return cls[c]($return);").softNewLine();
}
writer.outdent().append("}").softNewLine(); writer.outdent().append("}").softNewLine();
writer.append("return ").appendMethodBody(methodRef).append("(")
.append(context.getParameterName(1)).append(");").softNewLine(); writer.append("return ").appendMethodBody(methodRef).append("(").append(context.getParameterName(1));
if (context.isAsync()) {
writer.append(',').ws().append("$return");
}
writer.append(");").softNewLine();
} }
private void generateLookup(GeneratorContext context, SourceWriter writer) throws IOException { private void generateLookup(GeneratorContext context, SourceWriter writer) throws IOException {