From dba3089bdd5f97fcfcf4b63220e23d393ede6ae4 Mon Sep 17 00:00:00 2001 From: JohnnyMorganz Date: Thu, 23 Mar 2023 15:02:40 +0000 Subject: [PATCH] Ensure service imports are always after hot comment --- CHANGELOG.md | 1 + src/include/LSP/LuauExt.hpp | 13 ++++++++----- src/operations/Completion.cpp | 16 ++++++---------- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 50b8cea1..515d6110 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Fixed - Fixed server crash when auto require imports is enabled and there is a type-asserted require present in the file (`require(location) :: any`) +- Fixed additional automatic service imports when completing an automatic require import being placed before a hot comment (such as `--!strict`) ## [1.18.0] - 2023-03-20 diff --git a/src/include/LSP/LuauExt.hpp b/src/include/LSP/LuauExt.hpp index e73ff60e..7b0156d7 100644 --- a/src/include/LSP/LuauExt.hpp +++ b/src/include/LSP/LuauExt.hpp @@ -124,9 +124,12 @@ struct FindServicesVisitor : public Luau::AstVisitor std::optional lastServiceDefinitionLine = std::nullopt; std::map serviceLineMap{}; - size_t findBestLine(const std::string& serviceName, std::optional minimumLineNumber = std::nullopt) + size_t findBestLine(const std::string& serviceName, size_t minimumLineNumber) { - size_t lineNumber = minimumLineNumber.value_or(firstServiceDefinitionLine.value_or(0)); + if (firstServiceDefinitionLine) + minimumLineNumber = *firstServiceDefinitionLine > minimumLineNumber ? *firstServiceDefinitionLine : minimumLineNumber; + + size_t lineNumber = minimumLineNumber; for (auto& [definedService, stat] : serviceLineMap) { auto location = stat->location.begin.line; @@ -180,7 +183,8 @@ struct FindRequiresVisitor : public Luau::AstVisitor bool contains(const std::string& module) { - for (auto& map : requiresMap) { + for (auto& map : requiresMap) + { if (map.find(module) != map.end()) return true; } @@ -202,8 +206,7 @@ struct FindRequiresVisitor : public Luau::AstVisitor if (isRequire(expr)) { - firstRequireLine = - !firstRequireLine.has_value() || firstRequireLine.value() >= line ? line : firstRequireLine.value(); + firstRequireLine = !firstRequireLine.has_value() || firstRequireLine.value() >= line ? line : firstRequireLine.value(); // If the requires are too many lines away, treat it as a new group diff --git a/src/operations/Completion.cpp b/src/operations/Completion.cpp index d16a8eff..0aa308d0 100644 --- a/src/operations/Completion.cpp +++ b/src/operations/Completion.cpp @@ -285,26 +285,21 @@ void WorkspaceFolder::suggestImports(const Luau::ModuleName& moduleName, const L return; // Place after any hot comments - size_t minimumLineNumber = 0; + size_t hotCommentsLineNumber = 0; for (const auto& hotComment : sourceModule->hotcomments) { if (!hotComment.header) continue; - if (hotComment.location.begin.line >= minimumLineNumber) - minimumLineNumber = hotComment.location.begin.line + 1U; + if (hotComment.location.begin.line >= hotCommentsLineNumber) + hotCommentsLineNumber = hotComment.location.begin.line + 1U; } - FindServicesVisitor serviceVisitor; serviceVisitor.visit(sourceModule->root); // If in roblox mode - suggest services if (config.types.roblox) { - if (serviceVisitor.firstServiceDefinitionLine) - minimumLineNumber = - *serviceVisitor.firstServiceDefinitionLine > minimumLineNumber ? *serviceVisitor.firstServiceDefinitionLine : minimumLineNumber; - auto services = getServiceNames(frontend.globalsForAutocomplete.globalScope); for (auto& service : services) { @@ -312,7 +307,7 @@ void WorkspaceFolder::suggestImports(const Luau::ModuleName& moduleName, const L if (serviceVisitor.serviceLineMap.find(service) != serviceVisitor.serviceLineMap.end()) continue; - size_t lineNumber = serviceVisitor.findBestLine(service, minimumLineNumber); + size_t lineNumber = serviceVisitor.findBestLine(service, hotCommentsLineNumber); result.emplace_back(createSuggestService(service, lineNumber)); } } @@ -321,6 +316,7 @@ void WorkspaceFolder::suggestImports(const Luau::ModuleName& moduleName, const L FindRequiresVisitor visitor; visitor.visit(sourceModule->root); + size_t minimumLineNumber = hotCommentsLineNumber; if (serviceVisitor.lastServiceDefinitionLine) minimumLineNumber = *serviceVisitor.lastServiceDefinitionLine >= minimumLineNumber ? (*serviceVisitor.lastServiceDefinitionLine + 1) : minimumLineNumber; @@ -387,7 +383,7 @@ void WorkspaceFolder::suggestImports(const Luau::ModuleName& moduleName, const L if (serviceVisitor.serviceLineMap.find(service) == serviceVisitor.serviceLineMap.end()) { // If we haven't imported the service, then we auto-import it - textEdits.emplace_back(createServiceTextEdit(service, serviceVisitor.findBestLine(service))); + textEdits.emplace_back(createServiceTextEdit(service, serviceVisitor.findBestLine(service, hotCommentsLineNumber))); // Increment the require line number to account for the new service import lineNumber += 1;