Source Code Cross Referenced for BinaryIndexer.java in  » IDE-Eclipse » jdt » org » eclipse » jdt » internal » core » search » indexing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Eclipse » jdt » org.eclipse.jdt.internal.core.search.indexing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*******************************************************************************
002:         * Copyright (c) 2000, 2007 IBM Corporation and others.
003:         * All rights reserved. This program and the accompanying materials
004:         * are made available under the terms of the Eclipse Public License v1.0
005:         * which accompanies this distribution, and is available at
006:         * http://www.eclipse.org/legal/epl-v10.html
007:         *
008:         * Contributors:
009:         *     IBM Corporation - initial API and implementation
010:         *******************************************************************************/package org.eclipse.jdt.internal.core.search.indexing;
011:
012:        import org.eclipse.jdt.core.Signature;
013:        import org.eclipse.jdt.core.compiler.CharOperation;
014:        import org.eclipse.jdt.core.search.SearchDocument;
015:        import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
016:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
017:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
018:        import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
019:        import org.eclipse.jdt.internal.compiler.classfmt.FieldInfo;
020:        import org.eclipse.jdt.internal.compiler.classfmt.MethodInfo;
021:        import org.eclipse.jdt.internal.compiler.env.ClassSignature;
022:        import org.eclipse.jdt.internal.compiler.env.EnumConstantSignature;
023:        import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
024:        import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair;
025:        import org.eclipse.jdt.internal.compiler.lookup.TagBits;
026:        import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
027:        import org.eclipse.jdt.internal.compiler.util.SuffixConstants;
028:        import org.eclipse.jdt.internal.core.util.Util;
029:
030:        public class BinaryIndexer extends AbstractIndexer implements 
031:                SuffixConstants {
032:            private static final char[] BYTE = "byte".toCharArray(); //$NON-NLS-1$
033:            private static final char[] CHAR = "char".toCharArray(); //$NON-NLS-1$
034:            private static final char[] DOUBLE = "double".toCharArray(); //$NON-NLS-1$
035:            private static final char[] FLOAT = "float".toCharArray(); //$NON-NLS-1$
036:            private static final char[] INT = "int".toCharArray(); //$NON-NLS-1$
037:            private static final char[] LONG = "long".toCharArray(); //$NON-NLS-1$
038:            private static final char[] SHORT = "short".toCharArray(); //$NON-NLS-1$
039:            private static final char[] BOOLEAN = "boolean".toCharArray(); //$NON-NLS-1$
040:            private static final char[] VOID = "void".toCharArray(); //$NON-NLS-1$
041:            private static final char[] INIT = "<init>".toCharArray(); //$NON-NLS-1$
042:
043:            public BinaryIndexer(SearchDocument document) {
044:                super (document);
045:            }
046:
047:            private void addBinaryStandardAnnotations(long annotationTagBits) {
048:                if ((annotationTagBits & TagBits.AnnotationTargetMASK) != 0) {
049:                    char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_TARGET;
050:                    addTypeReference(compoundName[compoundName.length - 1]);
051:                    addBinaryTargetAnnotation(annotationTagBits);
052:                }
053:                if ((annotationTagBits & TagBits.AnnotationRetentionMASK) != 0) {
054:                    char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTION;
055:                    addTypeReference(compoundName[compoundName.length - 1]);
056:                    addBinaryRetentionAnnotation(annotationTagBits);
057:                }
058:                if ((annotationTagBits & TagBits.AnnotationDeprecated) != 0) {
059:                    char[][] compoundName = TypeConstants.JAVA_LANG_DEPRECATED;
060:                    addTypeReference(compoundName[compoundName.length - 1]);
061:                }
062:                if ((annotationTagBits & TagBits.AnnotationDocumented) != 0) {
063:                    char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED;
064:                    addTypeReference(compoundName[compoundName.length - 1]);
065:                }
066:                if ((annotationTagBits & TagBits.AnnotationInherited) != 0) {
067:                    char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_INHERITED;
068:                    addTypeReference(compoundName[compoundName.length - 1]);
069:                }
070:                if ((annotationTagBits & TagBits.AnnotationOverride) != 0) {
071:                    char[][] compoundName = TypeConstants.JAVA_LANG_OVERRIDE;
072:                    addTypeReference(compoundName[compoundName.length - 1]);
073:                }
074:                if ((annotationTagBits & TagBits.AnnotationSuppressWarnings) != 0) {
075:                    char[][] compoundName = TypeConstants.JAVA_LANG_SUPPRESSWARNINGS;
076:                    addTypeReference(compoundName[compoundName.length - 1]);
077:                }
078:            }
079:
080:            private void addBinaryTargetAnnotation(long bits) {
081:                char[][] compoundName = null;
082:                if ((bits & TagBits.AnnotationForAnnotationType) != 0) {
083:                    compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
084:                    addTypeReference(compoundName[compoundName.length - 1]);
085:                    addFieldReference(TypeConstants.UPPER_ANNOTATION_TYPE);
086:                }
087:                if ((bits & TagBits.AnnotationForConstructor) != 0) {
088:                    if (compoundName == null) {
089:                        compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
090:                        addTypeReference(compoundName[compoundName.length - 1]);
091:                    }
092:                    addFieldReference(TypeConstants.UPPER_CONSTRUCTOR);
093:                }
094:                if ((bits & TagBits.AnnotationForField) != 0) {
095:                    if (compoundName == null) {
096:                        compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
097:                        addTypeReference(compoundName[compoundName.length - 1]);
098:                    }
099:                    addFieldReference(TypeConstants.UPPER_FIELD);
100:                }
101:                if ((bits & TagBits.AnnotationForLocalVariable) != 0) {
102:                    if (compoundName == null) {
103:                        compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
104:                        addTypeReference(compoundName[compoundName.length - 1]);
105:                    }
106:                    addFieldReference(TypeConstants.UPPER_LOCAL_VARIABLE);
107:                }
108:                if ((bits & TagBits.AnnotationForMethod) != 0) {
109:                    if (compoundName == null) {
110:                        compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
111:                        addTypeReference(compoundName[compoundName.length - 1]);
112:                    }
113:                    addFieldReference(TypeConstants.UPPER_METHOD);
114:                }
115:                if ((bits & TagBits.AnnotationForPackage) != 0) {
116:                    if (compoundName == null) {
117:                        compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
118:                        addTypeReference(compoundName[compoundName.length - 1]);
119:                    }
120:                    addFieldReference(TypeConstants.UPPER_PACKAGE);
121:                }
122:                if ((bits & TagBits.AnnotationForParameter) != 0) {
123:                    if (compoundName == null) {
124:                        compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
125:                        addTypeReference(compoundName[compoundName.length - 1]);
126:                    }
127:                    addFieldReference(TypeConstants.UPPER_PARAMETER);
128:                }
129:                if ((bits & TagBits.AnnotationForType) != 0) {
130:                    if (compoundName == null) {
131:                        compoundName = TypeConstants.JAVA_LANG_ANNOTATION_ELEMENTTYPE;
132:                        addTypeReference(compoundName[compoundName.length - 1]);
133:                    }
134:                    addFieldReference(TypeConstants.TYPE);
135:                }
136:            }
137:
138:            private void addBinaryRetentionAnnotation(long bits) {
139:                char[][] compoundName = TypeConstants.JAVA_LANG_ANNOTATION_RETENTIONPOLICY;
140:                addTypeReference(compoundName[compoundName.length - 1]);
141:                if ((bits & TagBits.AnnotationRuntimeRetention) != 0) {
142:                    addFieldReference(TypeConstants.UPPER_RUNTIME);
143:                } else if ((bits & TagBits.AnnotationClassRetention) != 0) {
144:                    addFieldReference(TypeConstants.UPPER_CLASS);
145:                } else if ((bits & TagBits.AnnotationSourceRetention) != 0) {
146:                    addFieldReference(TypeConstants.UPPER_SOURCE);
147:                }
148:            }
149:
150:            private void addBinaryAnnotation(IBinaryAnnotation annotation) {
151:                addTypeReference(replace('/', '.', Signature
152:                        .toCharArray(annotation.getTypeName())));
153:                IBinaryElementValuePair[] valuePairs = annotation
154:                        .getElementValuePairs();
155:                if (valuePairs != null) {
156:                    for (int j = 0, vpLength = valuePairs.length; j < vpLength; j++) {
157:                        IBinaryElementValuePair valuePair = valuePairs[j];
158:                        addMethodReference(valuePair.getName(), 0);
159:                        Object pairValue = valuePair.getValue();
160:                        addPairValue(pairValue);
161:                    }
162:                }
163:            }
164:
165:            private void addPairValue(Object pairValue) {
166:                if (pairValue instanceof  EnumConstantSignature) {
167:                    EnumConstantSignature enumConstant = (EnumConstantSignature) pairValue;
168:                    addTypeReference(replace('/', '.', Signature
169:                            .toCharArray(enumConstant.getTypeName())));
170:                    addNameReference(enumConstant.getEnumConstantName());
171:                } else if (pairValue instanceof  ClassSignature) {
172:                    ClassSignature classConstant = (ClassSignature) pairValue;
173:                    addTypeReference(replace('/', '.', Signature
174:                            .toCharArray(classConstant.getTypeName())));
175:                } else if (pairValue instanceof  IBinaryAnnotation) {
176:                    addBinaryAnnotation((IBinaryAnnotation) pairValue);
177:                } else if (pairValue instanceof  Object[]) {
178:                    Object[] objects = (Object[]) pairValue;
179:                    for (int i = 0, l = objects.length; i < l; i++) {
180:                        addPairValue(objects[i]);
181:                    }
182:                }
183:            }
184:
185:            public void addTypeReference(char[] typeName) {
186:                int length = typeName.length;
187:                if (length > 2 && typeName[length - 2] == '$') {
188:                    switch (typeName[length - 1]) {
189:                    case '0':
190:                    case '1':
191:                    case '2':
192:                    case '3':
193:                    case '4':
194:                    case '5':
195:                    case '6':
196:                    case '7':
197:                    case '8':
198:                    case '9':
199:                        return; // skip local type names
200:                    }
201:                }
202:
203:                // consider that A$B is a member type: so replace '$' with '.'
204:                // (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=40116)
205:                typeName = CharOperation.replaceOnCopy(typeName, '$', '.'); // copy it so the original is not modified
206:
207:                super .addTypeReference(typeName);
208:            }
209:
210:            /**
211:             * For example:
212:             *   - int foo(String[]) is ([Ljava/lang/String;)I => java.lang.String[] in a char[][]
213:             *   - void foo(int) is (I)V ==> int
214:             */
215:            private void convertToArrayType(char[][] parameterTypes,
216:                    int counter, int arrayDim) {
217:                int length = parameterTypes[counter].length;
218:                char[] arrayType = new char[length + arrayDim * 2];
219:                System.arraycopy(parameterTypes[counter], 0, arrayType, 0,
220:                        length);
221:                for (int i = 0; i < arrayDim; i++) {
222:                    arrayType[length + (i * 2)] = '[';
223:                    arrayType[length + (i * 2) + 1] = ']';
224:                }
225:                parameterTypes[counter] = arrayType;
226:            }
227:
228:            /**
229:             * For example:
230:             *   - int foo(String[]) is ([Ljava/lang/String;)I => java.lang.String[] in a char[][]
231:             *   - void foo(int) is (I)V ==> int
232:             */
233:            private char[] convertToArrayType(char[] typeName, int arrayDim) {
234:                int length = typeName.length;
235:                char[] arrayType = new char[length + arrayDim * 2];
236:                System.arraycopy(typeName, 0, arrayType, 0, length);
237:                for (int i = 0; i < arrayDim; i++) {
238:                    arrayType[length + (i * 2)] = '[';
239:                    arrayType[length + (i * 2) + 1] = ']';
240:                }
241:                return arrayType;
242:            }
243:
244:            private char[] decodeFieldType(char[] signature)
245:                    throws ClassFormatException {
246:                if (signature == null)
247:                    return null;
248:                int arrayDim = 0;
249:                for (int i = 0, max = signature.length; i < max; i++) {
250:                    switch (signature[i]) {
251:                    case 'B':
252:                        if (arrayDim > 0)
253:                            return convertToArrayType(BYTE, arrayDim);
254:                        return BYTE;
255:
256:                    case 'C':
257:                        if (arrayDim > 0)
258:                            return convertToArrayType(CHAR, arrayDim);
259:                        return CHAR;
260:
261:                    case 'D':
262:                        if (arrayDim > 0)
263:                            return convertToArrayType(DOUBLE, arrayDim);
264:                        return DOUBLE;
265:
266:                    case 'F':
267:                        if (arrayDim > 0)
268:                            return convertToArrayType(FLOAT, arrayDim);
269:                        return FLOAT;
270:
271:                    case 'I':
272:                        if (arrayDim > 0)
273:                            return convertToArrayType(INT, arrayDim);
274:                        return INT;
275:
276:                    case 'J':
277:                        if (arrayDim > 0)
278:                            return convertToArrayType(LONG, arrayDim);
279:                        return LONG;
280:
281:                    case 'L':
282:                        int indexOfSemiColon = CharOperation.indexOf(';',
283:                                signature, i + 1);
284:                        if (indexOfSemiColon == -1)
285:                            throw new ClassFormatException(
286:                                    ClassFormatException.ErrInvalidMethodSignature);
287:                        if (arrayDim > 0) {
288:                            return convertToArrayType(replace('/', '.',
289:                                    CharOperation.subarray(signature, i + 1,
290:                                            indexOfSemiColon)), arrayDim);
291:                        }
292:                        return replace('/', '.', CharOperation.subarray(
293:                                signature, i + 1, indexOfSemiColon));
294:
295:                    case 'S':
296:                        if (arrayDim > 0)
297:                            return convertToArrayType(SHORT, arrayDim);
298:                        return SHORT;
299:
300:                    case 'Z':
301:                        if (arrayDim > 0)
302:                            return convertToArrayType(BOOLEAN, arrayDim);
303:                        return BOOLEAN;
304:
305:                    case 'V':
306:                        return VOID;
307:
308:                    case '[':
309:                        arrayDim++;
310:                        break;
311:
312:                    default:
313:                        throw new ClassFormatException(
314:                                ClassFormatException.ErrInvalidMethodSignature);
315:                    }
316:                }
317:                return null;
318:            }
319:
320:            /**
321:             * For example:
322:             *   - int foo(String[]) is ([Ljava/lang/String;)I => java.lang.String[] in a char[][]
323:             *   - void foo(int) is (I)V ==> int
324:             */
325:            private char[][] decodeParameterTypes(char[] signature,
326:                    boolean firstIsSynthetic) throws ClassFormatException {
327:                if (signature == null)
328:                    return null;
329:                int indexOfClosingParen = CharOperation.lastIndexOf(')',
330:                        signature);
331:                if (indexOfClosingParen == 1) {
332:                    // there is no parameter
333:                    return null;
334:                }
335:                if (indexOfClosingParen == -1) {
336:                    throw new ClassFormatException(
337:                            ClassFormatException.ErrInvalidMethodSignature);
338:                }
339:                char[][] parameterTypes = new char[3][];
340:                int parameterTypesCounter = 0;
341:                int arrayDim = 0;
342:                for (int i = 1; i < indexOfClosingParen; i++) {
343:                    if (parameterTypesCounter == parameterTypes.length) {
344:                        // resize
345:                        System
346:                                .arraycopy(
347:                                        parameterTypes,
348:                                        0,
349:                                        (parameterTypes = new char[parameterTypesCounter * 2][]),
350:                                        0, parameterTypesCounter);
351:                    }
352:                    switch (signature[i]) {
353:                    case 'B':
354:                        parameterTypes[parameterTypesCounter++] = BYTE;
355:                        if (arrayDim > 0)
356:                            convertToArrayType(parameterTypes,
357:                                    parameterTypesCounter - 1, arrayDim);
358:                        arrayDim = 0;
359:                        break;
360:
361:                    case 'C':
362:                        parameterTypes[parameterTypesCounter++] = CHAR;
363:                        if (arrayDim > 0)
364:                            convertToArrayType(parameterTypes,
365:                                    parameterTypesCounter - 1, arrayDim);
366:                        arrayDim = 0;
367:                        break;
368:
369:                    case 'D':
370:                        parameterTypes[parameterTypesCounter++] = DOUBLE;
371:                        if (arrayDim > 0)
372:                            convertToArrayType(parameterTypes,
373:                                    parameterTypesCounter - 1, arrayDim);
374:                        arrayDim = 0;
375:                        break;
376:
377:                    case 'F':
378:                        parameterTypes[parameterTypesCounter++] = FLOAT;
379:                        if (arrayDim > 0)
380:                            convertToArrayType(parameterTypes,
381:                                    parameterTypesCounter - 1, arrayDim);
382:                        arrayDim = 0;
383:                        break;
384:
385:                    case 'I':
386:                        parameterTypes[parameterTypesCounter++] = INT;
387:                        if (arrayDim > 0)
388:                            convertToArrayType(parameterTypes,
389:                                    parameterTypesCounter - 1, arrayDim);
390:                        arrayDim = 0;
391:                        break;
392:
393:                    case 'J':
394:                        parameterTypes[parameterTypesCounter++] = LONG;
395:                        if (arrayDim > 0)
396:                            convertToArrayType(parameterTypes,
397:                                    parameterTypesCounter - 1, arrayDim);
398:                        arrayDim = 0;
399:                        break;
400:
401:                    case 'L':
402:                        int indexOfSemiColon = CharOperation.indexOf(';',
403:                                signature, i + 1);
404:                        if (indexOfSemiColon == -1)
405:                            throw new ClassFormatException(
406:                                    ClassFormatException.ErrInvalidMethodSignature);
407:                        if (firstIsSynthetic && parameterTypesCounter == 0) {
408:                            // skip first synthetic parameter
409:                            firstIsSynthetic = false;
410:                        } else {
411:                            parameterTypes[parameterTypesCounter++] = replace(
412:                                    '/', '.', CharOperation.subarray(signature,
413:                                            i + 1, indexOfSemiColon));
414:                            if (arrayDim > 0)
415:                                convertToArrayType(parameterTypes,
416:                                        parameterTypesCounter - 1, arrayDim);
417:                        }
418:                        i = indexOfSemiColon;
419:                        arrayDim = 0;
420:                        break;
421:
422:                    case 'S':
423:                        parameterTypes[parameterTypesCounter++] = SHORT;
424:                        if (arrayDim > 0)
425:                            convertToArrayType(parameterTypes,
426:                                    parameterTypesCounter - 1, arrayDim);
427:                        arrayDim = 0;
428:                        break;
429:
430:                    case 'Z':
431:                        parameterTypes[parameterTypesCounter++] = BOOLEAN;
432:                        if (arrayDim > 0)
433:                            convertToArrayType(parameterTypes,
434:                                    parameterTypesCounter - 1, arrayDim);
435:                        arrayDim = 0;
436:                        break;
437:
438:                    case '[':
439:                        arrayDim++;
440:                        break;
441:
442:                    default:
443:                        throw new ClassFormatException(
444:                                ClassFormatException.ErrInvalidMethodSignature);
445:                    }
446:                }
447:                if (parameterTypes.length != parameterTypesCounter) {
448:                    System.arraycopy(parameterTypes, 0,
449:                            parameterTypes = new char[parameterTypesCounter][],
450:                            0, parameterTypesCounter);
451:                }
452:                return parameterTypes;
453:            }
454:
455:            private char[] decodeReturnType(char[] signature)
456:                    throws ClassFormatException {
457:                if (signature == null)
458:                    return null;
459:                int indexOfClosingParen = CharOperation.lastIndexOf(')',
460:                        signature);
461:                if (indexOfClosingParen == -1)
462:                    throw new ClassFormatException(
463:                            ClassFormatException.ErrInvalidMethodSignature);
464:                int arrayDim = 0;
465:                for (int i = indexOfClosingParen + 1, max = signature.length; i < max; i++) {
466:                    switch (signature[i]) {
467:                    case 'B':
468:                        if (arrayDim > 0)
469:                            return convertToArrayType(BYTE, arrayDim);
470:                        return BYTE;
471:
472:                    case 'C':
473:                        if (arrayDim > 0)
474:                            return convertToArrayType(CHAR, arrayDim);
475:                        return CHAR;
476:
477:                    case 'D':
478:                        if (arrayDim > 0)
479:                            return convertToArrayType(DOUBLE, arrayDim);
480:                        return DOUBLE;
481:
482:                    case 'F':
483:                        if (arrayDim > 0)
484:                            return convertToArrayType(FLOAT, arrayDim);
485:                        return FLOAT;
486:
487:                    case 'I':
488:                        if (arrayDim > 0)
489:                            return convertToArrayType(INT, arrayDim);
490:                        return INT;
491:
492:                    case 'J':
493:                        if (arrayDim > 0)
494:                            return convertToArrayType(LONG, arrayDim);
495:                        return LONG;
496:
497:                    case 'L':
498:                        int indexOfSemiColon = CharOperation.indexOf(';',
499:                                signature, i + 1);
500:                        if (indexOfSemiColon == -1)
501:                            throw new ClassFormatException(
502:                                    ClassFormatException.ErrInvalidMethodSignature);
503:                        if (arrayDim > 0) {
504:                            return convertToArrayType(replace('/', '.',
505:                                    CharOperation.subarray(signature, i + 1,
506:                                            indexOfSemiColon)), arrayDim);
507:                        }
508:                        return replace('/', '.', CharOperation.subarray(
509:                                signature, i + 1, indexOfSemiColon));
510:
511:                    case 'S':
512:                        if (arrayDim > 0)
513:                            return convertToArrayType(SHORT, arrayDim);
514:                        return SHORT;
515:
516:                    case 'Z':
517:                        if (arrayDim > 0)
518:                            return convertToArrayType(BOOLEAN, arrayDim);
519:                        return BOOLEAN;
520:
521:                    case 'V':
522:                        return VOID;
523:
524:                    case '[':
525:                        arrayDim++;
526:                        break;
527:
528:                    default:
529:                        throw new ClassFormatException(
530:                                ClassFormatException.ErrInvalidMethodSignature);
531:                    }
532:                }
533:                return null;
534:            }
535:
536:            private int extractArgCount(char[] signature, char[] className)
537:                    throws ClassFormatException {
538:                int indexOfClosingParen = CharOperation.lastIndexOf(')',
539:                        signature);
540:                if (indexOfClosingParen == 1) {
541:                    // there is no parameter
542:                    return 0;
543:                }
544:                if (indexOfClosingParen == -1) {
545:                    throw new ClassFormatException(
546:                            ClassFormatException.ErrInvalidMethodSignature);
547:                }
548:                int parameterTypesCounter = 0;
549:                for (int i = 1; i < indexOfClosingParen; i++) {
550:                    switch (signature[i]) {
551:                    case 'B':
552:                    case 'C':
553:                    case 'D':
554:                    case 'F':
555:                    case 'I':
556:                    case 'J':
557:                    case 'S':
558:                    case 'Z':
559:                        parameterTypesCounter++;
560:                        break;
561:                    case 'L':
562:                        int indexOfSemiColon = CharOperation.indexOf(';',
563:                                signature, i + 1);
564:                        if (indexOfSemiColon == -1)
565:                            throw new ClassFormatException(
566:                                    ClassFormatException.ErrInvalidMethodSignature);
567:                        // verify if first parameter is synthetic
568:                        if (className != null && parameterTypesCounter == 0) {
569:                            char[] classSignature = Signature
570:                                    .createCharArrayTypeSignature(className,
571:                                            true);
572:                            int length = indexOfSemiColon - i + 1;
573:                            if (classSignature.length > (length + 1)) {
574:                                // synthetic means that parameter type has same signature than given class
575:                                for (int j = i, k = 0; j < indexOfSemiColon; j++, k++) {
576:                                    if (!(signature[j] == classSignature[k] || (signature[j] == '/' && classSignature[k] == '.'))) {
577:                                        parameterTypesCounter++;
578:                                        break;
579:                                    }
580:                                }
581:                            } else {
582:                                parameterTypesCounter++;
583:                            }
584:                            className = null; // do not verify following parameters
585:                        } else {
586:                            parameterTypesCounter++;
587:                        }
588:                        i = indexOfSemiColon;
589:                        break;
590:                    case '[':
591:                        break;
592:                    default:
593:                        throw new ClassFormatException(
594:                                ClassFormatException.ErrInvalidMethodSignature);
595:                    }
596:                }
597:                return parameterTypesCounter;
598:            }
599:
600:            private char[] extractClassName(int[] constantPoolOffsets,
601:                    ClassFileReader reader, int index) {
602:                // the entry at i has to be a field ref or a method/interface method ref.
603:                int class_index = reader.u2At(constantPoolOffsets[index] + 1);
604:                int utf8Offset = constantPoolOffsets[reader
605:                        .u2At(constantPoolOffsets[class_index] + 1)];
606:                return reader.utf8At(utf8Offset + 3, reader
607:                        .u2At(utf8Offset + 1));
608:            }
609:
610:            private char[] extractName(int[] constantPoolOffsets,
611:                    ClassFileReader reader, int index) {
612:                int nameAndTypeIndex = reader
613:                        .u2At(constantPoolOffsets[index] + 3);
614:                int utf8Offset = constantPoolOffsets[reader
615:                        .u2At(constantPoolOffsets[nameAndTypeIndex] + 1)];
616:                return reader.utf8At(utf8Offset + 3, reader
617:                        .u2At(utf8Offset + 1));
618:            }
619:
620:            private char[] extractClassReference(int[] constantPoolOffsets,
621:                    ClassFileReader reader, int index) {
622:                // the entry at i has to be a class ref.
623:                int utf8Offset = constantPoolOffsets[reader
624:                        .u2At(constantPoolOffsets[index] + 1)];
625:                return reader.utf8At(utf8Offset + 3, reader
626:                        .u2At(utf8Offset + 1));
627:            }
628:
629:            /**
630:             * Extract all type, method, field and interface method references from the constant pool
631:             */
632:            private void extractReferenceFromConstantPool(byte[] contents,
633:                    ClassFileReader reader) throws ClassFormatException {
634:                int[] constantPoolOffsets = reader.getConstantPoolOffsets();
635:                int constantPoolCount = constantPoolOffsets.length;
636:                for (int i = 1; i < constantPoolCount; i++) {
637:                    int tag = reader.u1At(constantPoolOffsets[i]);
638:                    /**
639:                     * u1 tag
640:                     * u2 class_index
641:                     * u2 name_and_type_index
642:                     */
643:                    char[] name = null;
644:                    char[] type = null;
645:                    switch (tag) {
646:                    case ClassFileConstants.FieldRefTag:
647:                        // add reference to the class/interface and field name and type
648:                        name = extractName(constantPoolOffsets, reader, i);
649:                        addFieldReference(name);
650:                        break;
651:                    case ClassFileConstants.MethodRefTag:
652:                        // add reference to the class and method name and type
653:                    case ClassFileConstants.InterfaceMethodRefTag:
654:                        // add reference to the interface and method name and type
655:                        name = extractName(constantPoolOffsets, reader, i);
656:                        type = extractType(constantPoolOffsets, reader, i);
657:                        if (CharOperation.equals(INIT, name)) {
658:                            // get class name and see if it's a local type or not
659:                            char[] className = extractClassName(
660:                                    constantPoolOffsets, reader, i);
661:                            boolean localType = false;
662:                            if (className != null) {
663:                                for (int c = 0, max = className.length; c < max; c++) {
664:                                    switch (className[c]) {
665:                                    case '/':
666:                                        className[c] = '.';
667:                                        break;
668:                                    case '$':
669:                                        localType = true;
670:                                        break;
671:                                    }
672:                                }
673:                            }
674:                            // add a constructor reference, use class name to extract arg count if it's a local type to remove synthetic parameter
675:                            addConstructorReference(className, extractArgCount(
676:                                    type, localType ? className : null));
677:                        } else {
678:                            // add a method reference
679:                            addMethodReference(name,
680:                                    extractArgCount(type, null));
681:                        }
682:                        break;
683:                    case ClassFileConstants.ClassTag:
684:                        // add a type reference
685:                        name = extractClassReference(constantPoolOffsets,
686:                                reader, i);
687:                        if (name.length > 0 && name[0] == '[')
688:                            break; // skip over array references
689:                        name = replace('/', '.', name); // so that it looks like java.lang.String
690:                        addTypeReference(name);
691:
692:                        // also add a simple reference on each segment of the qualification (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=24741)
693:                        char[][] qualification = CharOperation.splitOn('.',
694:                                name);
695:                        for (int j = 0, length = qualification.length; j < length; j++) {
696:                            addNameReference(qualification[j]);
697:                        }
698:                        break;
699:                    }
700:                }
701:            }
702:
703:            private char[] extractType(int[] constantPoolOffsets,
704:                    ClassFileReader reader, int index) {
705:                int constantPoolIndex = reader
706:                        .u2At(constantPoolOffsets[index] + 3);
707:                int utf8Offset = constantPoolOffsets[reader
708:                        .u2At(constantPoolOffsets[constantPoolIndex] + 3)];
709:                return reader.utf8At(utf8Offset + 3, reader
710:                        .u2At(utf8Offset + 1));
711:            }
712:
713:            public void indexDocument() {
714:                try {
715:                    final byte[] contents = this .document.getByteContents();
716:                    // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=107124
717:                    // contents can potentially be null if a IOException occurs while retrieving the contents
718:                    if (contents == null)
719:                        return;
720:                    final String path = this .document.getPath();
721:                    ClassFileReader reader = new ClassFileReader(contents,
722:                            path == null ? null : path.toCharArray());
723:
724:                    // first add type references
725:                    char[] className = replace('/', '.', reader.getName()); // looks like java/lang/String
726:                    // need to extract the package name and the simple name
727:                    int packageNameIndex = CharOperation.lastIndexOf('.',
728:                            className);
729:                    char[] packageName = null;
730:                    char[] name = null;
731:                    if (packageNameIndex >= 0) {
732:                        packageName = CharOperation.subarray(className, 0,
733:                                packageNameIndex);
734:                        name = CharOperation.subarray(className,
735:                                packageNameIndex + 1, className.length);
736:                    } else {
737:                        packageName = CharOperation.NO_CHAR;
738:                        name = className;
739:                    }
740:                    char[] enclosingTypeName = null;
741:                    boolean isNestedType = reader.isNestedType();
742:                    if (isNestedType) {
743:                        if (reader.isAnonymous()) {
744:                            name = CharOperation.NO_CHAR;
745:                        } else {
746:                            name = reader.getInnerSourceName();
747:                        }
748:                        if (reader.isLocal() || reader.isAnonymous()) {
749:                            // set specific ['0'] value for local and anonymous to be able to filter them
750:                            enclosingTypeName = ONE_ZERO;
751:                        } else {
752:                            char[] fullEnclosingName = reader
753:                                    .getEnclosingTypeName();
754:                            int nameLength = fullEnclosingName.length
755:                                    - packageNameIndex - 1;
756:                            if (nameLength <= 0) {
757:                                // See PR 1GIR345: ITPJCORE:ALL - Indexer: NegativeArraySizeException
758:                                return;
759:                            }
760:                            enclosingTypeName = new char[nameLength];
761:                            System.arraycopy(fullEnclosingName,
762:                                    packageNameIndex + 1, enclosingTypeName, 0,
763:                                    nameLength);
764:                        }
765:                    }
766:                    // type parameters
767:                    char[][] typeParameterSignatures = null;
768:                    char[] genericSignature = reader.getGenericSignature();
769:                    if (genericSignature != null) {
770:                        CharOperation.replace(genericSignature, '/', '.');
771:                        typeParameterSignatures = Signature
772:                                .getTypeParameters(genericSignature);
773:                    }
774:
775:                    // eliminate invalid innerclasses (1G4KCF7)
776:                    if (name == null)
777:                        return;
778:
779:                    char[][] super interfaces = replace('/', '.', reader
780:                            .getInterfaceNames());
781:                    char[][] enclosingTypeNames = enclosingTypeName == null ? null
782:                            : new char[][] { enclosingTypeName };
783:                    int modifiers = reader.getModifiers();
784:                    switch (TypeDeclaration.kind(modifiers)) {
785:                    case TypeDeclaration.CLASS_DECL:
786:                        char[] super class = replace('/', '.', reader
787:                                .getSuperclassName());
788:                        addClassDeclaration(modifiers, packageName, name,
789:                                enclosingTypeNames, super class,
790:                                super interfaces, typeParameterSignatures, false);
791:                        break;
792:                    case TypeDeclaration.INTERFACE_DECL:
793:                        addInterfaceDeclaration(modifiers, packageName, name,
794:                                enclosingTypeNames, super interfaces,
795:                                typeParameterSignatures, false);
796:                        break;
797:                    case TypeDeclaration.ENUM_DECL:
798:                        super class = replace('/', '.', reader
799:                                .getSuperclassName());
800:                        addEnumDeclaration(modifiers, packageName, name,
801:                                enclosingTypeNames, super class,
802:                                super interfaces, false);
803:                        break;
804:                    case TypeDeclaration.ANNOTATION_TYPE_DECL:
805:                        addAnnotationTypeDeclaration(modifiers, packageName,
806:                                name, enclosingTypeNames, false);
807:                        break;
808:                    }
809:
810:                    // Look for references in class annotations
811:                    IBinaryAnnotation[] annotations = reader.getAnnotations();
812:                    if (annotations != null) {
813:                        for (int a = 0, length = annotations.length; a < length; a++) {
814:                            IBinaryAnnotation annotation = annotations[a];
815:                            addBinaryAnnotation(annotation);
816:                        }
817:                    }
818:                    long tagBits = reader.getTagBits()
819:                            & TagBits.AllStandardAnnotationsMask;
820:                    if (tagBits != 0) {
821:                        addBinaryStandardAnnotations(tagBits);
822:                    }
823:
824:                    // first reference all methods declarations and field declarations
825:                    MethodInfo[] methods = (MethodInfo[]) reader.getMethods();
826:                    if (methods != null) {
827:                        for (int i = 0, max = methods.length; i < max; i++) {
828:                            MethodInfo method = methods[i];
829:                            boolean isConstructor = method.isConstructor();
830:                            char[] descriptor = method.getMethodDescriptor();
831:                            char[][] parameterTypes = decodeParameterTypes(
832:                                    descriptor, isConstructor && isNestedType);
833:                            char[] returnType = decodeReturnType(descriptor);
834:                            char[][] exceptionTypes = replace('/', '.', method
835:                                    .getExceptionTypeNames());
836:                            if (isConstructor) {
837:                                addConstructorDeclaration(className,
838:                                        parameterTypes, exceptionTypes);
839:                            } else {
840:                                if (!method.isClinit()) {
841:                                    addMethodDeclaration(method.getSelector(),
842:                                            parameterTypes, returnType,
843:                                            exceptionTypes);
844:                                }
845:                            }
846:                            // look for references in method annotations
847:                            annotations = method.getAnnotations();
848:                            if (annotations != null) {
849:                                for (int a = 0, length = annotations.length; a < length; a++) {
850:                                    IBinaryAnnotation annotation = annotations[a];
851:                                    addBinaryAnnotation(annotation);
852:                                }
853:                            }
854:                        }
855:                    }
856:                    FieldInfo[] fields = (FieldInfo[]) reader.getFields();
857:                    if (fields != null) {
858:                        for (int i = 0, max = fields.length; i < max; i++) {
859:                            FieldInfo field = fields[i];
860:                            char[] fieldName = field.getName();
861:                            char[] fieldType = decodeFieldType(replace('/',
862:                                    '.', field.getTypeName()));
863:                            addFieldDeclaration(fieldType, fieldName);
864:                            // look for references in field annotations
865:                            annotations = field.getAnnotations();
866:                            if (annotations != null) {
867:                                for (int a = 0, length = annotations.length; a < length; a++) {
868:                                    IBinaryAnnotation annotation = annotations[a];
869:                                    addBinaryAnnotation(annotation);
870:                                }
871:                            }
872:                        }
873:                    }
874:                    // record all references found inside the .class file
875:                    extractReferenceFromConstantPool(contents, reader);
876:                } catch (ClassFormatException e) {
877:                    // ignore
878:                    this .document.removeAllIndexEntries();
879:                    Util
880:                            .log(
881:                                    e,
882:                                    "ClassFormatException in " + this .document.getPath() + ". Please report this issue to JDT/Core including the problematic document"); //$NON-NLS-1$ //$NON-NLS-2$
883:                } catch (RuntimeException e) {
884:                    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=182154
885:                    // logging the entry that could not be indexed and continue with the next one
886:                    // we remove all entries relative to the boggus document
887:                    this .document.removeAllIndexEntries();
888:                    Util
889:                            .log(
890:                                    e,
891:                                    "Indexer crashed on document " + this .document.getPath() + ". Please report this issue to JDT/Core including the problematic document"); //$NON-NLS-1$ //$NON-NLS-2$
892:                }
893:            }
894:
895:            /*
896:             * Modify the array by replacing all occurences of toBeReplaced with newChar
897:             */
898:            private char[][] replace(char toBeReplaced, char newChar,
899:                    char[][] array) {
900:                if (array == null)
901:                    return null;
902:                for (int i = 0, max = array.length; i < max; i++) {
903:                    replace(toBeReplaced, newChar, array[i]);
904:                }
905:                return array;
906:            }
907:
908:            /*
909:             * Modify the array by replacing all occurences of toBeReplaced with newChar
910:             */
911:            private char[] replace(char toBeReplaced, char newChar, char[] array) {
912:                if (array == null)
913:                    return null;
914:                for (int i = 0, max = array.length; i < max; i++) {
915:                    if (array[i] == toBeReplaced) {
916:                        array[i] = newChar;
917:                    }
918:                }
919:                return array;
920:            }
921:        }
ww__w.j_av__a__2s.___co__m | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.