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);
  }