diff --git a/package.json b/package.json index 083a528b..629511ce 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,15 @@ "bugs": { "url": "https://github.com/NomicFoundation/hardhat-vscode/issues" }, + "_scripts_comment_": [ + "To support the CI on testing an ugly hack is needed to force install the", + "windows ia32 version of the solidity analyzer. This is the architecture", + "that vscode extension host claims to run under, though the windows arch", + "according to node will be x64. This hack is in the root package.json as", + "a postinstall script.", + "npm install --no-save --ignore-scripts --force @nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1 @nomicfoundation/slang-win32-ia32-msvc@0.10.1" + ], "scripts": { - "postinstall": "npm install --no-save --ignore-scripts --force @nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.1 @nomicfoundation/slang-win32-ia32-msvc@0.10.1", "build": "tsc -b ./client/tsconfig.json && tsc -b ./server/tsconfig.build.json && tsc -b ./coc/tsconfig.json && tsc -b", "watch": "concurrently -n client,server \"tsc -b -w ./client/tsconfig.json\" \"tsc -b -w ./server/tsconfig.build.json\"", "test:unit": "npm -w server run test", diff --git a/server/src/services/documentSymbol/onDocumentSymbol.ts b/server/src/services/documentSymbol/onDocumentSymbol.ts index cf8e49ac..69c0cd83 100644 --- a/server/src/services/documentSymbol/onDocumentSymbol.ts +++ b/server/src/services/documentSymbol/onDocumentSymbol.ts @@ -11,6 +11,7 @@ import { ProductionKind } from "@nomicfoundation/slang/kinds"; import { Cursor } from "@nomicfoundation/slang/cursor"; import { RuleNode } from "@nomicfoundation/slang/cst"; import { ServerState } from "../../types"; +import { SlangNode } from "../../parser/slangHelpers"; import { SymbolTreeBuilder } from "./SymbolTreeBuilder"; import { StructDefinition } from "./visitors/StructDefinition"; import { StructMember } from "./visitors/StructMember"; @@ -31,6 +32,7 @@ import { ReceiveFunctionDefinition } from "./visitors/ReceiveFunctionDefinition" import { UserDefinedValueTypeDefinition } from "./visitors/UserDefinedValueTypeDefinition"; import { SymbolVisitor } from "./SymbolVisitor"; import { YulFunctionDefinition } from "./visitors/YulFunctionDefinition"; +import { UnnamedFunctionDefinition } from "./visitors/UnnamedFunctionDefinition"; export function onDocumentSymbol(serverState: ServerState) { return async ( @@ -80,17 +82,9 @@ export function onDocumentSymbol(serverState: ServerState) { document.getText() ); - const parseTree = parseOutput.parseTree; + const parseTree: SlangNode = parseOutput.parseTree; span.finish(); - if (parseTree === null) { - const strings = parseOutput.errors.map((e: any) => - e.toErrorReport(uri, text, false) - ); - - throw new Error(`Slang parsing error:\n${strings.join("\n")}`); - } - const builder = new SymbolTreeBuilder(); const visitors: SymbolVisitor[] = [ @@ -112,6 +106,7 @@ export function onDocumentSymbol(serverState: ServerState) { new ReceiveFunctionDefinition(document, builder), new UserDefinedValueTypeDefinition(document, builder), new YulFunctionDefinition(document, builder), + new UnnamedFunctionDefinition(document, builder), ]; const indexedVisitors = _.keyBy(visitors, "ruleKind"); diff --git a/server/src/services/documentSymbol/visitors/UnnamedFunctionDefinition.ts b/server/src/services/documentSymbol/visitors/UnnamedFunctionDefinition.ts new file mode 100644 index 00000000..54bdcfc5 --- /dev/null +++ b/server/src/services/documentSymbol/visitors/UnnamedFunctionDefinition.ts @@ -0,0 +1,9 @@ +import { SymbolKind } from "vscode-languageserver-types"; +import { RuleKind, TokenKind } from "@nomicfoundation/slang/kinds"; +import { SymbolVisitor } from "../SymbolVisitor"; + +export class UnnamedFunctionDefinition extends SymbolVisitor { + public ruleKind = RuleKind.UnnamedFunctionDefinition; + public symbolKind = SymbolKind.Function; + public nameTokenKind = TokenKind.FunctionKeyword; +} diff --git a/server/src/services/semanticHighlight/onSemanticTokensFull.ts b/server/src/services/semanticHighlight/onSemanticTokensFull.ts index 700ca7c4..9f98f969 100644 --- a/server/src/services/semanticHighlight/onSemanticTokensFull.ts +++ b/server/src/services/semanticHighlight/onSemanticTokensFull.ts @@ -13,6 +13,7 @@ import { ProductionKind, TokenKind } from "@nomicfoundation/slang/kinds"; import { Cursor } from "@nomicfoundation/slang/cursor"; import { TokenNode } from "@nomicfoundation/slang/cst"; import { ServerState } from "../../types"; +import { SlangNode } from "../../parser/slangHelpers"; import { CustomTypeHighlighter } from "./highlighters/CustomTypeHighlighter"; import { SemanticTokensBuilder } from "./SemanticTokensBuilder"; import { FunctionDefinitionHighlighter } from "./highlighters/FunctionDefinitionHighlighter"; @@ -87,22 +88,9 @@ export function onSemanticTokensFull(serverState: ServerState) { document.getText() ); - const parseTree = parseOutput.parseTree; + const parseTree: SlangNode = parseOutput.parseTree; span.finish(); - if (parseTree === null) { - logger.error("Slang parsing error"); - const strings = parseOutput.errors.map((e: any) => - e.toErrorReport(uri, text, false) - ); - logger.error(`Slang parsing error:\n${strings.join("\n")}`); - - return { - status: "internal_error", - result: emptyResponse, - }; - } - // Register visitors const builder = new SemanticTokensBuilder(document); diff --git a/test/protocol/projects/projectless/src/documentSymbol/UnnamedFunction.sol b/test/protocol/projects/projectless/src/documentSymbol/UnnamedFunction.sol new file mode 100644 index 00000000..ab9e6fd1 --- /dev/null +++ b/test/protocol/projects/projectless/src/documentSymbol/UnnamedFunction.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-3.0 + +pragma solidity 0.4.11; + +contract UnnamedTest { + function() payable {} +} diff --git a/test/protocol/test/textDocument/documentSymbol/documentSymbol.test.ts b/test/protocol/test/textDocument/documentSymbol/documentSymbol.test.ts index 53ef7cde..14216fca 100644 --- a/test/protocol/test/textDocument/documentSymbol/documentSymbol.test.ts +++ b/test/protocol/test/textDocument/documentSymbol/documentSymbol.test.ts @@ -885,3 +885,77 @@ describe('[hardhat] documentSymbol', () => { ]) }) }) + +describe('[projectless] documentSymbol', () => { + let testPath: string + + before(async () => { + client = await getInitializedClient() + + testPath = getProjectPath('projectless/src/documentSymbol/UnnamedFunction.sol') + + await client.openDocument(testPath) + }) + + after(async () => { + client.closeAllDocuments() + }) + + test('supports unnamed function definition', async function () { + const symbols = await client.getDocumentSymbols(toUri(testPath)) + + expect(symbols).to.deep.equal([ + { + children: [ + { + children: [], + kind: 12, + name: 'function', + range: { + start: { + line: 5, + character: 0, + }, + end: { + line: 6, + character: 0, + }, + }, + selectionRange: { + start: { + line: 5, + character: 4, + }, + end: { + line: 5, + character: 12, + }, + }, + }, + ], + kind: 5, + name: 'UnnamedTest', + range: { + start: { + line: 3, + character: 0, + }, + end: { + line: 7, + character: 0, + }, + }, + selectionRange: { + start: { + line: 4, + character: 9, + }, + end: { + line: 4, + character: 20, + }, + }, + }, + ]) + }) +})