Skip to content

Commit 82c86da

Browse files
committed
Renamed "property" to either "feature" or "attribute" according to Kolasu terminology
Correctly record references in node metadata for ECore nodes
1 parent 9715d9a commit 82c86da

10 files changed

+54
-31
lines changed

CHANGELOG.md

+8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
All notable changes to this project from version 1.2.0 upwards are documented in this file.
33
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
44

5+
## [1.6.17] – 2024-03-21
6+
7+
### Changed
8+
- TraceNode.get renamed to getDescendant
9+
10+
### Fixed
11+
- TraceNode.get to access nodes by path
12+
513
## [1.6.16] – 2024-03-21
614

715
### Changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"description": "AST building blocks for TypeScript/JavaScript, part of the *lasu family, with optional integrations with ANTLR4 and Ecore.",
44
"author": "Strumenta s.r.l.",
55
"publisher": "strumenta",
6-
"version": "1.6.16",
6+
"version": "1.6.17",
77
"license": "Apache-2.0",
88
"keywords": [
99
"antlr",

src/interop/ecore.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ export class ${className} extends ${superClassName} {`;
471471
defineProperty(classDef, name);
472472
const prop = registerNodeAttribute(classDef as any, name);
473473
prop.child = a.isTypeOf('EReference');
474-
const annotation = prop.child ? (prop.multiple ? "@Children()" : "@Child()") : "@Property()"
474+
const annotation = prop.child ? (prop.multiple ? "@Children()" : "@Child()") : "@Attribute()"
475475
classDef[SYMBOL_CLASS_DEFINITION] += `\n\t${annotation}\n\t${name};`;
476476
});
477477
classDef[SYMBOL_CLASS_DEFINITION] += "\n}";

src/model/model.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -267,8 +267,10 @@ export abstract class Node extends Origin implements Destination {
267267
const raw = this.doGetChildOrChildren(name);
268268
if (containment.multiple) {
269269
return (raw as Node[]) || [];
270+
} else if (raw) {
271+
return [raw as Node];
270272
} else {
271-
throw new Error(name.toString() + " is not a collection");
273+
return [];
272274
}
273275
}
274276

src/trace/trace-node.ts

+12-13
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ export class TraceNode extends Node implements PossiblyNamed {
209209
refTarget = refTarget.parent;
210210
}
211211
if (tempParent) {
212-
const newParent = this.getRoot().get(tempParent.getPathFromRoot());
212+
const newParent = this.getRoot().getDescendant(tempParent.getPathFromRoot());
213213
if (newParent instanceof Node) {
214214
return newParent;
215215
}
@@ -283,20 +283,19 @@ export class TraceNode extends Node implements PossiblyNamed {
283283
return this.nodeAdapter.isStatement();
284284
}
285285

286-
get(path: (string | number)[]) {
286+
getDescendant(path: (string | number)[]) {
287287
// eslint-disable-next-line @typescript-eslint/no-this-alias
288-
let node: Node | Node[] | undefined = this;
289-
for (const elem of path) {
290-
if (typeof elem == "string") {
291-
if (node instanceof Node) {
292-
node = node.getChild(elem);
293-
} else {
294-
throw new Error("Invalid path at " + elem + ", expected node, got " + node);
295-
}
296-
} else if (Array.isArray(node)) {
297-
node = node[elem];
288+
let node: Node | undefined = this;
289+
for (let i = 0; i < path.length; i++) {
290+
const elem = path[i];
291+
if (typeof elem !== "string") {
292+
throw new Error("Invalid path at " + elem + ", expected node, got " + node);
293+
}
294+
if (i < path.length - 1 && typeof path[i + 1] === "number") {
295+
node = node?.getChild(elem, path[i + 1] as number);
296+
i++;
298297
} else {
299-
throw new Error("Invalid path at " + elem + ", expected children, got " + node);
298+
node = node?.getChild(elem);
300299
}
301300
}
302301
return node;

tests/ecore.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ export class CompilationUnit extends Node {
257257
expect(NODE_TYPES["SimpleMM"].nodes["StringLiteral"][SYMBOL_CLASS_DEFINITION]).to.equal(
258258
`@ASTNode("SimpleMM", "StringLiteral")
259259
export class StringLiteral extends Expression {
260-
\t@Property()
260+
\t@Attribute()
261261
\tvalue;
262262
}`);
263263
node = new NODE_TYPES["SimpleMM"].nodes["StringLiteral"]() as any;

tests/interop/lionweb.test.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import FS_LANGUAGE_JSON from "./fs-language.json";
22
import FS_MODEL from "./fs-model.json";
33
import {expect} from "chai";
44
import {deserializeChunk, deserializeLanguages, SerializationChunk} from "@lionweb/core";
5-
import {Children, Node, Property, TraceNode, walk} from "../../src";
5+
import {Attribute, Children, Node, TraceNode, walk} from "../../src";
66
import {
77
findClassifier,
88
LanguageMapping, LionwebNode,
@@ -13,7 +13,7 @@ import {map, pipe, reduce} from "iter-ops";
1313
import {STARLASU_LANGUAGE} from "../../src/interop/lionweb-starlasu-language";
1414

1515
abstract class File extends Node {
16-
@Property()
16+
@Attribute()
1717
name: string;
1818
}
1919

@@ -23,7 +23,7 @@ class Directory extends File {
2323
}
2424

2525
class TextFile extends File {
26-
@Property()
26+
@Attribute()
2727
contents: string;
2828
}
2929

tests/interop/workspace-transpilation-trace.test.ts

+19-4
Original file line numberDiff line numberDiff line change
@@ -111,17 +111,17 @@ describe('Workspace Transpilation traces', function() {
111111
expect(sourceRoot.getSimpleType()).to.eql("CompilationUnit")
112112
expect(sourceRoot.getPosition()).to.eql(new Position(new Point(1, 0), new Point(82, 18)))
113113

114-
const refExpr = pipe(sourceRoot.walkDescendants(),
114+
let refExpr = pipe(sourceRoot.walkDescendants(),
115115
filter((node: TraceNode) => node.getType() == "com.strumenta.rpgparser.model.ReferenceExpr"),
116116
first()).first as TraceNode;
117117
expect(refExpr).not.to.be.undefined;
118118
expect(refExpr.getPathFromRoot()).to.eql(["mainStatements", 0, "expression", "target"]);
119-
const refDef = refExpr.nodeDefinition.features["dataDefinition"];
119+
let refDef = refExpr.nodeDefinition.features["dataDefinition"];
120120
expect(refDef?.reference).to.be.true;
121-
const reference = refExpr.getReference("dataDefinition");
121+
let reference = refExpr.getReference("dataDefinition");
122122
expect(reference).to.be.instanceof(ReferenceByName);
123123
expect(reference?.name).to.equal("CNT");
124-
const refTarget = reference?.referred;
124+
let refTarget = reference?.referred;
125125
expect(refTarget).to.be.instanceof(TraceNode);
126126
expect(refTarget?.getType()).to.equal("com.strumenta.rpgparser.model.StandaloneField");
127127
expect(refTarget?.name).to.equal("CNT");
@@ -130,6 +130,21 @@ describe('Workspace Transpilation traces', function() {
130130
expect(refTarget?.getRoot()).to.equal(sourceRoot);
131131
expect(refExpr.getAttributes()["dataDefinition"]).to.be.undefined;
132132

133+
refExpr = sourceRoot.getDescendant(["mainStatements", 4, "name"]) as TraceNode;
134+
refDef = refExpr.nodeDefinition.features["dataDefinition"];
135+
expect(refDef?.reference).to.be.true;
136+
reference = refExpr.getReference("dataDefinition");
137+
expect(reference).to.be.instanceof(ReferenceByName);
138+
expect(reference?.name).to.equal("CUSTOMER");
139+
refTarget = reference?.referred;
140+
expect(refTarget).to.be.instanceof(TraceNode);
141+
expect(refTarget?.getType()).to.equal("com.strumenta.rpgparser.model.ExternalFileDefinition");
142+
expect(refTarget?.name).to.equal("CUSTOMER");
143+
expect(refTarget?.getRole()).to.equal("file");
144+
expect(refTarget?.getPathFromRoot()).to.eql(["externalDefinitions", 17, "record", "file"]);
145+
expect(refTarget?.getRoot()).to.equal(sourceRoot);
146+
expect(refExpr.getAttributes()["dataDefinition"]).to.be.undefined;
147+
133148
// TODO broken expect(cus300File.node.getChildren("dataDefinition").length).to.eql(4)
134149
expect(sourceRoot.getChildren("mainStatements").length).to.eql(9)
135150
const firstStatement = sourceRoot.getChildren("mainStatements")[0];

tests/testing/testing.test.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {expect} from "chai";
22
import {assertASTsAreEqual} from "../../src/testing/testing";
3-
import {ASTNode, Children, Node, Point, Position, PossiblyNamed, Property} from "../../src";
3+
import {ASTNode, Attribute, Children, Node, Point, Position, PossiblyNamed} from "../../src";
44

55
describe('AssertASTsAreEqual', function() {
66
it("the very same node instance compared with itself must pass", function () {
@@ -99,7 +99,7 @@ describe('AssertASTsAreEqual', function() {
9999

100100
@ASTNode("", "SimpleNode")
101101
class SimpleNode extends Node implements PossiblyNamed {
102-
@Property() public name?: string;
102+
@Attribute() public name?: string;
103103
@Children() public subTree: Node[];
104104
constructor(name?: string, subTree: Node[] = []) {
105105
super();
@@ -110,7 +110,7 @@ class SimpleNode extends Node implements PossiblyNamed {
110110

111111
@ASTNode("", "AnotherSimpleNode")
112112
class AnotherSimpleNode extends Node implements PossiblyNamed {
113-
@Property() public name?: string;
113+
@Attribute() public name?: string;
114114
@Children() public subTree: Node[];
115115
constructor(name?: string, subTree: Node[] = []) {
116116
super();
@@ -121,7 +121,7 @@ class AnotherSimpleNode extends Node implements PossiblyNamed {
121121

122122
@ASTNode("", "NodeWithStringSubTree")
123123
class NodeWithStringSubTree extends Node implements PossiblyNamed {
124-
@Property() public name?: string;
124+
@Attribute() public name?: string;
125125
@Children() public subTree?: string;
126126
constructor(name?: string, subTree?: string) {
127127
super();

tests/transformation/transformation.test.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,12 @@ import {expect} from "chai";
22

33
import {
44
ASTNode,
5-
ASTTransformer,
5+
ASTTransformer, Attribute,
66
Child,
77
ErrorNode, GenericErrorNode,
88
IssueSeverity,
99
Node,
1010
pos,
11-
Property,
1211
} from "../../src";
1312

1413
@ASTNode("", "A")
@@ -31,7 +30,7 @@ class A extends Node {
3130
class B extends Node {
3231
@Child()
3332
aChild: Node;
34-
@Property()
33+
@Attribute()
3534
property: number;
3635
other2: string;
3736
notThere: any;

0 commit comments

Comments
 (0)