From e307d17ca9420eec3673efcd1bfc73f3b33061ec Mon Sep 17 00:00:00 2001 From: Marcin Jastrzebski Date: Wed, 19 Jun 2024 18:37:11 -0700 Subject: [PATCH] Fixed UDT syntax highlighting (#14372) Fixed the recent regression in syntax highlighting for user defined types: * Now emitting `SemanticTokenType.Namespace` for namespace symbols. * Now emitting `SemanticTokenType.Type` for `TypeVariableAccessSyntax` that resolves to a valid type symbol. * Now emitting `SemanticTokenType.Keyword` for `null`, `true` and `false` type keywords. Examples of changes: image I will look into adding tests separately since we don't currently have baselines or meaningful unit tests for syntax highlighting. (I recall we had some issues with that in the past, but will need to confirm.) This fixes #14147 ###### Microsoft Reviewers: [Open in CodeFlow](https://microsoft.github.io/open-pr/?codeflow=https://github.com/Azure/bicep/pull/14372) --- src/Bicep.LangServer/SemanticTokenVisitor.cs | 48 ++++++++++++++++---- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/src/Bicep.LangServer/SemanticTokenVisitor.cs b/src/Bicep.LangServer/SemanticTokenVisitor.cs index bcad1682b18..3c27d1ec623 100644 --- a/src/Bicep.LangServer/SemanticTokenVisitor.cs +++ b/src/Bicep.LangServer/SemanticTokenVisitor.cs @@ -4,6 +4,7 @@ using Bicep.Core.Parsing; using Bicep.Core.Semantics; using Bicep.Core.Syntax; +using Bicep.Core.TypeSystem; using Bicep.LanguageServer.Extensions; using OmniSharp.Extensions.LanguageServer.Protocol.Document; using OmniSharp.Extensions.LanguageServer.Protocol.Models; @@ -72,6 +73,12 @@ public override void VisitBooleanLiteralSyntax(BooleanLiteralSyntax syntax) base.VisitBooleanLiteralSyntax(syntax); } + public override void VisitBooleanTypeLiteralSyntax(BooleanTypeLiteralSyntax syntax) + { + AddTokenType(syntax.Literal, SemanticTokenType.Keyword); + base.VisitBooleanTypeLiteralSyntax(syntax); + } + public override void VisitFunctionCallSyntax(FunctionCallSyntax syntax) { // We need to set token types for OpenParen and CloseParen in case the function call @@ -98,6 +105,12 @@ public override void VisitNullLiteralSyntax(NullLiteralSyntax syntax) base.VisitNullLiteralSyntax(syntax); } + public override void VisitNullTypeLiteralSyntax(NullTypeLiteralSyntax syntax) + { + AddTokenType(syntax.NullKeyword, SemanticTokenType.Keyword); + base.VisitNullTypeLiteralSyntax(syntax); + } + public override void VisitIntegerLiteralSyntax(IntegerLiteralSyntax syntax) { AddTokenType(syntax.Literal, SemanticTokenType.Number); @@ -146,6 +159,13 @@ public override void VisitPropertyAccessSyntax(PropertyAccessSyntax syntax) base.VisitPropertyAccessSyntax(syntax); } + public override void VisitTypePropertyAccessSyntax(TypePropertyAccessSyntax syntax) + { + AddTokenType(syntax.Dot, SemanticTokenType.Operator); + AddTokenType(syntax.PropertyName, GetSemanticTokenForPotentialTypeSymbol(model.GetSymbolInfo(syntax))); + base.VisitTypePropertyAccessSyntax(syntax); + } + public override void VisitArrayAccessSyntax(ArrayAccessSyntax syntax) { AddTokenType(syntax.OpenSquare, SemanticTokenType.Operator); @@ -294,16 +314,16 @@ public override void VisitUnaryOperationSyntax(UnaryOperationSyntax syntax) public override void VisitVariableAccessSyntax(VariableAccessSyntax syntax) { - AddTokenType(syntax.Name, model.GetSymbolInfo(syntax) switch - { - TypeAliasSymbol or - AmbientTypeSymbol or - ImportedTypeSymbol => SemanticTokenType.Type, - _ => SemanticTokenType.Variable, - }); + AddTokenType(syntax.Name, GetSemanticTokenForPotentialTypeSymbol(model.GetSymbolInfo(syntax))); base.VisitVariableAccessSyntax(syntax); } + public override void VisitTypeVariableAccessSyntax(TypeVariableAccessSyntax syntax) + { + AddTokenType(syntax.Name, GetSemanticTokenForPotentialTypeSymbol(model.GetSymbolInfo(syntax))); + base.VisitTypeVariableAccessSyntax(syntax); + } + public override void VisitMetadataDeclarationSyntax(MetadataDeclarationSyntax syntax) { AddTokenType(syntax.Keyword, SemanticTokenType.Keyword); @@ -341,7 +361,7 @@ public override void VisitProviderWithClauseSyntax(ProviderWithClauseSyntax synt public override void VisitAliasAsClauseSyntax(AliasAsClauseSyntax syntax) { AddTokenType(syntax.Keyword, SemanticTokenType.Keyword); - AddTokenType(syntax.Alias, SemanticTokenType.Variable); + AddTokenType(syntax.Alias, SemanticTokenType.Namespace); } public override void VisitCompileTimeImportDeclarationSyntax(CompileTimeImportDeclarationSyntax syntax) @@ -409,5 +429,17 @@ public override void VisitObjectTypePropertySyntax(ObjectTypePropertySyntax synt Visit(syntax.Colon); Visit(syntax.Value); } + + private static SemanticTokenType GetSemanticTokenForPotentialTypeSymbol(Symbol? symbol) => + symbol switch + { + PropertySymbol property => GetSemanticTokenForPotentialTypeSymbol(property.Type), + TypeSymbol or + TypeAliasSymbol or + AmbientTypeSymbol or + ImportedTypeSymbol => SemanticTokenType.Type, + INamespaceSymbol => SemanticTokenType.Namespace, + _ => SemanticTokenType.Variable, + }; } }