@Override public void generateContentValuesBuilderMethod( TypeSpec.Builder builder, TypeName type, String contentValuesVarName) { builder.addMethod( MethodSpec.methodBuilder(field.getFieldName()) .addJavadoc("Adds the given value to this ContentValues\n") .addJavadoc("@param value The value\n") .addJavadoc("@return $T\n", type) .addModifiers(Modifier.PUBLIC) .addParameter(TypeName.get(field.getField().asType()), "value", Modifier.FINAL) .returns(type) .addStatement("$L.put($S, value)", contentValuesVarName, field.getColumnName()) .addStatement("return this") .build()); builder.addMethod( MethodSpec.methodBuilder(field.getFieldName() + "AsNull") .addJavadoc("Adds a null value to this ContentValues\n") .addJavadoc("@return $T\n", type) .addModifiers(Modifier.PUBLIC) .returns(type) .addStatement("$L.putNull( $S )", contentValuesVarName, field.getColumnName()) .addStatement("return this") .build()); }
private static List<MethodSpec> createIntentBuildMethods( AutoBundleBindingClass target, String fieldName) { List<MethodSpec> methodSpecs = new ArrayList<>(2); ClassName contextClass = ClassName.get("android.content", "Context"); ClassName intentClass = ClassName.get("android.content", "Intent"); MethodSpec buildWithContext = MethodSpec.methodBuilder("build") .addModifiers(Modifier.PUBLIC) .addParameter(contextClass, "context") .returns(intentClass) .addStatement( "$T intent = new $T(context, $T.class)", intentClass, intentClass, target.getTargetType()) .addStatement("intent.putExtras($N)", fieldName) .addStatement("return intent") .build(); MethodSpec buildWithIntent = MethodSpec.methodBuilder("build") .addModifiers(Modifier.PUBLIC) .addParameter(intentClass, "intent") .returns(intentClass) .addStatement("intent.putExtras($N)", fieldName) .addStatement("return intent") .build(); methodSpecs.add(buildWithContext); methodSpecs.add(buildWithIntent); return methodSpecs; }
private static List<MethodSpec> createBuilderMethods( AutoBundleBindingClass target, String fieldName) { List<MethodSpec> methodSpecs = new ArrayList<>(); for (AutoBundleBindingField arg : target.getNotRequiredArgs()) { String argKey = arg.getArgKey(); TypeName argType = arg.getArgType(); String operationName = arg.getOperationName("put"); MethodSpec.Builder builder = MethodSpec.methodBuilder(argKey) .addModifiers(Modifier.PUBLIC) .addParameter(argType, argKey) .returns(ClassName.get(target.getPackageName(), target.getBuilderClassName())); if (arg.hasCustomConverter()) { TypeName converter = arg.getConverter(); builder .addStatement("$T $NConverter = new $T()", converter, argKey, converter) .addStatement( "$N.$N($S, $NConverter.convert($N))", fieldName, operationName, argKey, argKey, argKey); } else { builder.addStatement("$N.$N($S, $N)", fieldName, operationName, argKey, argKey); } builder.addStatement("return this"); methodSpecs.add(builder.build()); } return methodSpecs; }
private MethodSpec getMethod() { return MethodSpec.methodBuilder("get") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .returns(exportClassName) .addStatement("return INSTANCE") .build(); }
private TypeSpec buildModule(ModuleSpec spec) { CodeBlock.Builder blockBuilder = CodeBlock.builder().add("return new $T(", spec.getPresenterTypeName()); int i = 0; for (ParameterSpec parameterSpec : spec.getPresenterArgs()) { blockBuilder.add(parameterSpec.name); if (i++ < spec.getPresenterArgs().size() - 1) { blockBuilder.add(", "); } } blockBuilder.add(");\n"); MethodSpec.Builder methodSpecBuilder = MethodSpec.methodBuilder("providesPresenter") .addModifiers(Modifier.PUBLIC) .returns(spec.getPresenterTypeName()) .addAnnotation(Provides.class) .addParameters(spec.getProvideParameters()) .addCode(blockBuilder.build()); if (spec.getScopeAnnotationSpec() != null) { methodSpecBuilder.addAnnotation(spec.getScopeAnnotationSpec()); } return TypeSpec.classBuilder(spec.getClassName().simpleName()) .addModifiers(Modifier.PUBLIC) .addAnnotation(Module.class) .addMethod(methodSpecBuilder.build()) .build(); }
private void addWriteToParcelMethod(HelperClassBuilder builder) throws ProcessorError { ClassName targetClassName = builder.getArgClassName(); String target = "target"; String parcel = "parcel"; MethodSpec.Builder method = MethodSpec.methodBuilder(METHOD_NAME_WRITE_TO_PARCEL) .addAnnotation( WeaveBuilder.weave() .method(METHOD_NAME_WRITE_TO_PARCEL, Parcel.class, int.class) .placed(WeaveBuilder.MethodWeaveType.AFTER_SUPER) .withStatement( "%s.%s(this, $1);", fullName(builder.getClassName()), METHOD_NAME_WRITE_TO_PARCEL) .build()) .addModifiers(Modifier.PUBLIC, Modifier.STATIC); addClassAsParameter(method, targetClassName, target); method.addParameter(Parcel.class, parcel); for (int i = 0, c = mFields.size(); i < c; i++) { Field field = mFields.get(i); CallFormat writeCall = Parceler.writeCall(field.element); if (writeCall == null) { continue; // TODO : should throw exception or ignore field ?! } Pair<String, List<Object>> mappedWriteCall = mapCall(field, writeCall, target, parcel); method.addStatement( mappedWriteCall.fst, mappedWriteCall.snd.toArray(new Object[mappedWriteCall.snd.size()])); } builder.getBuilder().addMethod(method.build()); }
private MethodSpec toStringMethod() { return MethodSpec.methodBuilder("toString") .addModifiers(Modifier.PUBLIC) .addParameter(Dialect.class, "dialect") .returns(String.class) .addStatement("return versionSet.toString(dialect)") .build(); }
public MethodSpec createCompareTo() { final String other = "other"; return MethodSpec.methodBuilder("compareTo") .addAnnotation(Override.class) .addModifiers(Modifier.PUBLIC) .returns(int.class) .addParameter(ParameterSpec.builder(terminalTypeName, other, Modifier.FINAL).build()) .addCode( CodeBlock.builder().addStatement("return value.compareTo($L.value)", other).build()) .build(); }
public MethodSpec createShow() { return MethodSpec.methodBuilder("show") .addAnnotation(Override.class) .addModifiers(Modifier.PUBLIC) .returns(String.class) .addCode( CodeBlock.builder() .addStatement("return String.format(\"<$L>%s</$L>\", value)", tag, tag) .build()) .build(); }
public MethodSpec createHashCode() { return MethodSpec.methodBuilder("hashCode") .addAnnotation(Override.class) .addModifiers(Modifier.PUBLIC) .returns(int.class) .addCode( CodeBlock.builder() .addStatement("final int prime = $L", prime) .addStatement("return prime + value.hashCode()") .build()) .build(); }
public MethodSpec createValueGetter() { return MethodSpec.methodBuilder("value") .addAnnotation(Override.class) .addJavadoc( "Returns this {@code $L}'s value.\n\n@return this {@code $L}'s value.\n", terminalName, terminalName) .addModifiers(Modifier.PUBLIC) .returns(String.class) .addCode(CodeBlock.builder().addStatement("return value").build()) .build(); }
private static MethodSpec createBindWithSourceMethod(AutoBundleBindingClass target) { List<AutoBundleBindingField> args = new ArrayList<>(); args.addAll(target.getRequiredArgs()); args.addAll(target.getNotRequiredArgs()); MethodSpec.Builder builder = MethodSpec.methodBuilder("bind") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .returns(void.class) .addParameter(target.getTargetType(), "target") .addParameter(CLASS_BUNDLE, "source"); for (AutoBundleBindingField arg : args) { String key = arg.getArgKey(); String fieldName = arg.getFieldName(); TypeName argType = arg.getArgType(); String operationName = arg.getOperationName("get"); builder.beginControlFlow("if (source.containsKey($S))", key); if (arg.hasCustomConverter()) { TypeName converter = arg.getConverter(); builder .addStatement("$T $NConverter = new $T()", converter, key, converter) .addStatement( "target.$N = ($T) $NConverter.original(source.$N($S))", fieldName, argType, key, operationName, key); } else { if (arg.noCast()) { builder.addStatement("target.$N = source.$N($S)", fieldName, operationName, key); } else { builder.addStatement( "target.$N = ($T) source.$N($S)", fieldName, argType, operationName, key); } } if (arg.isRequired()) { String exceptionMessage = String.format("%s is required, but not found in the bundle.", key); builder .nextControlFlow("else") .addStatement("throw new IllegalStateException($S)", exceptionMessage); } builder.endControlFlow(); } return builder.build(); }
private static List<MethodSpec> createFragmentBuildMethods( AutoBundleBindingClass target, String fieldName) { List<MethodSpec> methodSpecs = new ArrayList<>(2); ClassName targetClass = target.getTargetType(); MethodSpec buildWithNoParam = MethodSpec.methodBuilder("build") .addModifiers(Modifier.PUBLIC) .returns(targetClass) .addStatement("$T fragment = new $T()", targetClass, targetClass) .addStatement("fragment.setArguments($N)", fieldName) .addStatement("return fragment") .build(); MethodSpec buildWithFragment = MethodSpec.methodBuilder("build") .addModifiers(Modifier.PUBLIC) .addParameter(targetClass, "fragment") .returns(targetClass) .addStatement("fragment.setArguments($N)", fieldName) .addStatement("return fragment") .build(); methodSpecs.add(buildWithNoParam); methodSpecs.add(buildWithFragment); return methodSpecs; }
public static MethodSpec.Builder createParseFieldsFunction( String paramPackageName, String paramClassName) { ClassName clazzReturn = ClassName.get("java.lang", "String"); ClassName stringBuilder = ClassName.get("java.lang", "StringBuilder"); ClassName parameter = ClassName.get(paramPackageName, paramClassName); MethodSpec.Builder mapFieldsBuilder = MethodSpec.methodBuilder(parseFieldsFunction) .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .addException(fieldDecoratorEx) .addParameter(parameter, instanceName) .returns(clazzReturn) .addStatement("$T " + stringBuilderName + " = new $T()", stringBuilder, stringBuilder); return mapFieldsBuilder; }
private static MethodSpec createCallBuilderMethod(AutoBundleBindingClass target) { ClassName builderClass = ClassName.get(target.getPackageName(), target.getBuilderClassName()); MethodSpec.Builder builder = MethodSpec.methodBuilder("create" + target.getBuilderType().name() + "Builder") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .returns(builderClass) .addCode("return new $T(", builderClass); for (int i = 0, count = target.getRequiredArgs().size(); i < count; i++) { if (i > 0) { builder.addCode(","); } AutoBundleBindingField arg = target.getRequiredArgs().get(i); builder.addParameter(arg.getArgType(), arg.getArgKey()).addCode("$N", arg.getArgKey()); } return builder.addCode(");\n").build(); }
private MethodSpec createFillResponseMethod(RestActionClass actionClass) { MethodSpec.Builder builder = MethodSpec.methodBuilder("fillResponse") .addModifiers(Modifier.PUBLIC) .addAnnotation(Override.class) .returns(ClassName.get(actionClass.getTypeElement().asType())) .addParameter(actionClass.getTypeName(), "action") .addParameter(Response.class, "response") .addParameter(Converter.class, "converter"); addStatusField(actionClass, builder); addResponses(actionClass, builder); addBasicHeadersMap(actionClass, builder); addResponseHeaders(actionClass, builder); builder.addStatement("return action"); return builder.build(); }
private void addReadFromParcelMethod(HelperClassBuilder builder) throws ProcessorError { ClassName targetClassName = builder.getArgClassName(); String target = "target"; String parcel = "parcel"; MethodSpec.Builder method = MethodSpec.methodBuilder(METHOD_NAME_READ_FROM_PARCEL) .addAnnotation( WeaveBuilder.weave() .constructor(Parcel.class) .withStatement( "%s.%s(this, $1);", fullName(builder.getClassName()), METHOD_NAME_READ_FROM_PARCEL) .build()) .addModifiers(Modifier.PUBLIC, Modifier.STATIC); addClassAsParameter(method, targetClassName, target); method.addParameter(Parcel.class, parcel); for (int i = 0, c = mFields.size(); i < c; i++) { Field field = mFields.get(i); CallFormat readCall = Parceler.readCall(field.element); if (readCall == null) { continue; // TODO : should throw exception or ignore field ?! } Pair<String, List<Object>> mappedReadCall = mapCall(field, readCall, target, parcel); String format = mappedReadCall.fst; List<Object> args = mappedReadCall.snd; if (field.isAccessible()) { format = String.format("$N.$N = %s", format); args.add(0, field.element.getSimpleName()); args.add(0, target); } else { format = String.format("$N.$N(%s)", format); args.add(0, field.setter.getSimpleName()); args.add(0, target); } method.addStatement(format, args.toArray(new Object[args.size()])); } builder.getBuilder().addMethod(method.build()); }
private MethodSpec createFillErrorMethod(RestActionClass actionClass) { MethodSpec.Builder builder = MethodSpec.methodBuilder("fillError") .addModifiers(Modifier.PUBLIC) .addAnnotation(Override.class) .returns(actionClass.getTypeName()) .addParameter(actionClass.getTypeName(), "action") .addParameter(Throwable.class, "error"); for (Element element : actionClass.getAnnotatedElements(Error.class)) { String fieldAddress = getFieldAddress(actionClass, element); if (TypeUtils.containsType(element, Throwable.class)) { builder.addStatement(fieldAddress + " = error", element); } else if (TypeUtils.containsType(element, Exception.class)) { builder.addStatement(fieldAddress + " = ($T) error", element, Exception.class); } } builder.addStatement("return action"); return builder.build(); }
private static MethodSpec createBindMethod(AutoBundleBindingClass target) { MethodSpec.Builder builder = MethodSpec.methodBuilder("bind") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .returns(void.class) .addParameter(target.getTargetType(), "target"); switch (target.getBuilderType()) { case Fragment: builder.addStatement("bind(target, target.getArguments())"); break; case Intent: builder.addParameter(ClassName.get("android.content", "Intent"), "intent"); builder .beginControlFlow("if (intent.getExtras() != null)") .addStatement("bind(target, intent.getExtras())") .endControlFlow(); break; } return builder.build(); }
public MethodSpec createEquals() { final ParameterSpec object = ParameterSpec.builder(Object.class, "object", Modifier.FINAL).build(); return MethodSpec.methodBuilder("equals") .addAnnotation(Override.class) .addModifiers(Modifier.PUBLIC) .returns(boolean.class) .addParameter(object) .addCode( CodeBlock.builder() .beginControlFlow("if (this == $L)", object.name) .addStatement("return true") .endControlFlow() .beginControlFlow( "if ($L == null || getClass() != $L.getClass())", object.name, object.name) .addStatement("return false") .endControlFlow() .addStatement( "final $T other = ($T) $L", terminalTypeName, terminalTypeName, object.name) .addStatement("return value.equals(other.value)") .build()) .build(); }
private static MethodSpec createPackMethod(AutoBundleBindingClass target) { List<AutoBundleBindingField> args = new ArrayList<>(); args.addAll(target.getRequiredArgs()); args.addAll(target.getNotRequiredArgs()); MethodSpec.Builder builder = MethodSpec.methodBuilder("pack") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .returns(void.class) .addParameter(target.getTargetType(), "source") .addParameter(CLASS_BUNDLE, "args"); for (AutoBundleBindingField arg : args) { String key = arg.getArgKey(); String fieldName = arg.getFieldName(); TypeName argType = arg.getArgType(); String operationName = arg.getOperationName("put"); if (!argType.isPrimitive()) { String exceptionMessage = String.format("%s must not be null.", fieldName); builder .beginControlFlow("if (source.$N == null)", fieldName) .addStatement("throw new IllegalStateException($S)", exceptionMessage) .endControlFlow(); } if (arg.hasCustomConverter()) { TypeName converter = arg.getConverter(); builder .addStatement("$T $NConverter = new $T()", converter, key, converter) .addStatement( "args.$N($S, $NConverter.convert(source.$N))", operationName, key, key, fieldName); } else { builder.addStatement("args.$N($S, source.$N)", operationName, key, fieldName); } } return builder.build(); }
private MethodSpec injectorMethodForSubclasses( ImmutableMap<BindingKey, FieldSpec> dependencyFields, List<TypeVariableName> typeParameters, TypeName injectedTypeName, Element injectionElement, ImmutableSet<DependencyRequest> dependencies) { MethodSpec.Builder methodBuilder = MethodSpec.methodBuilder(injectionSiteDelegateMethodName(injectionElement)) .addModifiers(PUBLIC, STATIC) .addParameter(injectedTypeName, "instance") .addTypeVariables(typeParameters); ImmutableList.Builder<CodeBlock> providedParameters = ImmutableList.builder(); Set<String> parameterNames = new HashSet<>(); for (DependencyRequest dependency : dependencies) { FieldSpec field = dependencyFields.get(dependency.bindingKey()); ParameterSpec parameter = ParameterSpec.builder( field.type, staticInjectMethodDependencyParameterName(parameterNames, dependency, field)) .build(); methodBuilder.addParameter(parameter); providedParameters.add( frameworkTypeUsageStatement(CodeBlocks.format("$N", parameter), dependency.kind())); } if (injectionElement.getKind().isField()) { methodBuilder.addStatement( "instance.$L = $L", injectionElement.getSimpleName(), getOnlyElement(providedParameters.build())); } else { methodBuilder.addStatement( "instance.$L($L)", injectionElement.getSimpleName(), makeParametersCodeBlock(providedParameters.build())); } return methodBuilder.build(); }
private MethodSpec createRequestMethod(RestActionClass actionClass) { MethodSpec.Builder builder = MethodSpec.methodBuilder("createRequest") .addModifiers(Modifier.PUBLIC) .addAnnotation(Override.class) .returns(Request.class) .addParameter(TypeName.get(actionClass.getTypeElement().asType()), "action") .addParameter(RequestBuilder.class, "requestBuilder") .addStatement( "requestBuilder.setMethod($T.$L)", RestAction.Method.class, actionClass.getMethod()) .addStatement( "requestBuilder.setRequestType($T.$L)", RestAction.Type.class, actionClass.getRequestType()) .addStatement("requestBuilder.setPath($S)", actionClass.getPath()); addPathParams(actionClass, builder); addParts(actionClass, builder); addRequestHeaders(actionClass, builder); addRequestFields(actionClass, builder); addRequestQueries(actionClass, builder); addRequestBody(actionClass, builder); builder.addStatement("return requestBuilder.build()"); return builder.build(); }
private DeriveResult<DerivedCodeSpec> functionDispatchImpl(List<DataConstructor> constructors) { NameAllocator nameAllocator = nameAllocator(constructors); TypeElement f = FlavourImpl.findF(context.flavour(), utils.elements()); TypeName returnType = TypeName.get( utils .types() .getDeclaredType( f, adt.typeConstructor().declaredType(), adt.matchMethod().returnTypeVariable())); TypeSpec wrapper = TypeSpec.anonymousClassBuilder("") .addField( FieldSpec.builder(returnType, nameAllocator.get("cata")) .initializer( CodeBlock.builder() .addStatement( "$L -> $L.$L($L)", nameAllocator.get("adt var"), nameAllocator.get("adt var"), adt.matchMethod().element().getSimpleName(), Utils.joinStringsAsArguments( constructors .stream() .map( constructor -> constructor .arguments() .stream() .map(DataArguments::getType) .noneMatch( tm -> utils .types() .isSameType( tm, adt.typeConstructor() .declaredType())) ? constructor.name() : CodeBlock.builder() .add( "($L) -> $L.$L($L)", Utils.asLambdaParametersString( constructor.arguments(), constructor.typeRestrictions()), constructor.name(), MapperDerivator.mapperApplyMethod( utils, context, constructor), Utils.joinStringsAsArguments( Stream.concat( constructor .arguments() .stream() .map( argument -> utils .types() .isSameType( argument .type(), adt.typeConstructor() .declaredType()) ? "() -> this." + nameAllocator .get( "cata") + "." + FlavourImpl .functionApplyMethod( utils, context) + "(" + argument .fieldName() + ")" : argument .fieldName()), constructor .typeRestrictions() .stream() .map( TypeRestriction ::idFunction) .map( DataArgument ::fieldName)))) .build() .toString()))) .build()) .build()) .build(); MethodSpec cataMethod = MethodSpec.methodBuilder("cata") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .addTypeVariables( Stream.concat( adt.typeConstructor().typeVariables().stream(), Stream.of(adt.matchMethod().returnTypeVariable())) .map(TypeVariableName::get) .collect(Collectors.toList())) .returns(returnType) .addParameters( constructors .stream() .map( dc -> ParameterSpec.builder( cataMapperTypeName(dc), MapperDerivator.mapperFieldName(dc)) .build()) .collect(toList())) .addStatement("return $L.$L", wrapper, nameAllocator.get("cata")) .build(); return result(methodSpec(cataMethod)); }
private TypeSpec build(ScopeSpec spec) { MethodSpec configureScopeSpec = MethodSpec.methodBuilder("configureScope") .addModifiers(Modifier.PUBLIC) .addAnnotation(Override.class) .addParameter(ClassName.get(MortarScope.Builder.class), "builder") .addParameter(ClassName.get(MortarScope.class), "parentScope") .addCode( CodeBlock.builder() .add( "builder.withService($T.SERVICE_NAME, $T.builder()\n", DAGGERSERVICE_CLS, spec.getDaggerComponentTypeName()) .indent() .add( ".$L(parentScope.<$T>getService($T.SERVICE_NAME))\n", spec.getDaggerComponentBuilderDependencyMethodName(), spec.getDaggerComponentBuilderDependencyTypeName(), DAGGERSERVICE_CLS) .add(".module(new Module())\n") .add(".build());\n") .unindent() .build()) .build(); List<FieldSpec> fieldSpecs = new ArrayList<>(); for (ParameterSpec parameterSpec : spec.getModuleSpec().getInternalParameters()) { fieldSpecs.add(FieldSpec.builder(parameterSpec.type, parameterSpec.name).build()); } MethodSpec.Builder constructorBuilder = MethodSpec.constructorBuilder() .addModifiers(Modifier.PUBLIC) .addAnnotation(AnnotationSpec.builder(ParcelConstructor.class).build()) .addParameters(spec.getModuleSpec().getInternalParameters()); for (ParameterSpec parameterSpec : spec.getModuleSpec().getInternalParameters()) { constructorBuilder.addStatement("this.$L = $L", parameterSpec.name, parameterSpec.name); } TypeSpec.Builder builder = TypeSpec.classBuilder(spec.getClassName().simpleName()) .addModifiers(Modifier.PUBLIC) .addAnnotation( AnnotationSpec.builder(Generated.class) .addMember( "value", "$S", architect.autostack.compiler.AnnotationProcessor.class.getName()) .build()) .addAnnotation(spec.getComponentAnnotationSpec()) .addAnnotation( AnnotationSpec.builder(Parcel.class).addMember("parcelsIndex", "false").build()) .addType(buildModule(spec.getModuleSpec())) .addMethod(constructorBuilder.build()) .addMethod(configureScopeSpec) .addFields(fieldSpecs); if (spec.getScopeAnnotationSpec() != null) { builder.addAnnotation(spec.getScopeAnnotationSpec()); } if (spec.getPathViewTypeName() != null) { builder.addSuperinterface(PATH_CLS); MethodSpec createViewSpec = MethodSpec.methodBuilder("createView") .addModifiers(Modifier.PUBLIC) .returns(spec.getPathViewTypeName()) .addAnnotation(Override.class) .addParameter(CONTEXT_CLS, "context") .addStatement("return new $T(context)", spec.getPathViewTypeName()) .build(); builder.addMethod(createViewSpec); } else { builder.addSuperinterface(STACKABLE_CLS); } return builder.build(); }
public static DeriveResult<DerivedCodeSpec> derive( AlgebraicDataType adt, DeriveContext deriveContext, DeriveUtils deriveUtils) { // skip constructors for enums if (adt.typeConstructor().declaredType().asElement().getKind() == ElementKind.ENUM) { return result(none()); } TypeConstructor typeConstructor = adt.typeConstructor(); TypeElement lazyTypeElement = FlavourImpl.findF0(deriveContext.flavour(), deriveUtils.elements()); TypeName lazyArgTypeName = TypeName.get( deriveUtils.types().getDeclaredType(lazyTypeElement, typeConstructor.declaredType())); String lazyArgName = Utils.uncapitalize(typeConstructor.typeElement().getSimpleName()); TypeName typeName = TypeName.get(typeConstructor.declaredType()); List<TypeVariableName> typeVariableNames = adt.typeConstructor() .typeVariables() .stream() .map(TypeVariableName::get) .collect(Collectors.toList()); String className = "Lazy"; TypeSpec.Builder typeSpecBuilder = TypeSpec.classBuilder(className) .addModifiers(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) .addTypeVariables(typeVariableNames) .addField( FieldSpec.builder( TypeName.get(Object.class), "lock", Modifier.PRIVATE, Modifier.FINAL) .initializer("new Object()") .build()) .addField(FieldSpec.builder(lazyArgTypeName, "expression", Modifier.PRIVATE).build()) .addField( FieldSpec.builder(typeName, "evaluation", Modifier.PRIVATE, Modifier.VOLATILE) .build()) .addMethod( MethodSpec.constructorBuilder() .addParameter(ParameterSpec.builder(lazyArgTypeName, lazyArgName).build()) .addStatement("this.expression = $N", lazyArgName) .build()) .addMethod( MethodSpec.methodBuilder("eval") .addModifiers(Modifier.PRIVATE) .returns(typeName) .addCode( CodeBlock.builder() .addStatement("$T _evaluation = this.evaluation", typeName) .beginControlFlow("if (_evaluation == null)") .beginControlFlow("synchronized (this.lock)") .addStatement("_evaluation = this.evaluation") .beginControlFlow("if (_evaluation == null)") .addStatement( "this.evaluation = _evaluation = expression.$L()", Utils.getAbstractMethods(lazyTypeElement.getEnclosedElements()) .get(0) .getSimpleName()) .addStatement("this.expression = null") .endControlFlow() .endControlFlow() .endControlFlow() .addStatement("return _evaluation") .build()) .build()) .addMethod( Utils.overrideMethodBuilder(adt.matchMethod().element()) .addStatement( "return this.eval().$L($L)", adt.matchMethod().element().getSimpleName(), Utils.asArgumentsStringOld(adt.matchMethod().element().getParameters())) .build()); if (adt.typeConstructor().declaredType().asElement().getKind() == ElementKind.INTERFACE) { typeSpecBuilder.addSuperinterface(typeName); } else { typeSpecBuilder.superclass(typeName); } typeSpecBuilder.addMethods( optionalAsStream( findAbstractEquals(typeConstructor.typeElement(), deriveUtils.elements()) .map( equals -> deriveUtils .overrideMethodBuilder(equals) .addStatement( "return this.eval().equals($L)", equals.getParameters().get(0).getSimpleName()) .build())) .collect(Collectors.toList())); typeSpecBuilder.addMethods( optionalAsStream( findAbstractHashCode(typeConstructor.typeElement(), deriveUtils.elements()) .map( hashCode -> deriveUtils .overrideMethodBuilder(hashCode) .addStatement("return this.eval().hashCode()") .build())) .collect(Collectors.toList())); typeSpecBuilder.addMethods( optionalAsStream( findAbstractToString(typeConstructor.typeElement(), deriveUtils.elements()) .map( toString -> deriveUtils .overrideMethodBuilder(toString) .addStatement("return this.eval().toString()") .build())) .collect(Collectors.toList())); return result( codeSpec( typeSpecBuilder.build(), MethodSpec.methodBuilder("lazy") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .addTypeVariables( typeConstructor .typeVariables() .stream() .map(TypeVariableName::get) .collect(Collectors.toList())) .addParameter(lazyArgTypeName, lazyArgName) .returns(typeName) .addStatement( "return new $L$L($L)", className, typeVariableNames.isEmpty() ? "" : "<>", lazyArgName) .build())); }
@Override Optional<TypeSpec.Builder> write(ClassName generatedTypeName, MembersInjectionBinding binding) { // Empty members injection bindings are special and don't need source files. if (binding.injectionSites().isEmpty()) { return Optional.absent(); } // We don't want to write out resolved bindings -- we want to write out the generic version. checkState(!binding.unresolved().isPresent()); ImmutableList<TypeVariableName> typeParameters = bindingTypeElementTypeVariableNames(binding); TypeSpec.Builder injectorTypeBuilder = TypeSpec.classBuilder(generatedTypeName.simpleName()) .addModifiers(PUBLIC, FINAL) .addTypeVariables(typeParameters); TypeName injectedTypeName = TypeName.get(binding.key().type()); TypeName implementedType = membersInjectorOf(injectedTypeName); injectorTypeBuilder.addSuperinterface(implementedType); MethodSpec.Builder injectMembersBuilder = MethodSpec.methodBuilder("injectMembers") .returns(TypeName.VOID) .addModifiers(PUBLIC) .addAnnotation(Override.class) .addParameter(injectedTypeName, "instance") .addCode("if (instance == null) {") .addStatement( "throw new $T($S)", NullPointerException.class, "Cannot inject members into a null reference") .addCode("}"); ImmutableMap<BindingKey, FrameworkField> fields = SourceFiles.generateBindingFieldsForDependencies(dependencyRequestMapper, binding); ImmutableMap.Builder<BindingKey, FieldSpec> dependencyFieldsBuilder = ImmutableMap.builder(); MethodSpec.Builder constructorBuilder = MethodSpec.constructorBuilder().addModifiers(PUBLIC); // We use a static create method so that generated components can avoid having // to refer to the generic types of the factory. // (Otherwise they may have visibility problems referring to the types.) MethodSpec.Builder createMethodBuilder = MethodSpec.methodBuilder("create") .returns(implementedType) .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .addTypeVariables(typeParameters); createMethodBuilder.addCode( "return new $T(", javapoetParameterizedGeneratedTypeNameForBinding(binding)); ImmutableList.Builder<CodeBlock> constructorInvocationParameters = ImmutableList.builder(); boolean usesRawFrameworkTypes = false; UniqueNames fieldNames = new UniqueNames(); for (Entry<BindingKey, FrameworkField> fieldEntry : fields.entrySet()) { BindingKey bindingKey = fieldEntry.getKey(); FrameworkField bindingField = fieldEntry.getValue(); // If the dependency type is not visible to this members injector, then use the raw framework // type for the field. boolean useRawFrameworkType = !VISIBLE_TO_MEMBERS_INJECTOR.visit(bindingKey.key().type(), binding); String fieldName = fieldNames.getUniqueName(bindingField.name()); TypeName fieldType = useRawFrameworkType ? bindingField.javapoetFrameworkType().rawType : bindingField.javapoetFrameworkType(); FieldSpec.Builder fieldBuilder = FieldSpec.builder(fieldType, fieldName, PRIVATE, FINAL); ParameterSpec.Builder parameterBuilder = ParameterSpec.builder(fieldType, fieldName); // If we're using the raw type for the field, then suppress the injectMembers method's // unchecked-type warning and the field's and the constructor and create-method's // parameters' raw-type warnings. if (useRawFrameworkType) { usesRawFrameworkTypes = true; fieldBuilder.addAnnotation(SUPPRESS_WARNINGS_RAWTYPES); parameterBuilder.addAnnotation(SUPPRESS_WARNINGS_RAWTYPES); } constructorBuilder.addParameter(parameterBuilder.build()); createMethodBuilder.addParameter(parameterBuilder.build()); FieldSpec field = fieldBuilder.build(); injectorTypeBuilder.addField(field); constructorBuilder.addStatement("assert $N != null", field); constructorBuilder.addStatement("this.$N = $N", field, field); dependencyFieldsBuilder.put(bindingKey, field); constructorInvocationParameters.add(CodeBlocks.format("$N", field)); } createMethodBuilder.addCode(CodeBlocks.join(constructorInvocationParameters.build(), ", ")); createMethodBuilder.addCode(");"); injectorTypeBuilder.addMethod(constructorBuilder.build()); injectorTypeBuilder.addMethod(createMethodBuilder.build()); Set<String> delegateMethods = new HashSet<>(); ImmutableMap<BindingKey, FieldSpec> dependencyFields = dependencyFieldsBuilder.build(); List<MethodSpec> injectMethodsForSubclasses = new ArrayList<>(); for (InjectionSite injectionSite : binding.injectionSites()) { injectMembersBuilder.addCode( visibleToMembersInjector(binding, injectionSite.element()) ? directInjectMemberCodeBlock(binding, dependencyFields, injectionSite) : delegateInjectMemberCodeBlock(dependencyFields, injectionSite)); if (!injectionSite.element().getModifiers().contains(PUBLIC) && injectionSite.element().getEnclosingElement().equals(binding.bindingElement()) && delegateMethods.add(injectionSiteDelegateMethodName(injectionSite.element()))) { injectMethodsForSubclasses.add( injectorMethodForSubclasses( dependencyFields, typeParameters, injectedTypeName, injectionSite.element(), injectionSite.dependencies())); } } if (usesRawFrameworkTypes) { injectMembersBuilder.addAnnotation(SUPPRESS_WARNINGS_UNCHECKED); } injectorTypeBuilder.addMethod(injectMembersBuilder.build()); for (MethodSpec methodSpec : injectMethodsForSubclasses) { injectorTypeBuilder.addMethod(methodSpec); } return Optional.of(injectorTypeBuilder); }
public List<MethodSpec> buildMethodSpecs() { List<MethodSpec> methodSpecs = new ArrayList<>(); List<AnnotationSpec> overrideAndNonNull = Arrays.asList(Specs.buildNonNullAnnotationSpec(), Specs.buildOverrideAnnotationSpec()); List<AnnotationSpec> overrideAndNullable = Arrays.asList(Specs.buildNullableAnnotationSpec(), Specs.buildOverrideAnnotationSpec()); methodSpecs.add( MethodSpec.methodBuilder("getModelClass") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns( ParameterizedTypeName.get(ClassName.get(Class.class), schema.getModelClassName())) .addStatement("return $T.class", schema.getModelClassName()) .build()); methodSpecs.add( MethodSpec.methodBuilder("getTableName") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns(Types.String) .addStatement("return $L", TABLE_NAME) .build()); methodSpecs.add( MethodSpec.methodBuilder("getPrimaryKey") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns(Types.WildcardColumnDef) .addStatement("return $N", primaryKey) .build()); methodSpecs.add( MethodSpec.methodBuilder("getColumns") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns(Types.ColumnList) .addStatement("return $L", COLUMNS) .build()); methodSpecs.add( MethodSpec.methodBuilder("getEscapedColumnNames") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns(Types.StringArray) .addStatement("return $L", ESCAPED_COLUMN_NAMES) .build()); methodSpecs.add( MethodSpec.methodBuilder("getCreateTableStatement") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns(Types.String) .addStatement("return $S", sql.buildCreateTableStatement(schema)) .build()); methodSpecs.add( MethodSpec.methodBuilder("getCreateIndexStatements") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns(Types.getList(Types.String)) .addCode(sql.buildCreateIndexStatements(schema)) .build()); methodSpecs.add( MethodSpec.methodBuilder("getDropTableStatement") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns(Types.String) .addStatement("return $S", sql.buildDropTableStatement(schema)) .build()); methodSpecs.add( MethodSpec.methodBuilder("getInsertStatement") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns(Types.String) .addStatement("return $S", sql.buildInsertStatement(schema)) .build()); methodSpecs.add( MethodSpec.methodBuilder("bindArgs") .addModifiers(Modifier.PUBLIC) .returns(TypeName.VOID) .addParameter( ParameterSpec.builder(Types.OrmaConnection, "conn") .addAnnotation(Specs.buildNonNullAnnotationSpec()) .build()) .addParameter( ParameterSpec.builder(Types.SQLiteStatement, "statement") .addAnnotation(Specs.buildNonNullAnnotationSpec()) .build()) .addParameter( ParameterSpec.builder(schema.getModelClassName(), "model") .addAnnotation(Specs.buildNonNullAnnotationSpec()) .build()) .addCode(buildBindArgs()) .build()); methodSpecs.add( MethodSpec.methodBuilder("createModelFromCursor") .addAnnotations(overrideAndNonNull) .addModifiers(Modifier.PUBLIC) .returns(schema.getModelClassName()) .addParameter( ParameterSpec.builder(Types.OrmaConnection, "conn") .addAnnotation(Specs.buildNonNullAnnotationSpec()) .build()) .addParameter( ParameterSpec.builder(Types.Cursor, "cursor") .addAnnotation(Specs.buildNonNullAnnotationSpec()) .build()) .addCode(buildCreateModelFromCursor()) .build()); return methodSpecs; }
@Override public void onWriteDefinition(TypeSpec.Builder typeBuilder) { typeBuilder.addField( FieldSpec.builder( ClassName.get(String.class), AUTHORITY, Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) .initializer("$S", authority) .build()); int code = 0; for (TableEndpointDefinition endpointDefinition : endpointDefinitions) { for (ContentUriDefinition contentUriDefinition : endpointDefinition.contentUriDefinitions) { typeBuilder.addField( FieldSpec.builder( TypeName.INT, contentUriDefinition.name, Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL) .initializer(String.valueOf(code)) .build()); code++; } } FieldSpec.Builder uriField = FieldSpec.builder( ClassNames.URI_MATCHER, URI_MATCHER, Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL); CodeBlock.Builder initializer = CodeBlock.builder() .addStatement("new $T($T.NO_MATCH)", ClassNames.URI_MATCHER, ClassNames.URI_MATCHER) .add("static {\n"); for (TableEndpointDefinition endpointDefinition : endpointDefinitions) { for (ContentUriDefinition contentUriDefinition : endpointDefinition.contentUriDefinitions) { String path; if (contentUriDefinition.path != null) { path = "\"" + contentUriDefinition.path + "\""; } else { path = CodeBlock.builder() .add( "$L.$L.getPath()", contentUriDefinition.elementClassName, contentUriDefinition.name) .build() .toString(); } initializer.addStatement( "$L.addURI($L, $L, $L)", URI_MATCHER, AUTHORITY, path, contentUriDefinition.name); } } initializer.add("}\n"); typeBuilder.addField(uriField.initializer(initializer.build()).build()); typeBuilder.addMethod( MethodSpec.methodBuilder("getDatabaseName") .addAnnotation(Override.class) .addModifiers(Modifier.PUBLIC, Modifier.FINAL) .addStatement("return $S", databaseNameString) .returns(ClassName.get(String.class)) .build()); MethodSpec.Builder getTypeBuilder = MethodSpec.methodBuilder("getType") .addAnnotation(Override.class) .addParameter(ClassNames.URI, "uri") .returns(ClassName.get(String.class)) .addModifiers(Modifier.PUBLIC, Modifier.FINAL); CodeBlock.Builder getTypeCode = CodeBlock.builder() .addStatement("$T type = null", ClassName.get(String.class)) .beginControlFlow("switch($L.match(uri))", URI_MATCHER); for (TableEndpointDefinition tableEndpointDefinition : endpointDefinitions) { for (ContentUriDefinition uriDefinition : tableEndpointDefinition.contentUriDefinitions) { getTypeCode .beginControlFlow("case $L:", uriDefinition.name) .addStatement("type = $S", uriDefinition.type) .addStatement("break") .endControlFlow(); } } getTypeCode .beginControlFlow("default:") .addStatement( "throw new $T($S + $L)", ClassName.get(IllegalArgumentException.class), "Unknown URI", "uri") .endControlFlow(); getTypeCode.endControlFlow(); getTypeCode.addStatement("return type"); getTypeBuilder.addCode(getTypeCode.build()); typeBuilder.addMethod(getTypeBuilder.build()); for (MethodDefinition method : methods) { MethodSpec methodSpec = method.getMethodSpec(); if (methodSpec != null) { typeBuilder.addMethod(methodSpec); } } }