Skip to content

Commit

Permalink
Fix identify name range
Browse files Browse the repository at this point in the history
  • Loading branch information
qiuxiang committed Mar 23, 2022
1 parent efa05af commit 3a8aac4
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 36 deletions.
20 changes: 4 additions & 16 deletions src/definition.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { readFile } from "fs/promises";
import { DefinitionParams, Location, Range } from "vscode-languageserver";
import { TextDocument } from "vscode-languageserver-textdocument";
import { documents, solidityMap } from ".";
import { getAbsolutePath, getAbsoluteUri } from "./compile";
import { solidityMap } from ".";
import { getAbsoluteUri } from "./compile";
import { ASTNode } from "./parse";
import { getIdentifierRange } from "./references";
import { getIdentifierLocation } from "./references";

export async function onDefinition({
textDocument: { uri },
position,
}: DefinitionParams) {
let document = documents.get(uri);
if (!document) return null;

const solidity = solidityMap.get(uri);
if (!solidity) return null;

Expand All @@ -28,12 +23,5 @@ export async function onDefinition({
if (ref) node = solidity.nodeMap.get(ref);
if (!node) return null;
}

const targetUri = node.root!.absolutePath;
if (targetUri != uri) {
const path = getAbsolutePath(decodeURIComponent(targetUri));
const content = (await readFile(path)).toString();
document = TextDocument.create("file://" + path, "solidity", 0, content);
}
return Location.create(uri, getIdentifierRange(node, document));
return getIdentifierLocation(node);
}
50 changes: 37 additions & 13 deletions src/references.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { readFileSync } from "fs";
import {
Location,
Position,
Expand All @@ -6,18 +7,14 @@ import {
} from "vscode-languageserver";
import { TextDocument } from "vscode-languageserver-textdocument";
import { documents, solidityMap } from ".";
import { getAbsolutePath } from "./compile";
import { ASTNode, IdentifierNode } from "./parse";

export function onReferences({
textDocument: { uri },
position,
}: ReferenceParams): Location[] {
const document = documents.get(uri);
if (!document) return [];

return getReferences(uri, position).map((i) => {
return Location.create(uri, getIdentifierRange(i, document));
});
}: ReferenceParams) {
return getReferences(uri, position).map(getIdentifierLocation);
}

export function getReferences(
Expand All @@ -34,11 +31,38 @@ export function getReferences(
);
}

export function getIdentifierRange(node: ASTNode, document: TextDocument) {
const name = Reflect.get(node, "memberName") ?? Reflect.get(node, "name");
const { srcStart, srcEnd } = node;
return Range.create(
document.positionAt(srcStart! + (srcEnd! - srcStart! - name.length)),
document.positionAt(srcEnd!)
function getDocument({ root }: ASTNode) {
const document = documents.get(root!.absolutePath);
if (document) return document;

const path = getAbsolutePath(root!.absolutePath);
const content = readFileSync(path).toString();
return TextDocument.create("file://" + path, "solidity", 0, content);
}

export function getIdentifierLocation(node: ASTNode) {
const document = getDocument(node);
let { srcStart = 0, srcEnd = 0 } = node;
let name = "";
switch (node.nodeType) {
case "Identifier":
case "VariableDeclaration":
case "UserDefinedTypeName":
name = node.name ?? "";
break;
case "MemberAccess":
name = node.memberName;
break;
}
if (node.nodeType.match(/Definition/)) {
srcStart += node.nodeType.replace("Definition", "").length + 1;
}
if (name) {
srcStart += srcEnd - srcStart - name.length;
}
const range = Range.create(
document.positionAt(srcStart),
document.positionAt(srcEnd)
);
return Location.create(document.uri, range);
}
9 changes: 2 additions & 7 deletions src/rename.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import { RenameParams, TextEdit, WorkspaceEdit } from "vscode-languageserver";
import { documents } from ".";
import { getIdentifierRange, getReferences } from "./references";
import { getIdentifierLocation, getReferences } from "./references";

export function onRename({
textDocument: { uri },
position,
newName,
}: RenameParams): WorkspaceEdit {
const document = documents.get(uri);
if (!document) return {};

return getReferences(uri, position).reduce<WorkspaceEdit>(
(previous, node) => {
const { changes } = previous;
const { uri, range } = getIdentifierLocation(node);
if (!changes![uri]) changes![uri] = [];

const range = getIdentifierRange(node, document);
changes![uri].push(TextEdit.replace(range, newName));
return previous;
},
Expand Down

0 comments on commit 3a8aac4

Please sign in to comment.