use of com.sun.tools.javac.code.Symbol.MethodSymbol in project ceylon-compiler by ceylon.
the class Attr method visitMethodDef.
public void visitMethodDef(JCMethodDecl tree) {
MethodSymbol m = tree.sym;
Lint lint = env.info.lint.augment(m.attributes_field, m.flags());
Lint prevLint = chk.setLint(lint);
MethodSymbol prevMethod = chk.setMethod(m);
try {
deferredLintHandler.flush(tree.pos());
chk.checkDeprecatedAnnotation(tree.pos(), m);
attribBounds(tree.typarams);
// JLS ???
if (m.isStatic()) {
chk.checkHideClashes(tree.pos(), env.enclClass.type, m);
} else {
chk.checkOverrideClashes(tree.pos(), env.enclClass.type, m);
}
chk.checkOverride(tree, m);
// Create a new environment with local scope
// for attributing the method.
Env<AttrContext> localEnv = memberEnter.methodEnv(tree, env);
localEnv.info.lint = lint;
// Enter all type parameters into the local method scope.
for (List<JCTypeParameter> l = tree.typarams; l.nonEmpty(); l = l.tail) localEnv.info.scope.enterIfAbsent(l.head.type.tsym);
ClassSymbol owner = env.enclClass.sym;
if ((owner.flags() & ANNOTATION) != 0 && tree.params.nonEmpty())
log.error(tree.params.head.pos(), "intf.annotation.members.cant.have.params");
// Attribute all value parameters.
for (List<JCVariableDecl> l = tree.params; l.nonEmpty(); l = l.tail) {
attribStat(l.head, localEnv);
}
chk.checkVarargsMethodDecl(localEnv, tree);
// Check that type parameters are well-formed.
chk.validate(tree.typarams, localEnv);
// Check that result type is well-formed.
chk.validate(tree.restype, localEnv);
// annotation method checks
if ((owner.flags() & ANNOTATION) != 0) {
// annotation method cannot have throws clause
if (tree.thrown.nonEmpty()) {
log.error(tree.thrown.head.pos(), "throws.not.allowed.in.intf.annotation");
}
// annotation method cannot declare type-parameters
if (tree.typarams.nonEmpty()) {
log.error(tree.typarams.head.pos(), "intf.annotation.members.cant.have.type.params");
}
// validate annotation method's return type (could be an annotation type)
chk.validateAnnotationType(tree.restype);
// ensure that annotation method does not clash with members of Object/Annotation
chk.validateAnnotationMethod(tree.pos(), m);
if (tree.defaultValue != null) {
// if default value is an annotation, check it is a well-formed
// annotation value (e.g. no duplicate values, no missing values, etc.)
chk.validateAnnotationTree(tree.defaultValue);
}
}
for (List<JCExpression> l = tree.thrown; l.nonEmpty(); l = l.tail) chk.checkType(l.head.pos(), l.head.type, syms.throwableType);
if (tree.body == null) {
// in a retrofit signature class.
if ((owner.flags() & INTERFACE) == 0 && (tree.mods.flags & (ABSTRACT | NATIVE)) == 0 && !relax)
log.error(tree.pos(), "missing.meth.body.or.decl.abstract");
if (tree.defaultValue != null) {
if ((owner.flags() & ANNOTATION) == 0)
log.error(tree.pos(), "default.allowed.in.intf.annotation.member");
}
} else if ((owner.flags() & INTERFACE) != 0) {
log.error(tree.body.pos(), "intf.meth.cant.have.body");
} else if ((tree.mods.flags & ABSTRACT) != 0) {
log.error(tree.pos(), "abstract.meth.cant.have.body");
} else if ((tree.mods.flags & NATIVE) != 0) {
log.error(tree.pos(), "native.meth.cant.have.body");
} else {
// or we are compiling class java.lang.Object.
if (tree.name == names.init && owner.type != syms.objectType) {
JCBlock body = tree.body;
if (body.stats.isEmpty() || !TreeInfo.isSelfCall(names, body.stats.head)) {
body.stats = body.stats.prepend(memberEnter.SuperCall(make.at(body.pos), List.<Type>nil(), List.<JCVariableDecl>nil(), false));
} else if ((env.enclClass.sym.flags() & ENUM) != 0 && (tree.mods.flags & GENERATEDCONSTR) == 0 && TreeInfo.isSuperCall(names, body.stats.head)) {
// enum constructors are not allowed to call super
// directly, so make sure there aren't any super calls
// in enum constructors, except in the compiler
// generated one.
log.error(tree.body.stats.head.pos(), "call.to.super.not.allowed.in.enum.ctor", env.enclClass.sym);
}
}
// Attribute method body.
attribStat(tree.body, localEnv);
}
localEnv.info.scope.leave();
result = tree.type = m.type;
chk.validateAnnotations(tree.mods.annotations, m);
} finally {
chk.setLint(prevLint);
chk.setMethod(prevMethod);
}
}
use of com.sun.tools.javac.code.Symbol.MethodSymbol in project ceylon-compiler by ceylon.
the class JavacClass method getDirectMethods.
@Override
public List<MethodMirror> getDirectMethods() {
if (methods == null) {
List<MethodMirror> ret = new LinkedList<MethodMirror>();
for (Symbol sym : classSymbol.getEnclosedElements()) {
if (sym instanceof MethodSymbol && (sym.flags() & Flags.PRIVATE) == 0) {
ret.add(new JavacMethod(this, (MethodSymbol) sym));
}
}
methods = Collections.unmodifiableList(ret);
}
return methods;
}
use of com.sun.tools.javac.code.Symbol.MethodSymbol in project ceylon-compiler by ceylon.
the class JavacClass method getEnclosingMethod.
@Override
public MethodMirror getEnclosingMethod() {
if (!enclosingMethodSet) {
Symbol encl = classSymbol.getEnclosingElement();
if (encl != null && encl instanceof MethodSymbol) {
// it's a method, it must be in a Class
ClassSymbol enclosingClass = (ClassSymbol) encl.getEnclosingElement();
JavacClass enclosingClassMirror = new JavacClass(enclosingClass);
enclosingMethod = new JavacMethod(enclosingClassMirror, (MethodSymbol) encl);
}
enclosingMethodSet = true;
}
return enclosingMethod;
}
use of com.sun.tools.javac.code.Symbol.MethodSymbol in project ceylon-compiler by ceylon.
the class CeylonModelLoader method implemented.
/**
* Copied from MethodSymbol.implemented and adapted for ignoring methods
*/
private Symbol implemented(MethodSymbol m, TypeSymbol c, Types types) {
Symbol impl = null;
for (List<Type> is = types.interfaces(c.type); impl == null && is.nonEmpty(); is = is.tail) {
TypeSymbol i = is.head.tsym;
impl = implementedIn(m, i, types);
if (impl == null)
impl = implemented(m, i, types);
}
return impl;
}
use of com.sun.tools.javac.code.Symbol.MethodSymbol in project ceylon-compiler by ceylon.
the class CeylonModelLoader method isOverloadingMethod.
/**
* Returns true if the given method is overloading an inherited method (from super class or interfaces).
*/
private boolean isOverloadingMethod(final MethodSymbol method) {
/*
* Copied from getOverriddenMethod and adapted for overloading
*/
try {
// interfaces have a different way to work
if (method.owner.isInterface())
return overloaded(method, method.owner.type.tsym, types);
// so we stop there for it, especially since it does not have any overloading
if (method.owner.type.tsym.getQualifiedName().toString().equals("ceylon.language.Exception"))
return false;
for (Type superType = types.supertype(method.owner.type); superType.tsym != null; superType = types.supertype(superType)) {
TypeSymbol i = superType.tsym;
String fqn = i.getQualifiedName().toString();
// never go above this type since it has no supertype in Ceylon (does in Java though)
if (fqn.equals("ceylon.language.Anything"))
break;
try {
for (Entry e = i.members().lookup(method.name); e.scope != null; e = e.next()) {
// ignore some methods
if (isIgnored(e.sym))
continue;
if (!method.overrides(e.sym, (TypeSymbol) method.owner, types, false)) {
return true;
}
}
// try in the interfaces
if (overloaded(method, i, types))
return true;
} catch (Symbol.CompletionFailure x) {
// just ignore unresolved interfaces, error will be logged when we try to add it
}
// so we stop there for it, especially since it does not have any overloading
if (fqn.equals("ceylon.language.Exception"))
break;
}
// try in the interfaces
if (overloaded(method, method.owner.type.tsym, types))
return true;
return false;
} catch (CompletionFailure x) {
handleCompletionFailure(method, x);
return false;
}
}
Aggregations