• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5  * in compliance with the License. You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software distributed under the License
10  * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11  * or implied. See the License for the specific language governing permissions and limitations under
12  * the License.
13  */
14 
15 package com.google.googlejavaformat.java;
16 
17 import com.sun.source.tree.ClassTree;
18 import com.sun.source.tree.CompoundAssignmentTree;
19 import com.sun.source.tree.ExpressionTree;
20 import com.sun.source.tree.IdentifierTree;
21 import com.sun.source.tree.MemberSelectTree;
22 import com.sun.source.tree.MethodInvocationTree;
23 import com.sun.source.tree.ParenthesizedTree;
24 import com.sun.source.tree.Tree;
25 import com.sun.source.util.TreePath;
26 import com.sun.tools.javac.tree.JCTree;
27 import com.sun.tools.javac.tree.Pretty;
28 import com.sun.tools.javac.tree.TreeInfo;
29 import java.io.IOError;
30 import java.io.IOException;
31 import javax.lang.model.element.Name;
32 
33 /** Utilities for working with {@link Tree}s. */
34 class Trees {
35   /** Returns the length of the source for the node. */
getLength(Tree tree, TreePath path)36   static int getLength(Tree tree, TreePath path) {
37     return getEndPosition(tree, path) - getStartPosition(tree);
38   }
39 
40   /** Returns the source start position of the node. */
getStartPosition(Tree expression)41   static int getStartPosition(Tree expression) {
42     return ((JCTree) expression).getStartPosition();
43   }
44 
45   /** Returns the source end position of the node. */
getEndPosition(Tree expression, TreePath path)46   static int getEndPosition(Tree expression, TreePath path) {
47     return ((JCTree) expression)
48         .getEndPosition(((JCTree.JCCompilationUnit) path.getCompilationUnit()).endPositions);
49   }
50 
51   /** Returns the source text for the node. */
getSourceForNode(Tree node, TreePath path)52   static String getSourceForNode(Tree node, TreePath path) {
53     CharSequence source;
54     try {
55       source = path.getCompilationUnit().getSourceFile().getCharContent(false);
56     } catch (IOException e) {
57       throw new IOError(e);
58     }
59     return source.subSequence(getStartPosition(node), getEndPosition(node, path)).toString();
60   }
61 
62   /** Returns the simple name of a (possibly qualified) method invocation expression. */
getMethodName(MethodInvocationTree methodInvocation)63   static Name getMethodName(MethodInvocationTree methodInvocation) {
64     ExpressionTree select = methodInvocation.getMethodSelect();
65     return select instanceof MemberSelectTree
66         ? ((MemberSelectTree) select).getIdentifier()
67         : ((IdentifierTree) select).getName();
68   }
69 
70   /** Returns the receiver of a qualified method invocation expression, or {@code null}. */
getMethodReceiver(MethodInvocationTree methodInvocation)71   static ExpressionTree getMethodReceiver(MethodInvocationTree methodInvocation) {
72     ExpressionTree select = methodInvocation.getMethodSelect();
73     return select instanceof MemberSelectTree ? ((MemberSelectTree) select).getExpression() : null;
74   }
75 
76   /** Returns the string name of an operator, including assignment and compound assignment. */
operatorName(ExpressionTree expression)77   static String operatorName(ExpressionTree expression) {
78     JCTree.Tag tag = ((JCTree) expression).getTag();
79     if (tag == JCTree.Tag.ASSIGN) {
80       return "=";
81     }
82     boolean assignOp = expression instanceof CompoundAssignmentTree;
83     if (assignOp) {
84       tag = tag.noAssignOp();
85     }
86     String name = new Pretty(/*writer*/ null, /*sourceOutput*/ true).operatorName(tag);
87     return assignOp ? name + "=" : name;
88   }
89 
90   /** Returns the precedence of an expression's operator. */
precedence(ExpressionTree expression)91   static int precedence(ExpressionTree expression) {
92     return TreeInfo.opPrec(((JCTree) expression).getTag());
93   }
94 
95   /**
96    * Returns the enclosing type declaration (class, enum, interface, or annotation) for the given
97    * path.
98    */
getEnclosingTypeDeclaration(TreePath path)99   static ClassTree getEnclosingTypeDeclaration(TreePath path) {
100     for (; path != null; path = path.getParentPath()) {
101       switch (path.getLeaf().getKind()) {
102         case CLASS:
103         case ENUM:
104         case INTERFACE:
105         case ANNOTATED_TYPE:
106           return (ClassTree) path.getLeaf();
107         default:
108           break;
109       }
110     }
111     throw new AssertionError();
112   }
113 
114   /** Skips a single parenthesized tree. */
skipParen(ExpressionTree node)115   static ExpressionTree skipParen(ExpressionTree node) {
116     return ((ParenthesizedTree) node).getExpression();
117   }
118 }
119