22
22
import java .util .Collections ;
23
23
import java .util .LinkedList ;
24
24
import java .util .List ;
25
+ import java .util .concurrent .atomic .AtomicReference ;
25
26
import java .util .logging .Level ;
26
27
import java .util .logging .Logger ;
27
28
import org .netbeans .api .java .source .CancellableTask ;
28
29
import org .netbeans .api .java .source .CompilationInfo ;
29
30
import org .netbeans .api .java .source .JavaSource .Phase ;
30
31
import org .netbeans .api .java .source .JavaSource .Priority ;
31
32
import org .netbeans .api .java .source .JavaSourceTaskFactory ;
33
+ import org .netbeans .modules .parsing .spi .TaskIndexingMode ;
32
34
import org .openide .filesystems .FileObject ;
33
35
import org .openide .filesystems .FileUtil ;
34
36
import org .openide .util .Lookup ;
@@ -49,18 +51,34 @@ public class RunOnceFactory extends JavaSourceTaskFactory {
49
51
private CancellableTask <CompilationInfo > task ;
50
52
51
53
public RunOnceFactory () {
52
- super (Phase .RESOLVED , Priority .BELOW_NORMAL );
54
+ super (Phase .RESOLVED , Priority .BELOW_NORMAL , TaskIndexingMode . ALLOWED_DURING_SCAN );
53
55
// INSTANCE = this;
54
56
}
55
57
56
- protected synchronized CancellableTask <CompilationInfo > createTask (FileObject file ) {
57
- final CancellableTask <CompilationInfo > task = this .task ;
58
+ protected CancellableTask <CompilationInfo > createTask (FileObject file ) {
58
59
return new CancellableTask <CompilationInfo >() {
60
+ private final AtomicReference <CancellableTask <CompilationInfo >> currentTask =
61
+ new AtomicReference <>();
62
+
59
63
public void cancel () {
60
- task .cancel ();
64
+ CancellableTask <CompilationInfo > task = currentTask .get ();
65
+
66
+ if (task != null ) {
67
+ task .cancel ();
68
+ }
61
69
}
62
70
public void run (CompilationInfo parameter ) throws Exception {
71
+ CancellableTask <CompilationInfo > task ;
72
+
73
+ synchronized (RunOnceFactory .this ) {
74
+ task = RunOnceFactory .this .task ;
75
+ }
76
+
77
+ currentTask .set (task );
78
+
63
79
task .run (parameter );
80
+
81
+ currentTask .set (null );
64
82
next ();
65
83
}
66
84
};
@@ -87,25 +105,30 @@ private synchronized void addImpl(FileObject file, CancellableTask<CompilationIn
87
105
private synchronized void next () {
88
106
LOG .fine ("next, phase 1" );
89
107
90
- if (currentFile != null ) {
91
- currentFile = null ;
92
- task = null ;
93
- fileObjectsChanged () ;
94
- }
95
-
96
- LOG . fine ( "next, phase 1 done" );
108
+ if (work . isEmpty () ) {
109
+ if ( currentFile ! = null ) {
110
+ LOG . fine ( "clearing current file" ) ;
111
+ currentFile = null ;
112
+ task = null ;
113
+ fileObjectsChanged ();
114
+ }
97
115
98
- if ( work . isEmpty ())
116
+ LOG . fine ( "work is empty" );
99
117
return ;
118
+ }
100
119
101
120
LOG .fine ("next, phase 2" );
102
121
103
122
Pair <FileObject , CancellableTask <CompilationInfo >> p = work .remove (0 );
104
123
105
- currentFile = p .first ();
106
124
task = p .second ();
107
125
108
- fileObjectsChanged ();
126
+ if (currentFile == p .first ()) {
127
+ reschedule (currentFile );
128
+ } else {
129
+ currentFile = p .first ();
130
+ fileObjectsChanged ();
131
+ }
109
132
110
133
LOG .fine ("next, phase 2 done" );
111
134
}
0 commit comments