Skip to content

Commit

Permalink
Changes based on PR feedback (part 1)
Browse files Browse the repository at this point in the history
  • Loading branch information
antico5 committed Dec 8, 2023
1 parent c5dcf84 commit a357352
Show file tree
Hide file tree
Showing 18 changed files with 202 additions and 179 deletions.
9 changes: 9 additions & 0 deletions flags.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"documentSymbol": {
"percent": 0.1
},

"semanticHighlighting": {
"percent": 0.1
}
}
1 change: 0 additions & 1 deletion server/src/parser/slangHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion server/src/services/documentSymbol/SymbolTreeBuilder.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { DocumentSymbol } from "vscode-languageserver-types";
import _ from "lodash";

Expand Down Expand Up @@ -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);
}
}

Expand Down
13 changes: 5 additions & 8 deletions server/src/services/documentSymbol/SymbolVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand All @@ -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 = "-";
Expand All @@ -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
Expand Down
37 changes: 30 additions & 7 deletions server/src/services/documentSymbol/onDocumentSymbol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<DocumentSymbol[] | SymbolInformation[] | null> => {
const { telemetry, solcVersions } = serverState;
const { telemetry } = serverState;
return telemetry.trackTimingSync("onDocumentSymbol", (transaction) => {
const { uri } = params.textDocument;

Expand All @@ -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" });
Expand All @@ -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();
Expand All @@ -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");
Expand All @@ -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();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 1 addition & 1 deletion server/src/services/initialization/featureFlags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}
Expand Down
2 changes: 1 addition & 1 deletion server/src/services/initialization/onInitialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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),
]);
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
}
Loading

0 comments on commit a357352

Please sign in to comment.