in src/Bicep.LangServer/Handlers/BicepHoverHandler.cs [73:171]
private static string? TryGetDescription(SymbolResolutionResult result, WildcardImportSymbol symbol)
=> DescriptionHelper.TryGetFromDecorator(result.Context.Compilation.GetEntrypointSemanticModel(), symbol.EnclosingDeclaration);
private static async Task<MarkedStringsOrMarkupContent?> GetMarkdown(
HoverParams request,
SymbolResolutionResult result,
IModuleDispatcher moduleDispatcher,
IArtifactRegistryProvider moduleRegistryProvider)
{
// all of the generated markdown includes the language id to avoid VS code rendering
// with multiple borders
switch (result.Symbol)
{
case ExtensionNamespaceSymbol extension:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
$"{LanguageConstants.ExtensionKeyword} {extension.Name}", TryGetDescription(result, extension)));
case MetadataSymbol metadata:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
$"metadata {metadata.Name}: {metadata.Type}", TryGetDescription(result, metadata)));
case ParameterSymbol parameter:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
WithTypeModifiers($"param {parameter.Name}: {parameter.Type}", parameter.Type), TryGetDescription(result, parameter)));
case TypeAliasSymbol declaredType:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
WithTypeModifiers($"type {declaredType.Name}: {declaredType.Type}", declaredType.Type), TryGetDescription(result, declaredType)));
case ImportedTypeSymbol importedType:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
WithTypeModifiers($"type {importedType.Name}: {importedType.Type}", importedType.Type),
importedType.Description));
case ImportedVariableSymbol importedVariable:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"var {importedVariable.Name}: {importedVariable.Type}", importedVariable.Description));
case AmbientTypeSymbol ambientType:
return AsMarkdown(MarkdownHelper.CodeBlock(WithTypeModifiers($"type {ambientType.Name}: {ambientType.Type}", ambientType.Type)));
case VariableSymbol variable:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"var {variable.Name}: {variable.Type}", TryGetDescription(result, variable)));
case ResourceSymbol resource:
var docsSuffix = TryGetTypeDocumentationLink(resource) is { } typeDocsLink ? MarkdownHelper.GetDocumentationLink(typeDocsLink) : "";
var description = TryGetDescription(result, resource);
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
$"resource {resource.Name} {(resource.Type is ResourceType ? $"'{resource.Type}'" : resource.Type)}",
$"{MarkdownHelper.AppendNewline(description)}{docsSuffix}"));
case ModuleSymbol module:
return await GetModuleMarkdown(request, result, moduleDispatcher, moduleRegistryProvider, module);
case TestSymbol test:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"test {test.Name}", TryGetDescription(result, test)));
case OutputSymbol output:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
WithTypeModifiers($"output {output.Name}: {output.Type}", output.Type), TryGetDescription(result, output)));
case BuiltInNamespaceSymbol builtInNamespace:
return AsMarkdown(MarkdownHelper.CodeBlock($"{builtInNamespace.Name} namespace"));
case WildcardImportSymbol wildcardImport:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"{wildcardImport.Name} namespace", TryGetDescription(result, wildcardImport)));
case IFunctionSymbol function when result.Origin is FunctionCallSyntaxBase functionCall:
// it's not possible for a non-function call syntax to resolve to a function symbol
// but this simplifies the checks
return GetFunctionMarkdown(function, functionCall, result.Context.Compilation.GetEntrypointSemanticModel());
case DeclaredFunctionSymbol function:
return AsMarkdown(GetFunctionOverloadMarkdown(function.Overload));
case ImportedFunctionSymbol importedFunction:
return AsMarkdown(GetFunctionOverloadMarkdown(importedFunction.Overload));
case PropertySymbol property:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(WithTypeModifiers($"{property.Name}: {property.Type}", property.Type), property.Description));
case LocalVariableSymbol local:
return AsMarkdown(MarkdownHelper.CodeBlock($"{local.Name}: {local.Type}"));
case ParameterAssignmentSymbol parameterAssignment:
if (GetDeclaredParameterMetadata(parameterAssignment) is not ParameterMetadata declaredParamMetadata)
{
return null;
}
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription(
WithTypeModifiers($"param {parameterAssignment.Name}: {declaredParamMetadata.TypeReference.Type}", declaredParamMetadata.TypeReference.Type), declaredParamMetadata.Description));
case AssertSymbol assert:
return AsMarkdown(MarkdownHelper.CodeBlockWithDescription($"assert {assert.Name}: {assert.Type}", TryGetDescription(result, assert)));
default:
return null;
}
}