Bug 577760: Unify parser APIs and error handling
Follow-up-to: a5b730ae4fcfc88422a0ebf762cf1bd811ace567
Change-Id: Ie7a78e713d200de135d42e2bdda15c8aa4672468
diff --git a/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/ast/LtxParser.java b/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/ast/LtxParser.java
index 0e44ddd..07751c1 100644
--- a/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/ast/LtxParser.java
+++ b/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/ast/LtxParser.java
@@ -50,6 +50,7 @@
import org.eclipse.statet.docmlet.tex.core.parser.CustomScanner;
import org.eclipse.statet.docmlet.tex.core.parser.LtxLexer;
import org.eclipse.statet.ltk.ast.core.AstNode;
+import org.eclipse.statet.ltk.core.source.StatusDetail;
@NonNullByDefault
@@ -103,6 +104,7 @@
private final LtxLexer lexer;
+ private TextParserInput parseInput;
private int parseStartOffset;
private int parseEndOffset;
private @Nullable AstNode parseParent;
@@ -224,11 +226,25 @@
private void init0(final TextParserInput input, final @Nullable AstNode parent) {
+ this.parseInput= nonNullAssert(input);
this.parseStartOffset= input.getStartIndex();
this.parseEndOffset= input.getStopIndex();
this.parseParent= parent;
}
+ @SuppressWarnings("null")
+ private void clear0() {
+ this.parseInput= null;
+ this.parseParent= null;
+ }
+
+ private void logParseError(final Exception e) {
+ CommonsRuntime.log(new ErrorStatus(TexCore.BUNDLE_ID,
+ "An error occured while parsing TeX source code. Input:\n"
+ + this.parseInput.toString(),
+ e ));
+ }
+
private void initTask(final TextParserInput input, final TaskConfig config) {
if (this.commentsLevel != 0) {
this.comments.clear();
@@ -257,15 +273,19 @@
try {
initTask(input, new TaskConfig(commandSet));
- final SourceComponent node= new SourceComponent(null,
+ final SourceComponent sourceNode= new SourceComponent(null,
this.parseStartOffset, this.parseEndOffset );
- parseInput(node);
+ parseInput(sourceNode);
- return node;
+ return sourceNode;
}
catch (final Exception e) {
- return onParseError(e);
+ logParseError(e);
+ return createErrorSourceComponent();
+ }
+ finally {
+ clear0();
}
}
@@ -276,15 +296,19 @@
try {
initTask(input, new TaskConfig(commandSet));
- final SourceComponent node= new SourceComponent(parent,
+ final SourceComponent sourceNode= new SourceComponent(parent,
this.parseStartOffset, this.parseEndOffset );
- parseInput(node);
+ parseInput(sourceNode);
- return node;
+ return sourceNode;
}
catch (final Exception e) {
- return onParseError(e);
+ logParseError(e);
+ return createErrorSourceComponent();
+ }
+ finally {
+ clear0();
}
}
@@ -300,10 +324,7 @@
node.endOffset= this.lexer.getStopOffset();
}
- private SourceComponent onParseError(final Exception e) {
- CommonsRuntime.log(new ErrorStatus(TexCore.BUNDLE_ID,
- "An error occured while parsing LaTeX source code.",
- e ));
+ private SourceComponent createErrorSourceComponent() {
final int startOffset= this.parseStartOffset;
int endOffset= this.parseEndOffset;
if (endOffset < startOffset) {
@@ -317,23 +338,29 @@
return dummy;
}
- public ControlNode scanControlWordArgs(final TextParserInput input, final TexCommand command,
+ public ControlNode parseControlWordArgs(final TextParserInput input, final TexCommand command,
final boolean expand,
final TaskConfig config) {
- initTask(input, config);
-
- this.wasLinebreak= false;
- final ControlNode.Word controlNode= new ControlNode.Word(command.getControlWord());
- controlNode.startOffset= input.getStartIndex();
- controlNode.endOffset= input.getStartIndex();
- this.lexer.consume();
-
- parseWord(controlNode, command, false);
-
- if (expand && this.lexer.getOffset() > controlNode.endOffset) {
- controlNode.endOffset= this.lexer.getOffset();
+ init0(input, null);
+ try {
+ initTask(input, config);
+
+ this.wasLinebreak= false;
+ final ControlNode.Word controlNode= new ControlNode.Word(command.getControlWord());
+ controlNode.startOffset= this.parseStartOffset;
+ controlNode.endOffset= this.parseStartOffset;
+ this.lexer.consume();
+
+ parseWord(controlNode, command, false);
+
+ if (expand && this.lexer.getOffset() > controlNode.endOffset) {
+ controlNode.endOffset= this.lexer.getOffset();
+ }
+ return controlNode;
}
- return controlNode;
+ finally {
+ clear0();
+ }
}
@@ -874,6 +901,7 @@
if (this.lexer.next() == LtxLexer.VERBATIM_TEXT) {
this.wasLinebreak= false;
final TexAstNode verbatimNode;
+ final StatusDetail statusDetail;
switch (this.lexer.getFlags()) {
case LtxLexer.SUB_OPEN_MISSING:
// verbatimNode= new Dummy();
@@ -889,16 +917,18 @@
verbatimNode.texParent= controlNode;
verbatimNode.status= TYPE123_VERBATIM_INLINE_NOT_CLOSED;
verbatimNode.startOffset= this.lexer.getOffset() + 1;
- verbatimNode.endOffset= controlNode.endOffset=
- this.lexer.getStopOffset();
+ verbatimNode.endOffset= controlNode.endOffset= this.lexer.getStopOffset();
+ statusDetail= this.lexer.getStatusDetail();
+ if (statusDetail != null) {
+ verbatimNode.addAttachment(statusDetail);
+ }
this.lexer.consume();
break;
default:
verbatimNode= new Verbatim();
verbatimNode.texParent= controlNode;
verbatimNode.startOffset= this.lexer.getOffset() + 1;
- verbatimNode.endOffset= controlNode.endOffset=
- this.lexer.getStopOffset() - 1;
+ verbatimNode.endOffset= controlNode.endOffset= this.lexer.getStopOffset() - 1;
this.lexer.consume();
break;
}
diff --git a/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/model/build/LtxIssueReporter.java b/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/model/build/LtxIssueReporter.java
index 03caa46..462526f 100644
--- a/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/model/build/LtxIssueReporter.java
+++ b/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/model/build/LtxIssueReporter.java
@@ -26,7 +26,7 @@
import org.eclipse.statet.docmlet.tex.core.model.TexSourceUnit;
import org.eclipse.statet.docmlet.tex.core.project.TexProject;
import org.eclipse.statet.internal.docmlet.tex.core.builder.TexTaskTagReporter;
-import org.eclipse.statet.internal.docmlet.tex.core.model.LtxProblemAstVisitor;
+import org.eclipse.statet.internal.docmlet.tex.core.model.AstProblemReporter;
import org.eclipse.statet.internal.docmlet.tex.core.model.LtxProblemModelCheck;
import org.eclipse.statet.ltk.core.source.SourceContent;
import org.eclipse.statet.ltk.issues.core.IssueRequestor;
@@ -37,7 +37,7 @@
public class LtxIssueReporter {
- private final LtxProblemAstVisitor astVisitor= new LtxProblemAstVisitor();
+ private final AstProblemReporter astVisitor= new AstProblemReporter();
private final LtxProblemModelCheck modelCheck= new LtxProblemModelCheck();
private final TexTaskTagReporter taskReporter= new TexTaskTagReporter();
diff --git a/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/parser/LtxLexer.java b/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/parser/LtxLexer.java
index ddc96e0..d69e3b2 100644
--- a/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/parser/LtxLexer.java
+++ b/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/docmlet/tex/core/parser/LtxLexer.java
@@ -14,9 +14,13 @@
package org.eclipse.statet.docmlet.tex.core.parser;
+import org.eclipse.statet.jcommons.lang.Nullable;
+import org.eclipse.statet.jcommons.string.BasicStringFactory;
import org.eclipse.statet.jcommons.string.StringFactory;
import org.eclipse.statet.jcommons.text.core.input.TextParserInput;
+import org.eclipse.statet.ltk.core.source.StatusDetail;
+
public class LtxLexer {
@@ -70,11 +74,19 @@
/*=============================================================================*/
+ private static StatusDetail createDetail(final TextParserInput in,
+ final int startOffset, final int endOffset, final @Nullable String text) {
+ final int beginIndex= in.getIndex(startOffset);
+ return new StatusDetail(beginIndex, in.getIndex() + in.getLengthInSource(endOffset),
+ text );
+ }
+
private TextParserInput input;
private byte foundType;
private int foundFlags;
+ private @Nullable StatusDetail foundDetail;
private int foundOffset;
private int foundNum;
private int foundLength;
@@ -199,6 +211,10 @@
return this.foundFlags;
}
+ public final @Nullable StatusDetail getStatusDetail() {
+ return this.foundDetail;
+ }
+
public final int getOffset() {
return this.foundOffset;
}
@@ -267,18 +283,21 @@
private void foundEOF(final TextParserInput in) {
this.foundType= EOF;
this.foundFlags= 0;
+ this.foundDetail= null;
this.foundLength= in.getLengthInSource(this.foundNum= 0);
}
private void foundLineComment(final TextParserInput in, final int n) {
this.foundType= LINE_COMMENT;
this.foundFlags= 0;
+ this.foundDetail= null;
this.foundLength= in.getLengthInSource(this.foundNum= n);
}
private void foundLinebreak(final TextParserInput in, final int n) {
this.foundType= LINEBREAK;
this.foundFlags= 0;
+ this.foundDetail= null;
this.foundLength= in.getLengthInSource(this.foundNum= n);
this.wasLinebreak= true;
}
@@ -286,12 +305,14 @@
private void foundWhitespace(final TextParserInput in, final int n) {
this.foundType= WHITESPACE;
this.foundFlags= 0;
+ this.foundDetail= null;
this.foundLength= in.getLengthInSource(this.foundNum= n);
}
private void foundControlLinebreak(final TextParserInput in, final int n) {
this.foundType= CONTROL_CHAR;
this.foundFlags= 0;
+ this.foundDetail= null;
this.foundLength= in.getLengthInSource(this.foundNum= n);
this.wasLinebreak= true;
}
@@ -299,18 +320,21 @@
private void found1(final TextParserInput in, final byte type) {
this.foundType= type;
this.foundFlags= 0;
+ this.foundDetail= null;
this.foundLength= in.getLengthInSource(this.foundNum= 1);
}
private void found2(final TextParserInput in, final byte type) {
this.foundType= type;
this.foundFlags= 0;
+ this.foundDetail= null;
this.foundLength= in.getLengthInSource(this.foundNum= 2);
}
private void found(final TextParserInput in, final byte type, final int n) {
this.foundType= type;
this.foundFlags= 0;
+ this.foundDetail= null;
this.foundLength= in.getLengthInSource(this.foundNum= n);
}
@@ -318,14 +342,18 @@
final byte newState) {
this.foundType= VERBATIM_TEXT;
this.foundFlags= 0;
+ this.foundDetail= null;
this.foundLength= in.getLengthInSource(this.foundNum= n);
this.state= newState;
}
- private void foundVerbatimText(final TextParserInput in, final byte flags, final int n,
+ private void foundVerbatimText(final TextParserInput in,
+ final byte flags, final @Nullable StatusDetail detail,
+ final int n,
final byte newState) {
this.foundType= VERBATIM_TEXT;
this.foundFlags= flags;
+ this.foundDetail= detail;
this.foundLength= in.getLengthInSource(this.foundNum= n);
this.state= newState;
}
@@ -675,7 +703,9 @@
ITER_CN: while (true) {
switch (in.get(n++)) {
case TextParserInput.EOF:
- foundVerbatimText(in, SUB_CLOSE_MISSING, n - 1, S_DEFAULT);
+ foundVerbatimText(in, SUB_CLOSE_MISSING,
+ null,
+ n - 1, S_DEFAULT );
return;
case '\r':
if (in.get(n) == '\n') {
@@ -706,7 +736,7 @@
final TextParserInput in= this.input;
final int end= in.get(0);
if (end < 0x20) {
- foundVerbatimText(in, SUB_OPEN_MISSING, 0, this.savedVerbatimState);
+ foundVerbatimText(in, SUB_OPEN_MISSING, null, 0, this.savedVerbatimState);
return;
}
int n= 1;
@@ -716,7 +746,9 @@
case TextParserInput.EOF:
case '\r':
case '\n':
- foundVerbatimText(in, SUB_CLOSE_MISSING, n - 1, this.savedVerbatimState);
+ foundVerbatimText(in, SUB_CLOSE_MISSING,
+ createDetail(in, 0, n - 1, BasicStringFactory.INSTANCE.get(end)),
+ n - 1, this.savedVerbatimState );
return;
default:
if (c == end) {
diff --git a/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/internal/docmlet/tex/core/model/AstProblemReporter.java b/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/internal/docmlet/tex/core/model/AstProblemReporter.java
new file mode 100644
index 0000000..e13a9c7
--- /dev/null
+++ b/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/internal/docmlet/tex/core/model/AstProblemReporter.java
@@ -0,0 +1,380 @@
+/*=============================================================================#
+ # Copyright (c) 2012, 2021 Stephan Wahlbrink and others.
+ #
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ #
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ #
+ # Contributors:
+ # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.internal.docmlet.tex.core.model;
+
+import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_ENV_MISSING_NAME;
+import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_ENV_NOT_CLOSED;
+import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_ENV_NOT_OPENED;
+import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_GROUP_NOT_CLOSED;
+import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_GROUP_NOT_OPENED;
+import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_MATH_NOT_CLOSED;
+import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_VERBATIM_INLINE_C_MISSING;
+import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_VERBATIM_INLINE_NOT_CLOSED;
+import static org.eclipse.statet.ltk.core.StatusCodes.TYPE123;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.jface.text.BadLocationException;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+import org.eclipse.statet.jcommons.lang.Nullable;
+
+import org.eclipse.statet.docmlet.tex.core.ast.Comment;
+import org.eclipse.statet.docmlet.tex.core.ast.ControlNode;
+import org.eclipse.statet.docmlet.tex.core.ast.Dummy;
+import org.eclipse.statet.docmlet.tex.core.ast.Embedded;
+import org.eclipse.statet.docmlet.tex.core.ast.Environment;
+import org.eclipse.statet.docmlet.tex.core.ast.Group;
+import org.eclipse.statet.docmlet.tex.core.ast.Label;
+import org.eclipse.statet.docmlet.tex.core.ast.Math;
+import org.eclipse.statet.docmlet.tex.core.ast.SourceComponent;
+import org.eclipse.statet.docmlet.tex.core.ast.TexAstNode;
+import org.eclipse.statet.docmlet.tex.core.ast.TexAstVisitor;
+import org.eclipse.statet.docmlet.tex.core.ast.Text;
+import org.eclipse.statet.docmlet.tex.core.ast.Verbatim;
+import org.eclipse.statet.docmlet.tex.core.model.TexModel;
+import org.eclipse.statet.docmlet.tex.core.model.TexSourceUnit;
+import org.eclipse.statet.ltk.ast.core.util.AbstractAstProblemReporter;
+import org.eclipse.statet.ltk.core.source.SourceContent;
+import org.eclipse.statet.ltk.core.source.StatusDetail;
+import org.eclipse.statet.ltk.issues.core.IssueRequestor;
+import org.eclipse.statet.ltk.issues.core.Problem;
+
+
+@NonNullByDefault
+public class AstProblemReporter extends AbstractAstProblemReporter {
+
+
+ private static final int ENV_LABEL_LIMIT= 20;
+
+
+ private final Visitor visitor= new Visitor();
+
+
+ public AstProblemReporter() {
+ super(TexModel.LTX_TYPE_ID);
+ }
+
+
+ public void run(final TexSourceUnit sourceUnit, final TexAstNode node,
+ final SourceContent content,
+ final IssueRequestor requestor) {
+ try {
+ init(content, requestor);
+
+ node.acceptInTex(this.visitor);
+
+ flush();
+ }
+ catch (final InvocationTargetException e) {}
+ finally {
+ clear();
+ }
+ }
+
+
+ protected void handleCommonCodes(final TexAstNode node, final int code)
+ throws BadLocationException, InvocationTargetException {
+ super.handleCommonCodes(node, code);
+ }
+
+
+ private class Visitor extends TexAstVisitor {
+
+
+ @Override
+ public void visit(final SourceComponent node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ node.acceptInTexChildren(this);
+ }
+
+ @Override
+ public void visit(final Group node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ switch (code & TYPE123) {
+
+ case TYPE123_GROUP_NOT_CLOSED:
+ if (node.getParent() instanceof ControlNode) {
+ addProblem(Problem.SEVERITY_ERROR, code,
+ (node.getText() == "{") ? //$NON-NLS-1$
+ ProblemMessages.Ast_ReqArgument_NotClosed_message :
+ ProblemMessages.Ast_OptArgument_NotClosed_Opt_message,
+ node.getStartOffset(), node.getStartOffset() + 1 );
+ break STATUS;
+ }
+ else {
+ addProblem(Problem.SEVERITY_ERROR, code,
+ (node.getText() == "{") ? //$NON-NLS-1$
+ ProblemMessages.Ast_CurlyBracket_NotClosed_message :
+ ProblemMessages.Ast_SquareBracket_NotClosed_message,
+ node.getStartOffset(), node.getStartOffset() + 1 );
+ break STATUS;
+ }
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ node.acceptInTexChildren(this);
+ }
+
+ @Override
+ public void visit(final Environment node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ switch (code & TYPE123) {
+
+ case TYPE123_ENV_NOT_CLOSED: {
+ final TexAstNode beginNode= node.getBeginNode();
+ addProblem(Problem.SEVERITY_ERROR, code,
+ getMessageBuilder().bind(ProblemMessages.Ast_Env_NotClosed_message,
+ limit(node.getText(), ENV_LABEL_LIMIT) ),
+ beginNode.getStartOffset(), beginNode.getEndOffset() );
+ break STATUS;
+ }
+ case TYPE123_MATH_NOT_CLOSED: {
+ final TexAstNode beginNode= node.getBeginNode();
+ String c= node.getText();
+ if (c == "[") { //$NON-NLS-1$
+ c= "\\]"; //$NON-NLS-1$
+ }
+ else if (c == "(") { //$NON-NLS-1$
+ c= "\\)"; //$NON-NLS-1$
+ }
+ else {
+ c= null;
+ }
+ if (c != null) {
+ addProblem(Problem.SEVERITY_ERROR, code,
+ getMessageBuilder().bind(
+ ProblemMessages.Ast_Math_NotClosed_message,
+ c ),
+ beginNode.getStartOffset(), beginNode.getEndOffset() );
+ }
+ break STATUS;
+ }
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ node.acceptInTexChildren(this);
+ }
+
+ @Override
+ public void visit(final ControlNode node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ switch (code & TYPE123) {
+
+ case TYPE123_ENV_MISSING_NAME:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ (node.getText().equals("begin")) ? //$NON-NLS-1$
+ ProblemMessages.Ast_Env_MissingName_Begin_message :
+ ProblemMessages.Ast_Env_MissingName_End_message,
+ node.getStartOffset(), node.getEndOffset() );
+ break STATUS;
+ case TYPE123_ENV_NOT_OPENED:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ getMessageBuilder().bind(
+ ProblemMessages.Ast_Env_NotOpened_message,
+ limit(node.getChild(0).getChild(0).getText(), ENV_LABEL_LIMIT) ),
+ node.getStartOffset(), node.getEndOffset() );
+ break STATUS;
+
+ case TYPE123_VERBATIM_INLINE_C_MISSING:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Ast_Verbatim_MissingSep_message,
+ node.getEndOffset()-1, node.getEndOffset() );
+ break STATUS;
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ node.acceptInTexChildren(this);
+ }
+
+ @Override
+ public void visit(final Text node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ @Override
+ public void visit(final Label node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ @Override
+ public void visit(final Math node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ switch (code & TYPE123) {
+
+ case TYPE123_MATH_NOT_CLOSED:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ getMessageBuilder().bind(
+ ProblemMessages.Ast_Math_NotClosed_message,
+ node.getText() ),
+ node.getStartOffset(), node.getStartOffset() + node.getText().length() );
+ break STATUS;
+
+ default:
+ handleCommonCodes(node, code);
+ break;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ node.acceptInTexChildren(this);
+ }
+
+ @Override
+ public void visit(final Verbatim node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ switch (code & TYPE123) {
+
+ case TYPE123_VERBATIM_INLINE_NOT_CLOSED:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ getMessageBuilder().bind(
+ ProblemMessages.Ast_Verbatim_NotClosed_message,
+ StatusDetail.getStatusDetail(node).getText() ),
+ node.getEndOffset() - 1, node.getEndOffset() );
+ break STATUS;
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ @Override
+ public void visit(final Comment node) throws InvocationTargetException {
+ }
+
+ @Override
+ public void visit(final Dummy node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ switch (code & TYPE123) {
+
+ case TYPE123_GROUP_NOT_OPENED:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ (node.getText() == "{") ? //$NON-NLS-1$
+ ProblemMessages.Ast_CurlyBracket_NotOpened_message :
+ ProblemMessages.Ast_SquareBracket_NotOpened_message,
+ node.getStartOffset(), node.getStartOffset() + 1 );
+ break STATUS;
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+
+ node.acceptInTexChildren(this);
+ }
+
+ @Override
+ public void visit(final Embedded node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ }
+
+
+ protected static final @Nullable String limit(final @Nullable String label, final int limit) {
+ if (label != null && label.length() > limit) {
+ return label.substring(0, limit) + '…';
+ }
+ return label;
+ }
+
+}
diff --git a/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/internal/docmlet/tex/core/model/LtxProblemAstVisitor.java b/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/internal/docmlet/tex/core/model/LtxProblemAstVisitor.java
deleted file mode 100644
index 9c51b51..0000000
--- a/docmlet/org.eclipse.statet.docmlet.tex.core/src/org/eclipse/statet/internal/docmlet/tex/core/model/LtxProblemAstVisitor.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*=============================================================================#
- # Copyright (c) 2012, 2021 Stephan Wahlbrink and others.
- #
- # This program and the accompanying materials are made available under the
- # terms of the Eclipse Public License 2.0 which is available at
- # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
- # which is available at https://www.apache.org/licenses/LICENSE-2.0.
- #
- # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
- #
- # Contributors:
- # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
- #=============================================================================*/
-
-package org.eclipse.statet.internal.docmlet.tex.core.model;
-
-import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
-import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
-
-import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_ENV_MISSING_NAME;
-import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_ENV_NOT_CLOSED;
-import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_ENV_NOT_OPENED;
-import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_GROUP_NOT_CLOSED;
-import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_GROUP_NOT_OPENED;
-import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_MATH_NOT_CLOSED;
-import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_VERBATIM_INLINE_C_MISSING;
-import static org.eclipse.statet.docmlet.tex.core.ast.TexAstStatusConstants.TYPE123_VERBATIM_INLINE_NOT_CLOSED;
-import static org.eclipse.statet.ltk.core.StatusCodes.TYPE123;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.statet.jcommons.lang.NonNullByDefault;
-import org.eclipse.statet.jcommons.lang.Nullable;
-
-import org.eclipse.statet.ecommons.runtime.core.util.MessageBuilder;
-
-import org.eclipse.statet.docmlet.tex.core.ast.Comment;
-import org.eclipse.statet.docmlet.tex.core.ast.ControlNode;
-import org.eclipse.statet.docmlet.tex.core.ast.Dummy;
-import org.eclipse.statet.docmlet.tex.core.ast.Embedded;
-import org.eclipse.statet.docmlet.tex.core.ast.Environment;
-import org.eclipse.statet.docmlet.tex.core.ast.Group;
-import org.eclipse.statet.docmlet.tex.core.ast.Label;
-import org.eclipse.statet.docmlet.tex.core.ast.Math;
-import org.eclipse.statet.docmlet.tex.core.ast.SourceComponent;
-import org.eclipse.statet.docmlet.tex.core.ast.TexAstNode;
-import org.eclipse.statet.docmlet.tex.core.ast.TexAstVisitor;
-import org.eclipse.statet.docmlet.tex.core.ast.Text;
-import org.eclipse.statet.docmlet.tex.core.ast.Verbatim;
-import org.eclipse.statet.docmlet.tex.core.model.TexModel;
-import org.eclipse.statet.docmlet.tex.core.model.TexSourceUnit;
-import org.eclipse.statet.ltk.core.source.SourceContent;
-import org.eclipse.statet.ltk.issues.core.IssueRequestor;
-import org.eclipse.statet.ltk.issues.core.Problem;
-import org.eclipse.statet.ltk.issues.core.impl.BasicProblem;
-import org.eclipse.statet.ltk.model.core.element.SourceUnit;
-
-
-@NonNullByDefault
-public class LtxProblemAstVisitor extends TexAstVisitor {
-
-
- private static final int ENV_LABEL_LIMIT= 20;
- private static final int BUFFER_SIZE= 100;
-
-
- private SourceUnit sourceUnit= nonNullLateInit();
- private SourceContent sourceContent= nonNullLateInit();
- private IssueRequestor requestor= nonNullLateInit();
-
- private final MessageBuilder messageBuilder= new MessageBuilder();
- private final List<Problem> problemBuffer= new ArrayList<>(BUFFER_SIZE);
-
-
- public LtxProblemAstVisitor() {
- }
-
-
- public void run(final TexSourceUnit sourceUnit, final TexAstNode node,
- final SourceContent content,
- final IssueRequestor requestor) {
- try {
- this.sourceUnit= nonNullAssert(sourceUnit);
- this.sourceContent= nonNullAssert(content);
- this.requestor= nonNullAssert(requestor);
-
- node.acceptInTex(this);
-
- if (this.problemBuffer.size() > 0) {
- this.requestor.acceptProblems(TexModel.LTX_TYPE_ID, this.problemBuffer);
- }
- }
- catch (final InvocationTargetException e) {}
- finally {
- clear();
- }
- }
-
- @SuppressWarnings("null")
- private void clear() {
- this.problemBuffer.clear();
- this.sourceUnit= null;
- this.sourceContent= null;
- this.requestor= null;
- }
-
-
- @Override
- public void visit(final SourceComponent node) throws InvocationTargetException {
- node.acceptInTexChildren(this);
- }
-
- @Override
- public void visit(final Group node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & TYPE123);
- if (code == TYPE123_GROUP_NOT_CLOSED) {
- if (node.getParent() instanceof ControlNode) {
- addProblem(Problem.SEVERITY_ERROR, code, (node.getText() == "{") ? //$NON-NLS-1$
- ProblemMessages.Ast_ReqArgument_NotClosed_message :
- ProblemMessages.Ast_OptArgument_NotClosed_Opt_message,
- node.getStartOffset(), node.getStartOffset() + 1 );
- }
- else {
- addProblem(Problem.SEVERITY_ERROR, code, (node.getText() == "{") ? //$NON-NLS-1$
- ProblemMessages.Ast_CurlyBracket_NotClosed_message :
- ProblemMessages.Ast_SquareBracket_NotClosed_message,
- node.getStartOffset(), node.getStartOffset() + 1 );
- }
- }
-
- node.acceptInTexChildren(this);
- }
-
- @Override
- public void visit(final Environment node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & TYPE123);
- switch (code) {
- case TYPE123_ENV_NOT_CLOSED: {
- final TexAstNode beginNode= node.getBeginNode();
- addProblem(Problem.SEVERITY_ERROR, code,
- this.messageBuilder.bind(ProblemMessages.Ast_Env_NotClosed_message,
- limit(node.getText(), ENV_LABEL_LIMIT) ),
- beginNode.getStartOffset(), beginNode.getEndOffset() );
- break; }
- case TYPE123_MATH_NOT_CLOSED: {
- final TexAstNode beginNode= node.getBeginNode();
- String c= node.getText();
- if (c == "[") { //$NON-NLS-1$
- c= "\\]"; //$NON-NLS-1$
- }
- else if (c == "(") { //$NON-NLS-1$
- c= "\\)"; //$NON-NLS-1$
- }
- else {
- c= null;
- }
- if (c != null) {
- addProblem(Problem.SEVERITY_ERROR, code,
- this.messageBuilder.bind(ProblemMessages.Ast_Math_NotClosed_message, c),
- beginNode.getStartOffset(), beginNode.getEndOffset() );
- }
- break; }
- }
-
- node.acceptInTexChildren(this);
- }
-
- @Override
- public void visit(final ControlNode node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & TYPE123);
- switch (code) {
- case TYPE123_ENV_MISSING_NAME:
- addProblem(Problem.SEVERITY_ERROR, code, (node.getText().equals("begin")) ? //$NON-NLS-1$
- ProblemMessages.Ast_Env_MissingName_Begin_message :
- ProblemMessages.Ast_Env_MissingName_End_message,
- node.getStartOffset(), node.getEndOffset() );
- break;
- case TYPE123_ENV_NOT_OPENED:
- addProblem(Problem.SEVERITY_ERROR, code,
- this.messageBuilder.bind(ProblemMessages.Ast_Env_NotOpened_message,
- limit(node.getChild(0).getChild(0).getText(), ENV_LABEL_LIMIT) ),
- node.getStartOffset(), node.getEndOffset() );
- break;
- case TYPE123_VERBATIM_INLINE_C_MISSING:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Ast_Verbatim_MissingSep_message,
- node.getEndOffset()-1, node.getEndOffset() );
- break;
- }
-
- node.acceptInTexChildren(this);
- }
-
- @Override
- public void visit(final Text node) throws InvocationTargetException {
- }
-
- @Override
- public void visit(final Label node) throws InvocationTargetException {
- }
-
- @Override
- public void visit(final Math node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & TYPE123);
- switch (code) {
- case TYPE123_MATH_NOT_CLOSED:
- addProblem(Problem.SEVERITY_ERROR, code,
- this.messageBuilder.bind(ProblemMessages.Ast_Math_NotClosed_message,
- node.getText() ),
- node.getStartOffset(), node.getStartOffset() + node.getText().length() );
- break;
- }
- node.acceptInTexChildren(this);
- }
-
- @Override
- public void visit(final Verbatim node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & TYPE123);
- switch (code) {
- case TYPE123_VERBATIM_INLINE_NOT_CLOSED:
- addProblem(Problem.SEVERITY_ERROR, code,
- this.messageBuilder.bind(ProblemMessages.Ast_Verbatim_NotClosed_message,
- this.sourceContent.getString(node.getStartOffset() - 1, node.getStartOffset()) ),
- node.getEndOffset() - 1, node.getEndOffset() );
- break;
- }
- }
-
- @Override
- public void visit(final Comment node) throws InvocationTargetException {
- }
-
- @Override
- public void visit(final Dummy node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & TYPE123);
- switch (code) {
- case TYPE123_GROUP_NOT_OPENED:
- addProblem(Problem.SEVERITY_ERROR, code, (node.getText() == "{") ? //$NON-NLS-1$
- ProblemMessages.Ast_CurlyBracket_NotOpened_message :
- ProblemMessages.Ast_SquareBracket_NotOpened_message,
- node.getStartOffset(), node.getStartOffset() + 1 );
- break;
- }
- }
-
- @Override
- public void visit(final Embedded node) throws InvocationTargetException {
- }
-
-
- protected final @Nullable String limit(final @Nullable String label, final int limit) {
- if (label != null && label.length() > limit) {
- return label.substring(0, limit) + '…';
- }
- return label;
- }
-
- protected final void addProblem(final int severity, final int code, final String message,
- int startOffset, int endOffset) {
- if (startOffset < this.sourceContent.getStartOffset()) {
- startOffset= this.sourceContent.getStartOffset();
- }
- if (endOffset > this.sourceContent.getEndOffset()) {
- endOffset= this.sourceContent.getEndOffset();
- }
- this.problemBuffer.add(new BasicProblem(TexModel.LTX_TYPE_ID, severity, code, message,
- startOffset, endOffset ));
- if (this.problemBuffer.size() >= BUFFER_SIZE) {
- this.requestor.acceptProblems(TexModel.LTX_TYPE_ID, this.problemBuffer);
- this.problemBuffer.clear();
- }
- }
-
-}
diff --git a/docmlet/org.eclipse.statet.docmlet.tex.ui/src/org/eclipse/statet/internal/docmlet/tex/ui/sourceediting/LtxContextInformationValidator.java b/docmlet/org.eclipse.statet.docmlet.tex.ui/src/org/eclipse/statet/internal/docmlet/tex/ui/sourceediting/LtxContextInformationValidator.java
index 366a248..ccd783d 100644
--- a/docmlet/org.eclipse.statet.docmlet.tex.ui/src/org/eclipse/statet/internal/docmlet/tex/ui/sourceediting/LtxContextInformationValidator.java
+++ b/docmlet/org.eclipse.statet.docmlet.tex.ui/src/org/eclipse/statet/internal/docmlet/tex/ui/sourceediting/LtxContextInformationValidator.java
@@ -178,7 +178,7 @@
final int docEndOffset= Math.min(0x800, rRootNode.getEndOffset() - docStartOffset);
final String text= document.get(docStartOffset, docEndOffset);
final LtxParser parser= new LtxParser(new NowebLtxLexer(), null);
- args= parser.scanControlWordArgs(new OffsetStringParserInput(text, startOffset)
+ args= parser.parseControlWordArgs(new OffsetStringParserInput(text, startOffset)
.init(startOffset, startOffset + text.length()),
info.getCommand(), true, getParserTaskConfig());
}
diff --git a/yaml/org.eclipse.statet.yaml.core-tests/src/org/eclipse/statet/internal/yaml/core/model/SyntaxProblemReporterTest.java b/yaml/org.eclipse.statet.yaml.core-tests/src/org/eclipse/statet/internal/yaml/core/model/AstProblemReporterTest.java
similarity index 98%
rename from yaml/org.eclipse.statet.yaml.core-tests/src/org/eclipse/statet/internal/yaml/core/model/SyntaxProblemReporterTest.java
rename to yaml/org.eclipse.statet.yaml.core-tests/src/org/eclipse/statet/internal/yaml/core/model/AstProblemReporterTest.java
index 8256ef0..b98cfd7 100644
--- a/yaml/org.eclipse.statet.yaml.core-tests/src/org/eclipse/statet/internal/yaml/core/model/SyntaxProblemReporterTest.java
+++ b/yaml/org.eclipse.statet.yaml.core-tests/src/org/eclipse/statet/internal/yaml/core/model/AstProblemReporterTest.java
@@ -36,15 +36,15 @@
@NonNullByDefault
-public class SyntaxProblemReporterTest {
+public class AstProblemReporterTest {
private final YamlParser yamlParser= new YamlParser();
- private final SyntaxProblemReporter syntaxProblemReporter= new SyntaxProblemReporter();
+ private final AstProblemReporter syntaxProblemReporter= new AstProblemReporter();
- public SyntaxProblemReporterTest() {
+ public AstProblemReporterTest() {
}
diff --git a/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/internal/yaml/core/model/AstProblemReporter.java b/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/internal/yaml/core/model/AstProblemReporter.java
new file mode 100644
index 0000000..5d9b916
--- /dev/null
+++ b/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/internal/yaml/core/model/AstProblemReporter.java
@@ -0,0 +1,465 @@
+/*=============================================================================#
+ # Copyright (c) 2012, 2021 Stephan Wahlbrink and others.
+ #
+ # This program and the accompanying materials are made available under the
+ # terms of the Eclipse Public License 2.0 which is available at
+ # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
+ # which is available at https://www.apache.org/licenses/LICENSE-2.0.
+ #
+ # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
+ #
+ # Contributors:
+ # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
+ #=============================================================================*/
+
+package org.eclipse.statet.internal.yaml.core.model;
+
+import static org.eclipse.statet.ltk.ast.core.AstNode.NA_OFFSET;
+import static org.eclipse.statet.ltk.core.StatusCodes.CTX12;
+import static org.eclipse.statet.ltk.core.StatusCodes.TYPE12;
+import static org.eclipse.statet.ltk.core.StatusCodes.TYPE123;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_DIRECTIVES_END_MARKER;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_DOC_CONTENT;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_MAP_ENTRY;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_MAP_FLOW;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_MAP_KEY;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_MAP_VALUE;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_SCALAR_FLOW;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_SEQ_ENTRY;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_SEQ_FLOW;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_TAG_VERBATIM;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE123_SYNTAX_CHOMPING_INDICATOR_MULTIPLE;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE123_SYNTAX_INDENTATION_INDICATOR_INVALID;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE123_SYNTAX_LINE_BREAK_MISSING;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE123_SYNTAX_SPACE_BEFORE_COMMENT_MISSING;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_CHAR_INVALID;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_COLLECTION_NOT_CLOSED;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_ESCAPE_INVALID;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_MISSING_INDICATOR;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_MISSING_MARKER;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_MISSING_NODE;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_SEP_COMMA_MISSING;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_TOKEN_NOT_CLOSED;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_TOKEN_UNEXPECTED;
+import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_TOKEN_UNKNOWN;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.jface.text.BadLocationException;
+
+import org.eclipse.statet.jcommons.lang.NonNullByDefault;
+
+import org.eclipse.statet.ltk.ast.core.util.AbstractAstProblemReporter;
+import org.eclipse.statet.ltk.core.source.SourceContent;
+import org.eclipse.statet.ltk.core.source.StatusDetail;
+import org.eclipse.statet.ltk.issues.core.IssueRequestor;
+import org.eclipse.statet.ltk.issues.core.Problem;
+import org.eclipse.statet.yaml.core.model.YamlModel;
+import org.eclipse.statet.yaml.core.source.ast.Alias;
+import org.eclipse.statet.yaml.core.source.ast.Anchor;
+import org.eclipse.statet.yaml.core.source.ast.Collection;
+import org.eclipse.statet.yaml.core.source.ast.Directive;
+import org.eclipse.statet.yaml.core.source.ast.Dummy;
+import org.eclipse.statet.yaml.core.source.ast.MapEntry;
+import org.eclipse.statet.yaml.core.source.ast.Marker;
+import org.eclipse.statet.yaml.core.source.ast.Scalar;
+import org.eclipse.statet.yaml.core.source.ast.SeqEntry;
+import org.eclipse.statet.yaml.core.source.ast.Tag;
+import org.eclipse.statet.yaml.core.source.ast.YamlAstNode;
+import org.eclipse.statet.yaml.core.source.ast.YamlAstVisitor;
+
+
+@NonNullByDefault
+public class AstProblemReporter extends AbstractAstProblemReporter {
+
+
+ private final Visitor visitor= new Visitor();
+
+
+ public AstProblemReporter() {
+ super(YamlModel.YAML_TYPE_ID);
+ }
+
+
+ public void run(final YamlAstNode node,
+ final SourceContent content,
+ final IssueRequestor requestor) {
+ try {
+ init(content, requestor);
+
+ node.acceptInYaml(this.visitor);
+
+ flush();
+ }
+ catch (final OperationCanceledException | InvocationTargetException e) {}
+ finally {
+ clear();
+ }
+ }
+
+
+ protected void handleCommonCodes(final YamlAstNode node, final int code)
+ throws BadLocationException, InvocationTargetException {
+ final StatusDetail detail;
+ TYPE12: switch (code & TYPE12) {
+
+ case TYPE12_SYNTAX_TOKEN_UNKNOWN:
+ addProblem(Problem.SEVERITY_ERROR, code, getMessageBuilder().bind(
+ ProblemMessages.Syntax_Gen_TokenUnknown_message,
+ getMessageUtil().getStartText(node, 0) ),
+ node.getStartOffset(), node.getEndOffset() );
+ return;
+
+ case TYPE12_SYNTAX_TOKEN_UNEXPECTED:
+ addProblem(Problem.SEVERITY_ERROR, code, getMessageBuilder().bind(
+ ProblemMessages.Syntax_Gen_TokenUnexpected_message,
+ getMessageUtil().getStartText(node, 0) ),
+ node.getStartOffset(), node.getEndOffset() );
+ return;
+
+ case TYPE12_SYNTAX_MISSING_NODE:
+// addProblem(Problem.SEVERITY_ERROR, code,
+// ProblemMessages.Syntax_Gen_NodeMissing_message,
+// node.getStartOffset(), node.getEndOffset() );
+ return;
+
+ case TYPE12_SYNTAX_CHAR_INVALID:
+ detail= StatusDetail.getStatusDetail(node);
+ if (detail != null) {
+ switch (code & TYPE123) {
+ case TYPE123_SYNTAX_SPACE_BEFORE_COMMENT_MISSING:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_Comment_SpaceBeforeMissing_message,
+ detail.getStartOffset(), detail.getEndOffset() );
+ return;
+ case TYPE123_SYNTAX_LINE_BREAK_MISSING:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_Gen_LineBreakMissing_message,
+ detail.getStartOffset(), detail.getEndOffset() );
+ return;
+ default:
+ addProblem(Problem.SEVERITY_ERROR, code, getMessageBuilder().bind(
+ ProblemMessages.Syntax_Gen_TokenUnexpected_message,
+ getMessageUtil().getStartText(node, 0) ),
+ node.getStartOffset(), node.getEndOffset() );
+ return;
+ }
+ }
+ break TYPE12;
+
+ default:
+ break TYPE12;
+ }
+
+ super.handleCommonCodes(node, code);
+ }
+
+
+ private class Visitor extends YamlAstVisitor {
+
+
+ // @Override
+ // public void visit(SourceComponent node) throws InvocationTargetException {
+ // super.visit(node);
+ // }
+
+ // @Override
+ // public void visit(final DocumentNode node) throws InvocationTargetException {
+ // super.visit(node);
+ // }
+
+ @Override
+ public void visit(final Marker node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ { handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ @Override
+ public void visit(final Directive node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ { handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ // @Override
+ // public void visit(final NodeWithProperties node) throws InvocationTargetException {
+ // super.visit(node);
+ // }
+
+ @Override
+ public void visit(final Tag node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ switch (code & (TYPE12 | CTX12)) {
+ case TYPE12_SYNTAX_TOKEN_NOT_CLOSED | CTX12_TAG_VERBATIM:
+ addProblem(Problem.SEVERITY_ERROR, code, getMessageBuilder().bind(
+ ProblemMessages.Syntax_Tag_VerbatimTag_NotClosed_message,
+ getMessageUtil().getStartText(node, 0) ),
+ node.getEndOffset(), node.getEndOffset() + 1);
+ break STATUS;
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ @Override
+ public void visit(final Anchor node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ { handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ @Override
+ public void visit(final Collection node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ final int offset;
+ switch (code & (TYPE12 | CTX12)) {
+ case TYPE12_SYNTAX_COLLECTION_NOT_CLOSED | CTX12_SEQ_FLOW:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_FlowSeq_NotClosed_message,
+ offset= node.getStartOffset(), offset + 1 );
+ break STATUS;
+ case TYPE12_SYNTAX_COLLECTION_NOT_CLOSED | CTX12_MAP_FLOW:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_FlowMap_NotClosed_message,
+ offset= node.getStartOffset(), offset + 1 );
+ break STATUS;
+
+ case TYPE12_SYNTAX_SEP_COMMA_MISSING | CTX12_SEQ_FLOW:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_FlowSeq_SeqEntrySeparatorMissing_message,
+ offset= getMissingSepOffset((Collection.FlowCollection)node), offset + 1 );
+ break STATUS;
+ case TYPE12_SYNTAX_SEP_COMMA_MISSING | CTX12_MAP_FLOW:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_FlowMap_MapEntrySeparatorMissing_message,
+ offset= getMissingSepOffset((Collection.FlowCollection)node), offset + 1 );
+ break STATUS;
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ node.acceptInYamlChildren(this);
+ }
+
+ @Override
+ public void visit(final SeqEntry node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ switch (code & (TYPE12 | CTX12)) {
+ case TYPE12_SYNTAX_MISSING_INDICATOR | CTX12_SEQ_ENTRY:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_Seq_SeqEntryIndicatorMissing_message,
+ node.getStartOffset(), node.getStartOffset() + 1 );
+ break STATUS;
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ node.acceptInYamlChildren(this);
+ }
+
+ @Override
+ public void visit(final MapEntry node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ try {
+ final int offset;
+ TYPE: switch (code & (TYPE12 | CTX12)) {
+ case TYPE12_SYNTAX_MISSING_INDICATOR | CTX12_MAP_KEY:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_Map_MapKeyIndicatorMissing_messsage,
+ offset= node.getStartOffset(), offset + 1 );
+ break TYPE;
+ case TYPE12_SYNTAX_MISSING_INDICATOR | CTX12_MAP_VALUE:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_Map_MapValueIndicatorMissing_message,
+ node.getKey().getEndOffset() - 1, node.getKey().getEndOffset() + 1 );
+ break TYPE;
+
+ default:
+ handleCommonCodes(node, code);
+ break TYPE;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ node.acceptInYamlChildren(this);
+ }
+
+ @Override
+ public void visit(final Scalar node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ final StatusDetail detail;
+ switch (code & (TYPE123 | CTX12)) {
+ case TYPE12_SYNTAX_TOKEN_NOT_CLOSED | CTX12_SCALAR_FLOW:
+ addProblem(Problem.SEVERITY_ERROR, code, getMessageBuilder().bind(
+ ProblemMessages.Syntax_Scalar_QuotedScalar_NotClosed_message,
+ getMessageUtil().getStartText(node, 1),
+ String.valueOf(node.getOperator()) ),
+ node.getEndOffset() - 1, node.getEndOffset() + 1 );
+ break STATUS;
+
+ case TYPE123_SYNTAX_INDENTATION_INDICATOR_INVALID:
+ detail= StatusDetail.getStatusDetail(node);
+ if (detail != null) {
+ addProblem(Problem.SEVERITY_ERROR, code, getMessageBuilder().bind(
+ ProblemMessages.Syntax_Scalar_BlockScalar_IndentIndicatorInvalid_message,
+ detail.getText() ),
+ detail.getStartOffset(), detail.getEndOffset() );
+ break STATUS;
+ }
+ handleCommonCodes(node, code);
+ break STATUS;
+ case TYPE123_SYNTAX_CHOMPING_INDICATOR_MULTIPLE:
+ detail= StatusDetail.getStatusDetail(node);
+ if (detail != null) {
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_Scalar_BlockScalar_ChompingIndicatorMultiple_message,
+ detail.getStartOffset(), detail.getEndOffset() );
+ break STATUS;
+ }
+ handleCommonCodes(node, code);
+ break STATUS;
+
+ case TYPE12_SYNTAX_ESCAPE_INVALID | CTX12_SCALAR_FLOW:
+ detail= StatusDetail.getStatusDetail(node);
+ if (detail != null) {
+ addProblem(Problem.SEVERITY_ERROR, code, getMessageBuilder().bind(
+ ProblemMessages.Syntax_Scalar_QuotedScalar_EscapeSequenceInvalid_messsage,
+ detail.getText() ),
+ detail.getStartOffset(), detail.getEndOffset() );
+ break STATUS;
+ }
+ handleCommonCodes(node, code);
+ break STATUS;
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ @Override
+ public void visit(final Dummy node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ switch (code & (TYPE12 | CTX12)) {
+ case TYPE12_SYNTAX_MISSING_MARKER | CTX12_DIRECTIVES_END_MARKER:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_Doc_DirectiveEndMarkerMissing_message,
+ node.getStartOffset(), node.getEndOffset() );
+ break STATUS;
+
+ case TYPE12_SYNTAX_MISSING_NODE | CTX12_DOC_CONTENT:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_Doc_ContentMissing_message,
+ node.getStartOffset(), node.getEndOffset() );
+ break STATUS;
+ case TYPE12_SYNTAX_MISSING_NODE | CTX12_SEQ_ENTRY:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_FlowSeq_SeqEntryMissing_message,
+ node.getStartOffset(), node.getEndOffset() );
+ break STATUS;
+ case TYPE12_SYNTAX_MISSING_NODE | CTX12_MAP_ENTRY:
+ addProblem(Problem.SEVERITY_ERROR, code,
+ ProblemMessages.Syntax_FlowMap_MapEntryMissing_message,
+ node.getStartOffset(), node.getEndOffset() );
+ break STATUS;
+
+ default:
+ handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+ @Override
+ public void visit(final Alias node) throws InvocationTargetException {
+ final int code= (node.getStatusCode() & MASK);
+ if (requiredCheck(code)) {
+ STATUS: try {
+ { handleCommonCodes(node, code);
+ break STATUS;
+ }
+ }
+ catch (final BadLocationException e) {
+ throw new InvocationTargetException(e);
+ }
+ }
+ }
+
+
+
+ }
+
+ private static int getMissingSepOffset(final Collection.FlowCollection node) {
+ final int idx= node.getSepOffsets().indexOf(NA_OFFSET);
+ final YamlAstNode child= node.getChild(idx + 1);
+ return child.getStartOffset();
+ }
+
+}
diff --git a/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/internal/yaml/core/model/SyntaxProblemReporter.java b/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/internal/yaml/core/model/SyntaxProblemReporter.java
deleted file mode 100644
index ea45596..0000000
--- a/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/internal/yaml/core/model/SyntaxProblemReporter.java
+++ /dev/null
@@ -1,515 +0,0 @@
-/*=============================================================================#
- # Copyright (c) 2012, 2021 Stephan Wahlbrink and others.
- #
- # This program and the accompanying materials are made available under the
- # terms of the Eclipse Public License 2.0 which is available at
- # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
- # which is available at https://www.apache.org/licenses/LICENSE-2.0.
- #
- # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
- #
- # Contributors:
- # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
- #=============================================================================*/
-
-package org.eclipse.statet.internal.yaml.core.model;
-
-import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
-import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;
-
-import static org.eclipse.statet.ltk.ast.core.AstNode.NA_OFFSET;
-import static org.eclipse.statet.ltk.core.StatusCodes.CTX12;
-import static org.eclipse.statet.ltk.core.StatusCodes.SUBSEQUENT;
-import static org.eclipse.statet.ltk.core.StatusCodes.TYPE12;
-import static org.eclipse.statet.ltk.core.StatusCodes.TYPE123;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_DIRECTIVES_END_MARKER;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_DOC_CONTENT;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_MAP_ENTRY;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_MAP_FLOW;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_MAP_KEY;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_MAP_VALUE;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_SCALAR_FLOW;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_SEQ_ENTRY;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_SEQ_FLOW;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.CTX12_TAG_VERBATIM;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE123_SYNTAX_CHOMPING_INDICATOR_MULTIPLE;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE123_SYNTAX_INDENTATION_INDICATOR_INVALID;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE123_SYNTAX_LINE_BREAK_MISSING;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE123_SYNTAX_SPACE_BEFORE_COMMENT_MISSING;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_CHAR_INVALID;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_COLLECTION_NOT_CLOSED;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_ESCAPE_INVALID;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_MISSING_INDICATOR;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_MISSING_MARKER;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_MISSING_NODE;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_SEP_COMMA_MISSING;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_TOKEN_NOT_CLOSED;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_TOKEN_UNEXPECTED;
-import static org.eclipse.statet.yaml.core.source.YamlSourceConstants.TYPE12_SYNTAX_TOKEN_UNKNOWN;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.core.runtime.OperationCanceledException;
-import org.eclipse.jface.text.BadLocationException;
-
-import org.eclipse.statet.jcommons.lang.NonNullByDefault;
-
-import org.eclipse.statet.ecommons.runtime.core.util.MessageBuilder;
-
-import org.eclipse.statet.ltk.core.StatusCodes;
-import org.eclipse.statet.ltk.core.source.SourceContent;
-import org.eclipse.statet.ltk.core.source.StatusDetail;
-import org.eclipse.statet.ltk.core.util.SourceMessageUtil;
-import org.eclipse.statet.ltk.issues.core.IssueRequestor;
-import org.eclipse.statet.ltk.issues.core.Problem;
-import org.eclipse.statet.ltk.issues.core.impl.BasicProblem;
-import org.eclipse.statet.yaml.core.model.YamlModel;
-import org.eclipse.statet.yaml.core.source.ast.Alias;
-import org.eclipse.statet.yaml.core.source.ast.Anchor;
-import org.eclipse.statet.yaml.core.source.ast.Collection;
-import org.eclipse.statet.yaml.core.source.ast.Directive;
-import org.eclipse.statet.yaml.core.source.ast.Dummy;
-import org.eclipse.statet.yaml.core.source.ast.MapEntry;
-import org.eclipse.statet.yaml.core.source.ast.Marker;
-import org.eclipse.statet.yaml.core.source.ast.Scalar;
-import org.eclipse.statet.yaml.core.source.ast.SeqEntry;
-import org.eclipse.statet.yaml.core.source.ast.Tag;
-import org.eclipse.statet.yaml.core.source.ast.YamlAstNode;
-import org.eclipse.statet.yaml.core.source.ast.YamlAstVisitor;
-
-
-@NonNullByDefault
-public class SyntaxProblemReporter extends YamlAstVisitor {
-
-
- private static final int BUFFER_SIZE= 64;
-
- private static final int MASK= TYPE123 | CTX12 | SUBSEQUENT;
-
-
- private final boolean reportSubsequent= false;
-
- private SourceContent sourceContent= nonNullLateInit();
- private IssueRequestor requestor= nonNullLateInit();
-
- private final SourceMessageUtil messageUtil= new SourceMessageUtil();
- private final MessageBuilder messageBuilder= new MessageBuilder();
- private final List<Problem> problemBuffer= new ArrayList<>(BUFFER_SIZE);
-
-
- public SyntaxProblemReporter() {
- }
-
-
- public void run(final YamlAstNode node,
- final SourceContent content,
- final IssueRequestor requestor) {
- try {
- this.sourceContent= nonNullAssert(content);
- this.messageUtil.setSourceContent(content);
- this.requestor= requestor;
-
- node.acceptInYaml(this);
-
- if (!this.problemBuffer.isEmpty()) {
- this.requestor.acceptProblems(YamlModel.YAML_TYPE_ID, this.problemBuffer);
- }
- }
- catch (final OperationCanceledException | InvocationTargetException e) {}
- finally {
- clear();
- }
- }
-
- @SuppressWarnings("null")
- private void clear() {
- this.problemBuffer.clear();
- this.sourceContent= null;
- this.requestor= null;
- }
-
-
- private boolean requiredCheck(final int code) {
- return code != StatusCodes.TYPE1_OK &&
- (this.reportSubsequent || ((code & SUBSEQUENT) == 0));
- }
-
- protected final void addProblem(final int severity, final int code, final String message,
- int startOffset, int endOffset) {
- if (startOffset < this.sourceContent.getStartOffset()) {
- startOffset= this.sourceContent.getStartOffset();
- }
- if (endOffset <= startOffset) {
- endOffset= startOffset + 1;
- }
- if (endOffset > this.sourceContent.getEndOffset()) {
- endOffset= this.sourceContent.getEndOffset();
- }
-
- this.problemBuffer.add(new BasicProblem(YamlModel.YAML_TYPE_ID, severity, code, message,
- startOffset, endOffset ));
-
- if (this.problemBuffer.size() >= BUFFER_SIZE) {
- this.requestor.acceptProblems(YamlModel.YAML_TYPE_ID, this.problemBuffer);
- this.problemBuffer.clear();
- }
- }
-
- protected void handleCommonCodes(final YamlAstNode node, final int code)
- throws BadLocationException, InvocationTargetException {
- final StatusDetail detail;
- switch (code & TYPE12) {
- case TYPE12_SYNTAX_TOKEN_UNKNOWN:
- addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind(
- ProblemMessages.Syntax_Gen_TokenUnknown_message,
- this.messageUtil.getStartText(node, 0) ),
- node.getStartOffset(), node.getEndOffset() );
- return;
-
- case TYPE12_SYNTAX_TOKEN_UNEXPECTED:
- addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind(
- ProblemMessages.Syntax_Gen_TokenUnexpected_message,
- this.messageUtil.getStartText(node, 0) ),
- node.getStartOffset(), node.getEndOffset() );
- return;
-
- case TYPE12_SYNTAX_MISSING_NODE:
-// addProblem(Problem.SEVERITY_ERROR, code,
-// ProblemMessages.Syntax_Gen_NodeMissing_message,
-// node.getStartOffset(), node.getEndOffset() );
- return;
-
- case TYPE12_SYNTAX_CHAR_INVALID:
- detail= StatusDetail.getStatusDetail(node);
- if (detail != null) {
- switch (code & TYPE123) {
- case TYPE123_SYNTAX_SPACE_BEFORE_COMMENT_MISSING:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_Comment_SpaceBeforeMissing_message,
- detail.getStartOffset(), detail.getEndOffset() );
- return;
- case TYPE123_SYNTAX_LINE_BREAK_MISSING:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_Gen_LineBreakMissing_message,
- detail.getStartOffset(), detail.getEndOffset() );
- return;
- default:
- addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind(
- ProblemMessages.Syntax_Gen_TokenUnexpected_message,
- this.messageUtil.getStartText(node, 0) ),
- node.getStartOffset(), node.getEndOffset() );
- return;
- }
- }
- break;
-
- default:
- // TODO
- return;
- }
- }
-
-
-// @Override
-// public void visit(SourceComponent node) throws InvocationTargetException {
-// super.visit(node);
-// }
-
-// @Override
-// public void visit(final DocumentNode node) throws InvocationTargetException {
-// super.visit(node);
-// }
-
- @Override
- public void visit(final Marker node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- STATUS: try {
- { handleCommonCodes(node, code);
- break STATUS;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- }
-
- @Override
- public void visit(final Directive node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- STATUS: try {
- { handleCommonCodes(node, code);
- break STATUS;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- }
-
-// @Override
-// public void visit(final NodeWithProperties node) throws InvocationTargetException {
-// super.visit(node);
-// }
-
- @Override
- public void visit(final Tag node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- STATUS: try {
- switch (code & (TYPE12 | CTX12)) {
- case TYPE12_SYNTAX_TOKEN_NOT_CLOSED | CTX12_TAG_VERBATIM:
- addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind(
- ProblemMessages.Syntax_Tag_VerbatimTag_NotClosed_message,
- this.messageUtil.getStartText(node, 0) ),
- node.getEndOffset(), node.getEndOffset() + 1);
- break STATUS;
-
- default:
- handleCommonCodes(node, code);
- break STATUS;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- }
-
- @Override
- public void visit(final Anchor node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- STATUS: try {
- { handleCommonCodes(node, code);
- break STATUS;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- }
-
- @Override
- public void visit(final Collection node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- STATUS: try {
- final int offset;
- switch (code & (TYPE12 | CTX12)) {
- case TYPE12_SYNTAX_COLLECTION_NOT_CLOSED | CTX12_SEQ_FLOW:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_FlowSeq_NotClosed_message,
- offset= node.getStartOffset(), offset + 1 );
- break STATUS;
- case TYPE12_SYNTAX_COLLECTION_NOT_CLOSED | CTX12_MAP_FLOW:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_FlowMap_NotClosed_message,
- offset= node.getStartOffset(), offset + 1 );
- break STATUS;
-
- case TYPE12_SYNTAX_SEP_COMMA_MISSING | CTX12_SEQ_FLOW:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_FlowSeq_SeqEntrySeparatorMissing_message,
- offset= getMissingSepOffset((Collection.FlowCollection)node), offset + 1 );
- break STATUS;
- case TYPE12_SYNTAX_SEP_COMMA_MISSING | CTX12_MAP_FLOW:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_FlowMap_MapEntrySeparatorMissing_message,
- offset= getMissingSepOffset((Collection.FlowCollection)node), offset + 1 );
- break STATUS;
-
- default:
- handleCommonCodes(node, code);
- break STATUS;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- node.acceptInYamlChildren(this);
- }
-
- @Override
- public void visit(final SeqEntry node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- STATUS: try {
- switch (code & (TYPE12 | CTX12)) {
- case TYPE12_SYNTAX_MISSING_INDICATOR | CTX12_SEQ_ENTRY:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_Seq_SeqEntryIndicatorMissing_message,
- node.getStartOffset(), node.getStartOffset() + 1 );
- break STATUS;
-
- default:
- handleCommonCodes(node, code);
- break STATUS;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- node.acceptInYamlChildren(this);
- }
-
- @Override
- public void visit(final MapEntry node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- try {
- final int offset;
- TYPE: switch (code & (TYPE12 | CTX12)) {
- case TYPE12_SYNTAX_MISSING_INDICATOR | CTX12_MAP_KEY:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_Map_MapKeyIndicatorMissing_messsage,
- offset= node.getStartOffset(), offset + 1 );
- break TYPE;
- case TYPE12_SYNTAX_MISSING_INDICATOR | CTX12_MAP_VALUE:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_Map_MapValueIndicatorMissing_message,
- node.getKey().getEndOffset() - 1, node.getKey().getEndOffset() + 1 );
- break TYPE;
-
- default:
- handleCommonCodes(node, code);
- break TYPE;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- node.acceptInYamlChildren(this);
- }
-
- @Override
- public void visit(final Scalar node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- STATUS: try {
- final StatusDetail detail;
- switch (code & (TYPE123 | CTX12)) {
- case TYPE12_SYNTAX_TOKEN_NOT_CLOSED | CTX12_SCALAR_FLOW:
- addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind(
- ProblemMessages.Syntax_Scalar_QuotedScalar_NotClosed_message,
- this.messageUtil.getStartText(node, 1),
- String.valueOf(node.getOperator()) ),
- node.getEndOffset() - 1, node.getEndOffset() + 1 );
- break STATUS;
-
- case TYPE123_SYNTAX_INDENTATION_INDICATOR_INVALID:
- detail= StatusDetail.getStatusDetail(node);
- if (detail != null) {
- addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind(
- ProblemMessages.Syntax_Scalar_BlockScalar_IndentIndicatorInvalid_message,
- detail.getText() ),
- detail.getStartOffset(), detail.getEndOffset() );
- break STATUS;
- }
- handleCommonCodes(node, code);
- break STATUS;
- case TYPE123_SYNTAX_CHOMPING_INDICATOR_MULTIPLE:
- detail= StatusDetail.getStatusDetail(node);
- if (detail != null) {
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_Scalar_BlockScalar_ChompingIndicatorMultiple_message,
- detail.getStartOffset(), detail.getEndOffset() );
- break STATUS;
- }
- handleCommonCodes(node, code);
- break STATUS;
-
- case TYPE12_SYNTAX_ESCAPE_INVALID | CTX12_SCALAR_FLOW:
- detail= StatusDetail.getStatusDetail(node);
- if (detail != null) {
- addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind(
- ProblemMessages.Syntax_Scalar_QuotedScalar_EscapeSequenceInvalid_messsage,
- detail.getText() ),
- detail.getStartOffset(), detail.getEndOffset() );
- break STATUS;
- }
- handleCommonCodes(node, code);
- break STATUS;
-
- default:
- handleCommonCodes(node, code);
- break STATUS;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- }
-
- @Override
- public void visit(final Dummy node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- STATUS: try {
- switch (code & (TYPE12 | CTX12)) {
- case TYPE12_SYNTAX_MISSING_MARKER | CTX12_DIRECTIVES_END_MARKER:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_Doc_DirectiveEndMarkerMissing_message,
- node.getStartOffset(), node.getEndOffset() );
- break STATUS;
-
- case TYPE12_SYNTAX_MISSING_NODE | CTX12_DOC_CONTENT:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_Doc_ContentMissing_message,
- node.getStartOffset(), node.getEndOffset() );
- break STATUS;
- case TYPE12_SYNTAX_MISSING_NODE | CTX12_SEQ_ENTRY:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_FlowSeq_SeqEntryMissing_message,
- node.getStartOffset(), node.getEndOffset() );
- break STATUS;
- case TYPE12_SYNTAX_MISSING_NODE | CTX12_MAP_ENTRY:
- addProblem(Problem.SEVERITY_ERROR, code,
- ProblemMessages.Syntax_FlowMap_MapEntryMissing_message,
- node.getStartOffset(), node.getEndOffset() );
- break STATUS;
-
- default:
- handleCommonCodes(node, code);
- break STATUS;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- }
-
- @Override
- public void visit(final Alias node) throws InvocationTargetException {
- final int code= (node.getStatusCode() & MASK);
- if (requiredCheck(code)) {
- STATUS: try {
- { handleCommonCodes(node, code);
- break STATUS;
- }
- }
- catch (final BadLocationException e) {
- throw new InvocationTargetException(e);
- }
- }
- }
-
-
- private static int getMissingSepOffset(final Collection.FlowCollection node) {
- final int idx= node.getSepOffsets().indexOf(NA_OFFSET);
- final YamlAstNode child= node.getChild(idx + 1);
- return child.getStartOffset();
- }
-
-}
diff --git a/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/yaml/core/model/build/YamlIssueReporter.java b/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/yaml/core/model/build/YamlIssueReporter.java
index e70bd01..658176d 100644
--- a/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/yaml/core/model/build/YamlIssueReporter.java
+++ b/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/yaml/core/model/build/YamlIssueReporter.java
@@ -19,7 +19,7 @@
import org.eclipse.statet.ecommons.preferences.core.EPreferences;
-import org.eclipse.statet.internal.yaml.core.model.SyntaxProblemReporter;
+import org.eclipse.statet.internal.yaml.core.model.AstProblemReporter;
import org.eclipse.statet.ltk.ast.core.AstNode;
import org.eclipse.statet.ltk.core.source.SourceContent;
import org.eclipse.statet.ltk.issues.core.IssueRequestor;
@@ -36,7 +36,7 @@
public class YamlIssueReporter {
- private final SyntaxProblemReporter syntaxProblemReporter= new SyntaxProblemReporter();
+ private final AstProblemReporter syntaxProblemReporter= new AstProblemReporter();
private final YamlTaskTagReporter taskReporter= new YamlTaskTagReporter();
diff --git a/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/yaml/core/source/ast/YamlParser.java b/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/yaml/core/source/ast/YamlParser.java
index 4f21dad..f864d33 100644
--- a/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/yaml/core/source/ast/YamlParser.java
+++ b/yaml/org.eclipse.statet.yaml.core/src/org/eclipse/statet/yaml/core/source/ast/YamlParser.java
@@ -89,6 +89,7 @@
}
};
+ private String parseInput;
private int parseStartOffset;
private int parseEndOffset;
private @Nullable AstNode parseParent;
@@ -122,12 +123,26 @@
}
- private void init0(final int startOffset, final int endOffset, final @Nullable AstNode parent) {
- this.parseStartOffset= startOffset;
- this.parseEndOffset= endOffset;
+ private void init0(final String input, final int inputOffset, final @Nullable AstNode parent) {
+ this.parseInput= nonNullAssert(input);
+ this.parseStartOffset= inputOffset;
+ this.parseEndOffset= inputOffset + input.length();
this.parseParent= parent;
}
+ @SuppressWarnings("null")
+ private void clear0() {
+ this.parseInput= null;
+ this.parseParent= null;
+ }
+
+ private void logParseError(final Exception e) {
+ CommonsRuntime.log(new ErrorStatus(YamlCore.BUNDLE_ID,
+ "An error occured while parsing R source code. Input:\n"
+ + this.parseInput.toString(),
+ e ));
+ }
+
private void init() {
this.depth= -1;
@@ -137,16 +152,16 @@
this.docState= DOC_NONE;
}
- public SourceComponent parseSourceUnit(final String text, final int offset,
+ public SourceComponent parseSourceUnit(final String input, final int inputOffset,
final @Nullable AstNode parent) {
- init0(offset, offset + text.length(), parent);
+ init0(input, inputOffset, parent);
try {
init();
- this.lexer.reset(text, offset);
+ this.lexer.reset(input, inputOffset);
- final SourceComponent node= new SourceComponent(parent,
+ final SourceComponent sourceNode= new SourceComponent(parent,
this.parseStartOffset, this.parseEndOffset );
- enterNode(node);
+ enterNode(sourceNode);
processTokens();
@@ -155,15 +170,17 @@
}
if (this.commentsLevel != 0) {
- node.comments= ImCollections.toList(this.comments);
+ sourceNode.comments= ImCollections.toList(this.comments);
}
- return node;
+ return sourceNode;
}
catch (final Exception e) {
- return onParseError(e);
+ logParseError(e);
+ return createErrorSourceComponent();
}
finally {
+ clear0();
while (this.depth >= 0) {
if (this.depth < this.containerStack.size()) {
final var builder= this.containerStack.get(this.depth);
@@ -178,10 +195,7 @@
return parseSourceUnit(text, 0, null);
}
- private SourceComponent onParseError(final Exception e) {
- CommonsRuntime.log(new ErrorStatus(YamlCore.BUNDLE_ID,
- "An error occured while parsing YAML source code.",
- e ));
+ private SourceComponent createErrorSourceComponent() {
final int startOffset= this.parseStartOffset;
int endOffset= this.parseEndOffset;
if (endOffset < startOffset) {