Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/parsing/parser-base.h

Issue 2295743003: Revert of Refactor object/class literal property name parsing (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PARSING_PARSER_BASE_H 5 #ifndef V8_PARSING_PARSER_BASE_H
6 #define V8_PARSING_PARSER_BASE_H 6 #define V8_PARSING_PARSER_BASE_H
7 7
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/bailout-reason.h" 9 #include "src/bailout-reason.h"
10 #include "src/base/hashmap.h" 10 #include "src/base/hashmap.h"
(...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 bool* is_async, bool* ok); 1067 bool* is_async, bool* ok);
1068 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier, 1068 ExpressionT ParsePrimaryExpression(ExpressionClassifier* classifier,
1069 bool* ok) { 1069 bool* ok) {
1070 bool is_async; 1070 bool is_async;
1071 return ParsePrimaryExpression(classifier, &is_async, ok); 1071 return ParsePrimaryExpression(classifier, &is_async, ok);
1072 } 1072 }
1073 ExpressionT ParseExpression(bool accept_IN, bool* ok); 1073 ExpressionT ParseExpression(bool accept_IN, bool* ok);
1074 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier, 1074 ExpressionT ParseExpression(bool accept_IN, ExpressionClassifier* classifier,
1075 bool* ok); 1075 bool* ok);
1076 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok); 1076 ExpressionT ParseArrayLiteral(ExpressionClassifier* classifier, bool* ok);
1077 1077 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set,
1078 enum class PropertyKind {
1079 kAccessorProperty,
1080 kValueProperty,
1081 kShorthandProperty,
1082 kMethodProperty
1083 };
1084
1085 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind);
1086 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind,
1087 bool in_class, bool* is_generator, bool* is_get,
1088 bool* is_set, bool* is_async, bool* is_static,
1089 bool* is_computed_name, 1078 bool* is_computed_name,
1090 ExpressionClassifier* classifier, bool* ok); 1079 ExpressionClassifier* classifier, bool* ok);
1091 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok); 1080 ExpressionT ParseObjectLiteral(ExpressionClassifier* classifier, bool* ok);
1092 ObjectLiteralPropertyT ParsePropertyDefinition( 1081 ObjectLiteralPropertyT ParsePropertyDefinition(
1093 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, 1082 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
1094 bool* is_computed_name, bool* has_seen_constructor, 1083 MethodKind kind, bool* is_computed_name, bool* has_seen_constructor,
1095 ExpressionClassifier* classifier, IdentifierT* name, bool* ok); 1084 ExpressionClassifier* classifier, IdentifierT* name, bool* ok);
1096 typename Types::ExpressionList ParseArguments( 1085 typename Types::ExpressionList ParseArguments(
1097 Scanner::Location* first_spread_pos, bool maybe_arrow, 1086 Scanner::Location* first_spread_pos, bool maybe_arrow,
1098 ExpressionClassifier* classifier, bool* ok); 1087 ExpressionClassifier* classifier, bool* ok);
1099 typename Types::ExpressionList ParseArguments( 1088 typename Types::ExpressionList ParseArguments(
1100 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier, 1089 Scanner::Location* first_spread_pos, ExpressionClassifier* classifier,
1101 bool* ok) { 1090 bool* ok) {
1102 return ParseArguments(first_spread_pos, false, classifier, ok); 1091 return ParseArguments(first_spread_pos, false, classifier, ok);
1103 } 1092 }
1104 1093
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 if (is_sloppy(scope->language_mode())) { 1172 if (is_sloppy(scope->language_mode())) {
1184 // For sloppy scopes we also have to record the call at function level, 1173 // For sloppy scopes we also have to record the call at function level,
1185 // in case it includes declarations that will be hoisted. 1174 // in case it includes declarations that will be hoisted.
1186 scope->GetDeclarationScope()->RecordEvalCall(); 1175 scope->GetDeclarationScope()->RecordEvalCall();
1187 } 1176 }
1188 return Call::IS_POSSIBLY_EVAL; 1177 return Call::IS_POSSIBLY_EVAL;
1189 } 1178 }
1190 return Call::NOT_EVAL; 1179 return Call::NOT_EVAL;
1191 } 1180 }
1192 1181
1182 // Used to validate property names in object literals and class literals
1183 enum PropertyKind {
1184 kAccessorProperty,
1185 kValueProperty,
1186 kMethodProperty
1187 };
1188
1193 class ObjectLiteralCheckerBase { 1189 class ObjectLiteralCheckerBase {
1194 public: 1190 public:
1195 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {} 1191 explicit ObjectLiteralCheckerBase(ParserBase* parser) : parser_(parser) {}
1196 1192
1197 virtual void CheckProperty(Token::Value property, PropertyKind type, 1193 virtual void CheckProperty(Token::Value property, PropertyKind type,
1198 MethodKind method_type, 1194 MethodKind method_type,
1199 ExpressionClassifier* classifier, bool* ok) = 0; 1195 ExpressionClassifier* classifier, bool* ok) = 0;
1200 1196
1201 virtual ~ObjectLiteralCheckerBase() {} 1197 virtual ~ObjectLiteralCheckerBase() {}
1202 1198
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 // to change. Also, this error message will never appear while pre- 1855 // to change. Also, this error message will never appear while pre-
1860 // parsing (this is OK, as it is an implementation limitation). 1856 // parsing (this is OK, as it is an implementation limitation).
1861 ReportMessage(MessageTemplate::kTooManySpreads); 1857 ReportMessage(MessageTemplate::kTooManySpreads);
1862 return impl()->EmptyExpression(); 1858 return impl()->EmptyExpression();
1863 } 1859 }
1864 } 1860 }
1865 return result; 1861 return result;
1866 } 1862 }
1867 1863
1868 template <class Impl> 1864 template <class Impl>
1869 bool ParserBase<Impl>::SetPropertyKindFromToken(Token::Value token,
1870 PropertyKind* kind) {
1871 switch (token) {
1872 case Token::COLON:
1873 *kind = PropertyKind::kValueProperty;
1874 return true;
1875 case Token::COMMA:
1876 case Token::RBRACE:
1877 case Token::ASSIGN:
1878 *kind = PropertyKind::kShorthandProperty;
1879 return true;
1880 case Token::LPAREN:
1881 *kind = PropertyKind::kMethodProperty;
1882 return true;
1883 default:
1884 break;
1885 }
1886 return false;
1887 }
1888
1889 template <class Impl>
1890 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName( 1865 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParsePropertyName(
1891 IdentifierT* name, PropertyKind* kind, bool in_class, bool* is_generator, 1866 IdentifierT* name, bool* is_get, bool* is_set, bool* is_computed_name,
1892 bool* is_get, bool* is_set, bool* is_async, bool* is_static, 1867 ExpressionClassifier* classifier, bool* ok) {
1893 bool* is_computed_name, ExpressionClassifier* classifier, bool* ok) {
1894 *is_generator = Check(Token::MUL);
1895
1896 Token::Value token = peek(); 1868 Token::Value token = peek();
1897 int pos = peek_position(); 1869 int pos = peek_position();
1898 1870
1899 if (in_class && !*is_generator && token == Token::STATIC) {
1900 Consume(Token::STATIC);
1901 *kind = PropertyKind::kMethodProperty;
1902 if (peek() == Token::LPAREN) {
1903 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static'
1904 return factory()->NewStringLiteral(*name, pos);
1905 }
1906 *is_generator = Check(Token::MUL);
1907 *is_static = true;
1908 token = peek();
1909 pos = peek_position();
1910 }
1911
1912 if (allow_harmony_async_await() && !*is_generator && token == Token::ASYNC &&
1913 !scanner()->HasAnyLineTerminatorAfterNext()) {
1914 Consume(Token::ASYNC);
1915 token = peek();
1916 if (SetPropertyKindFromToken(token, kind)) {
1917 *name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'async'
1918 if (fni_ != nullptr) {
1919 impl()->PushLiteralName(fni_, *name);
1920 }
1921 return factory()->NewStringLiteral(*name, pos);
1922 }
1923 *kind = PropertyKind::kMethodProperty;
1924 *is_async = true;
1925 pos = peek_position();
1926 }
1927
1928 if (token == Token::IDENTIFIER && !*is_generator && !*is_async) {
1929 Consume(Token::IDENTIFIER);
1930 token = peek();
1931 if (SetPropertyKindFromToken(token, kind)) {
1932 *name = impl()->GetSymbol();
1933 if (fni_ != nullptr) {
1934 impl()->PushLiteralName(fni_, *name);
1935 }
1936 return factory()->NewStringLiteral(*name, pos);
1937 }
1938 scanner()->IsGetOrSet(is_get, is_set);
1939 if (!*is_get && !*is_set) { // TODO(bakkot) have IsGetOrSet return a bool
1940 Token::Value next = Next();
1941 ReportUnexpectedToken(next);
1942 *ok = false;
1943 return impl()->EmptyExpression();
1944 }
1945 *kind = PropertyKind::kAccessorProperty;
1946 pos = peek_position();
1947 }
1948
1949 // For non computed property names we normalize the name a bit: 1871 // For non computed property names we normalize the name a bit:
1950 // 1872 //
1951 // "12" -> 12 1873 // "12" -> 12
1952 // 12.3 -> "12.3" 1874 // 12.3 -> "12.3"
1953 // 12.30 -> "12.3" 1875 // 12.30 -> "12.3"
1954 // identifier -> "identifier" 1876 // identifier -> "identifier"
1955 // 1877 //
1956 // This is important because we use the property name as a key in a hash 1878 // This is important because we use the property name as a key in a hash
1957 // table when we compute constant properties. 1879 // table when we compute constant properties.
1958 ExpressionT expression;
1959 switch (token) { 1880 switch (token) {
1960 case Token::STRING: 1881 case Token::STRING:
1961 Consume(Token::STRING); 1882 Consume(Token::STRING);
1962 *name = impl()->GetSymbol(); 1883 *name = impl()->GetSymbol();
1963 break; 1884 break;
1964 1885
1965 case Token::SMI: 1886 case Token::SMI:
1966 Consume(Token::SMI); 1887 Consume(Token::SMI);
1967 *name = impl()->GetNumberAsSymbol(); 1888 *name = impl()->GetNumberAsSymbol();
1968 break; 1889 break;
1969 1890
1970 case Token::NUMBER: 1891 case Token::NUMBER:
1971 Consume(Token::NUMBER); 1892 Consume(Token::NUMBER);
1972 *name = impl()->GetNumberAsSymbol(); 1893 *name = impl()->GetNumberAsSymbol();
1973 break; 1894 break;
1974 1895
1975 case Token::LBRACK: { 1896 case Token::LBRACK: {
1976 *name = impl()->EmptyIdentifier();
1977 *is_computed_name = true; 1897 *is_computed_name = true;
1978 Consume(Token::LBRACK); 1898 Consume(Token::LBRACK);
1979 ExpressionClassifier computed_name_classifier(this); 1899 ExpressionClassifier computed_name_classifier(this);
1980 expression = 1900 ExpressionT expression =
1981 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK); 1901 ParseAssignmentExpression(true, &computed_name_classifier, CHECK_OK);
1982 impl()->RewriteNonPattern(&computed_name_classifier, CHECK_OK); 1902 impl()->RewriteNonPattern(&computed_name_classifier, CHECK_OK);
1983 classifier->AccumulateFormalParameterContainmentErrors( 1903 classifier->AccumulateFormalParameterContainmentErrors(
1984 &computed_name_classifier); 1904 &computed_name_classifier);
1985 Expect(Token::RBRACK, CHECK_OK); 1905 Expect(Token::RBRACK, CHECK_OK);
1986 break; 1906 return expression;
1987 } 1907 }
1988 1908
1989 default: 1909 default:
1990 *name = ParseIdentifierName(CHECK_OK); 1910 *name = ParseIdentifierName(CHECK_OK);
1911 scanner()->IsGetOrSet(is_get, is_set);
1991 break; 1912 break;
1992 } 1913 }
1993 1914
1994 if (*kind == PropertyKind::kValueProperty) {
1995 if (!SetPropertyKindFromToken(peek(), kind) ||
1996 (*kind == PropertyKind::kShorthandProperty &&
1997 !Token::IsIdentifier(token, language_mode(), this->is_generator(),
1998 parsing_module_ || is_async_function()))) {
1999 Token::Value next = Next();
2000 ReportUnexpectedToken(next);
2001 *ok = false;
2002 return impl()->EmptyExpression();
2003 }
2004 }
2005
2006 if (*is_computed_name) {
2007 return expression;
2008 }
2009
2010 if (fni_ != nullptr) {
2011 impl()->PushLiteralName(fni_, *name);
2012 }
2013
2014 uint32_t index; 1915 uint32_t index;
2015 return impl()->IsArrayIndex(*name, &index) 1916 return impl()->IsArrayIndex(*name, &index)
2016 ? factory()->NewNumberLiteral(index, pos) 1917 ? factory()->NewNumberLiteral(index, pos)
2017 : factory()->NewStringLiteral(*name, pos); 1918 : factory()->NewStringLiteral(*name, pos);
2018 } 1919 }
2019 1920
2020 template <typename Impl> 1921 template <typename Impl>
2021 typename ParserBase<Impl>::ObjectLiteralPropertyT 1922 typename ParserBase<Impl>::ObjectLiteralPropertyT
2022 ParserBase<Impl>::ParsePropertyDefinition(ObjectLiteralCheckerBase* checker, 1923 ParserBase<Impl>::ParsePropertyDefinition(
2023 bool in_class, bool has_extends, 1924 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends,
2024 bool* is_computed_name, 1925 MethodKind method_kind, bool* is_computed_name, bool* has_seen_constructor,
2025 bool* has_seen_constructor, 1926 ExpressionClassifier* classifier, IdentifierT* name, bool* ok) {
2026 ExpressionClassifier* classifier, 1927 DCHECK(!in_class || IsStaticMethod(method_kind) ||
2027 IdentifierT* name, bool* ok) { 1928 has_seen_constructor != nullptr);
2028 DCHECK(!in_class || has_seen_constructor != nullptr);
2029 bool is_get = false; 1929 bool is_get = false;
2030 bool is_set = false; 1930 bool is_set = false;
2031 bool is_generator = false; 1931 bool is_generator = Check(Token::MUL);
2032 bool is_async = false; 1932 bool is_async = false;
2033 bool is_static = false; 1933 const bool is_static = IsStaticMethod(method_kind);
2034 PropertyKind kind = PropertyKind::kValueProperty;
2035 1934
2036 Token::Value name_token = peek(); 1935 Token::Value name_token = peek();
1936
1937 if (is_generator) {
1938 method_kind |= MethodKind::kGenerator;
1939 } else if (allow_harmony_async_await() && name_token == Token::ASYNC &&
1940 !scanner()->HasAnyLineTerminatorAfterNext() &&
1941 PeekAhead() != Token::LPAREN && PeekAhead()) {
1942 is_async = true;
1943 }
1944
2037 int next_beg_pos = scanner()->peek_location().beg_pos; 1945 int next_beg_pos = scanner()->peek_location().beg_pos;
2038 int next_end_pos = scanner()->peek_location().end_pos; 1946 int next_end_pos = scanner()->peek_location().end_pos;
2039
2040 ExpressionT name_expression = 1947 ExpressionT name_expression =
2041 ParsePropertyName(name, &kind, in_class, &is_generator, &is_get, &is_set, 1948 ParsePropertyName(name, &is_get, &is_set, is_computed_name, classifier,
2042 &is_async, &is_static, is_computed_name, classifier,
2043 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1949 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2044 1950
2045 switch (kind) { 1951 if (fni_ != nullptr && !*is_computed_name) {
2046 case PropertyKind::kValueProperty: { 1952 impl()->PushLiteralName(fni_, *name);
2047 if (in_class) { 1953 }
2048 Token::Value next = Next();
2049 ReportUnexpectedToken(next);
2050 *ok = false;
2051 return impl()->EmptyObjectLiteralProperty();
2052 }
2053 1954
2054 DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static); 1955 if (!in_class && !is_generator) {
2055 1956 DCHECK(!IsStaticMethod(method_kind));
1957 if (peek() == Token::COLON) {
1958 // PropertyDefinition
1959 // PropertyName ':' AssignmentExpression
2056 if (!*is_computed_name) { 1960 if (!*is_computed_name) {
2057 checker->CheckProperty(name_token, PropertyKind::kValueProperty, 1961 checker->CheckProperty(name_token, kValueProperty, MethodKind::kNormal,
2058 MethodKind::kNormal, classifier, 1962 classifier,
2059 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1963 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2060 } 1964 }
2061 Consume(Token::COLON); 1965 Consume(Token::COLON);
2062 int beg_pos = peek_position(); 1966 int beg_pos = peek_position();
2063 ExpressionT value = ParseAssignmentExpression( 1967 ExpressionT value = ParseAssignmentExpression(
2064 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); 1968 true, classifier, CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2065 CheckDestructuringElement(value, classifier, beg_pos, 1969 CheckDestructuringElement(value, classifier, beg_pos,
2066 scanner()->location().end_pos); 1970 scanner()->location().end_pos);
2067 1971
2068 return factory()->NewObjectLiteralProperty(name_expression, value, 1972 return factory()->NewObjectLiteralProperty(name_expression, value,
2069 is_static, *is_computed_name); 1973 is_static, *is_computed_name);
2070 } 1974 }
2071 1975
2072 case PropertyKind::kShorthandProperty: { 1976 if (Token::IsIdentifier(name_token, language_mode(), this->is_generator(),
1977 parsing_module_ || is_async_function()) &&
1978 (peek() == Token::COMMA || peek() == Token::RBRACE ||
1979 peek() == Token::ASSIGN)) {
2073 // PropertyDefinition 1980 // PropertyDefinition
2074 // IdentifierReference 1981 // IdentifierReference
2075 // CoverInitializedName 1982 // CoverInitializedName
2076 // 1983 //
2077 // CoverInitializedName 1984 // CoverInitializedName
2078 // IdentifierReference Initializer? 1985 // IdentifierReference Initializer?
2079 if (in_class) {
2080 Token::Value next = Next();
2081 ReportUnexpectedToken(next);
2082 *ok = false;
2083 return impl()->EmptyObjectLiteralProperty();
2084 }
2085
2086 DCHECK(!is_get && !is_set && !is_generator && !is_async && !is_static &&
2087 !*is_computed_name);
2088
2089 if (classifier->duplicate_finder() != nullptr && 1986 if (classifier->duplicate_finder() != nullptr &&
2090 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) { 1987 scanner()->FindSymbol(classifier->duplicate_finder(), 1) != 0) {
2091 classifier->RecordDuplicateFormalParameterError(scanner()->location()); 1988 classifier->RecordDuplicateFormalParameterError(scanner()->location());
2092 } 1989 }
2093 1990
2094 if (impl()->IsEvalOrArguments(*name) && is_strict(language_mode())) { 1991 if (impl()->IsEvalOrArguments(*name) && is_strict(language_mode())) {
2095 classifier->RecordBindingPatternError( 1992 classifier->RecordBindingPatternError(
2096 scanner()->location(), MessageTemplate::kStrictEvalArguments); 1993 scanner()->location(), MessageTemplate::kStrictEvalArguments);
2097 } 1994 }
2098 1995
(...skipping 28 matching lines...) Expand all
2127 2024
2128 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs); 2025 impl()->SetFunctionNameFromIdentifierRef(rhs, lhs);
2129 } else { 2026 } else {
2130 value = lhs; 2027 value = lhs;
2131 } 2028 }
2132 2029
2133 return factory()->NewObjectLiteralProperty( 2030 return factory()->NewObjectLiteralProperty(
2134 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static, 2031 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static,
2135 false); 2032 false);
2136 } 2033 }
2034 }
2137 2035
2138 case PropertyKind::kMethodProperty: { 2036 // Method definitions are never valid in patterns.
2139 DCHECK(!is_get && !is_set); 2037 classifier->RecordPatternError(
2038 Scanner::Location(next_beg_pos, scanner()->location().end_pos),
2039 MessageTemplate::kInvalidDestructuringTarget);
2140 2040
2141 MethodKind method_kind = MethodKind::kNormal; 2041 if (is_async && !IsSpecialMethod(method_kind)) {
2142 if (is_generator) { 2042 DCHECK(!is_get);
2143 method_kind |= MethodKind::kGenerator; 2043 DCHECK(!is_set);
2144 } 2044 bool dont_care;
2145 if (is_async) { 2045 name_expression = ParsePropertyName(
2146 method_kind |= MethodKind::kAsync; 2046 name, &dont_care, &dont_care, is_computed_name, classifier,
2147 } 2047 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2148 if (is_static) { 2048 method_kind |= MethodKind::kAsync;
2149 method_kind |= MethodKind::kStatic; 2049 }
2150 }
2151 2050
2152 // MethodDefinition 2051 if (is_generator || peek() == Token::LPAREN) {
2153 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2052 // MethodDefinition
2154 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' 2053 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2155 2054 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}'
2156 classifier->RecordPatternError( 2055 if (!*is_computed_name) {
2157 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 2056 checker->CheckProperty(name_token, kMethodProperty, method_kind,
2158 MessageTemplate::kInvalidDestructuringTarget); 2057 classifier,
2159 2058 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2160 if (!*is_computed_name) {
2161 checker->CheckProperty(name_token, PropertyKind::kMethodProperty,
2162 method_kind, classifier,
2163 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2164 }
2165
2166 FunctionKind kind = is_generator
2167 ? FunctionKind::kConciseGeneratorMethod
2168 : is_async ? FunctionKind::kAsyncConciseMethod
2169 : FunctionKind::kConciseMethod;
2170
2171 if (in_class && !is_static && impl()->IsConstructor(*name)) {
2172 *has_seen_constructor = true;
2173 kind = has_extends ? FunctionKind::kSubclassConstructor
2174 : FunctionKind::kBaseConstructor;
2175 }
2176
2177 ExpressionT value = impl()->ParseFunctionLiteral(
2178 *name, scanner()->location(), kSkipFunctionNameCheck, kind,
2179 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
2180 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2181
2182 return factory()->NewObjectLiteralProperty(
2183 name_expression, value, ObjectLiteralProperty::COMPUTED, is_static,
2184 *is_computed_name);
2185 } 2059 }
2186 2060
2187 case PropertyKind::kAccessorProperty: { 2061 FunctionKind kind = is_generator
2188 DCHECK((is_get || is_set) && !is_generator && !is_async); 2062 ? FunctionKind::kConciseGeneratorMethod
2063 : is_async ? FunctionKind::kAsyncConciseMethod
2064 : FunctionKind::kConciseMethod;
2189 2065
2190 MethodKind method_kind = MethodKind::kNormal; 2066 if (in_class && !IsStaticMethod(method_kind) &&
2191 if (is_static) { 2067 impl()->IsConstructor(*name)) {
2192 DCHECK(in_class); 2068 *has_seen_constructor = true;
2193 method_kind |= MethodKind::kStatic; 2069 kind = has_extends ? FunctionKind::kSubclassConstructor
2194 } 2070 : FunctionKind::kBaseConstructor;
2071 }
2195 2072
2196 classifier->RecordPatternError( 2073 ExpressionT value = impl()->ParseFunctionLiteral(
2197 Scanner::Location(next_beg_pos, scanner()->location().end_pos), 2074 *name, scanner()->location(), kSkipFunctionNameCheck, kind,
2198 MessageTemplate::kInvalidDestructuringTarget); 2075 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(),
2199 if (!*is_computed_name) { 2076 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2200 checker->CheckProperty(name_token, PropertyKind::kAccessorProperty,
2201 method_kind, classifier,
2202 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2203 }
2204 2077
2205 typename Types::FunctionLiteral value = impl()->ParseFunctionLiteral( 2078 return factory()->NewObjectLiteralProperty(name_expression, value,
2206 *name, scanner()->location(), kSkipFunctionNameCheck, 2079 ObjectLiteralProperty::COMPUTED,
2207 is_get ? FunctionKind::kGetterFunction 2080 is_static, *is_computed_name);
2208 : FunctionKind::kSetterFunction, 2081 }
2209 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod,
2210 language_mode(), CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2211 2082
2212 // Make sure the name expression is a string since we need a Name for 2083 if (in_class && name_token == Token::STATIC && IsNormalMethod(method_kind)) {
2213 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this 2084 // ClassElement (static)
2214 // statically we can skip the extra runtime check. 2085 // 'static' MethodDefinition
2215 if (!*is_computed_name) { 2086 *name = impl()->EmptyIdentifier();
2216 name_expression = 2087 ObjectLiteralPropertyT property = ParsePropertyDefinition(
2217 factory()->NewStringLiteral(*name, name_expression->position()); 2088 checker, true, has_extends, MethodKind::kStatic, is_computed_name,
2218 } 2089 nullptr, classifier, name, ok);
2090 impl()->RewriteNonPattern(classifier, ok);
2091 return property;
2092 }
2219 2093
2220 return factory()->NewObjectLiteralProperty( 2094 if (is_get || is_set) {
2221 name_expression, value, is_get ? ObjectLiteralProperty::GETTER 2095 // MethodDefinition (Accessors)
2222 : ObjectLiteralProperty::SETTER, 2096 // get PropertyName '(' ')' '{' FunctionBody '}'
2223 is_static, *is_computed_name); 2097 // set PropertyName '(' PropertySetParameterList ')' '{' FunctionBody '}'
2098 *name = impl()->EmptyIdentifier();
2099 bool dont_care = false;
2100 name_token = peek();
2101
2102 name_expression = ParsePropertyName(
2103 name, &dont_care, &dont_care, is_computed_name, classifier,
2104 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2105
2106 if (!*is_computed_name) {
2107 checker->CheckProperty(name_token, kAccessorProperty, method_kind,
2108 classifier,
2109 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2224 } 2110 }
2111
2112 FunctionLiteralT value = impl()->ParseFunctionLiteral(
2113 *name, scanner()->location(), kSkipFunctionNameCheck,
2114 is_get ? FunctionKind::kGetterFunction : FunctionKind::kSetterFunction,
2115 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, language_mode(),
2116 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty));
2117
2118 // Make sure the name expression is a string since we need a Name for
2119 // Runtime_DefineAccessorPropertyUnchecked and since we can determine this
2120 // statically we can skip the extra runtime check.
2121 if (!*is_computed_name) {
2122 name_expression =
2123 factory()->NewStringLiteral(*name, name_expression->position());
2124 }
2125
2126 return factory()->NewObjectLiteralProperty(
2127 name_expression, value,
2128 is_get ? ObjectLiteralProperty::GETTER : ObjectLiteralProperty::SETTER,
2129 is_static, *is_computed_name);
2225 } 2130 }
2226 UNREACHABLE(); 2131
2132 Token::Value next = Next();
2133 ReportUnexpectedToken(next);
2134 *ok = false;
2227 return impl()->EmptyObjectLiteralProperty(); 2135 return impl()->EmptyObjectLiteralProperty();
2228 } 2136 }
2229 2137
2230 template <typename Impl> 2138 template <typename Impl>
2231 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral( 2139 typename ParserBase<Impl>::ExpressionT ParserBase<Impl>::ParseObjectLiteral(
2232 ExpressionClassifier* classifier, bool* ok) { 2140 ExpressionClassifier* classifier, bool* ok) {
2233 // ObjectLiteral :: 2141 // ObjectLiteral ::
2234 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}' 2142 // '{' (PropertyDefinition (',' PropertyDefinition)* ','? )? '}'
2235 2143
2236 int pos = peek_position(); 2144 int pos = peek_position();
2237 typename Types::PropertyList properties = impl()->NewPropertyList(4); 2145 typename Types::PropertyList properties = impl()->NewPropertyList(4);
2238 int number_of_boilerplate_properties = 0; 2146 int number_of_boilerplate_properties = 0;
2239 bool has_computed_names = false; 2147 bool has_computed_names = false;
2240 ObjectLiteralChecker checker(this); 2148 ObjectLiteralChecker checker(this);
2241 2149
2242 Expect(Token::LBRACE, CHECK_OK); 2150 Expect(Token::LBRACE, CHECK_OK);
2243 2151
2244 while (peek() != Token::RBRACE) { 2152 while (peek() != Token::RBRACE) {
2245 FuncNameInferrer::State fni_state(fni_); 2153 FuncNameInferrer::State fni_state(fni_);
2246 2154
2247 const bool in_class = false; 2155 const bool in_class = false;
2248 const bool has_extends = false; 2156 const bool has_extends = false;
2249 bool is_computed_name = false; 2157 bool is_computed_name = false;
2250 IdentifierT name = impl()->EmptyIdentifier(); 2158 IdentifierT name = impl()->EmptyIdentifier();
2251 ObjectLiteralPropertyT property = ParsePropertyDefinition( 2159 ObjectLiteralPropertyT property = ParsePropertyDefinition(
2252 &checker, in_class, has_extends, &is_computed_name, nullptr, classifier, 2160 &checker, in_class, has_extends, MethodKind::kNormal, &is_computed_name,
2253 &name, CHECK_OK); 2161 NULL, classifier, &name, CHECK_OK);
2254 2162
2255 if (is_computed_name) { 2163 if (is_computed_name) {
2256 has_computed_names = true; 2164 has_computed_names = true;
2257 } 2165 }
2258 2166
2259 // Count CONSTANT or COMPUTED properties to maintain the enumeration order. 2167 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
2260 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) { 2168 if (!has_computed_names && impl()->IsBoilerplateProperty(property)) {
2261 number_of_boilerplate_properties++; 2169 number_of_boilerplate_properties++;
2262 } 2170 }
2263 properties->Add(property, zone()); 2171 properties->Add(property, zone());
(...skipping 1469 matching lines...) Expand 10 before | Expand all | Expand 10 after
3733 3641
3734 3642
3735 #undef CHECK_OK 3643 #undef CHECK_OK
3736 #undef CHECK_OK_CUSTOM 3644 #undef CHECK_OK_CUSTOM
3737 3645
3738 template <typename Impl> 3646 template <typename Impl>
3739 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty( 3647 void ParserBase<Impl>::ObjectLiteralChecker::CheckProperty(
3740 Token::Value property, PropertyKind type, MethodKind method_type, 3648 Token::Value property, PropertyKind type, MethodKind method_type,
3741 ExpressionClassifier* classifier, bool* ok) { 3649 ExpressionClassifier* classifier, bool* ok) {
3742 DCHECK(!IsStaticMethod(method_type)); 3650 DCHECK(!IsStaticMethod(method_type));
3743 DCHECK(!IsSpecialMethod(method_type) || 3651 DCHECK(!IsSpecialMethod(method_type) || type == kMethodProperty);
3744 type == PropertyKind::kMethodProperty);
3745 3652
3746 if (property == Token::SMI || property == Token::NUMBER) return; 3653 if (property == Token::SMI || property == Token::NUMBER) return;
3747 3654
3748 if (type == PropertyKind::kValueProperty && IsProto()) { 3655 if (type == kValueProperty && IsProto()) {
3749 if (has_seen_proto_) { 3656 if (has_seen_proto_) {
3750 classifier->RecordExpressionError(this->scanner()->location(), 3657 classifier->RecordExpressionError(this->scanner()->location(),
3751 MessageTemplate::kDuplicateProto); 3658 MessageTemplate::kDuplicateProto);
3752 return; 3659 return;
3753 } 3660 }
3754 has_seen_proto_ = true; 3661 has_seen_proto_ = true;
3755 } 3662 }
3756 } 3663 }
3757 3664
3758 template <typename Impl> 3665 template <typename Impl>
3759 void ParserBase<Impl>::ClassLiteralChecker::CheckProperty( 3666 void ParserBase<Impl>::ClassLiteralChecker::CheckProperty(
3760 Token::Value property, PropertyKind type, MethodKind method_type, 3667 Token::Value property, PropertyKind type, MethodKind method_type,
3761 ExpressionClassifier* classifier, bool* ok) { 3668 ExpressionClassifier* classifier, bool* ok) {
3762 DCHECK(type == PropertyKind::kMethodProperty || 3669 DCHECK(type == kMethodProperty || type == kAccessorProperty);
3763 type == PropertyKind::kAccessorProperty);
3764 3670
3765 if (property == Token::SMI || property == Token::NUMBER) return; 3671 if (property == Token::SMI || property == Token::NUMBER) return;
3766 3672
3767 if (IsStaticMethod(method_type)) { 3673 if (IsStaticMethod(method_type)) {
3768 if (IsPrototype()) { 3674 if (IsPrototype()) {
3769 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype); 3675 this->parser()->ReportMessage(MessageTemplate::kStaticPrototype);
3770 *ok = false; 3676 *ok = false;
3771 return; 3677 return;
3772 } 3678 }
3773 } else if (IsConstructor()) { 3679 } else if (IsConstructor()) {
3774 const bool is_generator = IsGeneratorMethod(method_type); 3680 const bool is_generator = IsGeneratorMethod(method_type);
3775 const bool is_async = IsAsyncMethod(method_type); 3681 const bool is_async = IsAsyncMethod(method_type);
3776 if (is_generator || is_async || type == PropertyKind::kAccessorProperty) { 3682 if (is_generator || is_async || type == kAccessorProperty) {
3777 MessageTemplate::Template msg = 3683 MessageTemplate::Template msg =
3778 is_generator ? MessageTemplate::kConstructorIsGenerator 3684 is_generator ? MessageTemplate::kConstructorIsGenerator
3779 : is_async ? MessageTemplate::kConstructorIsAsync 3685 : is_async ? MessageTemplate::kConstructorIsAsync
3780 : MessageTemplate::kConstructorIsAccessor; 3686 : MessageTemplate::kConstructorIsAccessor;
3781 this->parser()->ReportMessage(msg); 3687 this->parser()->ReportMessage(msg);
3782 *ok = false; 3688 *ok = false;
3783 return; 3689 return;
3784 } 3690 }
3785 if (has_seen_constructor_) { 3691 if (has_seen_constructor_) {
3786 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor); 3692 this->parser()->ReportMessage(MessageTemplate::kDuplicateConstructor);
3787 *ok = false; 3693 *ok = false;
3788 return; 3694 return;
3789 } 3695 }
3790 has_seen_constructor_ = true; 3696 has_seen_constructor_ = true;
3791 return; 3697 return;
3792 } 3698 }
3793 } 3699 }
3794 3700
3795 3701
3796 } // namespace internal 3702 } // namespace internal
3797 } // namespace v8 3703 } // namespace v8
3798 3704
3799 #endif // V8_PARSING_PARSER_BASE_H 3705 #endif // V8_PARSING_PARSER_BASE_H
OLDNEW
« no previous file with comments | « src/parsing/parser.cc ('k') | src/parsing/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698