• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2021 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 "property.h"
17 
18 #include <ir/astDump.h>
19 #include <ir/expressions/arrayExpression.h>
20 #include <ir/expressions/assignmentExpression.h>
21 #include <ir/expressions/objectExpression.h>
22 #include <ir/expressions/identifier.h>
23 #include <ir/expressions/literals/stringLiteral.h>
24 
25 namespace panda::es2panda::ir {
26 
ConventibleToPatternProperty()27 bool Property::ConventibleToPatternProperty()
28 {
29     // Object pattern can't contain getter or setter
30     if (IsAccessor() || isMethod_) {
31         return false;
32     }
33 
34     switch (value_->Type()) {
35         case AstNodeType::OBJECT_EXPRESSION: {
36             return value_->AsObjectExpression()->ConvertibleToObjectPattern();
37         }
38         case AstNodeType::ARRAY_EXPRESSION: {
39             return value_->AsArrayExpression()->ConvertibleToArrayPattern();
40         }
41         case AstNodeType::ASSIGNMENT_EXPRESSION: {
42             return value_->AsAssignmentExpression()->ConvertibleToAssignmentPattern();
43         }
44         case AstNodeType::META_PROPERTY_EXPRESSION: {
45             return false;
46         }
47         default: {
48             break;
49         }
50     }
51 
52     return true;
53 }
54 
ValidateExpression()55 ValidationInfo Property::ValidateExpression()
56 {
57     ValidationInfo info;
58 
59     if (!IsComputed() && !IsMethod() && !IsAccessor() && !IsShorthand()) {
60         bool currentIsProto = false;
61 
62         if (key_->IsIdentifier()) {
63             currentIsProto = key_->AsIdentifier()->Name().Is("__proto__");
64         } else if (key_->IsStringLiteral()) {
65             currentIsProto = key_->AsStringLiteral()->Str().Is("__proto__");
66         }
67 
68         if (currentIsProto) {
69             kind_ = PropertyKind::PROTO;
70         }
71     }
72 
73     if (value_) {
74         if (value_->IsAssignmentPattern()) {
75             return {"Invalid shorthand property initializer.", value_->Start()};
76         }
77 
78         if (value_->IsObjectExpression()) {
79             info = value_->AsObjectExpression()->ValidateExpression();
80         } else if (value_->IsArrayExpression()) {
81             info = value_->AsArrayExpression()->ValidateExpression();
82         }
83     }
84 
85     return info;
86 }
87 
Iterate(const NodeTraverser & cb) const88 void Property::Iterate(const NodeTraverser &cb) const
89 {
90     cb(key_);
91     cb(value_);
92 }
93 
Dump(ir::AstDumper * dumper) const94 void Property::Dump(ir::AstDumper *dumper) const
95 {
96     const char *kind = nullptr;
97 
98     switch (kind_) {
99         case PropertyKind::INIT: {
100             kind = "init";
101             break;
102         }
103         case PropertyKind::PROTO: {
104             kind = "proto";
105             break;
106         }
107         case PropertyKind::GET: {
108             kind = "get";
109             break;
110         }
111         case PropertyKind::SET: {
112             kind = "set";
113             break;
114         }
115         default: {
116             UNREACHABLE();
117         }
118     }
119 
120     dumper->Add({{"type", "Property"},
121                  {"method", isMethod_},
122                  {"shorthand", isShorthand_},
123                  {"computed", isComputed_},
124                  {"key", key_},
125                  {"value", value_},
126                  {"kind", kind}});
127 }
128 
Compile(compiler::PandaGen * pg) const129 void Property::Compile([[maybe_unused]] compiler::PandaGen *pg) const {}
130 
Check(checker::Checker * checker) const131 checker::Type *Property::Check([[maybe_unused]] checker::Checker *checker) const
132 {
133     return nullptr;
134 }
135 
UpdateSelf(const NodeUpdater & cb,binder::Binder * binder)136 void Property::UpdateSelf(const NodeUpdater &cb, [[maybe_unused]] binder::Binder *binder)
137 {
138     key_ = std::get<ir::AstNode *>(cb(key_))->AsExpression();
139     value_ = std::get<ir::AstNode *>(cb(value_))->AsExpression();
140 }
141 
142 }  // namespace panda::es2panda::ir
143