use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class Check method checkOverrideClashes.
/**
* Check that all non-override equivalent methods accessible from 'site'
* are mutually compatible (JLS 8.4.8/9.4.1).
*
* @param pos Position to be used for error reporting.
* @param site The class whose methods are checked.
* @param sym The method symbol to be checked.
*/
void checkOverrideClashes(DiagnosticPosition pos, Type site, MethodSymbol sym) {
ClashFilter cf = new ClashFilter(site);
// for each method m1 that is overridden (directly or indirectly)
// by method 'sym' in 'site'...
List<MethodSymbol> potentiallyAmbiguousList = List.nil();
boolean overridesAny = false;
for (Symbol m1 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
if (!sym.overrides(m1, site.tsym, types, false)) {
if (m1 == sym) {
continue;
}
if (!overridesAny) {
potentiallyAmbiguousList = potentiallyAmbiguousList.prepend((MethodSymbol) m1);
}
continue;
}
if (m1 != sym) {
overridesAny = true;
potentiallyAmbiguousList = List.nil();
}
// ...check each method m2 that is a member of 'site'
for (Symbol m2 : types.membersClosure(site, false).getElementsByName(sym.name, cf)) {
if (m2 == m1)
continue;
// a member of 'site') and (ii) m1 has the same erasure as m2, issue an error
if (!types.isSubSignature(sym.type, types.memberType(site, m2), allowStrictMethodClashCheck) && types.hasSameArgs(m2.erasure(types), m1.erasure(types))) {
sym.flags_field |= CLASH;
String key = m1 == sym ? "name.clash.same.erasure.no.override" : "name.clash.same.erasure.no.override.1";
log.error(pos, key, sym, sym.location(), m2, m2.location(), m1, m1.location());
return;
}
}
}
if (!overridesAny) {
for (MethodSymbol m : potentiallyAmbiguousList) {
checkPotentiallyAmbiguousOverloads(pos, site, sym, m);
}
}
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class Check method is292targetTypeCast.
// where
private boolean is292targetTypeCast(JCTypeCast tree) {
boolean is292targetTypeCast = false;
JCExpression expr = TreeInfo.skipParens(tree.expr);
if (expr.hasTag(APPLY)) {
JCMethodInvocation apply = (JCMethodInvocation) expr;
Symbol sym = TreeInfo.symbol(apply.meth);
is292targetTypeCast = sym != null && sym.kind == MTH && (sym.flags() & HYPOTHETICAL) != 0;
}
return is292targetTypeCast;
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class Check method checkNonCyclicInternal.
/**
* Check for cyclic references. Issue an error if the
* symbol of the type referred to has a LOCKED flag set.
*
* @param pos Position to be used for error reporting.
* @param t The type referred to.
* @returns True if the check completed on all attributed classes
*/
private boolean checkNonCyclicInternal(DiagnosticPosition pos, Type t) {
// was the check complete?
boolean complete = true;
// - System.err.println("checkNonCyclicInternal("+t+");");//DEBUG
Symbol c = t.tsym;
if ((c.flags_field & ACYCLIC) != 0)
return true;
if ((c.flags_field & LOCKED) != 0) {
noteCyclic(pos, (ClassSymbol) c);
} else if (!c.type.isErroneous()) {
try {
c.flags_field |= LOCKED;
if (c.type.hasTag(CLASS)) {
ClassType clazz = (ClassType) c.type;
if (clazz.interfaces_field != null)
for (List<Type> l = clazz.interfaces_field; l.nonEmpty(); l = l.tail) complete &= checkNonCyclicInternal(pos, l.head);
if (clazz.supertype_field != null) {
Type st = clazz.supertype_field;
if (st != null && st.hasTag(CLASS))
complete &= checkNonCyclicInternal(pos, st);
}
if (c.owner.kind == TYP)
complete &= checkNonCyclicInternal(pos, c.owner.type);
}
} finally {
c.flags_field &= ~LOCKED;
}
}
if (complete)
complete = ((c.flags_field & UNATTRIBUTED) == 0) && c.completer == null;
if (complete)
c.flags_field |= ACYCLIC;
return complete;
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class Enter method visitTopLevel.
@Override
public void visitTopLevel(JCCompilationUnit tree) {
JavaFileObject prev = log.useSource(tree.sourcefile);
boolean addEnv = false;
boolean isPkgInfo = tree.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE);
if (tree.pid != null) {
tree.packge = reader.enterPackage(TreeInfo.fullName(tree.pid));
if (tree.packageAnnotations.nonEmpty() || pkginfoOpt == PkgInfo.ALWAYS) {
if (isPkgInfo) {
addEnv = true;
} else if (tree.packageAnnotations.nonEmpty()) {
log.error(tree.packageAnnotations.head.pos(), "pkg.annotations.sb.in.package-info.java");
}
}
} else {
tree.packge = syms.unnamedPackage;
}
// Find all classes in package.
tree.packge.complete();
Env<AttrContext> topEnv = topLevelEnv(tree);
// Save environment of package-info.java file.
if (isPkgInfo) {
Env<AttrContext> env0 = typeEnvs.get(tree.packge);
if (env0 == null) {
typeEnvs.put(tree.packge, topEnv);
} else {
JCCompilationUnit tree0 = env0.toplevel;
if (!fileManager.isSameFile(tree.sourcefile, tree0.sourcefile)) {
log.warning(tree.pid != null ? tree.pid.pos() : null, "pkg-info.already.seen", tree.packge);
if (addEnv || (tree0.packageAnnotations.isEmpty())) {
typeEnvs.put(tree.packge, topEnv);
}
}
}
for (Symbol q = tree.packge; q != null && q.kind == PCK; q = q.owner) q.flags_field |= EXISTS;
Name name = names.package_info;
ClassSymbol c = reader.enterClass(name, tree.packge);
c.flatname = names.fromString(tree.packge + "." + name);
c.sourcefile = tree.sourcefile;
c.completer = null;
c.members_field = new Scope(c);
tree.packge.package_info = c;
}
classEnter(tree.defs, topEnv);
if (addEnv) {
todo.append(topEnv);
}
log.useSource(prev);
result = null;
}
use of org.eclipse.ceylon.langtools.tools.javac.code.Symbol in project ceylon by eclipse.
the class Annotate method enterAnnotation.
// boolean typeAnnotation determines whether the method returns
// a Compound (false) or TypeCompound (true).
Attribute.Compound enterAnnotation(JCAnnotation a, Type expected, Env<AttrContext> env, boolean typeAnnotation) {
// The annotation might have had its type attributed (but not checked)
// by attr.attribAnnotationTypes during MemberEnter, in which case we do not
// need to do it again.
Type at = (a.annotationType.type != null ? a.annotationType.type : attr.attribType(a.annotationType, env));
a.type = chk.checkType(a.annotationType.pos(), at, expected);
if (a.type.isErroneous()) {
// Need to make sure nested (anno)trees does not have null as .type
attr.postAttr(a);
if (typeAnnotation) {
return new Attribute.TypeCompound(a.type, List.<Pair<MethodSymbol, Attribute>>nil(), new TypeAnnotationPosition());
} else {
return new Attribute.Compound(a.type, List.<Pair<MethodSymbol, Attribute>>nil());
}
}
if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) {
log.error(a.annotationType.pos(), "not.annotation.type", a.type.toString());
// Need to make sure nested (anno)trees does not have null as .type
attr.postAttr(a);
if (typeAnnotation) {
return new Attribute.TypeCompound(a.type, List.<Pair<MethodSymbol, Attribute>>nil(), null);
} else {
return new Attribute.Compound(a.type, List.<Pair<MethodSymbol, Attribute>>nil());
}
}
List<JCExpression> args = a.args;
if (args.length() == 1 && !args.head.hasTag(ASSIGN)) {
// special case: elided "value=" assumed
args.head = make.at(args.head.pos).Assign(make.Ident(names.value), args.head);
}
ListBuffer<Pair<MethodSymbol, Attribute>> buf = new ListBuffer<>();
for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
JCExpression t = tl.head;
if (!t.hasTag(ASSIGN)) {
log.error(t.pos(), "annotation.value.must.be.name.value");
continue;
}
JCAssign assign = (JCAssign) t;
if (!assign.lhs.hasTag(IDENT)) {
log.error(t.pos(), "annotation.value.must.be.name.value");
continue;
}
JCIdent left = (JCIdent) assign.lhs;
Symbol method = rs.resolveQualifiedMethod(assign.rhs.pos(), env, a.type, left.name, List.<Type>nil(), null);
left.sym = method;
left.type = method.type;
if (method.owner != a.type.tsym)
log.error(left.pos(), "no.annotation.member", left.name, a.type);
Type result = method.type.getReturnType();
Attribute value = enterAttributeValue(result, assign.rhs, env);
if (!method.type.isErroneous())
buf.append(new Pair<>((MethodSymbol) method, value));
t.type = result;
}
if (typeAnnotation) {
if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) {
// Create a new TypeCompound
Attribute.TypeCompound tc = new Attribute.TypeCompound(a.type, buf.toList(), new TypeAnnotationPosition());
a.attribute = tc;
return tc;
} else {
// Use an existing TypeCompound
return a.attribute;
}
} else {
Attribute.Compound ac = new Attribute.Compound(a.type, buf.toList());
a.attribute = ac;
return ac;
}
}
Aggregations