diff options
Diffstat (limited to 'org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core')
55 files changed, 2003 insertions, 680 deletions
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java index 1c16666e9f..7ff39d39c9 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java @@ -15,6 +15,7 @@ import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.SourceElementRequestorAdapter; import org.eclipse.jdt.internal.compiler.env.IBinaryMethod; import org.eclipse.jdt.internal.core.util.Util; @@ -37,7 +38,9 @@ import org.eclipse.jdt.internal.core.util.Util; int nameSourceEnd, char[][] paramTypes, char[][] paramNames, - char[][] exceptions) { + char[][] exceptions, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { if (paramNames != null) { int length = paramNames.length; this.parametersNames = new String[length]; @@ -55,7 +58,9 @@ import org.eclipse.jdt.internal.core.util.Util; int nameSourceEnd, char[][] paramTypes, char[][] paramNames, - char[][] exceptions) { + char[][] exceptions, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { if (paramNames != null) { int length = paramNames.length; this.parametersNames = new String[length]; @@ -106,20 +111,27 @@ public boolean equals(Object o) { public String[] getExceptionTypes() throws JavaModelException { if (this.exceptionTypes == null) { IBinaryMethod info = (IBinaryMethod) getElementInfo(); - char[][] eTypeNames = info.getExceptionTypeNames(); - if (eTypeNames == null || eTypeNames.length == 0) { - this.exceptionTypes = NO_TYPES; - } else { - eTypeNames = ClassFile.translatedNames(eTypeNames); - this.exceptionTypes = new String[eTypeNames.length]; - for (int j = 0, length = eTypeNames.length; j < length; j++) { - // 1G01HRY: ITPJCORE:WINNT - method.getExceptionType not in correct format - int nameLength = eTypeNames[j].length; - char[] convertedName = new char[nameLength + 2]; - System.arraycopy(eTypeNames[j], 0, convertedName, 1, nameLength); - convertedName[0] = 'L'; - convertedName[nameLength + 1] = ';'; - this.exceptionTypes[j] = new String(convertedName); + char[] genericSignature = info.getGenericSignature(); + if (genericSignature != null) { + char[] dotBasedSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.'); + this.exceptionTypes = Signature.getThrownExceptionTypes(new String(dotBasedSignature)); + } + if (this.exceptionTypes == null || this.exceptionTypes.length == 0) { + char[][] eTypeNames = info.getExceptionTypeNames(); + if (eTypeNames == null || eTypeNames.length == 0) { + this.exceptionTypes = NO_TYPES; + } else { + eTypeNames = ClassFile.translatedNames(eTypeNames); + this.exceptionTypes = new String[eTypeNames.length]; + for (int j = 0, length = eTypeNames.length; j < length; j++) { + // 1G01HRY: ITPJCORE:WINNT - method.getExceptionType not in correct format + int nameLength = eTypeNames[j].length; + char[] convertedName = new char[nameLength + 2]; + System.arraycopy(eTypeNames[j], 0, convertedName, 1, nameLength); + convertedName[0] = 'L'; + convertedName[nameLength + 1] = ';'; + this.exceptionTypes[j] = new String(convertedName); + } } } } @@ -222,8 +234,20 @@ public String[] getParameterTypes() { * @since 3.0 */ public String[] getTypeParameterSignatures() throws JavaModelException { - // TODO (jerome) - missing implementation - return new String[0]; + IBinaryMethod info = (IBinaryMethod) getElementInfo(); + char[] genericSignature = info.getGenericSignature(); + if (genericSignature == null) + return EmptyStringList; + char[] dotBasedSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.'); + char[][] typeParams = Signature.getTypeParameters(dotBasedSignature); + int length = typeParams.length; + if (length == 0) + return EmptyStringList; + String[] stringSignatures = new String[length]; + for (int i = 0; i < length; i++) { + stringSignatures[i] = new String(typeParams[i]); + } + return stringSignatures; } /* @@ -232,7 +256,10 @@ public String[] getTypeParameterSignatures() throws JavaModelException { public String getReturnType() throws JavaModelException { IBinaryMethod info = (IBinaryMethod) getElementInfo(); if (this.returnType == null) { - String returnTypeName= Signature.getReturnType(new String(info.getMethodDescriptor())); + char[] genericSignature = info.getGenericSignature(); + char[] signature = genericSignature == null ? info.getMethodDescriptor() : genericSignature; + char[] dotBasedSignature = CharOperation.replaceOnCopy(signature, '/', '.'); + String returnTypeName= Signature.getReturnType(new String(dotBasedSignature)); this.returnType= new String(ClassFile.translatedName(returnTypeName.toCharArray())); } return this.returnType; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java index 6ec52aad40..aa945d50be 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryType.java @@ -448,13 +448,27 @@ public String[] getSuperInterfaceTypeSignatures() throws JavaModelException { return strings; } + /** * @see IType#getTypeParameterSignatures() * @since 3.0 */ public String[] getTypeParameterSignatures() throws JavaModelException { - // TODO (jerome) - missing implementation - return new String[0]; + IBinaryType info = (IBinaryType) getElementInfo(); + char[] genericSignature = info.getGenericSignature(); + if (genericSignature == null) + return EmptyStringList; + + char[] dotBaseSignature = CharOperation.replaceOnCopy(genericSignature, '/', '.'); + char[][] typeParams = Signature.getTypeParameters(dotBaseSignature); + int length = typeParams.length; + if (length == 0) + return EmptyStringList; + String[] stringSignatures = new String[length]; + for (int i = 0; i < length; i++) { + stringSignatures[i] = new String(typeParams[i]); + } + return stringSignatures; } /* diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java index 33458c5736..ddb7a8b5e3 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java @@ -103,7 +103,16 @@ private void generateMethodInfos(IType type, IBinaryType typeInfo, HashMap newEl // TODO (jerome) filter out synthetic members // indexer should not index them as well // if ((methodInfo.getModifiers() & IConstants.AccSynthetic) != 0) continue; // skip synthetic - String[] pNames= Signature.getParameterTypes(new String(methodInfo.getMethodDescriptor())); + char[] signature = methodInfo.getGenericSignature(); + if (signature == null) signature = methodInfo.getMethodDescriptor(); + String[] pNames = null; + try { + pNames = Signature.getParameterTypes(new String(signature)); + } catch (IllegalArgumentException e) { + // protect against malformed .class file (e.g. com/sun/crypto/provider/SunJCE_b.class has a 'a' generic signature) + signature = methodInfo.getMethodDescriptor(); + pNames = Signature.getParameterTypes(new String(signature)); + } char[][] paramNames= new char[pNames.length][]; for (int j= 0; j < pNames.length; j++) { paramNames[j]= pNames[j].toCharArray(); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java index 41ef429613..686dfedacd 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClasspathEntry.java @@ -345,8 +345,14 @@ public class ClasspathEntry implements IClasspathEntry { String projSegment = path.segment(0); if (projSegment != null && projSegment.equals(project.getElementName())) { // this project return JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation); - } else { // another project - return JavaCore.newProjectEntry(path, isExported); + } else { + if (path.segmentCount() == 1) { + // another project + return JavaCore.newProjectEntry(path, isExported); + } else { + // an invalid source folder + return JavaCore.newSourceEntry(path, inclusionPatterns, exclusionPatterns, outputLocation); + } } case IClasspathEntry.CPE_VARIABLE : @@ -997,7 +1003,7 @@ public class ClasspathEntry implements IClasspathEntry { // Build some common strings for status message String projectName = project.getElementName(); boolean pathStartsWithProject = path.segment(0).toString().equals(projectName); - String entryPathMsg = pathStartsWithProject ? path.removeFirstSegments(1).toString() : path.makeRelative().toString(); + String entryPathMsg = pathStartsWithProject ? path.removeFirstSegments(1).makeRelative().toString() : path.toString(); switch(entry.getEntryKind()){ @@ -1057,7 +1063,7 @@ public class ClasspathEntry implements IClasspathEntry { } return validateClasspathEntry(project, entry, checkSourceAttachment, recurseInContainers); } else { - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalVariablePath", path.makeRelative().toString(), projectName)); //$NON-NLS-1$ + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalVariablePath", entryPathMsg, projectName)); //$NON-NLS-1$ } // library entry check @@ -1081,7 +1087,7 @@ public class ClasspathEntry implements IClasspathEntry { && sourceAttachment != null && !sourceAttachment.isEmpty() && JavaModel.getTarget(workspaceRoot, sourceAttachment, true) == null){ - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceAttachment", new String [] {sourceAttachment.makeRelative().toString(), path.makeRelative().toString(), projectName})); //$NON-NLS-1$ + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceAttachment", new String [] {sourceAttachment.toString(), path.toString(), projectName})); //$NON-NLS-1$ } } else { return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalLibraryArchive", entryPathMsg, projectName)); //$NON-NLS-1$ @@ -1092,7 +1098,7 @@ public class ClasspathEntry implements IClasspathEntry { && sourceAttachment != null && !sourceAttachment.isEmpty() && JavaModel.getTarget(workspaceRoot, sourceAttachment, true) == null){ - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceAttachment", new String [] {sourceAttachment.makeRelative().toString(), path.makeRelative().toString(), projectName})); //$NON-NLS-1$ + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceAttachment", new String [] {sourceAttachment.toString(), path.toString(), projectName})); //$NON-NLS-1$ } } } else if (target instanceof File){ @@ -1105,13 +1111,18 @@ public class ClasspathEntry implements IClasspathEntry { && sourceAttachment != null && !sourceAttachment.isEmpty() && JavaModel.getTarget(workspaceRoot, sourceAttachment, true) == null){ - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceAttachment", new String [] {sourceAttachment.toString(), path.makeRelative().toString(), projectName})); //$NON-NLS-1$ + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundSourceAttachment", new String [] {sourceAttachment.toString(), path.toOSString(), projectName})); //$NON-NLS-1$ } } else { - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundLibrary", path.makeRelative().toString(), projectName)); //$NON-NLS-1$ + boolean isExternal = path.getDevice() != null || !workspaceRoot.getProject(path.segment(0)).exists(); + if (isExternal) { + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundLibrary", path.toOSString(), projectName)); //$NON-NLS-1$ + } else { + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundLibrary", entryPathMsg, projectName)); //$NON-NLS-1$ + } } } else { - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalLibraryPath", path.makeRelative().toString(), projectName)); //$NON-NLS-1$ + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalLibraryPath", entryPathMsg, projectName)); //$NON-NLS-1$ } break; @@ -1122,10 +1133,10 @@ public class ClasspathEntry implements IClasspathEntry { IJavaProject prereqProject = JavaCore.create(prereqProjectRsc); try { if (!prereqProjectRsc.exists() || !prereqProjectRsc.hasNature(JavaCore.NATURE_ID)){ - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundProject", path.makeRelative().segment(0).toString(), projectName)); //$NON-NLS-1$ + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundProject", path.segment(0), projectName)); //$NON-NLS-1$ } if (!prereqProjectRsc.isOpen()){ - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.closedProject", path.segment(0).toString())); //$NON-NLS-1$ + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.closedProject", path.segment(0))); //$NON-NLS-1$ } if (project.getOption(JavaCore.CORE_INCOMPATIBLE_JDK_LEVEL, true) != JavaCore.IGNORE) { long projectTargetJDK = CompilerOptions.versionToJdkLevel(project.getOption(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM, true)); @@ -1135,10 +1146,10 @@ public class ClasspathEntry implements IClasspathEntry { } } } catch (CoreException e){ - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundProject", path.segment(0).toString(), projectName)); //$NON-NLS-1$ + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.unboundProject", path.segment(0), projectName)); //$NON-NLS-1$ } } else { - return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalProjectPath", path.segment(0).toString(), projectName)); //$NON-NLS-1$ + return new JavaModelStatus(IJavaModelStatusConstants.INVALID_CLASSPATH, Util.bind("classpath.illegalProjectPath", path.segment(0), projectName)); //$NON-NLS-1$ } break; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java index 1e13c5e10d..7978e29eb4 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnit.java @@ -1086,9 +1086,8 @@ public org.eclipse.jdt.core.dom.CompilationUnit reconcile( // client asking for level 2 AST; these are supported createAST = true; } else if (astLevel == AST.JLS3) { - // client asking for level 3 ASTs; these are not supported - // TODO (jerome) - these should also be supported in 1.5 stream - createAST = false; + // client asking for level 3 ASTs; these are supported + createAST = true; } else { // client asking for no AST (0) or unknown ast level // either way, request denied diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java index a61d3873ee..8d25a89218 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java @@ -226,9 +226,11 @@ public void enterClass( int nameSourceStart, int nameSourceEnd, char[] superclass, - char[][] superinterfaces) { + char[][] superinterfaces, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { - enterType(declarationStart, modifiers, name, nameSourceStart, nameSourceEnd, superclass, superinterfaces); + enterType(declarationStart, modifiers, name, nameSourceStart, nameSourceEnd, superclass, superinterfaces, typeParameterNames, typeParameterBounds); } /** @@ -251,10 +253,12 @@ public void enterConstructor( int nameSourceEnd, char[][] parameterTypes, char[][] parameterNames, - char[][] exceptionTypes) { + char[][] exceptionTypes, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { enterMethod(declarationStart, modifiers, null, name, nameSourceStart, - nameSourceEnd, parameterTypes, parameterNames, exceptionTypes, true); + nameSourceEnd, parameterTypes, parameterNames, exceptionTypes, true, typeParameterNames, typeParameterBounds); } /** * @see ISourceElementRequestor @@ -330,9 +334,11 @@ public void enterInterface( char[] name, int nameSourceStart, int nameSourceEnd, - char[][] superinterfaces) { + char[][] superinterfaces, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { - enterType(declarationStart, modifiers, name, nameSourceStart, nameSourceEnd, null, superinterfaces); + enterType(declarationStart, modifiers, name, nameSourceStart, nameSourceEnd, null, superinterfaces, typeParameterNames, typeParameterBounds); } /** @@ -347,10 +353,12 @@ public void enterMethod( int nameSourceEnd, char[][] parameterTypes, char[][] parameterNames, - char[][] exceptionTypes) { + char[][] exceptionTypes, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { enterMethod(declarationStart, modifiers, returnType, name, nameSourceStart, - nameSourceEnd, parameterTypes, parameterNames, exceptionTypes, false); + nameSourceEnd, parameterTypes, parameterNames, exceptionTypes, false, typeParameterNames, typeParameterBounds); } /** * @see ISourceElementRequestor @@ -365,7 +373,9 @@ protected void enterMethod( char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes, - boolean isConstructor) { + boolean isConstructor, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { SourceTypeElementInfo parentInfo = (SourceTypeElementInfo) this.infoStack.peek(); JavaElement parentHandle= (JavaElement) this.handleStack.peek(); @@ -403,7 +413,9 @@ protected void enterMethod( info.setArgumentTypeNames(parameterTypes); info.setReturnType(returnType == null ? new char[]{'v', 'o','i', 'd'} : returnType); info.setExceptionTypeNames(exceptionTypes); - + info.setTypeParameterNames(typeParameterNames); + info.setTypeParameterBounds(typeParameterBounds); + parentInfo.addChild(handle); this.newElements.put(handle, info); this.infoStack.push(info); @@ -419,7 +431,9 @@ protected void enterType( int nameSourceStart, int nameSourceEnd, char[] superclass, - char[][] superinterfaces) { + char[][] superinterfaces, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { JavaElementInfo parentInfo = (JavaElementInfo) this.infoStack.peek(); JavaElement parentHandle= (JavaElement) this.handleStack.peek(); @@ -454,6 +468,8 @@ protected void enterType( info.setSuperInterfaceNames(superinterfaces); info.setSourceFileName(this.sourceFileName); info.setPackageName(this.packageName); + info.setTypeParameterNames(typeParameterNames); + info.setTypeParameterBounds(typeParameterBounds); parentInfo.addChild(handle); this.newElements.put(handle, info); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompletionRequestorWrapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompletionRequestorWrapper.java index c58726ec4c..496ee7fca9 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompletionRequestorWrapper.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompletionRequestorWrapper.java @@ -230,8 +230,9 @@ public void acceptMethodDeclaration(char[] declaringTypePackageName, char[] decl completion.append(CharOperation.subarray(completionName, start, completionName.length)); } } - - completionName = completion.toString().toCharArray(); + int nameLength = completion.length(); + completionName = new char[nameLength]; + completion.getChars(0, nameLength, completionName, 0); } if(CompletionEngine.DEBUG) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java index 6d228584c8..fd2c0b2375 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java @@ -31,7 +31,6 @@ import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.core.runtime.Preferences; import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.ElementChangedEvent; import org.eclipse.jdt.core.IClasspathEntry; @@ -921,6 +920,8 @@ public class DeltaProcessor { } this.removeFromParentInfo(javaProject); + // remove preferences from per project info + this.manager.resetProjectPreferences(javaProject); } catch (JavaModelException e) { // java project doesn't exist: ignore } @@ -1731,65 +1732,7 @@ public class DeltaProcessor { } } } - /* - * Update the JavaModel according to a .jprefs file change. The file can have changed as a result of a previous - * call to JavaProject#setOptions or as a result of some user update (through repository) - * Unused until preference file get shared (.jpref) - */ - void reconcilePreferenceFileUpdate(IResourceDelta delta, IFile file, JavaProject project) { - - switch (delta.getKind()) { - case IResourceDelta.REMOVED : // flush project custom settings - project.setOptions(null); - return; - case IResourceDelta.CHANGED : - if ((delta.getFlags() & IResourceDelta.CONTENT) == 0 // only consider content change - && (delta.getFlags() & IResourceDelta.MOVED_FROM) == 0) // and also move and overide scenario - break; - identityCheck : { // check if any actual difference - // force to (re)read the property file - Preferences filePreferences = project.loadPreferences(); - if (filePreferences == null){ - project.setOptions(null); // should have got removed delta. - return; - } - Preferences projectPreferences = project.getPreferences(); - if (projectPreferences == null) return; // not a Java project - - // compare preferences set to their default - String[] defaultProjectPropertyNames = projectPreferences.defaultPropertyNames(); - String[] defaultFilePropertyNames = filePreferences.defaultPropertyNames(); - if (defaultProjectPropertyNames.length == defaultFilePropertyNames.length) { - for (int i = 0; i < defaultProjectPropertyNames.length; i++){ - String propertyName = defaultProjectPropertyNames[i]; - if (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){ - break identityCheck; - } - } - } else break identityCheck; - // compare custom preferences not set to their default - String[] projectPropertyNames = projectPreferences.propertyNames(); - String[] filePropertyNames = filePreferences.propertyNames(); - if (projectPropertyNames.length == filePropertyNames.length) { - for (int i = 0; i < projectPropertyNames.length; i++){ - String propertyName = projectPropertyNames[i]; - if (!projectPreferences.getString(propertyName).trim().equals(filePreferences.getString(propertyName).trim())){ - break identityCheck; - } - } - } else break identityCheck; - - // identical - do nothing - return; - } - case IResourceDelta.ADDED : - // not identical, create delta and reset cached preferences - project.setPreferences(null); - // create delta - //fCurrentDelta.changed(project, IJavaElementDelta.F_OPTIONS_CHANGED); - } - } /* * Traverse the set of projects which have changed namespace, and reset their * caches and their dependents diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java index f2a9e325e9..0f9d68c22d 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaElementDeltaBuilder.java @@ -216,9 +216,10 @@ private void findContentChange(JavaElementInfo oldInfo, JavaElementInfo newInfo, if (((MemberElementInfo)oldInfo).getModifiers() != ((MemberElementInfo)newInfo).getModifiers()) { this.delta.changed(newElement, IJavaElementDelta.F_MODIFIERS); } else if (oldInfo instanceof SourceMethodElementInfo && newInfo instanceof SourceMethodElementInfo) { - if (!CharOperation.equals( - ((SourceMethodElementInfo)oldInfo).getReturnTypeName(), - ((SourceMethodElementInfo)newInfo).getReturnTypeName())) { + SourceMethodElementInfo oldSourceMethodInfo = (SourceMethodElementInfo)oldInfo; + SourceMethodElementInfo newSourceMethodInfo = (SourceMethodElementInfo)newInfo; + if (!CharOperation.equals(oldSourceMethodInfo.getReturnTypeName(), newSourceMethodInfo.getReturnTypeName()) + || !CharOperation.equals(oldSourceMethodInfo.getTypeParameterSignatures(), newSourceMethodInfo.getTypeParameterSignatures())) { this.delta.changed(newElement, IJavaElementDelta.F_CONTENT); } } else if (oldInfo instanceof SourceFieldElementInfo && newInfo instanceof SourceFieldElementInfo) { @@ -233,9 +234,12 @@ private void findContentChange(JavaElementInfo oldInfo, JavaElementInfo newInfo, SourceTypeElementInfo oldSourceTypeInfo = (SourceTypeElementInfo)oldInfo; SourceTypeElementInfo newSourceTypeInfo = (SourceTypeElementInfo)newInfo; if (!CharOperation.equals(oldSourceTypeInfo.getSuperclassName(), newSourceTypeInfo.getSuperclassName()) - || !CharOperation.equals(oldSourceTypeInfo.getInterfaceNames(), newSourceTypeInfo.getInterfaceNames())) { + || !CharOperation.equals(oldSourceTypeInfo.getInterfaceNames(), newSourceTypeInfo.getInterfaceNames())) { this.delta.changed(newElement, IJavaElementDelta.F_SUPER_TYPES); } + if (!CharOperation.equals(oldSourceTypeInfo.getTypeParameterSignatures(), newSourceTypeInfo.getTypeParameterSignatures())) { + this.delta.changed(newElement, IJavaElementDelta.F_CONTENT); + } } } /** diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java index 5b7f53f2e9..f933f986f7 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaModelManager.java @@ -21,6 +21,7 @@ import javax.xml.parsers.ParserConfigurationException; import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.jdt.core.*; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.core.search.SearchEngine; @@ -33,6 +34,7 @@ import org.eclipse.jdt.internal.core.search.AbstractSearchScope; import org.eclipse.jdt.internal.core.search.indexing.IndexManager; import org.eclipse.jdt.internal.core.search.processing.JobManager; import org.eclipse.jdt.internal.core.util.Util; +import org.osgi.service.prefs.BackingStoreException; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -536,7 +538,7 @@ public class JavaModelManager implements ISaveParticipant { public IClasspathEntry[] resolvedClasspath; public Map resolvedPathToRawEntries; // reverse map from resolved path to raw entries public IPath outputLocation; - public Preferences preferences; + public IEclipsePreferences preferences; public PerProjectInfo(IProject project) { @@ -616,7 +618,7 @@ public class JavaModelManager implements ISaveParticipant { public String toString() { StringBuffer buffer = new StringBuffer(); buffer.append("Info for "); //$NON-NLS-1$ - buffer.append(((JavaElement)workingCopy).toStringWithAncestors()); + buffer.append(((JavaElement)this.workingCopy).toStringWithAncestors()); buffer.append("\nUse count = "); //$NON-NLS-1$ buffer.append(this.useCount); buffer.append("\nProblem requestor:\n "); //$NON-NLS-1$ @@ -639,13 +641,12 @@ public class JavaModelManager implements ISaveParticipant { /** * Update the classpath variable cache */ - public static class PluginPreferencesListener implements Preferences.IPropertyChangeListener { + public static class EclipsePreferencesListener implements IEclipsePreferences.IPreferenceChangeListener { /** - * @see org.eclipse.core.runtime.Preferences.IPropertyChangeListener#propertyChange(Preferences.PropertyChangeEvent) + * @see org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener#preferenceChange(org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent) */ - public void propertyChange(Preferences.PropertyChangeEvent event) { - - String propertyName = event.getProperty(); + public void preferenceChange(IEclipsePreferences.PreferenceChangeEvent event) { + String propertyName = event.getKey(); if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)) { String varName = propertyName.substring(CP_VARIABLE_PREFERENCES_PREFIX.length()); String newValue = (String)event.getNewValue(); @@ -759,7 +760,7 @@ public class JavaModelManager implements ISaveParticipant { deltaBuilder = new JavaElementDeltaBuilder(workingCopy); } PerWorkingCopyInfo info = null; - synchronized(perWorkingCopyInfos) { + synchronized(this.perWorkingCopyInfos) { WorkingCopyOwner owner = workingCopy.owner; Map workingCopyToInfos = (Map)this.perWorkingCopyInfos.get(owner); if (workingCopyToInfos == null) return -1; @@ -870,7 +871,7 @@ public class JavaModelManager implements ISaveParticipant { * Returns the handle to the active Java Model. */ public final JavaModel getJavaModel() { - return javaModel; + return this.javaModel; } /** @@ -906,11 +907,11 @@ public class JavaModelManager implements ISaveParticipant { * Returns the per-project info for the given project. If specified, create the info if the info doesn't exist. */ public PerProjectInfo getPerProjectInfo(IProject project, boolean create) { - synchronized(perProjectInfos) { // use the perProjectInfo collection as its own lock - PerProjectInfo info= (PerProjectInfo) perProjectInfos.get(project); + synchronized(this.perProjectInfos) { // use the perProjectInfo collection as its own lock + PerProjectInfo info= (PerProjectInfo) this.perProjectInfos.get(project); if (info == null && create) { info= new PerProjectInfo(project); - perProjectInfos.put(project, info); + this.perProjectInfos.put(project, info); } return info; } @@ -939,7 +940,7 @@ public class JavaModelManager implements ISaveParticipant { * Returns null if it doesn't exist and not create. */ public PerWorkingCopyInfo getPerWorkingCopyInfo(CompilationUnit workingCopy,boolean create, boolean recordUsage, IProblemRequestor problemRequestor) { - synchronized(perWorkingCopyInfos) { // use the perWorkingCopyInfo collection as its own lock + synchronized(this.perWorkingCopyInfos) { // use the perWorkingCopyInfo collection as its own lock WorkingCopyOwner owner = workingCopy.owner; Map workingCopyToInfos = (Map)this.perWorkingCopyInfos.get(owner); if (workingCopyToInfos == null && create) { @@ -1089,11 +1090,11 @@ public class JavaModelManager implements ISaveParticipant { * Returns null if it has none. */ public ICompilationUnit[] getWorkingCopies(WorkingCopyOwner owner, boolean addPrimary) { - synchronized(perWorkingCopyInfos) { + synchronized(this.perWorkingCopyInfos) { ICompilationUnit[] primaryWCs = addPrimary && owner != DefaultWorkingCopyOwner.PRIMARY ? getWorkingCopies(DefaultWorkingCopyOwner.PRIMARY, false) : null; - Map workingCopyToInfos = (Map)perWorkingCopyInfos.get(owner); + Map workingCopyToInfos = (Map)this.perWorkingCopyInfos.get(owner); if (workingCopyToInfos == null) return primaryWCs; int primaryLength = primaryWCs == null ? 0 : primaryWCs.length; int size = workingCopyToInfos.size(); // note size is > 0 otherwise pathToPerWorkingCopyInfos would be null @@ -1402,23 +1403,31 @@ public class JavaModelManager implements ISaveParticipant { } // load variables and containers from preferences into cache - Preferences preferences = JavaCore.getPlugin().getPluginPreferences(); + IEclipsePreferences preferences = JavaCore.getInstancePreferences(); // only get variable from preferences not set to their default - String[] propertyNames = preferences.propertyNames(); - int variablePrefixLength = CP_VARIABLE_PREFERENCES_PREFIX.length(); - for (int i = 0; i < propertyNames.length; i++){ - String propertyName = propertyNames[i]; - if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)){ - String varName = propertyName.substring(variablePrefixLength); - IPath varPath = new Path(preferences.getString(propertyName).trim()); - - this.variables.put(varName, varPath); - this.previousSessionVariables.put(varName, varPath); - } - if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)){ - recreatePersistedContainer(propertyName, preferences.getString(propertyName), true/*add to container values*/); + try { + String[] propertyNames = preferences.keys(); + int variablePrefixLength = CP_VARIABLE_PREFERENCES_PREFIX.length(); + for (int i = 0; i < propertyNames.length; i++){ + String propertyName = propertyNames[i]; + if (propertyName.startsWith(CP_VARIABLE_PREFERENCES_PREFIX)){ + String varName = propertyName.substring(variablePrefixLength); + String propertyValue = preferences.get(propertyName, null); + if (propertyValue != null) { + IPath varPath = new Path(propertyValue.trim()); + this.variables.put(varName, varPath); + this.previousSessionVariables.put(varName, varPath); + } + } + if (propertyName.startsWith(CP_CONTAINER_PREFERENCES_PREFIX)){ + String propertyValue = preferences.get(propertyName, null); + if (propertyValue != null) + recreatePersistedContainer(propertyName, propertyValue, true/*add to container values*/); + } } + } catch (BackingStoreException e1) { + // TODO (frederic) see if it's necessary to report this failure... } // override persisted values for variables which have a registered initializer String[] registeredVariables = getRegisteredVariableNames(); @@ -1603,11 +1612,24 @@ public class JavaModelManager implements ISaveParticipant { } public void removePerProjectInfo(JavaProject javaProject) { - synchronized(perProjectInfos) { // use the perProjectInfo collection as its own lock + synchronized(this.perProjectInfos) { // use the perProjectInfo collection as its own lock + IProject project = javaProject.getProject(); + PerProjectInfo info= (PerProjectInfo) this.perProjectInfos.get(project); + if (info != null) { + this.perProjectInfos.remove(project); + } + } + } + + /* + * Reset project preferences stored in info cache. + */ + public void resetProjectPreferences(JavaProject javaProject) { + synchronized(this.perProjectInfos) { // use the perProjectInfo collection as its own lock IProject project = javaProject.getProject(); - PerProjectInfo info= (PerProjectInfo) perProjectInfos.get(project); + PerProjectInfo info= (PerProjectInfo) this.perProjectInfos.get(project); if (info != null) { - perProjectInfos.remove(project); + info.preferences = null; } } } @@ -1689,7 +1711,6 @@ public class JavaModelManager implements ISaveParticipant { public void saving(ISaveContext context) throws CoreException { // save container values on snapshot/full save - Preferences preferences = JavaCore.getPlugin().getPluginPreferences(); IJavaProject[] projects = getJavaModel().getJavaProjects(); for (int i = 0, length = projects.length; i < length; i++) { IJavaProject project = projects[i]; @@ -1708,11 +1729,17 @@ public class JavaModelManager implements ISaveParticipant { } catch(JavaModelException e){ // could not encode entry: leave it as CP_ENTRY_IGNORE } - preferences.setDefault(containerKey, CP_ENTRY_IGNORE); // use this default to get rid of removed ones - preferences.setValue(containerKey, containerString); + JavaCore.getDefaultPreferences().put(containerKey, CP_ENTRY_IGNORE); // TODO (frederic) verify if this is really necessary... + JavaCore.getInstancePreferences().put(containerKey, containerString); } } - JavaCore.getPlugin().savePluginPreferences(); + try { + JavaCore.getInstancePreferences().flush(); + } catch (BackingStoreException e) { + // TODO (frederic) see if it's necessary to report this exception + // IStatus status = new Status(IStatus.ERROR, JavaCore.PLUGIN_ID, IStatus.ERROR, "Problems while saving context", e); //$NON-NLS-1$ + // throw new CoreException(status); + } if (context.getKind() == ISaveContext.FULL_SAVE) { // will need delta since this save (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=38658) @@ -1735,7 +1762,7 @@ public class JavaModelManager implements ISaveParticipant { } ArrayList vStats= null; // lazy initialized - for (Iterator iter = perProjectInfos.values().iterator(); iter.hasNext();) { + for (Iterator iter = this.perProjectInfos.values().iterator(); iter.hasNext();) { try { PerProjectInfo info = (PerProjectInfo) iter.next(); saveState(info, context); @@ -2044,11 +2071,16 @@ public class JavaModelManager implements ISaveParticipant { this.previousSessionVariables.remove(variableName); } - Preferences preferences = JavaCore.getPlugin().getPluginPreferences(); String variableKey = CP_VARIABLE_PREFERENCES_PREFIX+variableName; String variableString = variablePath == null ? CP_ENTRY_IGNORE : variablePath.toString(); - preferences.setDefault(variableKey, CP_ENTRY_IGNORE); // use this default to get rid of removed ones - preferences.setValue(variableKey, variableString); - JavaCore.getPlugin().savePluginPreferences(); + JavaCore.getDefaultPreferences().put(variableKey, CP_ENTRY_IGNORE); // TODO (frederic) verify if this is really necessary... + JavaCore.getInstancePreferences().put(variableKey, variableString); + try { + JavaCore.getInstancePreferences().flush(); + } catch (BackingStoreException e) { + // TODO (frederic) see if it's necessary to report this exception +// IStatus status = new Status(IStatus.ERROR, Platform.PI_RUNTIME, IStatus.ERROR, "Problems while saving context", e); //$NON-NLS-1$ +// throw new CoreException(status); + } } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java index 8cd77f4e66..5d8fa0ca40 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/JavaProject.java @@ -11,15 +11,12 @@ package org.eclipse.jdt.internal.core; import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.StringReader; import java.util.ArrayList; @@ -28,11 +25,9 @@ import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; import java.util.Map; - import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; - import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; @@ -43,13 +38,18 @@ import org.eclipse.core.resources.IProjectNature; import org.eclipse.core.resources.IResource; import org.eclipse.core.resources.IWorkspace; import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.QualifiedName; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; +import org.eclipse.core.runtime.preferences.IPreferencesService; +import org.eclipse.core.runtime.preferences.IScopeContext; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.ICompilationUnit; @@ -74,6 +74,7 @@ import org.eclipse.jdt.internal.core.eval.EvaluationContextWrapper; import org.eclipse.jdt.internal.core.util.MementoTokenizer; import org.eclipse.jdt.internal.core.util.Util; import org.eclipse.jdt.internal.eval.EvaluationContext; +import org.osgi.service.prefs.BackingStoreException; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -124,6 +125,10 @@ public class JavaProject /** * Name of file containing custom project preferences + * @deprecated WARNING Visibility will be reduce to private before M9 + * If you use this variable, change your implementation to avoid future comilation error... + * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=59258">bug 59258</a> + * TODO (frederic) set visibility from public to private */ public static final String PREF_FILENAME = ".jprefs"; //$NON-NLS-1$ @@ -131,8 +136,6 @@ public class JavaProject * Value of the project's raw classpath if the .classpath file contains invalid entries. */ public static final IClasspathEntry[] INVALID_CLASSPATH = new IClasspathEntry[0]; - - private static final String CUSTOM_DEFAULT_OPTION_VALUE = "#\r\n\r#custom-non-empty-default-value#\r\n\r#"; //$NON-NLS-1$ /* * Value of project's resolved classpath while it is being resolved @@ -1407,11 +1410,11 @@ public class JavaProject String propertyName = optionName; if (JavaModelManager.getJavaModelManager().optionNames.contains(propertyName)){ - Preferences preferences = getPreferences(); - if (preferences == null || preferences.isDefault(propertyName)) { - return inheritJavaCoreOptions ? JavaCore.getOption(propertyName) : null; - } - return preferences.getString(propertyName).trim(); + IEclipsePreferences preferences = getEclipsePreferences(); + String javaCoreDefault = inheritJavaCoreOptions ? JavaCore.getOption(propertyName) : null; + if (preferences == null) return javaCoreDefault; + String value = preferences.get(propertyName, javaCoreDefault); + return value == null ? null : value.trim(); } return null; } @@ -1424,21 +1427,25 @@ public class JavaProject // initialize to the defaults from JavaCore options pool Map options = inheritJavaCoreOptions ? JavaCore.getOptions() : new Hashtable(5); - Preferences preferences = getPreferences(); + IEclipsePreferences preferences = getEclipsePreferences(); if (preferences == null) return options; // cannot do better (non-Java project) HashSet optionNames = JavaModelManager.getJavaModelManager().optionNames; // project cannot hold custom preferences set to their default, as it uses CUSTOM_DEFAULT_OPTION_VALUE // get custom preferences not set to their default - String[] propertyNames = preferences.propertyNames(); - for (int i = 0; i < propertyNames.length; i++){ - String propertyName = propertyNames[i]; - String value = preferences.getString(propertyName).trim(); - if (optionNames.contains(propertyName)){ - options.put(propertyName, value); - } - } + try { + String[] propertyNames = preferences.keys(); + for (int i = 0; i < propertyNames.length; i++){ + String propertyName = propertyNames[i]; + String value = preferences.get(propertyName, null); + if (value != null && optionNames.contains(propertyName)){ + options.put(propertyName, value.trim()); + } + } + } catch (BackingStoreException e) { + // nothing to do + } return options; } @@ -1647,7 +1654,7 @@ public class JavaProject public JavaModelManager.PerProjectInfo getPerProjectInfo() throws JavaModelException { return JavaModelManager.getJavaModelManager().getPerProjectInfoCheckExistence(this.project); } - + /** * @see IJavaProject#getProject() */ @@ -1658,9 +1665,32 @@ public class JavaProject /** * Returns the project custom preference pool. * Project preferences may include custom encoding. - * @return Preferences + * @return IEclipsePreferences */ + public IEclipsePreferences getEclipsePreferences(){ + if (!JavaProject.hasJavaNature(this.project)) return null; + JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(this.project, true); + IEclipsePreferences eclipsePreferences = perProjectInfo.preferences; + if (eclipsePreferences != null) return eclipsePreferences; + IScopeContext context = new ProjectScope(getProject()); + eclipsePreferences = context.getNode(JavaCore.PLUGIN_ID); + updatePreferences(eclipsePreferences); + perProjectInfo.preferences = eclipsePreferences; + return eclipsePreferences; + } + + /** + * Returns the project custom preference pool. + * Project preferences may include custom encoding. + * @return Preferences + * @deprecated WARNING: this method do nothing from now and will be removed soon! + * If you use it, switch as soon as possible to new preferences API by using + * {@link #getEclipsePreferences()} to avoid future compilation error... + * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=59258">bug 59258</a> + * TODO (frederic) remove for 3.1... + */ public Preferences getPreferences(){ + /* if (!JavaProject.hasJavaNature(this.project)) return null; JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(this.project, true); Preferences preferences = perProjectInfo.preferences; @@ -1669,6 +1699,8 @@ public class JavaProject if (preferences == null) preferences = new Preferences(); perProjectInfo.preferences = preferences; return preferences; + */ + return new Preferences(); } /** @@ -2150,14 +2182,42 @@ public class JavaProject } /* + * Update eclipse preferences from old preferences. + */ + private void updatePreferences(IEclipsePreferences preferences) { + + Preferences oldPreferences = loadPreferences(); + IPreferencesService service = Platform.getPreferencesService(); + if (oldPreferences != null) { + String[] propertyNames = oldPreferences.propertyNames(); + for (int i = 0; i < propertyNames.length; i++){ + String propertyName = propertyNames[i]; + String propertyValue = oldPreferences.getString(propertyName); + String defaultValue = service.get(propertyName, null, JavaCore.preferencesLookup); + if (!"".equals(propertyValue) && (defaultValue == null || !propertyValue.equals(defaultValue))) { //$NON-NLS-1$ + preferences.put(propertyName, propertyValue); + } + } + try { + // save immediately old preferences + preferences.flush(); + } catch (BackingStoreException e) { + // fails silently + } + } + } + + /** * load preferences from a shareable format (VCM-wise) + * @deprecated WARNING, visibility of this method will be decreased soon + * to private and won't be usable in the future. + * @see <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=59258">bug 59258</a> + * TODO (frederic) set visibility from public to private */ public Preferences loadPreferences() { Preferences preferences = new Preferences(); - -// File prefFile = this.project.getLocation().append(PREF_FILENAME).toFile(); - IPath projectMetaLocation = getPluginWorkingLocation(); + IPath projectMetaLocation = getPluginWorkingLocation(); if (projectMetaLocation != null) { File prefFile = projectMetaLocation.append(PREF_FILENAME).toFile(); if (prefFile.exists()) { // load preferences from file @@ -2165,7 +2225,6 @@ public class JavaProject try { in = new BufferedInputStream(new FileInputStream(prefFile)); preferences.load(in); - return preferences; } catch (IOException e) { // problems loading preference store - quietly ignore } finally { if (in != null) { @@ -2175,11 +2234,14 @@ public class JavaProject } } } + // one shot read, delete old preferences + prefFile.delete(); + return preferences; } } return null; } - + /** * @see IJavaProject#newEvaluationContext() */ @@ -2448,49 +2510,6 @@ public class JavaProject throw new JavaModelException(e); } } - /** - * Save project custom preferences to shareable file (.jprefs) - */ - private void savePreferences(Preferences preferences) { - - if (!JavaProject.hasJavaNature(this.project)) return; // ignore - - if (preferences == null || (!preferences.needsSaving() && preferences.propertyNames().length != 0)) { - // nothing to save - return; - } - - // preferences need to be saved - // the preferences file is located in the plug-in's state area - // at a well-known name (.jprefs) -// File prefFile = this.project.getLocation().append(PREF_FILENAME).toFile(); - File prefFile = getPluginWorkingLocation().append(PREF_FILENAME).toFile(); - if (preferences.propertyNames().length == 0) { - // there are no preference settings - // rather than write an empty file, just delete any existing file - if (prefFile.exists()) { - prefFile.delete(); // don't worry if delete unsuccessful - } - return; - } - - // write file, overwriting an existing one - OutputStream out = null; - try { - // do it as carefully as we know how so that we don't lose/mangle - // the setting in times of stress - out = new BufferedOutputStream(new FileOutputStream(prefFile)); - preferences.store(out, null); - } catch (IOException e) { // problems saving preference store - quietly ignore - } finally { - if (out != null) { - try { - out.close(); - } catch (IOException e) { // ignore problems with close - } - } - } - } /** * Update the Java command in the build spec (replace existing one if present, @@ -2525,10 +2544,16 @@ public class JavaProject */ public void setOption(String optionName, String optionValue) { if (!JavaModelManager.getJavaModelManager().optionNames.contains(optionName)) return; // unrecognized option - Preferences preferences = getPreferences(); - preferences.setDefault(optionName, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251) - preferences.setValue(optionName, optionValue); - savePreferences(preferences); + IEclipsePreferences projectPreferences = getEclipsePreferences(); + String defaultValue = JavaCore.getOption(optionName); + if (defaultValue == null || !defaultValue.equals(optionValue)) { + projectPreferences.put(optionName, optionValue); + try { + projectPreferences.flush(); + } catch (BackingStoreException e) { + // problem with pref store - quietly ignore + } + } } /** @@ -2536,33 +2561,42 @@ public class JavaProject */ public void setOptions(Map newOptions) { - Preferences preferences = getPreferences(); - if (newOptions != null){ - Iterator keys = newOptions.keySet().iterator(); - while (keys.hasNext()){ - String key = (String)keys.next(); - if (!JavaModelManager.getJavaModelManager().optionNames.contains(key)) continue; // unrecognized option - // no filtering for encoding (custom encoding for project is allowed) - String value = (String)newOptions.get(key); - preferences.setDefault(key, CUSTOM_DEFAULT_OPTION_VALUE); // empty string isn't the default (26251) - preferences.setValue(key, value); + IEclipsePreferences projectPreferences = getEclipsePreferences(); + try { + if (newOptions == null){ + projectPreferences.clear(); + } else { + Iterator keys = newOptions.keySet().iterator(); + while (keys.hasNext()){ + String key = (String)keys.next(); + if (!JavaModelManager.getJavaModelManager().optionNames.contains(key)) continue; // unrecognized option + // no filtering for encoding (custom encoding for project is allowed) + String value = (String)newOptions.get(key); + projectPreferences.put(key, value); + } + + // reset to default all options not in new map + // @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=26255 + // @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49691 + String[] pNames = projectPreferences.keys(); + int ln = pNames.length; + for (int i=0; i<ln; i++) { + String key = pNames[i]; + if (!newOptions.containsKey(key)) { + projectPreferences.remove(key); // old preferences => remove from preferences table + } + } } - } - - // reset to default all options not in new map - // @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=26255 - // @see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49691 - String[] pNames = preferences.propertyNames(); - int ln = pNames.length; - for (int i=0; i<ln; i++) { - String key = pNames[i]; - if (newOptions == null || !newOptions.containsKey(key)) { - preferences.setToDefault(key); // set default => remove from preferences table + + // persist options + projectPreferences.flush(); + if (newOptions == null) { + // Uncache preferences + JavaModelManager.getJavaModelManager().resetProjectPreferences(this); } + } catch (BackingStoreException e) { + // problem with pref store - quietly ignore } - - // persist options - savePreferences(preferences); } /** @@ -2580,15 +2614,6 @@ public class JavaProject this.setRawClasspath(SetClasspathOperation.ReuseClasspath, path, monitor); } - /* - * Set cached preferences, no preference file is saved, only info is updated - */ - public void setPreferences(Preferences preferences) { - if (!JavaProject.hasJavaNature(this.project)) return; // ignore - JavaModelManager.PerProjectInfo perProjectInfo = JavaModelManager.getJavaModelManager().getPerProjectInfo(this.project, true); - perProjectInfo.preferences = preferences; - } - /** * Sets the underlying kernel project of this Java project, * and fills in its parent and name. diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java index 388336f28d..3e482eabce 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Member.java @@ -32,6 +32,11 @@ import org.eclipse.jdt.internal.core.util.MementoTokenizer; */ public abstract class Member extends SourceRefElement implements IMember { + /** + * An empty list of Strings + */ + protected static final String[] EmptyStringList = new String[0]; + protected Member(JavaElement parent, String name) { super(parent, name); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java index 93a3d5f810..70d045cd1b 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SelectionRequestor.java @@ -410,6 +410,35 @@ protected void acceptType(char[] packageName, char[] typeName, int acceptFlags, } } } +public void acceptTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] typeParameterName, boolean isDeclaration, int start, int end) { + // TODO missing implementation + + if(SelectionEngine.DEBUG){ + System.out.print("SELECTION - acceptTypeParameter("); //$NON-NLS-1$ + System.out.print(declaringTypePackageName); + System.out.print('.'); + System.out.print(declaringTypeName); + System.out.print('<'); + System.out.print(typeParameterName); + System.out.println(">)"); //$NON-NLS-1$ + } +} +public void acceptMethodTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor, char[] typeParameterName, boolean isDeclaration, int start, int end) { + // TODO missing implementation + + if(SelectionEngine.DEBUG){ + System.out.print("SELECTION - acceptTypeParameter("); //$NON-NLS-1$ + System.out.print(declaringTypePackageName); + System.out.print('.'); + System.out.print(declaringTypeName); + System.out.print('.'); + System.out.print('<'); + System.out.print(typeParameterName); + System.out.print('>'); + System.out.print(selector); + System.out.println("(...))"); //$NON-NLS-1$ + } +} /* * Adds the given element to the list of resolved elements. */ diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementBuilder.java index ae7c5cc42e..132f7ffcf6 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementBuilder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SortElementBuilder.java @@ -1008,7 +1008,9 @@ public class SortElementBuilder extends SourceElementRequestorAdapter { int nameSourceStart, int nameSourceEnd, char[] superclass, - char[][] superinterfaces) { + char[][] superinterfaces, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { SortType type = new SortClassDeclaration(declarationStart, modifiers, name, superclass, superinterfaces); this.currentElement.addChild(type); push(type); @@ -1033,7 +1035,9 @@ public class SortElementBuilder extends SourceElementRequestorAdapter { int nameSourceEnd, char[][] parameterTypes, char[][] parameterNames, - char[][] exceptionTypes) { + char[][] exceptionTypes, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { if ((this.currentElement.id & SortJavaElement.TYPE) != 0) { SortConstructorDeclaration constructorDeclaration = new SortConstructorDeclaration(declarationStart, modifiers, name, parameterNames, parameterTypes, exceptionTypes); this.currentElement.addChild(constructorDeclaration); @@ -1092,7 +1096,9 @@ public class SortElementBuilder extends SourceElementRequestorAdapter { char[] name, int nameSourceStart, int nameSourceEnd, - char[][] superinterfaces) { + char[][] superinterfaces, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { SortType type = new SortInterfaceDeclaration(declarationStart, modifiers, name, superinterfaces); this.currentElement.addChild(type); push(type); @@ -1110,7 +1116,9 @@ public class SortElementBuilder extends SourceElementRequestorAdapter { int nameSourceEnd, char[][] parameterTypes, char[][] parameterNames, - char[][] exceptionTypes) { + char[][] exceptionTypes, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { if ((this.currentElement.id & SortJavaElement.TYPE) != 0) { SortMethodDeclaration methodDeclaration = new SortMethodDeclaration(declarationStart, modifiers, name, parameterNames, parameterTypes, exceptionTypes, returnType); this.currentElement.addChild(methodDeclaration); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java index d969ade44d..08c9c36ecc 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java @@ -504,7 +504,9 @@ public class SourceMapper int nameSourceStart, int nameSourceEnd, char[] superclass, - char[][] superinterfaces) { + char[][] superinterfaces, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { this.typeDepth++; if (this.typeDepth == this.types.length) { // need to grow @@ -590,7 +592,9 @@ public class SourceMapper int nameSourceEnd, char[][] parameterTypes, char[][] parameterNames, - char[][] exceptionTypes) { + char[][] exceptionTypes, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { enterMethod( declarationStart, modifiers, @@ -600,7 +604,9 @@ public class SourceMapper nameSourceEnd, parameterTypes, parameterNames, - exceptionTypes); + exceptionTypes, + typeParameterNames, + typeParameterBounds); } /** @@ -639,7 +645,9 @@ public class SourceMapper char[] name, int nameSourceStart, int nameSourceEnd, - char[][] superinterfaces) { + char[][] superinterfaces, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { enterClass( declarationStart, modifiers, @@ -647,7 +655,9 @@ public class SourceMapper nameSourceStart, nameSourceEnd, null, - superinterfaces); + superinterfaces, + typeParameterNames, + typeParameterBounds); } /** @@ -662,7 +672,9 @@ public class SourceMapper int nameSourceEnd, char[][] parameterTypes, char[][] parameterNames, - char[][] exceptionTypes) { + char[][] exceptionTypes, + char[][] typeParameterNames, + char[][][] typeParameterBounds) { if (typeDepth >= 0) { fMemberName[typeDepth] = new String(name); fMemberNameRange[typeDepth] = @@ -1029,16 +1041,36 @@ public class SourceMapper unqualifiedName.append(Signature.C_ARRAY); ++count; } - if (qualifiedName.charAt(count) == Signature.C_RESOLVED) { + char currentChar = qualifiedName.charAt(count); + if (currentChar == Signature.C_RESOLVED || currentChar == Signature.C_TYPE_VARIABLE) { unqualifiedName.append(Signature.C_UNRESOLVED); String simpleName = Signature.getSimpleName(qualifiedName.substring(count+1)); - if(!noDollar) { - if(!hasDollar && simpleName.indexOf('$') != -1) { - hasDollar = true; + int lastDollar = simpleName.lastIndexOf('$'); + hasDollar |= lastDollar != -1; + int start = noDollar ? lastDollar + 1 : 0; + boolean sigStart = false; + for (int j = start, length = simpleName.length(); j < length; j++) { + char current = simpleName.charAt(j); + switch (current) { + case Signature.C_SUPER: + case Signature.C_EXTENDS: + case Signature.C_GENERIC_START: + case Signature.C_NAME_END: + unqualifiedName.append(current); + sigStart = true; + break; + default: + if (sigStart) { + if (current == Signature.C_TYPE_VARIABLE) { + unqualifiedName.append(Signature.C_UNRESOLVED); + } else { + unqualifiedName.append(current); + } + sigStart = false; + } else { + unqualifiedName.append(current); + } } - unqualifiedName.append(simpleName); - } else { - unqualifiedName.append(CharOperation.lastSegment(simpleName.toCharArray(), '$')); } } else { unqualifiedName.append(qualifiedName.substring(count, qualifiedName.length())); @@ -1235,4 +1267,5 @@ public class SourceMapper } return false; } + } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java index 811d3c406a..f9f7aa87ab 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java @@ -144,8 +144,16 @@ public String[] getParameterTypes() { * @since 3.0 */ public String[] getTypeParameterSignatures() throws JavaModelException { - // TODO (jerome) - missing implementation - return new String[0]; + SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo(); + char[][] signatures = info.getTypeParameterSignatures(); + if (signatures == null) + return EmptyStringList; + int length = signatures.length; + String[] stringSignatures = new String[length]; + for (int i = 0; i < length; i++) { + stringSignatures[i] = new String(signatures[i]); + } + return stringSignatures; } /* diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java index f2fdf3f758..96c1ab0c8e 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java @@ -11,6 +11,7 @@ package org.eclipse.jdt.internal.core; import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.env.ISourceMethod; /** @@ -53,6 +54,14 @@ public class SourceMethodElementInfo extends MemberElementInfo implements ISourc protected char[][] exceptionTypes; /** + * Signatures of type parameters (for generic types) + * + */ + protected char[][] typeParameterNames; + protected char[][][] typeParameterBounds; + protected char[][] typeParameterSignatures; + + /** * Constructor flag. */ protected boolean isConstructor= false; @@ -79,6 +88,34 @@ protected String getSignature() { } return Signature.createMethodSignature(paramSignatures, Signature.createTypeSignature(this.returnType, false)); } +public char[][] getTypeParameterNames() { + return this.typeParameterNames; +} +public char[][][] getTypeParameterBounds() { + return this.typeParameterBounds; +} +public char[][] getTypeParameterSignatures() { + if (this.typeParameterSignatures == null) { + if (this.typeParameterNames != null) { + int length = this.typeParameterNames.length; + this.typeParameterSignatures = new char[length][]; + for (int i = 0; i < length; i++) { + char[][] bounds = this.typeParameterBounds[i]; + if (bounds == null) { + this.typeParameterSignatures[i] = Signature.createTypeParameterSignature(this.typeParameterNames[i], CharOperation.NO_CHAR_CHAR); + } else { + int boundsLength = bounds.length; + char[][] boundSignatures = new char[boundsLength][]; + for (int j = 0; j < boundsLength; j++) { + boundSignatures[i] = Signature.createCharArrayTypeSignature(bounds[j], false); + } + this.typeParameterSignatures[i] = Signature.createTypeParameterSignature(this.typeParameterNames[i], boundSignatures); + } + } + } + } + return this.typeParameterSignatures; +} public boolean isConstructor() { return this.isConstructor; } @@ -97,4 +134,17 @@ protected void setExceptionTypeNames(char[][] types) { protected void setReturnType(char[] type) { this.returnType = type; } +/** + * Sets the names of the type parameters this method declares + */ +protected void setTypeParameterNames(char[][] typeParameterNames) { + this.typeParameterNames = typeParameterNames; +} +/** + * Sets the names of the type parameter bounds this method declares + */ +protected void setTypeParameterBounds(char[][][] typeParameterBounds) { + this.typeParameterBounds = typeParameterBounds; +} + } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java index b5d443f02f..367595dfa6 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceType.java @@ -37,10 +37,7 @@ import org.eclipse.jdt.internal.core.util.Util; */ public class SourceType extends Member implements IType { - /** - * An empty list of Strings - */ - protected static final String[] fgEmptyList= new String[] {}; + protected SourceType(JavaElement parent, String name) { super(parent, name); Assert.isTrue(name.indexOf('.') == -1, Util.bind("sourcetype.invalidName", name)); //$NON-NLS-1$ @@ -378,7 +375,7 @@ public String[] getSuperInterfaceNames() throws JavaModelException { SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo(); char[][] names= info.getInterfaceNames(); if (names == null) { - return fgEmptyList; + return EmptyStringList; } String[] strings= new String[names.length]; for (int i= 0; i < names.length; i++) { @@ -395,7 +392,7 @@ public String[] getSuperInterfaceTypeSignatures() throws JavaModelException { SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo(); char[][] names= info.getInterfaceNames(); if (names == null) { - return fgEmptyList; + return EmptyStringList; } String[] strings= new String[names.length]; for (int i= 0; i < names.length; i++) { @@ -409,8 +406,16 @@ public String[] getSuperInterfaceTypeSignatures() throws JavaModelException { * @since 3.0 */ public String[] getTypeParameterSignatures() throws JavaModelException { - // TODO (jerome) - missing implementation - return new String[0]; + SourceTypeElementInfo info = (SourceTypeElementInfo) getElementInfo(); + char[][] signatures = info.getTypeParameterSignatures(); + if (signatures == null) + return EmptyStringList; + int length = signatures.length; + String[] stringSignatures = new String[length]; + for (int i = 0; i < length; i++) { + stringSignatures[i] = new String(signatures[i]); + } + return stringSignatures; } /** @@ -738,6 +743,12 @@ public String[][] resolveType(String typeName, WorkingCopyOwner owner) throws Ja public void acceptPackage(char[] packageName){ // ignore } + public void acceptTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] typeParameterName, boolean isDeclaration, int start, int end) { + // ignore + } + public void acceptMethodTypeParameter(char[] declaringTypePackageName, char[] declaringTypeName, char[] selector, char[][] parameterPackageNames, char[][] parameterTypeNames, boolean isConstructor, char[] typeParameterName, boolean isDeclaration, int start, int end) { + // ignore + } } TypeResolveRequestor requestor = new TypeResolveRequestor(); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java index 428f07f41f..d0b17e5773 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceTypeElementInfo.java @@ -14,6 +14,8 @@ import org.eclipse.jdt.core.IImportDeclaration; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; +import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.env.IConstants; import org.eclipse.jdt.internal.compiler.env.ISourceField; import org.eclipse.jdt.internal.compiler.env.ISourceImport; @@ -66,6 +68,14 @@ public class SourceTypeElementInfo extends MemberElementInfo implements ISourceT */ protected IType handle = null; + /** + * Signatures of type parameters (for generic types) + * + */ + protected char[][] typeParameterNames; + protected char[][][] typeParameterBounds; + protected char[][] typeParameterSignatures; + /** * Returns the ISourceType that is the enclosing type for this * type, or <code>null</code> if this type is a top level type. @@ -237,6 +247,35 @@ public char[] getSuperclassName() { } return this.superclassName; } +public char[][] getTypeParameterNames() { + return this.typeParameterNames; +} +public char[][][] getTypeParameterBounds() { + return this.typeParameterBounds; +} +public char[][] getTypeParameterSignatures() { + if (this.typeParameterSignatures == null) { + if (this.typeParameterNames != null) { + int length = this.typeParameterNames.length; + this.typeParameterSignatures = new char[length][]; + for (int i = 0; i < length; i++) { + char[][] bounds = this.typeParameterBounds[i]; + if (bounds == null) { + this.typeParameterSignatures[i] = Signature.createTypeParameterSignature(this.typeParameterNames[i], CharOperation.NO_CHAR_CHAR); + } else { + int boundsLength = bounds.length; + char[][] boundSignatures = new char[boundsLength][]; + for (int j = 0; j < boundsLength; j++) { + boundSignatures[i] = Signature.createCharArrayTypeSignature(bounds[j], false); + } + this.typeParameterSignatures[i] = Signature.createTypeParameterSignature(this.typeParameterNames[i], boundSignatures); + } + } + } + } + return this.typeParameterSignatures; +} + /** * @see ISourceType */ @@ -285,6 +324,18 @@ protected void setSuperclassName(char[] superclassName) { protected void setSuperInterfaceNames(char[][] superInterfaceNames) { this.superInterfaceNames = superInterfaceNames; } +/** + * Sets the names of the type parameters this type declares + */ +protected void setTypeParameterNames(char[][] typeParameterNames) { + this.typeParameterNames = typeParameterNames; +} +/** + * Sets the names of the type parameter bounds this type declares + */ +protected void setTypeParameterBounds(char[][][] typeParameterBounds) { + this.typeParameterBounds = typeParameterBounds; +} public String toString() { return "Info for " + this.handle.toString(); //$NON-NLS-1$ } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeConverter.java index b6b2344cc0..3597ab7541 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeConverter.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/TypeConverter.java @@ -105,7 +105,8 @@ public class TypeConverter { argumentNames[i].toCharArray(), 0, createTypeReference(Signature.toString(argumentTypeNames[i]).toCharArray(), type), - CompilerModifiers.AccDefault); + CompilerModifiers.AccDefault, + false); // do not care whether was final or not } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java index 6c22a3a20e..abe2f2265e 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/UserLibraryManager.java @@ -22,16 +22,15 @@ import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; -import org.eclipse.core.runtime.Preferences; import org.eclipse.core.runtime.SubProgressMonitor; -import org.eclipse.core.runtime.Preferences.IPropertyChangeListener; -import org.eclipse.core.runtime.Preferences.PropertyChangeEvent; +import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.jdt.core.IClasspathContainer; import org.eclipse.jdt.core.IClasspathEntry; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.internal.core.util.Util; +import org.osgi.service.prefs.BackingStoreException; /** * @@ -43,10 +42,10 @@ public class UserLibraryManager { private static Map userLibraries; private static final boolean logProblems= false; - private static IPropertyChangeListener listener= new IPropertyChangeListener() { + private static IEclipsePreferences.IPreferenceChangeListener listener= new IEclipsePreferences.IPreferenceChangeListener() { - public void propertyChange(PropertyChangeEvent event) { - String key= event.getProperty(); + public void preferenceChange(IEclipsePreferences.PreferenceChangeEvent event) { + String key= event.getKey(); if (key.startsWith(CP_USERLIBRARY_PREFERENCES_PREFIX)) { try { recreatePersistedUserLibraryEntry(key, (String) event.getNewValue(), false, true); @@ -58,7 +57,6 @@ public class UserLibraryManager { } } } - }; private UserLibraryManager() { @@ -126,20 +124,26 @@ public class UserLibraryManager { if (userLibraries == null) { userLibraries= new HashMap(); // load variables and containers from preferences into cache - Preferences preferences = JavaCore.getPlugin().getPluginPreferences(); - preferences.addPropertyChangeListener(listener); + IEclipsePreferences instancePreferences = JavaCore.getInstancePreferences(); + instancePreferences.addPreferenceChangeListener(listener); // only get variable from preferences not set to their default - String[] propertyNames = preferences.propertyNames(); - for (int i = 0; i < propertyNames.length; i++) { - String propertyName = propertyNames[i]; - if (propertyName.startsWith(CP_USERLIBRARY_PREFERENCES_PREFIX)) { - try { - recreatePersistedUserLibraryEntry(propertyName, preferences.getString(propertyName), false, false); - } catch (JavaModelException e) { - // won't happen: no rebinding + try { + String[] propertyNames = instancePreferences.keys(); + for (int i = 0; i < propertyNames.length; i++) { + String propertyName = propertyNames[i]; + if (propertyName.startsWith(CP_USERLIBRARY_PREFERENCES_PREFIX)) { + try { + String propertyValue = instancePreferences.get(propertyName, null); + if (propertyValue != null) + recreatePersistedUserLibraryEntry(propertyName,propertyValue, false, false); + } catch (JavaModelException e) { + // won't happen: no rebinding + } } } + } catch (BackingStoreException e) { + // TODO (frederic) see if it's necessary to report this exception } } return userLibraries; @@ -178,7 +182,7 @@ public class UserLibraryManager { } } - Preferences preferences = JavaCore.getPlugin().getPluginPreferences(); + IEclipsePreferences instancePreferences = JavaCore.getInstancePreferences(); String containerKey = CP_USERLIBRARY_PREFERENCES_PREFIX+name; String containerString = CP_ENTRY_IGNORE; if (library != null) { @@ -188,19 +192,23 @@ public class UserLibraryManager { // could not encode entry: leave it as CP_ENTRY_IGNORE } } - preferences.removePropertyChangeListener(listener); + instancePreferences.removePreferenceChangeListener(listener); try { - preferences.setDefault(containerKey, CP_ENTRY_IGNORE); // use this default to get rid of removed ones - preferences.setValue(containerKey, containerString); + JavaCore.getDefaultPreferences().put(containerKey, CP_ENTRY_IGNORE); // TODO (frederic) verify if this is really necessary... + instancePreferences.put(containerKey, containerString); if (save) { - JavaCore.getPlugin().savePluginPreferences(); + try { + instancePreferences.flush(); + } catch (BackingStoreException e) { + // TODO (frederic) see if it's necessary to report this exception + } } if (rebind) { rebindClasspathEntries(name, library==null, monitor); } } finally { - preferences.addPropertyChangeListener(listener); + instancePreferences.addPreferenceChangeListener(listener); } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java index 1f085537a0..570c7d605f 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/AbstractImageBuilder.java @@ -84,6 +84,11 @@ public void acceptResult(CompilationResult result) { throw internalException(e); } + if (result.hasInconsistentToplevelHierarchies) + // ensure that this file is always retrieved from source for the rest of the build + if (!problemSourceFiles.contains(compilationUnit)) + problemSourceFiles.add(compilationUnit); + String typeLocator = compilationUnit.typeLocator(); ClassFile[] classFiles = result.getClassFiles(); int length = classFiles.length; @@ -91,6 +96,7 @@ public void acceptResult(CompilationResult result) { ArrayList definedTypeNames = new ArrayList(length); for (int i = 0; i < length; i++) { ClassFile classFile = classFiles[i]; + char[][] compoundName = classFile.getCompoundName(); char[] typeName = compoundName[compoundName.length - 1]; boolean isNestedType = classFile.enclosingClassFile != null; @@ -317,31 +323,10 @@ protected void storeProblemsFor(SourceFile sourceFile, IProblem[] problems) thro for (int i = 0, l = problems.length; i < l; i++) { IProblem problem = problems[i]; int id = problem.getID(); - switch (id) { - case IProblem.IsClassPathCorrect : - JavaBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject); // make this the only problem for this project - String[] args = problem.getArguments(); - missingClassFile = args[0]; - break; - case IProblem.SuperclassMustBeAClass : - case IProblem.SuperInterfaceMustBeAnInterface : - case IProblem.HierarchyCircularitySelfReference : - case IProblem.HierarchyCircularity : - case IProblem.HierarchyHasProblems : - case IProblem.SuperclassNotFound : - case IProblem.SuperclassNotVisible : - case IProblem.SuperclassAmbiguous : - case IProblem.SuperclassInternalNameProvided : - case IProblem.SuperclassInheritedNameHidesEnclosingName : - case IProblem.InterfaceNotFound : - case IProblem.InterfaceNotVisible : - case IProblem.InterfaceAmbiguous : - case IProblem.InterfaceInternalNameProvided : - case IProblem.InterfaceInheritedNameHidesEnclosingName : - // ensure that this file is always retrieved from source for the rest of the build - if (!problemSourceFiles.contains(sourceFile)) - problemSourceFiles.add(sourceFile); - break; + if (id == IProblem.IsClassPathCorrect) { + JavaBuilder.removeProblemsAndTasksFor(javaBuilder.currentProject); // make this the only problem for this project + String[] args = problem.getArguments(); + missingClassFile = args[0]; } if (id != IProblem.Task) { diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java index faede6176e..c8e6abed3a 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/JavaBuilder.java @@ -68,8 +68,7 @@ public static IMarker[] getTasksFor(IResource resource) { * This hook is invoked during PRE_AUTO_BUILD notification */ public static void buildStarting() { - // do nothing - // TODO (philippe) is it still needed? + // build is about to start } /** diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java index 34f1d6eeed..fafa0ee7a5 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyBinaryType.java @@ -68,6 +68,9 @@ public IBinaryField[] getFields() { public char[] getFileName() { return null; } +public char[] getGenericSignature() { + return null; +} /** * Answer the resolved names of the receiver's interfaces in the * class file format as specified in section 4.2 of the Java 2 VM spec diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java index 33e7a622aa..c29c0e8d27 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/hierarchy/HierarchyResolver.java @@ -33,6 +33,7 @@ import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.OperationCanceledException; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaModelException; +import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.CompilationResult; import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies; @@ -213,6 +214,7 @@ public void accept(ISourceType[] sourceTypes, PackageBinding packageBinding) { private IGenericType findSuperClass(IGenericType type, ReferenceBinding typeBinding) { ReferenceBinding superBinding = typeBinding.superclass(); if (superBinding != null) { + superBinding = (ReferenceBinding) superBinding.erasure(); if (superBinding.id == TypeIds.T_JavaLangObject && typeBinding.isHierarchyInconsistent()) { char[] superclassName; char separator; @@ -292,17 +294,21 @@ private IGenericType[] findSuperInterfaces(IGenericType type, ReferenceBinding t next : for (int i = 0; i < length; i++) { char[] superInterfaceName = superInterfaceNames[i]; int lastSeparator = CharOperation.lastIndexOf(separator, superInterfaceName); - char[] simpleName = lastSeparator == -1 ? superInterfaceName : CharOperation.subarray(superInterfaceName, lastSeparator+1, superInterfaceName.length); + int start = lastSeparator + 1; + int end = superInterfaceName.length; // case of binary inner type -> take the last part - int start = CharOperation.lastIndexOf('$', simpleName) + 1; - if (start != 0) { - int nameLength = simpleName.length - start; - System.arraycopy(simpleName, start, simpleName = new char[nameLength], 0, nameLength); - } + int lastDollar = CharOperation.lastIndexOf('$', superInterfaceName, start); + if (lastDollar != -1) start = lastDollar + 1; + + // case of a parameterized type -> take the first part + int genericStart = CharOperation.indexOf(Signature.C_GENERIC_START, superInterfaceName, start); + if (genericStart != -1) end = genericStart; + + char[] simpleName = CharOperation.subarray(superInterfaceName, start, end); if (bindingIndex < bindingLength) { - ReferenceBinding interfaceBinding = interfaceBindings[bindingIndex]; + ReferenceBinding interfaceBinding = (ReferenceBinding) interfaceBindings[bindingIndex].erasure(); // ensure that the binding corresponds to the interface defined by the user if (CharOperation.equals(simpleName, interfaceBinding.sourceName)) { @@ -769,12 +775,14 @@ private boolean subTypeOfType(ReferenceBinding subType, ReferenceBinding typeBin if (typeBinding == null || subType == null) return false; if (subType == typeBinding) return true; ReferenceBinding superclass = subType.superclass(); + if (superclass != null) superclass = (ReferenceBinding) superclass.erasure(); // if (superclass != null && superclass.id == TypeIds.T_JavaLangObject && subType.isHierarchyInconsistent()) return false; if (this.subTypeOfType(superclass, typeBinding)) return true; ReferenceBinding[] superInterfaces = subType.superInterfaces(); if (superInterfaces != null) { for (int i = 0, length = superInterfaces.length; i < length; i++) { - if (this.subTypeOfType(superInterfaces[i], typeBinding)) return true; + ReferenceBinding superInterface = (ReferenceBinding) superInterfaces[i].erasure(); + if (this.subTypeOfType(superInterface, typeBinding)) return true; } } return false; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java index fdc627eb77..d7896a11f9 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMBuilder.java @@ -63,14 +63,14 @@ public DOMBuilder() { * @see IDocumentElementRequestor#acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStartPosition, boolean onDemand) */ public void acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, - int nameStart, boolean onDemand) { + int nameStart, boolean onDemand, int modifiers) { int[] sourceRange = {declarationStart, declarationEnd}; int[] nameRange = {nameStart, declarationEnd - 1}; /* See 1FVII1P */ String importName = new String(CharOperation.subarray(fDocument, nameRange[0], nameRange[1] + 1)); - fNode= new DOMImport(fDocument, sourceRange, importName, nameRange, onDemand); + fNode= new DOMImport(fDocument, sourceRange, importName, nameRange, onDemand, modifiers); addChild(fNode); if (fBuildingSingleMember) { fFinishedSingleMember= true; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java index a3e76ef14d..8250fe05e1 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/DOMImport.java @@ -28,6 +28,7 @@ import org.eclipse.jdt.internal.core.util.CharArrayBuffer; */ // TODO (jerome) - add implementation support for 1.5 features class DOMImport extends DOMNode implements IDOMImport { + /** * Indicates if this import is an on demand type import */ @@ -64,9 +65,10 @@ DOMImport() { * or -1's if this node does not have a name. * @param onDemand - indicates if this import is an on demand style import */ -DOMImport(char[] document, int[] sourceRange, String name, int[] nameRange, boolean onDemand) { +DOMImport(char[] document, int[] sourceRange, String name, int[] nameRange, boolean onDemand, int modifiers) { super(document, sourceRange, name, nameRange); fOnDemand = onDemand; + fFlags = modifiers; setMask(MASK_DETAILED_SOURCE_INDEXES, true); } /** @@ -83,8 +85,8 @@ DOMImport(char[] document, int[] sourceRange, String name, int[] nameRange, bool * <code>null</code> if this node does not have a name * @param onDemand - indicates if this import is an on demand style import */ -DOMImport(char[] document, int[] sourceRange, String name, boolean onDemand) { - this(document, sourceRange, name, new int[] {-1, -1}, onDemand); +DOMImport(char[] document, int[] sourceRange, String name, boolean onDemand, int modifiers) { + this(document, sourceRange, name, new int[] {-1, -1}, onDemand, modifiers); fOnDemand = onDemand; setMask(MASK_DETAILED_SOURCE_INDEXES, false); } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java index dd8a0dfd39..524d0c2fa6 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/jdom/SimpleDOMBuilder.java @@ -43,7 +43,7 @@ public void acceptImport(int declarationStart, int declarationEnd, char[] name, if (onDemand) { importName+=".*"; //$NON-NLS-1$ } - fNode= new DOMImport(fDocument, sourceRange, importName, onDemand); + fNode= new DOMImport(fDocument, sourceRange, importName, onDemand, modifiers); addChild(fNode); } public void acceptPackage(int declarationStart, int declarationEnd, char[] name) { @@ -95,13 +95,13 @@ protected void enterAbstractMethod(int declarationStart, int modifiers, } /** */ -public void enterClass(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[] superclass, char[][] superinterfaces) { +public void enterClass(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[] superclass, char[][] superinterfaces, char[][] typeParameterNames, char[][][] typeParameterBounds) { enterType(declarationStart, modifiers, name, nameStart, nameEnd, superclass, superinterfaces, true); } /** */ -public void enterConstructor(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes) { +public void enterConstructor(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes, char[][] typeParameterNames, char[][][] typeParameterBounds) { /* see 1FVIIQZ */ String nameString = new String(fDocument, nameStart, nameEnd - nameStart); int openParenPosition = nameString.indexOf('('); @@ -138,13 +138,13 @@ public void enterInitializer(int declarationSourceStart, int modifiers) { } /** */ -public void enterInterface(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[][] superinterfaces) { +public void enterInterface(int declarationStart, int modifiers, char[] name, int nameStart, int nameEnd, char[][] superinterfaces, char[][] typeParameterNames, char[][][] typeParameterBounds) { enterType(declarationStart, modifiers, name, nameStart, nameEnd, null, superinterfaces, false); } /** */ -public void enterMethod(int declarationStart, int modifiers, char[] returnType, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes) { +public void enterMethod(int declarationStart, int modifiers, char[] returnType, char[] name, int nameStart, int nameEnd, char[][] parameterTypes, char[][] parameterNames, char[][] exceptionTypes, char[][] typeParameterNames, char[][][] typeParameterBounds) { enterAbstractMethod(declarationStart, modifiers, returnType, name, nameStart, nameEnd, parameterTypes, parameterNames, exceptionTypes,false); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java new file mode 100644 index 0000000000..5878194f5a --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Annotation.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IAnnotation; +import org.eclipse.jdt.core.util.IAnnotationComponent; +import org.eclipse.jdt.core.util.IConstantPool; + +/** + * Default implementation of IAnnotation + */ +public class Annotation extends ClassFileStruct implements IAnnotation { + + private static final IAnnotationComponent[] NO_ENTRIES = new IAnnotationComponent[0]; + + private int typeIndex; + private int componentsNumber; + private IAnnotationComponent[] components; + private int readOffset; + + /** + * Constructor for Annotation. + * + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public Annotation( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) throws ClassFormatException { + + this.typeIndex = u2At(classFileBytes, 0, offset); + final int length = u2At(classFileBytes, 2, offset); + this.componentsNumber = length; + if (length != 0) { + this.readOffset = 4; + this.components = new IAnnotationComponent[length]; + for (int i = 0; i < length; i++) { + AnnotationComponent component = new AnnotationComponent(classFileBytes, constantPool, offset + readOffset); + this.components[i++] = component; + this.readOffset += component.sizeInBytes(); + } + } else { + this.components = NO_ENTRIES; + } + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotation#getTypeIndex() + */ + public int getTypeIndex() { + return this.typeIndex; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotation#getComponentsNumber() + */ + public int getComponentsNumber() { + return this.componentsNumber; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotation#getComponents() + */ + public IAnnotationComponent[] getComponents() { + return this.components; + } + + int sizeInBytes() { + return this.readOffset; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java new file mode 100644 index 0000000000..10a4710e02 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponent.java @@ -0,0 +1,71 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IAnnotationComponent; +import org.eclipse.jdt.core.util.IAnnotationComponentValue; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IConstantPoolConstant; +import org.eclipse.jdt.core.util.IConstantPoolEntry; + +/** + * Default implementation of IAnnotationComponent + */ +public class AnnotationComponent extends ClassFileStruct implements IAnnotationComponent { + + private int componentNameIndex; + private char[] componentName; + private IAnnotationComponentValue componentValue; + private int readOffset; + + public AnnotationComponent( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) throws ClassFormatException { + final int nameIndex = u2At(classFileBytes, 0, offset); + this.componentNameIndex = nameIndex; + if (nameIndex != 0) { + IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(nameIndex); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.componentName = constantPoolEntry.getUtf8Value(); + } + this.readOffset = 2; + AnnotationComponentValue value = new AnnotationComponentValue(classFileBytes, constantPool, offset + readOffset); + this.componentValue = value; + this.readOffset += value.sizeInBytes(); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponent#getComponentNameIndex() + */ + public int getComponentNameIndex() { + return this.componentNameIndex; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponent#getComponentName() + */ + public char[] getComponentName() { + return this.componentName; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponent#getComponentValue() + */ + public IAnnotationComponentValue getComponentValue() { + return this.componentValue; + } + + int sizeInBytes() { + return this.readOffset; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java new file mode 100644 index 0000000000..b674db1eac --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationComponentValue.java @@ -0,0 +1,180 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IAnnotation; +import org.eclipse.jdt.core.util.IAnnotationComponentValue; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IConstantPoolConstant; +import org.eclipse.jdt.core.util.IConstantPoolEntry; + +/** + * Default implementation of IAnnotationComponent + */ +public class AnnotationComponentValue extends ClassFileStruct implements IAnnotationComponentValue { + + private int readOffset; + private int constantValueIndex; + private IConstantPoolEntry constantValue; + private int classFileInfoIndex; + private IConstantPoolEntry classFileInfo; + private int enumConstantIndex; + private IConstantPoolEntry enumConstant; + private IAnnotation attributeValue; + private int valuesNumber; + private IAnnotationComponentValue[] annotationComponentValues; + private int tag; + + public AnnotationComponentValue( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) throws ClassFormatException { + final int t = u1At(classFileBytes, 0, offset); + this.tag = t; + this.readOffset = 1; + switch(t) { + case 'B' : + case 'C' : + case 'D' : + case 'F' : + case 'I' : + case 'J' : + case 'S' : + case 'Z' : + case 's' : + final int constantIndex = this.u2At(classFileBytes, this.readOffset, offset); + this.constantValueIndex = constantIndex; + if (constantIndex != 0) { + IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(constantIndex); + switch(constantPoolEntry.getKind()) { + case IConstantPoolConstant.CONSTANT_Long : + case IConstantPoolConstant.CONSTANT_Float : + case IConstantPoolConstant.CONSTANT_Double : + case IConstantPoolConstant.CONSTANT_Integer : + case IConstantPoolConstant.CONSTANT_Utf8 : + break; + default : + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.constantValue = constantPoolEntry; + } + this.readOffset += 2; + break; + case 'e' : + final int enumIndex = this.u2At(classFileBytes, this.readOffset, offset); + this.enumConstantIndex = enumIndex; + if (enumIndex != 0) { + IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(enumIndex); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Fieldref) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.enumConstant = constantPoolEntry; + } + this.readOffset += 2; + break; + case 'c' : + final int classFileIndex = this.u2At(classFileBytes, this.readOffset, offset); + this.classFileInfoIndex = classFileIndex; + if (classFileIndex != 0) { + IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(classFileIndex); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.classFileInfo = constantPoolEntry; + } + this.readOffset += 2; + break; + case '@' : + Annotation annotation = new Annotation(classFileBytes, constantPool, this.readOffset + offset); + this.attributeValue = annotation; + this.readOffset += annotation.sizeInBytes(); + break; + case '[' : + final int numberOfValues = this.u2At(classFileBytes, this.readOffset, offset); + this.valuesNumber = numberOfValues; + if (numberOfValues != 0) { + this.readOffset += 2; + this.annotationComponentValues = new IAnnotationComponentValue[numberOfValues]; + for (int i = 0; i < numberOfValues; i++) { + AnnotationComponentValue value = new AnnotationComponentValue(classFileBytes, constantPool, offset + readOffset); + this.annotationComponentValues[i] = value; + this.readOffset += value.sizeInBytes(); + } + } + break; + } + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAnnotationComponentValues() + */ + public IAnnotationComponentValue[] getAnnotationComponentValues() { + return this.annotationComponentValues; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getAttributeValue() + */ + public IAnnotation getAttributeValue() { + return this.attributeValue; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfo() + */ + public IConstantPoolEntry getClassInfo() { + return this.classFileInfo; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getClassInfoIndex() + */ + public int getClassInfoIndex() { + return this.classFileInfoIndex; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getConstantValue() + */ + public IConstantPoolEntry getConstantValue() { + return this.constantValue; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getConstantValueIndex() + */ + public int getConstantValueIndex() { + return this.constantValueIndex; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstant() + */ + public IConstantPoolEntry getEnumConstant() { + return this.enumConstant; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getEnumConstantIndex() + */ + public int getEnumConstantIndex() { + return this.enumConstantIndex; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getTag() + */ + public int getTag() { + return this.tag; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationComponentValue#getValuesNumber() + */ + public int getValuesNumber() { + return this.valuesNumber; + } + + int sizeInBytes() { + return this.readOffset; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java new file mode 100644 index 0000000000..f8f5ac122a --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/AnnotationDefaultAttribute.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IAnnotationComponentValue; +import org.eclipse.jdt.core.util.IAnnotationDefaultAttribute; +import org.eclipse.jdt.core.util.IConstantPool; + +/** + * Default implementation of AnnotationDefaultAttribute. + * + * @since 3.0 + */ +public class AnnotationDefaultAttribute extends ClassFileAttribute + implements + IAnnotationDefaultAttribute { + + private IAnnotationComponentValue memberValue; + + /** + * Constructor for AnnotationDefaultAttribute. + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public AnnotationDefaultAttribute( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) + throws ClassFormatException { + super(classFileBytes, constantPool, offset); + this.memberValue = new AnnotationComponentValue(classFileBytes, constantPool, offset + 6); + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IAnnotationDefaultAttribute#getMemberValue() + */ + public IAnnotationComponentValue getMemberValue() { + return this.memberValue; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java index 27e104b816..5a4e660360 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ClassFileReader.java @@ -28,30 +28,30 @@ import org.eclipse.jdt.core.util.ISourceAttribute; public class ClassFileReader extends ClassFileStruct implements IClassFileReader { private static final IFieldInfo[] NO_FIELD_INFOS = new IFieldInfo[0]; - private static final IMethodInfo[] NO_METHOD_INFOS = new IMethodInfo[0]; private static final int[] NO_INTERFACE_INDEXES = new int[0]; private static final char[][] NO_INTERFACES_NAMES = CharOperation.NO_CHAR_CHAR; - - private IConstantPool constantPool; - private int magicNumber; + private static final IMethodInfo[] NO_METHOD_INFOS = new IMethodInfo[0]; private int accessFlags; + private IClassFileAttribute[] attributes; + private int attributesCount; private char[] className; - private char[] superclassName; - private int interfacesCount; - private char[][] interfaceNames; - private int[] interfaceIndexes; - private int fieldsCount; + private int classNameIndex; + + private IConstantPool constantPool; private IFieldInfo[] fields; - private int methodsCount; - private IMethodInfo[] methods; + private int fieldsCount; private IInnerClassesAttribute innerClassesAttribute; - private ISourceAttribute sourceFileAttribute; - private int classNameIndex; + private int[] interfaceIndexes; + private char[][] interfaceNames; + private int interfacesCount; + private int magicNumber; private int majorVersion; + private IMethodInfo[] methods; + private int methodsCount; private int minorVersion; + private ISourceAttribute sourceFileAttribute; + private char[] superclassName; private int superclassNameIndex; - private int attributesCount; - private IClassFileAttribute[] attributes; /** * Constructor for ClassFileReader. @@ -74,6 +74,10 @@ public class ClassFileReader extends ClassFileStruct implements IClassFileReader int[] constantPoolOffsets; try { this.magicNumber = (int) u4At(classFileBytes, 0, 0); + if (this.magicNumber != 0xCAFEBABE) { + throw new ClassFormatException(ClassFormatException.INVALID_MAGIC_NUMBER); + } + int readOffset = 10; this.minorVersion = this.u2At(classFileBytes, 4, 0); this.majorVersion = this.u2At(classFileBytes, 6, 0); @@ -156,7 +160,7 @@ public class ClassFileReader extends ClassFileStruct implements IClassFileReader if (superclassNameIndex != 0) { this.superclassName = getConstantClassNameAt(classFileBytes, constantPoolOffsets, this.superclassNameIndex); } - + // Read the interfaces, use exception handlers to catch bad format this.interfacesCount = u2At(classFileBytes, readOffset, 0); readOffset += 2; @@ -231,7 +235,7 @@ public class ClassFileReader extends ClassFileStruct implements IClassFileReader // Read the attributes this.attributesCount = u2At(classFileBytes, readOffset, 0); readOffset += 2; - + int attributesIndex = 0; this.attributes = ClassFileAttribute.NO_ATTRIBUTES; if (this.attributesCount != 0) { @@ -240,16 +244,20 @@ public class ClassFileReader extends ClassFileStruct implements IClassFileReader for (int i = 0; i < attributesCount; i++) { int utf8Offset = constantPoolOffsets[u2At(classFileBytes, readOffset, 0)]; char[] attributeName = utf8At(classFileBytes, utf8Offset + 3, 0, u2At(classFileBytes, utf8Offset + 1, 0)); - if (equals(attributeName, IAttributeNamesConstants.DEPRECATED)) { - this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, this.constantPool, readOffset); - } else if (equals(attributeName, IAttributeNamesConstants.INNER_CLASSES)) { + if (equals(attributeName, IAttributeNamesConstants.INNER_CLASSES)) { this.innerClassesAttribute = new InnerClassesAttribute(classFileBytes, this.constantPool, readOffset); this.attributes[attributesIndex++] = this.innerClassesAttribute; } else if (equals(attributeName, IAttributeNamesConstants.SOURCE)) { - this.sourceFileAttribute = new SourceFileAttribute(classFileBytes, this.constantPool, readOffset); - this.attributes[attributesIndex++] = this.sourceFileAttribute; - } else if (equals(attributeName, IAttributeNamesConstants.SYNTHETIC)) { - this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, this.constantPool, readOffset); + this.sourceFileAttribute = new SourceFileAttribute(classFileBytes, this.constantPool, readOffset); + this.attributes[attributesIndex++] = this.sourceFileAttribute; + } else if (equals(attributeName, IAttributeNamesConstants.ENCLOSING_METHOD)) { + this.attributes[attributesIndex++] = new EnclosingMethodAttribute(classFileBytes, this.constantPool, readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.SIGNATURE)) { + this.attributes[attributesIndex++] = new SignatureAttribute(classFileBytes, this.constantPool, readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS)) { + this.attributes[attributesIndex++] = new RuntimeVisibleAnnotationsAttribute(classFileBytes, this.constantPool, readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS)) { + this.attributes[attributesIndex++] = new RuntimeInvisibleAnnotationsAttribute(classFileBytes, this.constantPool, readOffset); } else { this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, this.constantPool, readOffset); } @@ -277,74 +285,85 @@ public class ClassFileReader extends ClassFileStruct implements IClassFileReader public int getAccessFlags() { return this.accessFlags; } - /** - * @see IClassFileReader#getSourceFileAttribute() + * @see IClassFileReader#getAttributeCount() */ - public ISourceAttribute getSourceFileAttribute() { - return this.sourceFileAttribute; + public int getAttributeCount() { + return this.attributesCount; } /** - * @see IClassFileReader#getConstantPool() + * @see IClassFileReader#getAttributes() */ - public IConstantPool getConstantPool() { - return this.constantPool; + public IClassFileAttribute[] getAttributes() { + return this.attributes; } /** - * @see IClassFileReader#getFieldInfos() + * @see IClassFileReader#getClassIndex() */ - public IFieldInfo[] getFieldInfos() { - return this.fields; + public int getClassIndex() { + return this.classNameIndex; } /** - * @see IClassFileReader#getInnerClassesAttribute() + * @see IClassFileReader#getClassName() */ - public IInnerClassesAttribute getInnerClassesAttribute() { - return this.innerClassesAttribute; + public char[] getClassName() { + return this.className; + } + + private char[] getConstantClassNameAt(byte[] classFileBytes, int[] constantPoolOffsets, int constantPoolIndex) { + int utf8Offset = constantPoolOffsets[u2At(classFileBytes, constantPoolOffsets[constantPoolIndex] + 1, 0)]; + return utf8At(classFileBytes, utf8Offset + 3, 0, u2At(classFileBytes, utf8Offset + 1, 0)); } /** - * @see IClassFileReader#getInterfaceNames() + * @see IClassFileReader#getConstantPool() */ - public char[][] getInterfaceNames() { - return this.interfaceNames; + public IConstantPool getConstantPool() { + return this.constantPool; + } + /** + * @see IClassFileReader#getFieldInfos() + */ + public IFieldInfo[] getFieldInfos() { + return this.fields; } /** - * @see IClassFileReader#getMethodInfos() + * @see IClassFileReader#getFieldsCount() */ - public IMethodInfo[] getMethodInfos() { - return this.methods; + public int getFieldsCount() { + return this.fieldsCount; } /** - * @see IClassFileReader#getClassName() + * @see IClassFileReader#getInnerClassesAttribute() */ - public char[] getClassName() { - return this.className; + public IInnerClassesAttribute getInnerClassesAttribute() { + return this.innerClassesAttribute; } /** - * @see IClassFileReader#getSuperclassName() + * @see IClassFileReader#getInterfaceIndexes() */ - public char[] getSuperclassName() { - return this.superclassName; + public int[] getInterfaceIndexes() { + return this.interfaceIndexes; } + /** - * @see IClassFileReader#isClass() + * @see IClassFileReader#getInterfaceNames() */ - public boolean isClass() { - return !isInterface(); + public char[][] getInterfaceNames() { + return this.interfaceNames; } /** - * @see IClassFileReader#isInterface() + * @see IClassFileReader#getMagic() */ - public boolean isInterface() { - return (getAccessFlags() & IModifierConstants.ACC_INTERFACE) != 0; + public int getMagic() { + return this.magicNumber; } /** @@ -355,35 +374,31 @@ public class ClassFileReader extends ClassFileStruct implements IClassFileReader } /** - * @see IClassFileReader#getMinorVersion() + * @see IClassFileReader#getMethodInfos() */ - public int getMinorVersion() { - return this.minorVersion; + public IMethodInfo[] getMethodInfos() { + return this.methods; } - private char[] getConstantClassNameAt(byte[] classFileBytes, int[] constantPoolOffsets, int constantPoolIndex) { - int utf8Offset = constantPoolOffsets[u2At(classFileBytes, constantPoolOffsets[constantPoolIndex] + 1, 0)]; - return utf8At(classFileBytes, utf8Offset + 3, 0, u2At(classFileBytes, utf8Offset + 1, 0)); - } /** - * @see IClassFileReader#getAttributeCount() + * @see IClassFileReader#getMethodsCount() */ - public int getAttributeCount() { - return this.attributesCount; + public int getMethodsCount() { + return this.methodsCount; } /** - * @see IClassFileReader#getClassIndex() + * @see IClassFileReader#getMinorVersion() */ - public int getClassIndex() { - return this.classNameIndex; + public int getMinorVersion() { + return this.minorVersion; } /** - * @see IClassFileReader#getInterfaceIndexes() + * @see IClassFileReader#getSourceFileAttribute() */ - public int[] getInterfaceIndexes() { - return this.interfaceIndexes; + public ISourceAttribute getSourceFileAttribute() { + return this.sourceFileAttribute; } /** @@ -394,31 +409,22 @@ public class ClassFileReader extends ClassFileStruct implements IClassFileReader } /** - * @see IClassFileReader#getMagic() - */ - public int getMagic() { - return this.magicNumber; - } - - /** - * @see IClassFileReader#getFieldsCount() + * @see IClassFileReader#getSuperclassName() */ - public int getFieldsCount() { - return this.fieldsCount; + public char[] getSuperclassName() { + return this.superclassName; } - /** - * @see IClassFileReader#getMethodsCount() + * @see IClassFileReader#isClass() */ - public int getMethodsCount() { - return this.methodsCount; + public boolean isClass() { + return !isInterface(); } /** - * @see IClassFileReader#getAttributes() + * @see IClassFileReader#isInterface() */ - public IClassFileAttribute[] getAttributes() { - return this.attributes; + public boolean isInterface() { + return (getAccessFlags() & IModifierConstants.ACC_INTERFACE) != 0; } - } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java index e712318092..549a1906f5 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/CodeAttribute.java @@ -28,19 +28,19 @@ import org.eclipse.jdt.core.util.IOpcodeMnemonics; */ public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute { private static final IExceptionTableEntry[] NO_EXCEPTION_TABLE = new IExceptionTableEntry[0]; - private int maxLocals; - private int maxStack; - private ILineNumberAttribute lineNumberAttribute; - private ILocalVariableAttribute localVariableAttribute; - private IExceptionTableEntry[] exceptionTableEntries; - private long codeLength; + private IClassFileAttribute[] attributes; private int attributesCount; - private int exceptionTableLength; private byte[] bytecodes; - private IConstantPool constantPool; - private int codeOffset; private byte[] classFileBytes; - private IClassFileAttribute[] attributes; + private long codeLength; + private int codeOffset; + private IConstantPool constantPool; + private IExceptionTableEntry[] exceptionTableEntries; + private int exceptionTableLength; + private ILineNumberAttribute lineNumberAttribute; + private ILocalVariableAttribute localVariableAttribute; + private int maxLocals; + private int maxStack; CodeAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException { super(classFileBytes, constantPool, offset); @@ -80,6 +80,8 @@ public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute } else if (equals(attributeName, IAttributeNamesConstants.LOCAL_VARIABLE)) { this.localVariableAttribute = new LocalVariableAttribute(classFileBytes, constantPool, offset + readOffset); this.attributes[attributesIndex++] = this.localVariableAttribute; + } else if (equals(attributeName, IAttributeNamesConstants.LOCAL_VARIABLE_TYPE_TABLE)) { + this.attributes[attributesIndex++] = new LocalVariableTypeAttribute(classFileBytes, constantPool, offset + readOffset); } else { this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset); } @@ -87,19 +89,49 @@ public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute } } - /** - * @see ICodeAttribute#getMaxLocals() + * @see ICodeAttribute#getAttributes() */ - public int getMaxLocals() { - return this.maxLocals; + public IClassFileAttribute[] getAttributes() { + return this.attributes; } /** - * @see ICodeAttribute#getMaxStack() + * @see ICodeAttribute#getAttributesCount() */ - public int getMaxStack() { - return this.maxStack; + public int getAttributesCount() { + return this.attributesCount; + } + + /** + * @see ICodeAttribute#getBytecodes() + */ + public byte[] getBytecodes() { + if (this.bytecodes == null) { + System.arraycopy(this.classFileBytes, this.codeOffset, (this.bytecodes = new byte[(int) this.codeLength]), 0, (int) this.codeLength); + } + return this.bytecodes; + } + + /** + * @see ICodeAttribute#getCodeLength() + */ + public long getCodeLength() { + return this.codeLength; + } + + /** + * @see ICodeAttribute#getExceptionTable() + */ + public IExceptionTableEntry[] getExceptionTable() { + return this.exceptionTableEntries; + } + + /** + * @see ICodeAttribute#getExceptionTableLength() + */ + public int getExceptionTableLength() { + return this.exceptionTableLength; } /** @@ -115,18 +147,22 @@ public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute public ILocalVariableAttribute getLocalVariableAttribute() { return this.localVariableAttribute; } - + /** - * @see ICodeAttribute#getBytecodes() + * @see ICodeAttribute#getMaxLocals() */ - public byte[] getBytecodes() { - if (this.bytecodes == null) { - System.arraycopy(this.classFileBytes, this.codeOffset, (this.bytecodes = new byte[(int) this.codeLength]), 0, (int) this.codeLength); - } - return this.bytecodes; + public int getMaxLocals() { + return this.maxLocals; } /** + * @see ICodeAttribute#getMaxStack() + */ + public int getMaxStack() { + return this.maxStack; + } + + /** * @see ICodeAttribute#traverse(IBytecodeVisitor visitor) */ public void traverse(IBytecodeVisitor visitor) throws ClassFormatException { @@ -213,7 +249,8 @@ public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute constantPoolEntry = this.constantPool.decodeEntry(index); if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Float && constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Integer - && constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_String) { + && constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_String + && constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) { throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); } visitor._ldc(pc - this.codeOffset, index, constantPoolEntry); @@ -1126,46 +1163,4 @@ public class CodeAttribute extends ClassFileAttribute implements ICodeAttribute } } } - - /** - * @see ICodeAttribute#getExceptionTable() - */ - public IExceptionTableEntry[] getExceptionTable() { - return this.exceptionTableEntries; - } - - /** - * @see ICodeAttribute#getAttributesCount() - */ - public int getAttributesCount() { - return this.attributesCount; - } - - /** - * @see ICodeAttribute#getCodeLength() - */ - public long getCodeLength() { - return this.codeLength; - } - - /** - * @see ICodeAttribute#getExceptionTableLength() - */ - public int getExceptionTableLength() { - return this.exceptionTableLength; - } - - /** - * @see IClassFileAttribute#getAttributeName() - */ - public char[] getAttributeName() { - return IAttributeNamesConstants.CODE; - } - /** - * @see ICodeAttribute#getAttributes() - */ - public IClassFileAttribute[] getAttributes() { - return this.attributes; - } - } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java index d8688ef18a..15d1981e18 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ConstantValueAttribute.java @@ -11,7 +11,6 @@ package org.eclipse.jdt.internal.core.util; import org.eclipse.jdt.core.util.ClassFormatException; -import org.eclipse.jdt.core.util.IAttributeNamesConstants; import org.eclipse.jdt.core.util.IConstantPool; import org.eclipse.jdt.core.util.IConstantPoolEntry; import org.eclipse.jdt.core.util.IConstantValueAttribute; @@ -30,7 +29,7 @@ public class ConstantValueAttribute ConstantValueAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException { super(classFileBytes, constantPool, offset); this.constantValueIndex = u2At(classFileBytes, 6, offset); - this.constantPool = constantPool; + this.constantPool = constantPool; } /** * @see IConstantValueAttribute#getConstantValue() @@ -45,11 +44,4 @@ public class ConstantValueAttribute public int getConstantValueIndex() { return this.constantValueIndex; } - - /** - * @see org.eclipse.jdt.core.util.IClassFileAttribute#getAttributeName() - */ - public char[] getAttributeName() { - return IAttributeNamesConstants.CONSTANT_VALUE; - } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java index a571781ece..bd0c4cfc71 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Disassembler.java @@ -1129,11 +1129,8 @@ public class Disassembler extends ClassFileBytesDisassembler { } private char[] getSignatureForField(char[] fieldDescriptor) { - final int length = fieldDescriptor.length; - char[] newFieldDescriptor = new char[length]; - System.arraycopy(fieldDescriptor, 0, newFieldDescriptor, 0, length); - CharOperation.replace(newFieldDescriptor, '/', '.'); - CharOperation.replace(newFieldDescriptor, '$', '~'); + char[] newFieldDescriptor = CharOperation.replaceOnCopy(fieldDescriptor, '/', '.'); + newFieldDescriptor = CharOperation.replaceOnCopy(newFieldDescriptor, '$', '~'); char[] fieldDescriptorSignature = Signature.toCharArray(newFieldDescriptor); CharOperation.replace(fieldDescriptorSignature, '~', '$'); return fieldDescriptorSignature; diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ElementInfoConverter.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ElementInfoConverter.java index 4578f6318c..960d42f351 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ElementInfoConverter.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ElementInfoConverter.java @@ -209,7 +209,8 @@ public class ElementInfoConverter implements CompilerModifiers { argumentNames[i], position, createTypeReference(argumentTypeNames[i], start, end), - AccDefault); + AccDefault, + false); // do not care whether was final or not } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java new file mode 100644 index 0000000000..8097a276b8 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/EnclosingMethodAttribute.java @@ -0,0 +1,103 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IConstantPoolConstant; +import org.eclipse.jdt.core.util.IConstantPoolEntry; +import org.eclipse.jdt.core.util.IEnclosingMethodAttribute; + +/** + * Default implementation of EnclosingMethodAttribute. + * + * @since 3.0 + */ +public class EnclosingMethodAttribute extends ClassFileAttribute implements IEnclosingMethodAttribute { + + private int enclosingClassIndex; + private char[] enclosingClassName; + private int methodDescriptorIndex; + private char[] methodDescriptor; + private int methodNameIndex; + private char[] methodName; + private int methodNameAndTypeIndex; + + EnclosingMethodAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException { + super(classFileBytes, constantPool, offset); + int index = u2At(classFileBytes, 6, offset); + this.enclosingClassIndex = index; + IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Class) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.enclosingClassName = constantPoolEntry.getClassInfoName(); + this.methodNameAndTypeIndex = u2At(classFileBytes, 8, offset); + constantPoolEntry = constantPool.decodeEntry(this.methodNameAndTypeIndex); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_NameAndType) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.methodDescriptorIndex = constantPoolEntry.getNameAndTypeInfoDescriptorIndex(); + this.methodNameIndex = constantPoolEntry.getNameAndTypeInfoNameIndex(); + constantPoolEntry = constantPool.decodeEntry(this.methodDescriptorIndex); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.methodDescriptor = constantPoolEntry.getUtf8Value(); + constantPoolEntry = constantPool.decodeEntry(this.methodNameIndex); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.methodName = constantPoolEntry.getUtf8Value(); + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getEnclosingClass() + */ + public char[] getEnclosingClass() { + return this.enclosingClassName; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodDeclaringClassDescriptorIndex() + */ + public int getEnclosingClassIndex() { + return this.enclosingClassIndex; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodDescriptor() + */ + public char[] getMethodDescriptor() { + return this.methodDescriptor; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodDescriptorIndex() + */ + public int getMethodDescriptorIndex() { + return this.methodDescriptorIndex; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodName() + */ + public char[] getMethodName() { + return this.methodName; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodNameIndex() + */ + public int getMethodNameIndex() { + return this.methodNameIndex; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IEnclosingMethodAttribute#getMethodNameAndTypeIndex() + */ + public int getMethodNameAndTypeIndex() { + return this.methodNameAndTypeIndex; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java index e9b178fc03..451e3989d7 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ExceptionAttribute.java @@ -12,7 +12,6 @@ package org.eclipse.jdt.internal.core.util; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.util.ClassFormatException; -import org.eclipse.jdt.core.util.IAttributeNamesConstants; import org.eclipse.jdt.core.util.IConstantPool; import org.eclipse.jdt.core.util.IConstantPoolConstant; import org.eclipse.jdt.core.util.IConstantPoolEntry; @@ -72,12 +71,4 @@ public class ExceptionAttribute extends ClassFileAttribute implements IException public int getExceptionsNumber() { return this.exceptionsNumber; } - - /** - * @see org.eclipse.jdt.core.util.IClassFileAttribute#getAttributeName() - */ - public char[] getAttributeName() { - return IAttributeNamesConstants.EXCEPTIONS; - } - } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java index 56aed05b2c..7bd61a3119 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/FieldInfo.java @@ -18,22 +18,23 @@ import org.eclipse.jdt.core.util.IConstantPoolConstant; import org.eclipse.jdt.core.util.IConstantPoolEntry; import org.eclipse.jdt.core.util.IConstantValueAttribute; import org.eclipse.jdt.core.util.IFieldInfo; +import org.eclipse.jdt.core.util.IModifierConstants; /** * Default implementation of IFieldInfo. */ public class FieldInfo extends ClassFileStruct implements IFieldInfo { + private int accessFlags; + private int attributeBytes; + private IClassFileAttribute[] attributes; + private int attributesCount; + private IConstantValueAttribute constantValueAttribute; + private char[] descriptor; + private int descriptorIndex; private boolean isDeprecated; private boolean isSynthetic; - private int accessFlags; private char[] name; - private char[] descriptor; private int nameIndex; - private int descriptorIndex; - private int attributesCount; - private int attributeBytes; - private IConstantValueAttribute constantValueAttribute; - private IClassFileAttribute[] attributes; /** * @param classFileBytes byte[] @@ -42,22 +43,25 @@ public class FieldInfo extends ClassFileStruct implements IFieldInfo { */ public FieldInfo(byte classFileBytes[], IConstantPool constantPool, int offset) throws ClassFormatException { - this.accessFlags = u2At(classFileBytes, 0, offset); - + final int flags = u2At(classFileBytes, 0, offset); + this.accessFlags = flags; + if ((flags & IModifierConstants.ACC_SYNTHETIC) != 0) { + this.isSynthetic = true; + } this.nameIndex = u2At(classFileBytes, 2, offset); IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.nameIndex); if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) { throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); } this.name = constantPoolEntry.getUtf8Value(); - + this.descriptorIndex = u2At(classFileBytes, 4, offset); constantPoolEntry = constantPool.decodeEntry(this.descriptorIndex); if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) { throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); } this.descriptor = constantPoolEntry.getUtf8Value(); - + this.attributesCount = u2At(classFileBytes, 6, offset); this.attributes = ClassFileAttribute.NO_ATTRIBUTES; int readOffset = 8; @@ -80,6 +84,12 @@ public class FieldInfo extends ClassFileStruct implements IFieldInfo { } else if (equals(attributeName, IAttributeNamesConstants.CONSTANT_VALUE)) { this.constantValueAttribute = new ConstantValueAttribute(classFileBytes, constantPool, offset + readOffset); this.attributes[attributesIndex++] = this.constantValueAttribute; + } else if (equals(attributeName, IAttributeNamesConstants.SIGNATURE)) { + this.attributes[attributesIndex++] = new SignatureAttribute(classFileBytes, constantPool, offset + readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS)) { + this.attributes[attributesIndex++] = new RuntimeVisibleAnnotationsAttribute(classFileBytes, constantPool, readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS)) { + this.attributes[attributesIndex++] = new RuntimeInvisibleAnnotationsAttribute(classFileBytes, constantPool, readOffset); } else { this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset); } @@ -94,6 +104,19 @@ public class FieldInfo extends ClassFileStruct implements IFieldInfo { public int getAccessFlags() { return this.accessFlags; } + /** + * @see IFieldInfo#getAttributeCount() + */ + public int getAttributeCount() { + return this.attributesCount; + } + + /** + * @see IFieldInfo#getAttributes() + */ + public IClassFileAttribute[] getAttributes() { + return this.attributes; + } /** * @see IFieldInfo#getConstantValueAttribute() @@ -110,6 +133,13 @@ public class FieldInfo extends ClassFileStruct implements IFieldInfo { } /** + * @see IFieldInfo#getDescriptorIndex() + */ + public int getDescriptorIndex() { + return this.descriptorIndex; + } + + /** * @see IFieldInfo#getName() */ public char[] getName() { @@ -117,6 +147,12 @@ public class FieldInfo extends ClassFileStruct implements IFieldInfo { } /** + * @see IFieldInfo#getNameIndex() + */ + public int getNameIndex() { + return this.nameIndex; + } + /** * @see IFieldInfo#hasConstantValueAttribute() */ public boolean hasConstantValueAttribute() { @@ -140,32 +176,4 @@ public class FieldInfo extends ClassFileStruct implements IFieldInfo { int sizeInBytes() { return this.attributeBytes; } - /** - * @see IFieldInfo#getAttributeCount() - */ - public int getAttributeCount() { - return this.attributesCount; - } - - /** - * @see IFieldInfo#getDescriptorIndex() - */ - public int getDescriptorIndex() { - return this.descriptorIndex; - } - - /** - * @see IFieldInfo#getNameIndex() - */ - public int getNameIndex() { - return this.nameIndex; - } - - /** - * @see IFieldInfo#getAttributes() - */ - public IClassFileAttribute[] getAttributes() { - return this.attributes; - } - } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java index fac7046502..b0767082b8 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/HandleFactory.java @@ -188,7 +188,7 @@ public class HandleFactory { public void endVisit(ConstructorDeclaration node, ClassScope scope) { pop(node); } - + public boolean visit(FieldDeclaration node, MethodScope scope) { push(node); if (node == toBeFound) throw new EndVisit(); @@ -246,7 +246,7 @@ public class HandleFactory { public void endVisit(MethodDeclaration node, ClassScope scope) { pop(node); } - + public boolean visit(TypeDeclaration node, CompilationUnitScope scope) { push(node); if (node == toBeFound) throw new EndVisit(); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java index 3ce5827df0..1b891e972b 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/InnerClassesAttribute.java @@ -37,8 +37,7 @@ public class InnerClassesAttribute extends ClassFileAttribute implements IInnerC throws ClassFormatException { super(classFileBytes, constantPool, offset); this.numberOfClasses = u2At(classFileBytes, 6, offset); - int length = this.numberOfClasses; - this.entries = NO_ENTRIES; + final int length = this.numberOfClasses; if (length != 0) { int readOffset = 8; this.entries = new IInnerClassesAttributeEntry[length]; @@ -46,6 +45,8 @@ public class InnerClassesAttribute extends ClassFileAttribute implements IInnerC this.entries[i] = new InnerClassesAttributeEntry(classFileBytes, constantPool, offset + readOffset); readOffset += 8; } + } else { + this.entries = NO_ENTRIES; } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java index 3b6820e886..19a94f07cc 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LineNumberAttribute.java @@ -11,7 +11,6 @@ package org.eclipse.jdt.internal.core.util; import org.eclipse.jdt.core.util.ClassFormatException; -import org.eclipse.jdt.core.util.IAttributeNamesConstants; import org.eclipse.jdt.core.util.IConstantPool; import org.eclipse.jdt.core.util.ILineNumberAttribute; @@ -40,26 +39,20 @@ public class LineNumberAttribute throws ClassFormatException { super(classFileBytes, constantPool, offset); - this.lineNumberTableLength = u2At(classFileBytes, 6, offset); - this.lineNumberTable = NO_ENTRIES; - if (this.lineNumberTableLength != 0) { - this.lineNumberTable = new int[this.lineNumberTableLength][2]; + final int length = u2At(classFileBytes, 6, offset); + this.lineNumberTableLength = length; + if (length != 0) { + this.lineNumberTable = new int[length][2]; + int readOffset = 8; + for (int i = 0; i < length; i++) { + this.lineNumberTable[i][0] = u2At(classFileBytes, readOffset, offset); + this.lineNumberTable[i][1] = u2At(classFileBytes, readOffset + 2, offset); + readOffset += 4; + } + } else { + this.lineNumberTable = NO_ENTRIES; } - int readOffset = 8; - for (int i = 0, max = this.lineNumberTableLength; i < max; i++) { - this.lineNumberTable[i][0] = u2At(classFileBytes, readOffset, offset); - this.lineNumberTable[i][1] = u2At(classFileBytes, readOffset + 2, offset); - readOffset += 4; - } - } - - /** - * @see org.eclipse.jdt.core.util.IClassFileAttribute#getAttributeName() - */ - public char[] getAttributeName() { - return IAttributeNamesConstants.LINE_NUMBER; } - /** * @see ILineNumberAttribute#getLineNumberTable() */ diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java index 8ca2c27eed..d82413c7e6 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableAttribute.java @@ -11,7 +11,6 @@ package org.eclipse.jdt.internal.core.util; import org.eclipse.jdt.core.util.ClassFormatException; -import org.eclipse.jdt.core.util.IAttributeNamesConstants; import org.eclipse.jdt.core.util.IConstantPool; import org.eclipse.jdt.core.util.ILocalVariableAttribute; import org.eclipse.jdt.core.util.ILocalVariableTableEntry; @@ -40,26 +39,19 @@ public class LocalVariableAttribute int offset) throws ClassFormatException { super(classFileBytes, constantPool, offset); - this.localVariableTableLength = u2At(classFileBytes, 6, offset); - int readOffset = 8; - int length = this.localVariableTableLength; - this.localVariableTable = NO_ENTRIES; + final int length = u2At(classFileBytes, 6, offset); + this.localVariableTableLength = length; if (length != 0) { - this.localVariableTable = new LocalVariableTableEntry[length]; + int readOffset = 8; + this.localVariableTable = new ILocalVariableTableEntry[length]; + for (int i = 0; i < length; i++) { + this.localVariableTable[i] = new LocalVariableTableEntry(classFileBytes, constantPool, offset + readOffset); + readOffset += 10; + } + } else { + this.localVariableTable = NO_ENTRIES; } - for (int i = 0; i < length; i++) { - this.localVariableTable[i] = new LocalVariableTableEntry(classFileBytes, constantPool, offset + readOffset); - readOffset += 10; - } - } - - /** - * @see org.eclipse.jdt.core.util.IClassFileAttribute#getAttributeName() - */ - public char[] getAttributeName() { - return IAttributeNamesConstants.LOCAL_VARIABLE; } - /** * @see ILocalVariableAttribute#getLocalVariableTable() */ diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java new file mode 100644 index 0000000000..7fceb5d5f9 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeAttribute.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.ILocalVariableTypeTableAttribute; +import org.eclipse.jdt.core.util.ILocalVariableTypeTableEntry; + +/** + * Default implementation of ILocalVariableTypeAttribute. + */ +public class LocalVariableTypeAttribute + extends ClassFileAttribute + implements ILocalVariableTypeTableAttribute { + + private static final ILocalVariableTypeTableEntry[] NO_ENTRIES = new ILocalVariableTypeTableEntry[0]; + private int localVariableTypeTableLength; + private ILocalVariableTypeTableEntry[] localVariableTypeTableEntries; + + /** + * Constructor for LocalVariableTypeAttribute. + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public LocalVariableTypeAttribute( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) + throws ClassFormatException { + super(classFileBytes, constantPool, offset); + final int length = u2At(classFileBytes, 6, offset); + this.localVariableTypeTableLength = length; + if (length != 0) { + int readOffset = 8; + this.localVariableTypeTableEntries = new ILocalVariableTypeTableEntry[length]; + for (int i = 0; i < length; i++) { + this.localVariableTypeTableEntries[i] = new LocalVariableTypeTableEntry(classFileBytes, constantPool, offset + readOffset); + readOffset += 10; + } + } else { + this.localVariableTypeTableEntries = NO_ENTRIES; + } + } + /** + * @see ILocalVariableTypeTableAttribute#getLocalVariableTable() + */ + public ILocalVariableTypeTableEntry[] getLocalVariableTypeTable() { + return this.localVariableTypeTableEntries; + } + + /** + * @see ILocalVariableTypeTableAttribute#getLocalVariableTableLength() + */ + public int getLocalVariableTypeTableLength() { + return this.localVariableTypeTableLength; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java new file mode 100644 index 0000000000..a2390c3e7a --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/LocalVariableTypeTableEntry.java @@ -0,0 +1,110 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IConstantPoolConstant; +import org.eclipse.jdt.core.util.IConstantPoolEntry; +import org.eclipse.jdt.core.util.ILocalVariableTypeTableEntry; + +/** + * Default implementation of ILocalVariableTypeTableEntry + */ +public class LocalVariableTypeTableEntry extends ClassFileStruct implements ILocalVariableTypeTableEntry { + + private int startPC; + private int length; + private int nameIndex; + private int signatureIndex; + private char[] name; + private char[] signature; + private int index; + + /** + * Constructor for LocalVariableTypeTableEntry. + * + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public LocalVariableTypeTableEntry( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) throws ClassFormatException { + this.startPC = u2At(classFileBytes, 0, offset); + this.length = u2At(classFileBytes, 2, offset); + this.nameIndex = u2At(classFileBytes, 4, offset); + this.signatureIndex = u2At(classFileBytes, 6, offset); + this.index = u2At(classFileBytes, 8, offset); + IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.nameIndex); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.name = constantPoolEntry.getUtf8Value(); + constantPoolEntry = constantPool.decodeEntry(this.signatureIndex); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.signature = constantPoolEntry.getUtf8Value(); + } + + /** + * @see ILocalVariableTypeTableEntry#getStartPC() + */ + public int getStartPC() { + return this.startPC; + } + + /** + * @see ILocalVariableTypeTableEntry#getLength() + */ + public int getLength() { + return this.length; + } + + /** + * @see ILocalVariableTypeTableEntry#getNameIndex() + */ + public int getNameIndex() { + return this.nameIndex; + } + + /** + * @see ILocalVariableTypeTableEntry#getSignatureIndex() + */ + public int getSignatureIndex() { + return this.signatureIndex; + } + + /** + * @see ILocalVariableTypeTableEntry#getIndex() + */ + public int getIndex() { + return this.index; + } + + /** + * @see ILocalVariableTypeTableEntry#getName() + */ + public char[] getName() { + return this.name; + } + + /** + * @see ILocalVariableTypeTableEntry#getSignature() + */ + public char[] getSignature() { + return this.signature; + } + +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java index 84186c0dc3..57d338f0ae 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/MethodInfo.java @@ -26,18 +26,18 @@ import org.eclipse.jdt.core.util.IModifierConstants; * Default implementation of IMethodInfo. */ public class MethodInfo extends ClassFileStruct implements IMethodInfo { - private boolean isDeprecated; - private boolean isSynthetic; private int accessFlags; - private char[] name; - private char[] descriptor; - private int nameIndex; - private int descriptorIndex; - private int attributesCount; private int attributeBytes; + private IClassFileAttribute[] attributes; + private int attributesCount; private ICodeAttribute codeAttribute; + private char[] descriptor; + private int descriptorIndex; private IExceptionAttribute exceptionAttribute; - private IClassFileAttribute[] attributes; + private boolean isDeprecated; + private boolean isSynthetic; + private char[] name; + private int nameIndex; /** * @param classFileBytes byte[] @@ -49,7 +49,11 @@ public class MethodInfo extends ClassFileStruct implements IMethodInfo { throws ClassFormatException { boolean no_code_attribute = (decodingFlags & IClassFileReader.METHOD_BODIES) == 0; - this.accessFlags = u2At(classFileBytes, 0, offset); + final int flags = u2At(classFileBytes, 0, offset); + this.accessFlags = flags; + if ((flags & IModifierConstants.ACC_SYNTHETIC) != 0) { + this.isSynthetic = true; + } this.nameIndex = u2At(classFileBytes, 2, offset); IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(this.nameIndex); @@ -98,6 +102,18 @@ public class MethodInfo extends ClassFileStruct implements IMethodInfo { } else if (equals(attributeName, IAttributeNamesConstants.EXCEPTIONS)) { this.exceptionAttribute = new ExceptionAttribute(classFileBytes, constantPool, offset + readOffset); this.attributes[attributesIndex++] = this.exceptionAttribute; + } else if (equals(attributeName, IAttributeNamesConstants.SIGNATURE)) { + this.attributes[attributesIndex++] = new SignatureAttribute(classFileBytes, constantPool, offset + readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_ANNOTATIONS)) { + this.attributes[attributesIndex++] = new RuntimeVisibleAnnotationsAttribute(classFileBytes, constantPool, readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_ANNOTATIONS)) { + this.attributes[attributesIndex++] = new RuntimeInvisibleAnnotationsAttribute(classFileBytes, constantPool, readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS)) { + this.attributes[attributesIndex++] = new RuntimeVisibleParameterAnnotationsAttribute(classFileBytes, constantPool, readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS)) { + this.attributes[attributesIndex++] = new RuntimeInvisibleParameterAnnotationsAttribute(classFileBytes, constantPool, readOffset); + } else if (equals(attributeName, IAttributeNamesConstants.ANNOTATION_DEFAULT)) { + this.attributes[attributesIndex++] = new AnnotationDefaultAttribute(classFileBytes, constantPool, readOffset); } else { this.attributes[attributesIndex++] = new ClassFileAttribute(classFileBytes, constantPool, offset + readOffset); } @@ -113,6 +129,19 @@ public class MethodInfo extends ClassFileStruct implements IMethodInfo { } /** + * @see IMethodInfo#getAttributeCount() + */ + public int getAttributeCount() { + return this.attributesCount; + } + /** + * @see IMethodInfo#getAttributes() + */ + public IClassFileAttribute[] getAttributes() { + return this.attributes; + } + + /** * @see IMethodInfo#getCodeAttribute() */ public ICodeAttribute getCodeAttribute() { @@ -127,6 +156,20 @@ public class MethodInfo extends ClassFileStruct implements IMethodInfo { } /** + * @see IMethodInfo#getDescriptorIndex() + */ + public int getDescriptorIndex() { + return this.descriptorIndex; + } + + /** + * @see IMethodInfo#getExceptionAttribute() + */ + public IExceptionAttribute getExceptionAttribute() { + return this.exceptionAttribute; + } + + /** * @see IMethodInfo#getName() */ public char[] getName() { @@ -134,6 +177,17 @@ public class MethodInfo extends ClassFileStruct implements IMethodInfo { } /** + * @see IMethodInfo#getNameIndex() + */ + public int getNameIndex() { + return this.nameIndex; + } + + private boolean isAbstract() { + return (this.accessFlags & IModifierConstants.ACC_ABSTRACT) != 0; + } + + /** * @see IMethodInfo#isClinit() */ public boolean isClinit() { @@ -153,6 +207,10 @@ public class MethodInfo extends ClassFileStruct implements IMethodInfo { public boolean isDeprecated() { return this.isDeprecated; } + + private boolean isNative() { + return (this.accessFlags & IModifierConstants.ACC_NATIVE) != 0; + } /** * @see IMethodInfo#isSynthetic() @@ -161,49 +219,7 @@ public class MethodInfo extends ClassFileStruct implements IMethodInfo { return this.isSynthetic; } - /** - * @see IMethodInfo#getExceptionAttribute() - */ - public IExceptionAttribute getExceptionAttribute() { - return this.exceptionAttribute; - } - - /** - * @see IMethodInfo#getAttributeCount() - */ - public int getAttributeCount() { - return this.attributesCount; - } - - /** - * @see IMethodInfo#getDescriptorIndex() - */ - public int getDescriptorIndex() { - return this.descriptorIndex; - } - - /** - * @see IMethodInfo#getNameIndex() - */ - public int getNameIndex() { - return this.nameIndex; - } - int sizeInBytes() { return this.attributeBytes; } - /** - * @see IMethodInfo#getAttributes() - */ - public IClassFileAttribute[] getAttributes() { - return this.attributes; - } - - private boolean isAbstract() { - return (this.accessFlags & IModifierConstants.ACC_ABSTRACT) != 0; - } - - private boolean isNative() { - return (this.accessFlags & IModifierConstants.ACC_NATIVE) != 0; - } } diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java new file mode 100644 index 0000000000..bcc0a02348 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/ParameterAnnotation.java @@ -0,0 +1,72 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IAnnotation; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IParameterAnnotation; + +/** + * Default implementation of IParameterAnnotation + */ +public class ParameterAnnotation extends ClassFileStruct implements IParameterAnnotation { + + private static final IAnnotation[] NO_ENTRIES = new IAnnotation[0]; + + private int annotationsNumber; + private IAnnotation[] annotations; + private int readOffset; + + /** + * Constructor for Annotation. + * + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public ParameterAnnotation( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) throws ClassFormatException { + + final int length = u2At(classFileBytes, 0, offset); + this.annotationsNumber = length; + if (length != 0) { + this.readOffset = 2; + this.annotations = new IAnnotation[length]; + for (int i = 0; i < length; i++) { + Annotation annotation = new Annotation(classFileBytes, constantPool, offset + readOffset); + this.annotations[i++] = annotation; + this.readOffset += annotation.sizeInBytes(); + } + } else { + this.annotations = NO_ENTRIES; + } + } + + int sizeInBytes() { + return this.readOffset; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IParameterAnnotation#getAnnotations() + */ + public IAnnotation[] getAnnotations() { + return this.annotations; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IParameterAnnotation#getAnnotationsNumber() + */ + public int getAnnotationsNumber() { + return this.annotationsNumber; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java new file mode 100644 index 0000000000..3644b28c52 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleAnnotationsAttribute.java @@ -0,0 +1,69 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IAnnotation; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IRuntimeInvisibleAnnotationsAttribute; + +/** + * Default implementation of IRuntimeInvisibleAnnotations + */ +public class RuntimeInvisibleAnnotationsAttribute + extends ClassFileAttribute + implements IRuntimeInvisibleAnnotationsAttribute { + + private static final IAnnotation[] NO_ENTRIES = new IAnnotation[0]; + private int annotationsNumber; + private IAnnotation[] annotations; + + /** + * Constructor for RuntimeInvisibleAnnotations. + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public RuntimeInvisibleAnnotationsAttribute( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) + throws ClassFormatException { + super(classFileBytes, constantPool, offset); + final int length = u2At(classFileBytes, 6, offset); + this.annotationsNumber = length; + if (length != 0) { + int readOffset = 8; + this.annotations = new IAnnotation[length]; + for (int i = 0; i < length; i++) { + Annotation annotation = new Annotation(classFileBytes, constantPool, offset + readOffset); + this.annotations[i] = annotation; + readOffset += annotation.sizeInBytes(); + } + } else { + this.annotations = NO_ENTRIES; + } + } + + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IRuntimeInvisibleAnnotations#getAnnotations() + */ + public IAnnotation[] getAnnotations() { + return this.annotations; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IRuntimeInvisibleAnnotations#getAnnotationsNumber() + */ + public int getAnnotationsNumber() { + return this.annotationsNumber; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java new file mode 100644 index 0000000000..def1d596f8 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeInvisibleParameterAnnotationsAttribute.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IParameterAnnotation; +import org.eclipse.jdt.core.util.IRuntimeInvisibleParameterAnnotationsAttribute; + +/** + * Default implementation of IRuntimeInvisibleParameterAnnotations + */ +public class RuntimeInvisibleParameterAnnotationsAttribute + extends ClassFileAttribute + implements IRuntimeInvisibleParameterAnnotationsAttribute { + + private static final IParameterAnnotation[] NO_ENTRIES = new IParameterAnnotation[0]; + private IParameterAnnotation[] parameterAnnotations; + private int parametersNumber; + + /** + * Constructor for RuntimeVisibleParameterAnnotations. + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public RuntimeInvisibleParameterAnnotationsAttribute( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) + throws ClassFormatException { + super(classFileBytes, constantPool, offset); + final int length = u1At(classFileBytes, 6, offset); + this.parametersNumber = length; + if (length != 0) { + int readOffset = 7; + this.parameterAnnotations = new IParameterAnnotation[length]; + for (int i = 0; i < length; i++) { + ParameterAnnotation parameterAnnotation = new ParameterAnnotation(classFileBytes, constantPool, offset + readOffset); + this.parameterAnnotations[i] = parameterAnnotation; + readOffset += parameterAnnotation.sizeInBytes(); + } + } else { + this.parameterAnnotations = NO_ENTRIES; + } + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IRuntimeInvisibleParameterAnnotations#getAnnotations() + */ + public IParameterAnnotation[] getParameterAnnotations() { + return this.parameterAnnotations; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IRuntimeInvisibleParameterAnnotations#getParametersNumber() + */ + public int getParametersNumber() { + return this.parametersNumber; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java new file mode 100644 index 0000000000..a56d40d5b4 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleAnnotationsAttribute.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IAnnotation; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IRuntimeVisibleAnnotationsAttribute; + +/** + * Default implementation of IRuntimeVisibleAnnotations + */ +public class RuntimeVisibleAnnotationsAttribute + extends ClassFileAttribute + implements IRuntimeVisibleAnnotationsAttribute { + + private static final IAnnotation[] NO_ENTRIES = new IAnnotation[0]; + private int annotationsNumber; + private IAnnotation[] annotations; + + /** + * Constructor for RuntimeVisibleAnnotations. + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public RuntimeVisibleAnnotationsAttribute( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) + throws ClassFormatException { + super(classFileBytes, constantPool, offset); + final int length = u2At(classFileBytes, 6, offset); + this.annotationsNumber = length; + if (length != 0) { + int readOffset = 8; + this.annotations = new IAnnotation[length]; + for (int i = 0; i < length; i++) { + Annotation annotation = new Annotation(classFileBytes, constantPool, offset + readOffset); + this.annotations[i] = annotation; + readOffset += annotation.sizeInBytes(); + } + } else { + this.annotations = NO_ENTRIES; + } + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IRuntimeVisibleAnnotations#getAnnotations() + */ + public IAnnotation[] getAnnotations() { + return this.annotations; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IRuntimeVisibleAnnotations#getAnnotationsNumber() + */ + public int getAnnotationsNumber() { + return this.annotationsNumber; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java new file mode 100644 index 0000000000..ec17be2570 --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/RuntimeVisibleParameterAnnotationsAttribute.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IParameterAnnotation; +import org.eclipse.jdt.core.util.IRuntimeVisibleParameterAnnotationsAttribute; + +/** + * Default implementation of IRuntimeVisibleAnnotations + */ +public class RuntimeVisibleParameterAnnotationsAttribute + extends ClassFileAttribute + implements IRuntimeVisibleParameterAnnotationsAttribute { + + private static final IParameterAnnotation[] NO_ENTRIES = new IParameterAnnotation[0]; + private int parametersNumber; + private IParameterAnnotation[] parameterAnnotations; + + /** + * Constructor for RuntimeVisibleParameterAnnotations. + * @param classFileBytes + * @param constantPool + * @param offset + * @throws ClassFormatException + */ + public RuntimeVisibleParameterAnnotationsAttribute( + byte[] classFileBytes, + IConstantPool constantPool, + int offset) + throws ClassFormatException { + super(classFileBytes, constantPool, offset); + final int length = u1At(classFileBytes, 6, offset); + this.parametersNumber = length; + if (length != 0) { + int readOffset = 7; + this.parameterAnnotations = new IParameterAnnotation[length]; + for (int i = 0; i < length; i++) { + ParameterAnnotation parameterAnnotation = new ParameterAnnotation(classFileBytes, constantPool, offset + readOffset); + this.parameterAnnotations[i] = parameterAnnotation; + readOffset += parameterAnnotation.sizeInBytes(); + } + } else { + this.parameterAnnotations = NO_ENTRIES; + } + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IRuntimeVisibleParameterAnnotations#getAnnotations() + */ + public IParameterAnnotation[] getParameterAnnotations() { + return this.parameterAnnotations; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.IRuntimeVisibleParameterAnnotations#getParametersNumber() + */ + public int getParametersNumber() { + return this.parametersNumber; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java new file mode 100644 index 0000000000..b04b091efe --- /dev/null +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SignatureAttribute.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.jdt.internal.core.util; + +import org.eclipse.jdt.core.util.ClassFormatException; +import org.eclipse.jdt.core.util.IConstantPool; +import org.eclipse.jdt.core.util.IConstantPoolConstant; +import org.eclipse.jdt.core.util.IConstantPoolEntry; +import org.eclipse.jdt.core.util.ISignatureAttribute; + +/** + * @since 3.0 + */ +public class SignatureAttribute extends ClassFileAttribute implements ISignatureAttribute { + + private int signatureIndex; + private char[] signature; + + SignatureAttribute(byte[] classFileBytes, IConstantPool constantPool, int offset) throws ClassFormatException { + super(classFileBytes, constantPool, offset); + final int index = u2At(classFileBytes, 6, offset); + this.signatureIndex = index; + IConstantPoolEntry constantPoolEntry = constantPool.decodeEntry(index); + if (constantPoolEntry.getKind() != IConstantPoolConstant.CONSTANT_Utf8) { + throw new ClassFormatException(ClassFormatException.INVALID_CONSTANT_POOL_ENTRY); + } + this.signature = constantPoolEntry.getUtf8Value(); + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.ISignatureAttribute#getSignatureIndex() + */ + public int getSignatureIndex() { + return this.signatureIndex; + } + /* (non-Javadoc) + * @see org.eclipse.jdt.core.util.ISignatureAttribute#getSignature() + */ + public char[] getSignature() { + return this.signature; + } +} diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java index 43d151ca41..1aa89da90d 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/SourceFileAttribute.java @@ -11,7 +11,6 @@ package org.eclipse.jdt.internal.core.util; import org.eclipse.jdt.core.util.ClassFormatException; -import org.eclipse.jdt.core.util.IAttributeNamesConstants; import org.eclipse.jdt.core.util.IConstantPool; import org.eclipse.jdt.core.util.IConstantPoolConstant; import org.eclipse.jdt.core.util.IConstantPoolEntry; @@ -47,14 +46,6 @@ public class SourceFileAttribute } this.sourceFileName = constantPoolEntry.getUtf8Value(); } - - /** - * @see org.eclipse.jdt.core.util.IClassFileAttribute#getAttributeName() - */ - public char[] getAttributeName() { - return IAttributeNamesConstants.SOURCE; - } - /** * @see ISourceAttribute#getSourceFileIndex() */ diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java index 58f671310c..2f8ef53a60 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/util/Util.java @@ -1675,7 +1675,7 @@ public class Util { * e.g. "QString;", "[int", "[[Qjava.util.Vector;" */ public static String typeSignature(TypeReference type) { - char[][] compoundName = type.getTypeName(); + char[][] compoundName = type.getParameterizedTypeName(); char[] typeName =CharOperation.concatWith(compoundName, '.'); String signature = Signature.createTypeSignature(typeName, false/*don't resolve*/); int dimensions = type.dimensions(); |