下面列出了javax.lang.model.element.QualifiedNameable#com.sun.source.tree.MemberSelectTree 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* Helper method for import declarations, names, and qualified names.
*/
private void visitName(Tree node) {
Deque<Name> stack = new ArrayDeque<>();
for (; node instanceof MemberSelectTree; node = ((MemberSelectTree) node).getExpression()) {
stack.addFirst(((MemberSelectTree) node).getIdentifier());
}
stack.addFirst(((IdentifierTree) node).getName());
boolean first = true;
for (Name name : stack) {
if (!first) {
token(".");
}
token(name.toString());
first = false;
}
}
private void dotExpressionUpToArgs(ExpressionTree expression, Optional<BreakTag> tyargTag) {
expression = getArrayBase(expression);
switch (expression.getKind()) {
case MEMBER_SELECT:
MemberSelectTree fieldAccess = (MemberSelectTree) expression;
visit(fieldAccess.getIdentifier());
break;
case METHOD_INVOCATION:
MethodInvocationTree methodInvocation = (MethodInvocationTree) expression;
if (!methodInvocation.getTypeArguments().isEmpty()) {
builder.open(plusFour);
addTypeArguments(methodInvocation.getTypeArguments(), ZERO);
// TODO(jdd): Should indent the name -4.
builder.breakOp(Doc.FillMode.UNIFIED, "", ZERO, tyargTag);
builder.close();
}
visit(getMethodName(methodInvocation));
break;
case IDENTIFIER:
visit(((IdentifierTree) expression).getName());
break;
default:
scan(expression, null);
break;
}
}
private API getXPAPI(ExpressionTree et) {
et = ASTHelpers.stripParentheses(et);
Kind k = et.getKind();
if (k.equals(Tree.Kind.METHOD_INVOCATION)) {
MethodInvocationTree mit = (MethodInvocationTree) et;
if (!mit.getMethodSelect().getKind().equals(Kind.MEMBER_SELECT)) {
return API.UNKNOWN;
}
MemberSelectTree mst = (MemberSelectTree) mit.getMethodSelect();
String methodName = mst.getIdentifier().toString();
if (!disabled && configMethodProperties.containsKey(methodName)) {
return getXPAPI(mit, configMethodProperties.get(methodName));
}
}
return API.UNKNOWN;
}
@Override
public Object visitMemberSelect(MemberSelectTree node, Object p) {
String exp = node.getExpression().toString();
// ClassName.this
if (exp.equals("this") || exp.endsWith(".this")) { // NOI18N
addInstanceForType(findType(node.getExpression()));
} else if (exp.equals("super")) { // NOI18N
// reference to superclass of this type
addSuperInstance(enclosingType);
} else if (exp.endsWith(".super")) { // NOI18N
// this is a reference to the superclass of some enclosing type.
if (node.getExpression().getKind() == Tree.Kind.MEMBER_SELECT) {
Tree t = ((MemberSelectTree)node.getExpression()).getExpression();
addSuperInstance(findType(t));
}
} else if (node.getIdentifier().contentEquals("this")) { // NOI18N
// reference to this
addInstanceForType(findType(node.getExpression()));
} else {
// references to Clazz.super are invalid, references to Clazz.super.whatever() must be
// a pert of a broader memberSelect, which will be caught one level up.
return super.visitMemberSelect(node, p);
}
return null;
}
public void testForEachLoop() throws Exception {
prepareTest("Test", "package test; public class Test { public Test(java.util.List<String> ll) { for (String s : ll.subList(0, ll.size()) ) { } } }");
TreePath tp1 = info.getTreeUtilities().pathFor(122 - 30);
assertEquals(Kind.IDENTIFIER, tp1.getLeaf().getKind());
assertEquals("ll", ((IdentifierTree) tp1.getLeaf()).getName().toString());
TreePath tp2 = info.getTreeUtilities().pathFor(127 - 30);
assertEquals(Kind.MEMBER_SELECT, tp2.getLeaf().getKind());
assertEquals("subList", ((MemberSelectTree) tp2.getLeaf()).getIdentifier().toString());
TreePath tp3 = info.getTreeUtilities().pathFor(140 - 30);
assertEquals(Kind.MEMBER_SELECT, tp3.getLeaf().getKind());
assertEquals("size", ((MemberSelectTree) tp3.getLeaf()).getIdentifier().toString());
TreePath tp4 = info.getTreeUtilities().pathFor(146 - 30);
assertEquals(Kind.METHOD_INVOCATION, tp4.getLeaf().getKind());
assertEquals("subList", ((MemberSelectTree) ((MethodInvocationTree) tp4.getLeaf()).getMethodSelect()).getIdentifier().toString());
}
@Override
public Void visitImport(ImportTree node, Stack<Tree> p) {
if (node.isStatic() && toFind.getModifiers().contains(Modifier.STATIC)) {
Tree qualIdent = node.getQualifiedIdentifier();
if (qualIdent.getKind() == Kind.MEMBER_SELECT) {
MemberSelectTree mst = (MemberSelectTree) qualIdent;
if (toFind.getSimpleName().contentEquals(mst.getIdentifier())) {
Element el = info.getTrees().getElement(new TreePath(getCurrentPath(), mst.getExpression()));
if (el != null && el.equals(toFind.getEnclosingElement())) {
Token<JavaTokenId> t = Utilities.getToken(info, doc, new TreePath(getCurrentPath(), mst));
if (t != null)
usages.add(t);
}
}
}
}
return super.visitImport(node, p);
}
@Override
public Void visitImport(ImportTree node, Void p) {
if (node.isStatic() && toFind.getModifiers().contains(Modifier.STATIC)) {
Tree qualIdent = node.getQualifiedIdentifier();
if (qualIdent.getKind() == Kind.MEMBER_SELECT) {
MemberSelectTree mst = (MemberSelectTree) qualIdent;
if (toFind.getSimpleName().contentEquals(mst.getIdentifier())) {
Element el = info.getTrees().getElement(new TreePath(getCurrentPath(), mst.getExpression()));
if (el != null && el.equals(toFind.getEnclosingElement())) {
try {
int[] span = treeUtils.findNameSpan(mst);
if(span != null) {
MutablePositionRegion region = createRegion(doc, span[0], span[1]);
usages.add(region);
}
} catch (BadLocationException ex) {
Exceptions.printStackTrace(ex);
}
}
}
}
}
return super.visitImport(node, p);
}
@Hint(displayName = "#DN_Imports_EXCLUDED", description = "#DESC_Imports_EXCLUDED", category="imports", id="Imports_EXCLUDED", options=Options.QUERY)
@TriggerTreeKind(Kind.IMPORT)
public static ErrorDescription exlucded(HintContext ctx) throws IOException {
ImportTree it = (ImportTree) ctx.getPath().getLeaf();
if (it.isStatic() || !(it.getQualifiedIdentifier() instanceof MemberSelectTree)) {
return null; // XXX
}
MemberSelectTree ms = (MemberSelectTree) it.getQualifiedIdentifier();
String pkg = ms.getExpression().toString();
String klass = ms.getIdentifier().toString();
String exp = pkg + "." + (!klass.equals("*") ? klass : ""); //NOI18N
if (Utilities.isExcluded(exp)) {
return ErrorDescriptionFactory.forTree(ctx, ctx.getPath(), NbBundle.getMessage(Imports.class, "DN_Imports_EXCLUDED"));
}
return null;
}
private void dotExpressionUpToArgs(ExpressionTree expression, Optional<BreakTag> tyargTag) {
expression = getArrayBase(expression);
switch (expression.getKind()) {
case MEMBER_SELECT:
MemberSelectTree fieldAccess = (MemberSelectTree) expression;
visit(fieldAccess.getIdentifier());
break;
case METHOD_INVOCATION:
MethodInvocationTree methodInvocation = (MethodInvocationTree) expression;
if (!methodInvocation.getTypeArguments().isEmpty()) {
builder.open(plusFour);
addTypeArguments(methodInvocation.getTypeArguments(), ZERO);
// TODO(jdd): Should indent the name -4.
builder.breakOp(Doc.FillMode.UNIFIED, "", ZERO, tyargTag);
builder.close();
}
visit(getMethodName(methodInvocation));
break;
case IDENTIFIER:
visit(((IdentifierTree) expression).getName());
break;
default:
scan(expression, null);
break;
}
}
@Override
public Object visitMemberSelect(MemberSelectTree node, Object p) {
if (wc.getTrees().getElement(new TreePath(getCurrentPath(), node.getExpression())) != varElement) {
return super.visitMemberSelect(node, p);
}
Element target = wc.getTrees().getElement(getCurrentPath());
if (target != null && target.getKind() == ElementKind.METHOD) {
Tree x = getCurrentPath().getParentPath().getLeaf();
Tree.Kind k = x.getKind();
if (k == Tree.Kind.METHOD_INVOCATION) {
if (node.getIdentifier().contentEquals("toString")) { // NOI18N
// rewrite the node to just the variable, which is going to change the type
gu.copyComments(x, node.getExpression(), true);
gu.copyComments(x, node.getExpression(), false);
wc.rewrite(x, node.getExpression());
}
}
}
return super.visitMemberSelect(node, p);
}
@Override
@Nullable
public final R visitMemberSelect(MemberSelectTree node, P p) {
TreePath referencingPath = getCurrentPath();
Element referencedElement = Objects.requireNonNull(trees.getElement(referencingPath));
return resolveElement(referencingPath, referencedElement, p);
}
@Override
public Pair<ASTRecord, Integer> visitMemberSelect(MemberSelectTree node, Insertion ins) {
dbug.debug("TypePositionFinder.visitMemberSelect(%s)%n", node);
JCFieldAccess raw = (JCFieldAccess) node;
return Pair.of(astRecord(node),
raw.getEndPosition(tree.endPositions) - raw.name.length());
}
@Override
public UExpression visitMemberSelect(MemberSelectTree tree, Void v) {
Symbol sym = ASTHelpers.getSymbol(tree);
if (sym instanceof ClassSymbol) {
return UClassIdent.create((ClassSymbol) sym);
} else if (sym.isStatic()) {
ExpressionTree selected = tree.getExpression();
checkState(ASTHelpers.getSymbol(selected) instanceof ClassSymbol,
"Refaster cannot match static methods used on instances");
return staticMember(sym);
}
return UMemberSelect.create(template(tree.getExpression()),
tree.getIdentifier().toString(), template(sym.type));
}
private static String fullyQualifiedPath(TreePath path) {
ExpressionTree packageNameExpr = path.getCompilationUnit().getPackageName();
MemberSelectTree packageID = packageNameExpr.getKind() == Tree.Kind.MEMBER_SELECT
? ((MemberSelectTree) packageNameExpr) : null;
StringBuilder result = new StringBuilder();
if (packageID != null) {
result.append(packageID.getExpression().toString())
.append(".")
.append(packageID.getIdentifier().toString());
}
Tree.Kind kind = path.getLeaf().getKind();
String leafName = null;
if (kind == Tree.Kind.CLASS || kind == Tree.Kind.INTERFACE) {
leafName = ((ClassTree) path.getLeaf()).getSimpleName().toString();
} else if (kind == Tree.Kind.ENUM) {
if (path.getParentPath() != null) {
Tree parent = path.getParentPath().getLeaf();
if (parent.getKind() == Tree.Kind.CLASS || parent.getKind() == Tree.Kind.INTERFACE) {
result.append(((ClassTree) parent).getSimpleName().toString()).append(".");
}
leafName = ((ClassTree) path.getLeaf()).getSimpleName().toString();
}
}
// leafName can be empty for anonymous inner classes, for example.
boolean isUsefulLeaf = leafName != null && !leafName.isEmpty();
if (isUsefulLeaf) {
result.append(".").append(leafName);
}
return isUsefulLeaf ? result.toString() : null;
}
private static void handleImport(Trees trees, ImportsTracker imports, TreePath importTreePath) {
ImportTree importTree = (ImportTree) importTreePath.getLeaf();
MemberSelectTree importedExpression = (MemberSelectTree) importTree.getQualifiedIdentifier();
TreePath importedExpressionPath = new TreePath(importTreePath, importedExpression);
Name simpleName = importedExpression.getIdentifier();
boolean isStarImport = simpleName.contentEquals("*");
if (!isStarImport && !importTree.isStatic()) {
TypeElement importedType = (TypeElement) trees.getElement(importedExpressionPath);
imports.importType(importedType, importedExpressionPath);
} else {
ExpressionTree containingElementExpression = importedExpression.getExpression();
TreePath containingElementExpressionPath =
new TreePath(importedExpressionPath, containingElementExpression);
QualifiedNameable containingElement =
(QualifiedNameable) trees.getElement(containingElementExpressionPath);
if (importTree.isStatic()) {
TypeElement containingType = (TypeElement) containingElement;
if (isStarImport) {
imports.importStaticMembers((TypeElement) containingElement);
} else {
imports.importStatic(containingType, simpleName);
}
} else {
// Normal star import
imports.importMembers(containingElement, containingElementExpressionPath);
}
}
}
/**
* Returns the simple name of a (possibly qualified) method invocation expression.
*/
static Name getMethodName(MethodInvocationTree methodInvocation) {
ExpressionTree select = methodInvocation.getMethodSelect();
return select instanceof MemberSelectTree
? ((MemberSelectTree) select).getIdentifier()
: ((IdentifierTree) select).getName();
}
@SuppressWarnings("TreeToString")
@Override
public Description matchImport(ImportTree importTree, VisitorState visitorState) {
if (importTree.isStatic()) {
Tree importIdentifier = importTree.getQualifiedIdentifier();
if (importIdentifier.getKind().equals(Kind.MEMBER_SELECT)) {
MemberSelectTree memberSelectTree = (MemberSelectTree) importIdentifier;
if (memberSelectTree.getIdentifier().toString().endsWith(xpFlagName)
|| (treatmentGroupsEnum != null
&& memberSelectTree.getExpression().toString().startsWith(treatmentGroupsEnum))) {
return buildDescription(importTree)
.addFix(SuggestedFix.replace(importTree, "", 0, 1))
.build();
} else if (treatmentGroup.length() > 0 && treatmentGroupsEnum == null) {
// Check if this import is for values in the same enum that includes the treatmentGroup
Symbol importSymbol = ASTHelpers.getSymbol(memberSelectTree.getExpression());
if (importSymbol.getKind().equals(ElementKind.ENUM)
&& isTreatmentGroupEnum((Symbol.ClassSymbol) importSymbol)) {
treatmentGroupsEnum = ((Symbol.ClassSymbol) importSymbol).fullname.toString();
return buildDescription(importTree)
.addFix(SuggestedFix.replace(importTree, "", 0, 1))
.build();
}
}
}
}
return Description.NO_MATCH;
}
@Override
public Set<String> visitMemberSelect(MemberSelectTree reference, Void v) {
Set<String> expressionSet = scan(reference.getExpression(), v);
if (expressionSet.size() != 1) {
throw new AssertionError("Internal error in NameFinder. Expected to find exactly one "
+ "identifier in the expression set. Found " + expressionSet);
}
String expressionStr = expressionSet.iterator().next();
return ImmutableSet.of(String.format("%s.%s", expressionStr, reference.getIdentifier()));
}
private static void verifyLambdaScopeCorrect(final String packageClause) throws Exception {
JavacTool tool = JavacTool.create();
JavaFileObject source = new SimpleJavaFileObject(URI.create("mem://Test.java"), Kind.SOURCE) {
@Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return packageClause + SOURCE_CODE;
}
@Override public boolean isNameCompatible(String simpleName, Kind kind) {
return true;
}
};
Iterable<? extends JavaFileObject> fos = Collections.singletonList(source);
JavacTask task = tool.getTask(null, null, null, new ArrayList<String>(), null, fos);
final Types types = JavacTypes.instance(((JavacTaskImpl) task).getContext());
final Trees trees = Trees.instance(task);
CompilationUnitTree cu = task.parse().iterator().next();
task.analyze();
new TreePathScanner<Void, Void>() {
@Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
if (node.getIdentifier().contentEquals("correct")) {
TypeMirror xType = trees.getTypeMirror(new TreePath(getCurrentPath(), node.getExpression()));
Scope scope = trees.getScope(getCurrentPath());
for (Element l : scope.getLocalElements()) {
if (!l.getSimpleName().contentEquals("x")) continue;
if (!types.isSameType(xType, l.asType())) {
throw new IllegalStateException("Incorrect variable type in scope: " + l.asType() + "; should be: " + xType);
}
}
}
return super.visitMemberSelect(node, p);
}
}.scan(cu, null);
}
private boolean checkTypePath(int i, Tree typeTree) {
try {
loop: while (typeTree != null && i < astPath.size()) {
ASTPath.ASTEntry entry = astPath.get(i);
Tree.Kind kind = entry.getTreeKind();
switch (kind) {
case ANNOTATED_TYPE:
typeTree = ((AnnotatedTypeTree) typeTree)
.getUnderlyingType();
continue;
case ARRAY_TYPE:
typeTree = ((ArrayTypeTree) typeTree).getType();
break;
case MEMBER_SELECT:
typeTree = ((MemberSelectTree) typeTree).getExpression();
break;
case PARAMETERIZED_TYPE:
if (entry.childSelectorIs(ASTPath.TYPE_ARGUMENT)) {
int arg = entry.getArgument();
typeTree = ((ParameterizedTypeTree) typeTree)
.getTypeArguments().get(arg);
} else { // TYPE
typeTree = ((ParameterizedTypeTree) typeTree).getType();
}
break;
default:
if (isWildcard(kind)) {
return ++i == astPath.size(); // ???
}
break loop;
}
++i;
}
} catch (RuntimeException ex) {}
return false;
}
/**
* Creates a new annotation argument whose value is a member of a type. For
* example it can be used to generate <code>@Target(ElementType.CONSTRUCTOR)</code>.
*
* @param argumentName the argument name; cannot be null.
* @param argumentType the fully-qualified name of the type whose member is to be invoked
* (e.g. <code>java.lang.annotations.ElementType</code> in the previous
* example); cannot be null.
* @param argumentTypeField a field of <code>argumentType</code>
* (e.g. <code>CONSTRUCTOR</code> in the previous example);
* cannot be null.
* @return the new annotation argument; never null.
*/
public ExpressionTree createAnnotationArgument(String argumentName, String argumentType, String argumentTypeField) {
Parameters.javaIdentifierOrNull("argumentName", argumentName); // NOI18N
Parameters.notNull("argumentType", argumentType); // NOI18N
Parameters.javaIdentifier("argumentTypeField", argumentTypeField); // NOI18N
TreeMaker make = getTreeMaker();
MemberSelectTree argumentValueTree = make.MemberSelect(createQualIdent(argumentType), argumentTypeField);
if (argumentName == null) {
return argumentValueTree;
} else {
return make.Assignment(make.Identifier(argumentName), argumentValueTree);
}
}
@Override
public Object visitIdentifier(IdentifierTree node, Object p) {
if (!fieldNames.contains(node.getName())) {
return null;
}
// TODO do not track dependencies for method refs
boolean ok = false;
Tree parent = getCurrentPath().getParentPath().getLeaf();
switch (parent.getKind()) {
case MEMBER_SELECT:
// dependency is only introduced by dereferencing the identifier.
ok = ((MemberSelectTree)parent).getExpression() != node;
break;
case ASSIGNMENT:
ok = ((AssignmentTree)parent).getVariable() == node;
break;
}
if (ok) {
return null;
}
if (!ok) {
if (collectNames) {
if (node.getName().equals(insertedName)) {
revDependencies.add(member);
}
} else {
addDependency(node.getName());
}
}
return null;
}
@Override
public Object visitMemberSelect(MemberSelectTree node, Object p) {
Tree parent = getCurrentPath().getParentPath().getLeaf();
if (fieldNames.contains(node.getIdentifier())) {
// NOTE: because of JLS 8.3.3, forward reference which is NOT a simple name (even this.id, or MyClassname.this.id !!)
// is NOT illegal, so I will not count the appearance as a dependency
}
Object o = super.visitMemberSelect(node, p);
return o;
}
private static void verifyLambdaScopeCorrect(final String packageClause) throws Exception {
JavacTool tool = JavacTool.create();
JavaFileObject source = new SimpleJavaFileObject(URI.create("mem://Test.java"), Kind.SOURCE) {
@Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
return packageClause + SOURCE_CODE;
}
@Override public boolean isNameCompatible(String simpleName, Kind kind) {
return !"module-info".equals(simpleName);
}
};
Iterable<? extends JavaFileObject> fos = Collections.singletonList(source);
JavacTask task = tool.getTask(null, null, null, new ArrayList<String>(), null, fos);
final Types types = JavacTypes.instance(((JavacTaskImpl) task).getContext());
final Trees trees = Trees.instance(task);
CompilationUnitTree cu = task.parse().iterator().next();
task.analyze();
new TreePathScanner<Void, Void>() {
@Override public Void visitMemberSelect(MemberSelectTree node, Void p) {
if (node.getIdentifier().contentEquals("correct")) {
TypeMirror xType = trees.getTypeMirror(new TreePath(getCurrentPath(), node.getExpression()));
Scope scope = trees.getScope(getCurrentPath());
for (Element l : scope.getLocalElements()) {
if (!l.getSimpleName().contentEquals("x")) continue;
if (!types.isSameType(xType, l.asType())) {
throw new IllegalStateException("Incorrect variable type in scope: " + l.asType() + "; should be: " + xType);
}
}
}
return super.visitMemberSelect(node, p);
}
}.scan(cu, null);
}
private static String name(Tree tree) {
switch (tree.getKind()) {
case VARIABLE:
return ((VariableTree)tree).getName().toString();
case METHOD:
return ((MethodTree)tree).getName().toString();
case CLASS:
return ((ClassTree)tree).getSimpleName().toString();
case IDENTIFIER:
return ((IdentifierTree)tree).getName().toString();
case MEMBER_SELECT:
return name(((MemberSelectTree)tree).getExpression()) + '.' + ((MemberSelectTree)tree).getIdentifier();
}
return ""; //NOI18N
}
@Override
public Symbol visitMemberSelect(MemberSelectTree node, Env<AttrContext> env) {
Symbol site = visit(node.getExpression(), env);
if (site.kind == ERR)
return site;
Name name = (Name)node.getIdentifier();
if (site.kind == PCK) {
env.toplevel.packge = (PackageSymbol)site;
return rs.findIdentInPackage(env, (TypeSymbol)site, name, TYP | PCK);
} else {
env.enclClass.sym = (ClassSymbol)site;
return rs.findMemberType(env, site.asType(), name, (TypeSymbol)site);
}
}
public Void visitMemberSelect(MemberSelectTree node, Object p) {
System.err.println("visitMemberSelect: " + node.getIdentifier());
super.visitMemberSelect(node, p);
MemberSelectTree copy = make.setLabel(node, node.getIdentifier() + "0");
this.copy.rewrite(node, copy);
return null;
}
private void buildObservableCallChain(MethodInvocationTree tree) {
ExpressionTree methodSelect = tree.getMethodSelect();
if (methodSelect instanceof MemberSelectTree) {
ExpressionTree receiverExpression = ((MemberSelectTree) methodSelect).getExpression();
if (receiverExpression instanceof MethodInvocationTree) {
observableOuterCallInChain.put((MethodInvocationTree) receiverExpression, tree);
}
} // ToDo: What else can be here? If there are other cases than MemberSelectTree, handle them.
}
private String getLastComponent(Tree name) {
switch (name.getKind()) {
case IDENTIFIER:
return ((IdentifierTree) name).getName().toString();
case MEMBER_SELECT:
return ((MemberSelectTree) name).getIdentifier().toString();
default:
return "";
}
}
@Override
public Void visitMemberSelect(MemberSelectTree tree, Void p) {
if (info.getTreeUtilities().isSynthetic(getCurrentPath()))
return null;
long memberSelectBypassLoc = memberSelectBypass;
memberSelectBypass = -1;
Element el = info.getTrees().getElement(getCurrentPath());
if (el != null && el.getKind() == ElementKind.MODULE) {
//Xxx
handlePossibleIdentifier(getCurrentPath(), false);
tl.moduleNameHere(tree, tree2Tokens);
return null;
}
super.visitMemberSelect(tree, p);
tl.moveToEnd(tree.getExpression());
if (memberSelectBypassLoc != (-1)) {
tl.moveToOffset(memberSelectBypassLoc);
}
handlePossibleIdentifier(getCurrentPath(), false);
firstIdentifier(tree.getIdentifier().toString());
addParameterInlineHint(tree);
return null;
}