Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2018-07-15 22:07:30 +0000
committerStephan Herrmann2019-09-15 13:14:45 +0000
commit5b9892bd4cc46055e381266dc749bbc43aff733b (patch)
treebf3d7777134dfb39ba67c18d1a5864ae8466565f
parent77036337e7aa47716d1719076ffb75fb4ca915ca (diff)
downloadeclipse.jdt.core-5b9892bd4cc46055e381266dc749bbc43aff733b.tar.gz
eclipse.jdt.core-5b9892bd4cc46055e381266dc749bbc43aff733b.tar.xz
eclipse.jdt.core-5b9892bd4cc46055e381266dc749bbc43aff733b.zip
Bug 537014 - [10] "Unexpected runtime error when computing a text hover"
for java 10 var Change-Id: I2528fdcfcf9f515b2b2f2604eb0d92ed1ff0b328
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java11
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java3
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests10.java125
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java52
4 files changed, 169 insertions, 22 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
index 4fd306813f..43d9ab94c7 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AbstractJavaModelTests.java
@@ -3172,8 +3172,13 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
String newJclLibString;
String newJclSrcString;
if (useFullJCL) {
- newJclLibString = "JCL18_FULL";
- newJclSrcString = "JCL18_SRC"; // Use the same source
+ if (compliance.equals("10")) {
+ newJclLibString = "JCL10_LIB"; // TODO: have no full variant yet
+ newJclSrcString = "JCL10_SRC";
+ } else {
+ newJclLibString = "JCL18_FULL";
+ newJclSrcString = "JCL18_SRC"; // Use the same source
+ }
} else {
if (compliance.equals("12")) {
newJclLibString = "JCL12_LIB";
@@ -3291,7 +3296,7 @@ public abstract class AbstractJavaModelTests extends SuiteOfTestCases {
setupExternalJCL("jclMin10");
JavaCore.setClasspathVariables(
new String[] {"JCL10_LIB", "JCL10_SRC", "JCL_SRCROOT"},
- new IPath[] {getExternalJCLPath("9"), getExternalJCLSourcePath("9"), getExternalJCLRootSourcePath()},
+ new IPath[] {getExternalJCLPath("10"), getExternalJCLSourcePath("10"), getExternalJCLRootSourcePath()},
null);
}
} else if ("11".equals(compliance)) {
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java
index 1fa9b48651..34262e98a9 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/AllJavaModelTests.java
@@ -102,6 +102,8 @@ private static Class[] getAllTestClasses() {
ResolveTests2.class,
ResolveTests_1_5.class,
ResolveTests18.class,
+ ResolveTests9.class,
+ ResolveTests10.class,
ResolveTests12.class,
SelectionJavadocModelTests.class,
@@ -216,7 +218,6 @@ private static Class[] getAllTestClasses() {
JavaElement8Tests.class,
Java9ElementTests.class,
- ResolveTests9.class,
NullAnnotationModelTests9.class,
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests10.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests10.java
new file mode 100644
index 0000000000..85b76d0b2a
--- /dev/null
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ResolveTests10.java
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2016, 2019 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.jdt.core.tests.model;
+
+import java.io.File;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jdt.core.IClasspathEntry;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.WorkingCopyOwner;
+import org.eclipse.jdt.internal.core.LocalVariable;
+
+import junit.framework.Test;
+
+public class ResolveTests10 extends AbstractJavaModelTests {
+ ICompilationUnit wc = null;
+
+ static {
+// TESTS_NAMES = new String[] { "testModuleInfo_" };
+// TESTS_NUMBERS = new int[] { 124 };
+// TESTS_RANGE = new int[] { 16, -1 };
+ }
+ public static Test suite() {
+ return buildModelTestSuite(ResolveTests10.class);
+ }
+ public ResolveTests10(String name) {
+ super(name);
+ }
+ public ICompilationUnit getWorkingCopy(String path, String source) throws JavaModelException {
+ return super.getWorkingCopy(path, source, this.wcOwner);
+ }
+ public void setUpSuite() throws Exception {
+ super.setUpSuite();
+
+ IJavaProject project = setUpJavaProject("Resolve", "10", true);
+
+ String bootModPath = System.getProperty("java.home") + File.separator +"jrt-fs.jar";
+ IClasspathEntry jrtEntry = JavaCore.newLibraryEntry(new Path(bootModPath), null, null, null, null, false);
+ IClasspathEntry[] old = project.getRawClasspath();
+ IClasspathEntry[] newPath = new IClasspathEntry[old.length +1];
+ System.arraycopy(old, 0, newPath, 0, old.length);
+ newPath[old.length] = jrtEntry;
+ project.setRawClasspath(newPath, null);
+
+ waitUntilIndexesReady();
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+ this.wcOwner = new WorkingCopyOwner(){};
+ }
+ public void tearDownSuite() throws Exception {
+ deleteProject("Resolve");
+
+ super.tearDownSuite();
+ }
+
+ protected void tearDown() throws Exception {
+ if (this.wc != null) {
+ this.wc.discardWorkingCopy();
+ }
+ super.tearDown();
+ }
+ public void testVarWithIntersectionType() throws CoreException {
+ this.wc = getWorkingCopy(
+ "/Resolve/src/Hey.java",
+ "interface Cloneable {}\n" +
+ "\n" +
+ "abstract class AbstractSet<S> {}\n" +
+ "\n" +
+ "class TreeSet<E> extends AbstractSet<E>\n" +
+ " implements Cloneable, java.io.Serializable\n" +
+ "{}\n" +
+ "\n" +
+ "class HashSet<E>\n" +
+ " extends AbstractSet<E>\n" +
+ " implements Cloneable, java.io.Serializable\n" +
+ "{}\n" +
+ "\n" +
+ "public class Hey {\n" +
+ " public static void main(String[] args) {\n" +
+ " var x = args.length > 0 ? new TreeSet<>() : new HashSet<>();\n" +
+ " x.add(1);\n" +
+ " }\n" +
+ "}\n");
+
+ String str = this.wc.getSource();
+ String selection = "x";
+ int start = str.lastIndexOf(selection);
+ int length = selection.length();
+
+ IJavaElement[] elements = this.wc.codeSelect(start, length);
+ assertElementsEqual(
+ "Unexpected elements",
+ "x [in main(String[]) [in Hey [in [Working copy] Hey.java [in <default> [in src [in Resolve]]]]]]",
+ elements
+ );
+
+ String typeSignature = ((LocalVariable)elements[0]).getTypeSignature();
+ assertEquals("type signature", "&LAbstractSet<Ljava.lang.Object;>;:LCloneable;:Ljava.io.Serializable;", typeSignature);
+
+ assertStringsEqual(
+ "Unexpected intersection type bounds",
+ "LAbstractSet<Ljava.lang.Object;>;\n" +
+ "LCloneable;\n" +
+ "Ljava.io.Serializable;\n",
+ Signature.getUnionTypeBounds(typeSignature) // method name is wrong, it actually means: getIntersectionTypeBounds
+ );
+ }
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
index b9ec8efeae..62d01107e0 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/core/Signature.java
@@ -1070,7 +1070,8 @@ public static String createArraySignature(String typeSignature, int arrayCount)
/**
* Creates a new type signature from the given type name encoded as a character
- * array. The type name may contain primitive types or array types or parameterized types.
+ * array. The type name may contain primitive types or array types or parameterized types
+ * or represent an intersection type in source code notation using {@code &}.
* This method is equivalent to
* <code>createTypeSignature(new String(typeName),isResolved).toCharArray()</code>,
* although more efficient for callers with character arrays rather than strings.
@@ -1338,6 +1339,7 @@ private static int encodeQualifiedName(char[] typeName, int pos, int length, Str
case '>' :
case '[' :
case ',' :
+ case '&' :
break nameLoop;
case '.' :
buffer.append(C_DOT);
@@ -1488,32 +1490,46 @@ private static int encodeTypeSignature(char[] typeName, int start, boolean isRes
end = -1;
}
buffer.append(isResolved ? C_RESOLVED : C_UNRESOLVED);
- while (true) { // loop on qualifiedName[<args>][.qualifiedName[<args>]*
- pos = encodeQualifiedName(typeName, pos, length, buffer);
- checkPos = checkNextChar(typeName, '<', pos, length, true);
- if (checkPos > 0) {
- buffer.append(C_GENERIC_START);
- // Stop gap fix for <>.
- if ((pos = checkNextChar(typeName, '>', checkPos, length, true)) > 0) {
- buffer.append(C_GENERIC_END);
- } else {
- pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
- while ((checkPos = checkNextChar(typeName, ',', pos, length, true)) > 0) {
+ while (true) { // loop on type[&type]*
+ while (true) { // loop on qualifiedName[<args>][.qualifiedName[<args>]*
+ pos = encodeQualifiedName(typeName, pos, length, buffer);
+ checkPos = checkNextChar(typeName, '<', pos, length, true);
+ if (checkPos > 0) {
+ buffer.append(C_GENERIC_START);
+ // Stop gap fix for <>.
+ if ((pos = checkNextChar(typeName, '>', checkPos, length, true)) > 0) {
+ buffer.append(C_GENERIC_END);
+ } else {
pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
+ while ((checkPos = checkNextChar(typeName, ',', pos, length, true)) > 0) {
+ pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
+ }
+ pos = checkNextChar(typeName, '>', pos, length, false);
+ buffer.append(C_GENERIC_END);
}
- pos = checkNextChar(typeName, '>', pos, length, false);
- buffer.append(C_GENERIC_END);
+ }
+ checkPos = checkNextChar(typeName, '.', pos, length, true);
+ if (checkPos > 0) {
+ buffer.append(C_DOT);
+ pos = checkPos;
+ } else {
+ break;
}
}
- checkPos = checkNextChar(typeName, '.', pos, length, true);
+ buffer.append(C_NAME_END);
+ checkPos = checkNextChar(typeName, '&', pos, length, true);
if (checkPos > 0) {
- buffer.append(C_DOT);
- pos = checkPos;
+ if (buffer.charAt(0) != C_UNION) // the constant name is wrong, its value is correct :-X
+ buffer.insert(0, C_UNION);
+ buffer.append(C_COLON);
+ pos = encodeTypeSignature(typeName, checkPos, isResolved, length, buffer);
+ if (pos == length) {
+ break;
+ }
} else {
break;
}
}
- buffer.append(C_NAME_END);
if (end > 0) pos = end; // skip array dimension which were preprocessed
return pos;
}

Back to the top