[LtxR-Model, WikidocR-Model] Make RChunkReconciler fully thread safe
Change-Id: I5228e7f1eaeeac88e42ea7340d18b2b3d2dc76cf
diff --git a/redocs/org.eclipse.statet.redocs.r/src/org/eclipse/statet/redocs/r/core/model/RChunkReconciler.java b/redocs/org.eclipse.statet.redocs.r/src/org/eclipse/statet/redocs/r/core/model/RChunkReconciler.java
index 3992ca9..962581d 100644
--- a/redocs/org.eclipse.statet.redocs.r/src/org/eclipse/statet/redocs/r/core/model/RChunkReconciler.java
+++ b/redocs/org.eclipse.statet.redocs.r/src/org/eclipse/statet/redocs/r/core/model/RChunkReconciler.java
@@ -67,14 +67,15 @@
private final RModelManager rManager;
+ private final Object raLock= new Object();
private final Matcher raChunkStartLineMatcher;
private final @Nullable Matcher raChunkRefLineMatcher;
private final Matcher raChunkEndLineMatcher;
-
private final RParser raParser= new RParser(RSourceConfig.DEFAULT_CONFIG,
AstInfo.LEVEL_MODEL_DEFAULT, new CacheStringFactory(0x20) );
private final StringParserInput raInput= new StringParserInput(0x1000);
+ private final Object riLock= new Object();
private final RIssueReporter riReporter= new RIssueReporter();
@@ -100,112 +101,114 @@
public void reconcileAst(final TModelContainer adapter,
final SourceContent sourceContent, final List<? extends EmbeddingAstNode> list,
final RSourceConfig rSourceConfig) {
- if (sourceContent.getStartOffset() != 0) {
- throw new UnsupportedOperationException();
- }
-
- final String source= sourceContent.getString();
- final TextLineInformation lines= sourceContent.getStringLines();
-
- this.raChunkStartLineMatcher.reset(source);
- if (this.raChunkRefLineMatcher != null) {
- this.raChunkRefLineMatcher.reset(source);
- }
- this.raChunkEndLineMatcher.reset(source);
-
- this.raInput.reset(source);
-
- this.raParser.setRSourceConfig(rSourceConfig);
- this.raParser.setCommentLevel(RParser.COLLECT_COMMENTS | RParser.ROXYGEN_COMMENTS);
-
- for (final EmbeddingAstNode embeddingNode : list) {
- if (embeddingNode.getForeignTypeId() != RModel.R_TYPE_ID) {
- continue;
+ synchronized (this.raLock) {
+ if (sourceContent.getStartOffset() != 0) {
+ throw new UnsupportedOperationException();
}
- final RChunkNode rChunk= new RChunkNode(embeddingNode);
- rChunk.startOffset= embeddingNode.getStartOffset();
- rChunk.endOffset= embeddingNode.getEndOffset();
- embeddingNode.setForeignNode(rChunk);
+ final String source= sourceContent.getString();
+ final TextLineInformation lines= sourceContent.getStringLines();
- final IRegion startRegion;
- final List<IRegion> rCode= new ArrayList<>(4);
+ this.raChunkStartLineMatcher.reset(source);
+ if (this.raChunkRefLineMatcher != null) {
+ this.raChunkRefLineMatcher.reset(source);
+ }
+ this.raChunkEndLineMatcher.reset(source);
- switch ((embeddingNode.getEmbedDescr() & 0xf)) {
+ this.raInput.reset(source);
- case EmbeddingAstNode.EMBED_INLINE:
- startRegion= null;
- rCode.add(new Region(embeddingNode.getStartOffset(), embeddingNode.getLength()));
- break;
-
- case EmbeddingAstNode.EMBED_CHUNK: {
- int lineOffset= rChunk.startOffset;
- int line= lines.getLineOfOffset(rChunk.startOffset);
- int rCodeStartOffset;
-
- // start line
- int lineEndOffset= lines.getEndOffset(line);
- this.raChunkStartLineMatcher.region(lineOffset, lineEndOffset);
- if (!this.raChunkStartLineMatcher.matches()) {
- throw new IllegalStateException("R chunk does not start with start line.");
+ this.raParser.setRSourceConfig(rSourceConfig);
+ this.raParser.setCommentLevel(RParser.COLLECT_COMMENTS | RParser.ROXYGEN_COMMENTS);
+
+ for (final EmbeddingAstNode embeddingNode : list) {
+ if (embeddingNode.getForeignTypeId() != RModel.R_TYPE_ID) {
+ continue;
}
- { final int start= this.raChunkStartLineMatcher.start(1);
- final int end= this.raChunkStartLineMatcher.end(1);
- startRegion= new Region(start, end - start);
- }
- rCodeStartOffset= lineEndOffset;
- if (lineEndOffset < rChunk.endOffset) {
- do {
- line++;
- lineOffset= lineEndOffset;
- lineEndOffset= lines.getEndOffset(line);
-
- if (this.raChunkRefLineMatcher != null) {
- this.raChunkRefLineMatcher.region(lineOffset, lineEndOffset);
- if (this.raChunkRefLineMatcher.matches()) {
- if (rCodeStartOffset < lineOffset) {
- rCode.add(new Region(rCodeStartOffset, lineOffset - rCodeStartOffset));
+ final RChunkNode rChunk= new RChunkNode(embeddingNode);
+ rChunk.startOffset= embeddingNode.getStartOffset();
+ rChunk.endOffset= embeddingNode.getEndOffset();
+ embeddingNode.setForeignNode(rChunk);
+
+ final IRegion startRegion;
+ final List<IRegion> rCode= new ArrayList<>(4);
+
+ switch ((embeddingNode.getEmbedDescr() & 0xf)) {
+
+ case EmbeddingAstNode.EMBED_INLINE:
+ startRegion= null;
+ rCode.add(new Region(embeddingNode.getStartOffset(), embeddingNode.getLength()));
+ break;
+
+ case EmbeddingAstNode.EMBED_CHUNK: {
+ int lineOffset= rChunk.startOffset;
+ int line= lines.getLineOfOffset(rChunk.startOffset);
+ int rCodeStartOffset;
+
+ // start line
+ int lineEndOffset= lines.getEndOffset(line);
+ this.raChunkStartLineMatcher.region(lineOffset, lineEndOffset);
+ if (!this.raChunkStartLineMatcher.matches()) {
+ throw new IllegalStateException("R chunk does not start with start line.");
+ }
+ { final int start= this.raChunkStartLineMatcher.start(1);
+ final int end= this.raChunkStartLineMatcher.end(1);
+ startRegion= new Region(start, end - start);
+ }
+ rCodeStartOffset= lineEndOffset;
+
+ if (lineEndOffset < rChunk.endOffset) {
+ do {
+ line++;
+ lineOffset= lineEndOffset;
+ lineEndOffset= lines.getEndOffset(line);
+
+ if (this.raChunkRefLineMatcher != null) {
+ this.raChunkRefLineMatcher.region(lineOffset, lineEndOffset);
+ if (this.raChunkRefLineMatcher.matches()) {
+ if (rCodeStartOffset < lineOffset) {
+ rCode.add(new Region(rCodeStartOffset, lineOffset - rCodeStartOffset));
+ }
+ rCodeStartOffset= lineEndOffset;
}
- rCodeStartOffset= lineEndOffset;
}
+ } while (lineEndOffset < rChunk.endOffset);
+
+ if (rChunk.endOffset != lineEndOffset) {
+ throw new IllegalStateException("R chunk does not end at line end.");
}
- } while (lineEndOffset < rChunk.endOffset);
-
- if (rChunk.endOffset != lineEndOffset) {
- throw new IllegalStateException("R chunk does not end at line end.");
- }
-
- this.raChunkEndLineMatcher.region(lineOffset, lineEndOffset);
- if (this.raChunkEndLineMatcher.matches()) {
- if (rCodeStartOffset < lineOffset) {
- rCode.add(new Region(rCodeStartOffset, lineOffset - rCodeStartOffset));
+
+ this.raChunkEndLineMatcher.region(lineOffset, lineEndOffset);
+ if (this.raChunkEndLineMatcher.matches()) {
+ if (rCodeStartOffset < lineOffset) {
+ rCode.add(new Region(rCodeStartOffset, lineOffset - rCodeStartOffset));
+ }
+ rCodeStartOffset= lineEndOffset;
}
- rCodeStartOffset= lineEndOffset;
+ else if (rCodeStartOffset < lineOffset) {
+ rCode.add(new Region(rCodeStartOffset, lineEndOffset - rCodeStartOffset));
+ }
}
- else if (rCodeStartOffset < lineOffset) {
- rCode.add(new Region(rCodeStartOffset, lineEndOffset - rCodeStartOffset));
- }
+ break; }
+
+ default:
+ throw new UnsupportedOperationException("embedType= " + embeddingNode.getEmbedDescr());
}
- break; }
-
- default:
- throw new UnsupportedOperationException("embedType= " + embeddingNode.getEmbedDescr());
+
+ if (startRegion != null) {
+ rChunk.weaveArgs= this.raParser.scanFCallArgs(
+ this.raInput.init(startRegion.getOffset(), startRegion.getOffset() + startRegion.getLength()),
+ true );
+ }
+ final SourceComponent[] rCodeNodes= new @NonNull SourceComponent[rCode.size()];
+ for (int j= 0; j < rCodeNodes.length; j++) {
+ final IRegion region= rCode.get(j);
+ rCodeNodes[j]= this.raParser.scanSourceRange(
+ this.raInput.init(region.getOffset(), region.getOffset() + region.getLength()),
+ rChunk, true );
+ }
+ rChunk.rSources= ImCollections.newList(rCodeNodes);
}
-
- if (startRegion != null) {
- rChunk.weaveArgs= this.raParser.scanFCallArgs(
- this.raInput.init(startRegion.getOffset(), startRegion.getOffset() + startRegion.getLength()),
- true );
- }
- final SourceComponent[] rCodeNodes= new @NonNull SourceComponent[rCode.size()];
- for (int j= 0; j < rCodeNodes.length; j++) {
- final IRegion region= rCode.get(j);
- rCodeNodes[j]= this.raParser.scanSourceRange(
- this.raInput.init(region.getOffset(), region.getOffset() + region.getLength()),
- rChunk, true );
- }
- rChunk.rSources= ImCollections.newList(rCodeNodes);
}
}
@@ -307,8 +310,10 @@
if (modelInfo == null) {
return;
}
- this.riReporter.configure(config.getIssueConfig());
- this.riReporter.run(adapter.getSourceUnit(), modelInfo, content, issueRequestor, level);
+ synchronized (this.riLock) {
+ this.riReporter.configure(config.getIssueConfig());
+ this.riReporter.run(adapter.getSourceUnit(), modelInfo, content, issueRequestor, level);
+ }
}
}