From afbef33f27ee09b81dbdea3bf9a752bfc78ff9ff Mon Sep 17 00:00:00 2001 From: axetroy Date: Tue, 6 Mar 2018 19:21:57 +0800 Subject: [PATCH] feat: support class property --- README.md | 3 +- src/evaluate.ts | 7 +- test/ClassDeclaration.test.ts | 282 +++++++++++++++++----------------- 3 files changed, 147 insertions(+), 145 deletions(-) diff --git a/README.md b/README.md index 1110b0c0..b984b9f4 100644 --- a/README.md +++ b/README.md @@ -50,13 +50,14 @@ It base on [https://github.com/bramblex/jsjs](https://github.com/bramblex/jsjs) * [ ] RegExp Unicode Property Escapes (Depends on environment) * [ ] Experimental * [x] Object rest spread + * [x] Class property ## Contributors | [
Axetroy](http://axetroy.github.io)
[💻](https://github.com/axetroy/vm.js/commits?author=axetroy) 🔌 [⚠️](https://github.com/axetroy/vm.js/commits?author=axetroy) [🐛](https://github.com/axetroy/vm.js/issues?q=author%3Aaxetroy) 🎨 | -| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | diff --git a/src/evaluate.ts b/src/evaluate.ts index 40557df5..2e840351 100644 --- a/src/evaluate.ts +++ b/src/evaluate.ts @@ -688,7 +688,6 @@ const evaluate_map = { function Class(...args) { _classCallCheck(this, Class); - // TODO: need babel plugin to support class property const newScope = scope.$child("function"); // babel way to call super(); @@ -706,7 +705,9 @@ const evaluate_map = { newScope.$const("this", __this); // define class property - properties.forEach(p => (__this[p.key.name] = p.value)); + properties.forEach(p => { + __this[p.key.name] = evaluate(p.value, newScope); + }); if (constructor) { // defined the params @@ -728,7 +729,7 @@ const evaluate_map = { .map((method: types.ClassMethod) => { const newScope = scope.$child("function"); const func = function(...args) { - newScope.$const("this", this); + newScope.$var("this", this); // defined the params method.params.forEach((p: types.LVal, i) => { diff --git a/test/ClassDeclaration.test.ts b/test/ClassDeclaration.test.ts index 33cf3171..b0425a4f 100644 --- a/test/ClassDeclaration.test.ts +++ b/test/ClassDeclaration.test.ts @@ -3,147 +3,147 @@ import * as fs from "fs"; import vm from "../src/vm"; -// test("ClassDeclaration-contructor", t => { -// const sandbox: any = vm.createContext({}); - -// const People: any = vm.runInContext( -// ` -// class People{ -// constructor(name){ -// this.name = name; -// this.word = "hello " + name; -// } -// } - -// module.exports = People; -// `, -// sandbox -// ); - -// const people = new People("axetroy"); - -// t.deepEqual(people.name, "axetroy"); -// t.deepEqual(people.word, "hello axetroy"); -// t.true(people instanceof People); -// t.true(people.__proto__.constructor === People); -// }); - -// // test("ClassDeclaration-property", t => { -// // const sandbox: any = vm.createContext({}); - -// // const People: any = vm.runInContext( -// // ` -// // class People{ -// // age = 21; -// // constructor(name){ -// // this.name = name; -// // } -// // getAge(){ -// // return this.age; -// // } -// // } - -// // module.exports = People; -// // `, -// // sandbox -// // ); - -// // const people = new People("axetroy"); - -// // t.deepEqual(people.name, "axetroy"); -// // t.deepEqual(people.age, 21); -// // t.deepEqual(people.getAge(), 21); -// // t.true(people instanceof People); -// // }); - -// test("ClassDeclaration-method", t => { -// const sandbox: any = vm.createContext({}); - -// const Base: any = vm.runInContext( -// ` -// class Base{ -// constructor(){ -// this.name = "hello world"; -// } -// say(word){ -// return "hello " + word; -// } -// } - -// module.exports = Base; -// `, -// sandbox -// ); - -// const base = new Base(); - -// t.deepEqual(base.name, "hello world"); -// t.true(base instanceof Base); -// t.deepEqual(base.say("world"), "hello world"); -// }); - -// test("ClassDeclaration-getter and setter", t => { -// const sandbox: any = vm.createContext({}); - -// const People: any = vm.runInContext( -// ` -// class People{ -// constructor(name, age){ -// this.name = name; -// this.__age = age; -// } -// get age(){ -// return this.__age; -// } -// set age(age){ -// this.__age = age; -// } -// } - -// module.exports = People; -// `, -// sandbox -// ); - -// const people = new People("axetroy", 21); - -// t.deepEqual(people.name, "axetroy"); -// t.deepEqual(people.__age, 21); -// t.deepEqual(people.age, 21); -// t.true(people instanceof People); - -// people.age = 22; -// t.deepEqual(people.__age, 22); -// t.deepEqual(people.age, 22); -// }); - -// test("ClassDeclaration-extends", t => { -// const sandbox: any = vm.createContext({}); - -// const {Life, People} = vm.runInContext( -// ` -// class Life{ -// eat(){ - -// } -// } -// class People extends Life{ -// learn(){ - -// } -// } - -// module.exports = { -// Life, -// People -// }; -// `, -// sandbox -// ); -// const people = new People("axetroy"); -// t.deepEqual(typeof people.eat, "function"); // inherti from Life -// t.deepEqual(typeof people.learn, "function"); -// }); +test("ClassDeclaration-contructor", t => { + const sandbox: any = vm.createContext({}); + + const People: any = vm.runInContext( + ` +class People{ + constructor(name){ + this.name = name; + this.word = "hello " + name; + } +} + +module.exports = People; + `, + sandbox + ); + + const people = new People("axetroy"); + + t.deepEqual(people.name, "axetroy"); + t.deepEqual(people.word, "hello axetroy"); + t.true(people instanceof People); + t.true(people.__proto__.constructor === People); +}); + +test("ClassDeclaration-property", t => { + const sandbox: any = vm.createContext({}); + + const People: any = vm.runInContext( + ` +class People{ + age = 21; + constructor(name){ + this.name = name; + } + getAge(){ + return this.age; + } +} + +module.exports = People; + `, + sandbox + ); + + const people = new People("axetroy"); + + t.deepEqual(people.name, "axetroy"); + t.deepEqual(people.age, 21); + t.deepEqual(people.getAge(), 21); + t.true(people instanceof People); +}); + +test("ClassDeclaration-method", t => { + const sandbox: any = vm.createContext({}); + + const Base: any = vm.runInContext( + ` +class Base{ + constructor(){ + this.name = "hello world"; + } + say(word){ + return "hello " + word; + } +} + +module.exports = Base; + `, + sandbox + ); + + const base = new Base(); + + t.deepEqual(base.name, "hello world"); + t.true(base instanceof Base); + t.deepEqual(base.say("world"), "hello world"); +}); + +test("ClassDeclaration-getter and setter", t => { + const sandbox: any = vm.createContext({}); + + const People: any = vm.runInContext( + ` +class People{ + constructor(name, age){ + this.name = name; + this.__age = age; + } + get age(){ + return this.__age; + } + set age(age){ + this.__age = age; + } +} + +module.exports = People; + `, + sandbox + ); + + const people = new People("axetroy", 21); + + t.deepEqual(people.name, "axetroy"); + t.deepEqual(people.__age, 21); + t.deepEqual(people.age, 21); + t.true(people instanceof People); + + people.age = 22; + t.deepEqual(people.__age, 22); + t.deepEqual(people.age, 22); +}); + +test("ClassDeclaration-extends", t => { + const sandbox: any = vm.createContext({}); + + const {Life, People} = vm.runInContext( + ` +class Life{ + eat(){ + + } +} +class People extends Life{ + learn(){ + + } +} + +module.exports = { + Life, + People +}; + `, + sandbox + ); + const people = new People("axetroy"); + t.deepEqual(typeof people.eat, "function"); // inherti from Life + t.deepEqual(typeof people.learn, "function"); +}); test("ClassDeclaration-extends and super", t => { const sandbox: any = vm.createContext({});