### Eclipse Workspace Patch 1.0 #P org.eclipse.jdt.core Index: model/org/eclipse/jdt/core/IMethod.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/core/IMethod.java,v retrieving revision 1.33 diff -u -r1.33 IMethod.java --- model/org/eclipse/jdt/core/IMethod.java 23 Apr 2010 13:11:05 -0000 1.33 +++ model/org/eclipse/jdt/core/IMethod.java 20 Feb 2011 22:26:41 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -100,6 +100,21 @@ * @return the number of parameters of this method */ int getNumberOfParameters(); + +/** + * Returns the parameters of this method. + *
An empty array is returned, if the method has no parameters.
+ *For binary types, associated source is used to retrieve the {@link ILocalVariable#getNameRange() name range}, + * {@link ILocalVariable#getSourceRange() source range} and the {@link ILocalVariable#getFlags() flags}.
+ *These local variables can be used to retrieve the {@link ILocalVariable#getAnnotations() parameter annotations}.
+ * + * @return the parameters of this method + * @throws JavaModelException if this element does not exist or if an + * exception occurs while accessing its corresponding resource. + * @since 3.7 + */ +ILocalVariable[] getParameters() throws JavaModelException; + /** * Returns the binding key for this method only if the given method is {@link #isResolved() resolved}. * A binding key is a key that uniquely identifies this method. It allows access Index: model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java,v retrieving revision 1.26 diff -u -r1.26 ISourceElementRequestor.java --- model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java 28 Jul 2010 16:17:03 -0000 1.26 +++ model/org/eclipse/jdt/internal/compiler/ISourceElementRequestor.java 20 Feb 2011 22:26:41 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -92,8 +92,17 @@ public int declaringTypeModifiers; public int extraFlags; public AbstractMethodDeclaration node; + public ParameterInfo[] parameterInfos; } + public static class ParameterInfo { + public int modifiers; + public int declarationStart; + public int declarationEnd; + public int nameSourceStart; + public int nameSourceEnd; + public char[] name; + } public static class FieldInfo { public int declarationStart; public int modifiers; Index: model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java,v retrieving revision 1.7 diff -u -r1.7 SourceElementNotifier.java --- model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java 28 Jul 2010 16:17:03 -0000 1.7 +++ model/org/eclipse/jdt/internal/compiler/SourceElementNotifier.java 20 Feb 2011 22:26:41 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 IBM Corporation and others. + * Copyright (c) 2008, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -14,6 +14,7 @@ import java.util.Map; import org.eclipse.jdt.core.compiler.CharOperation; +import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.ParameterInfo; import org.eclipse.jdt.internal.compiler.ISourceElementRequestor.TypeParameterInfo; import org.eclipse.jdt.internal.compiler.ast.ASTNode; import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; @@ -103,16 +104,27 @@ this.superTypeNames = new char[4][]; this.nestedTypeIndex = 0; } -protected char[][][] getArguments(Argument[] arguments) { +protected Object[][] getArgumentInfos(Argument[] arguments) { int argumentLength = arguments.length; char[][] argumentTypes = new char[argumentLength][]; char[][] argumentNames = new char[argumentLength][]; + ParameterInfo[] parameterInfos = new ParameterInfo[argumentLength]; for (int i = 0; i < argumentLength; i++) { - argumentTypes[i] = CharOperation.concatWith(arguments[i].type.getParameterizedTypeName(), '.'); - argumentNames[i] = arguments[i].name; + Argument argument = arguments[i]; + argumentTypes[i] = CharOperation.concatWith(argument.type.getParameterizedTypeName(), '.'); + char[] name = argument.name; + argumentNames[i] = name; + ParameterInfo parameterInfo = new ParameterInfo(); + parameterInfo.declarationStart = argument.declarationSourceStart; + parameterInfo.declarationEnd = argument.declarationSourceEnd; + parameterInfo.nameSourceStart = argument.sourceStart; + parameterInfo.nameSourceEnd = argument.sourceEnd; + parameterInfo.modifiers = argument.modifiers; + parameterInfo.name = name; + parameterInfos[i] = parameterInfo; } - return new char[][][] {argumentTypes, argumentNames}; + return new Object[][] { parameterInfos, new char[][][] { argumentTypes, argumentNames } }; } protected char[][] getInterfaceNames(TypeDeclaration typeDeclaration) { char[][] interfaceNames = null; @@ -256,10 +268,12 @@ char[][] argumentNames = null; boolean isVarArgs = false; Argument[] arguments = methodDeclaration.arguments; + ParameterInfo[] parameterInfos = null; if (arguments != null) { - char[][][] argumentTypesAndNames = getArguments(arguments); - argumentTypes = argumentTypesAndNames[0]; - argumentNames = argumentTypesAndNames[1]; + Object[][] argumentInfos = getArgumentInfos(arguments); + parameterInfos = (ParameterInfo[]) argumentInfos[0]; + argumentTypes = (char[][]) argumentInfos[1][0]; + argumentNames = (char[][]) argumentInfos[1][1]; isVarArgs = arguments[arguments.length-1].isVarArgs(); } @@ -287,6 +301,7 @@ methodInfo.parameterNames = argumentNames; methodInfo.exceptionTypes = thrownExceptionTypes; methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters()); + methodInfo.parameterInfos = parameterInfos; methodInfo.categories = (char[][]) this.nodesToCategories.get(methodDeclaration); methodInfo.annotations = methodDeclaration.annotations; methodInfo.declaringPackageName = currentPackage == null ? CharOperation.NO_CHAR : CharOperation.concatWith(currentPackage.tokens, '.'); @@ -346,6 +361,7 @@ methodInfo.parameterNames = argumentNames; methodInfo.exceptionTypes = thrownExceptionTypes; methodInfo.typeParameters = getTypeParameterInfos(methodDeclaration.typeParameters()); + methodInfo.parameterInfos = parameterInfos; methodInfo.categories = (char[][]) this.nodesToCategories.get(methodDeclaration); methodInfo.annotations = methodDeclaration.annotations; methodInfo.node = methodDeclaration; Index: model/org/eclipse/jdt/internal/core/BinaryMember.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMember.java,v retrieving revision 1.36 diff -u -r1.36 BinaryMember.java --- model/org/eclipse/jdt/internal/core/BinaryMember.java 28 Apr 2009 16:53:01 -0000 1.36 +++ model/org/eclipse/jdt/internal/core/BinaryMember.java 20 Feb 2011 22:26:41 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -47,7 +47,11 @@ return standardAnnotations; int length = binaryAnnotations.length; int standardLength = standardAnnotations.length; - IAnnotation[] annotations = new IAnnotation[length + standardLength]; + int fullLength = length + standardLength; + if (fullLength == 0) { + return Annotation.NO_ANNOTATIONS; + } + IAnnotation[] annotations = new IAnnotation[fullLength]; for (int i = 0; i < length; i++) { annotations[i] = Util.getAnnotation(this, binaryAnnotations[i], null); } @@ -57,7 +61,7 @@ private IAnnotation getAnnotation(char[][] annotationName) { return new Annotation(this, new String(CharOperation.concatWith(annotationName, '.'))); } -private IAnnotation[] getStandardAnnotations(long tagBits) { +protected IAnnotation[] getStandardAnnotations(long tagBits) { if ((tagBits & TagBits.AllStandardAnnotationsMask) == 0) return Annotation.NO_ANNOTATIONS; ArrayList annotations = new ArrayList(); Index: model/org/eclipse/jdt/internal/core/BinaryMethod.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java,v retrieving revision 1.111 diff -u -r1.111 BinaryMethod.java --- model/org/eclipse/jdt/internal/core/BinaryMethod.java 20 Jan 2011 02:28:43 -0000 1.111 +++ model/org/eclipse/jdt/internal/core/BinaryMethod.java 20 Feb 2011 22:26:41 -0000 @@ -11,7 +11,16 @@ package org.eclipse.jdt.internal.core; import org.eclipse.core.runtime.IProgressMonitor; -import org.eclipse.jdt.core.*; +import org.eclipse.jdt.core.Flags; +import org.eclipse.jdt.core.IAnnotation; +import org.eclipse.jdt.core.ILocalVariable; +import org.eclipse.jdt.core.IMemberValuePair; +import org.eclipse.jdt.core.IMethod; +import org.eclipse.jdt.core.IType; +import org.eclipse.jdt.core.ITypeParameter; +import org.eclipse.jdt.core.JavaCore; +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.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation; @@ -61,6 +70,51 @@ IBinaryAnnotation[] binaryAnnotations = info.getAnnotations(); return getAnnotations(binaryAnnotations, info.getTagBits()); } +public ILocalVariable[] getParameters() throws JavaModelException { + IBinaryMethod info = (IBinaryMethod) getElementInfo(); + int length = this.parameterTypes.length; + if (length == 0) { + return LocalVariable.NO_LOCAL_VARIABLES; + } + ILocalVariable[] localVariables = new ILocalVariable[length]; + char[][] argumentNames = info.getArgumentNames(); + if (argumentNames == null || argumentNames.length < length) { + argumentNames = new char[length][]; + for (int j = 0; j < length; j++) { + argumentNames[j] = ("arg" + j).toCharArray(); //$NON-NLS-1$ + } + } + for (int i= 0; i < length; i++) { + LocalVariable localVariable = new LocalVariable( + this, + new String(argumentNames[i]), + 0, + -1, + 0, + -1, + this.parameterTypes[i], + null, + -1, + true); + localVariables[i] = localVariable; + IAnnotation[] annotations = getAnnotations(localVariable, info.getParameterAnnotations(i), info.getTagBits()); + localVariable.annotations = annotations; + } + return localVariables; +} +private IAnnotation[] getAnnotations(JavaElement annotationParent, IBinaryAnnotation[] binaryAnnotations, long tagBits) { + IAnnotation[] standardAnnotations = getStandardAnnotations(tagBits); + if (binaryAnnotations == null) + return standardAnnotations; + int length = binaryAnnotations.length; + int standardLength = standardAnnotations.length; + IAnnotation[] annotations = new IAnnotation[length + standardLength]; + for (int i = 0; i < length; i++) { + annotations[i] = Util.getAnnotation(annotationParent, binaryAnnotations[i], null); + } + System.arraycopy(standardAnnotations, 0, annotations, length, standardLength); + return annotations; +} public IMemberValuePair getDefaultValue() throws JavaModelException { IBinaryMethod info = (IBinaryMethod) getElementInfo(); Object defaultValue = info.getDefaultValue(); Index: model/org/eclipse/jdt/internal/core/ClassFileInfo.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ClassFileInfo.java,v retrieving revision 1.49 diff -u -r1.49 ClassFileInfo.java --- model/org/eclipse/jdt/internal/core/ClassFileInfo.java 3 Sep 2010 15:20:03 -0000 1.49 +++ model/org/eclipse/jdt/internal/core/ClassFileInfo.java 20 Feb 2011 22:26:41 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -41,23 +41,26 @@ */ protected ITypeParameter[] typeParameters; +private void generateAnnotationsInfos(JavaElement member, IBinaryAnnotation[] binaryAnnotations, long tagBits, HashMap newElements) { + generateAnnotationsInfos(member, null, binaryAnnotations, tagBits, newElements); +} /** * Creates the handles and infos for the annotations of the given binary member. * Adds new handles to the given vector. */ -private void generateAnnotationsInfos(BinaryMember member, IBinaryAnnotation[] binaryAnnotations, long tagBits, HashMap newElements) { +private void generateAnnotationsInfos(JavaElement member, char[] parameterName, IBinaryAnnotation[] binaryAnnotations, long tagBits, HashMap newElements) { if (binaryAnnotations != null) { for (int i = 0, length = binaryAnnotations.length; i < length; i++) { IBinaryAnnotation annotationInfo = binaryAnnotations[i]; - generateAnnotationInfo(member, newElements, annotationInfo); + generateAnnotationInfo(member, parameterName, newElements, annotationInfo, null); } } - generateStandardAnnotationsInfos(member, tagBits, newElements); -} -private void generateAnnotationInfo(JavaElement parent, HashMap newElements, IBinaryAnnotation annotationInfo) { - generateAnnotationInfo(parent, newElements, annotationInfo, null); + generateStandardAnnotationsInfos(member, parameterName, tagBits, newElements); } private void generateAnnotationInfo(JavaElement parent, HashMap newElements, IBinaryAnnotation annotationInfo, String memberValuePairName) { + generateAnnotationInfo(parent, null, newElements, annotationInfo, memberValuePairName); +} +private void generateAnnotationInfo(JavaElement parent, char[] parameterName, HashMap newElements, IBinaryAnnotation annotationInfo, String memberValuePairName) { char[] typeName = org.eclipse.jdt.core.Signature.toCharArray(CharOperation.replaceOnCopy(annotationInfo.getTypeName(), '/', '.')); Annotation annotation = new Annotation(parent, new String(typeName), memberValuePairName); while (newElements.containsKey(annotation)) { @@ -81,29 +84,29 @@ } } } -private void generateStandardAnnotationsInfos(BinaryMember member, long tagBits, HashMap newElements) { +private void generateStandardAnnotationsInfos(JavaElement javaElement, char[] parameterName, long tagBits, HashMap newElements) { if ((tagBits & TagBits.AllStandardAnnotationsMask) == 0) return; if ((tagBits & TagBits.AnnotationTargetMASK) != 0) { - generateStandardAnnotation(member, TypeConstants.JAVA_LANG_ANNOTATION_TARGET, getTargetElementTypes(tagBits), newElements); + generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_ANNOTATION_TARGET, getTargetElementTypes(tagBits), newElements); } if ((tagBits & TagBits.AnnotationRetentionMASK) != 0) { - generateStandardAnnotation(member, TypeConstants.JAVA_LANG_ANNOTATION_RETENTION, getRetentionPolicy(tagBits), newElements); + generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_ANNOTATION_RETENTION, getRetentionPolicy(tagBits), newElements); } if ((tagBits & TagBits.AnnotationDeprecated) != 0) { - generateStandardAnnotation(member, TypeConstants.JAVA_LANG_DEPRECATED, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); + generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_DEPRECATED, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); } if ((tagBits & TagBits.AnnotationDocumented) != 0) { - generateStandardAnnotation(member, TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); + generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_ANNOTATION_DOCUMENTED, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); } if ((tagBits & TagBits.AnnotationInherited) != 0) { - generateStandardAnnotation(member, TypeConstants.JAVA_LANG_ANNOTATION_INHERITED, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); + generateStandardAnnotation(javaElement, TypeConstants.JAVA_LANG_ANNOTATION_INHERITED, Annotation.NO_MEMBER_VALUE_PAIRS, newElements); } // note that JAVA_LANG_SUPPRESSWARNINGS and JAVA_LANG_OVERRIDE cannot appear in binaries } -private void generateStandardAnnotation(BinaryMember member, char[][] typeName, IMemberValuePair[] members, HashMap newElements) { - IAnnotation annotation = new Annotation(member, new String(CharOperation.concatWith(typeName, '.'))); +private void generateStandardAnnotation(JavaElement javaElement, char[][] typeName, IMemberValuePair[] members, HashMap newElements) { + IAnnotation annotation = new Annotation(javaElement, new String(CharOperation.concatWith(typeName, '.'))); AnnotationInfo annotationInfo = new AnnotationInfo(); annotationInfo.members = members; newElements.put(annotation, annotationInfo); @@ -268,7 +271,7 @@ final String[] parameterTypes = Signature.getParameterTypes(new String(descriptor)); pNames[0] = parameterTypes[0]; } - }catch (IllegalArgumentException e) { + } 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)); @@ -290,13 +293,38 @@ BinaryMethod method = new BinaryMethod((JavaElement)type, selector, pNames); childrenHandles.add(method); - // ensure that 2 binary methods with the same signature but with different return types have different occurence counts. + // ensure that 2 binary methods with the same signature but with different return types have different occurrence counts. // (case of bridge methods in 1.5) while (newElements.containsKey(method)) method.occurrenceCount++; newElements.put(method, methodInfo); + int max = pNames.length; + char[][] argumentNames = methodInfo.getArgumentNames(); + if (argumentNames == null || argumentNames.length < max) { + argumentNames = new char[max][]; + for (int j = 0; j < max; j++) { + argumentNames[j] = ("arg" + j).toCharArray(); //$NON-NLS-1$ + } + } + for (int j = 0; j < max; j++) { + IBinaryAnnotation[] parameterAnnotations = methodInfo.getParameterAnnotations(j); + if (parameterAnnotations != null) { + LocalVariable localVariable = new LocalVariable( + method, + new String(argumentNames[j]), + 0, + -1, + 0, + -1, + method.parameterTypes[j], + null, + -1, + true); + generateAnnotationsInfos(localVariable, argumentNames[j], parameterAnnotations, methodInfo.getTagBits(), newElements); + } + } generateTypeParameterInfos(method, signature, newElements, typeParameterHandles); generateAnnotationsInfos(method, methodInfo.getAnnotations(), methodInfo.getTagBits(), newElements); Object defaultValue = methodInfo.getDefaultValue(); Index: model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java,v retrieving revision 1.87 diff -u -r1.87 CompilationUnitStructureRequestor.java --- model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java 28 Jul 2010 16:17:01 -0000 1.87 +++ model/org/eclipse/jdt/internal/core/CompilationUnitStructureRequestor.java 20 Feb 2011 22:26:41 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -17,11 +17,19 @@ import java.util.Stack; import org.eclipse.core.runtime.Assert; -import org.eclipse.jdt.core.*; +import org.eclipse.jdt.core.Flags; +import org.eclipse.jdt.core.IAnnotation; +import org.eclipse.jdt.core.ICompilationUnit; +import org.eclipse.jdt.core.IJavaElement; +import org.eclipse.jdt.core.IMemberValuePair; +import org.eclipse.jdt.core.ITypeParameter; +import org.eclipse.jdt.core.Signature; import org.eclipse.jdt.core.compiler.CategorizedProblem; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.compiler.IProblem; import org.eclipse.jdt.internal.compiler.ISourceElementRequestor; +import org.eclipse.jdt.internal.compiler.ast.ASTNode; +import org.eclipse.jdt.internal.compiler.ast.Argument; import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer; import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess; import org.eclipse.jdt.internal.compiler.ast.Expression; @@ -39,7 +47,6 @@ import org.eclipse.jdt.internal.compiler.util.HashtableOfObjectToInt; import org.eclipse.jdt.internal.core.util.ReferenceInfoAdapter; import org.eclipse.jdt.internal.core.util.Util; -import org.eclipse.jdt.internal.compiler.ast.ASTNode; /** * A requestor for the fuzzy parser, used to compute the children of an ICompilationUnit. */ @@ -427,8 +434,53 @@ acceptAnnotation(annotation, info, handle); } } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783 + // Process the parameter annotations from the arguments + if (methodInfo.node != null && methodInfo.node.arguments != null) { + info.arguments = acceptMethodParameters(methodInfo.node.arguments, handle, methodInfo); + } return info; } +private LocalVariable[] acceptMethodParameters(Argument[] arguments, JavaElement methodHandle, MethodInfo methodInfo) { + if (arguments == null) return null; + LocalVariable[] result = new LocalVariable[arguments.length]; + Annotation[][] paramAnnotations = new Annotation[arguments.length][]; + for(int i = 0; i < arguments.length; i++) { + Argument argument = arguments[i]; + AnnotatableInfo localVarInfo = new AnnotatableInfo(); + localVarInfo.setSourceRangeStart(argument.declarationSourceStart); + localVarInfo.setSourceRangeEnd(argument.declarationSourceStart); + localVarInfo.setNameSourceStart(argument.sourceStart); + localVarInfo.setNameSourceEnd(argument.sourceEnd); + + String paramTypeSig = JavaModelManager.getJavaModelManager().intern(Signature.createTypeSignature(methodInfo.parameterTypes[i], false)); + result[i] = new LocalVariable( + methodHandle, + new String(argument.name), + argument.declarationSourceStart, + argument.declarationSourceEnd, + argument.sourceStart, + argument.sourceEnd, + paramTypeSig, + argument.annotations, + argument.modifiers, + true); + this.newElements.put(result[i], localVarInfo); + this.infoStack.push(localVarInfo); + this.handleStack.push(result[i]); + if (argument.annotations != null) { + paramAnnotations[i] = new Annotation[argument.annotations.length]; + for (int j = 0; j < argument.annotations.length; j++ ) { + org.eclipse.jdt.internal.compiler.ast.Annotation annotation = argument.annotations[j]; + acceptAnnotation(annotation, localVarInfo, result[i]); + } + } + this.infoStack.pop(); + this.handleStack.pop(); + } + return result; +} + /** * @see ISourceElementRequestor */ Index: model/org/eclipse/jdt/internal/core/LocalVariable.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/LocalVariable.java,v retrieving revision 1.31 diff -u -r1.31 LocalVariable.java --- model/org/eclipse/jdt/internal/core/LocalVariable.java 7 Sep 2010 19:14:26 -0000 1.31 +++ model/org/eclipse/jdt/internal/core/LocalVariable.java 20 Feb 2011 22:26:42 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -34,6 +34,8 @@ public class LocalVariable extends SourceRefElement implements ILocalVariable { + public static final ILocalVariable[] NO_LOCAL_VARIABLES = new ILocalVariable[0]; + String name; public int declarationSourceStart, declarationSourceEnd; public int nameStart, nameEnd; @@ -288,10 +290,59 @@ * @since 3.7 */ public int getFlags() { + if (this.flags == -1) { + SourceMapper mapper= getSourceMapper(); + if (mapper != null) { + try { + // ensure the class file's buffer is open so that source ranges are computed + ClassFile classFile = (ClassFile)getClassFile(); + if (classFile != null) { + classFile.getBuffer(); + return mapper.getFlags(this); + } + } catch(JavaModelException e) { + // ignore + } + } + return 0; + } return this.flags; } + /** + * @see IMember#getClassFile() + */ + public IClassFile getClassFile() { + IJavaElement element = getParent(); + while (element instanceof IMember) { + element= element.getParent(); + } + if (element instanceof IClassFile) { + return (IClassFile) element; + } + return null; + } + /** + * {@inheritDoc} + * @since 3.7 + */ public ISourceRange getNameRange() { + if (this.nameEnd == -1) { + SourceMapper mapper= getSourceMapper(); + if (mapper != null) { + try { + // ensure the class file's buffer is open so that source ranges are computed + ClassFile classFile = (ClassFile)getClassFile(); + if (classFile != null) { + classFile.getBuffer(); + return mapper.getNameRange(this); + } + } catch(JavaModelException e) { + // ignore + } + } + return SourceMapper.UNKNOWN_RANGE; + } return new SourceRange(this.nameStart, this.nameEnd-this.nameStart+1); } @@ -326,9 +377,22 @@ } /** - * @see ISourceReference + * {@inheritDoc} + * @since 3.7 */ - public ISourceRange getSourceRange() { + public ISourceRange getSourceRange() throws JavaModelException { + if (this.declarationSourceEnd == -1) { + SourceMapper mapper= getSourceMapper(); + if (mapper != null) { + // ensure the class file's buffer is open so that source ranges are computed + ClassFile classFile = (ClassFile)getClassFile(); + if (classFile != null) { + classFile.getBuffer(); + return mapper.getSourceRange(this); + } + } + return SourceMapper.UNKNOWN_RANGE; + } return new SourceRange(this.declarationSourceStart, this.declarationSourceEnd-this.declarationSourceStart+1); } Index: model/org/eclipse/jdt/internal/core/SourceMapper.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMapper.java,v retrieving revision 1.151 diff -u -r1.151 SourceMapper.java --- model/org/eclipse/jdt/internal/core/SourceMapper.java 22 Oct 2010 10:48:10 -0000 1.151 +++ model/org/eclipse/jdt/internal/core/SourceMapper.java 20 Feb 2011 22:26:42 -0000 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -76,6 +76,66 @@ extends ReferenceInfoAdapter implements ISourceElementRequestor, SuffixConstants { + public static class LocalVariableElementKey { + String parent; + String name; + + public LocalVariableElementKey(IJavaElement method, String name) { + StringBuffer buffer = new StringBuffer(); + buffer + .append(method.getParent().getHandleIdentifier()) + .append('#') + .append(method.getElementName()) + .append('('); + if (method.getElementType() == IJavaElement.METHOD) { + String[] parameterTypes = ((IMethod) method).getParameterTypes(); + for (int i = 0, max = parameterTypes.length; i < max; i++) { + if (i > 0) { + buffer.append(','); + } + buffer.append(Signature.getSignatureSimpleName(parameterTypes[i])); + } + } + buffer.append(')'); + this.parent = String.valueOf(buffer); + this.name = name; + } + + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((this.name == null) ? 0 : this.name.hashCode()); + result = prime * result + ((this.parent == null) ? 0 : this.parent.hashCode()); + return result; + } + + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + LocalVariableElementKey other = (LocalVariableElementKey) obj; + if (this.name == null) { + if (other.name != null) + return false; + } else if (!this.name.equals(other.name)) + return false; + if (this.parent == null) { + if (other.parent != null) + return false; + } else if (!this.parent.equals(other.parent)) + return false; + return true; + } + public String toString() { + StringBuffer buffer = new StringBuffer(); + buffer.append('(').append(this.parent).append('.').append(this.name).append(')'); + return String.valueOf(buffer); + } + } + public static boolean VERBOSE = false; /** * Specifies the location of the package fragment roots within @@ -119,6 +179,16 @@ */ protected HashMap categories; + /** + * Table that contains all source ranges for local variables. + * Keys are the special local variable elements, entries arechar[][]
.
+ */
+ protected HashMap parametersRanges;
+
+ /**
+ * Set that contains all final local variables.
+ */
+ protected HashSet finalParameters;
/**
* The unknown source range {-1, 0}
@@ -209,6 +279,7 @@
}
this.sourcePath = sourcePath;
this.sourceRanges = new HashMap();
+ this.parametersRanges = new HashMap();
this.parameterNames = new HashMap();
this.importsTable = new HashMap();
this.importsCounterTable = new HashMap();
@@ -288,6 +359,8 @@
public void close() {
this.sourceRanges = null;
this.parameterNames = null;
+ this.parametersRanges = null;
+ this.finalParameters = null;
}
/**
@@ -751,6 +824,30 @@
typeParameterInfo.nameSourceEnd - typeParameterInfo.nameSourceStart + 1));
}
}
+ // parameters infos
+ if (methodInfo.parameterInfos != null) {
+ for (int i = 0, length = methodInfo.parameterInfos.length; i < length; i++) {
+ ParameterInfo parameterInfo = methodInfo.parameterInfos[i];
+ LocalVariableElementKey key = new LocalVariableElementKey(method, new String(parameterInfo.name));
+ SourceRange[] allRanges = new SourceRange[] {
+ new SourceRange(
+ parameterInfo.declarationStart,
+ parameterInfo.declarationEnd - parameterInfo.declarationStart + 1),
+ new SourceRange(
+ parameterInfo.nameSourceStart,
+ parameterInfo.nameSourceEnd - parameterInfo.nameSourceStart + 1)
+ };
+ this.parametersRanges.put(
+ key,
+ allRanges);
+ if (parameterInfo.modifiers != 0) {
+ if (this.finalParameters == null) {
+ this.finalParameters = new HashSet();
+ }
+ this.finalParameters.add(key);
+ }
+ }
+ }
// categories
addCategories(method, methodInfo.categories);
@@ -959,6 +1056,16 @@
}
+ public int getFlags(IJavaElement element) {
+ switch(element.getElementType()) {
+ case IJavaElement.LOCAL_VARIABLE :
+ LocalVariableElementKey key = new LocalVariableElementKey(element.getParent(), element.getElementName());
+ if (this.finalParameters != null && this.finalParameters.contains(key)) {
+ return Flags.AccFinal;
+ }
+ }
+ return 0;
+ }
/**
* Returns the SourceRange for the name of the given element, or
@@ -990,6 +1097,15 @@
element = method.getTypeParameter(element.getElementName());
}
}
+ break;
+ case IJavaElement.LOCAL_VARIABLE :
+ LocalVariableElementKey key = new LocalVariableElementKey(element.getParent(), element.getElementName());
+ SourceRange[] ranges = (SourceRange[]) this.parametersRanges.get(key);
+ if (ranges == null) {
+ return UNKNOWN_RANGE;
+ } else {
+ return ranges[1];
+ }
}
SourceRange[] ranges = (SourceRange[]) this.sourceRanges.get(element);
if (ranges == null) {
@@ -1050,6 +1166,15 @@
element = method.getTypeParameter(element.getElementName());
}
}
+ break;
+ case IJavaElement.LOCAL_VARIABLE :
+ LocalVariableElementKey key = new LocalVariableElementKey(element.getParent(), element.getElementName());
+ SourceRange[] ranges = (SourceRange[]) this.parametersRanges.get(key);
+ if (ranges == null) {
+ return UNKNOWN_RANGE;
+ } else {
+ return ranges[0];
+ }
}
SourceRange[] ranges = (SourceRange[]) this.sourceRanges.get(element);
if (ranges == null) {
Index: model/org/eclipse/jdt/internal/core/SourceMethod.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethod.java,v
retrieving revision 1.68
diff -u -r1.68 SourceMethod.java
--- model/org/eclipse/jdt/internal/core/SourceMethod.java 27 Jun 2008 16:03:51 -0000 1.68
+++ model/org/eclipse/jdt/internal/core/SourceMethod.java 20 Feb 2011 22:26:42 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -134,7 +134,12 @@
SourceMethodElementInfo info = (SourceMethodElementInfo) getElementInfo();
return info.typeParameters;
}
-
+public ILocalVariable[] getParameters() throws JavaModelException {
+ ILocalVariable[] arguments = ((SourceMethodElementInfo) getElementInfo()).arguments;
+ if (arguments == null)
+ return LocalVariable.NO_LOCAL_VARIABLES;
+ return arguments;
+}
/**
* @see IMethod#getTypeParameterSignatures()
* @since 3.0
Index: model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java,v
retrieving revision 1.22
diff -u -r1.22 SourceMethodElementInfo.java
--- model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java 27 Jun 2008 16:03:50 -0000 1.22
+++ model/org/eclipse/jdt/internal/core/SourceMethodElementInfo.java 20 Feb 2011 22:26:42 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -38,6 +38,8 @@
* For example, Hashtable or java.util.Hashtable.
*/
protected char[][] exceptionTypes;
+
+ protected ILocalVariable[] arguments;
/*
* The type parameters of this source type. Empty if none.
#P org.eclipse.jdt.core.tests.compiler
Index: src/org/eclipse/jdt/core/tests/util/Util.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.compiler/src/org/eclipse/jdt/core/tests/util/Util.java,v
retrieving revision 1.82
diff -u -r1.82 Util.java
--- src/org/eclipse/jdt/core/tests/util/Util.java 25 Oct 2010 10:30:15 -0000 1.82
+++ src/org/eclipse/jdt/core/tests/util/Util.java 20 Feb 2011 22:26:43 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -382,7 +382,9 @@
}
public static void createJar(String[] javaPathsAndContents, String[] extraPathsAndContents, String jarPath, String[] classpath, String compliance, Map options) throws IOException {
Map compileOptions = getCompileOptions(compliance);
- compileOptions.putAll(options);
+ if (options != null) {
+ compileOptions.putAll(options);
+ }
createJar(javaPathsAndContents, extraPathsAndContents, compileOptions, classpath, jarPath);
}
public static void createSourceZip(String[] pathsAndContents, String zipPath) throws IOException {
#P org.eclipse.jdt.core.tests.model
Index: src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java,v
retrieving revision 1.242
diff -u -r1.242 AbstractJavaModelTests.java
--- src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 6 Oct 2010 17:32:30 -0000 1.242
+++ src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java 20 Feb 2011 22:26:45 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -402,16 +402,28 @@
addLibraryEntry(javaProject, new Path(jarPath), true/*exported*/);
}
protected void addLibrary(String jarName, String sourceZipName, String[] pathAndContents, String compliance) throws CoreException, IOException {
- addLibrary(this.currentProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance);
+ addLibrary(this.currentProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, null);
+ }
+ protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance, Map options) throws CoreException, IOException {
+ addLibrary(javaProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, options);
}
protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance) throws CoreException, IOException {
- addLibrary(javaProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance);
+ addLibrary(javaProject, jarName, sourceZipName, pathAndContents, null/*no non-Java resources*/, null, null, compliance, null);
}
protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String compliance) throws CoreException, IOException {
- addLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, null, null, compliance);
+ addLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, null, null, compliance, null);
}
- protected void addLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String[] librariesInclusionPatterns, String[] librariesExclusionPatterns, String compliance) throws CoreException, IOException {
- IProject project = createLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, compliance);
+ protected void addLibrary(
+ IJavaProject javaProject,
+ String jarName,
+ String sourceZipName,
+ String[] pathAndContents,
+ String[] nonJavaResources,
+ String[] librariesInclusionPatterns,
+ String[] librariesExclusionPatterns,
+ String compliance,
+ Map options) throws CoreException, IOException {
+ IProject project = createLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, compliance, options);
String projectPath = '/' + project.getName() + '/';
addLibraryEntry(
javaProject,
@@ -423,13 +435,29 @@
true
);
}
-
- protected IProject createLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String[] nonJavaResources, String compliance) throws IOException, CoreException {
+ protected IProject createLibrary(
+ IJavaProject javaProject,
+ String jarName,
+ String sourceZipName,
+ String[] pathAndContents,
+ String[] nonJavaResources,
+ String compliance) throws IOException, CoreException {
+ return createLibrary(javaProject, jarName, sourceZipName, pathAndContents, nonJavaResources, compliance, null);
+ }
+
+ protected IProject createLibrary(
+ IJavaProject javaProject,
+ String jarName,
+ String sourceZipName,
+ String[] pathAndContents,
+ String[] nonJavaResources,
+ String compliance,
+ Map options) throws IOException, CoreException {
IProject project = javaProject.getProject();
String projectLocation = project.getLocation().toOSString();
String jarPath = projectLocation + File.separator + jarName;
String[] claspath = get15LibraryIfNeeded(compliance);
- org.eclipse.jdt.core.tests.util.Util.createJar(pathAndContents, nonJavaResources, jarPath, claspath, compliance);
+ org.eclipse.jdt.core.tests.util.Util.createJar(pathAndContents, nonJavaResources, jarPath, claspath, compliance, options);
if (pathAndContents != null && pathAndContents.length != 0) {
String sourceZipPath = projectLocation + File.separator + sourceZipName;
org.eclipse.jdt.core.tests.util.Util.createSourceZip(pathAndContents, sourceZipPath);
@@ -1159,6 +1187,10 @@
org.eclipse.jdt.core.tests.util.Util.createJar(javaPathsAndContents, null,jarPath, classpath, compliance);
}
+ protected void createJar(String[] javaPathsAndContents, String jarPath, String[] classpath, String compliance, Map options) throws IOException {
+ org.eclipse.jdt.core.tests.util.Util.createJar(javaPathsAndContents, null, jarPath, classpath, compliance, options);
+ }
+
/*
}
* Creates a Java project where prj=src=bin and with JCL_LIB on its classpath.
Index: src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java,v
retrieving revision 1.164
diff -u -r1.164 ReconcilerTests.java
--- src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java 3 Dec 2010 08:44:31 -0000 1.164
+++ src/org/eclipse/jdt/core/tests/model/ReconcilerTests.java 20 Feb 2011 22:26:46 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2010 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -356,7 +356,8 @@
"**/*"
},
null,
- "1.4"
+ "1.4",
+ null
);
createJavaProject("P2", new String[] {"src"}, new String[] {"JCL_LIB"}, new String[] {"/P1"}, "bin");
setUpWorkingCopy("/P2/src/Y.java", "public class Y extends p.X {}");
Index: src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java
===================================================================
RCS file: /cvsroot/eclipse/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java,v
retrieving revision 1.14
diff -u -r1.14 TypeResolveTests.java
--- src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java 27 Jun 2008 16:02:40 -0000 1.14
+++ src/org/eclipse/jdt/core/tests/model/TypeResolveTests.java 20 Feb 2011 22:26:46 -0000
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,12 +10,30 @@
*******************************************************************************/
package org.eclipse.jdt.core.tests.model;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.jdt.core.*;
-import org.eclipse.jdt.core.tests.util.Util;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
import junit.framework.Test;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.IAnnotation;
+import org.eclipse.jdt.core.ICodeAssist;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.ILocalVariable;
+import org.eclipse.jdt.core.IMemberValuePair;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IPackageFragmentRoot;
+import org.eclipse.jdt.core.ISourceRange;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.tests.util.Util;
+import org.eclipse.jdt.internal.core.LocalVariable;
+
public class TypeResolveTests extends ModifyingResourceTests {
ICompilationUnit cu;
public TypeResolveTests(String name) {
@@ -95,7 +113,7 @@
}
static {
// TESTS_NUMBERS = new int[] { 182, 183 };
-// TESTS_NAMES = new String[] {"test0177"};
+// TESTS_NAMES = new String[] { "testParamAnnotations4" };
}
public static Test suite() {
return buildModelTestSuite(TypeResolveTests.class);
@@ -299,4 +317,387 @@
"p4.A.Inner",
types);
}
+/**
+ * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783"
+ */
+public void testParamAnnotations() throws CoreException {
+ try {
+ createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5");
+ String source = "package p;\n" +
+ "public class X