public static MethodDefinitionBuilder main(AbstractTransformer gen) { MethodDefinitionBuilder mdb = new MethodDefinitionBuilder(gen, false, "main").modifiers(PUBLIC | STATIC); ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.instance(mdb.gen, "args"); pdb.type( gen.make().TypeArray(gen.make().Type(gen.syms().stringType)), List.<JCAnnotation>nil()); return mdb.parameter(pdb); }
public JCNewClass build() { // Generate a subclass of Callable ListBuffer<JCTree> classBody = new ListBuffer<JCTree>(); int numParams = paramLists.getParameters().size(); int minimumParams = 0; for (Parameter p : paramLists.getParameters()) { if (p.isDefaulted() || p.isSequenced()) break; minimumParams++; } boolean isVariadic = minimumParams != numParams; if (parameterListTree != null) { // generate a method for each defaulted param for (Tree.Parameter p : parameterListTree.getParameters()) { if (p.getDefaultArgument() != null || p.getDeclarationModel().isSequenced()) { MethodDefinitionBuilder methodBuilder = gen.classGen().makeParamDefaultValueMethod(false, null, parameterListTree, p); classBody.append(methodBuilder.build()); } } } // collect each parameter type from the callable type model rather than the declarations to get // them all bound java.util.List<ProducedType> parameterTypes = new ArrayList<ProducedType>(numParams); if (forwardCallTo != null) { for (int i = 0; i < numParams; i++) parameterTypes.add(gen.getParameterTypeOfCallable(typeModel, i)); } else { // get them from our declaration for (Parameter p : paramLists.getParameters()) parameterTypes.add(p.getType()); } // now generate a method for each supported minimum number of parameters below 4 // which delegates to the $call$typed method if required for (int i = minimumParams, max = Math.min(numParams, 4); i < max; i++) { classBody.append(makeDefaultedCall(i, isVariadic, parameterTypes)); } // generate the $call method for the max number of parameters, // which delegates to the $call$typed method if required classBody.append(makeDefaultedCall(numParams, isVariadic, parameterTypes)); // generate the $call$typed method if required if (isVariadic && forwardCallTo == null) classBody.append(makeCallTypedMethod(body, parameterTypes)); JCClassDecl classDef = gen.make().AnonymousClassDef(gen.make().Modifiers(0), classBody.toList()); JCNewClass instance = gen.make() .NewClass( null, null, gen.makeJavaType(typeModel, JT_EXTENDS | JT_CLASS_NEW), List.<JCExpression>of(gen.make().Literal(typeModel.getProducedTypeName(true))), classDef); return instance; }
private AttributeDefinitionBuilder( AbstractTransformer owner, TypedDeclaration attrType, String javaClassName, String attrName, String fieldName, boolean toplevel) { int typeFlags = 0; ProducedTypedReference typedRef = owner.getTypedReference(attrType); ProducedTypedReference nonWideningTypedRef = owner.nonWideningTypeDecl(typedRef); ProducedType nonWideningType = owner.nonWideningType(typedRef, nonWideningTypedRef); if (!CodegenUtil.isUnBoxed(nonWideningTypedRef.getDeclaration())) { typeFlags |= AbstractTransformer.JT_NO_PRIMITIVES; } this.attrType = owner.makeJavaType(nonWideningType, typeFlags); this.attrTypeRaw = owner.makeJavaType(nonWideningType, AbstractTransformer.JT_RAW); this.owner = owner; this.javaClassName = javaClassName; this.attrName = attrName; this.fieldName = fieldName; this.toplevel = toplevel; // Make sure we use the declaration for building the getter/setter names, as we might be trying // to // override a JavaBean property with an "isFoo" getter, or non-Ceylon casing, and we have to // respect that. getterBuilder = MethodDefinitionBuilder.method2(owner, Naming.getGetterName(attrType)) .block(generateDefaultGetterBlock()) .isOverride(attrType.isActual()) .annotations(owner.makeAtAnnotations(attrType.getAnnotations())) .resultType(this.attrType, attrType); setterBuilder = MethodDefinitionBuilder.method2(owner, Naming.getSetterName(attrType)) .block(generateDefaultSetterBlock()) // only actual if the superclass is also variable .isOverride( attrType.isActual() && ((TypedDeclaration) attrType.getRefinedDeclaration()).isVariable()) .parameter( Flags.FINAL, attrName, attrType, nonWideningTypedRef.getDeclaration(), nonWideningType, 0); }
private void generateValueConstructor(MethodDefinitionBuilder methodDefinitionBuilder) { ParameterDefinitionBuilder paramBuilder = ParameterDefinitionBuilder.instance(owner, fieldName).type(attrType, null); JCTree.JCAssign init = owner .make() .Assign( owner.makeQualIdent(owner.makeUnquotedIdent("this"), fieldName), owner.makeUnquotedIdent(fieldName)); methodDefinitionBuilder.parameter(paramBuilder).body(owner.make().Exec(init)); }
/** * Appends to <tt>defs</tt> the definitions that would go into the class generated by {@link * #build()} * * @param defs a {@link ListBuffer} to which the definitions will be appended. */ public void appendDefinitionsTo(ListBuffer<JCTree> defs) { if (hasField) { defs.append(generateField()); if (variableInit != null) defs.append(generateFieldInit()); } if (readable) { getterBuilder.modifiers(getGetSetModifiers()); getterBuilder.noAnnotations(noAnnotations); defs.append(getterBuilder.build()); } if (writable) { setterBuilder.modifiers(getGetSetModifiers()); setterBuilder.noAnnotations(noAnnotations); defs.append(setterBuilder.build()); } }
private JCTree makeCallTypedMethod( List<JCStatement> body, java.util.List<ProducedType> parameterTypes) { // make the method MethodDefinitionBuilder methodBuilder = MethodDefinitionBuilder.method(gen, false, Naming.getCallableTypedMethodName()); methodBuilder.modifiers(Flags.PRIVATE); ProducedType returnType = gen.getReturnTypeOfCallable(typeModel); methodBuilder.resultType(gen.makeJavaType(returnType, JT_NO_PRIMITIVES), null); // add all parameters int i = 0; for (Parameter param : paramLists.getParameters()) { ParameterDefinitionBuilder parameterBuilder = ParameterDefinitionBuilder.instance(gen, param.getName()); JCExpression paramType = gen.makeJavaType(parameterTypes.get(i)); parameterBuilder.type(paramType, null); methodBuilder.parameter(parameterBuilder); i++; } // Return the call result, or null if a void method methodBuilder.body(body); return methodBuilder.build(); }
private JCTree makeCallMethod(List<JCStatement> body, int numParams) { MethodDefinitionBuilder callMethod = MethodDefinitionBuilder.callable(gen); callMethod.isOverride(true); callMethod.modifiers(Flags.PUBLIC); ProducedType returnType = gen.getReturnTypeOfCallable(typeModel); callMethod.resultType(gen.makeJavaType(returnType, JT_NO_PRIMITIVES), null); // Now append formal parameters switch (numParams) { case 3: callMethod.parameter(makeCallableCallParam(0, numParams - 3)); // fall through case 2: callMethod.parameter(makeCallableCallParam(0, numParams - 2)); // fall through case 1: callMethod.parameter(makeCallableCallParam(0, numParams - 1)); break; case 0: break; default: // use varargs callMethod.parameter(makeCallableCallParam(Flags.VARARGS, 0)); } // Return the call result, or null if a void method callMethod.body(body); return callMethod.build(); }
/** * Marks the getter/setter methods as not actual. In general <tt>actual</tt> is derived from the * model while creating this builder so it will be correct. You can only disable this computation. * Enabling <tt>actual</tt> would otherwise depend on the question of whether the getter is or not * actual which may be different for the setter if the refined decl is not variable so we'd need * two parameters. */ public AttributeDefinitionBuilder notActual() { getterBuilder.isOverride(false); setterBuilder.isOverride(false); return this; }
/** * Sets the code block to use for the generated setter. If no setter is generated the code block * will be silently ignored. * * @param setterBlock a code block * @return this instance for method chaining */ public AttributeDefinitionBuilder setterBlock(JCTree.JCBlock setterBlock) { setterBuilder.block(setterBlock); return this; }
/** * Sets the code block to use for the generated getter. If no getter is generated the code block * will be silently ignored. * * @param getterBlock a code block * @return this instance for method chaining */ public AttributeDefinitionBuilder getterBlock(JCTree.JCBlock getterBlock) { skipField(); getterBuilder.block(getterBlock); return this; }
public AttributeDefinitionBuilder isFormal(boolean isFormal) { getterBuilder.isAbstract(isFormal); setterBuilder.isAbstract(isFormal); return this; }