11package 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-
93import java .util .HashSet ;
104import java .util .List ;
115import java .util .Set ;
2317
2418import 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+
2627public 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}
0 commit comments