diff --git a/ts2panda/src/addVariable2Scope.ts b/ts2panda/src/addVariable2Scope.ts index 8d65f686c1b414aea8763f32e298db82c7ca911c..692d9a1032c426c4f79b9f6468acf1c9b1aabc84 100644 --- a/ts2panda/src/addVariable2Scope.ts +++ b/ts2panda/src/addVariable2Scope.ts @@ -135,7 +135,13 @@ export function addVariableToScope(recorder: Recorder, enableTypeRecord: boolean } else if (decl instanceof ConstDecl) { v = scope.add(decl.name, VarDeclarationKind.CONST, InitStatus.UNINITIALIZED); } else if (decl instanceof FuncDecl) { - v = scope.add(decl.name, VarDeclarationKind.FUNCTION); + let funcNode = decl.node; + if (ts.isFunctionDeclaration(funcNode)) { + v = scope.add(decl.name, VarDeclarationKind.FUNCTION); + } else { + let functionScope = recorder.getScopeOfNode(funcNode); + v = functionScope.add(decl.name, VarDeclarationKind.FUNCTION); + } } else if (decl instanceof CatchParameter) { v = scope.add(decl.name, VarDeclarationKind.LET); } else if (decl instanceof ClassDecl) { diff --git a/ts2panda/src/compiler.ts b/ts2panda/src/compiler.ts index 26268be68da9288178993142f855463db819082e..11bfe99630cfa8ca14a4b25e7f269c4883f17792 100644 --- a/ts2panda/src/compiler.ts +++ b/ts2panda/src/compiler.ts @@ -157,6 +157,7 @@ export class Compiler { } compile() { + this.storeFuncObj2LexEnvIfNeeded(); this.compileLexicalBindingForArrowFunction(); if (this.rootNode.kind == ts.SyntaxKind.SourceFile) { @@ -230,6 +231,22 @@ export class Compiler { } } + private storeFuncObj2LexEnvIfNeeded() { + let rootNode = this.rootNode; + if (!ts.isFunctionExpression(rootNode) || !ts.isMethodDeclaration(rootNode)) { + return; + } + let functionScope = this.recorder.getScopeOfNode(rootNode); + if ((rootNode).name) { + let funcName = jshelpers.getTextOfIdentifierOrLiteral((rootNode).name); + let v = functionScope.find(funcName); + if (v.scope == functionScope) { + this.pandaGen.loadAccumulator(rootNode, getVregisterCache(this.pandaGen, CacheList.FUNC)); + this.pandaGen.storeAccToLexEnv(rootNode, v.scope, v.level, v.v, true); + } + } + } + private compileLexicalBindingForArrowFunction() { let rootNode = this.rootNode; diff --git a/ts2panda/src/recorder.ts b/ts2panda/src/recorder.ts index 75bca228e8cd0177abc0b740518eb5e56b73cdb8..2eb92ab545e9137f829d820ca2132105c2f9d319 100644 --- a/ts2panda/src/recorder.ts +++ b/ts2panda/src/recorder.ts @@ -128,7 +128,7 @@ export class Recorder { case ts.SyntaxKind.SetAccessor: case ts.SyntaxKind.ArrowFunction: { let functionScope = this.buildVariableScope(scope, childNode); - this.recordFuncInfo(childNode); + this.recordOtherFunc(childNode, functionScope); this.recordInfo(childNode, functionScope); break; } @@ -459,6 +459,18 @@ export class Recorder { } } + private recordOtherFunc(node: ts.FunctionLikeDeclaration, scope: Scope) { // functionlikedecalration except function declaration + this.recordFuncInfo(node); + if (!ts.isFunctionExpression(node) && !ts.isMethodDeclaration(node)) { + return; + } + if (node.name && ts.isIdentifier(node.name)) { + let funcName = jshelpers.getTextOfIdentifierOrLiteral(node.name); + let funcDecl = new FuncDecl(funcName, node); + scope.setDecls(funcDecl); + } + } + private recordFuncInfo(node: ts.FunctionLikeDeclaration) { this.recordFunctionParameters(node); this.recordFuncName(node);