Skip to content

Commit

Permalink
Improve go-to-definition for object pattern field aliases (#242)
Browse files Browse the repository at this point in the history
* Misc improvements

* Misc

* Add 'name' to 'Definition' when possible

* Improve go-to-definition for object pattern aliases

* Remove commented code

* Refactor

* Improve type checking UX (#239)

* Adjust 'processQueue()' logic

* Optimize main file type checking

* Increase main file type checking debounce

* Fix type checker sometimes using outdated file content

* 0.13.11

* Refactor for clarity

* Cancel checking workspace on file change

* Add notification on Mops / Vessel package configuration error (#240)

* Add notification for error in Mops / Vessel configuration

* Add 'View logs' button to error message

* Adjust error message detail rendering

* Bump formatter (#241)

* Bump formatter

* 0.13.12
  • Loading branch information
rvanasa authored Aug 26, 2023
1 parent 6327918 commit b343e76
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 66 deletions.
48 changes: 28 additions & 20 deletions src/server/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface Definition {
uri: string;
cursor: Node;
body: Node;
name: string | undefined;
}

interface Search {
Expand All @@ -34,7 +35,6 @@ export function findMostSpecificNodeForPosition(
node.end &&
position.line >= node.start[0] - 1 &&
position.line <= node.end[0] - 1 &&
// position.line == node.start[0] - 1 &&
(position.line !== node.start[0] - 1 ||
position.character >= node.start[1]) &&
(position.line !== node.end[0] - 1 ||
Expand All @@ -46,9 +46,6 @@ export function findMostSpecificNodeForPosition(
let nodeLines: number;
let nodeChars: number;
nodes.forEach((n: Node) => {
// if (ignoredAstNodes.includes(n.name)) {
// return;
// }
const nLines = n.end![0] - n.start![0];
const nChars = n.end![1] - n.start![1];
if (
Expand Down Expand Up @@ -107,10 +104,12 @@ export function locationFromDefinition(definition: Definition) {
return location;
}

// TODO: refactor to use `findInPattern()`
function findNameInPattern(search: Search, pat: Node): Node | undefined {
function findNameInPattern(
search: Search,
pat: Node,
): [string, Node] | undefined {
return findInPattern(pat, (name, node) =>
name === search.name ? node : undefined,
name === search.name ? [name, node] : undefined,
);
}

Expand Down Expand Up @@ -147,7 +146,7 @@ export function findDefinition(
if (!node) {
return;
}
const reference = { uri, node };
const reference: Reference = { uri, node };
const importDefinition = followImport(context, reference);
if (importDefinition) {
return importDefinition;
Expand Down Expand Up @@ -246,8 +245,10 @@ function followImport(
return;
}
// Find the relevant field name
const field = matchNode(reference.node.parent?.parent, 'ObjP', () =>
matchNode(reference.node, 'VarP', (name: string) => name),
const field = matchNode(
reference.node.parent?.parent,
'ObjP',
() => reference.node.parent?.name,
);
// Follow the module import
return matchNode(importNode, 'ImportE', (path: string) => {
Expand Down Expand Up @@ -275,18 +276,18 @@ function followImport(
console.log('AST:', status.program.export.ast);
return;
}
const declaration = {
uri,
cursor: exportNode,
body: exportNode,
};
if (field) {
return searchObject(
{ uri: declaration.uri, node: declaration.body },
{ uri, node: exportNode },
{ type: 'variable', name: field },
); // || declaration
);
}
return declaration;
return {
uri,
cursor: exportNode,
body: exportNode,
name: undefined,
};
});
}

Expand Down Expand Up @@ -349,12 +350,13 @@ function searchDeclaration(
): Definition | undefined {
return (
matchNode(dec, 'LetD', (pat: Node, body: Node) => {
const varNode = findNameInPattern(search, pat);
const [name, varNode] = findNameInPattern(search, pat) || [];
return (
varNode && {
uri: reference.uri,
cursor: varNode,
body,
name,
}
);
}) ||
Expand All @@ -364,6 +366,7 @@ function searchDeclaration(
uri: reference.uri,
cursor: dec, // TODO: cursor on variable name
body,
name,
}
: undefined,
) ||
Expand All @@ -373,6 +376,7 @@ function searchDeclaration(
uri: reference.uri,
cursor: dec, // TODO: cursor on variable name
body: dec,
name,
}
: undefined,
)
Expand All @@ -391,6 +395,7 @@ function searchTypeBinding(
uri: reference.uri,
cursor: typ, // TODO: source location from `name`
body: typ,
name,
}
: undefined,
) ||
Expand All @@ -400,6 +405,7 @@ function searchTypeBinding(
uri: reference.uri,
cursor: dec, // TODO: cursor on variable name
body: dec,
name,
}
: undefined,
)
Expand Down Expand Up @@ -430,6 +436,7 @@ function searchObject(
uri: reference.uri,
cursor: arg,
body,
name,
},
) ||
matchNode(arg, 'DecField', (dec: Node) =>
Expand Down Expand Up @@ -458,12 +465,13 @@ function searchObject(
},
);
if (!definition) {
const pat = findNameInPattern(search, arg); // Function parameters
const [name, pat] = findNameInPattern(search, arg) || []; // Function parameters
if (pat) {
definition = {
uri: reference.uri,
cursor: pat,
body: pat,
name,
};
}
}
Expand Down
37 changes: 4 additions & 33 deletions src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1063,7 +1063,10 @@ connection.onHover((event) => {
}
if (docNode.name === 'Prog' && !docNode.doc) {
// Get doc comment at top of file
return asNode(docNode.args?.[0])?.doc;
const doc = asNode(docNode.args?.[0])?.doc;
if (doc) {
return doc;
}
}
return docNode.doc;
}
Expand Down Expand Up @@ -1352,38 +1355,6 @@ connection.onRequest(TEST_FILE_REQUEST, async (event): Promise<TestResult> => {
} else {
throw new Error(`Invalid test mode: '${mode}'`);
}
// else {
// const start = Date.now();
// const wasiResult = motoko.wasm(virtualPath, 'wasi');
// console.log('Compile time:', Date.now() - start);

// const WebAssembly = (global as any).WebAssembly;
// const module = await (
// WebAssembly.compileStreaming || WebAssembly.compile
// )(wasiResult.wasm);
// const WASI = require('wasi');
// const wasi = new WASI({});
// const inst = new WebAssembly.Instance(module, {
// wasi_unstable: wasi.exports,
// });
// wasi.setMemory(inst.exports.memory);
// inst.exports._start();

// // if (exitCode !== 0) {
// // console.log(stdout);
// // console.error(stderr);
// // console.log('Exit code:', exitCode);
// // }
// // return {
// // passed: exitCode === 0,
// // stdout,
// // stderr,
// // };

// console.log(Object.keys(inst.exports)); ///////

// return { passed: true, stdout: '', stderr: '' };
// }
} catch (err) {
console.error(err);
return {
Expand Down
7 changes: 7 additions & 0 deletions src/server/syntax.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,11 @@ describe('syntax', () => {
expectFields(prog.exportFields, [undefined]);
expectWithFields(prog.exportFields[0].exp, ['a', 'b']);
});
test('object pattern with alias', () => {
const prog = parse(
'module { let { a; b = c } = { a = "a"; b = "b" }; }',
);
expectFields(prog.exportFields, [undefined]);
expectWithFields(prog.exportFields[0].exp, ['a', 'c']);
});
});
10 changes: 2 additions & 8 deletions src/server/syntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,14 +202,8 @@ export function findInPattern<T>(
matchNode(pat, 'VarP', (name: string) => fn(name, pat)) ||
matchNode(pat, 'ObjP', (...args: Node[]) => {
for (const field of args) {
const aliasNode = field.args![0] as Node;
const alias = matchNode(
aliasNode,
'VarP',
(alias) => alias,
field.name,
);
const result = fn(alias, pat);
const fieldPat = field.args![0] as Node;
const result = findInPattern(fieldPat, fn);
if (result !== undefined) {
return result;
}
Expand Down
5 changes: 0 additions & 5 deletions src/server/utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,13 @@ import { getAbsoluteUri, getRelativeUri } from './utils';

describe('utils', () => {
test('getRelativeUri', () => {
// expect(getRelativeUri('file:a/b/c', 'file:a')).toStrictEqual('..');
// expect(getRelativeUri('file://a/b/c', 'file://a')).toStrictEqual('..');
expect(getRelativeUri('file:///a/b', 'file:///a')).toStrictEqual('..');
expect(getRelativeUri('mo:a/b', 'mo:a/b/c')).toStrictEqual('c');
expect(getRelativeUri('mo:a/b', 'mo:a/c')).toStrictEqual('c');
});
test('getAbsoluteUri', () => {
expect(getAbsoluteUri('mo:a', 'b')).toStrictEqual('mo:a/b');
// expect(getAbsoluteUri('file:a/b', '..')).toStrictEqual('file:a');
// expect(getAbsoluteUri('file://a/b', '..')).toStrictEqual('file://a');
expect(getAbsoluteUri('file:///a/b', '..')).toStrictEqual('file:///a');
expect(getAbsoluteUri('mo:a/b', '../c')).toStrictEqual('mo:a/c');
// expect(getAbsoluteUri('file:///a', 'mo:b')).toStrictEqual('mo:b');
});
});

0 comments on commit b343e76

Please sign in to comment.