diff options
| author | Yong He <yonghe@outlook.com> | 2025-07-01 14:02:35 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-01 21:02:35 +0000 |
| commit | eb7f3357a1c316bad51cf0bfaea27d81a93f96ad (patch) | |
| tree | 448a2a07d36ef11b66ef79522086765efc5e708b /source | |
| parent | 5120c1cd072548654c9ce79fa85426a5e48736c4 (diff) | |
Misc language server improvements. (#7569)
* Misc language server improvements.
* Fix.
* Fix decl path printing for existential lookup.
* More existential decl path fix.
* Polish.
* Fix test.
Diffstat (limited to 'source')
| -rw-r--r-- | source/compiler-core/slang-json-value.cpp | 3 | ||||
| -rw-r--r-- | source/slang/slang-ast-decl-ref.cpp | 9 | ||||
| -rw-r--r-- | source/slang/slang-ast-print.cpp | 38 | ||||
| -rw-r--r-- | source/slang/slang-check-decl.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-check-expr.cpp | 2 | ||||
| -rw-r--r-- | source/slang/slang-content-assist-info.h | 3 | ||||
| -rw-r--r-- | source/slang/slang-language-server-auto-format.h | 1 | ||||
| -rw-r--r-- | source/slang/slang-language-server-completion.cpp | 32 | ||||
| -rw-r--r-- | source/slang/slang-language-server.cpp | 71 | ||||
| -rw-r--r-- | source/slang/slang-language-server.h | 1 |
10 files changed, 143 insertions, 19 deletions
diff --git a/source/compiler-core/slang-json-value.cpp b/source/compiler-core/slang-json-value.cpp index 56d003737..e2e95a968 100644 --- a/source/compiler-core/slang-json-value.cpp +++ b/source/compiler-core/slang-json-value.cpp @@ -655,6 +655,9 @@ bool JSONContainer::asBool(const JSONValue& value) return asInteger(value) != 0; case JSONValue::Type::FloatLexeme: return asFloat(value) != 0.0; + case JSONValue::Type::StringLexeme: + return getTransientString(value).caseInsensitiveEquals(toSlice("true")) || + getTransientString(value).caseInsensitiveEquals(toSlice("1")); default: return value.asBool(); } diff --git a/source/slang/slang-ast-decl-ref.cpp b/source/slang/slang-ast-decl-ref.cpp index 76d0324c6..7eec32a3a 100644 --- a/source/slang/slang-ast-decl-ref.cpp +++ b/source/slang/slang-ast-decl-ref.cpp @@ -131,9 +131,12 @@ DeclRefBase* LookupDeclRef::_substituteImplOverride( void LookupDeclRef::_toTextOverride(StringBuilder& out) { - getLookupSource()->toText(out); - if (out.getLength() && !out.endsWith(".")) - out << "."; + if (!as<ThisType>(getLookupSource())) + { + getLookupSource()->toText(out); + if (out.getLength() && !out.endsWith(".")) + out << "."; + } if (getDecl()->getName() && getDecl()->getName()->text.getLength() != 0) { out << getDecl()->getName()->text; diff --git a/source/slang/slang-ast-print.cpp b/source/slang/slang-ast-print.cpp index 94864b815..4b5a69f15 100644 --- a/source/slang/slang-ast-print.cpp +++ b/source/slang/slang-ast-print.cpp @@ -1168,8 +1168,34 @@ void ASTPrinter::_addDeclPathRec(const DeclRef<Decl>& declRef, Index depth) { auto& sb = m_builder; - // Find the parent declaration - auto parentDeclRef = declRef.getParent(); + // Find the parent declaration. + DeclRef<Decl> parentDeclRef; + + // If this is a lookup decl ref, prefix with the lookup source type instead of the parent. + if (auto lookupDeclRef = as<LookupDeclRef>(declRef.declRefBase)) + { + if (auto extractExistentialType = + as<ExtractExistentialType>(lookupDeclRef->getLookupSource())) + { + parentDeclRef = extractExistentialType->getOriginalInterfaceDeclRef(); + } + else + { + parentDeclRef = isDeclRefTypeOf<Decl>(lookupDeclRef->getLookupSource()); + } + if (as<ThisTypeDecl>(parentDeclRef.getDecl())) + { + if (auto baseLookupDeclRef = as<LookupDeclRef>(parentDeclRef.declRefBase)) + { + // If the base type is a lookup, we want to use its source type + parentDeclRef = isDeclRefTypeOf<Decl>(baseLookupDeclRef->getLookupSource()); + } + } + } + else + { + parentDeclRef = declRef.getParent(); + } // If the immediate parent is a generic, then we probably // want the declaration above that... @@ -1180,9 +1206,13 @@ void ASTPrinter::_addDeclPathRec(const DeclRef<Decl>& declRef, Index depth) } // Depending on what the parent is, we may want to format things specially - if (auto aggTypeDeclRef = parentDeclRef.as<AggTypeDecl>()) + if (parentDeclRef.as<ThisTypeDecl>()) + { + sb << "This."; + } + else if (parentDeclRef.as<AggTypeDecl>() || parentDeclRef.as<SimpleTypeDecl>()) { - _addDeclPathRec(aggTypeDeclRef, depth + 1); + _addDeclPathRec(parentDeclRef, depth + 1); sb << toSlice("."); } else if (auto namespaceDeclRef = parentDeclRef.as<NamespaceDecl>()) diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 9e4d5a6d3..6d8788b4f 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -7898,7 +7898,7 @@ void SemanticsVisitor::calcOverridableCompletionCandidates( contentAssistInfo.completionSuggestions.formatMode = varDeclBase ? CompletionSuggestions::FormatMode::FuncSignatureWithoutReturnType : CompletionSuggestions::FormatMode::FullSignature; - + contentAssistInfo.completionSuggestions.currentPartialDecl = memberDecl; List<LookupResultItem> candidateItems; for (auto facet : inheritanceInfo.facets) { diff --git a/source/slang/slang-check-expr.cpp b/source/slang/slang-check-expr.cpp index b90081af8..c3238bd9b 100644 --- a/source/slang/slang-check-expr.cpp +++ b/source/slang/slang-check-expr.cpp @@ -410,7 +410,7 @@ DeclRefExpr* SemanticsVisitor::ConstructDeclRefExpr( SharedTypeExpr* baseTypeExpr = m_astBuilder->create<SharedTypeExpr>(); baseTypeExpr->base.type = baseExprType; baseTypeExpr->type.type = m_astBuilder->getTypeType(baseExprType); - + baseTypeExpr->base.exp = baseExpr; auto expr = m_astBuilder->create<StaticMemberExpr>(); expr->loc = loc; expr->type = type; diff --git a/source/slang/slang-content-assist-info.h b/source/slang/slang-content-assist-info.h index 77102bf66..c913e1546 100644 --- a/source/slang/slang-content-assist-info.h +++ b/source/slang/slang-content-assist-info.h @@ -32,6 +32,7 @@ struct CompletionSuggestions ScopeKind scopeKind = ScopeKind::Invalid; FormatMode formatMode = FormatMode::Name; + Decl* currentPartialDecl = nullptr; List<LookupResultItem> candidateItems; Type* swizzleBaseType = nullptr; @@ -40,10 +41,12 @@ struct CompletionSuggestions void clear() { scopeKind = ScopeKind::Invalid; + formatMode = FormatMode::Name; candidateItems.clear(); elementCount[0] = 0; elementCount[1] = 0; swizzleBaseType = nullptr; + currentPartialDecl = nullptr; } }; diff --git a/source/slang/slang-language-server-auto-format.h b/source/slang/slang-language-server-auto-format.h index 24e89b051..d37359730 100644 --- a/source/slang/slang-language-server-auto-format.h +++ b/source/slang/slang-language-server-auto-format.h @@ -27,6 +27,7 @@ enum class FormatBehavior struct FormatOptions { + bool enableFormatOnType = true; String clangFormatLocation; String style = "file"; String fallbackStyle = "{BasedOnStyle: Microsoft}"; diff --git a/source/slang/slang-language-server-completion.cpp b/source/slang/slang-language-server-completion.cpp index 9a88fbaa7..b5864d972 100644 --- a/source/slang/slang-language-server-completion.cpp +++ b/source/slang/slang-language-server-completion.cpp @@ -617,6 +617,16 @@ CompletionResult CompletionContext::collectMembersAndSymbols() default: return result; } + + // If we are completing an override function signature, don't add keywords to the result. + switch (linkage->contentAssistInfo.completionSuggestions.formatMode) + { + case CompletionSuggestions::FormatMode::FullSignature: + case CompletionSuggestions::FormatMode::FuncSignatureWithoutReturnType: + addKeywords = false; + break; + } + HashSet<String> deduplicateSet; for (Index i = 0; i < linkage->contentAssistInfo.completionSuggestions.candidateItems.getCount(); @@ -639,6 +649,28 @@ CompletionResult CompletionContext::collectMembersAndSymbols() nameStart); if (item.label.getLength() == 0) continue; + if (linkage->contentAssistInfo.completionSuggestions.formatMode == + CompletionSuggestions::FormatMode::FullSignature) + { + // If the completion item is a `static` function, but there is no `static` keyword + // on the current incomplete decl, then we will add `static` keyword to the completion + // result. + if (suggestedItem.declRef.getDecl() && + suggestedItem.declRef.getDecl()->findModifier<HLSLStaticModifier>() && + linkage->contentAssistInfo.completionSuggestions.currentPartialDecl && + !linkage->contentAssistInfo.completionSuggestions.currentPartialDecl + ->findModifier<HLSLStaticModifier>()) + { + item.label = "static " + item.label; + nameStart += 7; + // Add an item for 'static' keyword. + LanguageServerProtocol::CompletionItem staticItem; + staticItem.label = "static"; + staticItem.kind = LanguageServerProtocol::kCompletionItemKindKeyword; + staticItem.data = "-1"; // Use -1 to indicate this is a keyword. + result.add(staticItem); + } + } item.kind = LanguageServerProtocol::kCompletionItemKindKeyword; if (as<TypeConstraintDecl>(member)) { diff --git a/source/slang/slang-language-server.cpp b/source/slang/slang-language-server.cpp index 6daeb75ad..3cc093ad7 100644 --- a/source/slang/slang-language-server.cpp +++ b/source/slang/slang-language-server.cpp @@ -210,15 +210,15 @@ SlangResult LanguageServer::parseNextMessage() if (response.result.getKind() == JSONValue::Kind::Array) { auto arr = m_connection->getContainer()->getArray(response.result); - if (arr.getCount() == 12) + if (arr.getCount() == 13) { updatePredefinedMacros(arr[0]); updateSearchPaths(arr[1]); updateSearchInWorkspace(arr[2]); updateCommitCharacters(arr[3]); - updateFormattingOptions(arr[4], arr[5], arr[6], arr[7], arr[8]); - updateInlayHintOptions(arr[9], arr[10]); - updateTraceOptions(arr[11]); + updateFormattingOptions(arr[4], arr[5], arr[6], arr[7], arr[8], arr[9]); + updateInlayHintOptions(arr[10], arr[11]); + updateTraceOptions(arr[12]); } } break; @@ -1876,6 +1876,9 @@ SlangResult LanguageServer::rangeFormatting( LanguageServerResult<List<LanguageServerProtocol::TextEdit>> LanguageServerCore::rangeFormatting( const LanguageServerProtocol::DocumentRangeFormattingParams& args) { + if (!m_formatOptions.enableFormatOnType) + return std::nullopt; + String canonicalPath = uriToCanonicalPath(args.textDocument.uri); RefPtr<DocumentVersion> doc; if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc)) @@ -1924,6 +1927,9 @@ SlangResult LanguageServer::onTypeFormatting( LanguageServerResult<List<LanguageServerProtocol::TextEdit>> LanguageServerCore::onTypeFormatting( const LanguageServerProtocol::DocumentOnTypeFormattingParams& args) { + if (!m_formatOptions.enableFormatOnType) + return std::nullopt; + String canonicalPath = uriToCanonicalPath(args.textDocument.uri); RefPtr<DocumentVersion> doc; if (!m_workspace->openedDocuments.tryGetValue(canonicalPath, doc)) @@ -2084,6 +2090,7 @@ void LanguageServer::updateCommitCharacters(const JSONValue& jsonValue) } void LanguageServer::updateFormattingOptions( + const JSONValue& enableFormatOnType, const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& clangFormatFallbackStyle, @@ -2092,6 +2099,8 @@ void LanguageServer::updateFormattingOptions( { auto container = m_connection->getContainer(); JSONToNativeConverter converter(container, &m_typeMap, m_connection->getSink()); + if (enableFormatOnType.isValid()) + converter.convert(enableFormatOnType, &m_core.m_formatOptions.enableFormatOnType); if (clangFormatLoc.isValid()) converter.convert(clangFormatLoc, &m_core.m_formatOptions.clangFormatLocation); if (clangFormatStyle.isValid()) @@ -2162,6 +2171,8 @@ void LanguageServer::sendConfigRequest() args.items.add(item); item.section = "slang.enableCommitCharactersInAutoCompletion"; args.items.add(item); + item.section = "slang.format.enableFormatOnType"; + args.items.add(item); item.section = "slang.format.clangFormatLocation"; args.items.add(item); item.section = "slang.format.clangFormatStyle"; @@ -2611,7 +2622,7 @@ SlangResult LanguageServerCore::didChangeTextDocument(const DidChangeTextDocumen SlangResult LanguageServer::didChangeConfiguration( const LanguageServerProtocol::DidChangeConfigurationParams& args) { - if (args.settings.isValid()) + if (args.settings.isValid() && args.settings.type != JSONValue::Type::Null) { updateConfigFromJSON(args.settings); } @@ -2657,25 +2668,65 @@ void LanguageServer::updateConfigFromJSON(const JSONValue& jsonVal) { updateCommitCharacters(kv.value); } + else if (key == "slang.format.enableFormatOnType") + { + updateFormattingOptions( + kv.value, + JSONValue(), + JSONValue(), + JSONValue(), + JSONValue(), + JSONValue()); + } else if (key == "slang.format.clangFormatLocation") { - updateFormattingOptions(kv.value, JSONValue(), JSONValue(), JSONValue(), JSONValue()); + updateFormattingOptions( + JSONValue(), + kv.value, + JSONValue(), + JSONValue(), + JSONValue(), + JSONValue()); } else if (key == "slang.format.clangFormatStyle") { - updateFormattingOptions(JSONValue(), kv.value, JSONValue(), JSONValue(), JSONValue()); + updateFormattingOptions( + JSONValue(), + JSONValue(), + kv.value, + JSONValue(), + JSONValue(), + JSONValue()); } else if (key == "slang.format.clangFormatFallbackStyle") { - updateFormattingOptions(JSONValue(), JSONValue(), kv.value, JSONValue(), JSONValue()); + updateFormattingOptions( + JSONValue(), + JSONValue(), + JSONValue(), + kv.value, + JSONValue(), + JSONValue()); } else if (key == "slang.format.allowLineBreakChangesInOnTypeFormatting") { - updateFormattingOptions(JSONValue(), JSONValue(), JSONValue(), kv.value, JSONValue()); + updateFormattingOptions( + JSONValue(), + JSONValue(), + JSONValue(), + JSONValue(), + kv.value, + JSONValue()); } else if (key == "slang.format.allowLineBreakChangesInRangeFormatting") { - updateFormattingOptions(JSONValue(), JSONValue(), JSONValue(), JSONValue(), kv.value); + updateFormattingOptions( + JSONValue(), + JSONValue(), + JSONValue(), + JSONValue(), + JSONValue(), + kv.value); } else if (key == "slang.inlayHints.deducedTypes") { diff --git a/source/slang/slang-language-server.h b/source/slang/slang-language-server.h index e31e77acb..43c3521eb 100644 --- a/source/slang/slang-language-server.h +++ b/source/slang/slang-language-server.h @@ -250,6 +250,7 @@ private: void updateSearchInWorkspace(const JSONValue& value); void updateCommitCharacters(const JSONValue& value); void updateFormattingOptions( + const JSONValue& enableFormatOnType, const JSONValue& clangFormatLoc, const JSONValue& clangFormatStyle, const JSONValue& clangFormatFallbackStyle, |
