use of com.redhat.ceylon.model.typechecker.model.TypedReference in project ceylon-compiler by ceylon.
the class ClassTransformer method producedTypeParameterBounds.
private java.util.List<java.util.List<Type>> producedTypeParameterBounds(final Reference typedMember, Generic subMethod) {
java.util.List<java.util.List<Type>> producedTypeParameterBounds = new ArrayList<java.util.List<Type>>(subMethod.getTypeParameters().size());
for (TypeParameter tp : subMethod.getTypeParameters()) {
java.util.List<Type> satisfiedTypes = tp.getType().getSatisfiedTypes();
ArrayList<Type> bounds = new ArrayList<>(satisfiedTypes.size());
for (Type bound : satisfiedTypes) {
if (typedMember instanceof Type) {
bounds.add(bound.substitute((Type) typedMember));
} else if (typedMember instanceof TypedReference) {
bounds.add(bound.substitute((TypedReference) typedMember));
}
}
producedTypeParameterBounds.add(bounds);
}
return producedTypeParameterBounds;
}
use of com.redhat.ceylon.model.typechecker.model.TypedReference in project ceylon-compiler by ceylon.
the class ClassTransformer method transformClassParameterType.
/**
* Transforms the type of the given class parameter
* @param decl
* @return
*/
JCExpression transformClassParameterType(Parameter parameter) {
FunctionOrValue decl = parameter.getModel();
if (!(decl.getContainer() instanceof Class)) {
throw new BugException("expected parameter of Class");
}
JCExpression type;
FunctionOrValue attr = decl;
if (!Decl.isTransient(attr)) {
TypedReference typedRef = getTypedReference(attr);
TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
Type paramType = nonWideningType(typedRef, nonWideningTypedRef);
type = makeJavaType(nonWideningTypedRef.getDeclaration(), paramType, 0);
} else {
Type paramType = decl.getType();
type = makeJavaType(decl, paramType, 0);
}
return type;
}
use of com.redhat.ceylon.model.typechecker.model.TypedReference in project ceylon-compiler by ceylon.
the class ClassTransformer method transform.
public void transform(AttributeDeclaration decl, ClassDefinitionBuilder classBuilder) {
final Value model = decl.getDeclarationModel();
boolean lazy = decl.getSpecifierOrInitializerExpression() instanceof LazySpecifierExpression;
boolean useField = Strategy.useField(model) && !lazy;
String attrName = decl.getIdentifier().getText();
// Only a non-formal or a concrete-non-lazy attribute has a corresponding field
// and if a captured class parameter exists with the same name we skip this part as well
Parameter parameter = CodegenUtil.findParamForDecl(decl);
boolean createField = Strategy.createField(parameter, model) && !lazy;
boolean concrete = Decl.withinInterface(decl) && decl.getSpecifierOrInitializerExpression() != null;
if (!lazy && (concrete || (!Decl.isFormal(decl) && createField))) {
TypedReference typedRef = getTypedReference(model);
TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
if (Decl.isIndirect(decl)) {
attrName = Naming.getAttrClassName(model, 0);
nonWideningType = getGetterInterfaceType(model);
}
JCExpression initialValue = null;
if (decl.getSpecifierOrInitializerExpression() != null) {
Value declarationModel = model;
initialValue = expressionGen().transformExpression(decl.getSpecifierOrInitializerExpression().getExpression(), CodegenUtil.getBoxingStrategy(declarationModel), nonWideningType);
}
int flags = 0;
if (!CodegenUtil.isUnBoxed(nonWideningTypedRef.getDeclaration())) {
flags |= JT_NO_PRIMITIVES;
}
JCExpression type = makeJavaType(nonWideningType, flags);
int modifiers = (useField) ? transformAttributeFieldDeclFlags(decl) : transformLocalDeclFlags(decl);
// does it in those cases)
if (parameter == null || parameter.isHidden()) {
if (concrete) {
classBuilder.getCompanionBuilder((TypeDeclaration) model.getContainer()).field(modifiers, attrName, type, initialValue, !useField);
} else {
List<JCAnnotation> annos = makeAtIgnore().prependList(expressionGen().transformAnnotations(OutputElement.FIELD, decl));
if (classBuilder.hasDelegatingConstructors()) {
annos = annos.prependList(makeAtNoInitCheck());
}
// fields should be ignored, they are accessed by the getters
classBuilder.field(modifiers, attrName, type, initialValue, !useField, annos);
if (model.isLate() && CodegenUtil.needsLateInitField(model, typeFact())) {
classBuilder.field(PRIVATE | Flags.VOLATILE | Flags.TRANSIENT, Naming.getInitializationFieldName(attrName), make().Type(syms().booleanType), make().Literal(false), false, makeAtIgnore());
}
}
}
// A shared attribute might be initialized in a for statement, so
// we might need a def-assignment subst for it
List<JCAnnotation> annots = makeJavaTypeAnnotations(decl.getDeclarationModel());
JCStatement outerSubs = statementGen().openOuterSubstitutionIfNeeded(decl.getDeclarationModel(), model.getType(), annots, 0);
if (outerSubs != null) {
classBuilder.getInitBuilder().init(outerSubs);
}
}
boolean withinInterface = Decl.withinInterface(decl);
if (useField || withinInterface || lazy) {
if (!withinInterface || model.isShared()) {
// Generate getter in main class or interface (when shared)
classBuilder.attribute(makeGetter(decl, false, lazy));
}
if (withinInterface && lazy) {
// Generate getter in companion class
classBuilder.getCompanionBuilder((Interface) decl.getDeclarationModel().getContainer()).attribute(makeGetter(decl, true, lazy));
}
if (Decl.isVariable(decl) || Decl.isLate(decl)) {
if (!withinInterface || model.isShared()) {
// Generate setter in main class or interface (when shared)
classBuilder.attribute(makeSetter(decl, false, lazy));
}
if (withinInterface && lazy) {
// Generate setter in companion class
classBuilder.getCompanionBuilder((Interface) decl.getDeclarationModel().getContainer()).attribute(makeSetter(decl, true, lazy));
}
}
}
}
use of com.redhat.ceylon.model.typechecker.model.TypedReference in project ceylon-compiler by ceylon.
the class ClassTransformer method makeAttributeForValueParameter.
private void makeAttributeForValueParameter(ClassDefinitionBuilder classBuilder, Tree.Parameter parameterTree, Tree.TypedDeclaration memberTree) {
Parameter decl = parameterTree.getParameterModel();
if (!(decl.getModel() instanceof Value)) {
return;
}
final Value value = (Value) decl.getModel();
if (decl.getDeclaration() instanceof Constructor) {
classBuilder.field(PUBLIC | FINAL, decl.getName(), makeJavaType(decl.getType()), null, false, expressionGen().transformAnnotations(OutputElement.FIELD, memberTree));
classBuilder.getInitBuilder().init(make().Exec(make().Assign(naming.makeQualIdent(naming.makeThis(), decl.getName()), naming.makeName(value, Naming.NA_IDENT))));
} else if (parameterTree instanceof Tree.ValueParameterDeclaration && (value.isShared() || value.isCaptured())) {
makeFieldForParameter(classBuilder, decl, memberTree);
AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.getter(this, decl.getName(), decl.getModel());
adb.modifiers(classGen().transformAttributeGetSetDeclFlags(decl.getModel(), false));
adb.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, memberTree));
classBuilder.attribute(adb);
if (value.isVariable()) {
AttributeDefinitionBuilder setter = AttributeDefinitionBuilder.setter(this, decl.getName(), decl.getModel());
setter.modifiers(classGen().transformAttributeGetSetDeclFlags(decl.getModel(), false));
//setter.userAnnotations(expressionGen().transform(AnnotationTarget.SETTER, memberTree.getAnnotationList()));
classBuilder.attribute(setter);
}
} else if (decl.isHidden() && // TODO Isn't this always true here? We know this is a parameter to a Class
(decl.getDeclaration() instanceof TypeDeclaration)) {
Declaration member = CodegenUtil.findMethodOrValueForParam(decl);
if (Strategy.createField(decl, (Value) member)) {
// The field itself is created by when we transform the AttributeDeclaration
// but it has to be initialized here so all the fields are initialized in parameter order
JCExpression parameterExpr = makeUnquotedIdent(Naming.getAliasedParameterName(decl));
TypedReference typedRef = getTypedReference(value);
TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
Type paramType = nonWideningType(typedRef, nonWideningTypedRef);
if (!paramType.isExactly(decl.getType())) {
// The parameter type follows normal erasure rules, not affected by inheritance
// but the attribute respects non-widening rules, so we may need to cast
// the parameter to the field type (see #1728)
parameterExpr = make().TypeCast(classGen().transformClassParameterType(decl), parameterExpr);
}
classBuilder.getInitBuilder().init(make().Exec(make().Assign(naming.makeQualifiedName(naming.makeThis(), value, Naming.NA_IDENT), parameterExpr)));
}
}
}
Aggregations