PageRenderTime 30ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/projects/eclipse_SDK-3.7.1/plugins/org.eclipse.jdt.core.source_3.7.1.v_B76_R37x/org/eclipse/jdt/internal/core/search/indexing/SourceIndexerRequestor.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 419 lines | 295 code | 13 blank | 111 comment | 58 complexity | 49924484126cbb872d86c806b77c1104 MD5 | raw file
  1. /*******************************************************************************
  2. * Copyright (c) 2000, 2010 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * IBM Corporation - initial API and implementation
  10. *******************************************************************************/
  11. package org.eclipse.jdt.internal.core.search.indexing;
  12. import org.eclipse.jdt.core.Signature;
  13. import org.eclipse.jdt.core.compiler.*;
  14. import org.eclipse.jdt.internal.compiler.ExtraFlags;
  15. import org.eclipse.jdt.internal.compiler.ISourceElementRequestor;
  16. import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
  17. import org.eclipse.jdt.internal.compiler.ast.Expression;
  18. import org.eclipse.jdt.internal.compiler.ast.ImportReference;
  19. import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
  20. import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
  21. import org.eclipse.jdt.internal.core.search.processing.JobManager;
  22. /**
  23. * This class is used by the JavaParserIndexer. When parsing the java file, the requestor
  24. * recognizes the java elements (methods, fields, ...) and add them to an index.
  25. */
  26. public class SourceIndexerRequestor implements ISourceElementRequestor, IIndexConstants {
  27. SourceIndexer indexer;
  28. char[] packageName = CharOperation.NO_CHAR;
  29. char[][] enclosingTypeNames = new char[5][];
  30. int depth = 0;
  31. int methodDepth = 0;
  32. public SourceIndexerRequestor(SourceIndexer indexer) {
  33. this.indexer = indexer;
  34. }
  35. /**
  36. * @see ISourceElementRequestor#acceptAnnotationTypeReference(char[][], int, int)
  37. */
  38. public void acceptAnnotationTypeReference(char[][] typeName, int sourceStart, int sourceEnd) {
  39. int length = typeName.length;
  40. for (int i = 0; i < length - 1; i++)
  41. acceptUnknownReference(typeName[i], 0);
  42. acceptAnnotationTypeReference(typeName[length - 1], 0);
  43. }
  44. /**
  45. * @see ISourceElementRequestor#acceptAnnotationTypeReference(char[], int)
  46. */
  47. public void acceptAnnotationTypeReference(char[] simpleTypeName, int sourcePosition) {
  48. this.indexer.addAnnotationTypeReference(simpleTypeName);
  49. }
  50. /**
  51. * @see ISourceElementRequestor#acceptConstructorReference(char[], int, int)
  52. */
  53. public void acceptConstructorReference(char[] typeName, int argCount, int sourcePosition) {
  54. if (CharOperation.indexOf(Signature.C_GENERIC_START, typeName) > 0) {
  55. typeName = Signature.toCharArray(Signature.getTypeErasure(Signature.createTypeSignature(typeName, false)).toCharArray());
  56. }
  57. this.indexer.addConstructorReference(typeName, argCount);
  58. int lastDot = CharOperation.lastIndexOf('.', typeName);
  59. if (lastDot != -1) {
  60. char[][] qualification = CharOperation.splitOn('.', CharOperation.subarray(typeName, 0, lastDot));
  61. for (int i = 0, length = qualification.length; i < length; i++) {
  62. this.indexer.addNameReference(qualification[i]);
  63. }
  64. }
  65. }
  66. /**
  67. * @see ISourceElementRequestor#acceptFieldReference(char[], int)
  68. */
  69. public void acceptFieldReference(char[] fieldName, int sourcePosition) {
  70. this.indexer.addFieldReference(fieldName);
  71. }
  72. /**
  73. * @see ISourceElementRequestor#acceptImport(int, int, int, int, char[][], boolean, int)
  74. */
  75. public void acceptImport(int declarationStart, int declarationEnd, int nameStart, int nameEnd, char[][] tokens, boolean onDemand, int modifiers) {
  76. // imports have already been reported while creating the ImportRef node (see SourceElementParser#comsume*ImportDeclarationName() methods)
  77. }
  78. /**
  79. * @see ISourceElementRequestor#acceptLineSeparatorPositions(int[])
  80. */
  81. public void acceptLineSeparatorPositions(int[] positions) {
  82. // implements interface method
  83. }
  84. /**
  85. * @see ISourceElementRequestor#acceptMethodReference(char[], int, int)
  86. */
  87. public void acceptMethodReference(char[] methodName, int argCount, int sourcePosition) {
  88. this.indexer.addMethodReference(methodName, argCount);
  89. }
  90. /**
  91. * @see ISourceElementRequestor#acceptPackage(ImportReference)
  92. */
  93. public void acceptPackage(ImportReference importReference) {
  94. this.packageName = CharOperation.concatWith(importReference.getImportName(), '.');
  95. }
  96. /**
  97. * @see ISourceElementRequestor#acceptProblem(CategorizedProblem)
  98. */
  99. public void acceptProblem(CategorizedProblem problem) {
  100. // implements interface method
  101. }
  102. /**
  103. * @see ISourceElementRequestor#acceptTypeReference(char[][], int, int)
  104. */
  105. public void acceptTypeReference(char[][] typeName, int sourceStart, int sourceEnd) {
  106. int length = typeName.length;
  107. for (int i = 0; i < length - 1; i++)
  108. acceptUnknownReference(typeName[i], 0); // ?
  109. acceptTypeReference(typeName[length - 1], 0);
  110. }
  111. /**
  112. * @see ISourceElementRequestor#acceptTypeReference(char[], int)
  113. */
  114. public void acceptTypeReference(char[] simpleTypeName, int sourcePosition) {
  115. this.indexer.addTypeReference(simpleTypeName);
  116. }
  117. /**
  118. * @see ISourceElementRequestor#acceptUnknownReference(char[][], int, int)
  119. */
  120. public void acceptUnknownReference(char[][] name, int sourceStart, int sourceEnd) {
  121. for (int i = 0; i < name.length; i++) {
  122. acceptUnknownReference(name[i], 0);
  123. }
  124. }
  125. /**
  126. * @see ISourceElementRequestor#acceptUnknownReference(char[], int)
  127. */
  128. public void acceptUnknownReference(char[] name, int sourcePosition) {
  129. this.indexer.addNameReference(name);
  130. }
  131. private void addDefaultConstructorIfNecessary(TypeInfo typeInfo) {
  132. boolean hasConstructor = false;
  133. TypeDeclaration typeDeclaration = typeInfo.node;
  134. AbstractMethodDeclaration[] methods = typeDeclaration.methods;
  135. int methodCounter = methods == null ? 0 : methods.length;
  136. done : for (int i = 0; i < methodCounter; i++) {
  137. AbstractMethodDeclaration method = methods[i];
  138. if (method.isConstructor() && !method.isDefaultConstructor()) {
  139. hasConstructor = true;
  140. break done;
  141. }
  142. }
  143. if (!hasConstructor) {
  144. this.indexer.addDefaultConstructorDeclaration(
  145. typeInfo.name,
  146. this.packageName == null ? CharOperation.NO_CHAR : this.packageName,
  147. typeInfo.modifiers,
  148. getMoreExtraFlags(typeInfo.extraFlags));
  149. }
  150. }
  151. /*
  152. * Rebuild the proper qualification for the current source type:
  153. *
  154. * java.lang.Object ---> null
  155. * java.util.Hashtable$Entry --> [Hashtable]
  156. * x.y.A$B$C --> [A, B]
  157. */
  158. public char[][] enclosingTypeNames(){
  159. if (this.depth == 0) return null;
  160. char[][] qualification = new char[this.depth][];
  161. System.arraycopy(this.enclosingTypeNames, 0, qualification, 0, this.depth);
  162. return qualification;
  163. }
  164. private void enterAnnotationType(TypeInfo typeInfo) {
  165. char[][] typeNames;
  166. if (this.methodDepth > 0) {
  167. typeNames = ONE_ZERO_CHAR;
  168. } else {
  169. typeNames = enclosingTypeNames();
  170. }
  171. this.indexer.addAnnotationTypeDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.secondary);
  172. addDefaultConstructorIfNecessary(typeInfo);
  173. pushTypeName(typeInfo.name);
  174. }
  175. private void enterClass(TypeInfo typeInfo) {
  176. // eliminate possible qualifications, given they need to be fully resolved again
  177. if (typeInfo.superclass != null) {
  178. typeInfo.superclass = getSimpleName(typeInfo.superclass);
  179. // add implicit constructor reference to default constructor
  180. this.indexer.addConstructorReference(typeInfo.superclass, 0);
  181. }
  182. if (typeInfo.superinterfaces != null){
  183. for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++) {
  184. typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
  185. }
  186. }
  187. char[][] typeNames;
  188. if (this.methodDepth > 0) {
  189. // set specific ['0'] value for local and anonymous to be able to filter them
  190. typeNames = ONE_ZERO_CHAR;
  191. } else {
  192. typeNames = enclosingTypeNames();
  193. }
  194. char[][] typeParameterSignatures = null;
  195. if (typeInfo.typeParameters != null) {
  196. int typeParametersLength = typeInfo.typeParameters.length;
  197. typeParameterSignatures = new char[typeParametersLength][];
  198. for (int i = 0; i < typeParametersLength; i++) {
  199. ISourceElementRequestor.TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
  200. typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameterInfo.name, typeParameterInfo.bounds == null ? CharOperation.NO_CHAR_CHAR : typeParameterInfo.bounds);
  201. }
  202. }
  203. this.indexer.addClassDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.superclass, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary);
  204. addDefaultConstructorIfNecessary(typeInfo);
  205. pushTypeName(typeInfo.name);
  206. }
  207. /**
  208. * @see ISourceElementRequestor#enterCompilationUnit()
  209. */
  210. public void enterCompilationUnit() {
  211. // implements interface method
  212. }
  213. /**
  214. * @see ISourceElementRequestor#enterConstructor(ISourceElementRequestor.MethodInfo)
  215. */
  216. public void enterConstructor(MethodInfo methodInfo) {
  217. int argCount = methodInfo.parameterTypes == null ? 0 : methodInfo.parameterTypes.length;
  218. this.indexer.addConstructorDeclaration(
  219. methodInfo.name,
  220. argCount,
  221. null,
  222. methodInfo.parameterTypes,
  223. methodInfo.parameterNames,
  224. methodInfo.modifiers,
  225. methodInfo.declaringPackageName,
  226. methodInfo.declaringTypeModifiers,
  227. methodInfo.exceptionTypes,
  228. getMoreExtraFlags(methodInfo.extraFlags));
  229. this.methodDepth++;
  230. }
  231. private void enterEnum(TypeInfo typeInfo) {
  232. // eliminate possible qualifications, given they need to be fully resolved again
  233. if (typeInfo.superinterfaces != null){
  234. for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){
  235. typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
  236. }
  237. }
  238. char[][] typeNames;
  239. if (this.methodDepth > 0) {
  240. typeNames = ONE_ZERO_CHAR;
  241. } else {
  242. typeNames = enclosingTypeNames();
  243. }
  244. char[] superclass = typeInfo.superclass == null ? CharOperation.concatWith(TypeConstants.JAVA_LANG_ENUM, '.'): typeInfo.superclass;
  245. this.indexer.addEnumDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, superclass, typeInfo.superinterfaces, typeInfo.secondary);
  246. addDefaultConstructorIfNecessary(typeInfo);
  247. pushTypeName(typeInfo.name);
  248. }
  249. /**
  250. * @see ISourceElementRequestor#enterField(ISourceElementRequestor.FieldInfo)
  251. */
  252. public void enterField(FieldInfo fieldInfo) {
  253. this.indexer.addFieldDeclaration(fieldInfo.type, fieldInfo.name);
  254. this.methodDepth++;
  255. }
  256. /**
  257. * @see ISourceElementRequestor#enterInitializer(int, int)
  258. */
  259. public void enterInitializer(int declarationSourceStart, int modifiers) {
  260. this.methodDepth++;
  261. }
  262. private void enterInterface(TypeInfo typeInfo) {
  263. // eliminate possible qualifications, given they need to be fully resolved again
  264. if (typeInfo.superinterfaces != null){
  265. for (int i = 0, length = typeInfo.superinterfaces.length; i < length; i++){
  266. typeInfo.superinterfaces[i] = getSimpleName(typeInfo.superinterfaces[i]);
  267. }
  268. }
  269. char[][] typeNames;
  270. if (this.methodDepth > 0) {
  271. typeNames = ONE_ZERO_CHAR;
  272. } else {
  273. typeNames = enclosingTypeNames();
  274. }
  275. char[][] typeParameterSignatures = null;
  276. if (typeInfo.typeParameters != null) {
  277. int typeParametersLength = typeInfo.typeParameters.length;
  278. typeParameterSignatures = new char[typeParametersLength][];
  279. for (int i = 0; i < typeParametersLength; i++) {
  280. ISourceElementRequestor.TypeParameterInfo typeParameterInfo = typeInfo.typeParameters[i];
  281. typeParameterSignatures[i] = Signature.createTypeParameterSignature(typeParameterInfo.name, typeParameterInfo.bounds);
  282. }
  283. }
  284. this.indexer.addInterfaceDeclaration(typeInfo.modifiers, this.packageName, typeInfo.name, typeNames, typeInfo.superinterfaces, typeParameterSignatures, typeInfo.secondary);
  285. addDefaultConstructorIfNecessary(typeInfo);
  286. pushTypeName(typeInfo.name);
  287. }
  288. /**
  289. * @see ISourceElementRequestor#enterMethod(ISourceElementRequestor.MethodInfo)
  290. */
  291. public void enterMethod(MethodInfo methodInfo) {
  292. this.indexer.addMethodDeclaration(methodInfo.name, methodInfo.parameterTypes, methodInfo.returnType, methodInfo.exceptionTypes);
  293. this.methodDepth++;
  294. }
  295. /**
  296. * @see ISourceElementRequestor#enterType(ISourceElementRequestor.TypeInfo)
  297. */
  298. public void enterType(TypeInfo typeInfo) {
  299. // TODO (jerome) might want to merge the 4 methods
  300. switch (TypeDeclaration.kind(typeInfo.modifiers)) {
  301. case TypeDeclaration.CLASS_DECL:
  302. enterClass(typeInfo);
  303. break;
  304. case TypeDeclaration.ANNOTATION_TYPE_DECL:
  305. enterAnnotationType(typeInfo);
  306. break;
  307. case TypeDeclaration.INTERFACE_DECL:
  308. enterInterface(typeInfo);
  309. break;
  310. case TypeDeclaration.ENUM_DECL:
  311. enterEnum(typeInfo);
  312. break;
  313. }
  314. }
  315. /**
  316. * @see ISourceElementRequestor#exitCompilationUnit(int)
  317. */
  318. public void exitCompilationUnit(int declarationEnd) {
  319. // implements interface method
  320. }
  321. /**
  322. * @see ISourceElementRequestor#exitConstructor(int)
  323. */
  324. public void exitConstructor(int declarationEnd) {
  325. this.methodDepth--;
  326. }
  327. /**
  328. * @see ISourceElementRequestor#exitField(int, int, int)
  329. */
  330. public void exitField(int initializationStart, int declarationEnd, int declarationSourceEnd) {
  331. this.methodDepth--;
  332. }
  333. /**
  334. * @see ISourceElementRequestor#exitInitializer(int)
  335. */
  336. public void exitInitializer(int declarationEnd) {
  337. this.methodDepth--;
  338. }
  339. /**
  340. * @see ISourceElementRequestor#exitMethod(int, Expression)
  341. */
  342. public void exitMethod(int declarationEnd, Expression defaultValue) {
  343. this.methodDepth--;
  344. }
  345. /**
  346. * @see ISourceElementRequestor#exitType(int)
  347. */
  348. public void exitType(int declarationEnd) {
  349. popTypeName();
  350. }
  351. /*
  352. * Returns the unqualified name without parameters from the given type name.
  353. */
  354. private char[] getSimpleName(char[] typeName) {
  355. int lastDot = -1, lastGenericStart = -1;
  356. int depthCount = 0;
  357. int length = typeName.length;
  358. lastDotLookup: for (int i = length -1; i >= 0; i--) {
  359. switch (typeName[i]) {
  360. case '.':
  361. if (depthCount == 0) {
  362. lastDot = i;
  363. break lastDotLookup;
  364. }
  365. break;
  366. case '<':
  367. depthCount--;
  368. if (depthCount == 0) lastGenericStart = i;
  369. break;
  370. case '>':
  371. depthCount++;
  372. break;
  373. }
  374. }
  375. if (lastGenericStart < 0) {
  376. if (lastDot < 0) {
  377. return typeName;
  378. }
  379. return CharOperation.subarray(typeName, lastDot + 1, length);
  380. }
  381. return CharOperation.subarray(typeName, lastDot + 1, lastGenericStart);
  382. }
  383. private int getMoreExtraFlags(int extraFlags) {
  384. if (this.methodDepth > 0) {
  385. extraFlags |= ExtraFlags.IsLocalType;
  386. }
  387. return extraFlags;
  388. }
  389. public void popTypeName() {
  390. if (this.depth > 0) {
  391. this.enclosingTypeNames[--this.depth] = null;
  392. } else if (JobManager.VERBOSE) {
  393. // dump a trace so it can be tracked down
  394. try {
  395. this.enclosingTypeNames[-1] = null;
  396. } catch (ArrayIndexOutOfBoundsException e) {
  397. e.printStackTrace();
  398. }
  399. }
  400. }
  401. public void pushTypeName(char[] typeName) {
  402. if (this.depth == this.enclosingTypeNames.length)
  403. System.arraycopy(this.enclosingTypeNames, 0, this.enclosingTypeNames = new char[this.depth*2][], 0, this.depth);
  404. this.enclosingTypeNames[this.depth++] = typeName;
  405. }
  406. }