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