diff options
| author | Terry Parker | 2014-05-06 22:15:35 +0000 |
|---|---|---|
| committer | Jayaprakash Arthanareeswaran | 2014-05-09 10:14:57 +0000 |
| commit | 1d3546ae21ffe0ff967875f1cabb468e47817326 (patch) | |
| tree | d8a08e0bc368d6a70b1cf5a8269f9a1ed616e57c | |
| parent | b652b7fd3a65d4ba23b1274ed0c9b6a3e193e11c (diff) | |
| download | eclipse.jdt.core-1d3546ae21ffe0ff967875f1cabb468e47817326.tar.gz eclipse.jdt.core-1d3546ae21ffe0ff967875f1cabb468e47817326.tar.xz eclipse.jdt.core-1d3546ae21ffe0ff967875f1cabb468e47817326.zip | |
Bug 418092 - ArrayOutOfBoundException while autocompleting a jar library with attached javadoc
Change-Id: I150b4dcb09451d563d01d52a5c64ede6b74e34c8
Signed-off-by: Terry Parker <tparker@google.com>
4 files changed, 67 insertions, 1 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java index 0ddf66498b..7a5995a318 100644 --- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java +++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AttachedJavadocTests.java @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Terry Parker <tparker@google.com> - Bug 418092 *******************************************************************************/ package org.eclipse.jdt.core.tests.model; @@ -97,6 +98,7 @@ public class AttachedJavadocTests extends ModifyingResourceTests { suite.addTest(new AttachedJavadocTests("testBug398272")); suite.addTest(new AttachedJavadocTests("testBug426058")); suite.addTest(new AttachedJavadocTests("testBug403154")); + suite.addTest(new AttachedJavadocTests("testBug418092")); return suite; } @@ -1328,4 +1330,33 @@ public class AttachedJavadocTests extends ModifyingResourceTests { this.project.setRawClasspath(oldClasspath, null); } } + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=418092 + // Correctly parse Javadoc for methods that have parameterized annotations. + public void testBug418092() throws JavaModelException { + try { + IClasspathAttribute attribute = + JavaCore.newClasspathAttribute( + IClasspathAttribute.JAVADOC_LOCATION_ATTRIBUTE_NAME, + "jar:platform:/resource/AttachedJavadocProject/bug418092_doc.zip!/"); + IClasspathEntry newEntry = JavaCore.newLibraryEntry(new Path("/AttachedJavadocProject/bug418092.jar"), null, null, null, new IClasspathAttribute[] {attribute}, true); + this.project.setRawClasspath(new IClasspathEntry[]{newEntry}, null); + this.project.getResolvedClasspath(false); + + IPackageFragmentRoot jarRoot = this.project.getPackageFragmentRoot(getFile("/AttachedJavadocProject/bug418092.jar")); + final IType type = jarRoot.getPackageFragment("p1.p2").getClassFile("Annot3.class").getType(); + assertNotNull(type); + IMethod method = type.getMethod("filter", new String[] {"I", "I"}); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + assertTrue(method.exists()); + String javadoc = method.getAttachedJavadoc(new NullProgressMonitor()); //$NON-NLS-1$ + assertNotNull("Should have a javadoc", javadoc); //$NON-NLS-1$ + String[] paramNames = method.getParameterNames(); + assertNotNull(paramNames); + assertEquals("Wrong size", 2, paramNames.length); //$NON-NLS-1$ + assertEquals("Wrong name for first param", "p1", paramNames[0]); //$NON-NLS-1$ //$NON-NLS-2$ + assertEquals("Wrong name for second param", "p2", paramNames[1]); //$NON-NLS-1$ //$NON-NLS-2$ + } catch (IndexOutOfBoundsException e) { + assertTrue("Should not happen", false); + } + } } + diff --git a/org.eclipse.jdt.core.tests.model/workspace/AttachedJavadocProject/bug418092.jar b/org.eclipse.jdt.core.tests.model/workspace/AttachedJavadocProject/bug418092.jar Binary files differnew file mode 100644 index 0000000000..b1b318c9d7 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/workspace/AttachedJavadocProject/bug418092.jar diff --git a/org.eclipse.jdt.core.tests.model/workspace/AttachedJavadocProject/bug418092_doc.zip b/org.eclipse.jdt.core.tests.model/workspace/AttachedJavadocProject/bug418092_doc.zip Binary files differnew file mode 100644 index 0000000000..cbaa203b71 --- /dev/null +++ b/org.eclipse.jdt.core.tests.model/workspace/AttachedJavadocProject/bug418092_doc.zip diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java index 7e7cccb236..53c3883cb0 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/BinaryMethod.java @@ -7,6 +7,7 @@ * * Contributors: * IBM Corporation - initial API and implementation + * Terry Parker <tparker@google.com> - Bug 418092 *******************************************************************************/ package org.eclipse.jdt.internal.core; @@ -28,6 +29,7 @@ import org.eclipse.jdt.internal.compiler.env.IBinaryMethod; import org.eclipse.jdt.internal.compiler.env.IBinaryType; import org.eclipse.jdt.internal.compiler.lookup.Binding; import org.eclipse.jdt.internal.compiler.lookup.ExtraCompilerModifiers; +import org.eclipse.jdt.internal.compiler.parser.ScannerHelper; import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo; import org.eclipse.jdt.internal.core.util.Util; @@ -353,7 +355,13 @@ public String[] getParameterNames() throws JavaModelException { } } if (methodDoc != null) { - final int indexOfOpenParen = methodDoc.indexOf('('); + int indexOfOpenParen = methodDoc.indexOf('('); + // Annotations may have parameters, so make sure we are parsing the actual method parameters. + if (info.getAnnotations() != null) { + while (indexOfOpenParen != -1 && !isOpenParenForMethod(methodDoc, getElementName(), indexOfOpenParen)) { + indexOfOpenParen = methodDoc.indexOf('(', indexOfOpenParen + 1); + } + } if (indexOfOpenParen != -1) { final int indexOfClosingParen = methodDoc.indexOf(')', indexOfOpenParen); if (indexOfClosingParen != -1) { @@ -391,6 +399,33 @@ public String[] getParameterNames() throws JavaModelException { // If still no parameter names, produce fake ones, but don't cache them (https://bugs.eclipse.org/bugs/show_bug.cgi?id=329671) return getRawParameterNames(paramCount); } +private boolean isOpenParenForMethod(String javaDoc, String methodName, int index) { + /* + * Annotations can have parameters associated with them, so we need to validate that this parameter list is + * actually for the method. Determine this by scanning backwards from where the paren was seen, skipping over + * HTML tags to find the identifier that precedes the paren, and then matching that identifier against the + * method's name. + */ + boolean scanningTag = false; + int endIndex = 0; + while (--index > methodName.length()) { + char previousChar = javaDoc.charAt(index); + if (endIndex > 0) { + if (!ScannerHelper.isJavaIdentifierPart(previousChar) + || !ScannerHelper.isJavaIdentifierStart(previousChar)) + return methodName.equals(javaDoc.substring(index + 1, endIndex)); + } else if (!scanningTag) { + if (previousChar == '>') + scanningTag = true; + else if (ScannerHelper.isJavaIdentifierPart(previousChar) + || ScannerHelper.isJavaIdentifierStart(previousChar)) + endIndex = index + 1; + } else if (previousChar == '<') + // We are only matching angle brackets here, without any other validation of the tags. + scanningTag = false; + } + return false; +} private char[][] splitParameters(char[] parametersSource, int paramCount) { // we have generic types as one of the parameter types char[][] params = new char[paramCount][]; |
