use of org.eclipse.ceylon.model.typechecker.model.Unit in project ceylon by eclipse.
the class Decl method isJavaObjectArrayWith.
public static boolean isJavaObjectArrayWith(Constructor ctor) {
if (ctor.isClassMember() && "with".equals(ctor.getName())) {
Unit unit = ctor.getUnit();
Scope cls = ctor.getContainer();
if (cls instanceof Class) {
return cls.equals(unit.getJavaObjectArrayDeclaration());
}
}
return false;
}
use of org.eclipse.ceylon.model.typechecker.model.Unit in project ceylon by eclipse.
the class TypeUtils method convertTupleToParameters.
/**
* Turns a Tuple type into a parameter list.
*/
public static List<Parameter> convertTupleToParameters(Type _tuple) {
final ArrayList<Parameter> rval = new ArrayList<>();
int pos = 0;
final Unit unit = getUnit(_tuple);
final Type empty = unit.getEmptyType();
while (_tuple != null && !(_tuple.isSubtypeOf(empty) || _tuple.isTypeParameter())) {
Parameter _p = null;
if (isTuple(_tuple)) {
_p = new Parameter();
_p.setModel(new Value());
if (_tuple.isUnion()) {
// Handle union types for defaulted parameters
for (Type mt : _tuple.getCaseTypes()) {
if (mt.isTuple()) {
_p.getModel().setType(mt.getTypeArgumentList().get(1));
_tuple = mt.getTypeArgumentList().get(2);
break;
}
}
_p.setDefaulted(true);
} else {
_p.getModel().setType(_tuple.getTypeArgumentList().get(1));
_tuple = _tuple.getTypeArgumentList().get(2);
}
} else if (unit.isSequentialType(_tuple)) {
// Handle Sequence, for nonempty variadic parameters
_p = new Parameter();
_p.setModel(new Value());
_p.getModel().setType(_tuple.getTypeArgumentList().get(0));
_p.setSequenced(true);
_tuple = null;
} else {
if (pos > 100) {
return rval;
}
}
if (_p != null) {
_p.setName("arg" + pos);
rval.add(_p);
}
pos++;
}
return rval;
}
use of org.eclipse.ceylon.model.typechecker.model.Unit in project ceylon by eclipse.
the class ModuleVisitor method visit.
@Override
public void visit(Tree.ModuleDescriptor that) {
Tree.AnnotationList al = that.getAnnotationList();
Unit u = unit.getUnit();
moduleBackends = getNativeBackend(al, u);
super.visit(that);
if (phase == Phase.SRC_MODULE) {
String version = getVersionString(that.getVersion(), null, that);
Tree.ImportPath importPath = that.getImportPath();
for (Tree.Identifier id : importPath.getIdentifiers()) {
if (containsDiscouragedChar(id)) {
id.addUsageWarning(Warning.packageName, "all-lowercase ASCII module names are recommended");
}
}
List<String> name = getNameAsList(importPath);
if (pkg.getNameAsString().isEmpty()) {
that.addError("module descriptor encountered in root source directory");
} else if (name.isEmpty()) {
that.addError("missing module name");
} else {
String initialName = name.get(0);
Backends unitBackends = u.getSupportedBackends();
if (initialName.equals(DEFAULT_MODULE_NAME)) {
importPath.addError("reserved module name: 'default'");
} else if (name.size() == 1 && initialName.equals("ceylon")) {
importPath.addError("reserved module name: 'ceylon'");
} else if (!moduleBackends.none() && moduleBackends.header()) {
that.addError("missing backend argument for native annotation on module: " + formatPath(importPath.getIdentifiers()));
} else if (!moduleBackends.none() && !unitBackends.none() && !unitBackends.supports(moduleBackends)) {
that.addError("module not meant for this backend: " + formatPath(importPath.getIdentifiers()));
} else {
if (initialName.equals("ceylon")) {
importPath.addUsageWarning(Warning.ceylonNamespace, "discouraged module name: this namespace is used by Ceylon platform modules");
} else if (initialName.equals("java") || initialName.equals("javax")) {
importPath.addUnsupportedError("unsupported module name: this namespace is used by Java platform modules");
}
mainModule = moduleManager.getOrCreateModule(name, version);
importPath.setModel(mainModule);
if (!completeOnlyAST) {
mainModule.setUnit(u);
mainModule.setVersion(version);
// if (hasAnnotation(al, "label", u)) {
// mainModule.setLabel(getAnnotationArgument(
// getAnnotation(al, "label", u),
// 0, u));
// }
}
String nameString = formatPath(importPath.getIdentifiers());
if (!pkg.getNameAsString().equals(nameString)) {
importPath.addError("module name does not match descriptor location: '" + nameString + "' should be '" + pkg.getNameAsString() + "'", 8000);
}
if (!completeOnlyAST) {
moduleManagerUtil.addLinkBetweenModuleAndNode(mainModule, that);
mainModule.setAvailable(true);
mainModule.getAnnotations().clear();
buildAnnotations(al, mainModule.getAnnotations());
mainModule.setNativeBackends(moduleBackends);
Tree.QuotedLiteral classifier = that.getClassifier();
if (classifier != null) {
mainModule.setClassifier(getNameString(classifier));
classifier.addUnsupportedError("classifiers not yet supported");
}
Tree.QuotedLiteral artifact = that.getArtifact();
if (artifact != null) {
mainModule.setArtifactId(getNameString(artifact));
}
Tree.ImportPath groupImportPath = that.getGroupImportPath();
Tree.QuotedLiteral groupQuotedLiteral = that.getGroupQuotedLiteral();
if (groupImportPath != null) {
mainModule.setGroupId(formatPath(groupImportPath.getIdentifiers()));
} else if (groupQuotedLiteral != null) {
mainModule.setGroupId(getNameString(groupQuotedLiteral));
}
}
}
}
HashSet<String> set = new HashSet<String>();
Tree.ImportModuleList iml = that.getImportModuleList();
if (iml != null) {
for (Tree.ImportModule im : iml.getImportModules()) {
String path = im.getName();
if (path != null) {
if (!set.add(path)) {
im.addError("duplicate module import: '" + path + "'");
}
}
}
}
}
moduleBackends = Backends.ANY;
}
use of org.eclipse.ceylon.model.typechecker.model.Unit in project ceylon by eclipse.
the class RefinementVisitor method checkOverloadedAnnotation.
private void checkOverloadedAnnotation(Tree.Declaration that, Declaration member) {
// non-actual overloaded methods
// must be annotated 'overloaded'
boolean marked = false;
Unit unit = that.getUnit();
for (Tree.Annotation a : that.getAnnotationList().getAnnotations()) {
Tree.Primary p = a.getPrimary();
if (p instanceof Tree.BaseMemberExpression) {
Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) p;
String aname = bme.getIdentifier().getText();
Declaration ad = p.getScope().getMemberOrParameter(unit, aname, null, false);
if (ad != null && isOverloadedAnnotation(ad)) {
marked = true;
}
}
}
if (!marked) {
if (member.isActual()) {
that.addUsageWarning(Warning.unknownWarning, "overloaded function should be declared with the 'overloaded' annotation in 'java.lang'");
} else {
if (member instanceof Constructor) {
// default constructors are the only
// thing that can legally have no name
that.addError("duplicate default constructor (overloaded default constructor must be declared with the 'overloaded' annotation in 'java.lang')");
} else if (member instanceof Function) {
// functions are the only thing
// that can legally have a name
// and be overloaded
that.addError("duplicate declaration: the name '" + member.getName() + "' is not unique in this scope " + "(overloaded function must be declared with the 'overloaded' annotation in 'java.lang')");
}
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Unit in project ceylon by eclipse.
the class RefinementVisitor method checkRefiningMemberUpperBounds.
private List<Type> checkRefiningMemberUpperBounds(Tree.Declaration that, ClassOrInterface ci, Declaration refined, List<TypeParameter> refinedTypeParams, List<TypeParameter> refiningTypeParams) {
int refiningSize = refiningTypeParams.size();
int refinedSize = refinedTypeParams.size();
int max = refiningSize <= refinedSize ? refiningSize : refinedSize;
if (max == 0) {
return NO_TYPE_ARGS;
}
// we substitute the type parameters of the refined
// declaration into the bounds of the refining
// declaration
Map<TypeParameter, Type> substitution = new HashMap<TypeParameter, Type>();
for (int i = 0; i < max; i++) {
TypeParameter refinedTypeParam = refinedTypeParams.get(i);
TypeParameter refiningTypeParam = refiningTypeParams.get(i);
substitution.put(refiningTypeParam, refinedTypeParam.getType());
}
Map<TypeParameter, SiteVariance> noVariances = emptyMap();
TypeDeclaration rc = (TypeDeclaration) refined.getContainer();
// we substitute the type arguments of the subtype's
// instantiation of the supertype into the bounds of
// the refined declaration
Type supertype = ci.getType().getSupertype(rc);
Map<TypeParameter, Type> args = supertype.getTypeArguments();
Map<TypeParameter, SiteVariance> variances = supertype.getVarianceOverrides();
List<Type> typeArgs = new ArrayList<Type>(max);
for (int i = 0; i < max; i++) {
TypeParameter refinedTypeParam = refinedTypeParams.get(i);
TypeParameter refiningTypeParam = refiningTypeParams.get(i);
refiningTypeParam.setReified(refinedTypeParam.isReified());
Type refinedProducedType = refinedTypeParam.getType();
List<Type> refinedBounds = refinedTypeParam.getSatisfiedTypes();
List<Type> refiningBounds = refiningTypeParam.getSatisfiedTypes();
Unit unit = that.getUnit();
for (Type bound : refiningBounds) {
Type refiningBound = bound.substitute(substitution, noVariances);
// for every type constraint of the refining member, there must
// be at least one type constraint of the refined member which
// is assignable to it, guaranteeing that the intersection of
// the refined member bounds is assignable to the intersection
// of the refining member bounds
// TODO: would it be better to just form the intersections and
// test assignability directly (the error messages might
// not be as helpful, but it might be less restrictive)
boolean ok = false;
for (Type refinedBound : refinedBounds) {
refinedBound = refinedBound.substitute(args, variances);
if (refinedBound.isSubtypeOf(refiningBound)) {
ok = true;
}
}
if (!ok) {
that.addError("refining member type parameter '" + refiningTypeParam.getName() + "' has upper bound which refined member type parameter '" + refinedTypeParam.getName() + "' of " + message(refined) + " does not satisfy: '" + bound.asString(unit) + "' ('" + refiningTypeParam.getName() + "' should be upper bounded by '" + intersectionOfSupertypes(refinedTypeParam).substitute(args, variances).asString(unit) + "')");
}
}
for (Type bound : refinedBounds) {
Type refinedBound = bound.substitute(args, variances);
boolean ok = false;
for (Type refiningBound : refiningBounds) {
refiningBound = refiningBound.substitute(substitution, noVariances);
if (refinedBound.isSubtypeOf(refiningBound)) {
ok = true;
}
}
if (!ok) {
that.addUnsupportedError("refined member type parameter '" + refinedTypeParam.getName() + "' of " + message(refined) + " has upper bound which refining member type parameter '" + refiningTypeParam.getName() + "' does not satisfy: '" + bound.asString(unit) + "' ('" + refiningTypeParam.getName() + "' should be upper bounded by '" + intersectionOfSupertypes(refinedTypeParam).substitute(args, variances).asString(unit) + "')");
}
}
typeArgs.add(refinedProducedType);
}
return typeArgs;
}
Aggregations