use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class ClassTransformer method addMissingUnrefinedMembers.
/**
* Recover from members not being refined in the class hierarchy
* by generating a stub method that throws.
*/
private void addMissingUnrefinedMembers(Node def, Class classModel, ClassDefinitionBuilder classBuilder) {
for (Reference unrefined : classModel.getUnimplementedFormals()) {
// classModel.getMember(memberName, null, false);
Declaration formalMember = unrefined.getDeclaration();
String errorMessage = "formal member '" + formalMember.getName() + "' of '" + ((TypeDeclaration) formalMember.getContainer()).getName() + "' not implemented in class hierarchy";
java.util.List<Type> params = new java.util.ArrayList<Type>();
for (TypeParameter tp : formalMember.getTypeParameters()) {
params.add(tp.getType());
}
if (formalMember instanceof Value) {
addRefinedThrowerAttribute(classBuilder, errorMessage, def, classModel, (Value) formalMember);
} else if (formalMember instanceof Function) {
addRefinedThrowerMethod(classBuilder, errorMessage, classModel, (Function) formalMember);
} else if (formalMember instanceof Class && formalMember.isClassMember()) {
addRefinedThrowerInstantiatorMethod(classBuilder, errorMessage, classModel, (Class) formalMember, unrefined);
}
// formal member class of interface handled in
// makeDelegateToCompanion()
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class ClassTransformer method serializationGet.
private void serializationGet(Class model, ClassDefinitionBuilder classBuilder) {
MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$get$.toString());
mdb.isOverride(true);
mdb.ignoreModelAnnotations();
mdb.modifiers(PUBLIC);
ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(this, Unfix.reference.toString());
pdb.modifiers(FINAL);
pdb.type(new TransformedType(make().Type(syms().ceylonReachableReferenceType), null, makeAtNonNull()));
mdb.parameter(pdb);
mdb.resultType(new TransformedType(make().Type(syms().objectType), null, makeAtNonNull()));
/*
* public void $get$(Object reference, Object instance) {
* switch((String)reference) {
* case ("attr1")
* return ...;
* // ... other fields of this class
* case ("lateAttr1")
* if (!$init$lateAttr1) {
* return ceylon.language.serialization.uninitializedLateValue.get_();
* }
* return ...;
* case (null):
* return Outer.this;
* default:
* return super.get(reference);
*/
ListBuffer<JCCase> cases = new ListBuffer<JCCase>();
boolean[] needsLookup = new boolean[] { false };
for (Declaration member : model.getMembers()) {
if (hasField(member)) {
if (member instanceof Function)
// TODO: This class is not serializable
continue;
ListBuffer<JCStatement> caseStmts = new ListBuffer<JCStatement>();
if (member instanceof Value && ((Value) member).isLate()) {
// TODO this should be encapsulated so the ADB and this
// code can just call something common
JCExpression test = AttributeDefinitionBuilder.field(this, null, member.getName(), (Value) member, false).buildUninitTest();
if (test != null) {
caseStmts.add(make().If(test, make().Return(makeLanguageSerializationValue("uninitializedLateValue")), null));
}
}
caseStmts.add(make().Return(makeSerializationGetter((Value) member)));
cases.add(make().Case(make().Literal(member.getQualifiedNameString()), caseStmts.toList()));
}
}
SyntheticName reference = naming.synthetic(Unfix.reference);
ListBuffer<JCStatement> defaultCase = new ListBuffer<JCStatement>();
if (extendsSerializable(model)) {
// super.get(reference);
defaultCase.add(make().Return(make().Apply(null, naming.makeQualIdent(naming.makeSuper(), Unfix.$get$.toString()), List.<JCExpression>of(reference.makeIdent()))));
} else {
// throw (or pass to something else to throw, based on policy)
defaultCase.add(make().Throw(make().NewClass(null, null, naming.makeQuotedFQIdent("java.lang.RuntimeException"), List.<JCExpression>of(make().Literal("unknown attribute")), null)));
}
cases.add(make().Case(null, defaultCase.toList()));
ListBuffer<JCStatement> stmts = new ListBuffer<JCStatement>();
if (needsLookup[0]) {
// if we needed to use a lookup object to reset final fields,
// prepend that variable
stmts.add(makeVar(FINAL, "lookup", naming.makeQualIdent(make().Type(syms().methodHandlesType), "Lookup"), make().Apply(null, naming.makeQuotedFQIdent("java.lang.invoke.MethodHandles.lookup"), List.<JCExpression>nil())));
}
JCSwitch swtch = make().Switch(make().Apply(null, naming.makeSelect(make().Apply(null, naming.makeSelect(make().TypeCast(make().Type(syms().ceylonMemberType), reference.makeIdent()), "getAttribute"), List.<JCExpression>nil()), "getQualifiedName"), List.<JCExpression>nil()), cases.toList());
if (model.isMember() && !model.getExtendedType().getDeclaration().isMember()) {
stmts.add(make().If(make().TypeTest(reference.makeIdent(), make().Type(syms().ceylonOuterType)), make().Return(expressionGen().makeOuterExpr(((TypeDeclaration) model.getContainer()).getType())), swtch));
} else {
stmts.add(swtch);
}
mdb.body(stmts.toList());
classBuilder.method(mdb);
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class ClassTransformer method transformTypeParameters.
<T> void transformTypeParameters(GenericBuilder<T> classBuilder, Declaration model) {
java.util.List<TypeParameter> typeParameters = Strategy.getEffectiveTypeParameters(model);
if (typeParameters != null) {
for (TypeParameter param : typeParameters) {
Scope cont = param.getContainer();
if (cont instanceof TypeDeclaration) {
TypeDeclaration container = (TypeDeclaration) cont;
classBuilder.typeParameter(param);
if (classBuilder instanceof ClassDefinitionBuilder) {
// Copy to the companion too
ClassDefinitionBuilder companionBuilder = ((ClassDefinitionBuilder) classBuilder).getCompanionBuilder(container);
if (companionBuilder != null)
companionBuilder.typeParameter(param);
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class ClassTransformer method addAtContainer.
private void addAtContainer(ClassDefinitionBuilder classBuilder, TypeDeclaration model) {
Scope scope = Decl.getNonSkippedContainer((Scope) model);
Scope declarationScope = Decl.getFirstDeclarationContainer((Scope) model);
boolean inlineObjectInToplevelAttr = Decl.isTopLevelObjectExpressionType(model);
if (scope == null || (scope instanceof Package && !inlineObjectInToplevelAttr) && scope == declarationScope)
return;
if (scope instanceof ClassOrInterface && scope == declarationScope && !inlineObjectInToplevelAttr && // we do not check for types inside initialiser section which are private and not captured because we treat them as members
!(model instanceof Interface && Decl.hasLocalNotInitializerAncestor(model))) {
ClassOrInterface container = (ClassOrInterface) scope;
List<JCAnnotation> atContainer = makeAtContainer(container.getType(), model.isStatic());
classBuilder.annotations(atContainer);
} else {
if (model instanceof Interface)
classBuilder.annotations(makeLocalContainerPath((Interface) model));
Declaration declarationContainer = getDeclarationContainer(model);
classBuilder.annotations(makeAtLocalDeclaration(model.getQualifier(), declarationContainer == null));
}
}
use of org.eclipse.ceylon.model.typechecker.model.TypeDeclaration in project ceylon by eclipse.
the class ClassTransformer method transformClassAlias.
private void transformClassAlias(final Tree.ClassDeclaration def, ClassDefinitionBuilder classBuilder) {
ClassAlias model = (ClassAlias) def.getDeclarationModel();
Type aliasedClass = model.getExtendedType();
TypeDeclaration classOrCtor = def.getClassSpecifier().getType().getDeclarationModel();
while (classOrCtor instanceof ClassAlias) {
classOrCtor = ((ClassAlias) classOrCtor).getConstructor();
}
classBuilder.annotations(makeAtAlias(aliasedClass, classOrCtor instanceof Constructor ? (Constructor) classOrCtor : null));
classBuilder.isAlias(true);
MethodDefinitionBuilder instantiator = transformClassAliasInstantiator(def, model, aliasedClass);
ClassDefinitionBuilder cbInstantiator = null;
switch(Strategy.defaultParameterMethodOwner(model)) {
case STATIC:
cbInstantiator = classBuilder;
break;
case OUTER:
cbInstantiator = classBuilder.getContainingClassBuilder();
break;
case OUTER_COMPANION:
cbInstantiator = classBuilder.getContainingClassBuilder().getCompanionBuilder(ModelUtil.getClassOrInterfaceContainer(model, true));
break;
default:
throw BugException.unhandledEnumCase(Strategy.defaultParameterMethodOwner(model));
}
cbInstantiator.method(instantiator);
}
Aggregations