List of usage examples for com.google.gwt.user.rebind SourceWriter indent
void indent();
From source file:sheath.rebind.SheathGenerator.java
License:Apache License
@Override public RebindResult generateIncrementally(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { TypeOracle oracle = context.getTypeOracle(); JClassType toGenerate = oracle.findType(typeName).isInterface(); if (toGenerate == null) { logger.log(TreeLogger.ERROR, typeName + " is not an interface type"); throw new UnableToCompleteException(); }//from ww w .j av a 2 s . c om JClassType sheathType = oracle.findType(Sheath.class.getCanonicalName()); if (!toGenerate.isAssignableTo(sheathType)) { logger.log(TreeLogger.ERROR, typeName + " is not assignable to " + Sheath.class.getCanonicalName()); throw new UnableToCompleteException(); } if (toGenerate.equals(sheathType)) { logger.log(TreeLogger.ERROR, "You must declare an interface that extends " + Sheath.class.getCanonicalName()); throw new UnableToCompleteException(); } // TODO: really generate incrementally! Class<?>[] moduleClasses = collectAllModules(logger, toGenerate); Map<String, String> injectableTypes = new LinkedHashMap<String, String>(); Set<Class<?>> staticInjections = new LinkedHashSet<Class<?>>(); for (Class<?> module : moduleClasses) { Module annotation = module.getAnnotation(Module.class); String moduleName = module.getCanonicalName(); for (Class<?> key : annotation.injects()) { injectableTypes.put(key.getName(), moduleName); } for (Class<?> c : annotation.staticInjections()) { staticInjections.add(c); } } String packageName = toGenerate.getPackage().getName(); String simpleSourceName = toGenerate.getName().replace('.', '_') + "Impl"; PrintWriter pw = context.tryCreate(logger, packageName, simpleSourceName); if (pw == null) { return new RebindResult(RebindMode.USE_ALL_NEW_WITH_NO_CACHING, packageName + "." + simpleSourceName); } ClassSourceFileComposerFactory factory = new ClassSourceFileComposerFactory(packageName, simpleSourceName); factory.setSuperclass(AbstractSheath.class.getCanonicalName()); factory.addImplementedInterface(typeName); SourceWriter sw = factory.createSourceWriter(context, pw); // Linker sw.println("private static class Plugin extends AbstractSheathPlugin {"); sw.indent(); sw.println("@java.lang.Override"); sw.println( "public native %1$s<?> getAtInjectBinding(%2$s key, %2$s className, boolean mustBeInjectable) /*-{", Binding.class.getCanonicalName(), String.class.getCanonicalName()); sw.indent(); sw.println("switch (className) {"); LinkedHashMap<String, String> factoryMethodsToGenerate = new LinkedHashMap<String, String>(); for (JClassType type : oracle.getTypes()) { // XXX: workaround for http://code.google.com/p/google-web-toolkit/issues/detail?id=6799 // We really should use type.getName().endsWith("$$InjectAdapter") but GWT makes a JClassType // with name "InjectAdapter", thinking it's a nested class, and we lose the part before the // dollar. So in the mean time, look for the InjectAdapter in the classpath FOR EACH CLASS, // and we additionally generate a non-JSNI class to instantiate it, so that processing of the // class name is done by JDT rather than GWT's TypeOracle. String adapterName = type.getQualifiedSourceName() + "$$InjectAdapter"; boolean found; try { Class.forName(adapterName, false, Thread.currentThread().getContextClassLoader()); found = true; } catch (Throwable t) { found = false; } if (found /*&& type.isAssignableTo(oracle.findType(Binding.class.getCanonicalName()))*/) { String name = type.getQualifiedSourceName(); String factoryName = "create_" + name.replace('.', '_') + "_InjectAdapter"; factoryMethodsToGenerate.put(adapterName, factoryName); sw.println("case '%s': return this.@%s.Plugin::%s()();", name, factory.getCreatedClassName(), factoryName); } } sw.println("default: return null;"); sw.println("}"); sw.outdent(); sw.println("}-*/;"); for (Map.Entry<String, String> factoryMethodToGenerate : factoryMethodsToGenerate.entrySet()) { sw.println(); sw.println("private %s %s() {", factoryMethodToGenerate.getKey(), factoryMethodToGenerate.getValue()); sw.indentln("return new %s();", factoryMethodToGenerate.getKey()); sw.println("}"); } sw.println(); sw.println("@java.lang.Override"); sw.println("public %s[] createStaticInjections() {", StaticInjection.class.getCanonicalName()); sw.indent(); sw.println("return new %s[] {", StaticInjection.class.getCanonicalName()); sw.indent(); for (Class<?> staticInjection : staticInjections) { sw.println("new %s$$StaticInjection(),", staticInjection.getName()); } sw.outdent(); sw.println("};"); sw.outdent(); sw.println("}"); sw.outdent(); sw.print("}"); // Constructor sw.println(); sw.println("public %s() {", simpleSourceName); sw.indent(); sw.println("super(new Plugin(), "); sw.println("new %s<?>[] {", ModuleAdapter.class.getCanonicalName()); sw.indent(); for (Class<?> module : moduleClasses) { sw.println("new %s$$ModuleAdapter(),", module.getName()); } sw.outdent(); sw.println("});"); sw.outdent(); sw.outdent(); sw.println("}"); for (JMethod method : toGenerate.getOverridableMethods()) { // TODO: check arguments (number, injectable types) if (method.getParameterTypes().length != 1) { // could be injectStatics() continue; } JType toInject = method.getParameterTypes()[0]; sw.println("@java.lang.Override"); sw.println("public %s %s(%s instance) {", method.getReturnType().getParameterizedQualifiedSourceName(), method.getName(), toInject.getParameterizedQualifiedSourceName()); sw.indent(); sw.println("doInject(instance, \"members/%s\", %s.class);", toInject.getParameterizedQualifiedSourceName(), injectableTypes.get(toInject.getQualifiedBinaryName())); if (!JPrimitiveType.VOID.equals(method.getReturnType())) { sw.println("return arg;"); } sw.outdent(); sw.println("}"); } sw.commit(logger); return new RebindResult(RebindMode.USE_ALL_NEW_WITH_NO_CACHING, packageName + "." + simpleSourceName); }
From source file:xapi.dev.generators.AbstractInjectionGenerator.java
License:Open Source License
public static InjectionCallbackArtifact ensureAsyncInjected(TreeLogger logger, String packageName, String className, String outputClass, GeneratorContext ctx) throws UnableToCompleteException { GwtInjectionMap gwtInjectionMap = getInjectionMap(logger, ctx); InjectionCallbackArtifact artifact = gwtInjectionMap.getOrCreateArtifact(ctx, packageName, className); if (artifact.isTargetUnbound()) { artifact.bindTo(outputClass);//from ww w .j a va 2 s . co m ensureProviderClass(logger, packageName, artifact.getSimpleName(), artifact.getCanonicalName(), artifact.getBoundTarget(), ctx); logger = logger.branch(Type.TRACE, "Creating asynchronous callback for " + artifact.getCanonicalName() + " -> " + outputClass); String generatedName = InjectionUtils.generatedAsyncProviderName(artifact.getGeneratedName()); String implPackage = artifact.getImplementationPackage(); PrintWriter printWriter = ctx.tryCreate(logger, implPackage, generatedName); if (printWriter == null) { logger.log(Type.WARN, "Could not create the source writer for " + implPackage + "." + generatedName); return artifact; } artifact.addCallback(implPackage + "." + generatedName + ".Deproxy"); ctx.commitArtifact(logger, artifact); ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(implPackage, generatedName); composer.setPrivacy("public final"); composer.addImport(com.google.gwt.core.client.GWT.class.getName()); composer.addImport(RunAsyncCallback.class.getName()); composer.addImport(Fifo.class.getName()); composer.addImport(JsFifo.class.getName()); composer.addImport(AsyncProxy.class.getName()); composer.addImport(ApplyMethod.class.getName()); composer.addImport(ReceivesValue.class.getName()); composer.addImport(ReceiverAdapter.class.getCanonicalName()); composer.addImport(artifact.getCanonicalName()); String simpleName = artifact.getSimpleName(); SourceWriter sw = composer.createSourceWriter(ctx, printWriter); sw.println(); sw.println("static final class Callbacks implements ApplyMethod{"); sw.indent(); sw.println("public void apply(Object ... args){"); sw.println("}"); sw.outdent(); sw.println("}"); sw.println(); sw.println("static final class Deproxy implements ReceivesValue<" + simpleName + ">{"); sw.indent(); sw.println("public final void set(final " + simpleName + " value){"); sw.indentln("getter = new ReceiverAdapter<" + simpleName + ">(value);"); sw.println("}"); sw.outdent(); sw.println("}"); sw.println(); sw.println("private static final class Proxy implements ReceivesValue<ReceivesValue<" + simpleName + ">>{"); sw.indent(); sw.println("public final void set(final ReceivesValue<" + simpleName + "> receiver){"); sw.indent(); sw.print("GWT.runAsync("); sw.println(artifact.getCanonicalName() + ".class,new Request(receiver));"); sw.outdent(); sw.println("}"); sw.outdent(); sw.println("}"); sw.println(); sw.println("private static final class Request"); sw.indent(); sw.println("extends AsyncProxy<" + simpleName + "> "); sw.println("implements RunAsyncCallback{"); DefermentWriter defer = new DefermentWriter(sw); defer.setStrategy(DefermentStrategy.NONE); sw.println("private static final Fifo<ReceivesValue<" + simpleName + ">> pending ="); sw.indentln("JsFifo.newFifo();"); sw.println(); sw.println("protected Request(ReceivesValue<" + simpleName + "> receiver){"); sw.indentln("accept(receiver);"); sw.println("}"); sw.println(); sw.println("@Override"); sw.println("protected final Fifo<ReceivesValue<" + simpleName + ">> pending(){"); sw.indentln("return pending;"); sw.println("}"); sw.println(); sw.println("protected final void dispatch(){"); sw.indentln("go();"); sw.println("}"); sw.println(); sw.println("public final void onSuccess(){"); sw.indent(); defer.printStart(); sw.println("final " + simpleName + " value = "); sw.print(packageName + "." + InjectionUtils.generatedProviderName(simpleName)); sw.println(".theProvider.get();"); sw.println(); sw.print("final ApplyMethod callbacks = GWT.create("); sw.print(packageName + ".impl." + generatedName + ".Callbacks.class"); sw.println(");"); sw.println("callbacks.apply(value);"); sw.println(); sw.println("apply(value);"); sw.outdent(); sw.println("}"); sw.outdent(); defer.printFinish(); sw.println("}"); sw.println(); sw.println("private static ReceivesValue<ReceivesValue<" + simpleName + ">> getter = new Proxy();"); sw.println(); sw.println("static void request(final ReceivesValue<" + simpleName + "> request){"); sw.indentln("getter.set(request);"); sw.println("}"); sw.println(); sw.println("static void go(){"); sw.indentln("request(null);"); sw.println("}"); sw.println(); sw.println("private " + generatedName + "(){}"); sw.commit(logger); } else { assert artifact.getBoundTarget().equals(outputClass) : "The injection target " + artifact.getCanonicalName() + " was bound " + "to " + artifact.getBoundTarget() + ", but you tried to bind it again, " + "to a different class: " + outputClass; } return artifact; }
From source file:xapi.dev.generators.AbstractInjectionGenerator.java
License:Open Source License
public static boolean ensureProviderClass(TreeLogger logger, String packageName, String simpleName0, String canonical, String qualifiedSourceName, GeneratorContext ctx) { String simpleName = SourceUtil.toSourceName(simpleName0); String generatedName = InjectionUtils.generatedProviderName(simpleName); String cleanedCanonical = SourceUtil.toSourceName(canonical); logger.log(Type.DEBUG, "Creating provider for " + packageName + "." + generatedName); PrintWriter printWriter = ctx.tryCreate(logger, packageName, generatedName); if (printWriter == null) { logger.log(Type.TRACE, "Already generated " + generatedName); return false; }/*from ww w. j a va 2 s . c o m*/ logger.log(Type.TRACE, "Newly Generating provider " + generatedName + " <- " + qualifiedSourceName); ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(packageName, generatedName); composer.setSuperclass(SingletonInitializer.class.getName() + "<" + simpleName0 + ">"); composer.addImport(cleanedCanonical); composer.addImport(GWT.class.getName()); composer.addImport(SingletonProvider.class.getName()); SourceWriter sw = composer.createSourceWriter(ctx, printWriter); sw.println("@Override"); sw.println("public " + simpleName + " initialValue(){"); sw.indent(); sw.print("return GWT.<" + cleanedCanonical + ">create("); sw.print(SourceUtil.toSourceName(qualifiedSourceName) + ".class"); sw.println(");"); sw.outdent(); sw.println("}"); sw.println(); //now, print a static final provider instance sw.print("public static final SingletonProvider<"); sw.print(simpleName0 + "> "); sw.print("theProvider = "); sw.println("new " + generatedName + "();"); sw.commit(logger); return true; }
From source file:xapi.dev.generators.AsyncInjectionGenerator.java
License:Open Source License
/** * @throws ClassNotFoundException//from ww w.j av a 2 s.co m */ public static RebindResult execImpl(TreeLogger logger, GeneratorContext context, JClassType type) throws ClassNotFoundException, UnableToCompleteException { logger.log(Type.TRACE, "Async Inject For " + type.getSimpleSourceName()); PlatformSet platforms = CurrentGwtPlatform.getPlatforms(context); JClassType targetType = type; String simpleName = type.getSimpleSourceName(); SingletonOverride winningOverride = null; JClassType winningType = null; for (JClassType subtype : type.getSubtypes()) { if (winningType == null) { SingletonDefault singletonDefault = subtype.getAnnotation(SingletonDefault.class); if (singletonDefault != null && platforms.isAllowedType(subtype)) { winningType = subtype; continue; } } SingletonOverride override = subtype.getAnnotation(SingletonOverride.class); if (override != null) { logger.log(Type.DEBUG, "Got subtype " + subtype + " : " + " - prodMode: " + context.isProdMode()); if (platforms.isAllowedType(subtype)) { if (winningOverride != null) { if (winningOverride.priority() > override.priority()) continue; } winningOverride = override; winningType = subtype; } } } if (winningType == null) { winningType = targetType;//no matches, resort to instantiate the class sent. //TODO sanity check here, or at least log a warning } String generatedName = "AsyncFor_" + simpleName; String packageName = type.getPackage().getName(); ensureAsyncInjected(logger, packageName, type.getName(), winningType.getQualifiedBinaryName(), context); // ensureCallbackClass(logger, packageName,type.getQualifiedSourceName(),type.getSimpleSourceName(), winningType.getQualifiedSourceName(), context); packageName = packageName + ".impl"; PrintWriter printWriter = context.tryCreate(logger, packageName, generatedName); if (printWriter == null) { return new RebindResult(RebindMode.USE_EXISTING, packageName + "." + generatedName); } ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(packageName, generatedName); composer.setPrivacy("public final"); composer.addImplementedInterface("ReceivesValue<ReceivesValue<" + simpleName + ">>"); composer.addImport(type.getQualifiedSourceName()); composer.addImport(ReceivesValue.class.getName()); SourceWriter sw = composer.createSourceWriter(context, printWriter); sw.println(); sw.indent(); sw.println("@Override"); sw.println("public final void set(ReceivesValue<" + simpleName + "> x) {"); sw.indent(); // sw.println(packageName+"."+generatedCallbackName(simpleName)+".deferred.push(x);"); // sw.println(packageName+"."+generatedCallbackName(simpleName)+".go();"); sw.outdent(); sw.println("}"); sw.outdent(); sw.commit(logger); return new RebindResult(RebindMode.USE_ALL_NEW_WITH_NO_CACHING, packageName + "." + generatedName); }
From source file:xapi.dev.generators.RunAsyncInjectionGenerator.java
License:Open Source License
@Override public RebindResult generateIncrementally(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { Iterable<InjectionCallbackArtifact> artifacts = getInjectionMap(logger, context).getArtifacts(); // ctx.getArtifacts().find(InjectionCallbackArtifact.class); if (typeName.endsWith(".Callbacks")) { typeName = typeName.substring(0, typeName.length() - 10); logger.log(Type.INFO, "" + typeName); for (InjectionCallbackArtifact artifact : artifacts) { if (artifact.getAsyncInjectionName().equals(typeName)) { //we have our injectable artifact! int packageIndex = typeName.lastIndexOf('.'); String packageName = typeName.substring(0, packageIndex); String generatedName = "RunAsync" + typeName.substring(packageIndex + 12); typeName = packageName + "." + generatedName; logger.log(Type.INFO, "WIN " + typeName + " <- " + artifact); PrintWriter printWriter = context.tryCreate(logger, packageName, generatedName); if (printWriter == null) { logger.log(Type.TRACE, "Re-Using existing " + typeName); return new RebindResult(RebindMode.USE_EXISTING, typeName); }//from ww w . j a v a 2s . c o m ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(packageName, generatedName); composer.addImplementedInterface(ApplyMethod.class.getName()); composer.setPrivacy("public final"); composer.addImport(GWT.class.getName()); composer.addImport(ApplyMethod.class.getName()); composer.addImport(ProvidesValue.class.getName()); composer.addImport(ReceivesValue.class.getName()); composer.addImport(Runnable.class.getName()); composer.addImport(Fifo.class.getName()); composer.addImport(JsFifo.class.getName()); composer.addImport(Timer.class.getName()); composer.addImport(Scheduler.class.getName()); composer.addImport(ScheduledCommand.class.getCanonicalName()); SourceWriter sw = composer.createSourceWriter(printWriter); sw.println("private static final Fifo<Object> callbacks;"); sw.println("static{"); sw.indent(); sw.println("callbacks = JsFifo.newFifo();"); for (String callback : artifact.getCallbacks()) { sw.println("callbacks.give(GWT.create(" + callback + ".class));"); } sw.outdent(); sw.println("}"); sw.println("@SuppressWarnings({\"unchecked\", \"rawtypes\"})"); sw.println("public void apply(final Object ... args){"); DefermentWriter defer = new DefermentWriter(sw); defer.printStart();//used to optionally push callbacks into new execution block //for now, we are only sending the service object as parameter sw.println(" Object service = args[0], callback;"); sw.println(" while(!callbacks.isEmpty()){"); sw.indent(); sw.println(" callback = callbacks.take();"); sw.println(" if (callback instanceof ReceivesValue){"); sw.println(" ((ReceivesValue)callback).set(service);"); sw.println(" }"); sw.println(" else if (callback instanceof ApplyMethod){"); sw.println(" ((ApplyMethod)callback).apply(args);"); sw.println(" }"); sw.println(" else if (callback instanceof ProvidesValue){"); sw.println(" ((ProvidesValue<ReceivesValue>)callback).get().set(service);"); sw.println(" }"); sw.println(" else if (callback instanceof Runnable){"); sw.println(" ((Runnable)callback).run();"); sw.println(" }"); sw.println("}"); sw.outdent(); defer.printFinish(); sw.println("}"); // sw.println("}"); sw.commit(logger); context.commit(logger, printWriter); return new RebindResult(RebindMode.USE_ALL_NEW, typeName); } } } logger.log(Type.INFO, "No callback class found for " + typeName + "; returning untransformed."); return new RebindResult(RebindMode.USE_EXISTING, typeName); }
From source file:xapi.dev.generators.SyncInjectionGenerator.java
License:Open Source License
/** * @throws ClassNotFoundException//w ww . j a v a2 s . c o m */ public static RebindResult execImpl(TreeLogger logger, GeneratorContext context, JClassType type) throws ClassNotFoundException { PlatformSet allowed = CurrentGwtPlatform.getPlatforms(context); JClassType targetType = type; String simpleName = "SingletonFor_" + type.getSimpleSourceName(); SingletonOverride winningOverride = null; JClassType winningType = null; boolean trace = logger.isLoggable(Type.TRACE); for (JClassType subtype : type.getSubtypes()) { if (winningType == null) { SingletonDefault singletonDefault = subtype.getAnnotation(SingletonDefault.class); if (singletonDefault != null) { if (allowed.isAllowedType(subtype)) winningType = subtype; continue; } } SingletonOverride override = subtype.getAnnotation(SingletonOverride.class); if (override != null) { if (trace) logger.log(Type.DEBUG, "Got subtype " + subtype + " : " + " - prodMode: " + context.isProdMode()); if (allowed.isAllowedType(subtype)) { if (winningOverride != null) { if (winningOverride.priority() > override.priority()) continue; } winningOverride = override; winningType = subtype; } } } if (winningType == null) { winningType = targetType;//no matches, resort to instantiate the class sent. //TODO sanity check here } if (trace) X_Log.info("Singleton Injection Winner: " + winningType.getName()); String packageName = type.getPackage().getName(); ensureProviderClass(logger, packageName, type.getSimpleSourceName(), type.getQualifiedSourceName(), SourceUtil.toSourceName(winningType.getQualifiedSourceName()), context); packageName = packageName + ".impl"; PrintWriter printWriter = context.tryCreate(logger, packageName, simpleName); if (printWriter == null) { return new RebindResult(RebindMode.USE_EXISTING, packageName + "." + simpleName); } ClassSourceFileComposerFactory composer = new ClassSourceFileComposerFactory(packageName, simpleName); composer.setSuperclass(SingletonInitializer.class.getName() + "<" + type.getQualifiedSourceName() + ">"); composer.addImport(ReceivesValue.class.getName()); SourceWriter sw = composer.createSourceWriter(context, printWriter); sw.println(); //TODO: also check if compile is set to async = false //if async is already generated when this singleton access occurs, //but we haven't yet injected the callback which accesses the global singleton, //we'll have to route our get() through the existing async callback block //to prevents code splitting from falling apart. This will, at worst, //cause providers to return null until the service is actually initialized. if (context.isProdMode() && isAsyncProvided(logger, packageName, type.getSimpleSourceName(), context) && !isCallbackInjected(logger, packageName, type.getSimpleSourceName(), context)) { //this edge case happens when a service is accessed synchronously //inside of its own asynchronous callback //TODO use GWT's AsyncProxy class to queue up requests... logger.log(Type.WARN, "Generating interim singleton provider"); sw.indent(); sw.println("private static " + type.getQualifiedSourceName() + " value = null;"); sw.println("@Override"); sw.println("public final " + type.getQualifiedSourceName() + " initialValue(){"); sw.indent(); sw.println("if (value!=null)return value;"); sw.println(packageName + "." + InjectionUtils.generatedAsyncProviderName(type.getSimpleSourceName())); sw.indent(); sw.print(".request(new ReceivesValue<"); sw.println(type.getQualifiedSourceName() + ">(){"); sw.indent(); sw.println("@Override"); sw.print("public void set("); sw.println(type.getQualifiedSourceName() + " x){"); sw.indent(); sw.println("value=x;"); sw.outdent(); sw.println("}"); sw.outdent(); sw.println("});"); sw.outdent(); sw.println("return value;"); } else { //all non-prod or non-async providers can safely access the singleton directly sw.println("@Override"); sw.println("public final " + type.getQualifiedSourceName() + " initialValue(){"); sw.indent(); //normal operation; just wrap the static final singleton provider. sw.print("return " + type.getPackage().getName() + "." + InjectionUtils.generatedProviderName(type.getSimpleSourceName())); sw.println(".theProvider.get();"); } sw.outdent(); sw.println("}"); sw.println(); sw.commit(logger); //TODO: implement caching once this code is finalized return new RebindResult(RebindMode.USE_ALL_NEW_WITH_NO_CACHING, packageName + "." + simpleName); }