Source located error in linter for include statement

This commit is contained in:
aNNiMON 2023-10-15 22:57:27 +03:00 committed by Victor Melnik
parent 35971e874b
commit 6a35f6e66a
4 changed files with 34 additions and 4 deletions

View File

@ -147,7 +147,7 @@ public final class Parser {
return useStatement(); return useStatement();
} }
if (match(TokenType.INCLUDE)) { if (match(TokenType.INCLUDE)) {
return new IncludeStatement(expression()); return includeStatement();
} }
if (match(TokenType.FOR)) { if (match(TokenType.FOR)) {
return forStatement(); return forStatement();
@ -167,6 +167,13 @@ public final class Parser {
return assignmentStatement(); return assignmentStatement();
} }
private IncludeStatement includeStatement() {
final var startTokenIndex = index - 1;
final var include = new IncludeStatement(expression());
include.setRange(getRange(startTokenIndex, index));
return include;
}
private UseStatement useStatement() { private UseStatement useStatement() {
final var modules = new HashSet<String>(); final var modules = new HashSet<String>();
do { do {

View File

@ -6,6 +6,8 @@ import com.annimon.ownlang.lib.NumberValue;
import com.annimon.ownlang.lib.Value; import com.annimon.ownlang.lib.Value;
import com.annimon.ownlang.parser.error.ParseErrorsFormatterStage; import com.annimon.ownlang.parser.error.ParseErrorsFormatterStage;
import com.annimon.ownlang.stages.*; import com.annimon.ownlang.stages.*;
import com.annimon.ownlang.util.Range;
import com.annimon.ownlang.util.SourceLocation;
import com.annimon.ownlang.util.input.InputSourceFile; import com.annimon.ownlang.util.input.InputSourceFile;
import com.annimon.ownlang.util.input.SourceLoaderStage; import com.annimon.ownlang.util.input.SourceLoaderStage;
@ -13,14 +15,24 @@ import com.annimon.ownlang.util.input.SourceLoaderStage;
* *
* @author aNNiMON * @author aNNiMON
*/ */
public final class IncludeStatement extends InterruptableNode implements Statement { public final class IncludeStatement extends InterruptableNode implements Statement, SourceLocation {
public final Node expression; public final Node expression;
private Range range;
public IncludeStatement(Node expression) { public IncludeStatement(Node expression) {
this.expression = expression; this.expression = expression;
} }
public void setRange(Range range) {
this.range = range;
}
@Override
public Range getRange() {
return range;
}
@Override @Override
public Value eval() { public Value eval() {
super.interruptionCheck(); super.interruptionCheck();
@ -31,6 +43,7 @@ public final class IncludeStatement extends InterruptableNode implements Stateme
new SourceLoaderStage() new SourceLoaderStage()
.then(new LexerStage()) .then(new LexerStage())
.then(new ParserStage()) .then(new ParserStage())
// TODO LinterStage based on main context
.then(new FunctionAddingStage()) .then(new FunctionAddingStage())
.then(new ExecutionStage()) .then(new ExecutionStage())
.perform(stagesData, new InputSourceFile(path)); .perform(stagesData, new InputSourceFile(path));

View File

@ -23,11 +23,13 @@ final class IncludeSourceValidator extends LintVisitor {
final String path = expr.eval().asString(); final String path = expr.eval().asString();
if (!detector.isReadable(path)) { if (!detector.isReadable(path)) {
results.add(LinterResult.error( results.add(LinterResult.error(
"Include statement path \"%s\" is not readable".formatted(path))); "Include statement path \"%s\" is not readable".formatted(path),
s.getRange()));
} }
} else { } else {
results.add(LinterResult.warning( results.add(LinterResult.warning(
"Include statement path \"%s\" is not a constant string".formatted(s.expression))); "Include statement path \"%s\" is not a constant string".formatted(s.expression),
s.getRange()));
} }
} }
} }

View File

@ -11,10 +11,18 @@ record LinterResult(Severity severity, String message, Range range) implements S
return new LinterResult(Severity.WARNING, message); return new LinterResult(Severity.WARNING, message);
} }
static LinterResult warning(String message, Range range) {
return new LinterResult(Severity.WARNING, message, range);
}
static LinterResult error(String message) { static LinterResult error(String message) {
return new LinterResult(Severity.ERROR, message); return new LinterResult(Severity.ERROR, message);
} }
static LinterResult error(String message, Range range) {
return new LinterResult(Severity.ERROR, message, range);
}
LinterResult(Severity severity, String message) { LinterResult(Severity severity, String message) {
this(severity, message, null); this(severity, message, null);
} }