public ExtraBindingTarget createTargetClass(TypeElement typeElement) { final String classPackage = compilerUtil.getPackageName(typeElement); final String className = compilerUtil.getClassName(typeElement, classPackage); return new ExtraBindingTarget(classPackage, className); }
public void addField(String key, String name, TypeMirror type, boolean required, boolean parcel) { ExtraInjection extraInjection = bindingMap.get(key); if (extraInjection == null) { extraInjection = new ExtraInjection(key); bindingMap.put(key, extraInjection); } extraInjection.addFieldBinding(new FieldBinding(name, type, required, parcel)); hasRequiredFields = hasRequiredFields || required; }
/** * @param builder the intent builder in which to emit. * @param binding the binding to emit. * @param generic generic value. */ private void emitOptionalSetter( TypeSpec.Builder builder, ExtraInjection binding, TypeName generic) { Collection<FieldBinding> fieldBindings = binding.getFieldBindings(); if (fieldBindings.isEmpty()) { return; } FieldBinding firstFieldBinding = fieldBindings.iterator().next(); TypeMirror extraType = firstFieldBinding.getType(); String castToParcelableIfNecessary = doCreateParcelableCastIfExtraIsParcelable(extraType); final String value = extractValue(firstFieldBinding); MethodSpec.Builder setterBuilder = MethodSpec.methodBuilder(binding.getKey()) .addModifiers(Modifier.PUBLIC) .addParameter(TypeName.get(extraType), firstFieldBinding.getName()) .returns(generic) .addStatement( "bundler.put($S," + castToParcelableIfNecessary + " $L)", binding.getKey(), value) .addStatement("return ($T) this", generic); builder.addMethod(setterBuilder.build()); }
private void emitFieldBindings(MethodSpec.Builder builder, ExtraInjection binding) { Collection<FieldBinding> fieldBindings = binding.getFieldBindings(); if (fieldBindings.isEmpty()) { return; } for (FieldBinding fieldBinding : fieldBindings) { builder.addCode("target.$L = ", fieldBinding.getName()); if (fieldBinding.isParcel()) { builder.addCode("org.parceler.Parcels.unwrap((android.os.Parcelable) object);\n"); } else { emitCast(builder, fieldBinding.getType()); builder.addCode("object;\n"); } } }
public void parseInjectExtra( Element element, Map<TypeElement, ExtraBindingTarget> targetClassMap) { // Verify common generated code restrictions. if (!isValidUsageOfBindExtra(element)) { return; } final TypeElement enclosingElement = (TypeElement) element.getEnclosingElement(); ExtraBindingTarget extraBindingTarget = targetClassMap.get(enclosingElement); if (extraBindingTarget == null) { // The ExtraBindingTarget was already created, @DartModel processed first if (!dartModelUtil.isValidUsageOfDartModel(enclosingElement)) { return; } extraBindingTarget = extraBindingTargetUtil.createTargetClass(enclosingElement); targetClassMap.put(enclosingElement, extraBindingTarget); } final String annotationValue = element.getAnnotation(BindExtra.class).value(); final String name = element.getSimpleName().toString(); final String key = StringUtil.isNullOrEmpty(annotationValue) ? name : annotationValue; final TypeMirror type = element.asType(); final boolean required = isRequiredInjection(element); final boolean parcel = parcelerUtil.isParcelerAvailable() && parcelerUtil.isValidExtraTypeForParceler(type); extraBindingTarget.addField(key, name, type, required, parcel); }
private void emitExtraInjection(MethodSpec.Builder builder, ExtraInjection binding) { builder.addStatement("object = finder.getExtra(source, $S)", binding.getKey()); List<Binding> requiredBindings = binding.getRequiredBindings(); if (!requiredBindings.isEmpty()) { builder .beginControlFlow("if (object == null)") .addStatement( "throw new IllegalStateException(\"Required extra with key '$L' for $L " + "was not found. If this extra is optional add '@Nullable' annotation.\")", binding.getKey(), emitHumanDescription(requiredBindings)) .endControlFlow(); emitFieldBindings(builder, binding); } else { // an optional extra, wrap it in a check to keep original value, if any builder.beginControlFlow("if (object != null)"); emitFieldBindings(builder, binding); builder.endControlFlow(); } }
public void createBindingTargetTrees(Map<TypeElement, ExtraBindingTarget> targetClassMap) { final Set<TypeElement> targetTypeElements = targetClassMap.keySet(); for (TypeElement typeElement : targetTypeElements) { TypeElement parentTypeElement = compilerUtil.findParent(typeElement, targetTypeElements); if (parentTypeElement != null) { final ExtraBindingTarget target = targetClassMap.get(typeElement); final ExtraBindingTarget parentTarget = targetClassMap.get(parentTypeElement); target.parentPackage = parentTarget.classPackage; target.parentClass = parentTarget.className; parentTarget.addChild(typeElement); } } checkForParentsOutside(targetClassMap); }
public NavigationModelBindingTarget createTargetClass( TypeElement classElement, VariableElement navigationModelVariableElement) { final String classPackage = compilerUtil.getPackageName(classElement); final String className = compilerUtil.getClassName(classElement, classPackage); final TypeElement navigationModelElement = (TypeElement) ((DeclaredType) navigationModelVariableElement.asType()).asElement(); final String navigationModelPackage = compilerUtil.getPackageName(navigationModelElement); final String navigationModelClass = compilerUtil.getClassName(navigationModelElement, navigationModelPackage); final String navigationModelFieldName = navigationModelVariableElement.getSimpleName().toString(); return new NavigationModelBindingTarget( classPackage, className, navigationModelPackage, navigationModelClass, navigationModelFieldName); }
private void emitBind(TypeSpec.Builder builder) { MethodSpec.Builder bindBuilder = MethodSpec.methodBuilder("bind") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .addParameter(ClassName.get(Dart.Finder.class), "finder") .addParameter(ClassName.bestGuess(target.getFQN() + DART_MODEL_SUFFIX), "target") .addParameter(ClassName.get(Object.class), "source"); if (target.parentPackage != null) { // Emit a call to the superclass binder, if any. bindBuilder.addStatement( "$T.bind(finder, target, source)", ClassName.bestGuess( target.getParentFQN() + DART_MODEL_SUFFIX + Dart.EXTRA_BINDER_SUFFIX)); } // Local variable in which all extras will be temporarily stored. bindBuilder.addStatement("Object object"); // Loop over each extras binding and emit it. for (ExtraInjection binding : target.bindingMap.values()) { emitExtraInjection(bindBuilder, binding); } builder.addMethod(bindBuilder.build()); }
private void emitAssign(TypeSpec.Builder builder) { MethodSpec.Builder bindBuilder = MethodSpec.methodBuilder("assign") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .addParameter(bestGuess(target.getFQN()), "target") .addParameter( get(target.navigationModelPackage, target.navigationModelClass), "navigationModel"); bindBuilder.addStatement("target.$L = navigationModel", target.navigationModelFieldName); if (target.parentPackage != null) { // Emit a call to the superclass binder, if any. bindBuilder.addStatement( "$T.assign(target, navigationModel)", bestGuess(target.getParentFQN() + NAVIGATION_MODEL_BINDER_SUFFIX)); } builder.addMethod(bindBuilder.build()); } }
public void writeFile(BaseGenerator generator, Element... originatingElements) throws IOException { Writer writer = null; try { JavaFileObject jfo = filer.createSourceFile(generator.getFqcn(), originatingElements); writer = jfo.openWriter(); if (isDebugEnabled) { System.out.println("File generated:\n" + generator.brewJava() + "---"); } writer.write(generator.brewJava()); } finally { if (writer != null) { writer.close(); } } } }
private void emitInitialStateGetter(TypeSpec.Builder intentBuilderTypeBuilder) { MethodSpec.Builder initialStateGetterForHensonBuilder = MethodSpec.methodBuilder(INITIAL_STATE_METHOD) .addModifiers(Modifier.PUBLIC) .addModifiers(Modifier.STATIC) .addParameter(get("android.content", "Context"), "context") .returns(get(target.classPackage, builderClassName(), INITIAL_STATE_CLASS)); initialStateGetterForHensonBuilder.addStatement( "final $T intent = new $T(context, getClassDynamically($S))", ClassName.get("android.content", "Intent"), ClassName.get("android.content", "Intent"), target.getFQN()); initialStateGetterForHensonBuilder.addStatement( "final $T bundler = $T.create()", Bundler.class, Bundler.class); initialStateGetterForHensonBuilder.addStatement( "return new $L(bundler, intent)", INITIAL_STATE_CLASS); intentBuilderTypeBuilder.addMethod(initialStateGetterForHensonBuilder.build()); }
private void emitExtraDSLStateMachine(TypeSpec.Builder intentBuilderTypeBuilder) { //separate required extras from optional extras and sort both sublists. List<ExtraInjection> requiredInjections = new ArrayList<>(); List<ExtraInjection> optionalInjections = new ArrayList<>(); for (ExtraInjection extraInjection : target.bindingMap.values()) { if (!extraInjection.getRequiredBindings().isEmpty()) { requiredInjections.add(extraInjection); } else { optionalInjections.add(extraInjection); } } final ExtraInjectionComparator extraInjectionComparator = new ExtraInjectionComparator(); Collections.sort(requiredInjections, extraInjectionComparator); Collections.sort(optionalInjections, extraInjectionComparator); emitRequiredSequence(intentBuilderTypeBuilder, requiredInjections); emitOptionalSequence(intentBuilderTypeBuilder, optionalInjections); }
@Before public void setup() { final ExtraBindingTarget extraBindingTarget = new ExtraBindingTarget("foo", "barNavigationModel"); extraBinderGenerator = new ExtraBinderGenerator(extraBindingTarget); }
public List<Binding> getRequiredBindings() { List<Binding> requiredBindings = new ArrayList<Binding>(); for (FieldBinding fieldBinding : fieldBindings) { if (fieldBinding.isRequired()) { requiredBindings.add(fieldBinding); } } return requiredBindings; }
/** Visible for testing */ String emitHumanDescription(List<Binding> bindings) { StringBuilder builder = new StringBuilder(); switch (bindings.size()) { case 1: builder.append(bindings.get(0).getDescription()); break; case 2: builder .append(bindings.get(0).getDescription()) .append(" and ") .append(bindings.get(1).getDescription()); break; default: for (int i = 0, count = bindings.size(); i < count; i++) { Binding requiredField = bindings.get(i); if (i != 0) { builder.append(", "); } if (i == count - 1) { builder.append("and "); } builder.append(requiredField.getDescription()); } break; } return builder.toString(); } }
final Collection<FieldBinding> fieldBindings = binding.getFieldBindings(); if (fieldBindings.isEmpty()) { return null; REQUIRED_SEQUENCE_INTERMEDIARY_CLASS_PREFIX + capitalize(binding.getKey()); final TypeMirror extraType = firstFieldBinding.getType(); final String castToParcelableIfNecessary = doCreateParcelableCastIfExtraIsParcelable(extraType); final String value = extractValue(firstFieldBinding); MethodSpec.methodBuilder(binding.getKey()) .addModifiers(Modifier.PUBLIC) .addParameter(TypeName.get(extraType), firstFieldBinding.getName()) .returns(nextState) .addStatement( "bundler.put($S," + castToParcelableIfNecessary + " $L)", binding.getKey(), value);
private void emitBind(TypeSpec.Builder builder) { MethodSpec.Builder bindBuilder = MethodSpec.methodBuilder("bind") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .addParameter(get(Dart.Finder.class), "finder") .addParameter(bestGuess(target.getFQN()), "target"); bindBuilder.addStatement( "target.$L = new $T()", target.navigationModelFieldName, get(target.navigationModelPackage, target.navigationModelClass)); bindBuilder.addStatement( "$T.bind(finder, target.$L, target)", get(target.navigationModelPackage, target.navigationModelClass + Dart.EXTRA_BINDER_SUFFIX), target.navigationModelFieldName); if (target.parentPackage != null) { // Emit a call to the superclass binder, if any. bindBuilder.addStatement( "$T.assign(target, target.$L)", bestGuess(target.getParentFQN() + NAVIGATION_MODEL_BINDER_SUFFIX), target.navigationModelFieldName); } builder.addMethod(bindBuilder.build()); }