Skip to content
This repository was archived by the owner on Sep 10, 2023. It is now read-only.

Commit bb6decb

Browse files
committed
fix: fix class will not auto super from super-class
1 parent 269d97c commit bb6decb

File tree

3 files changed

+88
-3
lines changed

3 files changed

+88
-3
lines changed

src/evaluate.ts

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,38 @@ const evaluate_map: EvaluateMap = {
439439
},
440440
ThisExpression(path) {
441441
const {scope} = path;
442+
443+
// TODO: can not use this before super
444+
445+
// let classBodyScope;
446+
// let tempScope = scope;
447+
448+
// while (!classBodyScope) {
449+
// if (!tempScope) break;
450+
// if (tempScope.type === "class") {
451+
// classBodyScope = tempScope;
452+
// } else {
453+
// if (!tempScope.parent) break;
454+
// tempScope = tempScope.parent;
455+
// }
456+
// }
457+
458+
// if (classBodyScope) {
459+
// const classContext = classBodyScope.$find("this");
460+
// const thisExpressionContext = scope.$find("this");
461+
// if (
462+
// classContext &&
463+
// thisExpressionContext &&
464+
// classContext.$get() === thisExpressionContext.$get()
465+
// ) {
466+
// // this and class in same scope
467+
468+
// if (!classBodyScope.$find("@super")) {
469+
// throw ErrNoSuper;
470+
// }
471+
// }
472+
// }
473+
442474
const this_val = scope.$find("this");
443475
return this_val ? this_val.$get() : null;
444476
},
@@ -794,7 +826,7 @@ const evaluate_map: EvaluateMap = {
794826
},
795827
ClassDeclaration(path) {
796828
const ClassConstructor = evaluate(
797-
path.$child(path.node.body, path.scope.$child("block"))
829+
path.$child(path.node.body, path.scope.$child("class"))
798830
);
799831
path.scope.$const(path.node.id.name, ClassConstructor);
800832
},
@@ -854,6 +886,16 @@ const evaluate_map: EvaluateMap = {
854886
throw ErrNoSuper;
855887
}
856888
}
889+
} else {
890+
// apply super
891+
_possibleConstructorReturn(
892+
this,
893+
((<any>Class).__proto__ || Object.getPrototypeOf(Class)).apply(
894+
this,
895+
args
896+
)
897+
);
898+
scope.$const("@super", true);
857899
}
858900

859901
return this;

src/scope.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import {ErrDuplicateDeclard} from "./error";
22
import Context from "./context";
33

4-
export type ScopeType = "function" | "loop" | "switch" | "block";
4+
export type ScopeType = "function" | "loop" | "switch" | "block" | "class";
55

66
export type Kind = "const" | "var" | "let";
77

@@ -32,7 +32,7 @@ export class Scope {
3232

3333
constructor(
3434
public readonly type: ScopeType,
35-
private parent: Scope | null = null,
35+
public parent: Scope | null = null,
3636
label?: string
3737
) {
3838
this.context = new Context();

test/ClassDeclaration.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,46 @@ module.exports = People;
303303
t.deepEqual(People.length, 1);
304304
t.deepEqual(People.name, "People");
305305
});
306+
307+
// test("ClassDeclaration-extends use this before super", t => {
308+
// const sandbox: any = vm.createContext({});
309+
310+
// t.throws(function() {
311+
// vm.runInContext(
312+
// `
313+
// class Life{
314+
// }
315+
// class People extends Life{
316+
// constructor(name){
317+
// this.name = 123; // it should throw an error, use 'this' before super()
318+
// super()
319+
// }
320+
// }
321+
322+
// new People();
323+
// `,
324+
// sandbox
325+
// );
326+
// }, ErrNoSuper.message);
327+
// });
328+
329+
test("ClassDeclaration-extends auto super without constructor", t => {
330+
const sandbox: any = vm.createContext({});
331+
332+
const people = vm.runInContext(
333+
`
334+
class Life{
335+
constructor(){
336+
this.id = 123;
337+
}
338+
}
339+
class People extends Life{
340+
341+
}
342+
343+
module.exports = new People();
344+
`,
345+
sandbox
346+
);
347+
t.deepEqual(people.id, 123);
348+
});

0 commit comments

Comments
 (0)