### 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 16 Feb 2011 20:26:51 -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,18 @@ * @return the number of parameters of this method */ int getNumberOfParameters(); + +/** + * Returns a two-dimensional array of annotations for this method's parameters. + *
An empty array is returned, if the method has no parameters.
+ *If a specific parameter has no annotations, an empty array is returned.
+ * + * @return the array of annotations for the specified parameter + * @throws JavaModelException + * @since 3.7 + */ +IAnnotation[][] getParameterAnnotations() 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/core/Annotation.java =================================================================== RCS file: /cvsroot/eclipse/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/Annotation.java,v retrieving revision 1.7 diff -u -r1.7 Annotation.java --- model/org/eclipse/jdt/internal/core/Annotation.java 8 Jul 2009 06:32:33 -0000 1.7 +++ model/org/eclipse/jdt/internal/core/Annotation.java 16 Feb 2011 20:26:51 -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 @@ -17,6 +17,7 @@ import org.eclipse.jdt.core.ISourceRange; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.SourceRange; +import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation; import org.eclipse.jdt.internal.compiler.env.IBinaryElementValuePair; import org.eclipse.jdt.internal.core.util.Util; @@ -24,19 +25,27 @@ public class Annotation extends SourceRefElement implements IAnnotation { public static final IAnnotation[] NO_ANNOTATIONS = new IAnnotation[0]; + public static final IAnnotation[][] NO_PARAMETER_ANNOTATIONS = new IAnnotation[0][0]; public static final IMemberValuePair[] NO_MEMBER_VALUE_PAIRS = new IMemberValuePair[0]; protected String name; // require to distinguish same annotations in different member value pairs protected String memberValuePairName; + protected char[] argumentName; + public Annotation(JavaElement parent, String name) { this(parent, name, null); } public Annotation(JavaElement parent, String name, String memberValuePairName) { + this(parent, null, name, memberValuePairName); + } + + public Annotation(JavaElement parent, char[] argumentName, String name, String memberValuePairName) { super(parent); this.name = name; + this.argumentName = argumentName; this.memberValuePairName = memberValuePairName; } @@ -45,6 +54,13 @@ return false; } Annotation other = (Annotation) o; + if (this.argumentName == null) { + if (other.argumentName != null) { + return false; + } + } else if (!CharOperation.equals(this.argumentName, other.argumentName)) { + return false; + } if (this.memberValuePairName == null) { if (other.memberValuePairName != null) return false; @@ -129,6 +145,7 @@ final int prime = 31; int result = super.hashCode(); result = prime * result + ((this.memberValuePairName == null) ? 0 : this.memberValuePairName.hashCode()); + result = prime * result + ((this.argumentName == null) ? 0 : CharOperation.hashCode(this.argumentName)); result = prime * result + this.name.hashCode(); return result; } 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 16 Feb 2011 20:26:51 -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,9 +47,13 @@ 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); + annotations[i] = Util.getAnnotation(this, null, binaryAnnotations[i], null); } System.arraycopy(standardAnnotations, 0, annotations, length, standardLength); return annotations; @@ -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 16 Feb 2011 20:26:51 -0000 @@ -11,7 +11,15 @@ 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.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 +69,41 @@ IBinaryAnnotation[] binaryAnnotations = info.getAnnotations(); return getAnnotations(binaryAnnotations, info.getTagBits()); } +/** + * @see IMethod#getParameterAnnotations() + */ +public IAnnotation[][] getParameterAnnotations() throws JavaModelException { + IBinaryMethod info = (IBinaryMethod) getElementInfo(); + int length = this.parameterTypes.length; + if (length == 0) { + return Annotation.NO_PARAMETER_ANNOTATIONS; + } + IAnnotation[][] annotations = new IAnnotation[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++) { + annotations[i] = getAnnotations(argumentNames[i], info.getParameterAnnotations(i), info.getTagBits()); + } + return annotations; +} +private IAnnotation[] getAnnotations(char[] argumentName, 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(this, argumentName, 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 16 Feb 2011 20:26:51 -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,25 +41,28 @@ */ protected ITypeParameter[] typeParameters; +private void generateAnnotationsInfos(BinaryMember 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(BinaryMember 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); + Annotation annotation = new Annotation(parent, parameterName, new String(typeName), memberValuePairName); while (newElements.containsKey(annotation)) { annotation.occurrenceCount++; } @@ -81,7 +84,7 @@ } } } -private void generateStandardAnnotationsInfos(BinaryMember member, long tagBits, HashMap newElements) { +private void generateStandardAnnotationsInfos(BinaryMember member, char[] parameterName, long tagBits, HashMap newElements) { if ((tagBits & TagBits.AllStandardAnnotationsMask) == 0) return; if ((tagBits & TagBits.AnnotationTargetMASK) != 0) { @@ -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,27 @@ 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) { + generateAnnotationsInfos(method, 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 16 Feb 2011 20:26:51 -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/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 16 Feb 2011 20:26:51 -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 @@ -135,6 +135,21 @@ return info.typeParameters; } +public IAnnotation[][] getParameterAnnotations() throws JavaModelException { + ILocalVariable[] arguments = ((SourceMethodElementInfo) getElementInfo()).arguments; + if (arguments == null) + return Annotation.NO_PARAMETER_ANNOTATIONS; + IAnnotation[][] annotations = new IAnnotation[arguments.length][]; + for (int i=0; i