1 19 20 package org.netbeans.modules.debugger.jpda.projects; 21 22 import com.sun.corba.se.impl.protocol.InfoOnlyServantCacheLocalCRDImpl; 23 import com.sun.source.tree.ArrayAccessTree; 24 import com.sun.source.tree.AssignmentTree; 25 import com.sun.source.tree.BinaryTree; 26 import com.sun.source.tree.CompilationUnitTree; 27 import com.sun.source.tree.CompoundAssignmentTree; 28 import com.sun.source.tree.ConditionalExpressionTree; 29 import com.sun.source.tree.ExpressionTree; 30 import com.sun.source.tree.IdentifierTree; 31 import com.sun.source.tree.InstanceOfTree; 32 import com.sun.source.tree.LineMap; 33 import com.sun.source.tree.LiteralTree; 34 import com.sun.source.tree.MemberSelectTree; 35 import com.sun.source.tree.MethodInvocationTree; 36 import com.sun.source.tree.NewArrayTree; 37 import com.sun.source.tree.NewClassTree; 38 import com.sun.source.tree.ParenthesizedTree; 39 import com.sun.source.tree.Tree; 40 import com.sun.source.tree.TypeCastTree; 41 import com.sun.source.tree.UnaryTree; 42 import com.sun.source.util.SourcePositions; 43 import com.sun.source.util.TreePath; 44 import com.sun.source.util.Trees; 45 import java.util.ArrayList ; 46 import java.util.HashMap ; 47 import java.util.List ; 48 import java.util.Map ; 49 import java.util.Set ; 50 import javax.lang.model.element.TypeElement; 51 import javax.lang.model.type.TypeKind; 52 import javax.lang.model.type.TypeMirror; 53 import javax.lang.model.util.Types; 54 import org.netbeans.api.java.source.CompilationController; 55 import org.netbeans.api.java.source.ElementUtilities; 56 57 import org.netbeans.spi.debugger.jpda.EditorContext; 58 59 66 class AST2Bytecode { 67 68 69 private AST2Bytecode() { 70 } 71 72 static EditorContext.Operation[] matchSourceTree2Bytecode( 73 CompilationUnitTree cu, CompilationController ci, 74 List <Tree> treeNodes, ExpressionScanner.ExpressionsInfo info, 75 byte[] bytecodes, int[] indexes, byte[] constantPool, 76 OperationCreationDelegate opCreationDelegate, 77 Map<Tree, EditorContext.Operation> nodeOperations) { 78 79 Trees trees = ci.getTrees(); 80 Types types = ci.getTypes(); 81 SourcePositions sp = trees.getSourcePositions(); 82 if (treeNodes == null) return null; 84 int length = treeNodes.size(); 85 List <EditorContext.Operation> operations = new ArrayList <EditorContext.Operation>(length); 86 LineMap lineMap = cu.getLineMap(); 87 int indexesIndex = 0; 88 int from = indexes[indexesIndex]; 89 int to = indexes[indexesIndex + 1]; 90 for (int treeIndex = 0; treeIndex < length; treeIndex++) { 91 Tree node = treeNodes.get(treeIndex); 92 Tree.Kind kind = node.getKind(); 93 EditorContext.Operation op = null; 94 if (kind.equals(Tree.Kind.METHOD_INVOCATION) || 95 kind.equals(Tree.Kind.NEW_CLASS)) { 96 97 int opcode; 98 do { 99 do { 100 opcode = bytecodes[from] & 0xFF; 101 if (isMethodCall(opcode)) { 102 break; 103 } 104 from += getInstrSize(opcode, bytecodes, from); 105 } while (from < to); 106 if (from < to) { 107 break; 108 } 109 if ((indexesIndex + 2) < indexes.length) { 110 indexesIndex += 2; 111 from = indexes[indexesIndex]; 112 to = indexes[indexesIndex + 1]; 113 } else { 114 break; 115 } 116 } while (true); 117 if (from < to) { int pos = (int) sp.getStartPosition(cu, node); 119 EditorContext.Position startPosition = 120 opCreationDelegate.createPosition( 121 pos, 122 (int) lineMap.getLineNumber(pos), 123 (int) lineMap.getColumnNumber(pos) 124 ); 125 pos = (int) sp.getEndPosition(cu, node); 126 EditorContext.Position endPosition = 127 opCreationDelegate.createPosition( 128 pos, 129 (int) lineMap.getLineNumber(pos), 130 (int) lineMap.getColumnNumber(pos) 131 ); 132 Tree identifier; 133 String methodName; 134 String methodClassType; 135 if (kind.equals(Tree.Kind.NEW_CLASS)) { 136 identifier = ((NewClassTree) node).getIdentifier(); 137 methodName = "<init>"; 138 TreePath iPath = TreePath.getPath(cu, identifier); 139 TypeMirror type = trees.getTypeMirror(iPath); 140 assert type.getKind() == TypeKind.DECLARED; 141 TypeElement te = (TypeElement) types.asElement(type); 142 methodClassType = ElementUtilities.getBinaryName(te); 143 } else { 144 identifier = ((MethodInvocationTree) node).getMethodSelect(); 146 if (identifier.getKind() == Tree.Kind.IDENTIFIER) { 147 methodName = ((IdentifierTree) identifier).getName().toString(); 148 TreePath iPath = TreePath.getPath(cu, identifier); 149 TypeElement te = trees.getScope(iPath).getEnclosingClass(); 150 methodClassType = ElementUtilities.getBinaryName(te); 151 } else { 152 methodName = ((MemberSelectTree) identifier).getIdentifier().toString(); 153 ExpressionTree exp = ((MemberSelectTree) identifier).getExpression(); 154 TreePath expPath = TreePath.getPath(cu, exp); 155 TypeMirror type = trees.getTypeMirror(expPath); 156 assert type.getKind() == TypeKind.DECLARED; 157 TypeElement te = (TypeElement) types.asElement(type); 158 methodClassType = ElementUtilities.getBinaryName(te); 159 } 160 } 161 pos = (int) sp.getStartPosition(cu, identifier); 162 EditorContext.Position methodStartPosition = 163 opCreationDelegate.createPosition( 164 pos, 165 (int) lineMap.getLineNumber(pos), 166 (int) lineMap.getColumnNumber(pos) 167 ); 168 pos = (int) sp.getEndPosition(cu, identifier); 169 EditorContext.Position methodEndPosition = 170 opCreationDelegate.createPosition( 171 pos, 172 (int) lineMap.getLineNumber(pos), 173 (int) lineMap.getColumnNumber(pos) 174 ); 175 183 op = opCreationDelegate.createMethodOperation( 184 startPosition, 185 endPosition, 186 methodStartPosition, 187 methodEndPosition, 188 methodName, 189 methodClassType, 190 from 191 ); 192 from += getInstrSize(opcode, bytecodes, from); 194 operations.add(op); 195 } else { 196 return null; } 198 } 199 if (op != null) { 200 nodeOperations.put(node, op); 201 } 202 } 203 do { 205 while (from < to) { 206 int opcode = bytecodes[(int) from] & 0xFF; 207 if (isMethodCall(opcode)) { 208 return null; } 210 from += getInstrSize(opcode, bytecodes, from); 211 } 212 if ((indexesIndex + 2) < indexes.length) { 213 indexesIndex += 2; 214 from = indexes[indexesIndex]; 215 to = indexes[indexesIndex + 1]; 216 } else { 217 break; 218 } 219 } while (true); 220 241 return operations.toArray(new EditorContext.Operation[] {}); 242 } 243 244 275 276 private static boolean isMethodCall(int opcode) { 277 return opcode >= 182 && opcode <= 185; 278 } 279 280 private static int getInstrSize(int opcode, byte[] bytecodes, long codeIndex) { 281 if (opcode <= 15) return 1; if (opcode == 16) return 2; if (opcode == 17) return 3; if (opcode == 18) return 2; if (opcode <= 20) return 3; if (opcode <= 25) return 2; if (opcode <= 53) return 1; if (opcode <= 58) return 2; if (opcode <= 86) return 1; if (opcode <= 94) return 1; if (opcode <= 131) return 1; if (opcode <= 132) return 3; if (opcode <= 147) return 1; if (opcode <= 152) return 1; if (opcode <= 168) return 3; if (opcode <= 169) return 2; if (opcode == 170) return tableswitchSize(bytecodes, codeIndex); 298 if (opcode == 171) return lookupswitchSize(bytecodes, codeIndex); 299 if (opcode <= 177) return 1; if (opcode <= 184) return 3; if (opcode == 185) return 5; if (opcode == 187) return 3; if (opcode == 188) return 2; if (opcode == 189) return 3; if (opcode <= 191) return 1; if (opcode <= 193) return 3; if (opcode <= 195) return 1; if (opcode == 196) return wideSize(bytecodes, codeIndex); 310 if (opcode == 197) return 4; if (opcode <= 199) return 3; if (opcode <= 201) return 5; return 1; } 315 316 private static int tableswitchSize(byte[] bytecodes, long codeIndex) { 317 int padding = 4 - ((int) codeIndex % 4); int pos = (int) codeIndex + padding; 319 pos += 4; int low = readInt(bytecodes, pos); 321 pos += 4; int high = readInt(bytecodes, pos); 323 pos += 4; pos += (high - low + 1) << 2; return pos - (int) codeIndex; 326 } 327 328 private static int lookupswitchSize(byte[] bytecodes, long codeIndex) { 329 int padding = 4 - ((int) codeIndex % 4); int pos = (int) codeIndex + padding; 331 pos += 4; int npairs = readInt(bytecodes, pos); 333 pos += 4; pos += npairs << 3; return pos - (int) codeIndex; 336 } 337 338 private static int wideSize(byte[] bytecodes, long codeIndex) { 339 int opcode = bytecodes[(int) codeIndex + 1] & 0xFF; 340 if (opcode == 132) { return 6; 342 } else { 343 return 4; 344 } 345 } 346 347 private static int readUnsignedShort(byte[] bytecodes, int pos) { 348 return ((bytecodes[pos] & 0xFF) << 8) | (bytecodes[pos + 1] & 0xFF); 349 } 350 351 private static int readInt(byte[] bytecodes, int pos) { 352 return (bytecodes[pos ] & 0xFF) << 24 | 353 (bytecodes[pos + 1] & 0xFF) << 16 | 354 (bytecodes[pos + 2] & 0xFF) << 8 | 355 (bytecodes[pos + 3] & 0xFF); 356 } 357 358 359 static interface OperationCreationDelegate { 360 361 367 368 EditorContext.Operation createMethodOperation( 369 EditorContext.Position startPosition, 370 EditorContext.Position endPosition, 371 EditorContext.Position methodStartPosition, 372 EditorContext.Position methodEndPosition, 373 String methodName, String methodClassType, 374 int bytecodeIndex); 375 376 EditorContext.Position createPosition(int offset, int line, int column); 377 378 void addNextOperationTo(EditorContext.Operation operation, 379 EditorContext.Operation next); 380 381 } 382 } 383 | Popular Tags |