diff options
author | Gunnar Wagenknecht | 2020-10-04 10:42:30 +0000 |
---|---|---|
committer | Gunnar Wagenknecht | 2020-11-17 12:46:15 +0000 |
commit | d9f4522941023e4b0df94db47b29d6b85f779391 (patch) | |
tree | bd48c2a7564f64f9848f627969cf2024efb67596 | |
parent | 099c3234ad711be08e2576635e68f4c922710331 (diff) | |
download | eclipse.jdt.core-d9f4522941023e4b0df94db47b29d6b85f779391.tar.gz eclipse.jdt.core-d9f4522941023e4b0df94db47b29d6b85f779391.tar.xz eclipse.jdt.core-d9f4522941023e4b0df94db47b29d6b85f779391.zip |
Bug 567532 - Fix module updates not persisted for test locations
Duplicate reading and writing module patches and updates for
testBinaryLocations. This fixes an issue with the first
build always being a full build because of improperly persisted state
for test classpath locations.
Change-Id: If17f0aafe09c36fef738a8ffd3136339f31ae08f
-rw-r--r-- | org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/StateTest.java | 55 | ||||
-rw-r--r-- | org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java | 87 |
2 files changed, 139 insertions, 3 deletions
diff --git a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/StateTest.java b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/StateTest.java index fed6380618..3a54ae9bb8 100644 --- a/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/StateTest.java +++ b/org.eclipse.jdt.core.tests.builder/src/org/eclipse/jdt/core/tests/builder/StateTest.java @@ -28,11 +28,16 @@ import java.util.Set; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; +import org.eclipse.jdt.core.IAccessRule; +import org.eclipse.jdt.core.IClasspathAttribute; +import org.eclipse.jdt.core.JavaCore; import org.eclipse.jdt.core.JavaModelException; import org.eclipse.jdt.core.compiler.CharOperation; import org.eclipse.jdt.core.tests.util.Util; import org.eclipse.jdt.internal.core.JavaModelManager; import org.eclipse.jdt.internal.core.JavaModelManager.PerProjectInfo; +import org.eclipse.jdt.internal.core.builder.ClasspathLocation; import org.eclipse.jdt.internal.core.builder.JavaBuilder; import org.eclipse.jdt.internal.core.builder.ReferenceCollection; import org.eclipse.jdt.internal.core.builder.State; @@ -108,6 +113,56 @@ public class StateTest extends BuilderTests { writeReadAndCompareReferences(project); } + public void testBug567532() throws JavaModelException, Exception { + IPath project = env.addProject("Bug567532"); //$NON-NLS-1$ + String[] classLibs = Util.getJavaClassLibs(); + for (String jar : classLibs) { + env.addEntry(project, + JavaCore.newLibraryEntry( + new Path(jar), + null, + null, + new IAccessRule[0], + new IClasspathAttribute[] { + JavaCore.newClasspathAttribute(IClasspathAttribute.TEST, "true"), + JavaCore.newClasspathAttribute(IClasspathAttribute.ADD_EXPORTS, + "jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED") }, + false)); + } + + env.addClass(project, "a", "WithOther", //$NON-NLS-1$ //$NON-NLS-2$ + "package a;\n" + + "class Other {\n" + + "}\n" + + "public class WithOther {\n" + + "}" //$NON-NLS-1$ + ); + fullBuild(); + env.removePackage(project, "a"); + incrementalBuild(); + + writeReadAndCompareTestBinaryLocations(project); + } + + private void writeReadAndCompareTestBinaryLocations(IPath projectPath) + throws JavaModelException, IOException, CoreException { + JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager(); + IProject project = env.getProject(projectPath); + PerProjectInfo info = javaModelManager.getPerProjectInfoCheckExistence(project); + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + State savedState = (State) info.savedState; + JavaBuilder.writeState(savedState, new DataOutputStream(outputStream)); + byte[] bytes = outputStream.toByteArray(); + State readState = JavaBuilder.readState(project, new DataInputStream(new ByteArrayInputStream(bytes))); + assertEqualBinaryLocations(savedState.testBinaryLocations, readState.testBinaryLocations); + } + + private void assertEqualBinaryLocations(ClasspathLocation[] a, + ClasspathLocation[] b) { + assertEquals(a.length, b.length); + assertArrayEquals(a, b); + } + private void writeReadAndCompareReferences(IPath projectPath) throws JavaModelException, IOException, CoreException { JavaModelManager javaModelManager = JavaModelManager.getJavaModelManager(); diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java index 4447a90877..d5b90cb384 100644 --- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java +++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/builder/State.java @@ -59,8 +59,8 @@ public class State { String javaProjectName; public ClasspathMultiDirectory[] sourceLocations; public ClasspathMultiDirectory[] testSourceLocations; -ClasspathLocation[] binaryLocations; -ClasspathLocation[] testBinaryLocations; +public ClasspathLocation[] binaryLocations; +public ClasspathLocation[] testBinaryLocations; // keyed by the project relative path of the type (i.e. "src1/p1/p2/A.java"), value is a ReferenceCollection or an AdditionalTypeCollection Map<String, ReferenceCollection> references; // keyed by qualified type name "p1/p2/A", value is the project relative path which defines this type "src1/p1/p2/A.java" @@ -76,7 +76,7 @@ private long previousStructuralBuildTime; private StringSet structurallyChangedTypes; public static int MaxStructurallyChangedTypes = 100; // keep track of ? structurally changed types, otherwise consider all to be changed -public static final byte VERSION = 0x0022; +public static final byte VERSION = 0x0023; static final byte SOURCE_FOLDER = 1; static final byte BINARY_FOLDER = 2; @@ -377,6 +377,38 @@ static State read(IProject project, DataInputStream in) throws IOException, Core readRestriction(in), new Path(in.readUTF()), in.readBoolean(), in.readUTF()); break; } + ClasspathLocation loc = newState.testBinaryLocations[i]; + char[] patchName = readName(in); + loc.patchModuleName = patchName.length > 0 ? new String(patchName) : null; + int limitSize = in.readInt(); + if (limitSize != 0) { + loc.limitModuleNames = new LinkedHashSet<>(limitSize); + for (int j = 0; j < limitSize; j++) { + loc.limitModuleNames.add(in.readUTF()); + } + } else { + loc.limitModuleNames = null; + } + IUpdatableModule.UpdatesByKind updates = new IUpdatableModule.UpdatesByKind(); + List<Consumer<IUpdatableModule>> packageUpdates = null; + int packageUpdatesSize = in.readInt(); + if (packageUpdatesSize != 0) { + packageUpdates = updates.getList(UpdateKind.PACKAGE, true); + for (int j = 0; j < packageUpdatesSize; j++) { + char[] pkgName = readName(in); + char[][] targets = readNames(in); + packageUpdates.add(new AddExports(pkgName, targets)); + } + } + List<Consumer<IUpdatableModule>> moduleUpdates = null; + int moduleUpdatesSize = in.readInt(); + if (moduleUpdatesSize != 0) { + moduleUpdates = updates.getList(UpdateKind.MODULE, true); + char[] modName = readName(in); + moduleUpdates.add(new AddReads(modName)); + } + if (packageUpdates != null || moduleUpdates != null) + loc.updates = updates; } newState.structuralBuildTimes = new SimpleLookupTable(length = in.readInt()); @@ -703,6 +735,55 @@ void write(DataOutputStream out) throws IOException { else out.writeUTF(""); //$NON-NLS-1$ } + char[] patchName = c.patchModuleName == null ? CharOperation.NO_CHAR : c.patchModuleName.toCharArray(); + writeName(patchName, out); + if (c.limitModuleNames != null) { + out.writeInt(c.limitModuleNames.size()); + for (String name : c.limitModuleNames) { + out.writeUTF(name); + } + } else { + out.writeInt(0); + } + if (c.updates != null) { + List<Consumer<IUpdatableModule>> pu = c.updates.getList(UpdateKind.PACKAGE, false); + if (pu != null) { + Map<String, List<Consumer<IUpdatableModule>>> map = pu.stream(). + collect(Collectors.groupingBy( + update -> CharOperation.charToString(((IUpdatableModule.AddExports)update).getName()))); + out.writeInt(map.size()); + map.entrySet().stream().forEach(entry -> { + String pkgName = entry.getKey(); + try { + writeName(pkgName.toCharArray(), out); + char[][] targetModules = entry.getValue().stream() + .map(consumer -> ((IUpdatableModule.AddExports) consumer).getTargetModules()) + .filter(targets -> targets != null) + .reduce((f,s) -> CharOperation.arrayConcat(f,s)) + .orElse(null); + writeNames(targetModules, out); + } catch (IOException e) { + // ignore + } + + }); + } else { + out.writeInt(0); + } + List<Consumer<IUpdatableModule>> mu = c.updates.getList(UpdateKind.MODULE, false); + if (mu != null) { + out.writeInt(mu.size()); + for (Consumer<IUpdatableModule> cons : mu) { + AddReads m = (AddReads) cons; + writeName(m.getTarget(), out); + } + } else { + out.writeInt(0); + } + } else { + out.writeInt(0); + out.writeInt(0); + } } /* |