Skip to content

Commit 854a6b0

Browse files
author
Amarin Phaosawasdi
committed
Merge branch 'fixparallel'
2 parents cf88cc8 + 86ec6f5 commit 854a6b0

File tree

15 files changed

+295
-159
lines changed

15 files changed

+295
-159
lines changed

plugins/checker.framework.change.propagator/src/checker/framework/change/propagator/ComputeQuickFixesJob.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package checker.framework.change.propagator;
22

33
import org.checkerframework.eclipse.actions.CheckerWorker;
4-
import org.checkerframework.eclipse.util.MutexSchedulingRule;
54
import org.eclipse.core.runtime.IProgressMonitor;
65
import org.eclipse.core.runtime.IStatus;
76
import org.eclipse.core.runtime.Status;
@@ -13,8 +12,8 @@ public class ComputeQuickFixesJob extends Job {
1312

1413
private String checkerID;
1514

16-
public ComputeQuickFixesJob(String name, ShadowOfShadowProject shadowProject,
17-
String checkerID) {
15+
public ComputeQuickFixesJob(String name,
16+
ShadowOfShadowProject shadowProject, String checkerID) {
1817
super(name);
1918
this.shadowProject = shadowProject;
2019
this.checkerID = checkerID;
@@ -27,9 +26,7 @@ private String[] getShadowSourceFiles() {
2726
private CheckerWorker getCheckerWorker() {
2827
CheckerWorker checkerJob = new CheckerWorker(
2928
shadowProject.getProject(), getShadowSourceFiles(), checkerID);
30-
checkerJob.setUser(true);
3129
checkerJob.setPriority(Job.BUILD);
32-
checkerJob.setRule(new MutexSchedulingRule());
3330
return checkerJob;
3431
}
3532

plugins/checker.framework.change.propagator/src/checker/framework/change/propagator/ShadowOfShadowProject.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ public void runChecker(String checkerID) {
2222
ComputeQuickFixesJob computeQuickFixesJob = new ComputeQuickFixesJob(
2323
"ComputeQuickFixes of " + getProject().getElementName(), this,
2424
checkerID);
25-
computeQuickFixesJob.setUser(true);
2625
computeQuickFixesJob.setPriority(Job.BUILD);
2726
computeQuickFixesJob.schedule();
2827
try {

plugins/checker.framework.errorcentric.view/META-INF/MANIFEST.MF

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Require-Bundle: org.eclipse.ui,
1717
checker.framework.quickfixes,
1818
com.google.guava,
1919
org.eclipse.jdt.ui,
20-
org.eclipse.ui.workbench.texteditor
20+
org.eclipse.ui.workbench.texteditor,
21+
org.eclipse.ltk.core.refactoring
2122
Bundle-ActivationPolicy: lazy
22-
Import-Package: org.apache.commons.lang3.builder
23+
Import-Package: org.apache.commons.lang3.builder,
24+
org.eclipse.jdt.core.refactoring

plugins/checker.framework.errorcentric.view/src/checker/framework/errorcentric/view/Messages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
public class Messages extends NLS {
66
private static final String BUNDLE_NAME = "checker.framework.errorcentric.view.messages"; //$NON-NLS-1$
7+
public static String ErrorCentricView_compute_change_effect_progress_bar_label;
78
public static String ErrorCentricView_refresh_icon;
89
public static String ErrorCentricView_refresh_text;
910
public static String ErrorCentricView_refresh_tool_tip;

plugins/checker.framework.errorcentric.view/src/checker/framework/errorcentric/view/messages.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
ErrorCentricView_compute_change_effect_progress_bar_label=Computing the effect of: {0}
12
ErrorCentricView_refresh_icon=icons/refresh.gif
23
ErrorCentricView_refresh_text=Refresh
34
ErrorCentricView_refresh_tool_tip=Refresh
Lines changed: 94 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,5 @@
11
package checker.framework.errorcentric.view.views;
22

3-
import static com.google.common.collect.Iterables.filter;
4-
import static com.google.common.collect.Iterables.transform;
5-
import static com.google.common.collect.Sets.difference;
6-
import static com.google.common.collect.Sets.newHashSet;
7-
import static com.google.common.collect.Sets.union;
8-
93
import java.util.HashSet;
104
import java.util.List;
115
import java.util.Set;
@@ -23,44 +17,99 @@
2317

2418
import com.google.common.base.Predicate;
2519

20+
import static com.google.common.collect.Sets.difference;
21+
import static com.google.common.collect.Sets.filter;
22+
import static com.google.common.collect.Sets.newHashSet;
23+
import static com.google.common.collect.Sets.union;
24+
25+
import static com.google.common.collect.Iterables.transform;
26+
2627
public class ChangeComputationJob extends Job {
2728

2829
private MarkerResolutionTreeNode markerResolutionTreeNode;
2930

31+
// We are using our own synchronization here. See MarkerResolutionTreeNode
32+
// for more detaila.
33+
private static Object lock = new Object();
34+
3035
public ChangeComputationJob(String name,
3136
MarkerResolutionTreeNode markerResolutionTreeNode) {
3237
super(name);
3338
this.markerResolutionTreeNode = markerResolutionTreeNode;
3439
}
3540

36-
// TODO(reprogrammer): I suggest that we break this method into several
37-
// smaller ones.
3841
@Override
3942
protected IStatus run(IProgressMonitor monitor) {
40-
monitor.beginTask(getName(), 25);
41-
final List<FixerDescriptor> parentFixerDescriptors = markerResolutionTreeNode
42-
.getParentFixerDescriptors();
43-
ActionableMarkerResolution resolution = markerResolutionTreeNode
44-
.getResolution();
45-
resolution.getShadowProject().updateToPrimaryProjectWithChanges(
46-
parentFixerDescriptors);
47-
monitor.worked(3);
48-
resolution.apply();
49-
monitor.worked(3);
50-
// WorkspaceUtils.saveAllEditors();
51-
monitor.worked(3);
52-
ShadowOfShadowProject shadowProject = resolution.getShadowProject();
53-
shadowProject.runChecker(InferCommandHandler.checkerID);
54-
monitor.worked(10);
55-
Set<ComparableMarker> allMarkersAfterResolution = shadowProject
56-
.getMarkers();
57-
Set<ComparableMarker> addedMarkers = difference(
58-
allMarkersAfterResolution,
59-
resolution.getAllMarkersBeforeResolution());
43+
synchronized (lock) {
44+
monitor.beginTask(getName(), 23);
45+
monitor.subTask("Updating shadow project: " + getThread());
46+
final List<FixerDescriptor> parentFixerDescriptors = markerResolutionTreeNode
47+
.getParentFixerDescriptors();
48+
ActionableMarkerResolution resolution = markerResolutionTreeNode
49+
.getResolution();
50+
ShadowOfShadowProject shadowProject = runChecker(monitor,
51+
parentFixerDescriptors, resolution);
52+
monitor.subTask("Getting new markers: " + getThread());
53+
Set<ComparableMarker> allMarkersAfterResolution = shadowProject
54+
.getMarkers();
55+
Set<ComparableMarker> addedMarkers = difference(
56+
allMarkersAfterResolution,
57+
resolution.getAllMarkersBeforeResolution());
58+
monitor.worked(1);
59+
HashSet<ActionableMarkerResolution> historicallyNewResolutions = computeResolutions(
60+
monitor, parentFixerDescriptors, resolution, shadowProject,
61+
allMarkersAfterResolution, addedMarkers);
62+
addChildrenToTree(monitor, resolution, addedMarkers,
63+
historicallyNewResolutions);
64+
monitor.done();
65+
return Status.OK_STATUS;
66+
}
67+
}
68+
69+
private void addChildrenToTree(IProgressMonitor monitor,
70+
ActionableMarkerResolution resolution,
71+
Set<ComparableMarker> addedMarkers,
72+
HashSet<ActionableMarkerResolution> historicallyNewResolutions) {
73+
monitor.subTask("Adding children to tree: " + getThread());
74+
Set<ComparableMarker> fixedMarkers = newHashSet();
75+
for (ActionableMarkerResolution historicallyNewResolution : historicallyNewResolutions) {
76+
fixedMarkers.addAll(historicallyNewResolution
77+
.getMarkersToBeResolvedByFixer());
78+
}
79+
Set<ComparableMarker> unresolvedMarkers = difference(addedMarkers,
80+
fixedMarkers);
81+
Set<ErrorTreeNode> errorTreeNodesWithoutResolutions = newHashSet(transform(
82+
unresolvedMarkers, marker -> new AddedErrorTreeNode(marker)));
83+
TreeUpdater treeUpdater = markerResolutionTreeNode.getTreeUpdater();
84+
HashSet<ErrorTreeNode> errorTreeNodesWithResolutions = newHashSet(AddedErrorTreeNode
85+
.createTreeNodesFrom(historicallyNewResolutions, treeUpdater));
86+
markerResolutionTreeNode
87+
.addChildren(union(errorTreeNodesWithResolutions,
88+
errorTreeNodesWithoutResolutions));
89+
int errorsFixed = resolution.getMarkersToBeResolvedByFixer().size();
90+
markerResolutionTreeNode.setFixedErrorsCount(errorsFixed);
91+
markerResolutionTreeNode.addErrorCountToLabel();
6092
monitor.worked(1);
93+
treeUpdater.recomputeDisabledNodes();
94+
// Since recomputeDisabledNodes makes a call to viewer.refresh(),
95+
// we do not need to call update() any more.
96+
// treeUpdater.update(markerResolutionTreeNode);
97+
monitor.worked(1);
98+
}
99+
100+
private HashSet<ActionableMarkerResolution> computeResolutions(
101+
IProgressMonitor monitor,
102+
final List<FixerDescriptor> parentFixerDescriptors,
103+
ActionableMarkerResolution resolution,
104+
ShadowOfShadowProject shadowProject,
105+
Set<ComparableMarker> allMarkersAfterResolution,
106+
Set<ComparableMarker> addedMarkers) {
107+
monitor.subTask("Getting new resolutions: " + getThread());
61108
Set<ActionableMarkerResolution> newResolutions = shadowProject
62109
.getResolutions(allMarkersAfterResolution, addedMarkers);
110+
yieldRule(monitor);
63111
monitor.worked(3);
112+
monitor.subTask("Filtering resolutions: " + getThread());
64113
HashSet<ActionableMarkerResolution> historicallyNewResolutions = newHashSet(filter(
65114
newResolutions, new Predicate<ActionableMarkerResolution>() {
66115
@Override
@@ -75,34 +124,23 @@ public boolean apply(
75124
}
76125
}));
77126
monitor.worked(1);
78-
Set<ComparableMarker> fixedMarkers = newHashSet();
79-
for (ActionableMarkerResolution historicallyNewResolution : historicallyNewResolutions) {
80-
fixedMarkers.addAll(historicallyNewResolution
81-
.getMarkersToBeResolvedByFixer());
82-
}
83-
Set<ComparableMarker> unresolvedMarkers = difference(addedMarkers,
84-
fixedMarkers);
85-
Set<ErrorTreeNode> errorTreeNodesWithoutResolutions = newHashSet(transform(
86-
unresolvedMarkers, marker -> new AddedErrorTreeNode(marker)));
87-
HashSet<ErrorTreeNode> errorTreeNodesWithResolutions = newHashSet(AddedErrorTreeNode
88-
.createTreeNodesFrom(historicallyNewResolutions,
89-
markerResolutionTreeNode.getTreeUpdater()));
90-
markerResolutionTreeNode
91-
.addChildren(union(errorTreeNodesWithResolutions,
92-
errorTreeNodesWithoutResolutions));
93-
int errorsFixed = resolution.getMarkersToBeResolvedByFixer().size();
94-
markerResolutionTreeNode.setFixedErrorsCount(errorsFixed);
95-
markerResolutionTreeNode.setName(markerResolutionTreeNode.getName()
96-
+ " (" + errorsFixed + ")");
97-
// TODO(reprogrammer): I suggest to redesign the classes such that the
98-
// following statement doesn't duplicate the reference to
99-
// markerResolutionTreeNode.
100-
markerResolutionTreeNode.getTreeUpdater().update(
101-
markerResolutionTreeNode);
102-
monitor.worked(1);
103-
monitor.done();
104-
JobManager.done(markerResolutionTreeNode);
105-
return Status.OK_STATUS;
127+
return historicallyNewResolutions;
128+
}
129+
130+
private ShadowOfShadowProject runChecker(IProgressMonitor monitor,
131+
final List<FixerDescriptor> parentFixerDescriptors,
132+
ActionableMarkerResolution resolution) {
133+
resolution.getShadowProject().updateToPrimaryProjectWithChanges(
134+
parentFixerDescriptors);
135+
monitor.worked(3);
136+
monitor.subTask("Applying resolution: " + getThread());
137+
resolution.apply();
138+
monitor.worked(3);
139+
monitor.subTask("Running checker: " + getThread());
140+
ShadowOfShadowProject shadowProject = resolution.getShadowProject();
141+
shadowProject.runChecker(InferCommandHandler.checkerID);
142+
monitor.worked(10);
143+
return shadowProject;
106144
}
107145

108146
}

plugins/checker.framework.errorcentric.view/src/checker/framework/errorcentric/view/views/ChangeStateViewer.java

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,50 @@
11
package checker.framework.errorcentric.view.views;
22

3-
import static com.google.common.collect.Sets.difference;
4-
import static com.google.common.collect.Sets.newHashSet;
5-
63
import java.util.Collection;
74
import java.util.HashSet;
5+
import java.util.Map;
86
import java.util.Set;
97

108
import org.eclipse.jface.viewers.TreeViewer;
11-
import org.eclipse.swt.graphics.Color;
12-
import org.eclipse.swt.widgets.TreeItem;
9+
import org.eclipse.swt.widgets.Display;
10+
11+
import static com.google.common.collect.Sets.difference;
12+
import static com.google.common.collect.Sets.newHashSet;
13+
14+
import static com.google.common.collect.Maps.newHashMap;
1315

1416
public class ChangeStateViewer {
1517
private Set<TreeObject> disabledNodes;
1618
private TreeViewer viewer;
19+
private Map<MarkerResolutionTreeNode, Set<TreeObject>> disabledNodesMap;
1720

1821
public ChangeStateViewer(TreeViewer viewer) {
1922
this.disabledNodes = newHashSet();
2023
this.viewer = viewer;
24+
this.disabledNodesMap = newHashMap();
2125
}
2226

2327
public void resetState() {
2428
disabledNodes.clear();
2529
}
2630

27-
public Set<TreeObject> disableChange(
28-
MarkerResolutionTreeNode resolutionTreeNode) {
31+
public void recomputeDisabledChanges() {
32+
Set<TreeObject> treeObjects = newHashSet(disabledNodes);
33+
for (TreeObject treeObject : treeObjects) {
34+
if (treeObject instanceof MarkerResolutionTreeNode) {
35+
disableChange((MarkerResolutionTreeNode) treeObject);
36+
}
37+
}
38+
}
39+
40+
/**
41+
* Disables a change node and (1) all the errors it fixes (2) all the other
42+
* "equivalent" change node in the tree, i.e. is the same change and fixes
43+
* the same set of errors (3) all the errors that (2) fixes
44+
*
45+
* @param resolutionTreeNode
46+
*/
47+
public void disableChange(MarkerResolutionTreeNode resolutionTreeNode) {
2948
// init
3049
Set<TreeObject> clonedDisabledNodes = newHashSet(disabledNodes);
3150
clonedDisabledNodes.add(resolutionTreeNode);
@@ -39,8 +58,16 @@ public Set<TreeObject> disableChange(
3958
clonedDisabledNodes, disabledNodes));
4059
// swap the clone
4160
disabledNodes = clonedDisabledNodes;
42-
viewer.refresh();
43-
return newDisabledNodes;
61+
Display.getDefault().syncExec(new Runnable() {
62+
public void run() {
63+
viewer.refresh();
64+
}
65+
});
66+
if (disabledNodesMap.containsKey(resolutionTreeNode)) {
67+
disabledNodesMap.get(resolutionTreeNode).addAll(newDisabledNodes);
68+
} else {
69+
disabledNodesMap.put(resolutionTreeNode, newDisabledNodes);
70+
}
4471
}
4572

4673
private boolean canAddRelatedNodes(Set<TreeObject> nodes) {
@@ -65,16 +92,21 @@ private boolean canAddRelatedNodes(Set<TreeObject> nodes) {
6592
}
6693
}
6794

68-
public void enableChange(Set<TreeObject> nodesToBeEnabled) {
95+
private void enableChange(Set<TreeObject> nodesToBeEnabled) {
6996
disabledNodes.removeAll(nodesToBeEnabled);
7097
viewer.refresh();
7198
}
7299

100+
public void enableChange(MarkerResolutionTreeNode markerResolutionTreeNode) {
101+
Set<TreeObject> disabledNodesToBeEnabled = disabledNodesMap
102+
.get(markerResolutionTreeNode);
103+
enableChange(disabledNodesToBeEnabled);
104+
}
105+
73106
private Set<TreeObject> getRelatedNodes(Set<TreeObject> nodes) {
74107
Set<TreeObject> relatedNodes = new HashSet<>();
75-
relatedNodes.addAll(getRelatedNodes(
76-
((MarkerResolutionTreeNode) viewer.getInput()).getChildren(),
77-
nodes));
108+
relatedNodes.addAll(getRelatedNodes(((MarkerResolutionTreeNode) viewer
109+
.getInput()).getExistingChildren(), nodes));
78110
return relatedNodes;
79111
}
80112

@@ -90,28 +122,11 @@ private Set<TreeObject> getRelatedNodes(TreeObject[] candidates,
90122
relatedNodes.addAll(errorsFixed);
91123
}
92124
}
93-
relatedNodes.addAll(getRelatedNodes(candidate.getChildren(),
94-
existingNodes));
95-
}
96-
return relatedNodes;
97-
}
98125

99-
private void setNodeColor(Set<TreeObject> nodes, Color color) {
100-
setNodeColor(viewer.getTree().getItems(), nodes, color);
101-
}
102-
103-
private void setNodeColor(TreeItem[] items, Set<TreeObject> nodes,
104-
Color color) {
105-
for (TreeItem item : items) {
106-
if (nodes.contains(item.getData())) {
107-
setNodeColor(item, color);
108-
}
109-
setNodeColor(item.getItems(), nodes, color);
126+
relatedNodes.addAll(getRelatedNodes(
127+
candidate.getExistingChildren(), existingNodes));
110128
}
111-
}
112-
113-
private void setNodeColor(TreeItem item, Color color) {
114-
item.setForeground(color);
129+
return relatedNodes;
115130
}
116131

117132
public boolean isDisabled(TreeObject treeObject) {

0 commit comments

Comments
 (0)