private JCExpression getTypedParameter(
     Parameter param, int argIndex, boolean varargs, java.util.List<ProducedType> parameterTypes) {
   JCExpression argExpr;
   if (!varargs) {
     // The Callable has overridden one of the non-varargs call()
     // methods
     argExpr = gen.make().Ident(makeParamName(gen, argIndex));
   } else {
     // The Callable has overridden the varargs call() method
     // so we need to index into the varargs array
     argExpr =
         gen.make().Indexed(gen.make().Ident(makeParamName(gen, 0)), gen.make().Literal(argIndex));
   }
   // make sure we unbox it if required
   argExpr =
       gen.expressionGen()
           .applyErasureAndBoxing(
               argExpr,
               gen.typeFact().getObjectDeclaration().getType(), // it came in as Object
               true, // it's completely erased
               true, // it came in boxed
               CodegenUtil.getBoxingStrategy(param), // see if we need to box
               parameterTypes.get(argIndex), // see what type we need
               0); // no flags
   return argExpr;
 }
 @Nullable
 private FunctionDescriptor getDeclaredMember(
     @NotNull String name,
     @NotNull ClassDescriptor returnedClassifier,
     @NotNull ClassDescriptor... valueParameterClassifiers) {
   return CodegenUtil.getDeclaredFunctionByRawSignature(
       classDescriptor, Name.identifier(name), returnedClassifier, valueParameterClassifiers);
 }
 private JCExpression paramType(
     TypedDeclaration nonWideningDecl, ProducedType nonWideningType, int flags) {
   if (gen.typeFact().isUnion(nonWideningType) || gen.typeFact().isIntersection(nonWideningType)) {
     final TypeDeclaration refinedTypeDecl =
         ((TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(nonWideningDecl))
             .getType()
             .getDeclaration();
     if (refinedTypeDecl instanceof TypeParameter
         && !refinedTypeDecl.getSatisfiedTypes().isEmpty()) {
       nonWideningType = refinedTypeDecl.getSatisfiedTypes().get(0);
     }
   }
   JCExpression type = gen.makeJavaType(nonWideningDecl, nonWideningType, flags);
   return type;
 }
  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);
  }
 public MethodDefinitionBuilder parameter(Parameter param, int flags) {
   String paramName = param.getName();
   String aliasedName = paramName;
   MethodOrValue mov = CodegenUtil.findMethodOrValueForParam(param);
   int mods = 0;
   if (!(mov instanceof Value) || !mov.isVariable() || mov.isCaptured()) {
     mods |= FINAL;
   }
   if (mov instanceof Method || mov instanceof Value && mov.isVariable() && mov.isCaptured()) {
     aliasedName = Naming.getAliasedParameterName(param);
   }
   TypedDeclaration nonWideningDecl;
   ProducedType nonWideningType;
   if (mov instanceof Value) {
     ProducedTypedReference typedRef = gen.getTypedReference(mov);
     ProducedTypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
     nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef);
     nonWideningDecl = nonWideningTypedRef.getDeclaration();
   } else {
     nonWideningType = param.getType();
     nonWideningDecl = param;
   }
   return parameter(mods, paramName, aliasedName, param, nonWideningDecl, nonWideningType, flags);
 }
 private JCTree makeDefaultedCall(
     int i, boolean isVariadic, java.util.List<ProducedType> parameterTypes) {
   // collect every parameter
   int a = 0;
   ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
   for (Parameter param : paramLists.getParameters()) {
     // don't read default parameter values for forwarded calls
     if (forwardCallTo != null && i == a) break;
     // read the value
     JCExpression paramExpression = getTypedParameter(param, a, i > 3, parameterTypes);
     JCExpression varInitialExpression;
     if (param.isDefaulted() || param.isSequenced()) {
       if (i > 3) {
         // must check if it's defined
         JCExpression test =
             gen.make()
                 .Binary(JCTree.GT, gen.makeSelect(getParamName(0), "length"), gen.makeInteger(a));
         JCExpression elseBranch = makeDefaultValueCall(param, a);
         varInitialExpression = gen.make().Conditional(test, paramExpression, elseBranch);
       } else if (a >= i) {
         // get its default value because we don't have it
         varInitialExpression = makeDefaultValueCall(param, a);
       } else {
         // we must have it
         varInitialExpression = paramExpression;
       }
     } else {
       varInitialExpression = paramExpression;
     }
     // store it in a local var
     JCStatement var =
         gen.make()
             .VarDef(
                 gen.make().Modifiers(Flags.FINAL),
                 gen.naming.makeUnquotedName(getCallableTempVarName(param)),
                 gen.makeJavaType(
                     parameterTypes.get(a),
                     CodegenUtil.isUnBoxed(param) ? 0 : gen.JT_NO_PRIMITIVES),
                 varInitialExpression);
     stmts.append(var);
     a++;
   }
   if (forwardCallTo != null) {
     InvocationBuilder invocationBuilder =
         InvocationBuilder.forCallableInvocation(gen, forwardCallTo, paramLists, i);
     boolean prevCallableInv = gen.expressionGen().withinCallableInvocation(true);
     try {
       stmts.append(gen.make().Return(invocationBuilder.build()));
     } finally {
       gen.expressionGen().withinCallableInvocation(prevCallableInv);
     }
   } else if (isVariadic) {
     // chain to n param typed method
     List<JCExpression> args = List.nil();
     // pass along the parameters
     for (a = paramLists.getParameters().size() - 1; a >= 0; a--) {
       Parameter param = paramLists.getParameters().get(a);
       args = args.prepend(gen.makeUnquotedIdent(getCallableTempVarName(param)));
     }
     JCMethodInvocation chain =
         gen.make().Apply(null, gen.makeUnquotedIdent(Naming.getCallableTypedMethodName()), args);
     stmts.append(gen.make().Return(chain));
   } else {
     // insert the method body directly
     stmts.appendList(this.body);
   }
   List<JCStatement> body = stmts.toList();
   return makeCallMethod(body, i);
 }