Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Xenos2016-11-19 03:30:15 +0000
committerStefan Xenos2016-12-21 19:12:18 +0000
commitf7ed9839ef5f6bfc6dd1db3bdc1a458b7b45c64b (patch)
tree738529eaaa35d3557a4855aae0ad59df6e0b4a57
parent6ad94a9ef57eda351ed99bde761c01b798ba1ec1 (diff)
downloadeclipse.jdt.core-f7ed9839ef5f6bfc6dd1db3bdc1a458b7b45c64b.tar.gz
eclipse.jdt.core-f7ed9839ef5f6bfc6dd1db3bdc1a458b7b45c64b.tar.xz
eclipse.jdt.core-f7ed9839ef5f6bfc6dd1db3bdc1a458b7b45c64b.zip
Bug 507795 - Functional dynamic dependenciesI20161221-2000
Write the JDT core handler for dynamic dependencies. Change-Id: I661fa11ac9d5ad36c5b70ae0654a7dcec26aa4cf Signed-off-by: Stefan Xenos <sxenos@gmail.com>
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java2
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java2
-rw-r--r--org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java2
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ChangeClasspathOperation.java8
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java24
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java26
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DynamicProjectReferences.java31
-rw-r--r--org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java120
-rw-r--r--org.eclipse.jdt.core/plugin.xml1
9 files changed, 56 insertions, 160 deletions
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java
index 2cc72b8322..6cafb5bb0e 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathInitializerTests.java
@@ -1030,7 +1030,7 @@ public void testContainerInitializer25() throws CoreException {
assertResourcesEqual(
"Unexpected project references on startup",
"/P1",
- p2.getProject().getDescription().getDynamicReferences());
+ p2.getProject().getReferencedProjects());
} finally {
deleteProject("P1");
deleteProject("P2");
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
index 970c74f187..e6535c2cec 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/ClasspathTests.java
@@ -5663,7 +5663,7 @@ public void testUpdateProjectReferences() throws CoreException {
createJavaProject("P1");
IJavaProject p = createJavaProject("P2");
p.setRawClasspath(new IClasspathEntry[] {JavaCore.newProjectEntry(new Path("/P1"))}, null);
- IProject[] references = p.getProject().getDescription().getDynamicReferences();
+ IProject[] references = p.getProject().getReferencedProjects();
assertResourcesEqual(
"Unexpected resources",
"/P1",
diff --git a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java
index 9ea4398ee4..a15213f4ec 100644
--- a/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java
+++ b/org.eclipse.jdt.core.tests.model/src/org/eclipse/jdt/core/tests/model/JavaProjectTests.java
@@ -1797,7 +1797,7 @@ public void testProjectOpen() throws CoreException {
p2.open(null);
waitForManualRefresh();
waitForAutoBuild();
- IProject[] references = p2.getDescription().getDynamicReferences();
+ IProject[] references = p2.getReferencedProjects();
assertResourcesEqual(
"Unexpected referenced projects",
"/P1",
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ChangeClasspathOperation.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ChangeClasspathOperation.java
index 9e8b329a03..45740257b4 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ChangeClasspathOperation.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ChangeClasspathOperation.java
@@ -54,10 +54,7 @@ public abstract class ChangeClasspathOperation extends JavaModelOperation {
// delta, indexing and classpath markers are going to be created by the delta processor
// while handling the resource change (either .classpath change, or project touched)
- // however ensure project references are updated
- // since some clients rely on the project references when run inside an IWorkspaceRunnable
- new ProjectReferenceChange(project, change.oldResolvedClasspath).updateProjectReferencesIfNecessary();
-
+ project.getProject().clearCachedDynamicReferences();
// and ensure that external folders are updated as well
new ExternalFolderChange(project, change.oldResolvedClasspath).updateExternalFoldersIfNecessary(refreshExternalFolder, null);
@@ -80,7 +77,8 @@ public abstract class ChangeClasspathOperation extends JavaModelOperation {
}
if ((result & ClasspathChange.HAS_PROJECT_CHANGE) != 0) {
// ensure project references are updated on next build
- state.addProjectReferenceChange(project, change.oldResolvedClasspath);
+ project.getProject().clearCachedDynamicReferences();
+ state.addProjectReferenceChange(project);
}
if ((result & ClasspathChange.HAS_LIBRARY_CHANGE) != 0) {
// ensure external folders are updated on next build
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
index bfcd867b31..22a6828598 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessingState.java
@@ -102,7 +102,7 @@ public class DeltaProcessingState implements IResourceChangeListener, Indexer.Li
private HashMap classpathValidations = new HashMap();
/* A table from JavaProject to ProjectReferenceChange */
- private HashMap projectReferenceChanges = new HashMap();
+ private HashSet<IJavaProject> projectReferenceChanges = new HashSet<>();
/* A table from JavaProject to ExternalFolderChange */
private HashMap externalFolderChanges = new HashMap();
@@ -228,15 +228,11 @@ public class DeltaProcessingState implements IResourceChangeListener, Indexer.Li
if (change == null) {
change = new ExternalFolderChange(project, oldResolvedClasspath);
this.externalFolderChanges.put(project, change);
- }
+ }
}
- public synchronized void addProjectReferenceChange(JavaProject project, IClasspathEntry[] oldResolvedClasspath) {
- ProjectReferenceChange change = (ProjectReferenceChange) this.projectReferenceChanges.get(project);
- if (change == null) {
- change = new ProjectReferenceChange(project, oldResolvedClasspath);
- this.projectReferenceChanges.put(project, change);
- }
+ public synchronized void addProjectReferenceChange(IJavaProject project) {
+ this.projectReferenceChanges.add(project);
}
public void initializeRoots(boolean initAfterLoad) {
@@ -387,13 +383,10 @@ public class DeltaProcessingState implements IResourceChangeListener, Indexer.Li
return updates;
}
- public synchronized ProjectReferenceChange[] removeProjectReferenceChanges() {
- int length = this.projectReferenceChanges.size();
- if (length == 0) return null;
- ProjectReferenceChange[] updates = new ProjectReferenceChange[length];
- this.projectReferenceChanges.values().toArray(updates);
- this.projectReferenceChanges.clear();
- return updates;
+ public synchronized Set<IJavaProject> removeProjectReferenceChanges() {
+ Set<IJavaProject> result = this.projectReferenceChanges;
+ this.projectReferenceChanges = new HashSet<>();
+ return result;
}
public synchronized HashSet removeExternalElementsToRefresh() {
@@ -656,5 +649,4 @@ public class DeltaProcessingState implements IResourceChangeListener, Indexer.Li
this.deltaProcessors.set(null);
}
}
-
}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
index 5311235038..59fe26bb94 100644
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DeltaProcessor.java
@@ -591,8 +591,8 @@ public class DeltaProcessor {
}
private void checkProjectReferenceChange(IProject project, JavaProject javaProject) {
- ClasspathChange change = this.state.getClasspathChange(project);
- this.state.addProjectReferenceChange(javaProject, change == null ? null : change.oldResolvedClasspath);
+ project.clearCachedDynamicReferences();
+ this.state.addProjectReferenceChange(javaProject);
}
private void readRawClasspath(JavaProject javaProject) {
@@ -2080,7 +2080,8 @@ public class DeltaProcessor {
this.state.addClasspathValidation(change.project);
}
if ((result & ClasspathChange.HAS_PROJECT_CHANGE) != 0) {
- this.state.addProjectReferenceChange(change.project, change.oldResolvedClasspath);
+ change.project.getProject().clearCachedDynamicReferences();
+ this.state.addProjectReferenceChange(change.project);
}
if ((result & ClasspathChange.HAS_LIBRARY_CHANGE) != 0) {
this.state.addExternalFolderChange(change.project, change.oldResolvedClasspath);
@@ -2145,20 +2146,13 @@ public class DeltaProcessor {
}
// update project references if necessary
- ProjectReferenceChange[] projectRefChanges = this.state.removeProjectReferenceChanges();
- if (projectRefChanges != null) {
- for (int i = 0, length = projectRefChanges.length; i < length; i++) {
- try {
- projectRefChanges[i].updateProjectReferencesIfNecessary();
- } catch(JavaModelException e) {
- // project doesn't exist any longer, continue with next one
- if (!e.isDoesNotExist())
- Util.log(e, "Exception while updating project references"); //$NON-NLS-1$
- }
- }
- }
+ Set<IJavaProject> referencedProjects = this.state.removeProjectReferenceChanges();
+ needCycleValidation = needCycleValidation || !referencedProjects.isEmpty();
- if (needCycleValidation || projectRefChanges != null) {
+ if (needCycleValidation) {
+ for (IJavaProject next : referencedProjects) {
+ next.getProject().clearCachedDynamicReferences();
+ }
// update all cycle markers since the project references changes may have affected cycles
try {
JavaProject.validateCycles(null);
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DynamicProjectReferences.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DynamicProjectReferences.java
new file mode 100644
index 0000000000..41e63ea6ed
--- /dev/null
+++ b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/DynamicProjectReferences.java
@@ -0,0 +1,31 @@
+package org.eclipse.jdt.internal.core;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.eclipse.core.resources.IBuildConfiguration;
+import org.eclipse.core.resources.IDynamicReferenceProvider;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.JavaCore;
+
+public class DynamicProjectReferences implements IDynamicReferenceProvider {
+ @Override
+ public List<IProject> getDependentProjects(IBuildConfiguration buildConfiguration) throws CoreException {
+ IProject input = buildConfiguration.getProject();
+ IJavaProject javaProject = JavaCore.create(input);
+ if (javaProject instanceof JavaProject) {
+ JavaProject project = (JavaProject) javaProject;
+
+ String[] required = project.projectPrerequisites(project.getResolvedClasspath());
+
+ IWorkspaceRoot wksRoot = input.getWorkspace().getRoot();
+ return Arrays.stream(required).sorted().map(name -> wksRoot.getProject(name)).collect(Collectors.toList());
+ }
+ return Collections.emptyList();
+ }
+}
diff --git a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java b/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java
deleted file mode 100644
index 548f383940..0000000000
--- a/org.eclipse.jdt.core/model/org/eclipse/jdt/internal/core/ProjectReferenceChange.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2013 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.internal.core;
-
-import java.util.HashSet;
-import java.util.Iterator;
-
-import org.eclipse.core.resources.IProject;
-import org.eclipse.core.resources.IProjectDescription;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.IWorkspace;
-import org.eclipse.core.resources.IWorkspaceRoot;
-import org.eclipse.core.resources.IWorkspaceRunnable;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IProgressMonitor;
-import org.eclipse.core.runtime.jobs.ISchedulingRule;
-import org.eclipse.jdt.core.IClasspathEntry;
-import org.eclipse.jdt.core.JavaModelException;
-import org.eclipse.jdt.core.compiler.CharOperation;
-import org.eclipse.jdt.internal.core.util.Util;
-
-@SuppressWarnings({"rawtypes", "unchecked"})
-public class ProjectReferenceChange {
-
- private JavaProject project;
- private IClasspathEntry[] oldResolvedClasspath;
-
- public ProjectReferenceChange(JavaProject project, IClasspathEntry[] oldResolvedClasspath) {
- this.project = project;
- this.oldResolvedClasspath = oldResolvedClasspath;
- }
-
- /*
- * Update projects references so that the build order is consistent with the classpath
- */
- public void updateProjectReferencesIfNecessary() throws JavaModelException {
-
- String[] oldRequired = this.oldResolvedClasspath == null ? CharOperation.NO_STRINGS : this.project.projectPrerequisites(this.oldResolvedClasspath);
- IClasspathEntry[] newResolvedClasspath = this.project.getResolvedClasspath();
- String[] newRequired = this.project.projectPrerequisites(newResolvedClasspath);
- final IProject projectResource = this.project.getProject();
-
- try {
- IProject[] projectReferences = projectResource.getDescription().getDynamicReferences();
-
- HashSet oldReferences = new HashSet(projectReferences.length);
- for (int i = 0; i < projectReferences.length; i++){
- String projectName = projectReferences[i].getName();
- oldReferences.add(projectName);
- }
- HashSet newReferences = (HashSet)oldReferences.clone();
-
- for (int i = 0; i < oldRequired.length; i++){
- String projectName = oldRequired[i];
- newReferences.remove(projectName);
- }
- for (int i = 0; i < newRequired.length; i++){
- String projectName = newRequired[i];
- newReferences.add(projectName);
- }
-
- Iterator iter;
- int newSize = newReferences.size();
-
- checkIdentity: {
- if (oldReferences.size() == newSize){
- iter = newReferences.iterator();
- while (iter.hasNext()){
- if (!oldReferences.contains(iter.next())){
- break checkIdentity;
- }
- }
- return;
- }
- }
- String[] requiredProjectNames = new String[newSize];
- int index = 0;
- iter = newReferences.iterator();
- while (iter.hasNext()){
- requiredProjectNames[index++] = (String)iter.next();
- }
- Util.sort(requiredProjectNames); // ensure that if changed, the order is consistent
-
- final IProject[] requiredProjectArray = new IProject[newSize];
- IWorkspaceRoot wksRoot = projectResource.getWorkspace().getRoot();
- for (int i = 0; i < newSize; i++){
- requiredProjectArray[i] = wksRoot.getProject(requiredProjectNames[i]);
- }
-
- // ensure that a scheduling rule is used so that the project description is not modified by another thread while we update it
- // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=214981
- // also ensure that if no change (checkIdentify block returned above) we don't reach here
- // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=241751
- IWorkspace workspace = projectResource.getWorkspace();
- ISchedulingRule rule = workspace.getRuleFactory().modifyRule(projectResource); // scheduling rule for modifying the project
- IWorkspaceRunnable runnable = new IWorkspaceRunnable() {
- public void run(IProgressMonitor monitor) throws CoreException {
- IProjectDescription description = projectResource.getDescription();
- description.setDynamicReferences(requiredProjectArray);
- projectResource.setDescription(description, IResource.AVOID_NATURE_CONFIG, null);
- }
- };
- workspace.run(runnable, rule, IWorkspace.AVOID_UPDATE, null);
- } catch(CoreException e){
- if (!ExternalJavaProject.EXTERNAL_PROJECT_NAME.equals(this.project.getElementName()))
- throw new JavaModelException(e);
- }
- }
- public String toString() {
- return "ProjectRefenceChange: " + this.project.getElementName(); //$NON-NLS-1$
- }
-}
diff --git a/org.eclipse.jdt.core/plugin.xml b/org.eclipse.jdt.core/plugin.xml
index 76e3e99149..318c37352f 100644
--- a/org.eclipse.jdt.core/plugin.xml
+++ b/org.eclipse.jdt.core/plugin.xml
@@ -101,6 +101,7 @@
<builder>
<run class="org.eclipse.jdt.internal.core.builder.JavaBuilder">
</run>
+ <dynamicReference class="org.eclipse.jdt.internal.core.DynamicProjectReferences"/>
</builder>
</extension>

Back to the top