use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method checkIndexElement.
private Type checkIndexElement(Tree.IndexExpression that, Type pt, Interface cd, boolean nullable, String superTypeName, boolean allowIndexedCorrespondenceMutator) {
if (dynamic && isTypeUnknown(pt)) {
// on any dynamic types
return null;
}
Type kt = null;
Type vt = null;
Tree.ElementOrRange eor = that.getElementOrRange();
Type cst = pt.getSupertype(cd);
if (cst != null) {
List<Type> args = cst.getTypeArgumentList();
kt = args.get(0);
vt = args.get(1);
if (nullable) {
vt = unit.getOptionalType(vt);
}
}
if (cst == null && allowIndexedCorrespondenceMutator) {
Interface ld = unit.getIndexedCorrespondenceMutatorDeclaration();
cst = pt.getSupertype(ld);
if (cst != null) {
List<Type> args = cst.getTypeArgumentList();
kt = unit.getIntegerType();
vt = args.get(0);
if (nullable) {
vt = unit.getOptionalType(vt);
}
}
}
if (cst == null) {
Interface ld = unit.getJavaListDeclaration();
cst = pt.getSupertype(ld);
if (cst != null) {
List<Type> args = cst.getTypeArgumentList();
kt = unit.getIntegerType();
vt = unit.getOptionalType(args.get(0));
}
}
if (cst == null) {
Interface md = unit.getJavaMapDeclaration();
cst = pt.getSupertype(md);
if (cst != null) {
List<Type> args = cst.getTypeArgumentList();
kt = args.get(0);
vt = unit.getOptionalType(args.get(1));
}
}
if (cst == null) {
boolean objectArray = unit.isJavaObjectArrayType(pt);
boolean primitiveArray = unit.isJavaPrimitiveArrayType(pt);
if (objectArray || primitiveArray) {
cst = pt;
kt = unit.getIntegerType();
Type et = unit.getJavaArrayElementType(pt);
vt = primitiveArray ? et : unit.getOptionalType(et);
}
}
if (cst == null) {
that.getPrimary().addError("illegal receiving type for index expression: '" + pt.getDeclaration().getName(unit) + "' is not a subtype of '" + superTypeName + "'" + (allowIndexedCorrespondenceMutator ? " or 'IndexedCorrespondenceMutator'" : ""));
} else {
Tree.Element e = (Tree.Element) eor;
Tree.Expression ee = e.getExpression();
checkAssignable(ee.getTypeModel(), kt, ee, "index must be assignable to key type");
that.setTypeModel(vt);
Tree.Term t = ee.getTerm();
refineTypeForTupleElement(that, pt, t);
}
return vt;
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method visitSpanOperator.
private void visitSpanOperator(Tree.RangeOp that) {
Type lhst = leftType(that);
Type rhst = rightType(that);
Interface ed = unit.getEnumerableDeclaration();
Type ot = checkOperandTypes(lhst, rhst, ed, that, "operand expressions must be of compatible enumerable type");
if (ot != null) {
that.setTypeModel(unit.getSpanType(ot));
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method visit.
@Override
public void visit(Tree.SequenceEnumeration that) {
super.visit(that);
for (Tree.Statement st : that.getStatements()) {
st.addError("enumeration expression may not contain statements");
}
Type st = null;
Tree.SequencedArgument sa = that.getSequencedArgument();
if (sa != null) {
List<Tree.PositionalArgument> pas = sa.getPositionalArguments();
Type tt = getTupleType(pas, unit, false);
if (tt != null) {
Interface id = unit.getIterableDeclaration();
st = tt.getSupertype(id);
if (st == null) {
st = unit.getIterableType(unit.getUnknownType());
}
}
} else {
st = unit.getIterableType(unit.getNothingType());
}
if (st != null) {
that.setTypeModel(st);
if (st.containsUnknowns()) {
that.addError("iterable element type could not be inferred");
}
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method checkSequencedArgument.
private void checkSequencedArgument(Tree.SequencedArgument sa, Reference pr, Parameter p) {
sa.setParameter(p);
List<Tree.PositionalArgument> args = sa.getPositionalArguments();
Type paramType = pr.getTypedParameter(p).getFullType();
Interface id = unit.getIterableDeclaration();
Type att = getTupleType(args, unit, false).getSupertype(id);
if (!isTypeUnknown(att) && !isTypeUnknown(paramType)) {
checkAssignable(att, paramType, sa, "iterable arguments must be assignable to iterable parameter " + argdesc(p, pr));
}
}
use of org.eclipse.ceylon.model.typechecker.model.Interface in project ceylon by eclipse.
the class ExpressionVisitor method checkValueCase.
private void checkValueCase(Tree.Expression e) {
if (e == null) {
return;
}
Tree.Term term = e.getTerm();
Type type = e.getTypeModel();
if (term instanceof Tree.Tuple) {
Tree.Tuple tuple = (Tree.Tuple) term;
Tree.SequencedArgument sa = tuple.getSequencedArgument();
if (sa != null) {
for (Tree.PositionalArgument pa : sa.getPositionalArguments()) {
if (pa instanceof Tree.ListedArgument) {
Tree.ListedArgument la = (Tree.ListedArgument) pa;
checkValueCase(la.getExpression());
} else {
pa.addError("case must be a simple tuple");
}
}
}
return;
}
if (term instanceof Tree.NegativeOp) {
Tree.NegativeOp no = (Tree.NegativeOp) term;
term = no.getTerm();
}
if (term instanceof Tree.Literal) {
if (term instanceof Tree.FloatLiteral) {
e.addError("literal case may not be a 'Float' literal");
}
} else if (term instanceof Tree.MemberOrTypeExpression) {
Tree.MemberOrTypeExpression mte = (Tree.MemberOrTypeExpression) term;
Declaration ref = mte.getDeclaration();
TypeDeclaration dec = type.getDeclaration();
if (isToplevelObjectCase(dec)) {
// no need to check for Identifiable
// because the anonymous type check
// itself is sufficient
warnIfCustomEquals(e, dec);
} else if (isToplevelValueConstructorCase(dec) || isConstantCase(ref)) {
// identity equality
if (!isPrimitiveCase(dec)) {
// TODO: actually we don't need to do this check
// if the toplevel value constructor is
// the only constructor of its type
Interface id = unit.getIdentifiableDeclaration();
if (dec.inherits(id)) {
warnIfCustomEquals(e, dec);
} else {
// we don't have a guaranteed well-defined disjoint
// equality unless it is a String, Integer, Character,
// a unit type (toplevel object), or an Identifiable
// TODO: change this to a warning?
e.addError("value case must be identifiable, a toplevel or static object, or a constant 'String', 'Integer', or 'Character': '" + dec.getName(unit) + "' does not inherit 'Identifiable'");
}
}
} else {
e.addError("value case must be a toplevel or static object, a value constructor of a toplevel or static class, or a literal 'String', 'Integer', or 'Character'");
}
} else if (term != null) {
e.addError("value case must be a toplevel or static object, a value constructor of a toplevel or static class, or a literal 'String', 'Integer', or 'Character'");
}
}
Aggregations