1 11 package org.eclipse.jdt.internal.compiler.parser.diagnose; 12 13 import org.eclipse.jdt.internal.compiler.ast.ASTNode; 14 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 15 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; 16 import org.eclipse.jdt.internal.compiler.ast.Initializer; 17 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 18 import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; 19 20 public class RangeUtil { 21 22 public static final int NO_FLAG = 0; 24 public static final int LBRACE_MISSING = 1; 25 public static final int IGNORE = 2; 26 27 static class RangeResult { 28 private static final int INITIAL_SIZE = 10; 29 int pos; 30 int[] intervalStarts; 31 int[] intervalEnds; 32 int[] intervalFlags; 33 34 RangeResult() { 35 this.pos = 0; 36 this.intervalStarts = new int[INITIAL_SIZE]; 37 this.intervalEnds = new int[INITIAL_SIZE]; 38 this.intervalFlags = new int[INITIAL_SIZE]; 39 } 40 41 void addInterval(int start, int end){ 42 addInterval(start, end, NO_FLAG); 43 } 44 45 void addInterval(int start, int end, int flags){ 46 if(pos >= intervalStarts.length) { 47 System.arraycopy(intervalStarts, 0, intervalStarts = new int[pos * 2], 0, pos); 48 System.arraycopy(intervalEnds, 0, intervalEnds = new int[pos * 2], 0, pos); 49 System.arraycopy(intervalFlags, 0, intervalFlags = new int[pos * 2], 0, pos); 50 } 51 intervalStarts[pos] = start; 52 intervalEnds[pos] = end; 53 intervalFlags[pos] = flags; 54 pos++; 55 } 56 57 int[][] getRanges() { 58 int[] resultStarts = new int[pos]; 59 int[] resultEnds = new int[pos]; 60 int[] resultFlags = new int[pos]; 61 62 System.arraycopy(intervalStarts, 0, resultStarts, 0, pos); 63 System.arraycopy(intervalEnds, 0, resultEnds, 0, pos); 64 System.arraycopy(intervalFlags, 0, resultFlags, 0, pos); 65 66 if (resultStarts.length > 1) { 67 quickSort(resultStarts, resultEnds, resultFlags, 0, resultStarts.length - 1); 68 } 69 return new int[][]{resultStarts, resultEnds, resultFlags}; 70 } 71 72 private void quickSort(int[] list, int[] list2, int[] list3, int left, int right) { 73 int original_left= left; 74 int original_right= right; 75 int mid= list[left + (right - left) / 2]; 76 do { 77 while (compare(list[left], mid) < 0) { 78 left++; 79 } 80 while (compare(mid, list[right]) < 0) { 81 right--; 82 } 83 if (left <= right) { 84 int tmp= list[left]; 85 list[left]= list[right]; 86 list[right]= tmp; 87 88 tmp = list2[left]; 89 list2[left]= list2[right]; 90 list2[right]= tmp; 91 92 tmp = list3[left]; 93 list3[left]= list3[right]; 94 list3[right]= tmp; 95 96 left++; 97 right--; 98 } 99 } while (left <= right); 100 101 if (original_left < right) { 102 quickSort(list, list2, list3, original_left, right); 103 } 104 if (left < original_right) { 105 quickSort(list, list2, list3, left, original_right); 106 } 107 } 108 109 private int compare(int i1, int i2) { 110 return i1 - i2; 111 } 112 } 113 114 115 116 public static boolean containsErrorInSignature(AbstractMethodDeclaration method){ 117 return method.sourceEnd + 1 == method.bodyStart || method.bodyEnd == method.declarationSourceEnd; 118 } 119 120 public static int[][] computeDietRange(TypeDeclaration[] types) { 121 if(types == null || types.length == 0) { 122 return new int[3][0]; 123 } else { 124 RangeResult result = new RangeResult(); 125 computeDietRange0(types, result); 126 return result.getRanges(); 127 } 128 } 129 130 private static void computeDietRange0(TypeDeclaration[] types, RangeResult result) { 131 for (int j = 0; j < types.length; j++) { 132 TypeDeclaration[] memberTypeDeclarations = types[j].memberTypes; 134 if(memberTypeDeclarations != null && memberTypeDeclarations.length > 0) { 135 computeDietRange0(types[j].memberTypes, result); 136 } 137 AbstractMethodDeclaration[] methods = types[j].methods; 139 if (methods != null) { 140 int length = methods.length; 141 for (int i = 0; i < length; i++) { 142 AbstractMethodDeclaration method = methods[i]; 143 if(containsIgnoredBody(method)) { 144 if(containsErrorInSignature(method)) { 145 method.bits |= ASTNode.ErrorInSignature; 146 result.addInterval(method.declarationSourceStart, method.declarationSourceEnd, IGNORE); 147 } else { 148 int flags = method.sourceEnd + 1 == method.bodyStart ? LBRACE_MISSING : NO_FLAG; 149 result.addInterval(method.bodyStart, method.bodyEnd, flags); 150 } 151 } 152 } 153 } 154 155 FieldDeclaration[] fields = types[j].fields; 157 if (fields != null) { 158 int length = fields.length; 159 for (int i = 0; i < length; i++) { 160 if (fields[i] instanceof Initializer) { 161 Initializer initializer = (Initializer)fields[i]; 162 if(initializer.declarationSourceEnd == initializer.bodyEnd && initializer.declarationSourceStart != initializer.declarationSourceEnd){ 163 initializer.bits |= ASTNode.ErrorInSignature; 164 result.addInterval(initializer.declarationSourceStart, initializer.declarationSourceEnd, IGNORE); 165 } else { 166 result.addInterval(initializer.bodyStart, initializer.bodyEnd); 167 } 168 } 169 } 170 } 171 } 172 } 173 174 public static boolean containsIgnoredBody(AbstractMethodDeclaration method){ 175 return !method.isDefaultConstructor() 176 && !method.isClinit() 177 && (method.modifiers & ExtraCompilerModifiers.AccSemicolonBody) == 0; 178 } 179 } 180 | Popular Tags |