Bug 505927: New IndexBinaryType is not sufficient for compilation of OT
types
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
index dfd3ea1..24e069f 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/env/IBinaryType.java
@@ -167,4 +167,15 @@
*/
ExternalAnnotationStatus getExternalAnnotationStatus();
+//{ObjectTeams:
+/**
+ * Answers the "real" binary type for the given binary type.
+ * By default this is an identity transformation.
+ * Only IndexBinaryType will retrieve the bytes from disk to answer a fresh ClassFileReader.
+ * @throws Exception
+ */
+default IBinaryType withClassBytes() throws Exception {
+ return this;
+}
+// SH}
}
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
index 185ff02..616c237 100644
--- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
+++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/BinaryTypeBinding.java
@@ -44,8 +44,6 @@
*******************************************************************************/
package org.eclipse.jdt.internal.compiler.lookup;
-import java.io.File;
-import java.io.IOException;
import java.util.ArrayList;
import org.eclipse.jdt.core.compiler.CharOperation;
@@ -54,7 +52,6 @@
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
-import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.classfmt.FieldInfo;
import org.eclipse.jdt.internal.compiler.classfmt.MethodInfo;
import org.eclipse.jdt.internal.compiler.classfmt.ExternalAnnotationProvider.IMethodAnnotationWalker;
@@ -68,8 +65,6 @@
import org.eclipse.jdt.internal.compiler.problem.AbortCompilation;
import org.eclipse.jdt.internal.compiler.util.SimpleLookupTable;
import org.eclipse.jdt.internal.compiler.util.Util;
-import org.eclipse.jdt.internal.core.nd.java.model.IndexBinaryMethod;
-import org.eclipse.jdt.internal.core.nd.java.model.IndexBinaryType;
import org.eclipse.objectteams.otdt.core.compiler.IOTConstants;
import org.eclipse.objectteams.otdt.internal.core.compiler.bytecode.AbstractAttribute;
import org.eclipse.objectteams.otdt.internal.core.compiler.control.Config;
@@ -572,17 +567,14 @@
this._teamModel = new TeamModel(this);
// Note, 'model' is already set in ctor of superclass ReferenceBinding.
- if (binaryType instanceof IndexBinaryType) {
- // for roles and teams we need the bytes, retrieve them now:
- if ((this.modifiers & (ExtraCompilerModifiers.AccRole|ClassFileConstants.AccTeam)) != 0) {
- File file = new File(String.valueOf(binaryType.getFileName()));
- try {
- binaryType = ClassFileReader.read(file, true);
- } catch (ClassFormatException | IOException e) {
- if (this.environment.problemReporter != null) {
- String errorMessage = "Cannot read class file for "+String.valueOf(binaryType.getName())+": "; //$NON-NLS-1$ //$NON-NLS-2$
- this.environment.problemReporter.abortDueToInternalError(errorMessage+e.getMessage());
- }
+ // for roles and teams we need the bytes, retrieve them now, if not already present:
+ if ((this.modifiers & (ExtraCompilerModifiers.AccRole|ClassFileConstants.AccTeam)) != 0) {
+ try {
+ binaryType = binaryType.withClassBytes();
+ } catch (Exception e) {
+ if (this.environment.problemReporter != null) {
+ String errorMessage = "Cannot read class file for "+String.valueOf(binaryType.getName())+": "; //$NON-NLS-1$ //$NON-NLS-2$
+ this.environment.problemReporter.abortDueToInternalError(errorMessage+e.getMessage());
}
}
}
@@ -1177,9 +1169,6 @@
this.environment.getTeamMethodGenerator().registerTeamMethod(method, result);
// Note, that maybeRegister() may reset the MethodInfo (nulling MethodInfo.reference):
((MethodInfo)method).maybeRegister(this, result, this.environment);
- } else if (method instanceof IndexBinaryMethod) {
- if (TypeAnalyzer.isOrgObjectteamsTeam(this))
- this.environment.getTeamMethodGenerator().registerTeamMethodWithoutBytes(binaryType, method, result, this.environment);
}
}
}
diff --git a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/IndexBinaryType.java b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/IndexBinaryType.java
index aaa7576..f011496 100644
--- a/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/IndexBinaryType.java
+++ b/org.eclipse.jdt.core/search/org/eclipse/jdt/internal/core/nd/java/model/IndexBinaryType.java
@@ -10,11 +10,19 @@
*******************************************************************************/
package org.eclipse.jdt.internal.core.nd.java.model;
+import java.io.File;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
+import java.util.zip.ZipFile;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaElement;
+import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.internal.compiler.classfmt.BinaryTypeFormatter;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFileReader;
+import org.eclipse.jdt.internal.compiler.classfmt.ClassFormatException;
import org.eclipse.jdt.internal.compiler.classfmt.ElementValuePairInfo;
import org.eclipse.jdt.internal.compiler.codegen.AnnotationTargetTypeConstants;
import org.eclipse.jdt.internal.compiler.env.ClassSignature;
@@ -26,10 +34,12 @@
import org.eclipse.jdt.internal.compiler.env.IBinaryNestedType;
import org.eclipse.jdt.internal.compiler.env.IBinaryType;
import org.eclipse.jdt.internal.compiler.env.IBinaryTypeAnnotation;
+import org.eclipse.jdt.internal.compiler.env.IDependent;
import org.eclipse.jdt.internal.compiler.env.ITypeAnnotationWalker;
import org.eclipse.jdt.internal.compiler.impl.Constant;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding.ExternalAnnotationStatus;
import org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
+import org.eclipse.jdt.internal.core.JarPackageFragmentRoot;
import org.eclipse.jdt.internal.core.nd.IReader;
import org.eclipse.jdt.internal.core.nd.db.IString;
import org.eclipse.jdt.internal.core.nd.java.JavaNames;
@@ -669,4 +679,23 @@
public ExternalAnnotationStatus getExternalAnnotationStatus() {
return ExternalAnnotationStatus.NOT_EEA_CONFIGURED;
}
+//{ObjectTeams: retrieve class file in workspace:
+ @Override
+ public IBinaryType withClassBytes() throws ClassFormatException, IOException, CoreException {
+ File file = new File(String.valueOf(this.fileName));
+ if (file.exists())
+ return ClassFileReader.read(file);
+ int pos = CharOperation.indexOf(IDependent.JAR_FILE_ENTRY_SEPARATOR, this.fileName);
+ if (pos != -1) {
+ String jarIdentifier = String.valueOf(CharOperation.subarray(this.fileName, 0, pos));
+ String fileInJarName = String.valueOf(CharOperation.subarray(this.fileName, pos+1, -1));
+ IJavaElement jJar = JavaCore.create(jarIdentifier);
+ if (jJar.exists()) {
+ ZipFile jarZip = ((JarPackageFragmentRoot) jJar).getJar();
+ return ClassFileReader.read(jarZip, fileInJarName);
+ }
+ }
+ return this; // could not improve
+ }
+// SH}
}
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/JCL/jclFull1.8.jar b/testplugins/org.eclipse.objectteams.otdt.tests/JCL/jclFull1.8.jar
new file mode 100644
index 0000000..02238aa
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/JCL/jclFull1.8.jar
Binary files differ
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/JCL/jclMin1.8.jar b/testplugins/org.eclipse.objectteams.otdt.tests/JCL/jclMin1.8.jar
new file mode 100644
index 0000000..0e017da
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/JCL/jclMin1.8.jar
Binary files differ
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/JCL/jclMin1.8src.zip b/testplugins/org.eclipse.objectteams.otdt.tests/JCL/jclMin1.8src.zip
new file mode 100644
index 0000000..c85ea26
--- /dev/null
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/JCL/jclMin1.8src.zip
Binary files differ
diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/model/org/eclipse/objectteams/otdt/tests/otmodel/OTReconcilerTests.java b/testplugins/org.eclipse.objectteams.otdt.tests/model/org/eclipse/objectteams/otdt/tests/otmodel/OTReconcilerTests.java
index 56159a1..1b1f346 100644
--- a/testplugins/org.eclipse.objectteams.otdt.tests/model/org/eclipse/objectteams/otdt/tests/otmodel/OTReconcilerTests.java
+++ b/testplugins/org.eclipse.objectteams.otdt.tests/model/org/eclipse/objectteams/otdt/tests/otmodel/OTReconcilerTests.java
@@ -30,6 +30,7 @@
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
@@ -40,6 +41,7 @@
import org.eclipse.jdt.core.compiler.IProblem;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.tests.model.ReconcilerTests;
+import org.eclipse.jdt.core.tests.util.AbstractCompilerTest;
import org.eclipse.jdt.internal.compiler.CompilationResult;
import org.eclipse.jdt.internal.compiler.Compiler;
import org.eclipse.jdt.internal.compiler.DefaultErrorHandlingPolicies;
@@ -184,13 +186,48 @@
}
// ===== End COPY_AND_PASTE
+ // --- support OT libraries: ---
+ boolean addOTtoLibrary = false;
+ protected void addOTLibrary(IJavaProject javaProject, String jarName, String sourceZipName, String[] pathAndContents, String compliance) throws CoreException, IOException {
+ boolean prev = this.addOTtoLibrary;
+ try {
+ this.addOTtoLibrary = true;
+ addLibrary(javaProject, jarName, sourceZipName, pathAndContents, compliance);
+ } finally {
+ this.addOTtoLibrary = prev;
+ }
+ }
+ @Override
+ protected String[] getJCL15PlusLibraryIfNeeded(String compliance) throws JavaModelException, IOException {
+ if (compliance.charAt(compliance.length()-1) >= '8' && (AbstractCompilerTest.getPossibleComplianceLevels() & AbstractCompilerTest.F_1_8) != 0) {
+ // ensure that the JCL 18 lib is setup (i.e. that the jclMin18.jar is copied)
+ setUpJCLClasspathVariables("1.8");
+ if (addOTtoLibrary) {
+ IPath otreMinJarPath = OTREContainer.getOtreMinJarPath();
+ return new String[] {getExternalJCLPathString("1.8"), otreMinJarPath.toString() };
+ }
+ return new String[] {getExternalJCLPathString("1.8")};
+ }
+ if (compliance.charAt(compliance.length()-1) >= '5' && (AbstractCompilerTest.getPossibleComplianceLevels() & AbstractCompilerTest.F_1_5) != 0) {
+ // ensure that the JCL 15 lib is setup (i.e. that the jclMin15.jar is copied)
+ setUpJCLClasspathVariables("1.5");
+ if (addOTtoLibrary)
+ return new String[] {getExternalJCLPathString("1.5"), "OTRE" };
+ return new String[] {getExternalJCLPathString("1.5")};
+ }
+ return null;
+ }
+ // ---
protected IJavaProject createOTJavaProject(String projectName, String[] sourceFolders, String[] libraries, String output) throws CoreException {
return createOTJavaProject(projectName, sourceFolders, libraries, "1.5", output);
}
protected IJavaProject createOTJavaProject(String projectName, String[] sourceFolders, String[] libraries, String compliance, String output) throws CoreException {
- IJavaProject javaProject = createJavaProject(projectName, sourceFolders, libraries, output, compliance);
+ return createOTJavaProject(projectName, sourceFolders, libraries, compliance, output, false);
+ }
+ protected IJavaProject createOTJavaProject(String projectName, String[] sourceFolders, String[] libraries, String compliance, String output, boolean useFullJcl) throws CoreException {
+ IJavaProject javaProject = createJavaProject(projectName, sourceFolders, libraries, output, compliance, useFullJcl);
IProjectDescription description = javaProject.getProject().getDescription();
description.setNatureIds(OTDTPlugin.createProjectNatures(description));
javaProject.getProject().setDescription(description, null);
@@ -2043,4 +2080,52 @@
deleteProject("P");
}
}
+
+ public void testTeamInJar1() throws CoreException, InterruptedException, IOException {
+ try {
+ // Resources creation
+ IJavaProject p = createOTJavaProject("P", new String[] {"src"}, new String[] {"JCL18_FULL"}, "1.8", "bin", true/*fullJCL*/);
+ IProject project = p.getProject();
+ IProjectDescription prjDesc = project.getDescription();
+ prjDesc.setBuildSpec(OTDTPlugin.createProjectBuildCommands(prjDesc));
+ project.setDescription(prjDesc, null);
+
+ OTREContainer.initializeOTJProject(project);
+
+ addOTLibrary(p, "teams.jar", "teamsSrc.zip", new String[] {
+ "p/MyTeam.java",
+ "package p;\n" +
+ "public team class MyTeam {\n" +
+ " protected class MyR {\n" +
+ " void test() {}\n" +
+ " }\n" +
+ "}\n"
+ }, "1.8");
+
+ this.createFolder("/P/src/p2");
+ String subTeamSourceString =
+ "package p2;\n" +
+ "public team class SubTeam extends p.MyTeam {\n" +
+ " @Override\n" +
+ " protected class MyR {\n" +
+ " void test2() {\n" +
+ " test();\n" +
+ " }\n" +
+ " }\n" +
+ "}\n";
+ String teamFileName = "P/src/p2/SubTeam.java";
+ this.createFile(teamFileName, subTeamSourceString);
+
+ waitUntilIndexesReady();
+ this.workingCopies = new ICompilationUnit[1];
+
+ // Get first working copy and verify that there's no error
+ this.problemRequestor.initialize(subTeamSourceString.toCharArray());
+ this.workingCopies[0] = getCompilationUnit(teamFileName).getWorkingCopy(this.wcOwner, null);
+ assertNoProblem(subTeamSourceString.toCharArray(), this.workingCopies[0]);
+
+ } finally {
+ deleteProject("P");
+ }
+ }
}