• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "expandBrackets.h"
17 
18 #include "checker/ETSchecker.h"
19 #include "compiler/lowering/util.h"
20 #include "compiler/lowering/scopesInit/scopesInitPhase.h"
21 #include "ir/statements/blockStatement.h"
22 #include "ir/expressions/memberExpression.h"
23 #include "parser/ETSparser.h"
24 #include "varbinder/ETSBinder.h"
25 
26 namespace panda::es2panda::compiler {
27 
Perform(public_lib::Context * ctx,parser::Program * program)28 bool ExpandBracketsPhase::Perform(public_lib::Context *ctx, parser::Program *program)
29 {
30     auto *const checker = ctx->checker->AsETSChecker();
31     auto *const allocator = checker->Allocator();
32     auto *const parser = ctx->parser->AsETSParser();
33 
34     program->Ast()->TransformChildrenRecursively([ctx, parser, checker, allocator](ir::AstNode *ast) -> ir::AstNode * {
35         if (!ast->IsETSNewArrayInstanceExpression()) {
36             return ast;
37         }
38         auto *newExpression = ast->AsETSNewArrayInstanceExpression();
39         auto *dimension = newExpression->Dimension();
40         auto *dimType = dimension->TsType();
41         if (auto *unboxed = checker->ETSBuiltinTypeAsPrimitiveType(dimType); unboxed != nullptr) {
42             dimType = unboxed;
43         }
44         if (!dimType->HasTypeFlag(checker::TypeFlag::ETS_FLOATING_POINT)) {
45             return ast;
46         }
47 
48         auto *castedDimension =
49             parser->CreateFormattedExpression("@@E1 as int", parser::DEFAULT_SOURCE_FILE, dimension);
50         castedDimension->Check(checker);
51         castedDimension->SetParent(dimension->Parent());
52         newExpression->SetDimension(castedDimension);
53 
54         auto *const scope = NearestScope(newExpression);
55         auto expressionCtx = varbinder::LexicalScope<varbinder::Scope>::Enter(checker->VarBinder(), scope);
56         auto *ident = Gensym(allocator);
57         auto *exprType = checker->AllocNode<ir::OpaqueTypeNode>(dimType);
58         auto *sequenceExpr = parser->CreateFormattedExpression(
59             "let @@I1 = (@@E2) as @@T3;"
60             "if (!isSafeInteger(@@I4)) {"
61             "  throw new TypeError(\"Index fractional part should not be different from 0.0\");"
62             "};"
63             "(@@E5);",
64             parser::DEFAULT_SOURCE_FILE, ident, dimension, exprType, ident->Clone(allocator), newExpression);
65         sequenceExpr->SetParent(newExpression->Parent());
66         InitScopesPhaseETS::RunExternalNode(sequenceExpr, ctx->compilerContext->VarBinder());
67         checker->VarBinder()->AsETSBinder()->ResolveReferencesForScope(sequenceExpr, scope);
68         sequenceExpr->Check(checker);
69 
70         return sequenceExpr;
71     });
72     return true;
73 }
74 
75 }  // namespace panda::es2panda::compiler
76