1 19 20 package org.netbeans.modules.java.hints; 21 22 import com.sun.source.tree.ArrayAccessTree; 23 import com.sun.source.tree.AssignmentTree; 24 import com.sun.source.tree.ExpressionTree; 25 import com.sun.source.tree.IdentifierTree; 26 import com.sun.source.tree.MemberSelectTree; 27 import com.sun.source.tree.MethodInvocationTree; 28 import com.sun.source.tree.MethodTree; 29 import com.sun.source.tree.NewClassTree; 30 import com.sun.source.tree.ParameterizedTypeTree; 31 import com.sun.source.tree.ReturnTree; 32 import com.sun.source.tree.Tree; 33 import com.sun.source.tree.Tree.Kind; 34 import com.sun.source.tree.VariableTree; 35 import com.sun.source.util.TreePath; 36 import com.sun.source.util.TreeScanner; 37 import java.util.ArrayList ; 38 import java.util.Collections ; 39 import java.util.List ; 40 import java.util.Set ; 41 import javax.lang.model.type.TypeKind; 42 import javax.lang.model.type.TypeMirror; 43 import org.netbeans.api.java.source.CompilationInfo; 44 import org.netbeans.modules.editor.java.Utilities; 45 import org.netbeans.modules.java.hints.spi.ErrorRule; 46 import org.netbeans.spi.editor.hints.Fix; 47 48 49 53 public final class AddCastCreator implements ErrorRule<Void > { 54 55 static void computeType(CompilationInfo info, int offset, TypeMirror[] tm, ExpressionTree[] expression, Tree[] leaf) { 56 TreePath path = info.getTreeUtilities().pathFor(offset); 57 58 while (path != null) { 60 Tree scope = path.getLeaf(); 61 TypeMirror expected = null; 62 ExpressionTree found = null; 63 64 if (scope.getKind() == Kind.VARIABLE && ((VariableTree) scope).getInitializer() != null) { 65 expected = info.getTrees().getTypeMirror(path); 66 found = ((VariableTree) scope).getInitializer(); 67 } 68 69 if (scope.getKind() == Kind.ASSIGNMENT) { 70 expected = info.getTrees().getTypeMirror(path); 71 found = ((AssignmentTree) scope).getExpression(); 72 } 73 74 if (scope.getKind() == Kind.RETURN) { 75 TreePath parents = path; 76 77 while (parents != null && parents.getLeaf().getKind() != Kind.METHOD) 78 parents = parents.getParentPath(); 79 80 if (parents != null) { 81 expected = info.getTrees().getTypeMirror(new TreePath(parents, ((MethodTree) parents.getLeaf()).getReturnType())); 82 found = ((ReturnTree) scope).getExpression(); 83 } 84 } 85 86 if (expected != null) { 87 TypeMirror foundTM = info.getTrees().getTypeMirror(new TreePath(path, found)); 88 89 if (foundTM.getKind() == TypeKind.EXECUTABLE) { 90 } else { 92 if ( !info.getTypes().isAssignable(foundTM, expected) 93 94 && foundTM.getKind() != TypeKind.ERROR 95 && expected.getKind() != TypeKind.ERROR) { 96 tm[0] = expected; 97 expression[0] = found; 98 leaf[0] = scope; 99 } 100 } 101 } 102 103 path = path.getParentPath(); 104 } 105 } 106 107 public Set <String > getCodes() { 108 return Collections.singleton("compiler.err.prob.found.req"); 109 } 110 111 public List <Fix> run(CompilationInfo info, String diagnosticKey, int offset, TreePath treePath, Data<Void > data) { 112 List <Fix> result = new ArrayList <Fix>(); 113 TypeMirror[] tm = new TypeMirror[1]; 114 ExpressionTree[] expression = new ExpressionTree[1]; 115 Tree[] leaf = new Tree[1]; 116 117 computeType(info, offset, tm, expression, leaf); 118 119 if (tm[0] != null) { 120 int position = (int) info.getTrees().getSourcePositions().getStartPosition(info.getCompilationUnit(), expression[0]); 121 122 result.add(new AddCastHint(info.getJavaSource(), new HintDisplayNameVisitor().scan(expression[0], null), Utilities.getTypeName(tm[0], false).toString(), position)); 123 } 124 125 return result; 126 } 127 128 public void cancel() { 129 } 131 132 public String getId() { 133 return AddCastCreator.class.getName(); 134 } 135 136 public String getDisplayName() { 137 return "Add Cast Fix"; 138 } 139 140 public String getDescription() { 141 return "Add Cast Fix"; 142 } 143 144 private static class HintDisplayNameVisitor extends TreeScanner<String , Void > { 145 146 public @Override String visitIdentifier(IdentifierTree tree, Void v) { 147 return "..." + tree.getName().toString(); 148 } 149 150 public @Override String visitMethodInvocation(MethodInvocationTree tree, Void v) { 151 ExpressionTree methodSelect = tree.getMethodSelect(); 152 153 return "..." + simpleName(methodSelect) + "(...)"; 154 } 155 156 public @Override String visitArrayAccess(ArrayAccessTree node, Void p) { 157 return "..." + simpleName(node.getExpression()) + "[]"; 158 } 159 160 public @Override String visitNewClass(NewClassTree nct, Void p) { 161 return "...new " + simpleName(nct.getIdentifier()) + "(...)"; 162 } 163 164 private String simpleName(Tree t) { 165 if (t.getKind() == Kind.IDENTIFIER) { 166 return ((IdentifierTree) t).getName().toString(); 167 } 168 169 if (t.getKind() == Kind.MEMBER_SELECT) { 170 return ((MemberSelectTree) t).getIdentifier().toString(); 171 } 172 173 if (t.getKind() == Kind.METHOD_INVOCATION) { 174 return scan(t, null); 175 } 176 177 if (t.getKind() == Kind.PARAMETERIZED_TYPE) { 178 return simpleName(((ParameterizedTypeTree) t).getType()) + "<...>"; 179 } 180 181 throw new IllegalStateException ("Currently unsupported kind of tree: " + t.getKind()); 182 } 183 } 184 185 } 186 | Popular Tags |