Skip to content

Commit 63d41cc

Browse files
committed
#66 offer higher-level APIs for Lionweb import
1 parent 414eb9f commit 63d41cc

File tree

2 files changed

+49
-28
lines changed

2 files changed

+49
-28
lines changed

src/interop/lionweb.ts

+31-8
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,16 @@
55
import {
66
Classifier,
77
Concept,
8-
Containment,
8+
Containment, deserializeChunk,
99
Feature as LWFeature,
1010
Id,
1111
InstantiationFacade,
1212
Interface,
1313
Language,
14-
Node as LWNodeInterface
14+
Node as LWNodeInterface,
15+
SerializationChunk
1516
} from "@lionweb/core";
16-
import {NodeAdapter, Issue, Node, NodeDefinition, Position, Feature, Point, pos} from "..";
17+
import {NodeAdapter, Issue, Node, NodeDefinition, Position, Feature, Point, pos, TraceNode} from "..";
1718
import {STARLASU_LANGUAGE} from "./lionweb-starlasu-language";
1819
export {STARLASU_LANGUAGE} from "./lionweb-starlasu-language";
1920

@@ -77,22 +78,22 @@ export class LanguageMapping {
7778
}
7879
}
7980

80-
function isSpecialConcept(classifier: Classifier) {
81-
return classifier.key == PositionClassifier.key;
81+
function isSpecialConcept(classifier: Classifier | null) {
82+
return classifier?.key == PositionClassifier.key;
8283
}
8384

8485
function importFeature(feature: LWFeature): Feature | undefined {
8586
const def: Feature = { name: feature.name };
8687
if (feature instanceof Containment) {
87-
if (feature.type && feature.type instanceof Concept && !isSpecialConcept(feature.type)) {
88+
if (!isSpecialConcept(feature.type)) {
8889
def.child = true;
8990
def.multiple = feature.multiple;
9091
} else {
91-
// TODO is it possible in Lionweb to have a Containment that's not a concept?
92+
// We don't import the containment because we handle it specially
9293
return undefined;
9394
}
9495
}
95-
return def
96+
return def;
9697
}
9798

9899
function importConcept(concept: NodeDefinition | undefined, classifier: Classifier) {
@@ -283,3 +284,25 @@ export class LionwebNode extends NodeAdapter {
283284
return other instanceof LionwebNode && other.lwnode == this.lwnode;
284285
}
285286
}
287+
288+
export function deserializeToTylasuNodes(
289+
chunk: SerializationChunk,
290+
languages: Language[],
291+
languageMappings: LanguageMapping[] = [STARLASU_LANGUAGE_MAPPING],
292+
dependentNodes: LWNodeInterface[] = []
293+
): Node[] {
294+
return deserializeChunk(
295+
chunk, new TylasuInstantiationFacade(languageMappings), [STARLASU_LANGUAGE, ...languages], dependentNodes
296+
)
297+
.filter(n => n instanceof TylasuNodeWrapper)
298+
.map(n => (n as TylasuNodeWrapper).node);
299+
}
300+
301+
export function deserializeToTraceNodes(
302+
chunk: SerializationChunk,
303+
languages: Language[],
304+
dependentNodes: LWNodeInterface[] = []
305+
): TraceNode[] {
306+
return deserializeToTylasuNodes(chunk, languages, [], dependentNodes).map(
307+
n => new TraceNode(n as LionwebNode));
308+
}

tests/interop/lionweb.test.ts

+18-20
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import {expect} from "chai";
66
import {deserializeChunk, deserializeLanguages, SerializationChunk} from "@lionweb/core";
77
import {Attribute, Children, Node, TraceNode, walk} from "../../src";
88
import {
9+
deserializeToTraceNodes,
10+
deserializeToTylasuNodes,
911
findClassifier,
1012
LanguageMapping, LionwebNode,
1113
STARLASU_LANGUAGE_MAPPING,
@@ -44,12 +46,12 @@ describe('Lionweb integration', function() {
4446

4547
it("can deserialize simple model",
4648
function () {
47-
const nodes = deserializeChunk(FS_MODEL, new TylasuInstantiationFacade([FS_LANGUAGE_MAPPING]), [FS_LANGUAGE], []);
49+
const nodes = deserializeToTylasuNodes(FS_MODEL, [FS_LANGUAGE], [FS_LANGUAGE_MAPPING]);
4850
expect(nodes).not.to.be.empty;
4951
expect(nodes.length).to.equal(1);
50-
const root = nodes[0] as TylasuNodeWrapper;
51-
expect(root.node).to.be.instanceof(Directory);
52-
let dir = root.node as Directory;
52+
const root = nodes[0];
53+
expect(root).to.be.instanceof(Directory);
54+
let dir = root as Directory;
5355
expect(dir.name).to.equal("resources.zip");
5456
expect(dir.files.length).to.equal(1);
5557
expect(dir.files[0]).to.be.instanceof(Directory);
@@ -61,7 +63,7 @@ describe('Lionweb integration', function() {
6163
expect(file.name).to.equal("delegate.egl");
6264
expect(file.contents.substring(0, 10)).to.equal("Delegate F");
6365

64-
expect(printSequence(walk(root.node))).to.equal(
66+
expect(printSequence(walk(root))).to.equal(
6567
"resources.zip, resources, delegate.egl, rosetta-code-count-examples-2.egl, " +
6668
"rosetta-code-count-examples-1.egl, sub1, sub2, foreach.egl, SQLDropTable.egl, for.egl, SQLBatch.egl, " +
6769
"SQLCreateTable.egl, SQLDropTable.egl, hello.egl, foreach.egl, Calc.egl, SQLBatch.egl, " +
@@ -71,12 +73,12 @@ describe('Lionweb integration', function() {
7173

7274
it("can deserialize simple model to dynamic nodes",
7375
function () {
74-
const nodes = deserializeChunk(FS_MODEL, new TylasuInstantiationFacade(), [FS_LANGUAGE], []);
76+
const nodes = deserializeToTylasuNodes(FS_MODEL, [FS_LANGUAGE]);
7577
expect(nodes).not.to.be.empty;
7678
expect(nodes.length).to.equal(1);
77-
const root = nodes[0] as TylasuNodeWrapper;
78-
expect(root.node).to.be.instanceof(LionwebNode);
79-
let dir = root.node as LionwebNode & any;
79+
const root = nodes[0];
80+
expect(root).to.be.instanceof(LionwebNode);
81+
let dir = root as LionwebNode & any;
8082
expect(dir.nodeDefinition.name).to.equal("Directory");
8183
expect(dir.getAttributeValue("name")).to.equal("resources.zip");
8284
expect(dir.files.length).to.equal(1);
@@ -91,7 +93,7 @@ describe('Lionweb integration', function() {
9193
expect(file.name).to.equal("delegate.egl");
9294
expect(file.contents.substring(0, 10)).to.equal("Delegate F");
9395

94-
expect(printSequence(walk(root.node))).to.equal(
96+
expect(printSequence(walk(root))).to.equal(
9597
"resources.zip, resources, delegate.egl, rosetta-code-count-examples-2.egl, " +
9698
"rosetta-code-count-examples-1.egl, sub1, sub2, foreach.egl, SQLDropTable.egl, for.egl, SQLBatch.egl, " +
9799
"SQLCreateTable.egl, SQLDropTable.egl, hello.egl, foreach.egl, Calc.egl, SQLBatch.egl, " +
@@ -101,12 +103,10 @@ describe('Lionweb integration', function() {
101103

102104
it("supports trace nodes",
103105
function () {
104-
const nodes = deserializeChunk(FS_MODEL, new TylasuInstantiationFacade(), [FS_LANGUAGE], []);
106+
const nodes = deserializeToTraceNodes(FS_MODEL, [FS_LANGUAGE]);
105107
expect(nodes).not.to.be.empty;
106108
expect(nodes.length).to.equal(1);
107-
const root = nodes[0] as TylasuNodeWrapper;
108-
expect(root.node).to.be.instanceof(LionwebNode);
109-
let dir = new TraceNode(root.node as LionwebNode);
109+
let dir = nodes[0];
110110
expect(dir.nodeDefinition).not.to.be.undefined;
111111
expect(dir.getRole()).to.be.undefined;
112112
expect(dir.nodeDefinition.name).to.equal("Directory");
@@ -124,7 +124,7 @@ describe('Lionweb integration', function() {
124124
expect(file.getRole()).to.equal("files");
125125
expect(file.getPathFromRoot()).to.eql(["files", 0, "files", 1]);
126126

127-
expect(printSequence(walk(root.node))).to.equal(
127+
expect(printSequence(walk(nodes[0]))).to.equal(
128128
"resources.zip, resources, delegate.egl, rosetta-code-count-examples-2.egl, " +
129129
"rosetta-code-count-examples-1.egl, sub1, sub2, foreach.egl, SQLDropTable.egl, for.egl, SQLBatch.egl, " +
130130
"SQLCreateTable.egl, SQLDropTable.egl, hello.egl, foreach.egl, Calc.egl, SQLBatch.egl, " +
@@ -133,12 +133,10 @@ describe('Lionweb integration', function() {
133133
});
134134
it("trace nodes don't include the position as a child",
135135
function () {
136-
const nodes = deserializeChunk(EGL_MODEL, new TylasuInstantiationFacade(), [EGL_LANGUAGE, STARLASU_LANGUAGE], []);
136+
const nodes = deserializeToTraceNodes(EGL_MODEL, [EGL_LANGUAGE]);
137137
expect(nodes).not.to.be.empty;
138-
expect(nodes.length).to.equal(4);
139-
const root = nodes[0] as TylasuNodeWrapper;
140-
expect(root.node).to.be.instanceof(LionwebNode);
141-
const dir = new TraceNode(root.node as LionwebNode);
138+
expect(nodes.length).to.equal(1);
139+
const dir = nodes[0];
142140
expect(dir.nodeDefinition).not.to.be.undefined;
143141
expect(dir.getRole()).to.be.undefined;
144142
expect(dir.nodeDefinition.name).to.equal("EglCompilationUnit");

0 commit comments

Comments
 (0)