use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.ClassDeclaration that) {
super.visit(that);
Class alias = that.getDeclarationModel();
Type et = alias.getExtendedType();
Tree.ClassSpecifier cs = that.getClassSpecifier();
if (cs != null && et != null) {
TypeDeclaration etd = et.getDeclaration();
if (etd instanceof Constructor) {
etd = etd.getExtendedType().getDeclaration();
}
if (etd instanceof Class) {
// TODO: some of this belongs in InheritanceVisitor!
Class c = (Class) etd;
if (c.isAbstract()) {
if (!alias.isFormal() && !alias.isAbstract()) {
that.addError("alias of abstract class must be annotated abstract", 310);
}
}
if (c.isAbstraction()) {
that.addError("class alias may not alias overloaded class");
} else {
Tree.InvocationExpression ie = cs.getInvocationExpression();
if (ie != null) {
checkClassAliasParameters(alias, that, ie);
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.QualifiedType that) {
super.visit(that);
TypeDeclaration type = that.getDeclarationModel();
if (type != null) {
type = (TypeDeclaration) handleNativeHeader(type, that, true);
if (!type.isVisible(that.getScope())) {
if (type instanceof Constructor) {
that.addError("constructor is not visible: " + qualifiedDescription(that), 400);
} else {
that.addError("member type is not visible: " + qualifiedDescription(that), 400);
}
} else if (type.isPackageVisibility() && !declaredInPackage(type, unit)) {
that.addError("member type is not visible: " + qualifiedDescription(that) + " is package private");
} else // in fact this restriction is OK
if (type.isProtectedVisibility() && !declaredInPackage(type, unit)) {
that.addError("member type is not visible: " + qualifiedDescription(that) + " is protected");
}
// Note: we should remove this check if we ever
// make qualified member types like T.Member
// into a sort of virtual type
Tree.StaticType outerType = that.getOuterType();
if (outerType instanceof Tree.SimpleType) {
Tree.SimpleType st = (Tree.SimpleType) outerType;
TypeDeclaration std = st.getDeclarationModel();
if (std.isAlias()) {
Type et = std.getExtendedType();
if (et != null) {
std = et.resolveAliases().getDeclaration();
}
}
if (std instanceof TypeParameter) {
outerType.addError("type parameter should not occur as qualifying type: '" + std.getName(unit) + "' is a type parameter");
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class DeclarationVisitor method visit.
@Override
public void visit(Tree.Enumerated that) {
Constructor e = new Constructor();
that.setEnumerated(e);
visitDeclaration(that, e, false);
Type at;
if (scope instanceof Class) {
Class clazz = (Class) scope;
Type ot = clazz.getType();
e.setExtendedType(ot);
at = e.appliedType(ot, NO_TYPE_ARGS);
clazz.setEnumerated(true);
if (clazz.isAnonymous()) {
that.addError("anonymous class may not have a value constructor: '" + clazz.getName() + "' is an anonymous class");
} else if (clazz.isAbstract()) {
that.addError("abstract class may not have a value constructor: '" + clazz.getName() + "' is abstract");
} else if (!clazz.getTypeParameters().isEmpty()) {
that.addError("generic class may not have a value constructor: '" + clazz.getName() + "' is generic");
} else if (scope.getContainer() instanceof Interface) {
that.addError("class nested inside an interface may not have a value constructor: '" + clazz.getName() + "' belongs to an interface");
}
} else {
at = null;
that.addError("value constructor declaration must occur directly in the body of a class");
}
Value v = new Value();
v.setType(at);
that.setDeclarationModel(v);
visitDeclaration(that, v);
Scope o = enterScope(e);
super.visit(that);
exitScope(o);
v.setImplemented(that.getBlock() != null);
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor in project ceylon by eclipse.
the class ClassTransformer method makeDelegateToCompanion.
/**
* Generates a method which delegates to the companion instance $Foo$impl
*/
private MethodDefinitionBuilder makeDelegateToCompanion(Interface iface, Reference typedMember, Type currentType, final long mods, final java.util.List<TypeParameter> typeParameters, final java.util.List<java.util.List<Type>> producedTypeParameterBounds, final Type methodType, final String methodName, final java.util.List<Parameter> parameters, boolean typeErased, final String targetMethodName, Parameter defaultedParam, boolean includeBody) {
final MethodDefinitionBuilder concreteWrapper = MethodDefinitionBuilder.systemMethod(gen(), methodName);
concreteWrapper.modifiers(mods);
concreteWrapper.ignoreModelAnnotations();
if ((mods & PRIVATE) == 0) {
concreteWrapper.isOverride(true);
}
if (typeParameters != null) {
concreteWrapper.reifiedTypeParametersFromModel(typeParameters);
}
Iterator<java.util.List<Type>> iterator = producedTypeParameterBounds.iterator();
if (typeParameters != null) {
for (TypeParameter tp : typeParameters) {
concreteWrapper.typeParameter(tp, iterator.next());
}
}
boolean explicitReturn = false;
Declaration member = (defaultedParam != null ? typedMember.getTypedParameter(defaultedParam) : typedMember).getDeclaration();
Type returnType = null;
if (!isAnything(methodType) || ((member instanceof Function || member instanceof Value) && !Decl.isUnboxedVoid(member)) || (member instanceof Function && Strategy.useBoxedVoid((Function) member))) {
explicitReturn = true;
if (CodegenUtil.isHashAttribute(member)) {
// delegates for hash attributes are int
concreteWrapper.resultType(new TransformedType(make().Type(syms().intType)));
returnType = typedMember.getType();
} else if (typedMember instanceof TypedReference && defaultedParam == null) {
TypedReference typedRef = (TypedReference) typedMember;
// This is very much like for method refinement: if the supertype is erased -> go raw.
// Except for some reason we only need to do it with multiple inheritance with different type
// arguments, so let's not go overboard
int flags = 0;
if (CodegenUtil.hasTypeErased((TypedDeclaration) member.getRefinedDeclaration()) || CodegenUtil.hasTypeErased((TypedDeclaration) member) && isInheritedTwiceWithDifferentTypeArguments(currentType, iface)) {
flags |= AbstractTransformer.JT_RAW;
}
concreteWrapper.resultTypeNonWidening(currentType, typedRef, typedMember.getType(), flags);
// FIXME: this is redundant with what we computed in the previous line in concreteWrapper.resultTypeNonWidening
TypedReference nonWideningTypedRef = gen().nonWideningTypeDecl(typedRef, currentType);
returnType = gen().nonWideningType(typedRef, nonWideningTypedRef);
} else if (defaultedParam != null) {
TypedReference typedParameter = typedMember.getTypedParameter(defaultedParam);
NonWideningParam nonWideningParam = concreteWrapper.getNonWideningParam(typedParameter, currentType.getDeclaration() instanceof Class ? WideningRules.FOR_MIXIN : WideningRules.NONE);
returnType = nonWideningParam.nonWideningType;
if (member instanceof Function)
returnType = typeFact().getCallableType(returnType);
concreteWrapper.resultType(new TransformedType(makeJavaType(returnType, nonWideningParam.flags)));
} else {
concreteWrapper.resultType(new TransformedType(makeJavaType((Type) typedMember)));
returnType = (Type) typedMember;
}
}
ListBuffer<JCExpression> arguments = new ListBuffer<JCExpression>();
if (typeParameters != null) {
for (TypeParameter tp : typeParameters) {
arguments.add(naming.makeUnquotedIdent(naming.getTypeArgumentDescriptorName(tp)));
}
}
Declaration declaration = typedMember.getDeclaration();
if (declaration instanceof Constructor && !Decl.isDefaultConstructor((Constructor) declaration) && defaultedParam == null) {
concreteWrapper.parameter(makeConstructorNameParameter((Constructor) declaration));
arguments.add(naming.makeUnquotedIdent(Unfix.$name$));
}
int ii = 0;
for (Parameter param : parameters) {
Parameter parameter;
if (declaration instanceof Functional) {
parameter = ((Functional) declaration).getFirstParameterList().getParameters().get(ii++);
} else if (declaration instanceof Setter) {
parameter = ((Setter) declaration).getParameter();
} else {
throw BugException.unhandledDeclarationCase(declaration);
}
final TypedReference typedParameter = typedMember.getTypedParameter(parameter);
concreteWrapper.parameter(null, param, typedParameter, null, FINAL, WideningRules.FOR_MIXIN);
arguments.add(naming.makeName(param.getModel(), Naming.NA_MEMBER | Naming.NA_ALIASED));
}
if (includeBody) {
JCExpression qualifierThis = makeUnquotedIdent(getCompanionFieldName(iface));
// our impl accessor to get the expected bounds of the qualifying type
if (explicitReturn) {
Type javaType = getBestSatisfiedType(currentType, iface);
Type ceylonType = typedMember.getQualifyingType();
// don't even bother if the impl accessor is turned to raw because casting it to raw doesn't help
if (!isTurnedToRaw(ceylonType) && // if it's exactly the same we don't need any cast
!javaType.isExactly(ceylonType))
// this will add the proper cast to the impl accessor
qualifierThis = expressionGen().applyErasureAndBoxing(qualifierThis, currentType, false, true, BoxingStrategy.BOXED, ceylonType, ExpressionTransformer.EXPR_WANTS_COMPANION);
}
JCExpression expr = make().Apply(// TODO Type args
null, makeSelect(qualifierThis, (targetMethodName != null) ? targetMethodName : methodName), arguments.toList());
if (isUnimplementedMemberClass(currentType, typedMember)) {
concreteWrapper.body(makeThrowUnresolvedCompilationError(// TODO encapsulate the error message
"formal member '" + declaration.getName() + "' of '" + iface.getName() + "' not implemented in class hierarchy"));
current().broken();
} else if (!explicitReturn) {
concreteWrapper.body(gen().make().Exec(expr));
} else {
// deal with erasure and stuff
BoxingStrategy boxingStrategy;
boolean exprBoxed;
if (member instanceof TypedDeclaration) {
TypedDeclaration typedDecl = (TypedDeclaration) member;
exprBoxed = !CodegenUtil.isUnBoxed(typedDecl);
boxingStrategy = CodegenUtil.getBoxingStrategy(typedDecl);
} else {
// must be a class or interface
exprBoxed = true;
boxingStrategy = BoxingStrategy.UNBOXED;
}
// to force an additional cast
if (isTurnedToRaw(typedMember.getQualifyingType()) || // in invariant locations
needsRawCastForMixinSuperCall(iface, methodType) || needsCastForErasedInstantiator(iface, methodName, member))
typeErased = true;
expr = gen().expressionGen().applyErasureAndBoxing(expr, methodType, typeErased, exprBoxed, boxingStrategy, returnType, 0);
concreteWrapper.body(gen().make().Return(expr));
}
}
return concreteWrapper;
}
use of org.eclipse.ceylon.model.typechecker.model.Constructor 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