1 11 package org.eclipse.jdt.internal.core.search.indexing; 12 13 import org.eclipse.jdt.core.Signature; 14 import org.eclipse.jdt.core.compiler.*; 15 import org.eclipse.jdt.internal.compiler.ISourceElementRequestor; 16 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 17 import org.eclipse.jdt.internal.compiler.lookup.TypeConstants; 18 import org.eclipse.jdt.internal.core.search.processing.JobManager; 19 20 24 public class SourceIndexerRequestor implements ISourceElementRequestor, IIndexConstants { 25 SourceIndexer indexer; 26 27 char[] packageName = CharOperation.NO_CHAR; 28 char[][] enclosingTypeNames = new char[5][]; 29 int depth = 0; 30 int methodDepth = 0; 31 32 public SourceIndexerRequestor(SourceIndexer indexer) { 33 this.indexer = indexer; 34 } 35 38 public void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition) { 39 if (CharOperation.indexOf(Signature.C_GENERIC_START, typeName) > 0) { 40 typeName = Signature.toCharArray(Signature.getTypeErasure(Signature.createTypeSignature(typeName, false)).toCharArray()); 41 } 42 this.indexer.addConstructorReference(typeName, argCount); 43 int lastDot = CharOperation.lastIndexOf('.', typeName); 44 if (lastDot != -1) { 45 char[][] qualification = CharOperation.splitOn('.', CharOperation.subarray(typeName, 0, lastDot)); 46 for (int i = 0, length = qualification.length; i < length; i++) { 47 this.indexer.addNameReference(qualification[i]); 48 } 49 } 50 } 51 54 public void acceptFieldReference(char[] fieldName, int sourcePosition) { 55 this.indexer.addFieldReference(fieldName); 56 } 57 60 public void acceptImport(int declarationStart, int declarationEnd, char[][] tokens, boolean onDemand, int modifiers) { 61 } 63 66 public void acceptLineSeparatorPositions(int[] positions) { 67 } 69 72 public void acceptMethodReference(char[] methodName, int argCount, int sourcePosition) { 73 this.indexer.addMethodReference(methodName, argCount); 74 } 75 78 public void acceptPackage(int declarationStart, int declarationEnd, char[] name) { 79 this.packageName = name; 80 } 81 84 public void acceptProblem(CategorizedProblem problem) { 85 } 87 90 public void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd) { 91 int length = typeName.length; 92 for (int i = 0; i < length - 1; i++) 93 acceptUnknownReference(typeName[i], 0); acceptTypeReference(typeName[length - 1], 0); 95 } 96 99 public void acceptTypeReference(char[] simpleTypeName, int sourcePosition) { 100 this.indexer.addTypeReference(simpleTypeName); 101 } 102 105 public void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd) { 106 for (int i = 0; i < name.length; i++) { 107 acceptUnknownReference(name[i], 0); 108 } 109 } 110 113 public void acceptUnknownReference(char[] name, int sourcePosition) { 114 this.indexer.addNameReference(name); 115 } 116 123 public char[][] enclosingTypeNames(){ 124 125 if (depth == 0) return null; 126 127 char[][] qualification = new char[this.depth][]; 128 System.arraycopy(this.enclosingTypeNames, 0, qualification, 0, this.depth); 129 return qualification; 130 } 131 private void enterAnnotationType(TypeInfo typeInfo) { 132 char[][] typeNames; 133 if (this.methodDepth > 0) { 134 typeNames = ONE_ZERO_CHAR; 135 } else { 136 typeNames = this.enclosingTypeNames(); 137 } 138 this.indexer.addAnnotationTypeDeclaration(typeInfo.modifiers, packageName, typeInfo.name, typeNames, typeInfo.secondary); 139 this.pushTypeName(typeInfo.name); 140 } 141 142 private void enterClass(TypeInfo typeInfo) { 143 144 if (typeInfo.superclass != null) { 146 typeInfo.superclass = getSimpleName(typeInfo.superclass); 147 148 this.indexer.addConstructorReference(typeInfo.superclass, 0); 150 } 151 if (typeInfo.superinterfaces != null){ 152 for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++) { 153 typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]); 154 } 155 } 156 char[][] typeNames; 157 if (this.methodDepth > 0) { 158 typeNames = ONE_ZERO_CHAR; 160 } else { 161 typeNames = this.enclosingTypeNames(); 162 } 163 char[][] typeParameterSignatures = null; 164 if (typeInfo.typeParameters != null) { 165 int typeParametersLength = typeInfo.typeParameters.length; 166 typeParameterSignatures = new char[typeParametersLength][]; 167 for (int i = 0; i < typeParametersLength; i++) { 168 ISourceElementRequestor.TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i]; 169 typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameterInfo.name, typeParameterInfo.bounds == null ? CharOperation.NO_CHAR_CHAR : typeParameterInfo.bounds); 170 } 171 } 172 this.indexer.addClassDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.superclass, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary); 173 this.pushTypeName(typeInfo.name); 174 } 175 178 public void enterCompilationUnit() { 179 } 181 184 public void enterConstructor(MethodInfo methodInfo) { 185 this.indexer.addConstructorDeclaration(methodInfo.name, methodInfo.parameterTypes, methodInfo.exceptionTypes); 186 this.methodDepth++; 187 } 188 private void enterEnum(TypeInfo typeInfo) { 189 if (typeInfo.superinterfaces != null){ 191 for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){ 192 typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]); 193 } 194 } 195 char[][] typeNames; 196 if (this.methodDepth > 0) { 197 typeNames = ONE_ZERO_CHAR; 198 } else { 199 typeNames = this.enclosingTypeNames(); 200 } 201 char[] superclass = typeInfo.superclass == null ? CharOperation.concatWith(TypeConstants.JAVA_LANG_ENUM, '.'): typeInfo.superclass; 202 this.indexer.addEnumDeclaration(typeInfo.modifiers, packageName, typeInfo.name, typeNames, superclass, typeInfo.superinterfaces, typeInfo.secondary); 203 this.pushTypeName(typeInfo.name); 204 } 205 208 public void enterField(FieldInfo fieldInfo) { 209 this.indexer.addFieldDeclaration(fieldInfo.type, fieldInfo.name); 210 this.methodDepth++; 211 } 212 215 public void enterInitializer(int declarationSourceStart, int modifiers) { 216 this.methodDepth++; 217 } 218 private void enterInterface(TypeInfo typeInfo) { 219 if (typeInfo.superinterfaces != null){ 221 for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){ 222 typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]); 223 } 224 } 225 char[][] typeNames; 226 if (this.methodDepth > 0) { 227 typeNames = ONE_ZERO_CHAR; 228 } else { 229 typeNames = this.enclosingTypeNames(); 230 } 231 char[][] typeParameterSignatures = null; 232 if (typeInfo.typeParameters != null) { 233 int typeParametersLength = typeInfo.typeParameters.length; 234 typeParameterSignatures = new char[typeParametersLength][]; 235 for (int i = 0; i < typeParametersLength; i++) { 236 ISourceElementRequestor.TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i]; 237 typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameterInfo.name, typeParameterInfo.bounds); 238 } 239 } 240 this.indexer.addInterfaceDeclaration(typeInfo.modifiers, packageName, typeInfo.name, typeNames, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary); 241 this.pushTypeName(typeInfo.name); 242 } 243 246 public void enterMethod(MethodInfo methodInfo) { 247 this.indexer.addMethodDeclaration(methodInfo.name, methodInfo.parameterTypes, methodInfo.returnType, methodInfo.exceptionTypes); 248 this.methodDepth++; 249 } 250 253 public void enterType(TypeInfo typeInfo) { 254 switch (TypeDeclaration.kind(typeInfo.modifiers)) { 256 case TypeDeclaration.CLASS_DECL: 257 enterClass(typeInfo); 258 break; 259 case TypeDeclaration.ANNOTATION_TYPE_DECL: 260 enterAnnotationType(typeInfo); 261 break; 262 case TypeDeclaration.INTERFACE_DECL: 263 enterInterface(typeInfo); 264 break; 265 case TypeDeclaration.ENUM_DECL: 266 enterEnum(typeInfo); 267 break; 268 } 269 } 270 271 274 public void exitCompilationUnit(int declarationEnd) { 275 } 277 280 public void exitConstructor(int declarationEnd) { 281 this.methodDepth--; 282 } 283 286 public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) { 287 this.methodDepth--; 288 } 289 292 public void exitInitializer(int declarationEnd) { 293 this.methodDepth--; 294 } 295 298 public void exitMethod(int declarationEnd, int defaultValueStart, int defaultValueEnd) { 299 this.methodDepth--; 300 } 301 304 public void exitType(int declarationEnd) { 305 popTypeName(); 306 } 307 310 private char[] getSimpleName(char[] typeName) { 311 int lastDot = -1, lastGenericStart = -1; 312 int depthCount = 0; 313 int length = typeName.length; 314 lastDotLookup: for (int i = length -1; i >= 0; i--) { 315 switch (typeName[i]) { 316 case '.': 317 if (depthCount == 0) { 318 lastDot = i; 319 break lastDotLookup; 320 } 321 break; 322 case '<': 323 depthCount--; 324 if (depthCount == 0) lastGenericStart = i; 325 break; 326 case '>': 327 depthCount++; 328 break; 329 } 330 } 331 if (lastGenericStart < 0) { 332 if (lastDot < 0) { 333 return typeName; 334 } 335 return CharOperation.subarray(typeName, lastDot + 1, length); 336 } 337 return CharOperation.subarray(typeName, lastDot + 1, lastGenericStart); 338 } 339 public void popTypeName() { 340 if (depth > 0) { 341 enclosingTypeNames[--depth] = null; 342 } else if (JobManager.VERBOSE) { 343 try { 345 enclosingTypeNames[-1] = null; 346 } catch (ArrayIndexOutOfBoundsException e) { 347 e.printStackTrace(); 348 } 349 } 350 } 351 public void pushTypeName(char[] typeName) { 352 if (depth == enclosingTypeNames.length) 353 System.arraycopy(enclosingTypeNames, 0, enclosingTypeNames = new char[depth*2][], 0, depth); 354 enclosingTypeNames[depth++] = typeName; 355 } 356 } 357 | Popular Tags |