List of usage examples for com.google.gwt.dev.javac StandardGeneratorContext runGeneratorIncrementally
public RebindResult runGeneratorIncrementally(TreeLogger logger, Class<? extends Generator> generatorClass, String typeName) throws UnableToCompleteException
From source file:xapi.dev.inject.MagicMethods.java
License:Open Source License
private static JDeclaredType injectSingletonAsync(TreeLogger logger, JClassLiteral classLiteral, JMethodCall methodCall, UnifyAstView ast) throws UnableToCompleteException { JDeclaredType type = (JDeclaredType) classLiteral.getRefType(); String[] names = type.getShortName().split("[$]"); // TODO: stop stripping the enclosing class name (need to update generators) // String reqType = JGwtCreate.nameOf(type); String answer = classLiteral.getRefType().getName(); answer = answer.substring(0, answer.lastIndexOf('.') + 1) + "impl.AsyncFor_" + names[names.length - 1]; JDeclaredType answerType = null;// ww w . j a va2s . c om JDeclaredType knownType = ast.getProgram().getFromTypeMap(answer); if (knownType != null) return ast.searchForTypeBySource(answer); else {// we need to generate the singleton on the fly, without updating rebind cache StandardGeneratorContext ctx = ast.getRebindPermutationOracle().getGeneratorContext(); // make sure the requested interface is compiled for the generator ast.searchForTypeBySource(type.getName()); try { // our hardcoded class is definitely a generator ;-} Class<? extends Generator> generator = AsyncInjectionGenerator.class; // (Class<? extends Generator>) Class // .forName("xapi.dev.generators.AsyncInjectionGenerator"); // creates the singleton and provider RebindResult rebindResult = ctx.runGeneratorIncrementally(logger, generator, type.getName()); // commit the generator result, w/out updating rebind cache (to allow GWT.create() rebinds) ctx.finish(logger); // pull back the LazySingeton provider answerType = ast.searchForTypeBySource(rebindResult.getResultTypeName()); // sanity check if (answerType == null) { ast.error(methodCall, "Rebind result '" + answer + "' could not be found. Please be sure that " + type.getName() + " has a subclass on the classpath which contains @SingletonOverride or @SingletonDefault annotations."); throw new UnableToCompleteException(); } } catch (UnableToCompleteException e) { logger.log(Type.ERROR, "Error trying to generator provider for " + type.getName() + ". " + "\nPlease make sure this class is non-abstract, or that a concrete class on the classpath " + "is annotated with @SingletonOverride or @SingletonDefault", e); ast.error(methodCall, "Rebind result '" + answer + "' could not be found"); throw new UnableToCompleteException(); } } if (!(answerType instanceof JClassType)) { ast.error(methodCall, "Rebind result '" + answer + "' must be a class"); throw new UnableToCompleteException(); } if (answerType.isAbstract()) { ast.error(methodCall, "Rebind result '" + answer + "' cannot be abstract"); throw new UnableToCompleteException(); } logger.log(logLevel(), "Injecting asynchronous singleton for " + type.getName() + " -> " + answerType); return answerType; }
From source file:xapi.dev.inject.MagicMethods.java
License:Open Source License
private static JExpression injectLazySingleton(TreeLogger logger, JClassLiteral classLiteral, JNode x, JDeclaredType enclosingType, UnifyAstView ast) throws UnableToCompleteException { JDeclaredType type = (JDeclaredType) classLiteral.getRefType(); String[] names = type.getShortName().split("[$]"); // TODO: stop stripping the enclosing class name (need to update generators) // String reqType = JGwtCreate.nameOf(type); String answer = classLiteral.getRefType().getName(); answer = answer.substring(0, answer.lastIndexOf('.') + 1) + "impl.SingletonFor_" + names[names.length - 1]; JDeclaredType answerType = null;//from w ww . ja v a 2 s .co m JDeclaredType knownType = ast.getProgram().getFromTypeMap(answer); if (knownType != null) {// if the singleton already exists, just use it answerType = ast.searchForTypeBySource(answer); } else {// we need to generate the singleton on the fly, without updating rebind cache StandardGeneratorContext ctx = ast.getRebindPermutationOracle().getGeneratorContext(); // make sure the requested interface is compiled for the generator ast.searchForTypeBySource(type.getName()); try { // our hardcoded class is definitely a generator ;-} Class<? extends Generator> generator = SyncInjectionGenerator.class; // creates the singleton and provider RebindResult result = ctx.runGeneratorIncrementally(logger, generator, type.getName()); // commit the generator result, w/out updating rebind cache (to allow GWT.create() rebinds) ctx.finish(logger); // pull back the LazySingeton provider logger.log(logLevel(), "Loading injected result: " + result.getResultTypeName()); answerType = ast.searchForTypeBySource(result.getResultTypeName()); // sanity check if (answerType == null) { ast.error(x, "Rebind result '" + answer + "' could not be found"); return null; } } catch (UnableToCompleteException e) { logger.log(Type.ERROR, "Error trying to generator provider for " + type.getName() + ". " + "\nPlease make sure this class is non-abstract, or that a concrete class on the classpath " + "is annotated with @SingletonOverride or @SingletonDefault", e); ast.error(x, "Rebind result '" + answer + "' could not be found"); return null; } } if (!(answerType instanceof JClassType)) { ast.error(x, "Rebind result '" + answer + "' must be a class"); return null; } if (answerType.isAbstract()) { ast.error(x, "Rebind result '" + answer + "' cannot be abstract"); return null; } logger.log(logLevel(), "Injecting lazy singleton for " + type.getName() + " -> " + answerType); JExpression result = JGwtCreate.createInstantiationExpression(x.getSourceInfo(), (JClassType) answerType); if (result == null) { ast.error(x, "Rebind result '" + answer + "' has no default (zero argument) constructors"); return null; } return result; }
From source file:xapi.dev.inject.MagicMethods.java
License:Open Source License
private static JExpression injectInstance(TreeLogger logger, JClassLiteral classLiteral, JMethodCall x, JMethod method, UnifyAstView ast) throws UnableToCompleteException { JDeclaredType type = (JDeclaredType) classLiteral.getRefType(); // JExpression expr = injectLazySingleton(logger, classLiteral, x, type, ast); // String[] names = type.getShortName().split("[$]"); String instanceType = classLiteral.getRefType().getName(); StandardGeneratorContext ctx = ast.getRebindPermutationOracle().getGeneratorContext(); // make sure the requested interface is compiled for the generator ast.searchForTypeBySource(type.getName()); JDeclaredType injectedInstance;//from ww w . j a va 2 s . co m try { // our hardcoded class is definitely a generator ;-} Class<? extends Generator> generator = InstanceInjectionGenerator.class; // creates the singleton and provider RebindResult result = ctx.runGeneratorIncrementally(logger, generator, type.getName()); // commit the generator result, w/out updating rebind cache (to allow GWT.create() rebinds) ctx.finish(logger); // pull back the LazySingeton provider logger.log(logLevel(), "Loading injected result: " + result.getResultTypeName()); injectedInstance = ast.searchForTypeBySource(result.getResultTypeName()); // sanity check if (injectedInstance == null) { ast.error(x, "Rebind result '" + instanceType + "' could not be found"); throw new InternalCompilerException("Unable to generate instance provider"); } } catch (UnableToCompleteException e) { logger.log(Type.ERROR, "Error trying to generate provider for " + type.getName() + ". " + "\nPlease make sure this class is non-abstract, or that a concrete class on the classpath " + "is annotated with @SingletonOverride or @SingletonDefault", e); ast.error(x, "Rebind result '" + instanceType + "' could not be found"); throw new InternalCompilerException("Unable to generate instance provider"); } if (!(injectedInstance instanceof JClassType)) { ast.error(x, "Rebind result '" + instanceType + "' must be a class"); throw new InternalCompilerException("Unable to generate instance provider"); } if (injectedInstance.isAbstract()) { ast.error(x, "Rebind result '" + instanceType + "' cannot be abstract"); throw new InternalCompilerException("Unable to generate instance provider"); } // now that we have our injected answer, // let's run it through normal gwt deferred binding as well // copied from UnifyAst#handleGwtCreate String reqType = BinaryName.toSourceName(injectedInstance.getName()); List<String> answers; try { answers = Lists.create(ast.getRebindPermutationOracle().getAllPossibleRebindAnswers(logger, reqType)); ast.getRebindPermutationOracle().getGeneratorContext().finish(logger); } catch (UnableToCompleteException e) { ast.error(x, "Failed to resolve '" + reqType + "' via deferred binding"); return null; } ArrayList<JExpression> instantiationExpressions = new ArrayList<JExpression>(answers.size()); for (String answer : answers) { JDeclaredType answerType = ast.searchForTypeBySource(answer); if (answerType == null) { ast.error(x, "Rebind result '" + answer + "' could not be found"); return null; } if (!(answerType instanceof JClassType)) { ast.error(x, "Rebind result '" + answer + "' must be a class"); return null; } if (answerType.isAbstract()) { ast.error(x, "Rebind result '" + answer + "' cannot be abstract"); return null; } JDeclaredType enclosing = injectedInstance.getEnclosingType(); if (enclosing == null) { enclosing = method.getEnclosingType(); } JExpression result = JGwtCreate.createInstantiationExpression(x.getSourceInfo(), (JClassType) answerType); if (result == null) { ast.error(x, "Rebind result '" + answer + "' has no default (zero argument) constructors"); return null; } instantiationExpressions.add(result); } assert answers.size() == instantiationExpressions.size(); if (answers.size() == 1) return instantiationExpressions.get(0); else return new JGwtCreate(x.getSourceInfo(), reqType, answers, ast.getProgram().getTypeJavaLangObject(), instantiationExpressions); // TODO: cache each injection to detect the first time a class is injected, // then see if the given injection target is Preloadable, // so we can call it's clinit before it is ever accessed, // to reduce the bloat of clinits by visiting preloadable methods before // any client code can possibly access them (less clinit in runtime code) }