Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 23 additions & 5 deletions tslang/lib/TypeScript/MLIRGenImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ class MLIRGenImpl
path(pathParam),
declarationMode(false),
tempEntryBlock(nullptr),
overwriteLoc(mlir::UnknownLoc::get(builder.getContext()))
overwriteLoc(mlir::UnknownLoc::get(builder.getContext())),
generatedNodesAnchor(mlir::UnknownLoc::get(builder.getContext()))
{
setCompileOptions(compileOptions);

Expand Down Expand Up @@ -1157,6 +1158,10 @@ class MLIRGenImpl
mlir::LogicalResult mlirGenDisposeOne(mlir::Location location, ts::VariableDeclarationDOM::TypePtr varDecl,
mlir::Value varValue, const GenContext &genContext)
{
// the call is made at the scope's exit, but an error in it belongs to the declaration
MLIRLocationGuard anchorGuard(generatedNodesAnchor);
generatedNodesAnchor = stripMetadata(varDecl->getLoc());

auto disposeGuard = varDecl->getDisposeGuard();
if (!disposeGuard)
{
Expand Down Expand Up @@ -13947,13 +13952,23 @@ class MLIRGenImpl
return mlir::UnknownLoc::get(builder.getContext());
}

// a node the compiler made (a for...of's loop, a `using`'s dispose call) has no position:
// it is where the code it was made for is, not at the start of the file
if (loc->isTextRangeEmpty() && !isa<mlir::UnknownLoc>(generatedNodesAnchor))
{
return locFuseWithScope(combine(overwriteLoc, generatedNodesAnchor));
}

return locFuseWithScope(combine(overwriteLoc, locWithoutScope(loc)));
}

// where the node is in the source, without the debug scope and the overwriteLoc loc() adds
mlir::Location locWithoutScope(TextRange loc)
{
auto pos = loc->pos.textPos > 0 ? loc->pos.textPos : loc->pos.pos;
//return loc1(sourceFile, fileName.str(), pos, loc->_end - pos);
//return loc2(sourceFile, fileName.str(), pos, loc->_end - pos);
return locFuseWithScope(
combine(
overwriteLoc,
loc2Fuse(sourceFile, mainSourceFileName.str(), pos, loc->_end - pos)));
return loc2Fuse(sourceFile, mainSourceFileName.str(), pos, loc->_end - pos);
}

mlir::Location loc1(ts::SourceFile sourceFile, std::string fileName, int start, int length)
Expand Down Expand Up @@ -14375,6 +14390,9 @@ class MLIRGenImpl
mlir::ModuleOp tempModule;
mlir_ts::FuncOp tempFuncOp;
mlir::Location overwriteLoc;
// where the innermost statement being generated is (no debug scope: loc() adds the current
// one): the location of the nodes the compiler makes for it, which have none of their own
mlir::Location generatedNodesAnchor;
};
} // namespace mlirgen
} // namespace typescript
8 changes: 8 additions & 0 deletions tslang/lib/TypeScript/MLIRGenStatements.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,14 @@ namespace mlirgen

mlir::LogicalResult MLIRGenImpl::mlirGen(Statement statementAST, const GenContext &genContext)
{
// what the compiler makes for this statement is reported where the statement is; a
// statement it made itself keeps the anchor of the one it was made for
MLIRLocationGuard anchorGuard(generatedNodesAnchor);
if (!statementAST->isTextRangeEmpty())
{
generatedNodesAnchor = locWithoutScope(statementAST);
}

auto kind = (SyntaxKind)statementAST;
if (kind == SyntaxKind::FunctionDeclaration)
{
Expand Down
20 changes: 20 additions & 0 deletions tslang/test/tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2947,6 +2947,26 @@ set_tests_properties(test-compile-diagnostic-location-implicit-constructor
PROPERTIES PASS_REGULAR_EXPRESSION "implicit_constructor\\.ts:9:1: error: Class constructor is not accessable"
FAIL_REGULAR_EXPRESSION "Stack dump|Assertion failed|implicit_constructor\\.ts:1:")

# An error in the code the compiler makes for a statement (a for...of's or for...in's loop) is
# reported at the statement, and one in a `using`'s dispose call at the declaration - not at 1:1,
# as a node the compiler makes has no position of its own.
set(diagnostic_location_statement_cases
"for_of|for_of\\.ts:6:5: error: Can't resolve property 'length' of type s32"
"for_in|for_in\\.ts:6:5: error: Can't resolve property 'length' of type s32"
"using|using\\.ts:5:11: error: Can't resolve property 'dispose' of type s32")
foreach(diagnostic_location_case ${diagnostic_location_statement_cases})
string(REPLACE "|" ";" diagnostic_location_parts "${diagnostic_location_case}")
list(GET diagnostic_location_parts 0 diagnostic_location_name)
list(GET diagnostic_location_parts 1 diagnostic_location_error)
add_test(NAME test-compile-diagnostic-location-${diagnostic_location_name}
COMMAND $<TARGET_FILE:tslang> --emit=obj --no-default-lib -mm=none
"${PROJECT_SOURCE_DIR}/test/tester/diagnostic-location/${diagnostic_location_name}.ts"
-o "${CMAKE_CURRENT_BINARY_DIR}/diagnostic-location-${diagnostic_location_name}.obj")
set_tests_properties(test-compile-diagnostic-location-${diagnostic_location_name}
PROPERTIES PASS_REGULAR_EXPRESSION "${diagnostic_location_error}"
FAIL_REGULAR_EXPRESSION "Stack dump|Assertion failed|${diagnostic_location_name}\\.ts:1:")
endforeach()

# `ns.name` is the namespace's member or an error: a local or an outer namespace's `name` isn't it.
foreach(namespace_member_case missing_member outer_member)
add_test(NAME test-compile-namespace-member-${namespace_member_case}
Expand Down
9 changes: 9 additions & 0 deletions tslang/test/tester/diagnostic-location/for_in.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// A for...in over something without a length was reported at the start of the file: the loop
// the compiler makes for it had no position.

function main() {
const n = 5;
for (const k in n) {
print(k);
}
}
9 changes: 9 additions & 0 deletions tslang/test/tester/diagnostic-location/for_of.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// A for...of over something that isn't iterable was reported at the start of the file: the loop
// the compiler makes for it had no position.

function main() {
const n = 5;
for (const x of n) {
print(x);
}
}
6 changes: 6 additions & 0 deletions tslang/test/tester/diagnostic-location/using.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// A `using` of a value with no dispose method was reported at the start of the file: the dispose
// call the compiler makes for it had no position.

function main() {
using x = 5;
}
Loading