Skip to content

Commit 1113bce

Browse files
committed
#63 allow abstract classes to be marked as @ASTNode
1 parent 3ed3029 commit 1113bce

File tree

3 files changed

+17
-15
lines changed

3 files changed

+17
-15
lines changed

src/interop/ecore.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,7 @@ export function fromEObject(obj: ECore.EObject | any, parent?: Node): ASTElement
327327
return fromEObject(obj.get("position")) as Position;
328328
}
329329
const ePackage = eClass.eContainer as ECore.EPackage;
330-
const constructor = NODE_TYPES[ePackage.get("name")]?.nodes[eClass.get("name")];
330+
const constructor = NODE_TYPES[ePackage.get("name")]?.nodes[eClass.get("name")] as new (...args: any[]) => Node;
331331
if(constructor) {
332332
const node = new constructor().withParent(parent);
333333
node.parent = parent;

src/model/model.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const NODE_DEFINITION_SYMBOL = Symbol("nodeDefinition");
66

77
export type PackageDescription = {
88
name: string,
9-
nodes: { [name: string]: new (...args: any[]) => Node }
9+
nodes: { [name: string]: abstract new (...args: any[]) => Node }
1010
};
1111
export const NODE_TYPES: { [name: string]: PackageDescription } = {
1212
"": { name: "", nodes: {} }
@@ -29,7 +29,7 @@ export type PropertyDefinition = {
2929
arrayType?: any
3030
}
3131

32-
export function getNodeDefinition(node: Node | (new (...args: any[]) => Node)): NodeDefinition {
32+
export function getNodeDefinition(node: Node | (abstract new (...args: any[]) => Node)): NodeDefinition {
3333
const target = typeof node === "function" ? node : node.constructor;
3434
let definition: NodeDefinition;
3535
if(Object.prototype.hasOwnProperty.call(target, NODE_DEFINITION_SYMBOL)) {
@@ -378,12 +378,14 @@ export function ensurePackage(packageName: string): PackageDescription {
378378
}
379379

380380
export function errorOnRedefinition<T>(
381-
name: string, target: { new(...args: any[]): T }, existingTarget: { new(...args: any[]): Node }): void {
381+
name: string, target: abstract new(...args: any[]) => T, existingTarget: abstract new(...args: any[]) => Node
382+
): void {
382383
throw new Error(`${name} (${target}) is already defined as ${existingTarget}`);
383384
}
384385

385386
export function warnOnRedefinition<T>(
386-
name: string, target: { new(...args: any[]): T }, existingTarget: { new(...args: any[]): Node }): void {
387+
name: string, target: abstract new(...args: any[]) => T , existingTarget: abstract new(...args: any[]) => Node
388+
): void {
387389
console.warn(`Redefining ${name} from`, existingTarget, 'to', target);
388390
}
389391

@@ -394,7 +396,7 @@ export function setNodeRedefinitionStrategy(strategy: typeof errorOnRedefinition
394396
}
395397

396398
export function registerNodeDefinition<T extends Node>(
397-
target: { new(...args: any[]): T }, pkg?: string, name?: string): NodeDefinition {
399+
target: abstract new (...args: any[]) => T, pkg?: string, name?: string): NodeDefinition {
398400
let def: NodeDefinition;
399401
if(pkg !== undefined) {
400402
if (!name) {
@@ -484,7 +486,7 @@ export function registerNodeReference<T extends Node & PossiblyNamed>(
484486
//------------//
485487

486488
export function ASTNode<T extends Node>(pkg: string, name: string) {
487-
return function (target: new (...args: any[]) => T): void {
489+
return function (target: abstract new (...args: any[]) => T): void {
488490
registerNodeDefinition(target, pkg, name);
489491
};
490492
}

tests/ecore.test.ts

+8-8
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,11 @@ export class CompilationUnit extends Node {
247247
\t@Child()
248248
\tstatements;
249249
}`);
250-
let node = new NODE_TYPES["SimpleMM"].nodes["CompilationUnit"]() as any;
251-
expect(node instanceof Node).to.be.true;
250+
let node = new (NODE_TYPES["SimpleMM"].nodes["CompilationUnit"] as any)();
251+
expect(node).to.be.instanceof(Node);
252252
expect(node.constructor[SYMBOL_NODE_NAME]).to.equal("CompilationUnit");
253-
node = new NODE_TYPES["SimpleMM"].nodes["Statement"]() as any;
254-
expect(node instanceof Node).to.be.true;
253+
node = new (NODE_TYPES["SimpleMM"].nodes["Statement"] as any)();
254+
expect(node).to.be.instanceof(Node);
255255
expect(node.constructor[SYMBOL_NODE_NAME]).to.equal("Statement");
256256
//Subclassing
257257
expect(NODE_TYPES["SimpleMM"].nodes["StringLiteral"][SYMBOL_CLASS_DEFINITION]).to.equal(
@@ -260,10 +260,10 @@ export class StringLiteral extends Expression {
260260
\t@Attribute()
261261
\tvalue;
262262
}`);
263-
node = new NODE_TYPES["SimpleMM"].nodes["StringLiteral"]() as any;
264-
expect(node instanceof NODE_TYPES["SimpleMM"].nodes["Expression"]).to.be.true;
265-
expect(node instanceof NODE_TYPES["SimpleMM"].nodes["StringLiteral"]).to.be.true;
266-
expect(node instanceof NODE_TYPES["SimpleMM"].nodes["CompilationUnit"]).to.be.false;
263+
node = new (NODE_TYPES["SimpleMM"].nodes["StringLiteral"] as any)();
264+
expect(node).to.be.instanceof(NODE_TYPES["SimpleMM"].nodes["Expression"]);
265+
expect(node).to.be.instanceof(NODE_TYPES["SimpleMM"].nodes["StringLiteral"]);
266+
expect(node).not.to.be.instanceof(NODE_TYPES["SimpleMM"].nodes["CompilationUnit"]);
267267
expect(node.constructor[SYMBOL_NODE_NAME]).to.equal("StringLiteral");
268268

269269
expect(NODE_TYPES[""].nodes["CompilationUnit"]).to.be.undefined;

0 commit comments

Comments
 (0)