List of usage examples for com.google.gwt.dev.jjs InternalCompilerException InternalCompilerException
public InternalCompilerException(String message)
From source file:xapi.dev.inject.MagicMethods.java
License:Open Source License
/** * Replaces a call from {@link X_Inject#singletonAsync(Class, xapi.util.api.ReceivesValue)} by first a) * generating an async provider, and then b) sending the value receiver into the async provider as a * callback. See the {@link AsyncProxy} class and {@link AsyncInjectionGenerator} for implementation. * * @param logger - The logger to log to. * @param methodCall - The method call we are overwriting * @param currentMethod - The encapsulated method itself * @param context - The method call context, so you can insert clinits / whatnot * @param ast - A view over UnifyAst, exposing our basic needs * @return - A JExpression to replace this method call with * @throws UnableToCompleteException/* w w w .jav a2s . co m*/ */ public static JExpression rebindSingletonAsync(TreeLogger logger, JMethodCall methodCall, JMethod currentMethod, Context context, UnifyAstView ast) throws UnableToCompleteException { assert (methodCall.getArgs().size() == 2); JExpression classParam = methodCall.getArgs().get(0); JExpression receiverParam = methodCall.getArgs().get(1); if (!(classParam instanceof JClassLiteral)) { ast.error(methodCall, "Only class literals may be used as arguments to X_Inject.singletonAsync; you sent " + classParam.getClass() + " - " + classParam); return null; } logger.log(logLevel(), receiverParam.toString() + " : " + receiverParam.getClass() + " : " + receiverParam.toSource()); JClassLiteral classLiteral = (JClassLiteral) classParam; JDeclaredType answerType = injectSingletonAsync(logger, classLiteral, methodCall, ast); JDeclaredType receiverType = ast.searchForTypeBySource("xapi.util.api.ReceivesValue"); for (JMethod method : receiverType.getMethods()) { if (method.getName().equals("set")) { SourceInfo info = methodCall.getSourceInfo().makeChild(SourceOrigin.UNKNOWN); JExpression result; result = JGwtCreate.createInstantiationExpression(methodCall.getSourceInfo(), (JClassType) answerType); if (result == null) { ast.error(methodCall, "Rebind result '" + answerType + "' has no default (zero argument) constructors"); return null; } JMethodCall call = new JMethodCall(info, result, method); call.addArg(receiverParam); if (logger.isLoggable(logLevel())) { TreeLogger branch = logger.branch(logLevel(), "Generated asynchronous magic singleton: "); for (String str : call.toSource().split("\n")) { branch.log(logLevel(), str); } } return call; } } throw new InternalCompilerException("Unable to generate asynchronous class injector"); }
From source file:xapi.dev.inject.MagicMethods.java
License:Open Source License
/** * Replaces a call from {@link X_Inject#singletonAsync(Class, xapi.util.api.ReceivesValue)} by first a) * generating an async provider, and then b) sending the value receiver into the async provider as a * callback. See the {@link AsyncProxy} class and {@link AsyncInjectionGenerator} for implementation. * * @param logger - The logger to log to. * @param methodCall - The method call we are overwriting * @param currentMethod - The encapsulated method itself * @param context - The method call context, so you can insert clinits / whatnot * @param ast - A view over UnifyAst, exposing our basic needs * @return - A JExpression to replace this method call with * @throws UnableToCompleteException/* w w w . j a v a2s. c om*/ */ public static JExpression rebindSingletonAndCallback(TreeLogger logger, JMethodCall methodCall, JMethod currentMethod, Context context, UnifyAstView ast) throws UnableToCompleteException { assert (methodCall.getArgs().size() == 2); JExpression classParam = methodCall.getArgs().get(0); JExpression receiveParam = methodCall.getArgs().get(1); if (!(classParam instanceof JClassLiteral)) { ast.error(methodCall, "Only class literals may be used as arguments to X_Inject.singletonAsync; you sent " + classParam.getClass() + " - " + classParam); return null; } logger.log(logLevel(), receiveParam.toString() + " : " + receiveParam.getClass() + " : " + receiveParam.toSource()); JClassLiteral classLiteral = (JClassLiteral) classParam; JClassLiteral receiverLiteral = (JClassLiteral) receiveParam; 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 = receiverLiteral.getRefType().getName(); answer = answer.substring(0, answer.lastIndexOf('.') + 1) + "impl.AsyncProxy_" + names[names.length - 1]; JDeclaredType answerType = null; JDeclaredType knownType = ast.getProgram().getFromTypeMap(answer); // ensure we have a service provider JDeclaredType provider = injectSingletonAsync(logger, classLiteral, methodCall, ast); StandardGeneratorContext ctx = ast.getRebindPermutationOracle().getGeneratorContext(); // ctx.finish(logger); if (knownType != null) {// if the singleton already exists, just use it answerType = ast.searchForTypeBySource(answer); // result = // JGwtCreate.createInstantiationExpression(methodCall.getSourceInfo(), (JClassType) answerType, // currentMethod.getEnclosingType()); } else {// we need to generate the singleton on the fly, without updating rebind cache // make sure the requested interface is compiled for the generator logger.log(logLevel(), "Rebinding singleton w/ callback: " + type + " -> " + provider.getName()); ast.searchForTypeBySource(type.getName()); ast.searchForTypeBySource(BinaryName.toSourceName(provider.getName())); try { InjectionCallbackArtifact rebindResult; try { logger.log(logLevel(), "Loading injected result: " + provider.getName()); rebindResult = AsyncProxyGenerator.setupAsyncCallback(logger, ctx, ctx.getTypeOracle().findType(BinaryName.toSourceName(type.getName())), ((JDeclaredType) receiverLiteral.getRefType())); } catch (ClassNotFoundException e) { e.printStackTrace(); throw new UnableToCompleteException(); } // 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.getAsyncInjectionName()); // 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."); 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(methodCall, "Rebind result '" + answer + "' could not be found"); return null; } } for (JMethod method : answerType.getMethods()) { if (method.getName().equals("go")) // JExpression inst = JGwtCreate.createInstantiationExpression(answerType.getSourceInfo(), // (JClassType)answerType, answerType.getEnclosingType()); return new JMethodCall(method.getSourceInfo(), null, method); } throw new InternalCompilerException("Did not generate async proxy for " + answerType); }
From source file:xapi.dev.inject.MagicMethods.java
License:Open Source License
private static JExpression injectSingleton(TreeLogger logger, JClassLiteral classLiteral, JNode x, UnifyAstView ast) throws UnableToCompleteException { // check for cached result. // inject our provider class JDeclaredType type = (JDeclaredType) classLiteral.getRefType(); if (cachedProviders.containsKey(type)) return cachedProviders.get(type); JExpression expr = injectLazySingleton(logger, classLiteral, x, type, ast); String[] names = type.getShortName().split("[$]"); String answer = classLiteral.getRefType().getName(); answer = answer.substring(0, answer.lastIndexOf('.') + 1) + "impl.SingletonFor_" + names[names.length - 1]; JDeclaredType enclosing = ast.searchForTypeBySource(answer); JDeclaredType lazyProvider = ast.searchForTypeBySource(SingletonProvider.class.getName()); for (JMethod method : lazyProvider.getMethods()) { if (method.getName().equals("get")) { // Create a new method for each singleton to access the desired provider SourceInfo info = null;/* w w w . j a v a2 s.c o m*/ JMethod getSingleton = null; String targetName = "singleton" + type.getShortName().replaceAll("[$]", "_"); for (JMethod existingMethod : enclosing.getMethods()) { if (existingMethod.getName().equals(existingMethod)) { getSingleton = existingMethod; info = getSingleton.getSourceInfo(); logger.log(logLevel(), "Reusing generated method " + getSingleton.toSource()); break; } } if (getSingleton == null) { info = expr.getSourceInfo().makeChild(SourceOrigin.UNKNOWN); JMethodBody body = new JMethodBody(info); getSingleton = new JMethod(info, targetName, enclosing, type, false, true, true, AccessModifier.PRIVATE); // insert our generated method into the enclosing type; needed for super dev mode enclosing.addMethod(getSingleton); // freeze this method getSingleton.setBody(body); getSingleton.freezeParamTypes(); getSingleton.setSynthetic(); info.addCorrelation(info.getCorrelator().by(getSingleton)); JMethodCall call = new JMethodCall(info, expr, method); JReturnStatement value = new JReturnStatement(x.getSourceInfo(), call); if (enclosing.getClinitTarget() != null) { JDeclaredType clinit = enclosing.getClinitTarget(); JMethod clinitMethod = clinit.getMethods().get(0); assert (JProgram.isClinit(clinitMethod)); JMethodCall doClinit = new JMethodCall(clinit.getSourceInfo(), null, clinitMethod); body.getBlock().addStmt(doClinit.makeStatement()); } body.getBlock().addStmt(value); if (logger.isLoggable(Type.DEBUG)) { logger = logger.branch(Type.DEBUG, "Generated magic singleton: "); for (String str : getSingleton.toSource().split("\n")) { logger.branch(Type.DEBUG, str); } } } expr = new JMethodCall(info, null, getSingleton); cachedProviders.put(type, expr); return expr; } } throw new InternalCompilerException("Unable to generate synchronous injected class access"); }
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 w w w . ja v a 2s.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) }