Skip to content

Commit

Permalink
Merge branch 'gh-pages' of https://github.com/LivelyKernel/lively4-core
Browse files Browse the repository at this point in the history
… into gh-pages
  • Loading branch information
onsetsu committed Sep 19, 2023
2 parents a6fc0d4 + 0d20467 commit 1e34000
Show file tree
Hide file tree
Showing 12 changed files with 341 additions and 41 deletions.
12 changes: 1 addition & 11 deletions demos/tree-sitter/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,7 @@
😊

<script>
await lively.loadJavaScriptThroughDOM("treeSitter", lively4url + "/src/external/tree-sitter/tree-sitter.js")


const Parser = window.TreeSitter;
await Parser.init()

const parser = new Parser;


const JavaScript = await Parser.Language.load(lively4url + "/src/external/tree-sitter/tree-sitter-javascript.wasm");

import {Parser, JavaScript} from "src/client/tree-sitter.js"

parser.setLanguage(JavaScript);

Expand Down
42 changes: 28 additions & 14 deletions src/client/domain-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,19 @@ MD*/
import tinycolor from 'src/external/tinycolor.js';


// #Copy from /src/components/tools/lively-ast-treesitter-inspector.js
// #TODO extract... ?
await lively.loadJavaScriptThroughDOM("treeSitter", lively4url + "/src/external/tree-sitter/tree-sitter.js")
const Parser = window.TreeSitter;
await Parser.init()
const JavaScript = await Parser.Language.load(lively4url + "/src/external/tree-sitter/tree-sitter-javascript.wasm");

import {Parser, JavaScript} from "src/client/tree-sitter.js"

import {loc} from "utils"

export function treesitterVisit(node, func) {
func(node)
for(let i=0; i< node.childCount; i++) {
let ea = node.child(i)
treesitterVisit(ea, func)
}
}


export class DomainObject {

replaceType(type, classObj) {
Expand Down Expand Up @@ -85,7 +88,7 @@ export class DomainObject {
MD*/
static updateFromTreeSitter(rootNode, treeSitterNode) {
debugger
let usedDomainObjects = new Set()
let removedDomainObjects = new Set()
let addedDomainObjects = new Set()
Expand Down Expand Up @@ -116,15 +119,12 @@ export class DomainObject {
replacement.target = domainObject
usedDomainObjects.add(replacement)
} else {
removedDomainObjects.add(replacement)

removedDomainObjects.add(replacement)
}
}
for(let removedDomainObject of removedDomainObjects) {
removedDomainObject.removed()
}


// keep same rootNode, alternative would be have another outside object that keeps the reference
rootNode.treeSitter = newRootNode.treeSitter
rootNode.children = newRootNode.children
Expand Down Expand Up @@ -156,7 +156,7 @@ export class TreeSitterDomainObject extends DomainObject {
}

get treeSitter() {
return this._treeSitterHistory.last
return this._treeSitterHistory && this._treeSitterHistory.last
}

get type() {
Expand Down Expand Up @@ -256,8 +256,9 @@ export class TreeSitterDomainObject extends DomainObject {
}
if (!domainObject) {
domainObject = new TreeSitterDomainObject(ast)
domainObject.children = []
}

domainObject.children = []
for(var i=0; i < ast.childCount; i++) {
var child = ast.child(i)
let domainChild = TreeSitterDomainObject.fromTreeSitterAST(child, optionalDomainObjectsById, optionalUsedDomainObjects)
Expand Down Expand Up @@ -286,10 +287,23 @@ export class ReplacementDomainObject extends DomainObject {
return true
}

get treeSitter() {
return this.target.treeSitter
}

set treeSitter(node) {
this.target.treeSitter = node
}


get children() {
return this.target ? this.target.children : []
}

set children(list) {
this.target.children = list
}

get type() {
return this.target && this.target.type
}
Expand Down
13 changes: 13 additions & 0 deletions src/client/tree-sitter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

// #Copy from /src/components/tools/lively-ast-treesitter-inspector.js
// #TODO extract... ?
await lively.loadJavaScriptThroughDOM("treeSitter", lively4url + "/src/external/tree-sitter/tree-sitter.js")

export const Parser = window.TreeSitter;

await Parser.init()
export const JavaScript = await Parser.Language.load(lively4url + "/src/external/tree-sitter/tree-sitter-javascript.wasm");




2 changes: 1 addition & 1 deletion src/components/tools/domain-code-explorer.html
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
<lively-separator></lively-separator>
<div class="pane tool layout-column">
<b>Domain Object <button id="domainUpdateButton">update</button><button id="domainGraphButton">graph</button></b>
<lively-inspector class="pane" id="domainobject"></lively-inspector>
<lively-ast-domain-object-inspector class="pane" id="domainobject"></lively-inspector>
</div>
<lively-separator></lively-separator>
<div class="pane tool layout-column">
Expand Down
12 changes: 11 additions & 1 deletion src/components/tools/domain-code-explorer.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,17 @@ export default class DomainCodeExplorer extends Morph {

onDomainCodeChanged(evt) {
lively.notify("on domain code changed " + evt.detail.edit.startIndex)
this.domainObjectInspector.inspect(this.domainObjectInspector.targetObject)
this.domainObjectInspector.inspect(this.domainObjectInspector.targetObject)

// prevent cycle....
var oldAutoUpdate = this._autoUpdate
this._autoUpdate = false
this.sourceEditor.setText(this.editor.getText())

this.treeSitterRootNode = evt.detail.node.debugNewAST.rootNode
this.astInspector.inspect(this.treeSitterRootNode)

this._autoUpdate = true
}

onDomainUpdateButton() {
Expand Down
19 changes: 19 additions & 0 deletions src/components/tools/lively-ast-domain-object-inspector.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<template id="lively-ast-domain-object-inspector" >
<style data-src="/src/external/font-awesome/css/font-awesome.css"></style>
<style data-src="/templates/livelystyle.css"></style>
<style data-src="/src/components/tools/lively-ast-inspector.css"></style>
<style>
button.inspect {
opacity: 0.3
}


button.inspect:hover {
opacity: 1
}

</style>

<div id="container"></div>
</template>

161 changes: 161 additions & 0 deletions src/components/tools/lively-ast-domain-object-inspector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
import AstInspector from "./lively-ast-inspector.js"

import {TreeSitterDomainObject, LetSmilyReplacementDomainObject, ConstSmilyReplacementDomainObject} from "src/client/domain-code.js"


import {Parser, JavaScript} from "src/client/tree-sitter.js"

import LivelyCodeMirrorCodeProvider from 'src/components/widgets/lively-code-mirror-code-provider.js';

import { loc, range } from 'src/client/utils.js';

export default class AstDomainObjectInspector extends AstInspector {

async treeSitterParse(sourceCode) {
const parser = new Parser;

parser.setLanguage(JavaScript);


const tree = parser.parse(sourceCode);
return tree
}


treeSitterNodeSummary(astNode, isExpanded) {
if (astNode.id) return astNode.id.name;
if (astNode.key) {
return astNode.key.value || astNode.key.name;
}
//}
return null;
}




domainObjectClassifications(node) {
const classifications = {};
const allKeys = this.allKeys(node);

// const fields = t.NODE_FIELDS[node.type];
// const visitorKeys = t.VISITOR_KEYS[node.type];
allKeys.forEach(key => {
classifications[key] = new Set();
// if (this.isLocationKey(key)) return classifications[key].add("location");
// if (this.isTypeKey(key)) return classifications[key].add("type");
if (this.isChildKey(key)) {
classifications[key].add("child");
} else {
classifications[key].add("field");
}

});
return classifications;
}

renderDomainObject(element, expanded) {
const target = element.target;
if (target.childCount > 0) {
element.append(this.expansionIndicatorTemplate(element.isExpanded));
}
element.append(this.keyTemplate(element));
if (target.isReplacement) {
element.append(<span style="font-size:8pt;padding:0px 2px 0px 2px;margin:0px; border-radius:3px; background:green; color:white">Replacement:</span>);
}
element.append(this.labelTemplate(target.type));
element.append(<span style="font-size:6pt;padding:0px 2px 0px 2px;margin:0px; border-radius:3px; background:lightgray; color:white">{target.treeSitter.id}</span>);
element.append(<span style="font-size:6pt;padding:0px;margin:0px"> {target.treeSitter.startIndex}-{target.treeSitter.endIndex} </span>);
element.append(<button class="inspect" style="font-size:6pt;padding:0px;margin:0px"
click={(evt) => lively.openInspector(element.target)}>inspect</button>);
const summary = this.treeSitterNodeSummary(element.target, element.isExpanded);
if (summary) element.append(this.summaryTemplate(summary));
this.attachHandlers(element);
if (element.isExpanded) {
const content = this.contentTemplate();
const classifications = this.domainObjectClassifications(target);
for (const key in classifications) {
const classification = classifications[key];
if (this.isVisibleAstNodeKey(classification)) {
content.append(this.display(this.getKey(target, key),
this.isFoldable(key), key, { classification }))
}
}
element.append(content);
}
}

// (A) handle children via key
isChildKey(key) {
return Number.isInteger(key) || key.match(/^[0-9]+$/)
}

getKey(element, key) {
if (this.isChildKey(key)) {
return element.children[key]
} else {
return element.childForFieldName(key)
}
// return element[key]
}

allKeys(obj) {
if (obj.isDomainObject) {
var result = []
for(let i=0; i < obj.children.length; i++) {
// let child = obj.children[i]
let key = i
result.push(key)
}
return result
}
return super.allKeys(obj)
}


// getChildren(node) {
// var children = super.getChildren(node)
// if(this.isTreeSitterNode(node)) {
// for(let i=0; i < node.childCount; i++) {
// children.push(node.child(i))
// }
// }
// return children
// }

getElementType(obj) {
if (obj.isDomainObject) return "DomainObject";
return super.getElementType(obj)
}

async initialize() {
await super.initialize()
this.windowTitle = "AST TreeSitter Inspector";
if (this.editor) {
this.connectEditor(this.editor)
}
}


livelyMigrate(other) {
super.livelyMigrate(other)
this.editor = other.editor
}


async livelyExample() {
// const url = lively4url + "/src/components/tools/lively-ast-inspector.js";
// const src = await fetch(url).then(r => r.text());

const sourceCode = 'let x = 1; console.log(x);';
var tree = await this.treeSitterParse(sourceCode)

this.domainObject = TreeSitterDomainObject.fromTreeSitterAST(tree.rootNode)
this.domainObject.replaceType('let', LetSmilyReplacementDomainObject)
this.domainObject.replaceType('const', ConstSmilyReplacementDomainObject)

const rootNode = tree.rootNode;
this.inspect(this.domainObject);
}

}
2 changes: 2 additions & 0 deletions src/components/tools/lively-ast-inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,7 @@ export default class AstInspector extends Morph {
}

setViewState(state) {
if (!state) return
return this.applyViewState(this.container.childNodes[0], state)
}

Expand All @@ -493,6 +494,7 @@ export default class AstInspector extends Morph {
}

captureViewState(node) {
if (!node) return
const result = {
pattern: node.pattern,
children: [],
Expand Down
8 changes: 1 addition & 7 deletions src/components/tools/lively-ast-treesitter-inspector.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
import AstInspector from "./lively-ast-inspector.js"

await lively.loadJavaScriptThroughDOM("treeSitter", lively4url + "/src/external/tree-sitter/tree-sitter.js")

const Parser = window.TreeSitter;
await Parser.init()

const JavaScript = await Parser.Language.load(lively4url + "/src/external/tree-sitter/tree-sitter-javascript.wasm");

import {Parser, JavaScript} from "src/client/tree-sitter.js"

import LivelyCodeMirrorCodeProvider from 'src/components/widgets/lively-code-mirror-code-provider.js';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// hello
let a = 3 + 4
const b = a
let a = 3 + 4
const b = a
var c = b
1 change: 1 addition & 0 deletions src/components/tools/lively-inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ export default class Inspector extends Morph {
try {
obj.livelyInspect(contentNode, this)
} catch(e) {
debugger
var selection = <div class="element" style="color:red"><b>Error in livleyInspect:</b> {e}</div>;
contentNode.appendChild(selection);
}
Expand Down
Loading

0 comments on commit 1e34000

Please sign in to comment.