case NEW_CLASS:
JCNewClass frameNewClass = (JCNewClass) frame;
if (frameNewClass.def != null) {
// Special handling for anonymous class instantiations
JCClassDecl frameClassDecl = frameNewClass.def;
if (frameClassDecl.extending == tree) {
p.type = TargetType.CLASS_EXTENDS;
p.type_index = -1;
} else if (frameClassDecl.implementing.contains(tree)) {
p.type = TargetType.CLASS_EXTENDS;
p.type_index = frameClassDecl.implementing.indexOf(tree);
} else {
// In contrast to CLASS below, typarams cannot occur here.
Assert.error("Could not determine position of tree " + tree +
" within frame " + frame);
}
} else if (frameNewClass.typeargs.contains(tree)) {
p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
p.type_index = frameNewClass.typeargs.indexOf(tree);
} else {
p.type = TargetType.NEW;
}
p.pos = frame.pos;
return;
case NEW_ARRAY:
p.type = TargetType.NEW;
p.pos = frame.pos;
return;
case ANNOTATION_TYPE:
case CLASS:
case ENUM:
case INTERFACE:
p.pos = frame.pos;
if (((JCClassDecl)frame).extending == tree) {
p.type = TargetType.CLASS_EXTENDS;
p.type_index = -1;
} else if (((JCClassDecl)frame).implementing.contains(tree)) {
p.type = TargetType.CLASS_EXTENDS;
p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree);
} else if (((JCClassDecl)frame).typarams.contains(tree)) {
p.type = TargetType.CLASS_TYPE_PARAMETER;
p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree);
} else {
Assert.error("Could not determine position of tree " + tree +
" within frame " + frame);
}
return;
case METHOD: {
JCMethodDecl frameMethod = (JCMethodDecl) frame;
p.pos = frame.pos;
if (frameMethod.thrown.contains(tree)) {
p.type = TargetType.THROWS;
p.type_index = frameMethod.thrown.indexOf(tree);
} else if (frameMethod.restype == tree) {
p.type = TargetType.METHOD_RETURN;
} else if (frameMethod.typarams.contains(tree)) {
p.type = TargetType.METHOD_TYPE_PARAMETER;
p.parameter_index = frameMethod.typarams.indexOf(tree);
} else {
Assert.error("Could not determine position of tree " + tree +
" within frame " + frame);
}
return;
}
case PARAMETERIZED_TYPE: {
List<JCTree> newPath = path.tail;
if (((JCTypeApply)frame).clazz == tree) {
// generic: RAW; noop
} else if (((JCTypeApply)frame).arguments.contains(tree)) {
JCTypeApply taframe = (JCTypeApply) frame;
int arg = taframe.arguments.indexOf(tree);
p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg));
Type typeToUse;
if (newPath.tail != null && newPath.tail.head.hasTag(Tag.NEWCLASS)) {
// If we are within an anonymous class instantiation, use its type,
// because it contains a correctly nested type.
typeToUse = newPath.tail.head.type;
} else {
typeToUse = taframe.type;
}
locateNestedTypes(typeToUse, p);
} else {
Assert.error("Could not determine type argument position of tree " + tree +
" within frame " + frame);
}
resolveFrame(newPath.head, newPath.tail.head, newPath, p);
return;
}
case MEMBER_REFERENCE: {
JCMemberReference mrframe = (JCMemberReference) frame;
if (mrframe.expr == tree) {
switch (mrframe.mode) {
case INVOKE:
p.type = TargetType.METHOD_REFERENCE;
break;
case NEW:
p.type = TargetType.CONSTRUCTOR_REFERENCE;
break;
default:
Assert.error("Unknown method reference mode " + mrframe.mode +
" for tree " + tree + " within frame " + frame);
}
p.pos = frame.pos;
} else if (mrframe.typeargs != null &&
mrframe.typeargs.contains(tree)) {
int arg = mrframe.typeargs.indexOf(tree);
p.type_index = arg;
switch (mrframe.mode) {
case INVOKE:
p.type = TargetType.METHOD_REFERENCE_TYPE_ARGUMENT;
break;
case NEW:
p.type = TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
break;
default:
Assert.error("Unknown method reference mode " + mrframe.mode +
" for tree " + tree + " within frame " + frame);
}
p.pos = frame.pos;
} else {
Assert.error("Could not determine type argument position of tree " + tree +
" within frame " + frame);
}
return;
}
case ARRAY_TYPE: {
ListBuffer<TypePathEntry> index = new ListBuffer<>();
index = index.append(TypePathEntry.ARRAY);
List<JCTree> newPath = path.tail;
while (true) {
JCTree npHead = newPath.tail.head;
if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) {
newPath = newPath.tail;
index = index.append(TypePathEntry.ARRAY);
} else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
newPath = newPath.tail;
} else {
break;
}
}
p.location = p.location.prependList(index.toList());
resolveFrame(newPath.head, newPath.tail.head, newPath, p);
return;
}
case TYPE_PARAMETER:
if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) {
JCClassDecl clazz = (JCClassDecl)path.tail.tail.head;
p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND;
p.parameter_index = clazz.typarams.indexOf(path.tail.head);
p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) {
// Account for an implicit Object as bound 0