• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "ast_verifier_test.h"
17 #include "ir/astNode.h"
18 
19 #include <gtest/gtest.h>
20 
21 using ark::es2panda::compiler::ast_verifier::ASTVerifier;
22 using ark::es2panda::compiler::ast_verifier::InvariantNameSet;
23 using ark::es2panda::ir::AstNode;
24 
25 namespace {
TEST_F(ASTVerifierTest,CatchClause)26 TEST_F(ASTVerifierTest, CatchClause)
27 {
28     ASTVerifier verifier {Allocator()};
29 
30     char const *text = R"(
31         let a = 10;
32         try {
33             a / 0;
34         } catch (e) {
35             if (e instanceof Error) {
36             }
37         }
38     )";
39 
40     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
41     impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
42     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
43 
44     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
45 
46     InvariantNameSet checks;
47     checks.insert("VariableHasEnclosingScopeForAll");
48     const auto &messages = verifier.Verify(ast, checks);
49     ASSERT_EQ(messages.size(), 0);
50 
51     impl_->DestroyContext(ctx);
52 }
53 
TEST_F(ASTVerifierTest,LambdasHaveCorrectScope)54 TEST_F(ASTVerifierTest, LambdasHaveCorrectScope)
55 {
56     ASTVerifier verifier {Allocator()};
57 
58     char const *text = R"(
59         type BenchmarkFunc = () => void;
60 
61         function main() {
62             const arr: number[] = [1, 2, 3, 4];
63             const ITERATE_FUNC: BenchmarkFunc = () => {
64                 const length = arr.length;
65             };
66         }
67     )";
68 
69     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
70     impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
71     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
72 
73     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
74 
75     InvariantNameSet checks;
76     checks.insert("VariableHasEnclosingScopeForAll");
77     const auto &messages = verifier.Verify(ast, checks);
78     ASSERT_EQ(messages.size(), 0);
79 
80     impl_->DestroyContext(ctx);
81 }
82 
TEST_F(ASTVerifierTest,ParametersInArrowFunctionExpression)83 TEST_F(ASTVerifierTest, ParametersInArrowFunctionExpression)
84 {
85     ASTVerifier verifier {Allocator()};
86 
87     char const *text = R"(
88         let b = 1;
89         let f = (p: double) => b + p;
90         function main () {
91             assert f(42) == 43
92         }
93     )";
94 
95     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
96     impl_->ProceedToState(ctx, ES2PANDA_STATE_CHECKED);
97     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_CHECKED);
98 
99     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
100 
101     InvariantNameSet checks;
102     checks.insert("VariableHasEnclosingScopeForAll");
103     const auto &messages = verifier.Verify(ast, checks);
104     ASSERT_EQ(messages.size(), 0);
105 
106     impl_->DestroyContext(ctx);
107 }
108 
TEST_F(ASTVerifierTest,LambdaAsParameter)109 TEST_F(ASTVerifierTest, LambdaAsParameter)
110 {
111     ASTVerifier verifier {Allocator()};
112 
113     char const *text = R"(
114         function foo(callback: (resolve: (val: int) => void) => void): void {}
115 
116         function main(): void {
117             foo((resolve: (val: int) => void): void => {});
118         }
119     )";
120 
121     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
122     impl_->ProceedToState(ctx, ES2PANDA_STATE_LOWERED);
123     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_LOWERED);
124 
125     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
126 
127     InvariantNameSet checks;
128     checks.insert("VariableHasEnclosingScopeForAll");
129     const auto &messages = verifier.Verify(ast, checks);
130     ASSERT_EQ(messages.size(), 0);
131 
132     impl_->DestroyContext(ctx);
133 }
134 
TEST_F(ASTVerifierTest,PartialClassDeclaration)135 TEST_F(ASTVerifierTest, PartialClassDeclaration)
136 {
137     ASTVerifier verifier {Allocator()};
138 
139     char const *text = R"(
140         export class IncrementalNode {
141             protected onChildInserted: ((node: IncrementalNode) => void) | undefined = undefined
142             private static readonly ESCAPED_CHARS: char[] = [c'\"', c'\\']
143         }
144     )";
145 
146     es2panda_Context *ctx = impl_->CreateContextFromString(cfg_, text, "dummy.sts");
147     impl_->ProceedToState(ctx, ES2PANDA_STATE_LOWERED);
148     ASSERT_EQ(impl_->ContextState(ctx), ES2PANDA_STATE_LOWERED);
149 
150     auto *ast = reinterpret_cast<AstNode *>(impl_->ProgramAst(impl_->ContextProgram(ctx)));
151 
152     InvariantNameSet checks;
153     checks.insert("VariableHasEnclosingScopeForAll");
154     const auto &messages = verifier.Verify(ast, checks);
155     ASSERT_EQ(messages.size(), 0);
156 
157     impl_->DestroyContext(ctx);
158 }
159 }  // namespace
160