From b873a301281b25e50b6487b31523fb4b54034baa Mon Sep 17 00:00:00 2001 From: yexiangrun Date: Sun, 4 Sep 2022 21:45:19 +0800 Subject: [PATCH] Record function/this type instead of parameter's type Issue:I5PV3L Test: python3 ./testTs/run_testTs.py --testinstype Signed-off-by: yexiangrun Change-Id: I4ceaf0cf6233665c2ac7311848a113256816ef6d --- .../classExpressions/classExpression3.txt | 3 + .../classExpressions/classExpression4.txt | 1 + ...ifierOnClassExpressionMemberInFunction.txt | 1 + .../quotedConstructors.txt | 14 ++--- .../typeOfThisInStaticMembers.txt | 6 +- .../staticFactory1.txt | 5 +- .../staticPropertyAndFunctionWithSameName.txt | 2 +- .../declarationEmitWorkWithInlineComments.txt | 7 ++- .../constructorTagOnClassConstructor.txt | 2 +- .../declarations/jsDeclarationsThisTypes.txt | 5 +- .../jsdocImplements_namespacedInterface.txt | 6 +- testTs/expect/override/override12.txt | 5 +- testTs/expect/override/override17.txt | 5 +- testTs/instype/recordthis-expected.txt | 22 +++++++ testTs/instype/recordthis.ts | 55 +++++++++++++++++ testTs/run_testTs.py | 61 +++++++++++++++++-- ts2panda/src/base/typeSystem.ts | 17 +++++- ts2panda/src/base/util.ts | 18 +++++- ts2panda/src/compilerDriver.ts | 4 +- ts2panda/src/pandagen.ts | 17 ++++-- ts2panda/src/ts2panda.ts | 58 +++++++++++++----- ts2panda/src/typeChecker.ts | 28 +++------ ts2panda/src/typeRecorder.ts | 12 ++-- .../tests/expression/numericLiteral.test.ts | 10 +-- .../tests/expression/stringLiteral.test.ts | 2 +- ts2panda/tests/expression/thisKeyWord.test.ts | 2 +- ts2panda/tests/lexenv.test.ts | 24 ++++---- ts2panda/tests/pandagen.test.ts | 2 +- ts2panda/tests/regAllocator.test.ts | 4 +- 29 files changed, 298 insertions(+), 100 deletions(-) create mode 100644 testTs/instype/recordthis-expected.txt create mode 100644 testTs/instype/recordthis.ts diff --git a/testTs/expect/classes/classExpressions/classExpression3.txt b/testTs/expect/classes/classExpressions/classExpression3.txt index 5cb9a64cdd..a45bae7ac3 100644 --- a/testTs/expect/classes/classExpressions/classExpression3.txt +++ b/testTs/expect/classes/classExpressions/classExpression3.txt @@ -1,3 +1,6 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 102}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'c'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 103}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'b'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'a'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 103}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 102}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} \ No newline at end of file diff --git a/testTs/expect/classes/classExpressions/classExpression4.txt b/testTs/expect/classes/classExpressions/classExpression4.txt index 641f5a666c..687b042c50 100644 --- a/testTs/expect/classes/classExpressions/classExpression4.txt +++ b/testTs/expect/classes/classExpressions/classExpression4.txt @@ -1,2 +1,3 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 102}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} \ No newline at end of file diff --git a/testTs/expect/classes/classExpressions/modifierOnClassExpressionMemberInFunction.txt b/testTs/expect/classes/classExpressions/modifierOnClassExpressionMemberInFunction.txt index 364cc84a4e..c023f20fc9 100644 --- a/testTs/expect/classes/classExpressions/modifierOnClassExpressionMemberInFunction.txt +++ b/testTs/expect/classes/classExpressions/modifierOnClassExpressionMemberInFunction.txt @@ -1,3 +1,4 @@ {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'g'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'prop1'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 103}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'prop2'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 102}]} \ No newline at end of file diff --git a/testTs/expect/classes/constructorDeclarations/quotedConstructors.txt b/testTs/expect/classes/constructorDeclarations/quotedConstructors.txt index ff03b64350..df7858f545 100644 --- a/testTs/expect/classes/constructorDeclarations/quotedConstructors.txt +++ b/testTs/expect/classes/constructorDeclarations/quotedConstructors.txt @@ -1,12 +1,12 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 102}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 104}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 105}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5}, {'t': 2, 'v': 106}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 104}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5}, {'t': 2, 'v': 108}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 108}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 103}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 105}]} {'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 107}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 111}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 110}]} \ No newline at end of file diff --git a/testTs/expect/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers.txt b/testTs/expect/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers.txt index 7c40a304e1..56f92214de 100644 --- a/testTs/expect/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers.txt +++ b/testTs/expect/classes/members/instanceAndStaticMembers/typeOfThisInStaticMembers.txt @@ -1,8 +1,8 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 102}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'bar'}, {'t': 2, 'v': 103}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 2, 'v': 1}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 4}, {'t': 5, 'v': 'bar'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 105}, {'t': 2, 'v': 2}, {'t': 5, 'v': 'test'}, {'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 4}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'bar'}, {'t': 2, 'v': 106}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 106}, {'t': 2, 'v': 2}, {'t': 5, 'v': 'test'}, {'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 4}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'bar'}, {'t': 2, 'v': 107}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 2, 'v': 4}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 4}, {'t': 5, 'v': 'bar'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 104}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 105}]} \ No newline at end of file diff --git a/testTs/expect/classes/propertyMemberDeclarations/memberFunctionDeclarations/staticFactory1.txt b/testTs/expect/classes/propertyMemberDeclarations/memberFunctionDeclarations/staticFactory1.txt index dd061241b4..9f5e73eede 100644 --- a/testTs/expect/classes/propertyMemberDeclarations/memberFunctionDeclarations/staticFactory1.txt +++ b/testTs/expect/classes/propertyMemberDeclarations/memberFunctionDeclarations/staticFactory1.txt @@ -1,6 +1,7 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 102}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'create'}, {'t': 2, 'v': 103}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 4}, {'t': 5, 'v': 'create'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 101}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 105}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 101}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 106}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'foo'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 104}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 105}]} \ No newline at end of file diff --git a/testTs/expect/classes/propertyMemberDeclarations/staticPropertyAndFunctionWithSameName.txt b/testTs/expect/classes/propertyMemberDeclarations/staticPropertyAndFunctionWithSameName.txt index 1dbe373f72..0f7b38b576 100644 --- a/testTs/expect/classes/propertyMemberDeclarations/staticPropertyAndFunctionWithSameName.txt +++ b/testTs/expect/classes/propertyMemberDeclarations/staticPropertyAndFunctionWithSameName.txt @@ -1,5 +1,5 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'f'}, {'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'f'}, {'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'f'}, {'t': 2, 'v': 103}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'f'}, {'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'f'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} {'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 102}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} \ No newline at end of file diff --git a/testTs/expect/declarationEmit/declarationEmitWorkWithInlineComments.txt b/testTs/expect/declarationEmit/declarationEmitWorkWithInlineComments.txt index ca42648726..55e47aed44 100644 --- a/testTs/expect/declarationEmit/declarationEmitWorkWithInlineComments.txt +++ b/testTs/expect/declarationEmit/declarationEmitWorkWithInlineComments.txt @@ -1,6 +1,9 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 102}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 10}, {'t': 2, 'v': 4}, {'t': 2, 'v': 4}, {'t': 2, 'v': 4}, {'t': 2, 'v': 4}, {'t': 2, 'v': 4}, {'t': 2, 'v': 4}, {'t': 2, 'v': 4}, {'t': 2, 'v': 4}, {'t': 2, 'v': 4}, {'t': 2, 'v': 4}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 104}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 105}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 2, 'v': 4}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 106}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 104}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 108}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 2, 'v': 4}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 107}]} \ No newline at end of file diff --git a/testTs/expect/jsdoc/constructorTagOnClassConstructor.txt b/testTs/expect/jsdoc/constructorTagOnClassConstructor.txt index 6987c24a26..d00b2a8b62 100644 --- a/testTs/expect/jsdoc/constructorTagOnClassConstructor.txt +++ b/testTs/expect/jsdoc/constructorTagOnClassConstructor.txt @@ -1,5 +1,5 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 103}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'constructor'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} {'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 102}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} \ No newline at end of file diff --git a/testTs/expect/jsdoc/declarations/jsDeclarationsThisTypes.txt b/testTs/expect/jsdoc/declarations/jsDeclarationsThisTypes.txt index 8279cebd73..efed675887 100644 --- a/testTs/expect/jsdoc/declarations/jsDeclarationsThisTypes.txt +++ b/testTs/expect/jsdoc/declarations/jsDeclarationsThisTypes.txt @@ -1,5 +1,6 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'method'}, {'t': 2, 'v': 102}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'method'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 101}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'verify'}, {'t': 2, 'v': 104}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 101}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'verify'}, {'t': 2, 'v': 105}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'verify'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 103}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 104}]} \ No newline at end of file diff --git a/testTs/expect/jsdoc/jsdocImplements_namespacedInterface.txt b/testTs/expect/jsdoc/jsdocImplements_namespacedInterface.txt index 7c23f003f9..3a68dbe013 100644 --- a/testTs/expect/jsdoc/jsdocImplements_namespacedInterface.txt +++ b/testTs/expect/jsdoc/jsdocImplements_namespacedInterface.txt @@ -1,6 +1,6 @@ {'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'mNumber'}, {'t': 2, 'v': 102}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'mNumber'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'gen'}, {'t': 2, 'v': 104}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} -{'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'gen'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 103}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}, {'t': 5, 'v': 'gen'}, {'t': 2, 'v': 105}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'gen'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 104}]} \ No newline at end of file diff --git a/testTs/expect/override/override12.txt b/testTs/expect/override/override12.txt index e94bb50f9c..2f8070856f 100644 --- a/testTs/expect/override/override12.txt +++ b/testTs/expect/override/override12.txt @@ -2,8 +2,9 @@ {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm1'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm2'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm3'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 3}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 101}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 3}, {'t': 5, 'v': 'm1'}, {'t': 2, 'v': 106}, {'t': 5, 'v': 'm2'}, {'t': 2, 'v': 107}, {'t': 5, 'v': 'm3'}, {'t': 2, 'v': 108}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 101}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 3}, {'t': 5, 'v': 'm1'}, {'t': 2, 'v': 107}, {'t': 5, 'v': 'm2'}, {'t': 2, 'v': 108}, {'t': 5, 'v': 'm3'}, {'t': 2, 'v': 109}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm1'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm2'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm3'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 3}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 105}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 106}]} \ No newline at end of file diff --git a/testTs/expect/override/override17.txt b/testTs/expect/override/override17.txt index e94bb50f9c..2f8070856f 100644 --- a/testTs/expect/override/override17.txt +++ b/testTs/expect/override/override17.txt @@ -2,8 +2,9 @@ {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm1'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm2'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm3'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 3}]} -{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 101}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 3}, {'t': 5, 'v': 'm1'}, {'t': 2, 'v': 106}, {'t': 5, 'v': 'm2'}, {'t': 2, 'v': 107}, {'t': 5, 'v': 'm3'}, {'t': 2, 'v': 108}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 101}]} +{'lb': [{'t': 2, 'v': 1}, {'t': 2, 'v': 0}, {'t': 2, 'v': 101}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 3}, {'t': 5, 'v': 'm1'}, {'t': 2, 'v': 107}, {'t': 5, 'v': 'm2'}, {'t': 2, 'v': 108}, {'t': 5, 'v': 'm3'}, {'t': 2, 'v': 109}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm1'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm2'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 1}]} {'lb': [{'t': 2, 'v': 3}, {'t': 2, 'v': 0}, {'t': 5, 'v': 'm3'}, {'t': 2, 'v': 0}, {'t': 2, 'v': 0}, {'t': 2, 'v': 3}]} -{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 105}]} +{'lb': [{'t': 2, 'v': 2}, {'t': 2, 'v': 106}]} \ No newline at end of file diff --git a/testTs/instype/recordthis-expected.txt b/testTs/instype/recordthis-expected.txt new file mode 100644 index 0000000000..ea841a5f92 --- /dev/null +++ b/testTs/instype/recordthis-expected.txt @@ -0,0 +1,22 @@ +Handle types for function: #1#A +(instruction order, type): (-2, 111), (-1, 106), +Handle types for function: getName +(instruction order, type): (-2, 111), (-1, 102), +Handle types for function: getId +(instruction order, type): (-2, 111), (-1, 103), +Handle types for function: setName +(instruction order, type): (-2, 111), (-1, 104), +Handle types for function: setId +(instruction order, type): (-2, 111), (-1, 105), +Handle types for function: dump +(instruction order, type): (-2, 111), (-1, 107), (14, 4), +Handle types for function: stest +(instruction order, type): (-2, 101), (-1, 108), +Handle types for function: test +(instruction order, type): (-2, 111), (-1, 109), +Handle types for function: testwiththis +(instruction order, type): (-2, 111), (-1, 110), +Handle types for function: add +(instruction order, type): (-1, 112), (9, 1), +Handle types for function: func_main_0 +(instruction order, type): diff --git a/testTs/instype/recordthis.ts b/testTs/instype/recordthis.ts new file mode 100644 index 0000000000..c032ae27be --- /dev/null +++ b/testTs/instype/recordthis.ts @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class A { + name: string = "A"; + id: number = 0; + get getName(): string { + return this.name; + } + get getId() { + return this.id; + } + set setName(name: string) { + this.name = name; + } + set setId(id: number) { + this.id = id; + } + constructor() { + this.id = 95; + } + dump(): string { + let msg: string = this.name + ":" + this.id; + return msg; + } + static a: number = 1; + a: number = 2; + static stest() { + console.log(this.a); + } + test() { + console.log(this.a); + } + testwiththis(this: A) { + console.log(this.a); + } +} + +function add(x: number, y: number): number { + let z: number = x + y; + this.z = z; + return z; +} diff --git a/testTs/run_testTs.py b/testTs/run_testTs.py index bbc1637553..3ab0e31f67 100644 --- a/testTs/run_testTs.py +++ b/testTs/run_testTs.py @@ -25,6 +25,7 @@ import datetime import sys import shutil import json +from glob import glob from utils import * from config import * @@ -36,6 +37,7 @@ class MyException(Exception): def parse_args(): parser = argparse.ArgumentParser() + parser.add_argument('--testinstype', action='store_true', dest='testinstype', default=False, help="ins type test") parser.add_argument('--dir', metavar='DIR', help="Directory to test") parser.add_argument('--file', metavar='FILE', help="File to test") parser.add_argument( @@ -276,13 +278,64 @@ def prepare_ts_code(): print("pull test code fail") +def test_instype(args): + # output path for abc file generation + outpath = os.path.join(OUT_TEST_DIR, 'instype') + mk_dir(outpath) + + # source ts files + files = glob('./testTs/instype/*.ts'); + ark_frontend_tool = DEFAULT_ARK_FRONTEND_TOOL + if args.ark_frontend_tool: + ark_frontend_tool = args.ark_frontend_tool + + fail_list = [] + for file in files: + abc_file = os.path.abspath(os.path.join(outpath, '%s.abc' % os.path.splitext(os.path.basename(file))[0])) + cmd = ['node', '--expose-gc', ark_frontend_tool, os.path.abspath(file), '--display-typeinfo', '-o', abc_file]; + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + try: + out, err = process.communicate(timeout=10) + except subprocess.TimeoutExpired: + process.kill() + fail_list.append(file) + print("TIMEOUT:", " ".join(cmd)) + continue + output = out.decode("utf-8", errors="ignore") + err.decode("utf-8", errors="ignore") + + expected_file = "%s-expected.txt" % (os.path.splitext(file)[0]) + expected = "" + try: + with open(expected_file, 'r') as expected_fp: + expected = expected_fp.read() + passed = expected == output + except Exception: + passed = False + if not passed: + fail_list.append(file) + print("FAILED:", " ".join(cmd)) + print("output:") + print(output) + print("expected:") + print(expected) + + print("Summary:") + print("\033[37mTotal: %5d" % (len(files))) + print("\033[92mPassed: %5d" % (len(files) - len(fail_list))) + print("\033[91mFailed: %5d" % (len(fail_list))) + print("\033[0m") + + def main(args): try: init_path() - excuting_npm_install(args) - prepare_ts_code() - run_test_machine(args) - summary() + if (args.testinstype): + test_instype(args) + else: + excuting_npm_install(args) + prepare_ts_code() + run_test_machine(args) + summary() except BaseException: print("Run Python Script Fail") diff --git a/ts2panda/src/base/typeSystem.ts b/ts2panda/src/base/typeSystem.ts index ee2226bbcb..43bdf6e64f 100644 --- a/ts2panda/src/base/typeSystem.ts +++ b/ts2panda/src/base/typeSystem.ts @@ -24,6 +24,7 @@ import { LiteralBuffer, LiteralTag } from "./literal"; +import { hasAbstractModifier } from "./util"; import { CmdOptions } from "../cmdOptions"; export enum PrimitiveType { @@ -258,13 +259,15 @@ export class ClassType extends BaseType { methods: Map = new Map(); typeIndex: number; shiftedTypeIndex: number; + field_with_init_num: number = 0; + method_with_body_num: number = 0; constructor(classNode: ts.ClassDeclaration | ts.ClassExpression, builtinTypeIdx: number = undefined) { super(); let res = this.calculateIndex(builtinTypeIdx); this.typeIndex = res.typeIndex; this.shiftedTypeIndex = res.shiftedTypeIndex; - + // record type before its initialization, so its index can be recorded // in case there's recursive reference of this type this.addCurrentType(classNode, this.shiftedTypeIndex); @@ -275,6 +278,12 @@ export class ClassType extends BaseType { if (!builtinTypeIdx || isGlobalDeclare()) { this.setTypeArrayBuffer(this, this.typeIndex); } + + // create class instance type used by recording 'this' later + if ((this.method_with_body_num > 0 || this.field_with_init_num > 0) && !hasAbstractModifier(classNode)) { + let instTypeIdx = this.typeChecker.getOrCreateInstanceType(this.shiftedTypeIndex); + this.typeRecorder.addUserDefinedTypeSet(instTypeIdx); + } } private fillInModifiers(node: ts.ClassDeclaration | ts.ClassExpression) { @@ -348,6 +357,9 @@ export class ClassType extends BaseType { this.staticFields.set(fieldName, fieldInfo); } else { this.fields.set(fieldName, fieldInfo); + if (member.initializer != undefined) { + this.field_with_init_num++; + } } } @@ -372,6 +384,9 @@ export class ClassType extends BaseType { this.staticMethods.set(funcType.getFunctionName(), typeIndex!); } else { this.methods.set(funcType.getFunctionName(), typeIndex!); + if (member.body != undefined) { + this.method_with_body_num++; + } } } diff --git a/ts2panda/src/base/util.ts b/ts2panda/src/base/util.ts index 3662772e19..7f2742eb4a 100644 --- a/ts2panda/src/base/util.ts +++ b/ts2panda/src/base/util.ts @@ -338,4 +338,20 @@ export function transformCommonjsModule(sourceFile: ts.SourceFile) { ))]; return ts.factory.updateSourceFile(sourceFile, newStatements); -} \ No newline at end of file +} + +export function hasAbstractModifier(node: ts.Node): boolean { + if (!node.modifiers) { + return false; + } + for (let modifier of node.modifiers) { + switch (modifier.kind) { + case ts.SyntaxKind.AbstractKeyword: { + return true; + } + default: + break; + } + } + return false; +} diff --git a/ts2panda/src/compilerDriver.ts b/ts2panda/src/compilerDriver.ts index 7c98513005..934449b3a2 100644 --- a/ts2panda/src/compilerDriver.ts +++ b/ts2panda/src/compilerDriver.ts @@ -218,7 +218,7 @@ export class CompilerDriver { private compileImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, internalName: string, recorder: Recorder): void { - let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); + let pandaGen = new PandaGen(internalName, node, this.getParametersCount(node), scope); if (CmdOptions.needRecordSourceCode() && !ts.isSourceFile(node)) { // souceCode of [ts.sourceFile] will be record in debugInfo later. @@ -269,7 +269,7 @@ export class CompilerDriver { private compileUnitTestImpl(node: ts.SourceFile | ts.FunctionLikeDeclaration, scope: Scope, internalName: string, recorder: Recorder) { - let pandaGen = new PandaGen(internalName, this.getParametersCount(node), scope); + let pandaGen = new PandaGen(internalName, node, this.getParametersCount(node), scope); if (CmdOptions.needRecordSourceCode() && !ts.isSourceFile(node)) { pandaGen.setSourceCode(node.getText()); } diff --git a/ts2panda/src/pandagen.ts b/ts2panda/src/pandagen.ts index 4a43d4f83d..9680b19894 100644 --- a/ts2panda/src/pandagen.ts +++ b/ts2panda/src/pandagen.ts @@ -196,6 +196,7 @@ export class PandaGen { // @ts-ignore private debugTag: string = "PandaGen"; readonly internalName: string; + private node: ts.SourceFile | ts.FunctionLikeDeclaration; private parametersCount: number; private locals: VReg[] = []; private temps: VReg[] = []; @@ -214,8 +215,10 @@ export class PandaGen { private static literalArrayBuffer: Array = new Array(); - constructor(internalName: string, parametersCount: number, scope: Scope | undefined = undefined) { + constructor(internalName: string, node: ts.SourceFile | ts.FunctionLikeDeclaration, + parametersCount: number, scope: Scope | undefined = undefined) { this.internalName = internalName; + this.node = node; this.parametersCount = parametersCount; this.scope = scope; this.vregisterCache = new VregisterCache(); @@ -409,10 +412,6 @@ export class PandaGen { this.locals = locals; } - getInstTypeMap() { - return this.instTypeMap; - } - getLocals(): VReg[] { return this.locals; } @@ -421,6 +420,14 @@ export class PandaGen { return this.temps; } + getInstTypeMap() { + return this.instTypeMap; + } + + getNode() { + return this.node; + } + storeAccumulator(node: ts.Node | NodeKind, vreg: VReg) { this.add(node, storeAccumulator(vreg)); } diff --git a/ts2panda/src/ts2panda.ts b/ts2panda/src/ts2panda.ts index 0a7f54dc14..ce26b5286e 100644 --- a/ts2panda/src/ts2panda.ts +++ b/ts2panda/src/ts2panda.ts @@ -13,6 +13,7 @@ * limitations under the License. */ +import * as ts from "typescript"; import { CmdOptions } from "./cmdOptions"; import { SourceTextModuleRecord } from "./ecmaModule"; import { @@ -42,15 +43,17 @@ import { generateCatchTables } from "./statement/tryStatement"; import { escapeUnicode, isRangeInst, - getRangeStartVregPos + getRangeStartVregPos, + getRecordTypeFlag } from "./base/util"; import { LiteralBuffer } from "./base/literal"; +import { PrimitiveType, BuiltinType } from "./base/typeSystem"; import { CompilerDriver } from "./compilerDriver"; +import { hasStaticModifier } from "./jshelpers"; import { ModuleScope } from "./scope"; -import { getRecordTypeFlag } from "./base/util"; -import { PrimitiveType, BuiltinType } from "./base/typeSystem"; import { TypeRecorder } from "./typeRecorder"; import { isGlobalDeclare } from "./strictMode"; +import { isFunctionLikeDeclaration } from "./syntaxCheckHelper"; const dollarSign: RegExp = /\$/g; @@ -235,24 +238,49 @@ export class Ts2Panda { continue; } - // local vreg -> inst - let vreg = undefined; - let instIdx = i; + // skip arg type if (i < paraCount && inst.kind == IRNodeKind.MOV_DYN) { - vreg = (inst.operands[0] as VReg).num; + let vreg = (inst.operands[0] as VReg).num; let arg = (inst.operands[1] as VReg).num; if (vreg >= paraCount || arg < vregCount) { continue; // not arg } - // param's inst idx start from -1 - instIdx = vregCount - arg - 1; - } else if (inst.kind == IRNodeKind.STA_DYN) { - vreg = (inst.operands[0] as VReg).num; - } - if (vreg != undefined && vreg < locals.length && !handledSet.has(vreg)) { - typeIdx = locals[vreg].getTypeIndex(); - instTypeMap.set(instIdx, typeIdx); + // no need to record arg type handledSet.add(vreg); + continue; + } + + // local vreg -> inst + if (inst.kind == IRNodeKind.STA_DYN) { + let vreg = (inst.operands[0] as VReg).num; + if (vreg < locals.length && !handledSet.has(vreg)) { + typeIdx = locals[vreg].getTypeIndex(); + instTypeMap.set(i, typeIdx); + handledSet.add(vreg); + } + } + } + + // add function/this type + let functionNode = pg.getNode(); + let typeRecorder = TypeRecorder.getInstance(); + if (typeRecorder != undefined && isFunctionLikeDeclaration(functionNode)) { + // -1 for function type + const functionTypeIndex = -1; + let typeIdx = typeRecorder.tryGetTypeIndex(ts.getOriginalNode(functionNode)); + instTypeMap.set(functionTypeIndex, typeIdx); + + // -2 for this type + let classNode = functionNode.parent; + if (ts.isClassLike(classNode)) { + const thisTypeIndex = -2; + typeIdx = typeRecorder.tryGetTypeIndex(ts.getOriginalNode(classNode)); + if (!hasStaticModifier(functionNode)) { + typeIdx = typeRecorder.getClass2InstanceMap(typeIdx); + } + if (typeIdx != undefined) { + instTypeMap.set(thisTypeIndex, typeIdx); + } } } diff --git a/ts2panda/src/typeChecker.ts b/ts2panda/src/typeChecker.ts index 3e4a2530ff..a9ec53df8f 100644 --- a/ts2panda/src/typeChecker.ts +++ b/ts2panda/src/typeChecker.ts @@ -140,11 +140,7 @@ export class TypeChecker { classTypeIndex = classType.shiftedTypeIndex; } if (getTypeForInstace) { - // class type was already created, need to get the classInstance - if (!TypeRecorder.getInstance().hasClass2InstanceMap(classTypeIndex)) { - new ClassInstType(classTypeIndex); - } - classTypeIndex = TypeRecorder.getInstance().getClass2InstanceMap(classTypeIndex)!; + classTypeIndex = this.getOrCreateInstanceType(classTypeIndex); } return classTypeIndex; } @@ -171,7 +167,7 @@ export class TypeChecker { let interefaceType = new InterfaceType(typeDeclNode); interfaceTypeIndex = interefaceType.shiftedTypeIndex; } - return interfaceTypeIndex; + return interfaceTypeIndex; } public getTypeFromDecl(typeDeclNode: ts.Node, getTypeForInstace: boolean): number { @@ -247,12 +243,12 @@ export class TypeChecker { return node.getSourceFile().hasNoDefaultLib; } - getOrCreateInstanceTypeForBuiltin(builtinIdx: number) { + getOrCreateInstanceType(classTypeIdx: number) { let typeRec = TypeRecorder.getInstance(); - if (typeRec.hasClass2InstanceMap(builtinIdx)) { - return typeRec.getClass2InstanceMap(builtinIdx); + if (typeRec.hasClass2InstanceMap(classTypeIdx)) { + return typeRec.getClass2InstanceMap(classTypeIdx); } - let instanceType = new ClassInstType(builtinIdx); + let instanceType = new ClassInstType(classTypeIdx); return instanceType.shiftedTypeIndex; } @@ -263,11 +259,7 @@ export class TypeChecker { } let builtinContainerType = new BuiltinContainerType(builtinContainerSignature); let builtinContainerTypeIdx = builtinContainerType.shiftedTypeIndex; - if (typeRec.hasClass2InstanceMap(builtinContainerTypeIdx)) { - return typeRec.getClass2InstanceMap(builtinContainerTypeIdx); - } - let instanceType = new ClassInstType(builtinContainerTypeIdx); - return instanceType.shiftedTypeIndex; + return this.getOrCreateInstanceType(builtinContainerTypeIdx); } getBuiltinTypeIndex(expr: ts.NewExpression) { @@ -286,14 +278,14 @@ export class TypeChecker { } return this.getOrCreateInstanceTypeForBuiltinContainer(builtinContainerSignature); } - return this.getOrCreateInstanceTypeForBuiltin(BuiltinType[name]); + return this.getOrCreateInstanceType(BuiltinType[name]); } public getOrCreateRecordForDeclNode(initializer: ts.Node | undefined, variableNode?: ts.Node) { if (!initializer) { return PrimitiveType.ANY; } - + let typeIndex = PrimitiveType.ANY; if (initializer.kind == ts.SyntaxKind.NewExpression && this.isBuiltinType(initializer)) { typeIndex = this.getBuiltinTypeIndex(initializer); @@ -357,7 +349,7 @@ export class TypeChecker { let classType = new ClassType(classDeclNode, BuiltinType[className]); typeIndex = classType.shiftedTypeIndex; } - + if (this.hasExportKeyword(classDeclNode)) { TypeRecorder.getInstance().setExportedType(className, typeIndex); } else if (this.hasDeclareKeyword(classDeclNode) && isGlobalDeclare()) { diff --git a/ts2panda/src/typeRecorder.ts b/ts2panda/src/typeRecorder.ts index 3baff2ea18..cb9cdee40f 100644 --- a/ts2panda/src/typeRecorder.ts +++ b/ts2panda/src/typeRecorder.ts @@ -59,7 +59,9 @@ export class TypeRecorder { } public addUserDefinedTypeSet(index: number) { - this.userDefinedTypeSet.add(index); + if (index > userDefinedTypeStartIndex) { + this.userDefinedTypeSet.add(index); + } } public countUserDefinedTypeSet(): number { @@ -68,16 +70,12 @@ export class TypeRecorder { public addType2Index(typeNode: ts.Node, index: number) { this.type2Index.set(typeNode, index); - if (index > userDefinedTypeStartIndex) { - this.addUserDefinedTypeSet(index); - } + this.addUserDefinedTypeSet(index); } public setVariable2Type(variableNode: ts.Node, index: number) { this.variable2Type.set(variableNode, index); - if (index > userDefinedTypeStartIndex) { - this.addUserDefinedTypeSet(index); - } + this.addUserDefinedTypeSet(index); } public hasType(typeNode: ts.Node): boolean { diff --git a/ts2panda/tests/expression/numericLiteral.test.ts b/ts2panda/tests/expression/numericLiteral.test.ts index 467721ea3f..2444d29d9b 100644 --- a/ts2panda/tests/expression/numericLiteral.test.ts +++ b/ts2panda/tests/expression/numericLiteral.test.ts @@ -29,7 +29,7 @@ import { checkInstructions } from "../utils/base"; describe("compileNumericLiteral", function () { it("NaN", function () { - let pandaGen = new PandaGen("ignored", 0, undefined); + let pandaGen = new PandaGen("ignored", undefined, 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("NaN"); compileNumericLiteral(pandaGen, node); let insns = pandaGen.getInsns(); @@ -38,7 +38,7 @@ describe("compileNumericLiteral", function () { }); it("Infinity", function () { - let pandaGen = new PandaGen("ignored", 0, undefined); + let pandaGen = new PandaGen("ignored", undefined, 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("10e10000"); compileNumericLiteral(pandaGen, node); let insns = pandaGen.getInsns(); @@ -46,7 +46,7 @@ describe("compileNumericLiteral", function () { expect(checkInstructions(insns, expected)).to.be.true; }); it("int", function () { - let pandaGen = new PandaGen("ignored", 0, undefined); + let pandaGen = new PandaGen("ignored", undefined, 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("1"); compileNumericLiteral(pandaGen, node); let insns = pandaGen.getInsns(); @@ -54,7 +54,7 @@ describe("compileNumericLiteral", function () { expect(checkInstructions(insns, expected)).to.be.true; }); it("Integer overflow", function () { - let pandaGen = new PandaGen("ignored", 0, undefined); + let pandaGen = new PandaGen("ignored", undefined, 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("2147483648"); compileNumericLiteral(pandaGen, node); let insns = pandaGen.getInsns(); @@ -62,7 +62,7 @@ describe("compileNumericLiteral", function () { expect(checkInstructions(insns, expected)).to.be.true; }); it("double", function () { - let pandaGen = new PandaGen("ignored", 0, undefined); + let pandaGen = new PandaGen("ignored", undefined, 0, undefined); let node: ts.NumericLiteral = ts.createNumericLiteral("1.1"); compileNumericLiteral(pandaGen, node); let insns = pandaGen.getInsns(); diff --git a/ts2panda/tests/expression/stringLiteral.test.ts b/ts2panda/tests/expression/stringLiteral.test.ts index cf56ba16dc..d421d78a65 100644 --- a/ts2panda/tests/expression/stringLiteral.test.ts +++ b/ts2panda/tests/expression/stringLiteral.test.ts @@ -24,7 +24,7 @@ import { checkInstructions } from "../utils/base"; describe("compileStringLiteral", function () { it("i am a string", function () { - let pandaGen = new PandaGen("ignored", 0, undefined); + let pandaGen = new PandaGen("ignored", undefined, 0, undefined); let node: ts.StringLiteral = ts.createStringLiteral("i am a string"); compileStringLiteral(pandaGen, node); let insns = pandaGen.getInsns(); diff --git a/ts2panda/tests/expression/thisKeyWord.test.ts b/ts2panda/tests/expression/thisKeyWord.test.ts index 186c2d2b94..e88f39146d 100644 --- a/ts2panda/tests/expression/thisKeyWord.test.ts +++ b/ts2panda/tests/expression/thisKeyWord.test.ts @@ -30,7 +30,7 @@ describe("ThisKeyword", function () { let pandaGen: PandaGen; beforeEach(function () { - pandaGen = new PandaGen("" /* internalName */, 0 /* number of parameters */); + pandaGen = new PandaGen("" /* internalName */, undefined, 0 /* number of parameters */); }); it("this in global scope", function () { diff --git a/ts2panda/tests/lexenv.test.ts b/ts2panda/tests/lexenv.test.ts index a2180a6a15..a57433b157 100644 --- a/ts2panda/tests/lexenv.test.ts +++ b/ts2panda/tests/lexenv.test.ts @@ -235,10 +235,10 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { * the function inherit chart, total IIFE expression * +---------+ * | global | - * +---.-----+ - * .` `. - * .` `, - * .` ', + * +---.-----+ + * .` `. + * .` `, + * .` ', * +-----`--+ +----'---+ * | 1 | | 2 | * +--------+ +----/---+ @@ -247,9 +247,9 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { * | * +----\---+ * | 3 | - * +--,.-,--+ - * ,-` `. - * .'` `. + * +--,.-,--+ + * ,-` `. + * .'` `. * +----'`-+ +---'--+ * | 4 | | 5 | * +-------+ +------+ @@ -289,7 +289,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { it("test loadAccFromLexEnv with local variable", function () { let globalScope = new GlobalScope(); - let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); + let pandaGen = new PandaGen("lexVarPassPandaGen", undefined, 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.LET); let funcObj = globalScope.add("4funcObj", VarDeclarationKind.LET); funcObj!.bindVreg(new VReg()); @@ -311,7 +311,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { it("test loadAccFromLexEnv with lex env variable", function () { let globalScope = new GlobalScope(); - let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); + let pandaGen = new PandaGen("lexVarPassPandaGen", undefined, 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.LET); let funcObj = globalScope.add("4funcObj", VarDeclarationKind.LET); funcObj!.bindVreg(new VReg()); @@ -337,7 +337,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { it("test storeAccFromLexEnv with local variable", function () { let globalScope = new GlobalScope(); - let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); + let pandaGen = new PandaGen("lexVarPassPandaGen", undefined, 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.LET); let pass = new CacheExpander(); let varReg = pandaGen.getVregForVariable(var1!); @@ -356,7 +356,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { it("test storeAccFromLexEnv with lex env let-variable", function () { let globalScope = new GlobalScope(); - let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); + let pandaGen = new PandaGen("lexVarPassPandaGen", undefined, 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.LET); let funcObj = globalScope.add("4funcObj", VarDeclarationKind.LET); funcObj!.bindVreg(new VReg()); @@ -379,7 +379,7 @@ describe("lexenv-compile-testcase in lexenv.test.ts", function () { it("test storeAccFromLexEnv with lex env const-variable", function () { let globalScope = new GlobalScope(); - let pandaGen = new PandaGen("lexVarPassPandaGen", 1, globalScope); + let pandaGen = new PandaGen("lexVarPassPandaGen", undefined, 1, globalScope); let var1 = globalScope.add("var1", VarDeclarationKind.CONST); let funcObj = globalScope.add("4funcObj", VarDeclarationKind.LET); funcObj!.bindVreg(new VReg()); diff --git a/ts2panda/tests/pandagen.test.ts b/ts2panda/tests/pandagen.test.ts index c380eeb24e..5fc849d389 100644 --- a/ts2panda/tests/pandagen.test.ts +++ b/ts2panda/tests/pandagen.test.ts @@ -27,7 +27,7 @@ import { checkInstructions } from "./utils/base"; describe("PandaGenTest", function () { it("StoreAccumulator", function () { - let pandaGen = new PandaGen("pandaGen", 0); + let pandaGen = new PandaGen("pandaGen", undefined, 0); let vreg = new VReg(); pandaGen.storeAccumulator(ts.createNode(0), vreg); let insns = pandaGen.getInsns(); diff --git a/ts2panda/tests/regAllocator.test.ts b/ts2panda/tests/regAllocator.test.ts index 2888a1424f..55fb074c0f 100644 --- a/ts2panda/tests/regAllocator.test.ts +++ b/ts2panda/tests/regAllocator.test.ts @@ -132,7 +132,7 @@ describe("RegAllocator", function () { }); it("VReg sequence of CalliDynRange is not continuous", function () { - let pandaGen = new PandaGen('', 0); + let pandaGen = new PandaGen('', undefined, 0); let para1 = pandaGen.getTemp(); let para2 = pandaGen.getTemp(); @@ -155,7 +155,7 @@ describe("RegAllocator", function () { }); it("VReg sequence of DynRange is not continuous", function () { - let pandaGen = new PandaGen('', 0); + let pandaGen = new PandaGen('', undefined, 0); let para1 = pandaGen.getTemp(); let para2 = pandaGen.getTemp(); -- Gitee