Example usage for com.google.gwt.dev.jjs.ast JNode getSourceInfo

List of usage examples for com.google.gwt.dev.jjs.ast JNode getSourceInfo

Introduction

In this page you can find the example usage for com.google.gwt.dev.jjs.ast JNode getSourceInfo.

Prototype

public SourceInfo getSourceInfo() 

Source Link

Usage

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;//ww  w  .j a v a2s .  com
    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 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;//from  ww  w.  j a  va2  s  .  co 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");
}