diff --git a/Lexer.fu b/Lexer.fu index 020f30ff..3aa3e21d 100644 --- a/Lexer.fu +++ b/Lexer.fu @@ -21,7 +21,16 @@ public abstract class FuParserHost { internal FuProgram! Program; + public abstract void ReportError!(string filename, int line, int startUtf16Column, int endUtf16Column, string message); + + internal void ReportStatementError!(FuStatement statement, string message) + { + int line = this.Program.GetLine(statement.Loc); + int column = statement.Loc - this.Program.LineLocs[line]; + FuSourceFile file = this.Program.GetSourceFile(line); + ReportError(file.Filename, line - file.Line, column, column + statement.GetLocLength(), message); + } } public enum FuToken diff --git a/Parser.fu b/Parser.fu index 0f672351..ab57b874 100644 --- a/Parser.fu +++ b/Parser.fu @@ -523,7 +523,7 @@ public class FuParser : FuLexer void AddSymbol!(FuScope! scope, FuSymbol# symbol) { if (scope.Contains(symbol)) - ReportError("Duplicate symbol"); + this.Host.ReportStatementError(symbol, "Duplicate symbol"); else scope.Add(symbol); } diff --git a/Sema.fu b/Sema.fu index 8a47d889..c06c59ba 100644 --- a/Sema.fu +++ b/Sema.fu @@ -21,14 +21,6 @@ public abstract class FuSemaHost : FuParserHost { internal virtual int GetResourceLength!(string name, FuPrefixExpr expr) => 0; - - internal void ReportStatementError!(FuStatement statement, string message) - { - int line = this.Program.GetLine(statement.Loc); - int column = statement.Loc - this.Program.LineLocs[line]; - FuSourceFile file = this.Program.GetSourceFile(line); - ReportError(file.Filename, line - file.Line, column, column + statement.GetLocLength(), message); - } } public class FuSema diff --git a/libfut.cpp b/libfut.cpp index d43f2650..9d7d486b 100644 --- a/libfut.cpp +++ b/libfut.cpp @@ -31,6 +31,14 @@ static std::string FuString_Replace(std::string_view s, std::string_view oldValu } } +void FuParserHost::reportStatementError(const FuStatement * statement, std::string_view message) +{ + int line = this->program->getLine(statement->loc); + int column = statement->loc - this->program->lineLocs[line]; + const FuSourceFile * file = this->program->getSourceFile(line); + reportError(file->filename, line - file->line, column, column + statement->getLocLength(), message); +} + void FuLexer::setHost(FuParserHost * host) { this->host = host; @@ -3668,7 +3676,7 @@ std::shared_ptr FuParser::parseInitializer() void FuParser::addSymbol(FuScope * scope, std::shared_ptr symbol) { if (scope->contains(symbol.get())) - reportError("Duplicate symbol"); + this->host->reportStatementError(symbol.get(), "Duplicate symbol"); else scope->add(symbol); } @@ -4365,14 +4373,6 @@ int FuSemaHost::getResourceLength(std::string_view name, const FuPrefixExpr * ex { return 0; } - -void FuSemaHost::reportStatementError(const FuStatement * statement, std::string_view message) -{ - int line = this->program->getLine(statement->loc); - int column = statement->loc - this->program->lineLocs[line]; - const FuSourceFile * file = this->program->getSourceFile(line); - reportError(file->filename, line - file->line, column, column + statement->getLocLength(), message); -} FuSema::FuSema() { this->poison->name = "poison"; diff --git a/libfut.cs b/libfut.cs index 3d569d93..e00ec1ab 100644 --- a/libfut.cs +++ b/libfut.cs @@ -14,6 +14,14 @@ public abstract class FuParserHost internal FuProgram Program; public abstract void ReportError(string filename, int line, int startUtf16Column, int endUtf16Column, string message); + + internal void ReportStatementError(FuStatement statement, string message) + { + int line = this.Program.GetLine(statement.Loc); + int column = statement.Loc - this.Program.LineLocs[line]; + FuSourceFile file = this.Program.GetSourceFile(line); + ReportError(file.Filename, line - file.Line, column, column + statement.GetLocLength(), message); + } } public enum FuToken @@ -4000,7 +4008,7 @@ FuExpr ParseInitializer() void AddSymbol(FuScope scope, FuSymbol symbol) { if (scope.Contains(symbol)) - ReportError("Duplicate symbol"); + this.Host.ReportStatementError(symbol, "Duplicate symbol"); else scope.Add(symbol); } @@ -4628,14 +4636,6 @@ public abstract class FuSemaHost : FuParserHost { internal virtual int GetResourceLength(string name, FuPrefixExpr expr) => 0; - - internal void ReportStatementError(FuStatement statement, string message) - { - int line = this.Program.GetLine(statement.Loc); - int column = statement.Loc - this.Program.LineLocs[line]; - FuSourceFile file = this.Program.GetSourceFile(line); - ReportError(file.Filename, line - file.Line, column, column + statement.GetLocLength(), message); - } } public class FuSema diff --git a/libfut.hpp b/libfut.hpp index 87a3a00d..d052d143 100644 --- a/libfut.hpp +++ b/libfut.hpp @@ -479,6 +479,7 @@ class FuParserHost FuParserHost() = default; public: FuProgram * program; + void reportStatementError(const FuStatement * statement, std::string_view message); }; class FuLexer @@ -1658,7 +1659,6 @@ class FuSemaHost : public FuParserHost FuSemaHost() = default; public: virtual int getResourceLength(std::string_view name, const FuPrefixExpr * expr); - void reportStatementError(const FuStatement * statement, std::string_view message); }; class GenHost : public FuSemaHost diff --git a/libfut.js b/libfut.js index 1f826ce6..58c8cc9c 100644 --- a/libfut.js +++ b/libfut.js @@ -10,6 +10,14 @@ export const RegexOptions = { export class FuParserHost { program; + + reportStatementError(statement, message) + { + let line = this.program.getLine(statement.loc); + let column = statement.loc - this.program.lineLocs[line]; + let file = this.program.getSourceFile(line); + this.reportError(file.filename, line - file.line, column, column + statement.getLocLength(), message); + } } export const FuToken = { @@ -4202,7 +4210,7 @@ export class FuParser extends FuLexer #addSymbol(scope, symbol) { if (scope.contains(symbol)) - this.reportError("Duplicate symbol"); + this.host.reportStatementError(symbol, "Duplicate symbol"); else scope.add(symbol); } @@ -4829,14 +4837,6 @@ export class FuSemaHost extends FuParserHost { return 0; } - - reportStatementError(statement, message) - { - let line = this.program.getLine(statement.loc); - let column = statement.loc - this.program.lineLocs[line]; - let file = this.program.getSourceFile(line); - this.reportError(file.filename, line - file.line, column, column + statement.getLocLength(), message); - } } export class GenHost extends FuSemaHost diff --git a/test/error/ClassDuplicate.fu b/test/error/ClassDuplicate.fu deleted file mode 100644 index 84eafbba..00000000 --- a/test/error/ClassDuplicate.fu +++ /dev/null @@ -1,9 +0,0 @@ -public class Test -{ -} - -public class Test -// FIXME: line -{ //ERROR: Duplicate symbol - public static bool Run() => true; -} diff --git a/test/error/SymbolDuplicate.fu b/test/error/SymbolDuplicate.fu new file mode 100644 index 00000000..0545f24a --- /dev/null +++ b/test/error/SymbolDuplicate.fu @@ -0,0 +1,9 @@ +public class Foo +{ + public const int A = 0; + public const int A = 0; //ERROR: Duplicate symbol +} + +public class Foo //ERROR: Duplicate symbol +{ +}