Lines 44-136
Link Here
|
44 |
|
44 |
|
45 |
import java.io.File; |
45 |
import java.io.File; |
46 |
import java.io.IOException; |
46 |
import java.io.IOException; |
47 |
import java.net.URL; |
|
|
48 |
import java.util.Set; |
47 |
import java.util.Set; |
|
|
48 |
import java.util.concurrent.atomic.AtomicReference; |
49 |
import javax.lang.model.element.Element; |
49 |
import javax.lang.model.element.ElementKind; |
50 |
import javax.lang.model.element.ElementKind; |
50 |
import javax.lang.model.element.Modifier; |
51 |
import javax.lang.model.element.Modifier; |
51 |
import javax.lang.model.element.TypeElement; |
52 |
import javax.lang.model.element.TypeElement; |
52 |
import javax.swing.Icon; |
53 |
import javax.swing.Icon; |
|
|
54 |
import javax.swing.event.ChangeListener; |
53 |
import org.netbeans.api.annotations.common.CheckForNull; |
55 |
import org.netbeans.api.annotations.common.CheckForNull; |
54 |
import org.netbeans.api.annotations.common.NonNull; |
56 |
import org.netbeans.api.annotations.common.NonNull; |
55 |
import org.netbeans.api.annotations.common.NullAllowed; |
57 |
import org.netbeans.api.annotations.common.NullAllowed; |
56 |
import org.netbeans.api.java.classpath.ClassPath; |
58 |
import org.netbeans.api.java.classpath.ClassPath; |
57 |
import org.netbeans.api.java.source.ClasspathInfo; |
59 |
import org.netbeans.api.java.source.ClasspathInfo; |
|
|
60 |
import org.netbeans.api.java.source.CompilationController; |
58 |
import org.netbeans.api.java.source.ElementHandle; |
61 |
import org.netbeans.api.java.source.ElementHandle; |
|
|
62 |
import org.netbeans.api.java.source.JavaSource; |
59 |
import org.netbeans.api.java.source.SourceUtils; |
63 |
import org.netbeans.api.java.source.SourceUtils; |
|
|
64 |
import org.netbeans.api.java.source.Task; |
60 |
import org.netbeans.api.java.source.ui.ElementOpen; |
65 |
import org.netbeans.api.java.source.ui.ElementOpen; |
61 |
import org.netbeans.api.project.Project; |
66 |
import org.netbeans.api.project.Project; |
62 |
import org.netbeans.api.project.ProjectInformation; |
67 |
import org.netbeans.api.project.ProjectInformation; |
63 |
import org.netbeans.api.project.ProjectUtils; |
68 |
import org.netbeans.modules.java.source.indexing.TransactionContext; |
|
|
69 |
import org.netbeans.modules.java.source.parsing.FileManagerTransaction; |
64 |
import org.netbeans.modules.java.source.parsing.FileObjects; |
70 |
import org.netbeans.modules.java.source.parsing.FileObjects; |
|
|
71 |
import org.netbeans.modules.java.source.parsing.ProcessorGenerated; |
65 |
import org.netbeans.modules.java.source.usages.ClassIndexImpl; |
72 |
import org.netbeans.modules.java.source.usages.ClassIndexImpl; |
|
|
73 |
import org.netbeans.modules.java.source.usages.ClasspathInfoAccessor; |
66 |
import org.netbeans.modules.java.ui.Icons; |
74 |
import org.netbeans.modules.java.ui.Icons; |
67 |
import org.netbeans.spi.java.classpath.support.ClassPathSupport; |
75 |
import org.netbeans.spi.java.classpath.support.ClassPathSupport; |
|
|
76 |
import org.netbeans.spi.jumpto.support.AsyncDescriptor; |
68 |
import org.netbeans.spi.jumpto.symbol.SymbolDescriptor; |
77 |
import org.netbeans.spi.jumpto.symbol.SymbolDescriptor; |
69 |
import org.openide.filesystems.FileObject; |
78 |
import org.openide.filesystems.FileObject; |
70 |
import org.openide.filesystems.FileUtil; |
79 |
import org.openide.filesystems.FileUtil; |
|
|
80 |
import org.openide.util.ChangeSupport; |
71 |
import org.openide.util.Exceptions; |
81 |
import org.openide.util.Exceptions; |
|
|
82 |
import org.openide.util.Pair; |
83 |
import org.openide.util.RequestProcessor; |
72 |
|
84 |
|
73 |
/** |
85 |
/** |
74 |
* |
86 |
* |
75 |
* @author Tomas Zezula |
87 |
* @author Tomas Zezula |
76 |
*/ |
88 |
*/ |
77 |
public class JavaSymbolDescriptor extends SymbolDescriptor { |
89 |
public class AsyncJavaSymbolDescriptor extends SymbolDescriptor implements AsyncDescriptor { |
78 |
|
90 |
|
79 |
private final String simpleName; |
91 |
private static final RequestProcessor WORKER = new RequestProcessor(AsyncJavaSymbolDescriptor.class); |
80 |
private final String simpleNameSuffix; |
92 |
private static final String INIT = "<init>"; //NOI18N |
|
|
93 |
|
81 |
private final ElementHandle<TypeElement> owner; |
94 |
private final ElementHandle<TypeElement> owner; |
82 |
private final ElementHandle<?> me; |
|
|
83 |
private final ElementKind kind; |
84 |
private final Set<Modifier> modifiers; |
85 |
private final FileObject root; |
95 |
private final FileObject root; |
86 |
private final Project project; |
96 |
private final Project project; |
87 |
private final ClassIndexImpl ci; |
97 |
private final ClassIndexImpl ci; |
|
|
98 |
private final String ident; |
99 |
private final ChangeSupport changeSupport; |
100 |
|
88 |
private FileObject cachedFo; |
101 |
private FileObject cachedFo; |
89 |
private volatile String cachedPath; |
102 |
private volatile String cachedPath; |
90 |
|
103 |
|
91 |
public JavaSymbolDescriptor ( |
104 |
private final AtomicReference<State> state; |
92 |
@NonNull final String simpleName, |
105 |
private String simpleName; |
93 |
@NullAllowed final String simpleNameSuffix, |
106 |
private String simpleNameSuffix; |
94 |
@NonNull final ElementKind kind, |
107 |
private ElementHandle<?> me; |
95 |
@NonNull final Set<Modifier> modifiers, |
108 |
private ElementKind kind; |
96 |
@NonNull final ElementHandle<TypeElement> owner, |
109 |
private Set<Modifier> modifiers; |
97 |
@NonNull final ElementHandle<?> me, |
110 |
|
|
|
111 |
public AsyncJavaSymbolDescriptor ( |
98 |
@NullAllowed final Project project, |
112 |
@NullAllowed final Project project, |
99 |
@NonNull final FileObject root, |
113 |
@NonNull final FileObject root, |
100 |
@NonNull final ClassIndexImpl ci) { |
114 |
@NonNull final ClassIndexImpl ci, |
101 |
assert simpleName != null; |
115 |
@NonNull final ElementHandle<TypeElement> owner, |
102 |
assert kind != null; |
116 |
@NonNull final String ident) { |
103 |
assert modifiers != null; |
|
|
104 |
assert owner != null; |
117 |
assert owner != null; |
105 |
assert me != null; |
|
|
106 |
assert root != null; |
118 |
assert root != null; |
107 |
assert ci != null; |
119 |
assert ci != null; |
108 |
this.simpleName = simpleName; |
120 |
assert ident != null; |
109 |
this.simpleNameSuffix = simpleNameSuffix; |
|
|
110 |
this.kind = kind; |
111 |
this.modifiers = modifiers; |
112 |
this.owner = owner; |
121 |
this.owner = owner; |
113 |
this.me = me; |
|
|
114 |
this.root = root; |
122 |
this.root = root; |
115 |
this.project = project; |
123 |
this.project = project; |
116 |
this.ci = ci; |
124 |
this.ci = ci; |
|
|
125 |
this.ident = ident; |
126 |
this.changeSupport = new ChangeSupport(this); |
127 |
this.state = new AtomicReference<>(State.NEW); |
117 |
} |
128 |
} |
118 |
|
129 |
|
119 |
@Override |
130 |
@Override |
120 |
public Icon getIcon() { |
131 |
public Icon getIcon() { |
121 |
return Icons.getElementIcon(kind, modifiers); |
132 |
if (State.INITIALIZED == this.state.get()) { |
|
|
133 |
return Icons.getElementIcon(kind, modifiers); |
134 |
} else { |
135 |
initialize(false); |
136 |
return null; |
137 |
} |
122 |
} |
138 |
} |
123 |
|
139 |
|
124 |
@Override |
140 |
@Override |
125 |
public String getSymbolName() { |
141 |
public String getSymbolName() { |
126 |
return simpleNameSuffix == null ? |
142 |
if (State.INITIALIZED == this.state.get()) { |
127 |
simpleName : |
143 |
return simpleNameSuffix == null ? |
128 |
simpleName + simpleNameSuffix; |
144 |
simpleName : |
|
|
145 |
simpleName + simpleNameSuffix; |
146 |
} else { |
147 |
initialize(false); |
148 |
return ident; |
149 |
} |
129 |
} |
150 |
} |
130 |
|
151 |
|
131 |
@Override |
152 |
@Override |
132 |
public String getSimpleName() { |
153 |
public String getSimpleName() { |
133 |
return simpleName; |
154 |
if (State.INITIALIZED == this.state.get()) { |
|
|
155 |
return simpleName; |
156 |
} else { |
157 |
return ident; |
158 |
} |
134 |
} |
159 |
} |
135 |
|
160 |
|
136 |
@Override |
161 |
@Override |
Lines 194-200
Link Here
|
194 |
FileObject file = getFileObject(); |
219 |
FileObject file = getFileObject(); |
195 |
if (file != null) { |
220 |
if (file != null) { |
196 |
ClasspathInfo cpInfo = ClasspathInfo.create(file); |
221 |
ClasspathInfo cpInfo = ClasspathInfo.create(file); |
197 |
|
222 |
if (State.INITIALIZED != this.state.get()) { |
|
|
223 |
initialize(true); |
224 |
} |
198 |
ElementOpen.open(cpInfo, me); |
225 |
ElementOpen.open(cpInfo, me); |
199 |
} |
226 |
} |
200 |
} |
227 |
} |
Lines 221-236
Link Here
|
221 |
return -1; |
248 |
return -1; |
222 |
} |
249 |
} |
223 |
|
250 |
|
224 |
@NonNull |
|
|
225 |
public ElementKind getElementKind() { |
226 |
return kind; |
227 |
} |
228 |
|
229 |
@NonNull |
230 |
public Set<? extends Modifier> getModifiers() { |
231 |
return modifiers; |
232 |
} |
233 |
|
234 |
@CheckForNull |
251 |
@CheckForNull |
235 |
private ProjectInformation getProjectInfo() { |
252 |
private ProjectInformation getProjectInfo() { |
236 |
return project == null ? |
253 |
return project == null ? |
Lines 238-241
Link Here
|
238 |
project.getLookup().lookup(ProjectInformation.class); //Intentionally does not use ProjectUtils.getInformation() it does project icon annotation which is expensive |
255 |
project.getLookup().lookup(ProjectInformation.class); //Intentionally does not use ProjectUtils.getInformation() it does project icon annotation which is expensive |
239 |
} |
256 |
} |
240 |
|
257 |
|
|
|
258 |
private void initialize(final boolean force) { |
259 |
if (force || state.compareAndSet(State.NEW, State.INITIALIZING)) { |
260 |
final Runnable action = new Resolver(); |
261 |
if (force) { |
262 |
action.run(); |
263 |
} else { |
264 |
WORKER.execute(action); |
265 |
} |
266 |
} |
267 |
} |
268 |
|
269 |
@Override |
270 |
public void addChangeListener(ChangeListener listener) { |
271 |
changeSupport.addChangeListener(listener); |
272 |
} |
273 |
|
274 |
@Override |
275 |
public void removeChangeListener(ChangeListener listener) { |
276 |
changeSupport.removeChangeListener(listener); |
277 |
} |
278 |
|
279 |
private final class Resolver implements Runnable { |
280 |
|
281 |
@Override |
282 |
public void run() { |
283 |
try { |
284 |
TransactionContext. |
285 |
beginTrans(). |
286 |
register(FileManagerTransaction.class, FileManagerTransaction.read()). |
287 |
register(ProcessorGenerated.class, ProcessorGenerated.nullWrite()); |
288 |
try { |
289 |
final ClasspathInfo cpInfo = ClasspathInfoAccessor.getINSTANCE().create(root,null,true,true,false,false); |
290 |
final JavaSource js = JavaSource.create(cpInfo); |
291 |
js.runUserActionTask(new Task<CompilationController>() { |
292 |
@Override |
293 |
public void run (final CompilationController controller) { |
294 |
final TypeElement te = owner.resolve(controller); |
295 |
if (te != null) { |
296 |
if (ident.equals(getSimpleName(te, null)) /*TODO && matchesRestrictions(te, restriction)*/) { |
297 |
simpleName = te.getSimpleName().toString(); |
298 |
simpleNameSuffix = null; |
299 |
kind = te.getKind(); |
300 |
modifiers = te.getModifiers(); |
301 |
me = ElementHandle.create(te); |
302 |
state.set(State.INITIALIZED); |
303 |
changeSupport.fireChange(); |
304 |
} |
305 |
for (Element ne : te.getEnclosedElements()) { |
306 |
if (ident.equals(getSimpleName(ne, te)) /*TODO && matchesRestrictions(ne, restriction)*/) { |
307 |
final Pair<String,String> name = JavaSymbolProvider.getDisplayName(ne, te); |
308 |
simpleName = name.first(); |
309 |
simpleNameSuffix = name.second(); |
310 |
kind = ne.getKind(); |
311 |
modifiers = ne.getModifiers(); |
312 |
me = ElementHandle.create(ne); |
313 |
state.set(State.INITIALIZED); |
314 |
changeSupport.fireChange(); |
315 |
break; |
316 |
} |
317 |
} |
318 |
} |
319 |
} |
320 |
}, true); |
321 |
}finally { |
322 |
TransactionContext.get().commit(); |
323 |
} |
324 |
} catch (IOException e) { |
325 |
Exceptions.printStackTrace(e); |
326 |
} |
327 |
} |
328 |
|
329 |
private String getSimpleName ( |
330 |
@NonNull final Element element, |
331 |
@NullAllowed final Element enclosingElement) { |
332 |
String result = element.getSimpleName().toString(); |
333 |
if (enclosingElement != null && INIT.equals(result)) { |
334 |
result = enclosingElement.getSimpleName().toString(); |
335 |
} |
336 |
//TODO if (!caseSensitive) { |
337 |
result = result.toLowerCase(); |
338 |
// } |
339 |
return result; |
340 |
} |
341 |
} |
342 |
|
343 |
private enum State { |
344 |
NEW, |
345 |
INITIALIZING, |
346 |
INITIALIZED |
347 |
} |
241 |
} |
348 |
} |