Skip to content

Commit eab0004

Browse files
committed
#60 initial Lionweb integration
1 parent 69816ac commit eab0004

13 files changed

+1536
-13
lines changed

jest.config.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ const config = {
1919
// Note: we have several deprecated functions that reduce coverage
2020
global: {
2121
statements: 88,
22-
branches: 81,
23-
functions: 76,
22+
branches: 84,
23+
functions: 79,
2424
lines: 88,
2525
},
2626
},
@@ -85,7 +85,12 @@ const config = {
8585
// transformation
8686
transformIgnorePatterns: [
8787
"node_modules/",
88-
]
88+
],
89+
globals: {
90+
"ts-jest": {
91+
tsConfig: `tests/tsconfig.json`
92+
}
93+
}
8994
};
9095

9196
module.exports = config

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
"generate-classes": "dist/cjs/cli.js"
8383
},
8484
"dependencies": {
85+
"@lionweb/core": "^0.6.1",
8586
"iter-ops": "^1.5.0",
8687
"reflect-metadata": "^0.1.13"
8788
},

src/interop/lionweb.ts

+271
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
import {
2+
Classifier,
3+
Containment, deserializeLanguages,
4+
EnumerationLiteral,
5+
Feature,
6+
Id,
7+
InstantiationFacade, Language,
8+
Node as LionwebNode
9+
} from "@lionweb/core";
10+
import {Node} from "..";
11+
12+
export class TylasuNode implements LionwebNode {
13+
id: Id;
14+
node: Node;
15+
parent?: LionwebNode;
16+
annotations: LionwebNode[];
17+
}
18+
19+
export class LanguageMapping {
20+
readonly nodeTypes = new Map<any, Classifier>();
21+
readonly classifiers = new Map<Classifier, any>();
22+
23+
register(nodeType: any, classifier: Classifier) {
24+
this.nodeTypes.set(nodeType, classifier);
25+
this.classifiers.set(classifier, nodeType);
26+
}
27+
28+
extend(languageMapping: LanguageMapping): this {
29+
const entries = languageMapping.nodeTypes.entries();
30+
for (let entry of entries) {
31+
this.nodeTypes.set(entry[0], entry[1]);
32+
this.classifiers.set(entry[1], entry[0]);
33+
}
34+
return this;
35+
}
36+
}
37+
38+
export class TylasuInstantiationFacade implements InstantiationFacade<TylasuNode> {
39+
40+
constructor(public languageMappings: LanguageMapping[] = [STARLASU_LANGUAGE_MAPPING]) {}
41+
42+
encodingOf(literal: EnumerationLiteral): unknown {
43+
return undefined;
44+
}
45+
nodeFor(parent: TylasuNode | undefined, classifier: Classifier, id: string, propertySettings: {
46+
[p: string]: unknown
47+
}): TylasuNode {
48+
let node: Node | undefined;
49+
for (let language of this.languageMappings) {
50+
const nodeType = language.classifiers.get(classifier);
51+
if (nodeType) {
52+
node = this.makeNode(nodeType, parent?.node, propertySettings);
53+
break;
54+
}
55+
}
56+
if (node) {
57+
return {
58+
id,
59+
parent,
60+
node,
61+
annotations: []
62+
};
63+
} else {
64+
throw new Error("Unknown classifier: " + classifier.id);
65+
}
66+
}
67+
setFeatureValue(node: TylasuNode, feature: Feature, value: unknown): void {
68+
if (feature instanceof Containment) {
69+
node.node.setChild(feature.name, (value as TylasuNode)?.node);
70+
} else {
71+
node.node[feature.name] = value;
72+
}
73+
}
74+
75+
protected makeNode(nodeType: any, parent: Node | undefined, propertySettings: {
76+
[p: string]: unknown
77+
}): Node {
78+
const node = new nodeType() as Node;
79+
Object.keys(propertySettings).forEach(k => {
80+
node[k] = propertySettings[k]; //TODO protect parent, origin etc.
81+
})
82+
return node.withParent(parent);
83+
}
84+
85+
}
86+
87+
export const STARLASU_LANGUAGE_MAPPING = new LanguageMapping();
88+
89+
export const STARLASU_LANGUAGE = deserializeLanguages({
90+
"serializationFormatVersion": "2023.1",
91+
"languages": [
92+
{
93+
"key": "LionCore-M3",
94+
"version": "2023.1"
95+
},
96+
{
97+
"key": "LionCore-builtins",
98+
"version": "2023.1"
99+
}
100+
],
101+
"nodes": [
102+
{
103+
"id": "com_strumenta_starlasu",
104+
"classifier": {
105+
"language": "LionCore-M3",
106+
"version": "2023.1",
107+
"key": "Language"
108+
},
109+
"properties": [
110+
{
111+
"property": {
112+
"language": "LionCore-M3",
113+
"version": "2023.1",
114+
"key": "Language-version"
115+
},
116+
"value": "1"
117+
},
118+
{
119+
"property": {
120+
"language": "LionCore-M3",
121+
"version": "2023.1",
122+
"key": "IKeyed-key"
123+
},
124+
"value": "com_strumenta_starlasu"
125+
},
126+
{
127+
"property": {
128+
"language": "LionCore-builtins",
129+
"version": "2023.1",
130+
"key": "LionCore-builtins-INamed-name"
131+
},
132+
"value": "com.strumenta.StarLasu"
133+
}
134+
],
135+
"containments": [
136+
{
137+
"containment": {
138+
"language": "LionCore-M3",
139+
"version": "2023.1",
140+
"key": "Language-entities"
141+
},
142+
"children": [
143+
"com_strumenta_starlasu_ASTNode",
144+
"com_strumenta_starlasu_Char"
145+
]
146+
}
147+
],
148+
"references": [
149+
{
150+
"reference": {
151+
"language": "LionCore-M3",
152+
"version": "2023.1",
153+
"key": "Language-dependsOn"
154+
},
155+
"targets": []
156+
}
157+
],
158+
"annotations": [],
159+
"parent": null
160+
},
161+
{
162+
"id": "com_strumenta_starlasu_ASTNode",
163+
"classifier": {
164+
"language": "LionCore-M3",
165+
"version": "2023.1",
166+
"key": "Concept"
167+
},
168+
"properties": [
169+
{
170+
"property": {
171+
"language": "LionCore-M3",
172+
"version": "2023.1",
173+
"key": "Concept-abstract"
174+
},
175+
"value": "false"
176+
},
177+
{
178+
"property": {
179+
"language": "LionCore-M3",
180+
"version": "2023.1",
181+
"key": "Concept-partition"
182+
},
183+
"value": "false"
184+
},
185+
{
186+
"property": {
187+
"language": "LionCore-M3",
188+
"version": "2023.1",
189+
"key": "IKeyed-key"
190+
},
191+
"value": "com_strumenta_starlasu_ASTNode"
192+
},
193+
{
194+
"property": {
195+
"language": "LionCore-builtins",
196+
"version": "2023.1",
197+
"key": "LionCore-builtins-INamed-name"
198+
},
199+
"value": "ASTNode"
200+
}
201+
],
202+
"containments": [
203+
{
204+
"containment": {
205+
"language": "LionCore-M3",
206+
"version": "2023.1",
207+
"key": "Classifier-features"
208+
},
209+
"children": []
210+
}
211+
],
212+
"references": [
213+
{
214+
"reference": {
215+
"language": "LionCore-M3",
216+
"version": "2023.1",
217+
"key": "Concept-extends"
218+
},
219+
"targets": []
220+
},
221+
{
222+
"reference": {
223+
"language": "LionCore-M3",
224+
"version": "2023.1",
225+
"key": "Concept-implements"
226+
},
227+
"targets": []
228+
}
229+
],
230+
"annotations": [],
231+
"parent": "com_strumenta_starlasu"
232+
},
233+
{
234+
"id": "com_strumenta_starlasu_Char",
235+
"classifier": {
236+
"language": "LionCore-M3",
237+
"version": "2023.1",
238+
"key": "PrimitiveType"
239+
},
240+
"properties": [
241+
{
242+
"property": {
243+
"language": "LionCore-M3",
244+
"version": "2023.1",
245+
"key": "IKeyed-key"
246+
},
247+
"value": "com_strumenta_starlasu_Char"
248+
},
249+
{
250+
"property": {
251+
"language": "LionCore-builtins",
252+
"version": "2023.1",
253+
"key": "LionCore-builtins-INamed-name"
254+
},
255+
"value": "Char"
256+
}
257+
],
258+
"containments": [],
259+
"references": [],
260+
"annotations": [],
261+
"parent": "com_strumenta_starlasu"
262+
}
263+
]
264+
})[0];
265+
266+
export function findClassifier(language: Language, id: string) {
267+
return language.entities.find(e => e.id == id) as Classifier;
268+
}
269+
270+
export const AST_NODE_CLASSIFIER = findClassifier(STARLASU_LANGUAGE, "com_strumenta_starlasu_ASTNode");
271+
STARLASU_LANGUAGE_MAPPING.register(Node, AST_NODE_CLASSIFIER)

src/interop/strumenta-playground.ts

+5
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ export class ParserTrace {
8888
}
8989

9090
export abstract class TraceNode extends Node {
91+
92+
abstract parent?: TraceNode;
93+
9194
protected constructor(public eo: ECore.EObject) {
9295
super();
9396
}
@@ -191,6 +194,8 @@ export abstract class TraceNode extends Node {
191194

192195
export class ParserNode extends TraceNode {
193196

197+
parent?: ParserNode;
198+
194199
constructor(eo: ECore.EObject, parent: ParserNode | undefined, protected trace: ParserTrace) {
195200
super(eo);
196201
this.parent = parent;

src/model/model.ts

-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ export abstract class Origin {
8080
overlaps(position?: Position): boolean {
8181
return this.position?.overlaps(position) || false
8282
}
83-
8483
}
8584

8685
export class SimpleOrigin extends Origin {

tests/data/playground/metamodel.json

+4
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@
123123
{
124124
"eClass": "http://www.eclipse.org/emf/2002/Ecore#//EAttribute",
125125
"name": "b",
126+
"eType": {
127+
"$ref": "http://www.eclipse.org/emf/2002/Ecore#//EString",
128+
"eClass": "http://www.eclipse.org/emf/2002/Ecore#//EDataType"
129+
},
126130
"ordered": true,
127131
"unique": true,
128132
"lowerBound": 0,

0 commit comments

Comments
 (0)