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