diff options
| author | Yong He <yonghe@outlook.com> | 2024-02-20 23:13:29 -0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-20 23:13:29 -0800 |
| commit | 2e2c7943da89b0100db3bba4b11267b5a857ca92 (patch) | |
| tree | 8cbf8010e964cdbb7381fa15b1062b2c43cbd870 | |
| parent | 2ee05c1257c916e5c804a6b565a2a6aa362050e0 (diff) | |
Language server robustness fix. (#3607)
* Language server robustness fix.
* Allow parameter name to be the same as its type.
* fix
* Fix test.
| -rw-r--r-- | source/slang/slang-ast-iterator.h | 2 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 5 | ||||
| -rw-r--r-- | source/slang/slang-language-server-ast-lookup.cpp | 6 | ||||
| -rw-r--r-- | source/slang/slang-parser.cpp | 24 | ||||
| -rw-r--r-- | source/slang/slang.cpp | 25 | ||||
| -rw-r--r-- | tests/diagnostics/recursive-import.slang | 3 | ||||
| -rw-r--r-- | tests/language-feature/modules/error-in-nested-import/error-in-nested-import.slang | 3 |
7 files changed, 48 insertions, 20 deletions
diff --git a/source/slang/slang-ast-iterator.h b/source/slang/slang-ast-iterator.h index fc6f321e3..2b6a2d3e2 100644 --- a/source/slang/slang-ast-iterator.h +++ b/source/slang/slang-ast-iterator.h @@ -479,6 +479,8 @@ void ASTIterator<CallbackFunc, FilterFunc>::visitDecl(DeclBase* decl) { visitDecl(member); } + if (auto aggTypeDecl = as<AggTypeDecl>(decl)) + visitExpr(aggTypeDecl->wrappedType.exp); } for (auto modifier : decl->modifiers) { diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 1c964ab88..28db66c45 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -7665,11 +7665,16 @@ namespace Slang { // Create a new sub-scope to wire the module // into our lookup chain. + if (!fileDecl) + return; addSiblingScopeForContainerDecl(getASTBuilder(), scope, fileDecl); } void SemanticsVisitor::importModuleIntoScope(Scope* scope, ModuleDecl* moduleDecl) { + if (!moduleDecl) + return; + // If we've imported this one already, then // skip the step where we modify the current scope. auto& importedModulesList = getShared()->importedModulesList; diff --git a/source/slang/slang-language-server-ast-lookup.cpp b/source/slang/slang-language-server-ast-lookup.cpp index 13db8af18..755805b51 100644 --- a/source/slang/slang-language-server-ast-lookup.cpp +++ b/source/slang/slang-language-server-ast-lookup.cpp @@ -752,6 +752,12 @@ bool _findAstNodeImpl(ASTLookupContext& context, SyntaxNode* node) return true; } } + if (auto aggTypeDecl = as<AggTypeDecl>(container)) + { + ASTLookupExprVisitor visitor(&context); + if (visitor.dispatchIfNotNull(aggTypeDecl->wrappedType.exp)) + return true; + } } } return false; diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp index b208e1098..ad4e65bf2 100644 --- a/source/slang/slang-parser.cpp +++ b/source/slang/slang-parser.cpp @@ -105,7 +105,8 @@ namespace Slang int sameTokenPeekedTimes = 0; Scope* outerScope = nullptr; - Scope* currentScope = nullptr; + Scope* currentLookupScope = nullptr; // Scope where expr lookup should initiate from. + Scope* currentScope = nullptr; // Scope where new decl definitions should be inserted into. ModuleDecl* currentModule = nullptr; bool hasSeenCompletionToken = false; @@ -126,20 +127,20 @@ namespace Slang { node->loc = tokenReader.peekLoc(); } - void PushScope(ContainerDecl* containerDecl) + + void resetLookupScope() { - // TODO(JS): - // - // Previously Scope was ref counted. This meant that if a scope was pushed, but not used when popped - // it's memory would be freed. - // - // Here the memory is consumed and will not be freed until the astBuilder goes out of scope. + currentLookupScope = currentScope; + } + void PushScope(ContainerDecl* containerDecl) + { Scope* newScope = astBuilder->create<Scope>(); newScope->containerDecl = containerDecl; newScope->parent = currentScope; currentScope = newScope; containerDecl->ownedScope = newScope; + resetLookupScope(); } void pushScopeAndSetParent(ContainerDecl* containerDecl) @@ -151,6 +152,7 @@ namespace Slang void PopScope() { currentScope = currentScope->parent; + resetLookupScope(); } ModuleDecl* getCurrentModuleDecl() @@ -2554,7 +2556,7 @@ namespace Slang Token typeName = parser->ReadToken(TokenType::Identifier); auto basicType = parser->astBuilder->create<VarExpr>(); - basicType->scope = parser->currentScope; + basicType->scope = parser->currentLookupScope; basicType->loc = typeName.loc; basicType->name = typeName.getNameOrNull(); @@ -5591,9 +5593,9 @@ namespace Slang { ParamDecl* parameter = astBuilder->create<ParamDecl>(); parameter->modifiers = ParseModifiers(this); - + currentLookupScope = currentScope->parent; _parseTraditionalParamDeclCommonBase(this, parameter, kDeclaratorParseOption_AllowEmpty); - + resetLookupScope(); return parameter; } diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index 498dc67f5..a1627286d 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -3302,22 +3302,33 @@ RefPtr<Module> Linkage::loadModule( return nullptr; } - loadParsedModule( - frontEndReq, - translationUnit, - name, - filePathInfo); - + try + { + loadParsedModule( + frontEndReq, + translationUnit, + name, + filePathInfo); + } + catch (const Slang::AbortCompilationException&) + { + // Something is fatally wrong, we should return nullptr. + module = nullptr; + } errorCountAfter = sink->getErrorCount(); if (errorCountAfter != errorCountBefore && !isInLanguageServer()) { + // If something is fatally wrong, we want to report + // the diagnostic even if we are in language server + // and processing a different module. _diagnoseErrorInImportedModule(sink); // Something went wrong during the parsing, so we should bail out. return nullptr; } - module->setPathInfo(filePathInfo); + if (module) + module->setPathInfo(filePathInfo); return module; } diff --git a/tests/diagnostics/recursive-import.slang b/tests/diagnostics/recursive-import.slang index b74e55be4..312c579cf 100644 --- a/tests/diagnostics/recursive-import.slang +++ b/tests/diagnostics/recursive-import.slang @@ -1,6 +1,7 @@ -//DIAGNOSTIC_TEST:SIMPLE: +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): // A file that recursively imports itself // (including transitive cases) should be diagnosed. +// CHECK: ([[#@LINE+1]]): error 38200 import recursive_import_extra; diff --git a/tests/language-feature/modules/error-in-nested-import/error-in-nested-import.slang b/tests/language-feature/modules/error-in-nested-import/error-in-nested-import.slang index 2efa69121..b709b52b1 100644 --- a/tests/language-feature/modules/error-in-nested-import/error-in-nested-import.slang +++ b/tests/language-feature/modules/error-in-nested-import/error-in-nested-import.slang @@ -1,6 +1,7 @@ // error-in-nested-import.slang -//DIAGNOSTIC_TEST:SIMPLE: +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): +// CHECK: ([[#@LINE+1]]): error import a; int main() |
