use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class MethodOrValueReferenceVisitor method visit.
@Override
public void visit(Tree.ClassDefinition that) {
if (!that.getDeclarationModel().hasConstructors()) {
boolean cs = enterCapturingScope();
super.visit(that);
exitCapturingScope(cs);
} else {
// super special case for unshared members when we have constructors
if (!declaration.isCaptured() && declaration instanceof FunctionOrValue && declaration.isClassMember()) {
Map<Constructor, ConstructorPlan> constructorPlans = new HashMap<Constructor, ConstructorPlan>();
List<Tree.Statement> statements = new ArrayList<>(that.getClassBody().getStatements().size());
// find every constructor, and build a model of how they delegate
for (Tree.Statement stmt : that.getClassBody().getStatements()) {
if (stmt instanceof Tree.Constructor) {
Tree.Constructor ctor = (Tree.Constructor) stmt;
// build a new plan for it
ConstructorPlan plan = new ConstructorPlan();
plan.constructor = ctor;
constructorPlans.put(ctor.getConstructor(), plan);
// find every constructor which delegates to another constructor
if (ctor.getDelegatedConstructor() != null && ctor.getDelegatedConstructor().getInvocationExpression() != null) {
if (ctor.getDelegatedConstructor().getInvocationExpression().getPrimary() instanceof Tree.ExtendedTypeExpression) {
Tree.ExtendedTypeExpression ete = (Tree.ExtendedTypeExpression) ctor.getDelegatedConstructor().getInvocationExpression().getPrimary();
// are we delegating to a constructor (not a supertype) of the same class (this class)?
if (Decl.isConstructor(ete.getDeclaration()) && ModelUtil.getConstructedClass(ete.getDeclaration()).equals(that.getDeclarationModel())) {
// remember the delegation
Constructor delegate = ModelUtil.getConstructor(ete.getDeclaration());
ConstructorPlan delegatePlan = constructorPlans.get(delegate);
plan.delegate = delegatePlan;
// mark the delegate as delegated
delegatePlan.isDelegate = true;
// we have all the statements before us and after our delegate
plan.before.addAll(delegatePlan.after);
}
}
}
// if we have no delegate, we start with every common statement
if (plan.delegate == null)
plan.before.addAll(statements);
// also add all the constructor's statements
if (ctor.getBlock() != null) {
plan.before.addAll(ctor.getBlock().getStatements());
}
} else {
statements.add(stmt);
// make sure all existing constructors get this statement too
for (ConstructorPlan constructorPlan : constructorPlans.values()) constructorPlan.after.add(stmt);
}
}
// try every constructor plan and see if it's used in two methods
for (ConstructorPlan constructorPlan : constructorPlans.values()) {
visitConstructorPlan(constructorPlan);
// are we done?
if (declaration.isCaptured())
break;
}
}
// do regular capturing after that (for members), if required
if (!declaration.isCaptured()) {
boolean cs = enterCapturingScope();
super.visit(that);
exitCapturingScope(cs);
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class AbstractModelLoader method addValue.
private Value addValue(ClassOrInterface klass, String ceylonName, FieldMirror fieldMirror, boolean isCeylon, boolean isNativeHeader) {
// make sure it's a FieldValue so we can figure it out in the backend
Value value = new FieldValue(fieldMirror.getName());
value.setContainer(klass);
value.setScope(klass);
// use the name annotation if present (used by Java arrays)
String nameAnnotation = getAnnotationStringValue(fieldMirror, CEYLON_NAME_ANNOTATION);
value.setName(nameAnnotation != null ? nameAnnotation : ceylonName);
value.setUnit(klass.getUnit());
value.setShared(fieldMirror.isPublic() || fieldMirror.isProtected() || fieldMirror.isDefaultAccess());
value.setProtectedVisibility(fieldMirror.isProtected());
value.setPackageVisibility(fieldMirror.isDefaultAccess());
value.setStatic(fieldMirror.isStatic());
setDeclarationAliases(value, fieldMirror);
setDeclarationRestrictions(value, fieldMirror);
// field can't be abstract or interface, so not formal
// can we override fields? good question. Not really, but from an external point of view?
// FIXME: figure this out: (default)
// FIXME: for the same reason, can it be an overriding field? (actual)
value.setVariable(!fieldMirror.isFinal());
// figure out if it's an enum subtype in a final static field
if (fieldMirror.getType().getKind() == TypeKind.DECLARED && fieldMirror.getType().getDeclaredClass() != null && fieldMirror.getType().getDeclaredClass().isEnum() && fieldMirror.isFinal() && fieldMirror.isStatic())
value.setEnumValue(true);
Module module = ModelUtil.getModuleContainer(klass);
Type type = obtainType(fieldMirror.getType(), fieldMirror, klass, module, "field '" + value.getName() + "'", klass);
if (type.isCached()) {
type = type.clone();
}
if (value.isEnumValue()) {
Constructor enumValueType = new Constructor();
enumValueType.setJavaEnum(true);
enumValueType.setExtendedType(type);
Scope scope = value.getContainer();
enumValueType.setContainer(scope);
enumValueType.setScope(scope);
enumValueType.setDeprecated(value.isDeprecated());
enumValueType.setName(value.getName());
enumValueType.setUnit(value.getUnit());
enumValueType.setStatic(value.isStatic());
value.setType(enumValueType.getType());
value.setUncheckedNullType(false);
} else {
NullStatus nullPolicy = getUncheckedNullPolicy(isCeylon, fieldMirror.getType(), fieldMirror);
switch(nullPolicy) {
case Optional:
if (!isCeylon) {
type = makeOptionalTypePreserveUnderlyingType(type, module);
}
break;
case UncheckedNull:
value.setUncheckedNullType(true);
break;
}
value.setType(type);
}
type.setRaw(isRaw(module, fieldMirror.getType()));
markUnboxed(value, null, fieldMirror.getType());
markSmall(value, fieldMirror.getType());
markTypeErased(value, fieldMirror, fieldMirror.getType());
markUntrustedType(value, fieldMirror, fieldMirror.getType());
value.setDeprecated(isDeprecated(fieldMirror));
setAnnotations(value, fieldMirror, isNativeHeader);
klass.addMember(value);
ModelUtil.setVisibleScope(value);
return value;
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class AbstractModelLoader method addConstructor.
private Constructor addConstructor(Class klass, ClassMirror classMirror, MethodMirror ctor, boolean isNativeHeader) {
boolean isCeylon = classMirror.getAnnotation(CEYLON_CEYLON_ANNOTATION) != null;
Constructor constructor = new Constructor();
constructor.setName(getCtorName(ctor));
constructor.setContainer(klass);
constructor.setScope(klass);
constructor.setUnit(klass.getUnit());
constructor.setAbstract(ctor.getAnnotation(CEYLON_LANGUAGE_ABSTRACT_ANNOTATION) != null);
constructor.setExtendedType(klass.getType());
setNonLazyDeclarationProperties(constructor, ctor, ctor, classMirror, isCeylon);
setAnnotations(constructor, ctor, isNativeHeader);
klass.addMember(constructor);
return constructor;
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.Enumerated that) {
Constructor e = that.getEnumerated();
checkDelegatedConstructor(that.getDelegatedConstructor(), e, that);
TypeDeclaration occ = enterConstructorDelegation(e);
Declaration od = beginReturnDeclaration(e);
Tree.Type rt = beginReturnScope(fakeVoid(that));
super.visit(that);
endReturnScope(rt, null);
endReturnDeclaration(od);
endConstructorDelegation(occ);
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class ExpressionVisitor method visitQualifiedTypeExpression.
private void visitQualifiedTypeExpression(Tree.QualifiedTypeExpression that, Type receivingType, TypeDeclaration memberType, List<Type> typeArgs, Tree.TypeArguments tal) {
checkMemberOperator(receivingType, that);
if (memberType instanceof Constructor) {
that.addError("constructor is not a type: '" + memberType.getName(unit) + "' is a constructor");
}
Type receiverType = accountForStaticReferenceReceiverType(that, unwrap(receivingType, that));
if (acceptsTypeArguments(memberType, receiverType, typeArgs, tal, that) || true) {
Type type = receiverType.getTypeMember(memberType, typeArgs);
that.setTarget(type);
Type fullType = type.getFullType(wrap(type, receivingType, that));
if (!dynamic && !that.getStaticMethodReference() && memberType instanceof Class && !isAbstraction(memberType) && isTypeUnknown(fullType) && !hasError(that)) {
// this occurs with an ambiguous reference
// to a member of an intersection type
String rtname = receiverType.getDeclaration().getName(unit);
that.addError("could not determine type of member class reference: '" + memberType.getName(unit) + "' of '" + rtname + "' is ambiguous");
}
that.setTypeModel(accountForStaticReferenceType(that, memberType, fullType));
}
if (that.getStaticMethodReference()) {
handleStaticReferenceImplicitTypeArguments(that);
}
}
Aggregations