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

Commit

Permalink
fix: fix class will not auto super from super-class
Browse files Browse the repository at this point in the history
  • Loading branch information
axetroy committed Mar 8, 2018
1 parent 269d97c commit bb6decb
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 3 deletions.
44 changes: 43 additions & 1 deletion src/evaluate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,38 @@ const evaluate_map: EvaluateMap = {
},
ThisExpression(path) {
const {scope} = path;

// TODO: can not use this before super

// let classBodyScope;
// let tempScope = scope;

// while (!classBodyScope) {
// if (!tempScope) break;
// if (tempScope.type === "class") {
// classBodyScope = tempScope;
// } else {
// if (!tempScope.parent) break;
// tempScope = tempScope.parent;
// }
// }

// if (classBodyScope) {
// const classContext = classBodyScope.$find("this");
// const thisExpressionContext = scope.$find("this");
// if (
// classContext &&
// thisExpressionContext &&
// classContext.$get() === thisExpressionContext.$get()
// ) {
// // this and class in same scope

// if (!classBodyScope.$find("@super")) {
// throw ErrNoSuper;
// }
// }
// }

const this_val = scope.$find("this");
return this_val ? this_val.$get() : null;
},
Expand Down Expand Up @@ -794,7 +826,7 @@ const evaluate_map: EvaluateMap = {
},
ClassDeclaration(path) {
const ClassConstructor = evaluate(
path.$child(path.node.body, path.scope.$child("block"))
path.$child(path.node.body, path.scope.$child("class"))
);
path.scope.$const(path.node.id.name, ClassConstructor);
},
Expand Down Expand Up @@ -854,6 +886,16 @@ const evaluate_map: EvaluateMap = {
throw ErrNoSuper;
}
}
} else {
// apply super
_possibleConstructorReturn(
this,
((<any>Class).__proto__ || Object.getPrototypeOf(Class)).apply(
this,
args
)
);
scope.$const("@super", true);
}

return this;
Expand Down
4 changes: 2 additions & 2 deletions src/scope.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {ErrDuplicateDeclard} from "./error";
import Context from "./context";

export type ScopeType = "function" | "loop" | "switch" | "block";
export type ScopeType = "function" | "loop" | "switch" | "block" | "class";

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

Expand Down Expand Up @@ -32,7 +32,7 @@ export class Scope {

constructor(
public readonly type: ScopeType,
private parent: Scope | null = null,
public parent: Scope | null = null,
label?: string
) {
this.context = new Context();
Expand Down
43 changes: 43 additions & 0 deletions test/ClassDeclaration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,46 @@ module.exports = People;
t.deepEqual(People.length, 1);
t.deepEqual(People.name, "People");
});

// test("ClassDeclaration-extends use this before super", t => {
// const sandbox: any = vm.createContext({});

// t.throws(function() {
// vm.runInContext(
// `
// class Life{
// }
// class People extends Life{
// constructor(name){
// this.name = 123; // it should throw an error, use 'this' before super()
// super()
// }
// }

// new People();
// `,
// sandbox
// );
// }, ErrNoSuper.message);
// });

test("ClassDeclaration-extends auto super without constructor", t => {
const sandbox: any = vm.createContext({});

const people = vm.runInContext(
`
class Life{
constructor(){
this.id = 123;
}
}
class People extends Life{
}
module.exports = new People();
`,
sandbox
);
t.deepEqual(people.id, 123);
});

0 comments on commit bb6decb

Please sign in to comment.