/**
* Definition of a variable, such as parameter, field, and local variables.
*/
public Void visitVariable(VariableTree vt, Void _) {
VariableElement e = (VariableElement) TreeUtil.getElement(vt);
if(e!=null) {
switch (e.getKind()) {
case ENUM_CONSTANT:
case FIELD:
gen.add(new FieldDecl(cu,srcPos,vt));
break;
case EXCEPTION_PARAMETER:
case LOCAL_VARIABLE:
case PARAMETER:
gen.add(new LocalVarDecl(cu,srcPos,vt,e));
break;
}
Token token;
if(e.getKind()!= ElementKind.ENUM_CONSTANT) {
// put the marker just on the variable name.
// the token for the variable name is after its type.
// note that we need to handle declarations like "int a,b".
token = gen.findTokenAfter(vt.getType(), true, vt.getName().toString());
} else {
// for the enum constant put the anchor around vt
token = gen.findTokenAfter(vt, false, vt.getName().toString());
}
// TODO: handle declarations like "String abc[]"
if(token!=null)
gen.add(new DeclName(lineMap,token));
}
return super.visitVariable(vt,_);
}
/**
* Method declaration.
*/
public Void visitMethod(MethodTree mt, Void _) {
ExecutableElement e = (ExecutableElement) TreeUtil.getElement(mt);
if(e!=null) {
if(e.getKind()==ElementKind.CONSTRUCTOR && e.getEnclosingElement().getSimpleName().length()==0)
return _; // this is a synthesized constructor for an anonymous class
// TODO: I suspect we need some kind of uniform treatment for all synthesized methods
// mark up the method name
Tree prev = mt.getReturnType();
String name;
if(e.getKind()== ElementKind.CONSTRUCTOR)
name = e.getEnclosingElement().getSimpleName().toString();
else // constructor returns <init> from getName(), so we need the above code
name = mt.getName().toString();
Token token;
if(prev!=null)
token = gen.findTokenAfter(prev, true, name);
else
token = gen.findTokenAfter(mt,false,name);
if(token!=null)
gen.add(new DeclName(lineMap,token));
ParsedType pt = getParsedType((TypeElement) e.getEnclosingElement());
gen.add(new MethodDecl(cu, srcPos, mt, e,
pt.findOverriddenMethods(elements, e),
pt.findOverridingMethods(elements, e)
));
}
return super.visitMethod(mt, _);
}
/**
* Class declaration.
*/
public Void visitClass(ClassTree ct, Void _) {
TypeElement e = (TypeElement) TreeUtil.getElement(ct);
if(e!=null) {
// put the marker on the class name portion.
Token token=null;
if(ct.getModifiers()!=null)
token = gen.findTokenAfter(ct.getModifiers(), true, ct.getSimpleName().toString());
// on enum class, like "public enum En {ABC,DEF}", the above returns null somehow.
// so go with the plan B if it's not found.
// TODO: report to javac team
if(token==null)
token = gen.findTokenAfter(ct, false, ct.getSimpleName().toString());
if(token!=null)
gen.add(new DeclName(lineMap, token));
List<ParsedType> descendants = getParsedType(e).descendants;
gen.add(new ClassDecl(cu, srcPos, ct, e, descendants));
if(e.getNestingKind()== NestingKind.ANONYMOUS) {
// don't visit the extends and implements clause as
// they already show up in the NewClassTree
scan(ct.getMembers());
return _;
}
}
return super.visitClass(ct, _);
}
/**
* All the symbols found in the source code.
*/
public Void visitIdentifier(IdentifierTree id, Void _) {
if(!ReservedWords.LIST.contains(id.getName().toString())) {
Element e = TreeUtil.getElement(id);
if(e!=null) {
switch (e.getKind()) {
case ANNOTATION_TYPE:
case CLASS:
case ENUM:
case INTERFACE:
gen.add(new TypeRef(cu,srcPos,id,(TypeElement)e));
break;
case FIELD: // such as objects imported by static import.
case ENUM_CONSTANT:
gen.add(new FieldRef(cu,srcPos,id,(VariableElement)e));
break;
case PARAMETER:
case EXCEPTION_PARAMETER:
case LOCAL_VARIABLE:
gen.add(new LocalVarRef(cu,srcPos,id,(VariableElement)e));
break;
}
}
}
return super.visitIdentifier(id,_);
}
/**
* "exp.token"
*/
public Void visitMemberSelect(MemberSelectTree mst, Void _) {
// avoid marking 'Foo.class' as static reference
if(!mst.getIdentifier().equals(CLASS)) {
// just select the 'token' portion
long ep = srcPos.getEndPosition(cu,mst);
long sp = ep-mst.getIdentifier().length();
// marker for the selected identifier
Element e = TreeUtil.getElement(mst);
if(e!=null) {
switch(e.getKind()) {
case FIELD:
case ENUM_CONSTANT:
gen.add(new FieldRef(sp, ep, PositionUtils.getLineNumber(lineMap, sp), PositionUtils.getColNumber(lineMap, sp), (VariableElement)e));
break;