Lines 73-97
Link Here
|
73 |
import org.netbeans.api.lexer.LanguagePath; |
73 |
import org.netbeans.api.lexer.LanguagePath; |
74 |
import org.netbeans.api.queries.FileEncodingQuery; |
74 |
import org.netbeans.api.queries.FileEncodingQuery; |
75 |
import org.netbeans.lib.editor.util.swing.DocumentUtilities; |
75 |
import org.netbeans.lib.editor.util.swing.DocumentUtilities; |
76 |
import org.netbeans.modules.parsing.impl.Installer; |
76 |
import org.netbeans.modules.parsing.impl.ParserEventForward; |
77 |
import org.netbeans.modules.parsing.impl.SchedulerAccessor; |
77 |
import org.netbeans.modules.parsing.impl.SchedulerAccessor; |
78 |
import org.netbeans.modules.parsing.impl.SourceAccessor; |
78 |
import org.netbeans.modules.parsing.impl.SourceAccessor; |
79 |
import org.netbeans.modules.parsing.impl.SourceCache; |
79 |
import org.netbeans.modules.parsing.impl.SourceCache; |
80 |
import org.netbeans.modules.parsing.impl.SourceFlags; |
80 |
import org.netbeans.modules.parsing.impl.SourceFlags; |
81 |
import org.netbeans.modules.parsing.impl.TaskProcessor; |
81 |
import org.netbeans.modules.parsing.impl.TaskProcessor; |
82 |
import org.netbeans.modules.parsing.impl.event.EventSupport; |
82 |
import org.netbeans.modules.parsing.impl.Utilities; |
83 |
import org.netbeans.modules.parsing.impl.indexing.Util; |
83 |
import org.netbeans.modules.parsing.implspi.SchedulerControl; |
|
|
84 |
import org.netbeans.modules.parsing.implspi.SourceControl; |
85 |
import org.netbeans.modules.parsing.implspi.SourceEnvironment; |
84 |
import org.netbeans.modules.parsing.spi.Parser; |
86 |
import org.netbeans.modules.parsing.spi.Parser; |
85 |
import org.netbeans.modules.parsing.spi.Scheduler; |
87 |
import org.netbeans.modules.parsing.spi.Scheduler; |
86 |
import org.netbeans.modules.parsing.spi.SchedulerEvent; |
88 |
import org.netbeans.modules.parsing.spi.SchedulerEvent; |
87 |
import org.netbeans.modules.parsing.spi.SourceModificationEvent; |
89 |
import org.netbeans.modules.parsing.spi.SourceModificationEvent; |
88 |
import org.openide.cookies.EditorCookie; |
|
|
89 |
import org.openide.filesystems.FileObject; |
90 |
import org.openide.filesystems.FileObject; |
90 |
import org.openide.filesystems.FileUtil; |
91 |
import org.openide.filesystems.FileUtil; |
91 |
import org.openide.loaders.DataObject; |
92 |
import org.openide.util.Lookup; |
92 |
import org.openide.loaders.DataObjectNotFoundException; |
|
|
93 |
import org.openide.util.Parameters; |
93 |
import org.openide.util.Parameters; |
94 |
import org.openide.util.UserQuestionException; |
|
|
95 |
|
94 |
|
96 |
|
95 |
|
97 |
/** |
96 |
/** |
Lines 109-120
Link Here
|
109 |
* calls for the same file or document will return two different <code>Source</code> |
108 |
* calls for the same file or document will return two different <code>Source</code> |
110 |
* instances if the first instance is garbage collected prior the second call. |
109 |
* instances if the first instance is garbage collected prior the second call. |
111 |
* |
110 |
* |
|
|
111 |
* <p> |
112 |
* The Source can be created with a {@link Lookup} instance. This Lookup should be used |
113 |
* by parsing system, or callback tasks to locate services, that depend on the execution |
114 |
* context (ie which user is executing the task). Check the specific service's documentation |
115 |
* on details of the service's context dependencies. |
112 |
* |
116 |
* |
113 |
* @author Jan Jancura |
117 |
* @author Jan Jancura |
114 |
* @author Tomas Zezula |
118 |
* @author Tomas Zezula |
|
|
119 |
* @since 9.2 implements Lookup.Provider |
115 |
*/ |
120 |
*/ |
116 |
public final class Source { |
121 |
public final class Source implements Lookup.Provider { |
117 |
|
122 |
|
118 |
/** |
123 |
/** |
119 |
* Gets a <code>Source</code> instance for a file. The <code>FileObject</code> |
124 |
* Gets a <code>Source</code> instance for a file. The <code>FileObject</code> |
120 |
* passed to this method has to be a valid data file. There is no <code>Source</code> |
125 |
* passed to this method has to be a valid data file. There is no <code>Source</code> |
Lines 134-143
Link Here
|
134 |
return null; |
139 |
return null; |
135 |
} |
140 |
} |
136 |
|
141 |
|
137 |
return _get(fileObject.getMIMEType(), fileObject); |
142 |
return _get(fileObject.getMIMEType(), fileObject, Lookup.getDefault()); |
138 |
} |
143 |
} |
139 |
|
144 |
|
140 |
/** |
145 |
/** |
|
|
146 |
* Gets a <code>Source</code> instance for a file. The <code>FileObject</code> |
147 |
* passed to this method has to be a valid data file. There is no <code>Source</code> |
148 |
* representation for a folder. |
149 |
* <p/> |
150 |
* This form allows to specify Lookup that provides access to context-dependent |
151 |
* services for the parsing system and the user tasks called from parsing API. |
152 |
* |
153 |
* @param fileObject The file to get <code>Source</code> for. |
154 |
* @param lkp The Lookup that provides the context |
155 |
* @return The <code>Source</code> for the given file or <code>null</code> |
156 |
* if the file doesn't exist. |
157 |
* @since 9.2 |
158 |
*/ |
159 |
public static Source create ( |
160 |
FileObject fileObject, Lookup lkp |
161 |
) { |
162 |
Parameters.notNull("fileObject", fileObject); //NOI18N |
163 |
Parameters.notNull("lkp", lkp); //NOI18N |
164 |
if (!fileObject.isValid() || !fileObject.isData()) { |
165 |
return null; |
166 |
} |
167 |
|
168 |
return _get(fileObject.getMIMEType(), fileObject, lkp); |
169 |
} |
170 |
|
171 |
/** |
141 |
* Gets a <code>Source</code> instance for a <code>Document</code>. This method |
172 |
* Gets a <code>Source</code> instance for a <code>Document</code>. This method |
142 |
* is consistent with {@link #create(org.openide.filesystems.FileObject)} in the way |
173 |
* is consistent with {@link #create(org.openide.filesystems.FileObject)} in the way |
143 |
* that they both will return the same <code>Source</code> instance for |
174 |
* that they both will return the same <code>Source</code> instance for |
Lines 171-176
Link Here
|
171 |
public static Source create ( |
202 |
public static Source create ( |
172 |
Document document |
203 |
Document document |
173 |
) { |
204 |
) { |
|
|
205 |
return create(document, Lookup.getDefault()); |
206 |
} |
207 |
|
208 |
/** |
209 |
* Gets a <code>Source</cide> instance for a <code>Document</code>. For details, please |
210 |
* see {@link #create(javax.swing.text.Document)}; this form allows to specify |
211 |
* a Lookup that provides access to user or context-dependent services. |
212 |
* |
213 |
* @param document the document to get <code>Source</code> for |
214 |
* @param lkp the context for the source |
215 |
* @return the Source instance |
216 |
* @see #create(javax.swing.text.Document) |
217 |
* @since 9.2 |
218 |
*/ |
219 |
public static Source create ( |
220 |
Document document, Lookup lkp |
221 |
) { |
174 |
Parameters.notNull("document", document); //NOI18N |
222 |
Parameters.notNull("document", document); //NOI18N |
175 |
|
223 |
|
176 |
String mimeType = DocumentUtilities.getMimeType(document); |
224 |
String mimeType = DocumentUtilities.getMimeType(document); |
Lines 190-210
Link Here
|
190 |
} |
238 |
} |
191 |
|
239 |
|
192 |
if (source == null) { |
240 |
if (source == null) { |
193 |
FileObject fileObject = Util.getFileObject(document); |
241 |
FileObject fileObject = Utilities.getFileObject(document); |
194 |
if (fileObject != null) { |
242 |
if (fileObject != null) { |
195 |
source = Source._get(mimeType, fileObject); |
243 |
source = Source._get(mimeType, fileObject, lkp); |
196 |
} else { |
244 |
} else { |
197 |
if ("text/x-dialog-binding".equals(mimeType)) { //NOI18N |
245 |
if ("text/x-dialog-binding".equals(mimeType)) { //NOI18N |
198 |
InputAttributes attributes = (InputAttributes) document.getProperty(InputAttributes.class); |
246 |
InputAttributes attributes = (InputAttributes) document.getProperty(InputAttributes.class); |
199 |
LanguagePath path = LanguagePath.get(MimeLookup.getLookup(mimeType).lookup(Language.class)); |
247 |
LanguagePath path = LanguagePath.get(MimeLookup.getLookup(mimeType).lookup(Language.class)); |
200 |
Document doc = (Document) attributes.getValue(path, "dialogBinding.document"); //NOI18N |
248 |
Document doc = (Document) attributes.getValue(path, "dialogBinding.document"); //NOI18N |
201 |
if (doc != null) { |
249 |
if (doc != null) { |
202 |
fileObject = Util.getFileObject(doc); |
250 |
fileObject = Utilities.getFileObject(doc); |
203 |
} else { |
251 |
} else { |
204 |
fileObject = (FileObject) attributes.getValue(path, "dialogBinding.fileObject"); //NOI18N |
252 |
fileObject = (FileObject) attributes.getValue(path, "dialogBinding.fileObject"); //NOI18N |
205 |
} |
253 |
} |
206 |
} |
254 |
} |
207 |
source = new Source(mimeType, document, fileObject); |
255 |
source = new Source(mimeType, document, fileObject, lkp); |
208 |
} |
256 |
} |
209 |
document.putProperty(Source.class, new WeakReference<Source>(source)); |
257 |
document.putProperty(Source.class, new WeakReference<Source>(source)); |
210 |
} |
258 |
} |
Lines 254-284
Link Here
|
254 |
} |
302 |
} |
255 |
} |
303 |
} |
256 |
if (document != null) return document; |
304 |
if (document != null) return document; |
257 |
EditorCookie ec = null; |
305 |
assert fileObject != null; |
258 |
|
|
|
259 |
try { |
306 |
try { |
260 |
DataObject dataObject = DataObject.find (fileObject); |
307 |
return sourceEnv.readDocument(fileObject, forceOpen); |
261 |
ec = dataObject.getLookup ().lookup (EditorCookie.class); |
308 |
} catch (IOException ioe) { |
262 |
} catch (DataObjectNotFoundException ex) { |
309 |
LOG.log (Level.WARNING, null, ioe); |
263 |
//DataobjectNotFoundException may happen in case of deleting opened file |
310 |
return null; |
264 |
//handled by returning null |
|
|
265 |
} |
311 |
} |
266 |
|
|
|
267 |
if (ec == null) return null; |
268 |
Document doc = ec.getDocument (); |
269 |
if (doc == null && forceOpen) { |
270 |
try { |
271 |
try { |
272 |
doc = ec.openDocument (); |
273 |
} catch (UserQuestionException uqe) { |
274 |
uqe.confirmed (); |
275 |
doc = ec.openDocument (); |
276 |
} |
277 |
} catch (IOException ioe) { |
278 |
LOG.log (Level.WARNING, null, ioe); |
279 |
} |
280 |
} |
281 |
return doc; |
282 |
} |
312 |
} |
283 |
|
313 |
|
284 |
/** |
314 |
/** |
Lines 329-335
Link Here
|
329 |
// but they usually don't and this should be good enough for Snapshots. |
359 |
// but they usually don't and this should be good enough for Snapshots. |
330 |
try { |
360 |
try { |
331 |
if (fileObject.isValid ()) { |
361 |
if (fileObject.isValid ()) { |
332 |
if (fileObject.getSize() <= Installer.MAX_FILE_SIZE) { |
362 |
if (fileObject.getSize() <= Utilities.getMaxFileSize()) { |
333 |
final InputStream is = fileObject.getInputStream (); |
363 |
final InputStream is = fileObject.getInputStream (); |
334 |
assert is != null : "FileObject.getInputStream() returned null for FileObject: " + FileUtil.getFileDisplayName(fileObject); //NOI18N |
364 |
assert is != null : "FileObject.getInputStream() returned null for FileObject: " + FileUtil.getFileDisplayName(fileObject); //NOI18N |
335 |
try { |
365 |
try { |
Lines 396-402
Link Here
|
396 |
new Object[]{ |
426 |
new Object[]{ |
397 |
FileUtil.getFileDisplayName(fileObject), |
427 |
FileUtil.getFileDisplayName(fileObject), |
398 |
fileObject.getSize(), |
428 |
fileObject.getSize(), |
399 |
Installer.MAX_FILE_SIZE |
429 |
Utilities.getMaxFileSize() |
400 |
}); |
430 |
}); |
401 |
} |
431 |
} |
402 |
} |
432 |
} |
Lines 480-485
Link Here
|
480 |
SourceAccessor.setINSTANCE(new MySourceAccessor()); |
510 |
SourceAccessor.setINSTANCE(new MySourceAccessor()); |
481 |
} |
511 |
} |
482 |
|
512 |
|
|
|
513 |
private final Lookup context; |
483 |
private final String mimeType; |
514 |
private final String mimeType; |
484 |
private final FileObject fileObject; |
515 |
private final FileObject fileObject; |
485 |
private final Document document; |
516 |
private final Document document; |
Lines 493-517
Link Here
|
493 |
private Map<Class<? extends Scheduler>, SchedulerEvent> schedulerEvents; |
524 |
private Map<Class<? extends Scheduler>, SchedulerEvent> schedulerEvents; |
494 |
//GuardedBy(this) |
525 |
//GuardedBy(this) |
495 |
private SourceCache cache; |
526 |
private SourceCache cache; |
496 |
//GuardedBy(this) |
527 |
//GuardedBy(flags) |
497 |
private volatile long eventId; |
528 |
private volatile long eventId; |
498 |
//Changes handling |
529 |
private volatile boolean listeningOnChanges; |
499 |
private final EventSupport support = new EventSupport (this); |
|
|
500 |
|
530 |
|
|
|
531 |
/** |
532 |
* SourceEnvironment callback |
533 |
*/ |
534 |
private final SourceControl ctrl = new SourceControl(this); |
535 |
/** |
536 |
* Binding of source to its environment |
537 |
*/ |
538 |
private final SourceEnvironment sourceEnv; |
539 |
/** |
540 |
* Demultiplexes events from all parsers to SourceEnvironment. |
541 |
*/ |
542 |
private final ParserEventForward peFwd; |
543 |
|
544 |
@SuppressWarnings("LeakingThisInConstructor") |
501 |
private Source ( |
545 |
private Source ( |
502 |
String mimeType, |
546 |
String mimeType, |
503 |
Document document, |
547 |
Document document, |
504 |
FileObject fileObject |
548 |
FileObject fileObject, |
|
|
549 |
Lookup context |
505 |
) { |
550 |
) { |
506 |
this.mimeType = mimeType; |
551 |
this.mimeType = mimeType; |
507 |
this.document = document; |
552 |
this.document = document; |
508 |
this.fileObject = fileObject; |
553 |
this.fileObject = fileObject; |
|
|
554 |
this.context = context; |
555 |
this.peFwd = new ParserEventForward(); |
556 |
this.sourceEnv = Utilities.createEnvironment(this, ctrl); |
509 |
} |
557 |
} |
510 |
|
558 |
|
511 |
@NonNull |
559 |
@NonNull |
512 |
private static Source _get( |
560 |
private static Source _get( |
513 |
@NonNull final String mimeType, |
561 |
@NonNull final String mimeType, |
514 |
@NonNull final FileObject fileObject) { |
562 |
@NonNull final FileObject fileObject, |
|
|
563 |
@NonNull final Lookup context) { |
515 |
assert mimeType != null; |
564 |
assert mimeType != null; |
516 |
assert fileObject != null; |
565 |
assert fileObject != null; |
517 |
|
566 |
|
Lines 519-548
Link Here
|
519 |
final Reference<Source> sourceRef = instances.get(fileObject); |
568 |
final Reference<Source> sourceRef = instances.get(fileObject); |
520 |
Source source = sourceRef == null ? null : sourceRef.get(); |
569 |
Source source = sourceRef == null ? null : sourceRef.get(); |
521 |
if (source == null || !mimeType.equals(source.getMimeType())) { |
570 |
if (source == null || !mimeType.equals(source.getMimeType())) { |
522 |
source = new Source(mimeType, null, fileObject); |
571 |
source = new Source(mimeType, null, fileObject, context); |
523 |
instances.put(fileObject, new WeakReference<>(source)); |
572 |
instances.put(fileObject, new WeakReference<>(source)); |
524 |
} |
573 |
} |
|
|
574 |
assert source.context == context; |
525 |
return source; |
575 |
return source; |
526 |
} |
576 |
} |
527 |
} |
577 |
} |
528 |
|
578 |
|
529 |
private void assignListeners () { |
579 |
private void assignListeners () { |
530 |
boolean listen = !suppressListening.get(); |
580 |
final boolean listen = !suppressListening.get(); |
531 |
if (listen) { |
581 |
if (listen) { |
532 |
support.init(); |
582 |
if (listeningOnChanges) { |
|
|
583 |
return; |
584 |
} |
585 |
synchronized (TaskProcessor.INTERNAL_LOCK) { |
586 |
if (listeningOnChanges) { |
587 |
return; |
588 |
} |
589 |
try { |
590 |
sourceEnv.activate(); |
591 |
} finally { |
592 |
listeningOnChanges = true; |
593 |
} |
594 |
} |
533 |
} |
595 |
} |
534 |
} |
596 |
} |
535 |
|
597 |
|
|
|
598 |
private void setFlags(final Set<SourceFlags> flags) { |
599 |
// synchronized because of eventId |
600 |
synchronized (flags) { |
601 |
this.flags.addAll(flags); |
602 |
eventId++; |
603 |
} |
604 |
} |
605 |
|
606 |
private void setSourceModification (boolean sourceChanged, int startOffset, int endOffset) { |
607 |
ASourceModificationEvent oldSourceModificationEvent; |
608 |
ASourceModificationEvent newSourceModificationEvent; |
609 |
do { |
610 |
oldSourceModificationEvent = sourceModificationEvent.get(); |
611 |
boolean mergedChange = sourceChanged | (oldSourceModificationEvent == null ? false : oldSourceModificationEvent.sourceChanged()); |
612 |
newSourceModificationEvent = new ASourceModificationEvent (this, mergedChange, startOffset, endOffset); |
613 |
} while (!sourceModificationEvent.compareAndSet(oldSourceModificationEvent, newSourceModificationEvent)); |
614 |
} |
615 |
|
616 |
private void mimeTypeMayChanged() { |
617 |
final FileObject file = getFileObject(); |
618 |
if (file != null && !Objects.equals(getMimeType(), file.getMIMEType())) { |
619 |
synchronized (Source.class) { |
620 |
instances.remove(file); |
621 |
} |
622 |
} |
623 |
} |
624 |
|
625 |
private SourceCache getCache() { |
626 |
synchronized (TaskProcessor.INTERNAL_LOCK) { |
627 |
if (cache == null) |
628 |
cache = new SourceCache (this, null); |
629 |
return cache; |
630 |
} |
631 |
} |
632 |
|
633 |
@SuppressWarnings("AccessingNonPublicFieldOfAnotherObject") // accessing internals is accessor's job |
536 |
private static class MySourceAccessor extends SourceAccessor { |
634 |
private static class MySourceAccessor extends SourceAccessor { |
537 |
|
635 |
|
538 |
@Override |
636 |
@Override |
539 |
public void setFlags (final Source source, final Set<SourceFlags> flags) { |
637 |
public void setFlags (final Source source, final Set<SourceFlags> flags) { |
540 |
assert source != null; |
638 |
assert source != null; |
541 |
assert flags != null; |
639 |
assert flags != null; |
542 |
synchronized (source.flags) { |
640 |
source.setFlags(flags); |
543 |
source.flags.addAll(flags); |
|
|
544 |
source.eventId++; |
545 |
} |
546 |
} |
641 |
} |
547 |
|
642 |
|
548 |
@Override |
643 |
@Override |
Lines 555-561
Link Here
|
555 |
@Override |
650 |
@Override |
556 |
public boolean cleanFlag (final Source source, final SourceFlags flag) { |
651 |
public boolean cleanFlag (final Source source, final SourceFlags flag) { |
557 |
assert source != null; |
652 |
assert source != null; |
558 |
assert flag != null; |
653 |
assert flag != null; |
559 |
return source.flags.remove(flag); |
654 |
return source.flags.remove(flag); |
560 |
} |
655 |
} |
561 |
|
656 |
|
Lines 585-590
Link Here
|
585 |
} |
680 |
} |
586 |
|
681 |
|
587 |
@Override |
682 |
@Override |
|
|
683 |
public void revalidate(Source source, int delay) { |
684 |
source.ctrl.revalidate(delay); |
685 |
} |
686 |
|
687 |
@Override |
588 |
public boolean invalidate(Source source, long id, Snapshot snapshot) { |
688 |
public boolean invalidate(Source source, long id, Snapshot snapshot) { |
589 |
assert source != null; |
689 |
assert source != null; |
590 |
synchronized (TaskProcessor.INTERNAL_LOCK) { |
690 |
synchronized (TaskProcessor.INTERNAL_LOCK) { |
Lines 594-602
Link Here
|
594 |
else { |
694 |
else { |
595 |
//The eventId and flags are bound |
695 |
//The eventId and flags are bound |
596 |
long eventId; |
696 |
long eventId; |
597 |
synchronized (source.flags) { |
697 |
eventId = source.eventId; |
598 |
eventId = source.eventId; |
|
|
599 |
} |
600 |
if (id != eventId) { |
698 |
if (id != eventId) { |
601 |
return false; |
699 |
return false; |
602 |
} |
700 |
} |
Lines 610-615
Link Here
|
610 |
} |
708 |
} |
611 |
} |
709 |
} |
612 |
} |
710 |
} |
|
|
711 |
|
712 |
@Override |
713 |
public void attachScheduler(Source src, SchedulerControl sched, boolean attach) { |
714 |
src.sourceEnv.attachScheduler(sched, attach); |
715 |
} |
613 |
|
716 |
|
614 |
@Override |
717 |
@Override |
615 |
public Parser getParser(Source source) { |
718 |
public Parser getParser(Source source) { |
Lines 636-644
Link Here
|
636 |
} |
739 |
} |
637 |
|
740 |
|
638 |
@Override |
741 |
@Override |
639 |
public EventSupport getEventSupport (final Source source) { |
742 |
public SourceControl getEnvControl(final Source source) { |
640 |
assert source != null; |
743 |
assert source != null; |
641 |
return source.support; |
744 |
return source.ctrl; |
|
|
745 |
} |
746 |
|
747 |
@Override |
748 |
public SourceEnvironment getEnv(final Source source) { |
749 |
assert source != null; |
750 |
return source.sourceEnv; |
642 |
} |
751 |
} |
643 |
|
752 |
|
644 |
@Override |
753 |
@Override |
Lines 650-673
Link Here
|
650 |
@Override |
759 |
@Override |
651 |
public void setSourceModification (Source source, boolean sourceChanged, int startOffset, int endOffset) { |
760 |
public void setSourceModification (Source source, boolean sourceChanged, int startOffset, int endOffset) { |
652 |
assert source != null; |
761 |
assert source != null; |
653 |
ASourceModificationEvent oldSourceModificationEvent; |
762 |
source.setSourceModification(sourceChanged, startOffset, endOffset); |
654 |
ASourceModificationEvent newSourceModificationEvent; |
|
|
655 |
do { |
656 |
oldSourceModificationEvent = source.sourceModificationEvent.get(); |
657 |
boolean mergedChange = sourceChanged | (oldSourceModificationEvent == null ? false : oldSourceModificationEvent.sourceChanged()); |
658 |
newSourceModificationEvent = new ASourceModificationEvent (source, mergedChange, startOffset, endOffset); |
659 |
} while (!source.sourceModificationEvent.compareAndSet(oldSourceModificationEvent, newSourceModificationEvent)); |
660 |
} |
763 |
} |
661 |
|
764 |
|
662 |
@Override |
765 |
@Override |
663 |
public void mimeTypeMayChanged(@NonNull final Source source) { |
766 |
public void mimeTypeMayChanged(@NonNull final Source source) { |
664 |
assert source != null; |
767 |
assert source != null; |
665 |
final FileObject file = source.getFileObject(); |
768 |
source.mimeTypeMayChanged(); |
666 |
if (file != null && !Objects.equals(source.getMimeType(), file.getMIMEType())) { |
|
|
667 |
synchronized (Source.class) { |
668 |
instances.remove(file); |
669 |
} |
670 |
} |
671 |
} |
769 |
} |
672 |
|
770 |
|
673 |
@Override |
771 |
@Override |
Lines 735-745
Link Here
|
735 |
@Override |
833 |
@Override |
736 |
public SourceCache getCache (final Source source) { |
834 |
public SourceCache getCache (final Source source) { |
737 |
assert source != null; |
835 |
assert source != null; |
738 |
synchronized (TaskProcessor.INTERNAL_LOCK) { |
836 |
return source.getCache(); |
739 |
if (source.cache == null) |
|
|
740 |
source.cache = new SourceCache (source, null); |
741 |
return source.cache; |
742 |
} |
743 |
} |
837 |
} |
744 |
|
838 |
|
745 |
@Override |
839 |
@Override |
Lines 806-814
Link Here
|
806 |
return origCache; |
900 |
return origCache; |
807 |
} |
901 |
} |
808 |
|
902 |
|
|
|
903 |
@Override |
904 |
@NonNull |
905 |
public ParserEventForward getParserEventForward(@NonNull final Source source) { |
906 |
return source.peFwd; |
907 |
} |
809 |
} // End of MySourceAccessor class |
908 |
} // End of MySourceAccessor class |
810 |
|
909 |
|
811 |
static class ASourceModificationEvent extends SourceModificationEvent { |
910 |
private static class ASourceModificationEvent extends SourceModificationEvent { |
812 |
|
911 |
|
813 |
private int startOffset; |
912 |
private int startOffset; |
814 |
private int endOffset; |
913 |
private int endOffset; |
Lines 829-835
Link Here
|
829 |
int _endOffset |
928 |
int _endOffset |
830 |
) { |
929 |
) { |
831 |
startOffset = Math.min (startOffset, _startOffset); |
930 |
startOffset = Math.min (startOffset, _startOffset); |
832 |
endOffset = Math.min (endOffset, _endOffset); |
931 |
endOffset = Math.max (endOffset, _endOffset); |
|
|
932 |
} |
933 |
|
934 |
@Override |
935 |
public int getAffectedStartOffset() { |
936 |
return startOffset; |
937 |
} |
938 |
|
939 |
@Override |
940 |
public int getAffectedEndOffset() { |
941 |
return endOffset; |
833 |
} |
942 |
} |
834 |
|
943 |
|
835 |
@Override |
944 |
@Override |
Lines 838-841
Link Here
|
838 |
return "SourceModificationEvent " + startOffset + ":" + endOffset; |
947 |
return "SourceModificationEvent " + startOffset + ":" + endOffset; |
839 |
} |
948 |
} |
840 |
} |
949 |
} |
|
|
950 |
|
951 |
/** |
952 |
* Returns a Lookup providing a context for the source. |
953 |
* In the presence of multiple scopes or users in the system, this Lookup may |
954 |
* provide access to necessary context-dependent services or scope-dependent data. |
955 |
* <p/> |
956 |
* A Source may be created with a Lookup, or it will use the default Lookup as a context |
957 |
* @return Lookup. |
958 |
* @since 9.2 |
959 |
*/ |
960 |
public Lookup getLookup() { |
961 |
return context; |
962 |
} |
841 |
} |
963 |
} |