use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method handleExpressionParameterList.
private Type handleExpressionParameterList(Tree.ParameterizedExpression that, Tree.MemberOrTypeExpression mte, Type pt, Tree.ParameterList pl) {
Interface cd = unit.getCallableDeclaration();
Type ct = pt.getSupertype(cd);
String refName = mte.getDeclaration().getName();
if (ct == null) {
pl.addError("no matching parameter list in referenced declaration: '" + refName + "'");
} else if (ct.getTypeArgumentList().size() >= 2) {
Type tupleType = ct.getTypeArgumentList().get(1);
List<Type> argTypes = unit.getTupleElementTypes(tupleType);
boolean variadic = unit.isTupleLengthUnbounded(tupleType);
boolean atLeastOne = unit.isTupleVariantAtLeastOne(tupleType);
List<Tree.Parameter> params = pl.getParameters();
if (argTypes.size() != params.size()) {
pl.addError("wrong number of declared parameters: '" + refName + "' has " + argTypes.size() + " parameters");
}
for (int i = 0; i < argTypes.size() && i < params.size(); i++) {
Type at = argTypes.get(i);
Tree.Parameter param = params.get(i);
Parameter model = param.getParameterModel();
// TODO: for #1329 this is not working yet
// because the parameters of a specification
// all wind up getting shoved into the
// namespace of the containing Declaration
// back in DeclarationVisitor, when by rights
// they should belong to the Specification,
// which means they all get muddled up with
// each other (this is probably causing other
// bugs too!)
/*Reference ref = mte.getTarget();
Declaration fakeDec = model.getDeclaration();
if (pt.isTypeConstructor()) {
List<Type> typeArgs =
typeParametersAsArgList(
pt.getDeclaration());
ref = fakeDec.appliedReference(null, typeArgs);
}
else {
ref = fakeDec.getReference();
}
Type paramType =
ref.getTypedParameter(model)
.getFullType();*/
Type paramType = model.getModel().getTypedReference().getFullType();
if (!isTypeUnknown(paramType) && !isTypeUnknown(at) && !at.isSubtypeOf(paramType)) {
param.addError("type of parameter '" + model.getName() + "' must be a supertype of corresponding parameter type in declaration of '" + refName + "'");
}
}
if (!params.isEmpty()) {
Tree.Parameter lastParam = params.get(params.size() - 1);
Parameter model = lastParam.getParameterModel();
boolean refSequenced = model.isSequenced();
boolean refAtLeastOne = model.isAtLeastOne();
if (refSequenced && !variadic) {
lastParam.addError("parameter list in declaration of '" + refName + "' does not have a variadic parameter");
} else if (!refSequenced && variadic) {
lastParam.addError("parameter list in declaration of '" + refName + "' has a variadic parameter");
} else if (refAtLeastOne && !atLeastOne) {
lastParam.addError("variadic parameter in declaration of '" + refName + "' is optional");
} else if (!refAtLeastOne && atLeastOne) {
lastParam.addError("variadic parameter in declaration of '" + refName + "' is not optional");
}
}
pt = ct.getTypeArgumentList().get(0);
that.setTypeModel(pt);
}
return pt;
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method warnIfCustomEquals.
private void warnIfCustomEquals(Node node, TypeDeclaration dec) {
// reasonable definitions of equality
if (!dec.isJavaEnum()) {
Declaration eq = dec.getMember("equals", Arrays.asList(unit.getObjectType()), false);
if (eq != null) {
Scope container = eq.getContainer();
if (container instanceof TypeDeclaration) {
TypeDeclaration td = (TypeDeclaration) container;
Interface id = unit.getIdentifiableDeclaration();
if (!container.equals(id)) {
node.addUsageWarning(Warning.valueEqualityIgnored, "value equality defined by type '" + td.getName(unit) + "' ignored (identity equality is used to match value case)");
}
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.InterfaceDefinition that) {
Interface i = that.getDeclarationModel();
Declaration od = beginReturnDeclaration(i);
Tree.Type rt = beginReturnScope(null);
super.visit(that);
endReturnScope(rt, null);
endReturnDeclaration(od);
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class DeclarationVisitor method visit.
@Override
public void visit(Tree.AnyInterface that) {
Interface i = that.getDeclarationModel();
that.setDeclarationModel(i);
visitDeclaration(that, i);
Scope o = enterScope(i);
super.visit(that);
exitScope(o);
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class DeclarationVisitor method checkForNativeAnnotation.
private void checkForNativeAnnotation(Tree.Declaration that, Declaration model, Scope scope) {
Unit unit = model.getUnit();
if (model.isNative()) {
Backends mbackends = model.getNativeBackends();
boolean isHeader = model.isNativeHeader();
String name = model.getName();
boolean canBeNative = canBeNative(that);
if (canBeNative) {
Backends moduleBackends = unit.getPackage().getModule().getNativeBackends();
Backends backends = model.getScope().getScopedBackends();
if (!isHeader && !moduleBackends.none() && !mbackends.supports(moduleBackends)) {
that.addError("native backend name on declaration conflicts with module descriptor: '\"" + mbackends.names() + "\"' is not '\"" + moduleBackends.names() + "\"' for '" + name + "'");
} else if (!isHeader && !backends.none() && !backends.supports(mbackends)) {
that.addError("native backend for declaration conflicts with its scope: native implementation '" + name + "' for '\"" + mbackends.names() + "\"' occurs in a scope which only supports '\"" + backends.names() + "\"'");
}
if (isHeader && existImplementations(model)) {
that.addError("native header must be declared before its implementations: the native header '" + name + "' is declared after an implementation");
}
if (model instanceof Interface && ((Interface) model).isAlias()) {
that.addError("interface alias may not be marked native: '" + name + "' (add a body if a native interface was intended)");
}
model.setNativeBackends(mbackends);
Declaration member = getNativeHeader(model);
if (member == null || member.isNativeImplementation()) {
// it's not shared
if (!isHeader && mustHaveHeader(model) && !moduleBackends.equals(mbackends)) {
that.addError("shared native implementation must have a header: '" + model.getName() + "' has no native header");
}
}
if (member == null) {
if (model.isNativeHeader()) {
handleNativeHeader(model, name);
if (that instanceof Tree.ObjectDefinition) {
Tree.ObjectDefinition od = (Tree.ObjectDefinition) that;
handleNativeHeader(od.getAnonymousClass(), name);
} else if (that instanceof Tree.Constructor) {
Tree.Constructor c = (Tree.Constructor) that;
handleNativeHeader(c.getConstructor(), name);
}
} else {
member = model.getContainer().getDirectMemberForBackend(model.getName(), mbackends);
if (member != null && member != model) {
that.addError("duplicate native implementation: the implementation '" + name + "' for '\"" + mbackends.names() + "\"' is not unique");
unit.getDuplicateDeclarations().add(member);
}
}
} else {
if (member.isNative()) {
List<Declaration> overloads = member.getOverloads();
if (isHeader && member.isNativeHeader()) {
that.addError("duplicate native header: the header for '" + name + "' is not unique");
unit.getDuplicateDeclarations().add(member);
} else {
Declaration overload = findOverloadForBackend(mbackends, model, overloads);
if (overload != null) {
that.addError("duplicate native implementation: the implementation '" + name + "' for '\"" + mbackends.names() + "\"' is not unique");
unit.getDuplicateDeclarations().add(overload);
}
}
if (isAllowedToChangeModel(member) && !hasModelInOverloads(model, overloads)) {
overloads.add(model);
if (that instanceof Tree.ObjectDefinition) {
Tree.ObjectDefinition od = (Tree.ObjectDefinition) that;
Declaration objImplCls = od.getAnonymousClass();
Value value = (Value) member;
Class objHdrCls = (Class) value.getType().getDeclaration();
objHdrCls.getOverloads().add(objImplCls);
} else if (that instanceof Tree.Constructor) {
Tree.Constructor c = (Tree.Constructor) that;
Declaration cd = c.getConstructor();
FunctionOrValue fov = (FunctionOrValue) member;
Constructor hdr = (Constructor) fov.getType().getDeclaration();
hdr.getOverloads().add(cd);
}
}
} else {
if (isHeader) {
that.addError("native header for non-native declaration: '" + name + "' is not declared native");
} else {
that.addError("native implementation for non-native header: '" + name + "' is not declared native");
}
}
}
} else if (!(model instanceof Setter) && !isHeader) {
if (!canBeNative) {
that.addError("native declaration is not a class, constructor, method, attribute or object: '" + name + "' may not be annotated 'native'");
}
}
}
}
Aggregations