Public
Edited
Jun 5, 2024
Importers
1 star
Insert cell
Insert cell
// NOTE: has getModule() added to the end of the file.
treeSitter_js = FileAttachment("tree-sitter.js").url()
Insert cell
treeSitter_wasm = FileAttachment("tree-sitter.wasm").url()
Insert cell
treeSitterJavascript = FileAttachment("tree-sitter-javascript.wasm").url()
Insert cell
treeSitterC = FileAttachment("tree-sitter-c.wasm").url()
Insert cell
treeSitterCpp = FileAttachment("tree-sitter-cpp.wasm").url()
Insert cell
Parser = {
const module = await import(treeSitter_js);
// custom method to extract the TreeSitter class
// haven't figured a way to get it to work without this
const parser = module.getModule();

const mm = await parser.init({
locateFile: function (fileName) {
console.log("locateFile", fileName);
return treeSitter_wasm;
}
});

return parser;
}
Insert cell
LangJavaScript = await Parser.Language.load(treeSitterJavascript)
Insert cell
LangC = await Parser.Language.load(treeSitterC)
Insert cell
LangCpp = await Parser.Language.load(treeSitterCpp)
Insert cell
function treeToJson(node) {
const r = { type: node.type };

const name = node.childForFieldName("name");
if (name) {
r.name = name.text;
}

if (node.childCount > 0) {
r.children = [];
for (let i = 0; i < node.childCount; i++) {
r.children.push(treeToJson(node.child(i)));
}
}

return r;
}
Insert cell
function createFunctionCallMap(tree) {
const m = new Map();

function traverse(node, currentFunctionName) {
if (
node.type === "function_declaration" ||
node.type === "method_definition"
) {
currentFunctionName = node.childForFieldName("name")?.text || null;
}

if (currentFunctionName && node.type === "call_expression") {
const calleeName = node.childForFieldName("function")?.text;
if (!m.has(currentFunctionName)) {
m.set(currentFunctionName, []);
}
m.get(currentFunctionName).push(calleeName);
}

if (currentFunctionName && node.type === "function_expression") {
const calleeName = node.childForFieldName("name")?.text;
if (!m.has(currentFunctionName)) {
m.set(currentFunctionName, []);
}
m.get(currentFunctionName).push(calleeName);
}

for (let i = 0; i < node.childCount; i++) {
traverse(node.child(i), currentFunctionName);
}
}

traverse(tree.rootNode, null);
return m;
}
Insert cell
results = {
// based on https://github.com/asgerf/dts-tree-sitter/blob/master/examples/javascript/index.ts
const parser = new Parser();
parser.setLanguage(LangJavaScript);
let tree = parser.parse(`
function foo() {
return function bar() {}
}
function baz() {}
class C {
f = 5;
m() { }
}
`);

return {
tree: treeToJson(tree.rootNode),
callMap: createFunctionCallMap(tree)
};
}
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more