| /*=============================================================================# |
| # Copyright (c) 2008, 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.r.core.sourcemodel; |
| |
| import static org.eclipse.statet.ltk.ast.core.AstNode.NA_OFFSET; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_NUMBER_EXP_DIGIT_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_NUMBER_HEX_DIGIT_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_NUMBER_HEX_FLOAT_EXP_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_NUMBER_INT_WITH_DEC_POINT; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_NUMBER_NON_INT_WITH_L; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_TEXT_ESCAPE_SEQ_HEX_DIGIT_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_TEXT_ESCAPE_SEQ_NOT_CLOSED; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_TEXT_ESCAPE_SEQ_UNEXPECTED; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_TEXT_ESCAPE_SEQ_UNKOWN; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS123_SYNTAX_TEXT_NULLCHAR; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS12_SYNTAX_TEXT_INVALID; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS12_SYNTAX_TOKEN_NOT_CLOSED; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS12_SYNTAX_TOKEN_OPENING_INCOMPLETE; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS12_SYNTAX_TOKEN_UNEXPECTED; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS12_SYNTAX_TOKEN_UNKNOWN; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_CC_NOT_CLOSED; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_CONDITION_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_CONDITION_NOT_CLOSED; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_ELEMENTNAME_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_EXPR_AFTER_OP_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_EXPR_AS_ARGVALUE_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_EXPR_AS_BODY_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_EXPR_AS_CONDITION_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_EXPR_AS_FORSEQ_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_EXPR_BEFORE_OP_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_EXPR_IN_GROUP_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_FCALL_NOT_CLOSED; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_FDEF_ARGS_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_FDEF_ARGS_NOT_CLOSED; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_IF_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_IN_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_OPERATOR_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS2_SYNTAX_SYMBOL_MISSING; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUSFLAG_SUBSEQUENT; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS_MASK_12; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS_MASK_123; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS_MASK_3; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS_OK; |
| import static org.eclipse.statet.r.core.rsource.RSourceConstants.STATUS_RUNTIME_ERROR; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.ArrayList; |
| import java.util.List; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.jface.text.BadLocationException; |
| |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.text.core.TextLineInformation; |
| |
| import org.eclipse.statet.ecommons.runtime.core.util.MessageBuilder; |
| |
| import org.eclipse.statet.internal.r.core.RCorePlugin; |
| import org.eclipse.statet.ltk.ast.core.StatusDetail; |
| import org.eclipse.statet.ltk.core.SourceContent; |
| import org.eclipse.statet.ltk.issues.core.BasicProblem; |
| import org.eclipse.statet.ltk.issues.core.Problem; |
| import org.eclipse.statet.ltk.issues.core.ProblemRequestor; |
| import org.eclipse.statet.ltk.model.core.element.SourceUnit; |
| import org.eclipse.statet.r.core.RCore; |
| import org.eclipse.statet.r.core.data.RValueFormatter; |
| import org.eclipse.statet.r.core.model.RModel; |
| import org.eclipse.statet.r.core.model.RSourceUnit; |
| import org.eclipse.statet.r.core.rlang.RTerminal; |
| import org.eclipse.statet.r.core.rsource.RSourceConstants; |
| import org.eclipse.statet.r.core.rsource.ast.Arithmetic; |
| import org.eclipse.statet.r.core.rsource.ast.Assignment; |
| import org.eclipse.statet.r.core.rsource.ast.Block; |
| import org.eclipse.statet.r.core.rsource.ast.CForLoop; |
| import org.eclipse.statet.r.core.rsource.ast.CIfElse; |
| import org.eclipse.statet.r.core.rsource.ast.CLoopCommand; |
| import org.eclipse.statet.r.core.rsource.ast.CRepeatLoop; |
| import org.eclipse.statet.r.core.rsource.ast.CWhileLoop; |
| import org.eclipse.statet.r.core.rsource.ast.Dummy; |
| import org.eclipse.statet.r.core.rsource.ast.FCall; |
| import org.eclipse.statet.r.core.rsource.ast.FDef; |
| import org.eclipse.statet.r.core.rsource.ast.Group; |
| import org.eclipse.statet.r.core.rsource.ast.Help; |
| import org.eclipse.statet.r.core.rsource.ast.Logical; |
| import org.eclipse.statet.r.core.rsource.ast.Model; |
| import org.eclipse.statet.r.core.rsource.ast.NSGet; |
| import org.eclipse.statet.r.core.rsource.ast.NodeType; |
| import org.eclipse.statet.r.core.rsource.ast.NullConst; |
| import org.eclipse.statet.r.core.rsource.ast.NumberConst; |
| import org.eclipse.statet.r.core.rsource.ast.Power; |
| import org.eclipse.statet.r.core.rsource.ast.RAstNode; |
| import org.eclipse.statet.r.core.rsource.ast.RAstVisitor; |
| import org.eclipse.statet.r.core.rsource.ast.Relational; |
| import org.eclipse.statet.r.core.rsource.ast.Seq; |
| import org.eclipse.statet.r.core.rsource.ast.Sign; |
| import org.eclipse.statet.r.core.rsource.ast.SourceComponent; |
| import org.eclipse.statet.r.core.rsource.ast.Special; |
| import org.eclipse.statet.r.core.rsource.ast.StringConst; |
| import org.eclipse.statet.r.core.rsource.ast.SubIndexed; |
| import org.eclipse.statet.r.core.rsource.ast.SubNamed; |
| import org.eclipse.statet.r.core.rsource.ast.Symbol; |
| |
| |
| /** |
| * Reports syntax problems in AST to {@link ProblemRequestor} of source units |
| */ |
| @NonNullByDefault |
| public class SyntaxProblemReporter extends RAstVisitor { |
| |
| |
| private static final int BUFFER_SIZE= 100; |
| |
| private static final int FULL_TEXT_LIMIT= 100; |
| private static final int START_TEXT_LIMIT= 25; |
| |
| private static final int MASK= 0x00ffffff; |
| |
| |
| private final boolean reportSubsequent= false; |
| |
| private SourceUnit sourceUnit; |
| private SourceContent sourceContent; |
| private String currentText; |
| private ProblemRequestor currentRequestor; |
| |
| private final StringBuilder tmpBuilder= new StringBuilder(); |
| private final MessageBuilder messageBuilder= new MessageBuilder(); |
| private final List<Problem> problemBuffer= new ArrayList<>(BUFFER_SIZE); |
| private final RValueFormatter valueFormatter= new RValueFormatter(); |
| // private int maxOffset; |
| |
| |
| public SyntaxProblemReporter() { |
| } |
| |
| |
| public void run(final RSourceUnit su, final SourceContent content, |
| final RAstNode node, final ProblemRequestor problemRequestor) { |
| try { |
| this.sourceUnit= su; |
| this.sourceContent= content; |
| this.currentText= content.getText(); |
| // this.currentDoc= su.getDocument(null); |
| // this.maxOffset= this.currentDoc.getLength(); |
| this.currentRequestor= problemRequestor; |
| node.acceptInR(this); |
| if (this.problemBuffer.size() > 0) { |
| this.currentRequestor.acceptProblems(RModel.R_TYPE_ID, this.problemBuffer); |
| } |
| } |
| catch (final OperationCanceledException e) {} |
| catch (final InvocationTargetException e) {} |
| finally { |
| this.problemBuffer.clear(); |
| this.sourceUnit= null; |
| // this.currentDoc= null; |
| this.currentRequestor= null; |
| } |
| } |
| |
| |
| private boolean requiredCheck(final int code) { |
| return code != STATUS_OK && |
| (this.reportSubsequent || ((code & STATUSFLAG_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; |
| } |
| else if (endOffset > this.sourceContent.getEndOffset()) { |
| endOffset= this.sourceContent.getEndOffset(); |
| } |
| |
| this.problemBuffer.add(new BasicProblem(RModel.R_TYPE_ID, severity, code, message, |
| startOffset, endOffset )); |
| |
| if (this.problemBuffer.size() >= BUFFER_SIZE) { |
| this.currentRequestor.acceptProblems(RModel.R_TYPE_ID, this.problemBuffer); |
| this.problemBuffer.clear(); |
| } |
| } |
| |
| |
| protected final StringBuilder getStringBuilder() { |
| this.tmpBuilder.setLength(0); |
| return this.tmpBuilder; |
| } |
| |
| protected String getStartText(final RAstNode node, final int offset) |
| throws BadLocationException { |
| final String text= node.getText(); |
| if (text != null) { |
| if (text.length() > START_TEXT_LIMIT) { |
| final StringBuilder sb= getStringBuilder(); |
| sb.append(text, 0, START_TEXT_LIMIT); |
| sb.append('…'); |
| return sb.toString(); |
| } |
| else { |
| return text; |
| } |
| } |
| else { |
| if (node.getLength() - offset > START_TEXT_LIMIT) { |
| final StringBuilder sb= getStringBuilder(); |
| sb.append(this.sourceContent.getText(), |
| node.getStartOffset() + offset, node.getStartOffset() + offset + START_TEXT_LIMIT); |
| sb.append('…'); |
| return sb.toString(); |
| } |
| else { |
| return this.sourceContent.getText().substring( |
| node.getStartOffset() + offset, node.getEndOffset() + offset ); |
| } |
| } |
| } |
| |
| protected String getFullText(final RAstNode node) throws BadLocationException { |
| final String text= node.getText(); |
| if (text != null) { |
| if (text.length() > FULL_TEXT_LIMIT) { |
| return text.substring(0, FULL_TEXT_LIMIT) + '…'; |
| } |
| else { |
| return text; |
| } |
| } |
| else { |
| if (node.getLength() > FULL_TEXT_LIMIT) { |
| return this.currentText.substring(node.getStartOffset(), |
| node.getStartOffset() + FULL_TEXT_LIMIT ) + '…'; |
| } |
| else { |
| return this.currentText.substring(node.getStartOffset(), node.getEndOffset()); |
| } |
| } |
| } |
| |
| protected String getDetailText(final RAstNode node, final int offset, final StatusDetail detail) |
| throws BadLocationException { |
| final String text= node.getText(); |
| if (text != null) { |
| final int begin= detail.getStartOffset() - node.getStartOffset() - offset; |
| return text.substring(begin, begin + detail.getLength()); |
| } |
| else { |
| return this.sourceContent.getText().substring( |
| detail.getStartOffset(), detail.getEndOffset() ); |
| } |
| } |
| |
| |
| private void handleCommonCodes(final RAstNode node, final int code) |
| throws BadLocationException, InvocationTargetException { |
| STATUS: switch (code & STATUS_MASK_12) { |
| case STATUS_RUNTIME_ERROR: |
| throw new InvocationTargetException(new CoreException( |
| new Status(IStatus.ERROR, RCore.BUNDLE_ID, -1, |
| "Error occurred when parsing source code. Please submit a bug report with a code snippet.", //$NON-NLS-1$ |
| null))); |
| |
| case STATUS12_SYNTAX_TOKEN_UNEXPECTED: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| this.messageBuilder.bind(ProblemMessages.Syntax_TokenUnexpected_message, getFullText(node)), |
| node.getStartOffset(), node.getEndOffset() ); |
| break STATUS; |
| |
| default: |
| handleUnknownCodes(node); |
| break STATUS; |
| } |
| } |
| |
| protected void handleUnknownCodes(final RAstNode node) { |
| final int code= (node.getStatusCode() & MASK); |
| final StringBuilder sb= new StringBuilder(); |
| sb.append("Unhandled/Unknown code of R AST node:"); //$NON-NLS-1$ |
| sb.append('\n'); |
| sb.append(" Code: 0x").append(Integer.toHexString(code)); //$NON-NLS-1$ |
| sb.append('\n'); |
| sb.append(" Node: ").append(node); |
| sb.append(" (").append(node.getStartOffset()).append(", ").append(node.getLength()).append(')'); //$NON-NLS-1$ //$NON-NLS-2$ |
| sb.append('\n'); |
| if (this.sourceContent != null) { |
| final TextLineInformation lines= this.sourceContent.getLines(); |
| final int line= lines.getLineOfOffset(node.getStartOffset()); |
| sb.append(" Line ").append((line + 1)).append(" (offset )").append(lines.getStartOffset(line)); //$NON-NLS-1$ //$NON-NLS-2$ |
| sb.append('\n'); |
| |
| final int firstLine= Math.max(0, line - 2); |
| final int lastLine= Math.min(lines.getNumberOfLines() - 1, lines.getLineOfOffset(line) + 2); |
| sb.append(" Source (line ").append((firstLine + 1)).append('-').append((lastLine)).append("): \n"); //$NON-NLS-1$ //$NON-NLS-2$ |
| sb.append(this.currentText.substring(lines.getStartOffset(firstLine), |
| lines.getStartOffset(lastLine) )); |
| } |
| RCorePlugin.log(new Status(IStatus.WARNING, RCore.BUNDLE_ID, sb.toString())); |
| } |
| |
| |
| @Override |
| public void visit(final SourceComponent node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & RSourceConstants.STATUS_MASK_2)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Block node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS2_SYNTAX_CC_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_BlockNotClosed_message, |
| node.getEndOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Group node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS2_SYNTAX_CC_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_GroupNotClosed_message, |
| node.getEndOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final CIfElse node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS2_SYNTAX_IF_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_IfOfElseMissing_message, |
| node.getStartOffset(), node.getStartOffset() + 1 ); |
| break STATUS; |
| case STATUS2_SYNTAX_CONDITION_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ConditionMissing_If_message, |
| node.getStartOffset() + 1, node.getStartOffset() + 3 ); |
| break STATUS; |
| case STATUS2_SYNTAX_CONDITION_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ConditionNotClosed_If_message, |
| node.getCondChild().getEndOffset() - 1, node.getCondChild().getEndOffset() + 1 ); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final CForLoop node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS2_SYNTAX_CONDITION_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ConditionMissing_For_message, |
| node.getStartOffset() + 2, node.getStartOffset() + 4 ); |
| break STATUS; |
| case STATUS2_SYNTAX_CONDITION_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ConditionNotClosed_For_message, |
| node.getCondChild().getEndOffset() - 1, node.getCondChild().getEndOffset() + 1 ); |
| break STATUS; |
| case STATUS2_SYNTAX_IN_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_InOfForConditionMissing_message, |
| node.getVarChild().getEndOffset() - 1, node.getVarChild().getEndOffset() + 1 ); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| |
| @Override |
| public void visit(final CRepeatLoop node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final CWhileLoop node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS2_SYNTAX_CONDITION_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ConditionMissing_While_message, |
| node.getStartOffset() + 4, node.getStartOffset() + 6 ); |
| break; |
| case STATUS2_SYNTAX_CONDITION_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ConditionNotClosed_While_message, |
| node.getCondChild().getEndOffset() - 1, node.getCondChild().getEndOffset() + 1 ); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final CLoopCommand node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final FCall node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS2_SYNTAX_FCALL_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_FcallArgsNotClosed_message, |
| node.getArgsChild().getEndOffset() - 1, node.getArgsChild().getEndOffset() + 1 ); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final FCall.Args node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final FCall.Arg node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final FDef node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS2_SYNTAX_FDEF_ARGS_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_FdefArgsMissing_message, |
| node.getStartOffset() + 7, node.getStartOffset() + 9 ); |
| break STATUS; |
| case STATUS2_SYNTAX_FDEF_ARGS_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_FdefArgsNotClosed_message, |
| node.getArgsChild().getEndOffset() - 1, node.getArgsChild().getEndOffset() + 1 ); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final FDef.Args node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final FDef.Arg node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Assignment node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Model node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Relational node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| if ((code & STATUS_MASK_123) == (RSourceConstants.STATUS123_SYNTAX_SEQREL_UNEXPECTED)) { |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_TokenUnexpected_SeqRel_message, |
| node.getOperator(0).text ), |
| node.getStartOffset(), node.getEndOffset() ); |
| } |
| else { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Logical node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Arithmetic node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Power node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Seq node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Special node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS12_SYNTAX_TOKEN_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_SpecialNotClosed_message, |
| this.valueFormatter.escapeString(getStartText(node, 1)) ), |
| node.getStartOffset(), node.getEndOffset() ); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Sign node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final SubIndexed node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case RSourceConstants.STATUS2_SYNTAX_SUBINDEXED_NOT_CLOSED: |
| if (node.getNodeType() == NodeType.SUB_INDEXED_S) { |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_SubindexedNotClosed_S_message, |
| getStartText(node, 0) ), |
| node.getEndOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| } |
| else if (node.getSublistCloseOffset() != NA_OFFSET) { |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_SubindexedNotClosed_Done_message, |
| getStartText(node, 0) ), |
| node.getEndOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| } |
| else { |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_SubindexedNotClosed_Dboth_message, |
| getStartText(node, 0) ), |
| node.getEndOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| } |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final SubIndexed.Args node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final SubIndexed.Arg node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final SubNamed node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final NSGet node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| private void handleTextInvalid(final RAstNode node, final int code) throws BadLocationException { |
| final StatusDetail detail= StatusDetail.getStatusDetail(node); |
| switch ((code & STATUS_MASK_123)) { |
| case STATUS123_SYNTAX_TEXT_NULLCHAR: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_Text_NullCharNotAllowed_message, |
| detail.getStartOffset(), detail.getEndOffset() ); |
| return; |
| case STATUS123_SYNTAX_TEXT_ESCAPE_SEQ_HEX_DIGIT_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_Text_EscapeSeqHexDigitMissing_message, |
| detail.getText() ), |
| detail.getStartOffset(), detail.getEndOffset() ); |
| return; |
| case STATUS123_SYNTAX_TEXT_ESCAPE_SEQ_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_Text_EscapeSeqNotClosed_message, |
| detail.getText() ), |
| detail.getStartOffset(), detail.getEndOffset() ); |
| return; |
| case STATUS123_SYNTAX_TEXT_ESCAPE_SEQ_UNEXPECTED: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_Text_QuotedSymbol_EscapeSeqUnexpected_message, |
| detail.getText() ), |
| detail.getStartOffset(), detail.getEndOffset() ); |
| return; |
| case STATUS123_SYNTAX_TEXT_ESCAPE_SEQ_UNKOWN: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_Text_EscapeSeqUnknown_message, |
| detail.getText() ), |
| detail.getStartOffset(), detail.getEndOffset() ); |
| return; |
| default: |
| handleUnknownCodes(node); |
| return; |
| } |
| } |
| |
| @Override |
| @SuppressWarnings("null") |
| public void visit(final StringConst node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS12_SYNTAX_TOKEN_OPENING_INCOMPLETE: |
| // (node.getOperator(0) == RTerminal.STRING_R) |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_StringROpeningIncomplete_message, |
| node.getStartOffset(), node.getEndOffset() ); |
| break STATUS; |
| case STATUS12_SYNTAX_TOKEN_NOT_CLOSED: |
| addProblem(Problem.SEVERITY_ERROR, code, (node.getOperator(0) == RTerminal.STRING_R) ? |
| this.messageBuilder.bind( |
| ProblemMessages.Syntax_StringRNotClosed_message, |
| this.valueFormatter.escapeString(getStartText(node, 1)), |
| StatusDetail.getStatusDetail(node).getText() ) : |
| this.messageBuilder.bind( |
| ProblemMessages.Syntax_StringNotClosed_message, |
| this.valueFormatter.escapeString(getStartText(node, 1)), |
| node.getOperator(0).text ), |
| node.getStartOffset(), node.getEndOffset() ); |
| break STATUS; |
| case STATUS12_SYNTAX_TEXT_INVALID: |
| handleTextInvalid(node, code); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| } |
| |
| @Override |
| public void visit(final NumberConst node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_123)) { |
| case STATUS123_SYNTAX_NUMBER_HEX_DIGIT_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_Number_HexDigitMissing_message, |
| getFullText(node) ), |
| node.getStartOffset(), node.getEndOffset() ); |
| break STATUS; |
| case STATUS123_SYNTAX_NUMBER_HEX_FLOAT_EXP_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_Number_HexFloatExpMissing_message, |
| getFullText(node) ), |
| node.getStartOffset(), node.getEndOffset() ); |
| break STATUS; |
| case STATUS123_SYNTAX_NUMBER_EXP_DIGIT_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_Number_ExpDigitMissing_message, |
| getFullText(node) ), |
| node.getStartOffset(), node.getEndOffset() ); |
| break STATUS; |
| case STATUS123_SYNTAX_NUMBER_NON_INT_WITH_L: |
| addProblem(Problem.SEVERITY_WARNING, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_Number_NonIntWithLLiteral_message, |
| getFullText(node) ), |
| node.getStartOffset(), node.getEndOffset() ); |
| break STATUS; |
| case STATUS123_SYNTAX_NUMBER_INT_WITH_DEC_POINT: |
| addProblem(Problem.SEVERITY_WARNING, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_Number_IntWithDecPoint_message, |
| getFullText(node) ), |
| 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 NullConst node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break STATUS; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Symbol node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS2_SYNTAX_SYMBOL_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_SymbolMissing_message, |
| node.getStartOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| case STATUS2_SYNTAX_ELEMENTNAME_MISSING: |
| // this can be a status for string too, but never used there |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ElementnameMissing_message, |
| node.getStartOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| case STATUS12_SYNTAX_TOKEN_NOT_CLOSED: |
| // assert(node.getOperator(0) == RTerminal.SYMBOL_G) |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_QuotedSymbolNotClosed_message, |
| this.valueFormatter.escapeString(getStartText(node, 1)) ), |
| node.getEndOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| case STATUS12_SYNTAX_TEXT_INVALID: |
| // assert(node.getOperator(0) == RTerminal.SYMBOL_G) |
| handleTextInvalid(node, code); |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| } |
| |
| @Override |
| public void visit(final Help node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| // STATUS: switch ((code & STATUS_MASK_12)) { |
| // default: |
| handleCommonCodes(node, code); |
| // break; |
| // } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| @Override |
| public void visit(final Dummy node) throws InvocationTargetException { |
| final int code= (node.getStatusCode() & MASK); |
| if (requiredCheck(code)) { |
| try { |
| STATUS: switch ((code & STATUS_MASK_12)) { |
| case STATUS12_SYNTAX_TOKEN_UNKNOWN: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_TokenUnknown_message, |
| getFullText(node) ), |
| node.getStartOffset(), node.getEndOffset() ); |
| break STATUS; |
| case STATUS2_SYNTAX_EXPR_BEFORE_OP_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ExprBeforeOpMissing_message, |
| node.getStartOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| case STATUS2_SYNTAX_EXPR_AFTER_OP_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, this.messageBuilder.bind( |
| ProblemMessages.Syntax_ExprAfterOpMissing_message, |
| getFullText(node) ), |
| node.getStartOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| // case STATUS2_SYNTAX_EXPR_AS_REF_MISSING: |
| // addProblem(Problem.ERROR, code, |
| // ProblemMessages., |
| // node.getStartOffset() - 1, node.getEndOffset() + 1); |
| // break; |
| case STATUS2_SYNTAX_EXPR_AS_CONDITION_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ExprAsConditionMissing_message, |
| node.getStartOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| case STATUS2_SYNTAX_EXPR_AS_FORSEQ_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ExprAsForSequenceMissing_message, |
| node.getStartOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| case STATUS2_SYNTAX_EXPR_AS_BODY_MISSING: |
| { |
| final String message; |
| STATUS3: switch (code & RSourceConstants.STATUS_MASK_3) { |
| case RSourceConstants.STATUS3_IF: |
| message= ProblemMessages.Syntax_ExprAsThenBodyMissing_message; |
| break STATUS3; |
| case RSourceConstants.STATUS3_ELSE: |
| message= ProblemMessages.Syntax_ExprAsElseBodyMissing_message; |
| break STATUS3; |
| case RSourceConstants.STATUS3_FOR: |
| case RSourceConstants.STATUS3_WHILE: |
| case RSourceConstants.STATUS3_REPEAT: |
| message= ProblemMessages.Syntax_ExprAsLoopBodyMissing_message; |
| break STATUS3; |
| case RSourceConstants.STATUS3_FDEF: |
| message= ProblemMessages.Syntax_ExprAsFdefBodyMissing_message; |
| break STATUS3; |
| default: |
| handleUnknownCodes(node); |
| break STATUS; |
| } |
| if (node.getLength() > 0) { |
| addProblem(Problem.SEVERITY_ERROR, code, message, |
| node.getStartOffset(), node.getEndOffset() ); |
| } |
| else { |
| addProblem(Problem.SEVERITY_ERROR, code, message, |
| node.getStartOffset() - 1, node.getEndOffset() + 1 ); |
| } |
| break STATUS; |
| } |
| case STATUS2_SYNTAX_EXPR_IN_GROUP_MISSING: |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ExprInGroupMissing_message, |
| node.getStartOffset() - 1, node.getEndOffset() + 1 ); |
| break STATUS; |
| case STATUS2_SYNTAX_EXPR_AS_ARGVALUE_MISSING: |
| if ((code & STATUS_MASK_3) == RSourceConstants.STATUS3_FDEF) { |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_ExprAsFdefArgDefaultMissing_message, |
| node.getStartOffset() - 1, node.getEndOffset() ); |
| } |
| else { |
| handleUnknownCodes(node); |
| } |
| break STATUS; |
| case STATUS2_SYNTAX_OPERATOR_MISSING: |
| if (node.getChildCount() == 2) { |
| addProblem(Problem.SEVERITY_ERROR, code, |
| ProblemMessages.Syntax_OperatorMissing_message, |
| node.getChild(0).getEndOffset() - 1, node.getChild(1).getStartOffset() + 1 ); |
| } |
| else { |
| handleUnknownCodes(node); |
| } |
| break STATUS; |
| default: |
| handleCommonCodes(node, code); |
| break STATUS; |
| } |
| } |
| catch (final BadLocationException e) { |
| throw new InvocationTargetException(e); |
| } |
| } |
| node.acceptInRChildren(this); |
| } |
| |
| } |