From a3573528f6bf4bae77eb9f6d6d55e621d5ba38ea Mon Sep 17 00:00:00 2001 From: Armando Andini Date: Fri, 8 Dec 2023 13:36:41 -0300 Subject: [PATCH] Changes based on PR feedback (part 1) --- flags.json | 9 ++ server/src/parser/slangHelpers.ts | 1 - .../documentSymbol/SymbolTreeBuilder.ts | 3 +- .../services/documentSymbol/SymbolVisitor.ts | 13 +-- .../documentSymbol/onDocumentSymbol.ts | 37 +++++-- .../visitors/YulFunctionDefinition.ts | 9 ++ .../services/initialization/featureFlags.ts | 2 +- .../services/initialization/onInitialize.ts | 2 +- ...ighter.ts => EnumDefinitionHighlighter.ts} | 19 ++-- ...ghter.ts => ErrorDefinitionHighlighter.ts} | 19 ++-- .../highlighters/KeywordHighlighter.ts | 103 ------------------ .../LibraryDefinitionHighlighter.ts | 20 ++++ ...inedValueTypeDefinitionHighlighter copy.ts | 21 ++++ .../semanticHighlight/onSemanticTokensFull.ts | 41 +++++-- .../documentSymbol/DocumentSymbols.sol | 6 + .../semanticTokens/full/SemanticTokens.sol | 12 ++ .../documentSymbol/documentSymbol.test.ts | 53 ++++++--- .../textDocument/semanticTokens/full.test.ts | 11 +- 18 files changed, 202 insertions(+), 179 deletions(-) create mode 100644 flags.json create mode 100644 server/src/services/documentSymbol/visitors/YulFunctionDefinition.ts rename server/src/services/semanticHighlight/highlighters/{NumberHighlighter.ts => EnumDefinitionHighlighter.ts} (54%) rename server/src/services/semanticHighlight/highlighters/{StringHighlighter.ts => ErrorDefinitionHighlighter.ts} (54%) delete mode 100644 server/src/services/semanticHighlight/highlighters/KeywordHighlighter.ts create mode 100644 server/src/services/semanticHighlight/highlighters/LibraryDefinitionHighlighter.ts create mode 100644 server/src/services/semanticHighlight/highlighters/UserDefinedValueTypeDefinitionHighlighter copy.ts diff --git a/flags.json b/flags.json new file mode 100644 index 00000000..b5627fc5 --- /dev/null +++ b/flags.json @@ -0,0 +1,9 @@ +{ + "documentSymbol": { + "percent": 0.1 + }, + + "semanticHighlighting": { + "percent": 0.1 + } +} diff --git a/server/src/parser/slangHelpers.ts b/server/src/parser/slangHelpers.ts index 905bcc7b..29c77d27 100644 --- a/server/src/parser/slangHelpers.ts +++ b/server/src/parser/slangHelpers.ts @@ -8,7 +8,6 @@ import { getPlatform } from "../utils/operatingSystem"; export type SlangNode = RuleNode | TokenNode; export type NodeKind = RuleKind | TokenKind; -export type NodeCallback = (node: SlangNodeWrapper) => void; export interface SlangNodeWrapper { textRange: TextRange; diff --git a/server/src/services/documentSymbol/SymbolTreeBuilder.ts b/server/src/services/documentSymbol/SymbolTreeBuilder.ts index bf4aee01..b777a87d 100644 --- a/server/src/services/documentSymbol/SymbolTreeBuilder.ts +++ b/server/src/services/documentSymbol/SymbolTreeBuilder.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ import { DocumentSymbol } from "vscode-languageserver-types"; import _ from "lodash"; @@ -30,7 +31,7 @@ export class SymbolTreeBuilder { throw new Error("Attempting to close a symbol but none is open"); } - lastSymbol.children?.push(symbol); + lastSymbol.children!.push(symbol); } } diff --git a/server/src/services/documentSymbol/SymbolVisitor.ts b/server/src/services/documentSymbol/SymbolVisitor.ts index 8965cc22..2b8d1dff 100644 --- a/server/src/services/documentSymbol/SymbolVisitor.ts +++ b/server/src/services/documentSymbol/SymbolVisitor.ts @@ -2,7 +2,7 @@ import { SymbolKind } from "vscode-languageserver-types"; import _ from "lodash"; import { RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; -import { RuleNode, TokenNode } from "@nomicfoundation/slang/cst"; +import { TokenNode } from "@nomicfoundation/slang/cst"; import { TextDocument } from "vscode-languageserver-textdocument"; import { Cursor } from "@nomicfoundation/slang/cursor"; import { slangToVSCodeRange } from "../../parser/slangHelpers"; @@ -18,7 +18,7 @@ export abstract class SymbolVisitor { public symbolBuilder: SymbolTreeBuilder ) {} - public onRuleNode(node: RuleNode, cursor: Cursor): void { + public onRuleNode(cursor: Cursor): void { const range = slangToVSCodeRange(this.document, cursor.textRange); let symbolName = "-"; @@ -28,15 +28,12 @@ export abstract class SymbolVisitor { const childCursor = cursor.spawn(); do { - const identifierNode: TokenNode | null = childCursor.findTokenWithKind([ + const nameToken: TokenNode | null = childCursor.findTokenWithKind([ this.nameTokenKind, ]); - if ( - identifierNode && - _.last(childCursor.pathRuleNodes).kind === this.ruleKind - ) { - symbolName = identifierNode.text; + if (nameToken && childCursor.pathRuleNodes.length === 1) { + symbolName = nameToken.text; selectionRange = slangToVSCodeRange( this.document, childCursor.textRange diff --git a/server/src/services/documentSymbol/onDocumentSymbol.ts b/server/src/services/documentSymbol/onDocumentSymbol.ts index 7f2fde40..cf8e49ac 100644 --- a/server/src/services/documentSymbol/onDocumentSymbol.ts +++ b/server/src/services/documentSymbol/onDocumentSymbol.ts @@ -30,12 +30,13 @@ import { ModifierDefinition } from "./visitors/ModifierDefinition"; import { ReceiveFunctionDefinition } from "./visitors/ReceiveFunctionDefinition"; import { UserDefinedValueTypeDefinition } from "./visitors/UserDefinedValueTypeDefinition"; import { SymbolVisitor } from "./SymbolVisitor"; +import { YulFunctionDefinition } from "./visitors/YulFunctionDefinition"; export function onDocumentSymbol(serverState: ServerState) { return async ( params: DocumentSymbolParams ): Promise => { - const { telemetry, solcVersions } = serverState; + const { telemetry } = serverState; return telemetry.trackTimingSync("onDocumentSymbol", (transaction) => { const { uri } = params.textDocument; @@ -53,11 +54,22 @@ export function onDocumentSymbol(serverState: ServerState) { const { versionPragmas } = analyze(text); span.finish(); - versionPragmas.push("<= 0.8.19"); // latest supported by slang + const versions = Language.supportedVersions(); + versionPragmas.push( + `>= ${versions[0]}`, + `<= ${versions[versions.length - 1]}` + ); + + const solcVersion = semver.maxSatisfying( + Language.supportedVersions(), + versionPragmas.join(" ") + ); - const solcVersion = - semver.maxSatisfying(solcVersions, versionPragmas.join(" ")) || - _.last(solcVersions); + if (solcVersion === null) { + throw new Error( + `No supported solidity version found. Supported versions: ${Language.supportedVersions()}, pragma directives: ${versionPragmas}` + ); + } // Parse using slang span = transaction.startChild({ op: "slang-parsing" }); @@ -76,7 +88,7 @@ export function onDocumentSymbol(serverState: ServerState) { e.toErrorReport(uri, text, false) ); - throw new Error(`Slang parsing error: ${strings.join("")}`); + throw new Error(`Slang parsing error:\n${strings.join("\n")}`); } const builder = new SymbolTreeBuilder(); @@ -99,6 +111,7 @@ export function onDocumentSymbol(serverState: ServerState) { new ModifierDefinition(document, builder), new ReceiveFunctionDefinition(document, builder), new UserDefinedValueTypeDefinition(document, builder), + new YulFunctionDefinition(document, builder), ]; const indexedVisitors = _.keyBy(visitors, "ruleKind"); @@ -107,10 +120,20 @@ export function onDocumentSymbol(serverState: ServerState) { const ruleKinds = visitors.map((v) => v.ruleKind); let node: RuleNode; + // Useful to keep this here for development + // const kursor: Cursor = parseTree.cursor.clone(); + // do { + // console.log( + // `${" ".repeat(kursor.pathRuleNodes.length)}${kursor.node.kind}(${ + // ["R", "T"][kursor.node.type] + // }): ${kursor.node?.text ?? ""}` + // ); + // } while (kursor.goToNext()); + span = transaction.startChild({ op: "walk-generate-symbols" }); while ((node = cursor.findRuleWithKind(ruleKinds)) !== null) { const visitor: SymbolVisitor = indexedVisitors[node.kind]; - visitor.onRuleNode(node, cursor); + visitor.onRuleNode(cursor); cursor.goToNext(); } diff --git a/server/src/services/documentSymbol/visitors/YulFunctionDefinition.ts b/server/src/services/documentSymbol/visitors/YulFunctionDefinition.ts new file mode 100644 index 00000000..e1565c83 --- /dev/null +++ b/server/src/services/documentSymbol/visitors/YulFunctionDefinition.ts @@ -0,0 +1,9 @@ +import { SymbolKind } from "vscode-languageserver-types"; +import { RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; +import { SymbolVisitor } from "../SymbolVisitor"; + +export class YulFunctionDefinition extends SymbolVisitor { + public ruleKind = RuleKind.YulFunctionDefinition; + public symbolKind = SymbolKind.Function; + public nameTokenKind = TokenKind.YulIdentifier; +} diff --git a/server/src/services/initialization/featureFlags.ts b/server/src/services/initialization/featureFlags.ts index 3d7a7b1c..0058f801 100644 --- a/server/src/services/initialization/featureFlags.ts +++ b/server/src/services/initialization/featureFlags.ts @@ -29,7 +29,7 @@ export async function fetchFeatureFlags( try { return await got .get( - "https://raw.githubusercontent.com/antico5/hardhat-vscode/flags/flags.json", + "https://raw.githubusercontent.com/NomicFoundation/hardhat-vscode/development/flags.json", { timeout: 2000, } diff --git a/server/src/services/initialization/onInitialize.ts b/server/src/services/initialization/onInitialize.ts index 62413bd2..cba45bcc 100644 --- a/server/src/services/initialization/onInitialize.ts +++ b/server/src/services/initialization/onInitialize.ts @@ -45,7 +45,7 @@ export const onInitialize = (serverState: ServerState) => { }); // fetch available solidity versions and feature flags - const [flags] = await Promise.all([ + const [flags, _] = await Promise.all([ fetchFeatureFlags(serverState), updateAvailableSolcVersions(serverState), ]); diff --git a/server/src/services/semanticHighlight/highlighters/NumberHighlighter.ts b/server/src/services/semanticHighlight/highlighters/EnumDefinitionHighlighter.ts similarity index 54% rename from server/src/services/semanticHighlight/highlighters/NumberHighlighter.ts rename to server/src/services/semanticHighlight/highlighters/EnumDefinitionHighlighter.ts index 09852474..ff239114 100644 --- a/server/src/services/semanticHighlight/highlighters/NumberHighlighter.ts +++ b/server/src/services/semanticHighlight/highlighters/EnumDefinitionHighlighter.ts @@ -1,25 +1,20 @@ import { SemanticTokenTypes } from "vscode-languageserver-protocol"; -import { TokenKind } from "@nomicfoundation/slang/kinds"; import { NodeType } from "@nomicfoundation/slang/cst"; +import { RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; import { HighlightVisitor } from "../HighlightVisitor"; import { SlangNodeWrapper } from "../../../parser/slangHelpers"; -const numberKinds = new Set([ - TokenKind.HexLiteral, - TokenKind.YulHexLiteral, - TokenKind.DecimalLiteral, -]); - -// Highlights numbers -export class NumberHighlighter extends HighlightVisitor { - public tokenKinds = numberKinds; +export class EnumDefinitionHighlighter extends HighlightVisitor { + public tokenKinds = new Set([TokenKind.Identifier]); public enter(nodeWrapper: SlangNodeWrapper): void { + const ancestors = nodeWrapper.pathRuleNodes; if ( nodeWrapper.type === NodeType.Token && - numberKinds.has(nodeWrapper.kind as TokenKind) + nodeWrapper.kind === TokenKind.Identifier && + ancestors[ancestors.length - 1]?.kind === RuleKind.EnumDefinition ) { - this.tokenBuilder.addToken(nodeWrapper, SemanticTokenTypes.number); + this.tokenBuilder.addToken(nodeWrapper, SemanticTokenTypes.type); } } } diff --git a/server/src/services/semanticHighlight/highlighters/StringHighlighter.ts b/server/src/services/semanticHighlight/highlighters/ErrorDefinitionHighlighter.ts similarity index 54% rename from server/src/services/semanticHighlight/highlighters/StringHighlighter.ts rename to server/src/services/semanticHighlight/highlighters/ErrorDefinitionHighlighter.ts index 9937e472..76b46d8c 100644 --- a/server/src/services/semanticHighlight/highlighters/StringHighlighter.ts +++ b/server/src/services/semanticHighlight/highlighters/ErrorDefinitionHighlighter.ts @@ -1,25 +1,20 @@ import { SemanticTokenTypes } from "vscode-languageserver-protocol"; -import { TokenKind } from "@nomicfoundation/slang/kinds"; import { NodeType } from "@nomicfoundation/slang/cst"; +import { RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; import { HighlightVisitor } from "../HighlightVisitor"; import { SlangNodeWrapper } from "../../../parser/slangHelpers"; -const stringKinds = new Set([ - TokenKind.HexStringLiteral, - TokenKind.AsciiStringLiteral, - TokenKind.UnicodeStringLiteral, -]); - -// Highlights strings -export class StringHighlighter extends HighlightVisitor { - public tokenKinds = stringKinds; +export class ErrorDefinitionHighlighter extends HighlightVisitor { + public tokenKinds = new Set([TokenKind.Identifier]); public enter(nodeWrapper: SlangNodeWrapper): void { + const ancestors = nodeWrapper.pathRuleNodes; if ( nodeWrapper.type === NodeType.Token && - stringKinds.has(nodeWrapper.kind as TokenKind) + nodeWrapper.kind === TokenKind.Identifier && + ancestors[ancestors.length - 1]?.kind === RuleKind.ErrorDefinition ) { - this.tokenBuilder.addToken(nodeWrapper, SemanticTokenTypes.string); + this.tokenBuilder.addToken(nodeWrapper, SemanticTokenTypes.type); } } } diff --git a/server/src/services/semanticHighlight/highlighters/KeywordHighlighter.ts b/server/src/services/semanticHighlight/highlighters/KeywordHighlighter.ts deleted file mode 100644 index e44e40c4..00000000 --- a/server/src/services/semanticHighlight/highlighters/KeywordHighlighter.ts +++ /dev/null @@ -1,103 +0,0 @@ -import { SemanticTokenTypes } from "vscode-languageserver-protocol"; -import { TokenKind } from "@nomicfoundation/slang/kinds"; -import { NodeType } from "@nomicfoundation/slang/cst"; -import { HighlightVisitor } from "../HighlightVisitor"; -import { SlangNodeWrapper } from "../../../parser/slangHelpers"; - -const keywordKinds = new Set([ - TokenKind.ABICoderKeyword, - TokenKind.AbstractKeyword, - TokenKind.AddressKeyword, - TokenKind.AnonymousKeyword, - TokenKind.AsKeyword, - TokenKind.AssemblyKeyword, - TokenKind.BoolKeyword, - TokenKind.BreakKeyword, - TokenKind.CalldataKeyword, - TokenKind.CaseKeyword, - TokenKind.CatchKeyword, - TokenKind.ConstantKeyword, - TokenKind.ConstructorKeyword, - TokenKind.ContinueKeyword, - TokenKind.ContractKeyword, - TokenKind.DaysKeyword, - TokenKind.DefaultKeyword, - TokenKind.DeleteKeyword, - TokenKind.DoKeyword, - TokenKind.ElseKeyword, - TokenKind.EmitKeyword, - TokenKind.EnumKeyword, - TokenKind.ErrorKeyword, - TokenKind.EtherKeyword, - TokenKind.EventKeyword, - TokenKind.ExperimentalKeyword, - TokenKind.ExternalKeyword, - TokenKind.FallbackKeyword, - TokenKind.FalseKeyword, - TokenKind.FinneyKeyword, - TokenKind.ForKeyword, - TokenKind.FromKeyword, - TokenKind.FunctionKeyword, - TokenKind.GlobalKeyword, - TokenKind.GweiKeyword, - TokenKind.HoursKeyword, - TokenKind.IfKeyword, - TokenKind.ImmutableKeyword, - TokenKind.ImportKeyword, - TokenKind.IndexedKeyword, - TokenKind.InterfaceKeyword, - TokenKind.InternalKeyword, - TokenKind.IsKeyword, - TokenKind.LeaveKeyword, - TokenKind.LetKeyword, - TokenKind.LibraryKeyword, - TokenKind.MappingKeyword, - TokenKind.MemoryKeyword, - TokenKind.MinutesKeyword, - TokenKind.ModifierKeyword, - TokenKind.NewKeyword, - TokenKind.OverrideKeyword, - TokenKind.PayableKeyword, - TokenKind.PragmaKeyword, - TokenKind.PrivateKeyword, - TokenKind.PublicKeyword, - TokenKind.PureKeyword, - TokenKind.ReceiveKeyword, - TokenKind.ReturnKeyword, - TokenKind.ReturnsKeyword, - TokenKind.RevertKeyword, - TokenKind.SecondsKeyword, - TokenKind.SolidityKeyword, - TokenKind.StorageKeyword, - TokenKind.StringKeyword, - TokenKind.StructKeyword, - TokenKind.SwitchKeyword, - TokenKind.SzaboKeyword, - TokenKind.ThrowKeyword, - TokenKind.TrueKeyword, - TokenKind.TryKeyword, - TokenKind.TypeKeyword, - TokenKind.UncheckedKeyword, - TokenKind.UnsignedIntegerType, - TokenKind.UsingKeyword, - TokenKind.ViewKeyword, - TokenKind.VirtualKeyword, - TokenKind.WeeksKeyword, - TokenKind.WeiKeyword, - TokenKind.WhileKeyword, - TokenKind.YearsKeyword, -]); - -// Highlights keywords -export class KeywordHighlighter extends HighlightVisitor { - public tokenKinds = keywordKinds; - - public enter(nodeWrapper: SlangNodeWrapper): void { - if ( - nodeWrapper.type === NodeType.Token && - keywordKinds.has(nodeWrapper.kind as TokenKind) - ) { - this.tokenBuilder.addToken(nodeWrapper, SemanticTokenTypes.keyword); - } - } -} diff --git a/server/src/services/semanticHighlight/highlighters/LibraryDefinitionHighlighter.ts b/server/src/services/semanticHighlight/highlighters/LibraryDefinitionHighlighter.ts new file mode 100644 index 00000000..5cc2ec6c --- /dev/null +++ b/server/src/services/semanticHighlight/highlighters/LibraryDefinitionHighlighter.ts @@ -0,0 +1,20 @@ +import { SemanticTokenTypes } from "vscode-languageserver-protocol"; +import { NodeType } from "@nomicfoundation/slang/cst"; +import { RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; +import { HighlightVisitor } from "../HighlightVisitor"; +import { SlangNodeWrapper } from "../../../parser/slangHelpers"; + +export class LibraryDefinitionHighlighter extends HighlightVisitor { + public tokenKinds = new Set([TokenKind.Identifier]); + + public enter(nodeWrapper: SlangNodeWrapper): void { + const ancestors = nodeWrapper.pathRuleNodes; + if ( + nodeWrapper.type === NodeType.Token && + nodeWrapper.kind === TokenKind.Identifier && + ancestors[ancestors.length - 1]?.kind === RuleKind.LibraryDefinition + ) { + this.tokenBuilder.addToken(nodeWrapper, SemanticTokenTypes.type); + } + } +} diff --git a/server/src/services/semanticHighlight/highlighters/UserDefinedValueTypeDefinitionHighlighter copy.ts b/server/src/services/semanticHighlight/highlighters/UserDefinedValueTypeDefinitionHighlighter copy.ts new file mode 100644 index 00000000..96a6f7bf --- /dev/null +++ b/server/src/services/semanticHighlight/highlighters/UserDefinedValueTypeDefinitionHighlighter copy.ts @@ -0,0 +1,21 @@ +import { SemanticTokenTypes } from "vscode-languageserver-protocol"; +import { NodeType } from "@nomicfoundation/slang/cst"; +import { RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; +import { HighlightVisitor } from "../HighlightVisitor"; +import { SlangNodeWrapper } from "../../../parser/slangHelpers"; + +export class UserDefinedValueTypeDefinitionHighlighter extends HighlightVisitor { + public tokenKinds = new Set([TokenKind.Identifier]); + + public enter(nodeWrapper: SlangNodeWrapper): void { + const ancestors = nodeWrapper.pathRuleNodes; + if ( + nodeWrapper.type === NodeType.Token && + nodeWrapper.kind === TokenKind.Identifier && + ancestors[ancestors.length - 1]?.kind === + RuleKind.UserDefinedValueTypeDefinition + ) { + this.tokenBuilder.addToken(nodeWrapper, SemanticTokenTypes.type); + } + } +} diff --git a/server/src/services/semanticHighlight/onSemanticTokensFull.ts b/server/src/services/semanticHighlight/onSemanticTokensFull.ts index 943bf6e8..700ca7c4 100644 --- a/server/src/services/semanticHighlight/onSemanticTokensFull.ts +++ b/server/src/services/semanticHighlight/onSemanticTokensFull.ts @@ -15,9 +15,6 @@ import { TokenNode } from "@nomicfoundation/slang/cst"; import { ServerState } from "../../types"; import { CustomTypeHighlighter } from "./highlighters/CustomTypeHighlighter"; import { SemanticTokensBuilder } from "./SemanticTokensBuilder"; -import { KeywordHighlighter } from "./highlighters/KeywordHighlighter"; -import { NumberHighlighter } from "./highlighters/NumberHighlighter"; -import { StringHighlighter } from "./highlighters/StringHighlighter"; import { FunctionDefinitionHighlighter } from "./highlighters/FunctionDefinitionHighlighter"; import { FunctionCallHighlighter } from "./highlighters/FunctionCallHighlighter"; import { EventEmissionHighlighter } from "./highlighters/EventEmissionHighlighter"; @@ -26,12 +23,16 @@ import { ContractDefinitionHighlighter } from "./highlighters/ContractDefinition import { InterfaceDefinitionHighlighter } from "./highlighters/InterfaceDefinitionHighlighter"; import { StructDefinitionHighlighter } from "./highlighters/StructDefinitionHighlighter"; import { HighlightVisitor } from "./HighlightVisitor"; +import { UserDefinedValueTypeDefinitionHighlighter } from "./highlighters/UserDefinedValueTypeDefinitionHighlighter copy"; +import { EnumDefinitionHighlighter } from "./highlighters/EnumDefinitionHighlighter"; +import { ErrorDefinitionHighlighter } from "./highlighters/ErrorDefinitionHighlighter"; +import { LibraryDefinitionHighlighter } from "./highlighters/LibraryDefinitionHighlighter"; const emptyResponse: SemanticTokens = { data: [] }; export function onSemanticTokensFull(serverState: ServerState) { return (params: SemanticTokensParams): SemanticTokens => { - const { telemetry, logger, solcVersions } = serverState; + const { telemetry, logger } = serverState; return ( telemetry.trackTimingSync("onSemanticTokensFull", (transaction) => { @@ -55,11 +56,26 @@ export function onSemanticTokensFull(serverState: ServerState) { const { versionPragmas } = analyze(text); span.finish(); - versionPragmas.push("<= 0.8.19"); // latest supported by slang + const versions = Language.supportedVersions(); + versionPragmas.push( + `>= ${versions[0]}`, + `<= ${versions[versions.length - 1]}` + ); - const solcVersion = - semver.maxSatisfying(solcVersions, versionPragmas.join(" ")) || - _.last(solcVersions); + const solcVersion = semver.maxSatisfying( + Language.supportedVersions(), + versionPragmas.join(" ") + ); + + if (solcVersion === null) { + logger.error( + `No supported solidity version found. Supported versions: ${Language.supportedVersions()}, pragma directives: ${versionPragmas}` + ); + return { + status: "internal_error", + result: emptyResponse, + }; + } try { // Parse using slang @@ -79,7 +95,7 @@ export function onSemanticTokensFull(serverState: ServerState) { const strings = parseOutput.errors.map((e: any) => e.toErrorReport(uri, text, false) ); - logger.error(strings.join("")); + logger.error(`Slang parsing error:\n${strings.join("\n")}`); return { status: "internal_error", @@ -92,9 +108,6 @@ export function onSemanticTokensFull(serverState: ServerState) { const visitors = [ new CustomTypeHighlighter(document, builder), - new KeywordHighlighter(document, builder), - new NumberHighlighter(document, builder), - new StringHighlighter(document, builder), new FunctionDefinitionHighlighter(document, builder), new FunctionCallHighlighter(document, builder), new EventEmissionHighlighter(document, builder), @@ -102,6 +115,10 @@ export function onSemanticTokensFull(serverState: ServerState) { new ContractDefinitionHighlighter(document, builder), new InterfaceDefinitionHighlighter(document, builder), new StructDefinitionHighlighter(document, builder), + new UserDefinedValueTypeDefinitionHighlighter(document, builder), + new EnumDefinitionHighlighter(document, builder), + new ErrorDefinitionHighlighter(document, builder), + new LibraryDefinitionHighlighter(document, builder), ]; // Visit the CST diff --git a/test/protocol/projects/hardhat/contracts/documentSymbol/DocumentSymbols.sol b/test/protocol/projects/hardhat/contracts/documentSymbol/DocumentSymbols.sol index d09e073e..97cd7179 100644 --- a/test/protocol/projects/hardhat/contracts/documentSymbol/DocumentSymbols.sol +++ b/test/protocol/projects/hardhat/contracts/documentSymbol/DocumentSymbols.sol @@ -78,6 +78,12 @@ contract testContract { TestStruct memory afterUTF8; afterUTF8; anotherFunction(); + + assembly { + function mult(a, b) -> result { + result := mul(a, b) + } + } } function anotherFunction() public pure {} diff --git a/test/protocol/projects/hardhat/contracts/semanticTokens/full/SemanticTokens.sol b/test/protocol/projects/hardhat/contracts/semanticTokens/full/SemanticTokens.sol index 443abb91..59a8773b 100644 --- a/test/protocol/projects/hardhat/contracts/semanticTokens/full/SemanticTokens.sol +++ b/test/protocol/projects/hardhat/contracts/semanticTokens/full/SemanticTokens.sol @@ -2,6 +2,8 @@ pragma solidity ^0.8.8; +type CustomType is uint256; + interface TestInterface {} struct TestStruct { @@ -10,6 +12,16 @@ struct TestStruct { address anAddress; } +enum TestEnum { + A, + B, + C +} + +error CustomError(); + +library MyLibrary {} + contract testContract { event TestEvent( testContract contractAsEventParam, TestInterface interfaceAsEventParam, TestStruct structAsEventParam diff --git a/test/protocol/test/textDocument/documentSymbol/documentSymbol.test.ts b/test/protocol/test/textDocument/documentSymbol/documentSymbol.test.ts index f8c63c05..53ef7cde 100644 --- a/test/protocol/test/textDocument/documentSymbol/documentSymbol.test.ts +++ b/test/protocol/test/textDocument/documentSymbol/documentSymbol.test.ts @@ -734,6 +734,31 @@ describe('[hardhat] documentSymbol', () => { }, }, }, + { + children: [], + kind: 12, + name: 'mult', + range: { + start: { + line: 82, + character: 0, + }, + end: { + line: 85, + character: 0, + }, + }, + selectionRange: { + start: { + line: 82, + character: 21, + }, + end: { + line: 82, + character: 25, + }, + }, + }, ], kind: 12, name: 'testFunction', @@ -743,7 +768,7 @@ describe('[hardhat] documentSymbol', () => { character: 0, }, end: { - line: 81, + line: 87, character: 0, }, }, @@ -764,21 +789,21 @@ describe('[hardhat] documentSymbol', () => { name: 'anotherFunction', range: { start: { - line: 81, + line: 87, character: 0, }, end: { - line: 83, + line: 89, character: 0, }, }, selectionRange: { start: { - line: 82, + line: 88, character: 13, }, end: { - line: 82, + line: 88, character: 28, }, }, @@ -789,21 +814,21 @@ describe('[hardhat] documentSymbol', () => { name: 'fallback', range: { start: { - line: 83, + line: 89, character: 0, }, end: { - line: 85, + line: 91, character: 0, }, }, selectionRange: { start: { - line: 84, + line: 90, character: 4, }, end: { - line: 84, + line: 90, character: 12, }, }, @@ -814,21 +839,21 @@ describe('[hardhat] documentSymbol', () => { name: 'receive', range: { start: { - line: 85, + line: 91, character: 0, }, end: { - line: 87, + line: 93, character: 0, }, }, selectionRange: { start: { - line: 86, + line: 92, character: 4, }, end: { - line: 86, + line: 92, character: 11, }, }, @@ -842,7 +867,7 @@ describe('[hardhat] documentSymbol', () => { character: 0, }, end: { - line: 88, + line: 94, character: 0, }, }, diff --git a/test/protocol/test/textDocument/semanticTokens/full.test.ts b/test/protocol/test/textDocument/semanticTokens/full.test.ts index 6b52b58d..1a3bf9a2 100644 --- a/test/protocol/test/textDocument/semanticTokens/full.test.ts +++ b/test/protocol/test/textDocument/semanticTokens/full.test.ts @@ -27,13 +27,10 @@ describe('[hardhat] semanticTokens/full', () => { expect(semanticTokens).to.deep.equal({ data: [ - 2, 0, 6, 0, 0, 0, 7, 8, 0, 0, 2, 0, 9, 0, 0, 0, 10, 13, 2, 0, 2, 0, 6, 0, 0, 0, 7, 10, 2, 0, 1, 4, 7, 0, 0, 1, - 4, 6, 0, 0, 1, 4, 7, 0, 0, 3, 0, 8, 0, 0, 0, 9, 12, 2, 0, 1, 4, 5, 0, 0, 0, 6, 9, 2, 0, 1, 8, 12, 2, 0, 0, 35, - 13, 2, 0, 0, 37, 10, 2, 0, 3, 4, 12, 2, 0, 2, 4, 13, 2, 0, 2, 4, 10, 2, 0, 2, 4, 7, 0, 0, 0, 18, 4, 1, 0, 0, 7, - 3, 1, 0, 2, 4, 6, 0, 0, 0, 17, 6, 3, 0, 2, 4, 8, 0, 0, 0, 9, 12, 4, 0, 1, 8, 12, 2, 0, 1, 8, 13, 2, 0, 1, 8, 10, - 2, 0, 0, 11, 6, 0, 0, 1, 6, 6, 0, 0, 1, 8, 12, 2, 0, 2, 8, 13, 2, 0, 1, 8, 10, 2, 0, 0, 11, 6, 0, 0, 8, 8, 4, 0, - 0, 0, 5, 9, 2, 0, 4, 8, 10, 2, 0, 0, 11, 6, 0, 0, 2, 8, 15, 4, 0, 3, 4, 8, 0, 0, 0, 9, 15, 4, 0, 0, 18, 6, 0, 0, - 0, 7, 4, 0, 0, + 4, 5, 10, 2, 0, 2, 10, 13, 2, 0, 2, 7, 10, 2, 0, 6, 5, 8, 2, 0, 6, 6, 11, 2, 0, 2, 8, 9, 2, 0, 2, 9, 12, 2, 0, + 1, 10, 9, 2, 0, 1, 8, 12, 2, 0, 0, 35, 13, 2, 0, 0, 37, 10, 2, 0, 3, 4, 12, 2, 0, 2, 4, 13, 2, 0, 2, 4, 10, 2, + 0, 6, 13, 12, 4, 0, 1, 8, 12, 2, 0, 1, 8, 13, 2, 0, 1, 8, 10, 2, 0, 2, 8, 12, 2, 0, 2, 8, 13, 2, 0, 1, 8, 10, 2, + 0, 8, 13, 9, 2, 0, 4, 8, 10, 2, 0, 2, 8, 15, 4, 0, 3, 13, 15, 4, 0, ], }) })