Skip to content

Commit

Permalink
[Update] Full support of generator
Browse files Browse the repository at this point in the history
  • Loading branch information
Siubaak committed Mar 8, 2019
1 parent efe24b6 commit 46a5ee5
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 21 deletions.
12 changes: 9 additions & 3 deletions src/evaluate/declaration.ts
Expand Up @@ -3,7 +3,7 @@ import Scope from '../scope'
import evaluate from '.'
import { createFunc, pattern, createClass } from '../share/helper'
import { VarKind } from '../scope/variable'
import { define } from '../share/util'
import { define, getDptor } from '../share/util'

import { Identifier } from './identifier'

Expand Down Expand Up @@ -107,18 +107,24 @@ export function* MethodDefinition(node: estree.MethodDefinition, scope: Scope, o
configurable: true,
})
break
case 'get':
case 'get': {
const oriDptor = getDptor(obj, key)
define(obj, key, {
get: value,
set: oriDptor && oriDptor.set,
configurable: true,
})
break
case 'set':
}
case 'set': {
const oriDptor = getDptor(obj, key)
define(obj, key, {
get: oriDptor && oriDptor.get,
set: value,
configurable: true,
})
break
}
default:
throw new SyntaxError('Unexpected token')
}
Expand Down
6 changes: 5 additions & 1 deletion src/evaluate/expression.ts
Expand Up @@ -378,7 +378,11 @@ export function* ArrowFunctionExpression(node: estree.ArrowFunctionExpression, s
}

export function* YieldExpression(node: estree.YieldExpression, scope: Scope) {
yield yield* evaluate(node.argument, scope)
if (node.delegate) {
yield* yield* evaluate(node.argument, scope)
} else {
yield yield* evaluate(node.argument, scope)
}
}

export function* TemplateLiteral(node: estree.TemplateLiteral, scope: Scope) {
Expand Down
8 changes: 2 additions & 6 deletions src/index.ts
Expand Up @@ -18,12 +18,8 @@ class Sval {
constructor(options: SvalOptions = {}) {
let { ecmaVer, sandBox = true } = options

if (
ecmaVer !== 5
&& ecmaVer !== 6
&& ecmaVer !== 2015
) {
ecmaVer = 6
if ([3, 5, 6, 7, 2015, 2016].indexOf(ecmaVer) === -1) {
ecmaVer = 7
}

this.options.ecmaVersion = ecmaVer
Expand Down
11 changes: 3 additions & 8 deletions src/share/helper.ts
Expand Up @@ -162,14 +162,9 @@ export function* createFunc(
}
}

let func: any
if (node.generator) {
func = tmpGenerator
} else {
func = function (...args: any[]) {
runGenerator(tmpGenerator.bind(this), ...args)
}
}
const func: any = node.generator
? tmpGenerator
: function (...args: any[]) { return runGenerator(tmpGenerator.bind(this), ...args) }

if (node.type === 'FunctionDeclaration') {
define(func, 'name', {
Expand Down
2 changes: 2 additions & 0 deletions src/share/util.ts
Expand Up @@ -2,6 +2,8 @@ export const freeze = Object.freeze

export const define = Object.defineProperty

export const getDptor = Object.getOwnPropertyDescriptor

const hasOwnProperty = Object.prototype.hasOwnProperty
export function hasOwn(obj: any, key: symbol | string): boolean {
return hasOwnProperty.call(obj, key)
Expand Down
11 changes: 8 additions & 3 deletions test/class.test.ts
Expand Up @@ -3,11 +3,15 @@ import Sval from '../src'
describe('testing src/index.ts', () => {
it('should create class normally', () => {
const interpreter = new Sval()
interpreter.import({ JSON })
interpreter.run(`
class A {
constructor() {
this.b = 1
}
p() {
this.b++
}
get k() {
return this.b + 1
}
Expand All @@ -17,9 +21,10 @@ describe('testing src/index.ts', () => {
}
exports.inst = new A()
exports.inst.g = 3
exports.inst.p()
`)
expect(interpreter.exports.inst.b).toBe(3)
expect(interpreter.exports.inst.k).toBe(4)
expect(interpreter.exports.inst.b).toBe(4)
expect(interpreter.exports.inst.k).toBe(5)
})
it('should extend class normally', () => {
const interpreter = new Sval()
Expand Down Expand Up @@ -56,7 +61,7 @@ describe('testing src/index.ts', () => {
super.g = 1
}
}
const k = new c()
const k = new C()
exports.k = k.k
`)
expect(interpreter.exports.k).toBe(1)
Expand Down
16 changes: 16 additions & 0 deletions test/generator.test.ts
Expand Up @@ -19,4 +19,20 @@ describe('testing src/index.ts', () => {
`)
expect(interpreter.exports.res).toEqual([1, 2, 3])
})
it('should proxy generator normally', () => {
const interpreter = new Sval()
interpreter.run(`
function* a() {
yield* [1, 2, 3]
}
const f = a()
let result = f.next()
exports.res = []
while (!result.done) {
exports.res.push(result.value)
result = f.next()
}
`)
expect(interpreter.exports.res).toEqual([1, 2, 3])
})
})

0 comments on commit 46a5ee5

Please sign in to comment.