### 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 are char[][]. + */ + 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 {\n" + + " X field;\n" + + " @Inject\n" + + " public void Test(@Default String processor) {}\n" + + "}" + + "@interface Inject{\n" + + "}" + + "@interface Default{\n" + + "}"; + createFolder("/P/src/p"); + createFile( + "/P/src/p/X.java", + source + ); + waitForAutoBuild(); + + ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); + IJavaElement[] variable = ((ICodeAssist) unit).codeSelect(source.indexOf("processor"), "processor".length()); + + assertEquals(1, variable.length); + String annotationString = "@Default [in processor [in Test(String) [in X [in X.java [in p [in src [in P]]]]]]]"; + assertEquals(annotationString, ((LocalVariable)variable[0]).getAnnotations()[0].toString()); + IType type = unit.getType("X"); + + IMethod method = type.getMethods()[0]; + assertEquals(annotationString, method.getParameters()[0].getAnnotations()[0].toString()); + } finally { + deleteProject("P"); + } +} +/** + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783" + */ +public void testParamAnnotations2() throws CoreException, IOException { + try { + IJavaProject project = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5"); + String[] pathAndContents = new String[]{"p/X.java", + "package p;\n" + + "public class X {\n" + + " X field;\n" + + " @Inject\n" + + " public void Test(@Default String processor) {}\n" + + "}" + + "@interface Inject{\n" + + "}" + + "@interface Default{\n" + + "}"}; + addLibrary(project, "lib334783.jar", "libsrc.zip", pathAndContents, JavaCore.VERSION_1_5); + + waitForAutoBuild(); + IPackageFragmentRoot root = project.getPackageFragmentRoot(getFile("/P/lib334783.jar")); + IType type = root.getPackageFragment("p").getClassFile("X.class").getType(); + String annotationString = "@p.Default [in processor [in Test(java.lang.String) [in X [in X.class [in p [in lib334783.jar [in P]]]]]]]"; + + IMethod method = type.getMethods()[1]; + assertEquals(annotationString, method.getParameters()[0].getAnnotations()[0].toString()); + } finally { + deleteProject("P"); + } +} +/** + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783" + */ +public void testParamAnnotations3() throws CoreException { + try { + createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5"); + String source = "package p;\n" + + "public class X {\n" + + " X field;\n" + + " @Inject\n" + + " public void Test(int i, @Default @Marker(id=1) String processor, int k) {}\n" + + "}\n" + + "@interface Inject{\n" + + "}\n" + + "@interface Marker {\n" + + " int id() default 0;\n" + + "}\n" + + "@interface Default{\n" + + "}"; + createFolder("/P/src/p"); + createFile( + "/P/src/p/X.java", + source + ); + waitForAutoBuild(); + + ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); + IJavaElement[] variable = ((ICodeAssist) unit).codeSelect(source.indexOf("processor"), "processor".length()); + + assertEquals(1, variable.length); + String annotationString1 = "@Default [in processor [in Test(int, String, int) [in X [in X.java [in p [in src [in P]]]]]]]"; + String annotationString2 = "@Marker [in processor [in Test(int, String, int) [in X [in X.java [in p [in src [in P]]]]]]]"; + assertEquals(annotationString1, ((LocalVariable)variable[0]).getAnnotations()[0].toString()); + IType type = unit.getType("X"); + + IMethod method = type.getMethods()[0]; + IAnnotation[] parameterAnnotations = method.getParameters()[1].getAnnotations(); + assertEquals("Wrong length", 2, parameterAnnotations.length); + assertEquals(annotationString1, parameterAnnotations[0].toString()); + IAnnotation iAnnotation = parameterAnnotations[1]; + assertEquals(annotationString2, iAnnotation.toString()); + IMemberValuePair[] memberValuePairs = iAnnotation.getMemberValuePairs(); + assertEquals("Wrong number of pairs", 1, memberValuePairs.length); + StringBuffer output = new StringBuffer(); + output.append(memberValuePairs[0].getMemberName()); + output.append(' '); + output.append(memberValuePairs[0].getValue()); + assertEquals("Wrong value", "id 1", String.valueOf(output)); + assertEquals("Wrong length", 0, method.getParameters()[0].getAnnotations().length); + assertEquals("Wrong length", 0, method.getParameters()[2].getAnnotations().length); + } finally { + deleteProject("P"); + } +} +/** + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783" + */ +public void testParamAnnotations4() throws CoreException, IOException { + try { + IJavaProject project = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5"); + String sourceX = + "package p;\n" + + "public class X {\n" + + " X field;\n" + + " @Inject @Marker(id=3)\n" + + " public void Test(final int i, @Default final @Marker(id=1) String processor, int k) {}\n" + + "}"; + String[] pathAndContents = new String[]{"p/X.java", + sourceX, + "p/Inject.java", + "package p;\n"+ + "public @interface Inject{\n" + + "}", + "p/Marker.java", + "package p;\n" + + "public @interface Marker {\n" + + " int id() default 0;\n" + + "}", + "p/Default.java", + "package p;\n" + + "public @interface Default{\n" + + "}"}; + addLibrary(project, "lib334783_2.jar", "lib334783_2src.zip", pathAndContents, JavaCore.VERSION_1_5); + + waitForAutoBuild(); + IPackageFragmentRoot root = project.getPackageFragmentRoot(getFile("/P/lib334783_2.jar")); + IType type = root.getPackageFragment("p").getClassFile("X.class").getType(); + String annotationString1 = "@p.Default [in processor [in Test(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_2.jar [in P]]]]]]]"; + String annotationString2 = "@p.Marker [in processor [in Test(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_2.jar [in P]]]]]]]"; + IMethod method = type.getMethods()[1]; + IAnnotation[] annotations = method.getAnnotations(); + assertEquals("Wrong length", 2, annotations.length); + assertEquals("@p.Inject [in Test(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_2.jar [in P]]]]]]", annotations[0].toString()); + IAnnotation annotation = annotations[1]; + assertEquals("@p.Marker [in Test(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_2.jar [in P]]]]]]", annotation.toString()); + IMemberValuePair[] memberValuePairs = annotation.getMemberValuePairs(); + assertEquals("Wrong number of pairs", 1, memberValuePairs.length); + StringBuffer output = new StringBuffer(); + output.append(memberValuePairs[0].getMemberName()); + output.append(' '); + output.append(memberValuePairs[0].getValue()); + assertEquals("Wrong value", "id 3", String.valueOf(output)); + ILocalVariable localVariable = method.getParameters()[1]; + ISourceRange sourceRange = localVariable.getSourceRange(); + String localSource = sourceX.substring( + sourceRange.getOffset(), + sourceRange.getOffset() + sourceRange.getLength()); + assertEquals("Wrong source", "@Default final @Marker(id=1) String processor", localSource); + assertTrue("Wrong modifiers", Flags.isFinal(localVariable.getFlags())); + IAnnotation[] parameterAnnotations = localVariable.getAnnotations(); + assertEquals("Wrong length", 2, parameterAnnotations.length); + assertEquals(annotationString1, parameterAnnotations[0].toString()); + annotation = parameterAnnotations[1]; + assertEquals(annotationString2, annotation.toString()); + memberValuePairs = annotation.getMemberValuePairs(); + assertEquals("Wrong number of pairs", 1, memberValuePairs.length); + output = new StringBuffer(); + output.append(memberValuePairs[0].getMemberName()); + output.append(' '); + output.append(memberValuePairs[0].getValue()); + assertEquals("Wrong value", "id 1", String.valueOf(output)); + localVariable = method.getParameters()[0]; + assertEquals("Wrong length", 0, localVariable.getAnnotations().length); + assertTrue("Wrong modifiers", Flags.isFinal(localVariable.getFlags())); + assertEquals("Wrong length", 0, method.getParameters()[2].getAnnotations().length); + } finally { + deleteProject("P"); + } +} +/** + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783" + */ +public void testParamAnnotations5() throws CoreException, IOException { + try { + IJavaProject project = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5"); + String[] pathAndContents = new String[]{"p/X.java", + "package p;\n" + + "public class X {\n" + + " X field;\n" + + " @Inject @Marker(id=3)\n" + + " public void Test(int i, @Default @Marker(id=1) String processor, int k) {}\n" + + "}", + "p/Inject.java", + "package p;\n"+ + "public @interface Inject{\n" + + "}", + "p/Marker.java", + "package p;\n" + + "public @interface Marker {\n" + + " int id() default 0;\n" + + "}", + "p/Default.java", + "package p;\n" + + "public @interface Default{\n" + + "}"}; + Map options = new HashMap(); + options.put(JavaCore.COMPILER_LOCAL_VARIABLE_ATTR, JavaCore.DO_NOT_GENERATE); + addLibrary(project, "lib334783_3.jar", "lib334783_3src.zip", pathAndContents, JavaCore.VERSION_1_5, options); + + waitForAutoBuild(); + IPackageFragmentRoot root = project.getPackageFragmentRoot(getFile("/P/lib334783_3.jar")); + IType type = root.getPackageFragment("p").getClassFile("X.class").getType(); + String annotationString1 = "@p.Default [in arg1 [in Test(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_3.jar [in P]]]]]]]"; + String annotationString2 = "@p.Marker [in arg1 [in Test(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_3.jar [in P]]]]]]]"; + IMethod method = type.getMethods()[1]; + IAnnotation[] annotations = method.getAnnotations(); + assertEquals("Wrong length", 2, annotations.length); + assertEquals("@p.Inject [in Test(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_3.jar [in P]]]]]]", annotations[0].toString()); + IAnnotation annotation = annotations[1]; + assertEquals("@p.Marker [in Test(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_3.jar [in P]]]]]]", annotation.toString()); + IMemberValuePair[] memberValuePairs = annotation.getMemberValuePairs(); + assertEquals("Wrong number of pairs", 1, memberValuePairs.length); + StringBuffer output = new StringBuffer(); + output.append(memberValuePairs[0].getMemberName()); + output.append(' '); + output.append(memberValuePairs[0].getValue()); + assertEquals("Wrong value", "id 3", String.valueOf(output)); + IAnnotation[] parameterAnnotations = method.getParameters()[1].getAnnotations(); + assertEquals("Wrong length", 2, parameterAnnotations.length); + assertEquals(annotationString1, parameterAnnotations[0].toString()); + annotation = parameterAnnotations[1]; + assertEquals(annotationString2, annotation.toString()); + memberValuePairs = annotation.getMemberValuePairs(); + assertEquals("Wrong number of pairs", 1, memberValuePairs.length); + output = new StringBuffer(); + output.append(memberValuePairs[0].getMemberName()); + output.append(' '); + output.append(memberValuePairs[0].getValue()); + assertEquals("Wrong value", "id 1", String.valueOf(output)); + assertEquals("Wrong length", 0, method.getParameters()[0].getAnnotations().length); + assertEquals("Wrong length", 0, method.getParameters()[2].getAnnotations().length); + } finally { + deleteProject("P"); + } +} +/** + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783" + */ +public void testParamAnnotations6() throws CoreException { + try { + createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5"); + String source = "package p;\n" + + "public class X {\n" + + " X field;\n" + + " public void Test() {}\n" + + "}"; + createFolder("/P/src/p"); + createFile( + "/P/src/p/X.java", + source + ); + waitForAutoBuild(); + + ICompilationUnit unit = getCompilationUnit("/P/src/p/X.java"); + IType type = unit.getType("X"); + IMethod method = type.getMethods()[0]; + ILocalVariable[] localVariables = method.getParameters(); + assertNotNull(localVariables); + assertEquals("Wrong length", 0, localVariables.length); + } finally { + deleteProject("P"); + } +} +/** + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783" + */ +public void testParamAnnotations7() throws CoreException, IOException { + try { + IJavaProject project = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5"); + String[] pathAndContents = new String[]{"p/X.java", + "package p;\n" + + "public class X {\n" + + " X field;\n" + + " public void Test() {}\n" + + "}" + }; + addLibrary(project, "lib334783.jar", "libsrc.zip", pathAndContents, JavaCore.VERSION_1_5); + + waitForAutoBuild(); + IPackageFragmentRoot root = project.getPackageFragmentRoot(getFile("/P/lib334783.jar")); + IType type = root.getPackageFragment("p").getClassFile("X.class").getType(); + + IMethod method = type.getMethods()[1]; + ILocalVariable[] localVariables = method.getParameters(); + assertNotNull(localVariables); + assertEquals("Wrong length", 0, localVariables.length); + } finally { + deleteProject("P"); + } +} +/** + * @see "https://bugs.eclipse.org/bugs/show_bug.cgi?id=334783" + */ +public void testParamAnnotations8() throws CoreException, IOException { + try { + IJavaProject project = createJavaProject("P", new String[] {"src"}, new String[] {"JCL15_LIB"}, "bin", "1.5"); + String[] pathAndContents = new String[]{"p/X.java", + "package p;\n" + + "public class X {\n" + + " X field;\n" + + " @Inject @Marker(id=3)\n" + + " public X(int i, @Default @Marker(id=1) String processor, int k) {}\n" + + "}", + "p/Inject.java", + "package p;\n"+ + "public @interface Inject{\n" + + "}", + "p/Marker.java", + "package p;\n" + + "public @interface Marker {\n" + + " int id() default 0;\n" + + "}", + "p/Default.java", + "package p;\n" + + "public @interface Default{\n" + + "}"}; + Map options = new HashMap(); + options.put(JavaCore.COMPILER_LOCAL_VARIABLE_ATTR, JavaCore.DO_NOT_GENERATE); + addLibrary(project, "lib334783_3.jar", "lib334783_3src.zip", pathAndContents, JavaCore.VERSION_1_5, options); + + waitForAutoBuild(); + IPackageFragmentRoot root = project.getPackageFragmentRoot(getFile("/P/lib334783_3.jar")); + IType type = root.getPackageFragment("p").getClassFile("X.class").getType(); + String annotationString1 = "@p.Default [in arg1 [in X(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_3.jar [in P]]]]]]]"; + String annotationString2 = "@p.Marker [in arg1 [in X(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_3.jar [in P]]]]]]]"; + IMethod method = type.getMethods()[0]; + IAnnotation[] annotations = method.getAnnotations(); + assertEquals("Wrong length", 2, annotations.length); + assertEquals("@p.Inject [in X(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_3.jar [in P]]]]]]", annotations[0].toString()); + IAnnotation annotation = annotations[1]; + assertEquals("@p.Marker [in X(int, java.lang.String, int) [in X [in X.class [in p [in lib334783_3.jar [in P]]]]]]", annotation.toString()); + IMemberValuePair[] memberValuePairs = annotation.getMemberValuePairs(); + assertEquals("Wrong number of pairs", 1, memberValuePairs.length); + StringBuffer output = new StringBuffer(); + output.append(memberValuePairs[0].getMemberName()); + output.append(' '); + output.append(memberValuePairs[0].getValue()); + assertEquals("Wrong value", "id 3", String.valueOf(output)); + IAnnotation[] parameterAnnotations = method.getParameters()[1].getAnnotations(); + assertEquals("Wrong length", 2, parameterAnnotations.length); + assertEquals(annotationString1, parameterAnnotations[0].toString()); + annotation = parameterAnnotations[1]; + assertEquals(annotationString2, annotation.toString()); + memberValuePairs = annotation.getMemberValuePairs(); + assertEquals("Wrong number of pairs", 1, memberValuePairs.length); + output = new StringBuffer(); + output.append(memberValuePairs[0].getMemberName()); + output.append(' '); + output.append(memberValuePairs[0].getValue()); + assertEquals("Wrong value", "id 1", String.valueOf(output)); + assertEquals("Wrong length", 0, method.getParameters()[0].getAnnotations().length); + assertEquals("Wrong length", 0, method.getParameters()[2].getAnnotations().length); + } finally { + deleteProject("P"); + } +} }