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.cc

Issue 2297563007: Move ParseVariableDeclarations to ParserBase. (Closed)
Patch Set: rebased 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.h ('k') | src/parsing/parser-base.h » ('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 #include "src/parsing/parser.h" 5 #include "src/parsing/parser.h"
6 6
7 #include <memory> 7 #include <memory>
8 8
9 #include "src/api.h" 9 #include "src/api.h"
10 #include "src/ast/ast-expression-rewriter.h" 10 #include "src/ast/ast-expression-rewriter.h"
(...skipping 1886 matching lines...) Expand 10 before | Expand all | Expand 10 after
1897 Block* result = factory()->NewBlock( 1897 Block* result = factory()->NewBlock(
1898 NULL, 1, true, parsing_result->descriptor.declaration_pos); 1898 NULL, 1, true, parsing_result->descriptor.declaration_pos);
1899 for (auto declaration : parsing_result->declarations) { 1899 for (auto declaration : parsing_result->declarations) {
1900 PatternRewriter::DeclareAndInitializeVariables( 1900 PatternRewriter::DeclareAndInitializeVariables(
1901 this, result, &(parsing_result->descriptor), &declaration, names, 1901 this, result, &(parsing_result->descriptor), &declaration, names,
1902 CHECK_OK); 1902 CHECK_OK);
1903 } 1903 }
1904 return result; 1904 return result;
1905 } 1905 }
1906 1906
1907 void Parser::DeclareAndInitializeVariables(
1908 Block* block, const DeclarationDescriptor* declaration_descriptor,
1909 const DeclarationParsingResult::Declaration* declaration,
1910 ZoneList<const AstRawString*>* names, bool* ok) {
1911 DCHECK_NOT_NULL(block);
1912 PatternRewriter::DeclareAndInitializeVariables(
1913 this, block, declaration_descriptor, declaration, names, ok);
1914 }
1907 1915
1908 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context, 1916 Block* Parser::ParseVariableStatement(VariableDeclarationContext var_context,
1909 ZoneList<const AstRawString*>* names, 1917 ZoneList<const AstRawString*>* names,
1910 bool* ok) { 1918 bool* ok) {
1911 // VariableStatement :: 1919 // VariableStatement ::
1912 // VariableDeclarations ';' 1920 // VariableDeclarations ';'
1913 1921
1914 // The scope of a var declared variable anywhere inside a function 1922 // The scope of a var declared variable anywhere inside a function
1915 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can 1923 // is the entire function (ECMA-262, 3rd, 10.1.3, and 12.2). Thus we can
1916 // transform a source-level var declaration into a (Function) Scope 1924 // transform a source-level var declaration into a (Function) Scope
1917 // declaration, and rewrite the source-level initialization into an assignment 1925 // declaration, and rewrite the source-level initialization into an assignment
1918 // statement. We use a block to collect multiple assignments. 1926 // statement. We use a block to collect multiple assignments.
1919 // 1927 //
1920 // We mark the block as initializer block because we don't want the 1928 // We mark the block as initializer block because we don't want the
1921 // rewriter to add a '.result' assignment to such a block (to get compliant 1929 // rewriter to add a '.result' assignment to such a block (to get compliant
1922 // behavior for code such as print(eval('var x = 7')), and for cosmetic 1930 // behavior for code such as print(eval('var x = 7')), and for cosmetic
1923 // reasons when pretty-printing. Also, unless an assignment (initialization) 1931 // reasons when pretty-printing. Also, unless an assignment (initialization)
1924 // is inside an initializer block, it is ignored. 1932 // is inside an initializer block, it is ignored.
1925 1933
1926 DeclarationParsingResult parsing_result; 1934 DeclarationParsingResult parsing_result;
1927 Block* result = 1935 Block* result =
1928 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK); 1936 ParseVariableDeclarations(var_context, &parsing_result, names, CHECK_OK);
1929 ExpectSemicolon(CHECK_OK); 1937 ExpectSemicolon(CHECK_OK);
1930 return result; 1938 return result;
1931 } 1939 }
1932 1940
1933 Block* Parser::ParseVariableDeclarations(
1934 VariableDeclarationContext var_context,
1935 DeclarationParsingResult* parsing_result,
1936 ZoneList<const AstRawString*>* names, bool* ok) {
1937 // VariableDeclarations ::
1938 // ('var' | 'const' | 'let') (Identifier ('=' AssignmentExpression)?)+[',']
1939 //
1940 // The ES6 Draft Rev3 specifies the following grammar for const declarations
1941 //
1942 // ConstDeclaration ::
1943 // const ConstBinding (',' ConstBinding)* ';'
1944 // ConstBinding ::
1945 // Identifier '=' AssignmentExpression
1946 //
1947 // TODO(ES6):
1948 // ConstBinding ::
1949 // BindingPattern '=' AssignmentExpression
1950
1951 parsing_result->descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1952 parsing_result->descriptor.declaration_pos = peek_position();
1953 parsing_result->descriptor.initialization_pos = peek_position();
1954 parsing_result->descriptor.mode = VAR;
1955
1956 Block* init_block = nullptr;
1957 if (var_context != kForStatement) {
1958 init_block = factory()->NewBlock(
1959 NULL, 1, true, parsing_result->descriptor.declaration_pos);
1960 }
1961
1962 if (peek() == Token::VAR) {
1963 Consume(Token::VAR);
1964 } else if (peek() == Token::CONST) {
1965 Consume(Token::CONST);
1966 DCHECK(var_context != kStatement);
1967 parsing_result->descriptor.mode = CONST;
1968 } else if (peek() == Token::LET) {
1969 Consume(Token::LET);
1970 DCHECK(var_context != kStatement);
1971 parsing_result->descriptor.mode = LET;
1972 } else {
1973 UNREACHABLE(); // by current callers
1974 }
1975
1976 parsing_result->descriptor.scope = scope();
1977 parsing_result->descriptor.hoist_scope = nullptr;
1978
1979
1980 bool first_declaration = true;
1981 int bindings_start = peek_position();
1982 do {
1983 FuncNameInferrer::State fni_state(fni_);
1984
1985 // Parse name.
1986 if (!first_declaration) Consume(Token::COMMA);
1987
1988 Expression* pattern;
1989 int decl_pos = peek_position();
1990 {
1991 ExpressionClassifier pattern_classifier(this);
1992 pattern = ParsePrimaryExpression(CHECK_OK);
1993 ValidateBindingPattern(CHECK_OK);
1994 if (IsLexicalVariableMode(parsing_result->descriptor.mode)) {
1995 ValidateLetPattern(CHECK_OK);
1996 }
1997 }
1998
1999 Scanner::Location variable_loc = scanner()->location();
2000 const AstRawString* single_name =
2001 pattern->IsVariableProxy() ? pattern->AsVariableProxy()->raw_name()
2002 : nullptr;
2003 if (single_name != nullptr) {
2004 if (fni_ != NULL) fni_->PushVariableName(single_name);
2005 }
2006
2007 Expression* value = NULL;
2008 int initializer_position = kNoSourcePosition;
2009 if (Check(Token::ASSIGN)) {
2010 ExpressionClassifier classifier(this);
2011 value = ParseAssignmentExpression(var_context != kForStatement, CHECK_OK);
2012 RewriteNonPattern(CHECK_OK);
2013 variable_loc.end_pos = scanner()->location().end_pos;
2014
2015 if (!parsing_result->first_initializer_loc.IsValid()) {
2016 parsing_result->first_initializer_loc = variable_loc;
2017 }
2018
2019 // Don't infer if it is "a = function(){...}();"-like expression.
2020 if (single_name) {
2021 if (fni_ != NULL && value->AsCall() == NULL &&
2022 value->AsCallNew() == NULL) {
2023 fni_->Infer();
2024 } else {
2025 fni_->RemoveLastFunction();
2026 }
2027 }
2028
2029 SetFunctionNameFromIdentifierRef(value, pattern);
2030
2031 // End position of the initializer is after the assignment expression.
2032 initializer_position = scanner()->location().end_pos;
2033 } else {
2034 // Initializers may be either required or implied unless this is a
2035 // for-in/of iteration variable.
2036 if (var_context != kForStatement || !PeekInOrOf()) {
2037 // ES6 'const' and binding patterns require initializers.
2038 if (parsing_result->descriptor.mode == CONST ||
2039 !pattern->IsVariableProxy()) {
2040 ReportMessageAt(
2041 Scanner::Location(decl_pos, scanner()->location().end_pos),
2042 MessageTemplate::kDeclarationMissingInitializer,
2043 !pattern->IsVariableProxy() ? "destructuring" : "const");
2044 *ok = false;
2045 return nullptr;
2046 }
2047
2048 // 'let x' initializes 'x' to undefined.
2049 if (parsing_result->descriptor.mode == LET) {
2050 value = GetLiteralUndefined(position());
2051 }
2052 }
2053
2054 // End position of the initializer is after the variable.
2055 initializer_position = position();
2056 }
2057
2058 DeclarationParsingResult::Declaration decl(pattern, initializer_position,
2059 value);
2060 if (var_context == kForStatement) {
2061 // Save the declaration for further handling in ParseForStatement.
2062 parsing_result->declarations.Add(decl);
2063 } else {
2064 // Immediately declare the variable otherwise. This avoids O(N^2)
2065 // behavior (where N is the number of variables in a single
2066 // declaration) in the PatternRewriter having to do with removing
2067 // and adding VariableProxies to the Scope (see bug 4699).
2068 DCHECK_NOT_NULL(init_block);
2069 PatternRewriter::DeclareAndInitializeVariables(
2070 this, init_block, &parsing_result->descriptor, &decl, names,
2071 CHECK_OK);
2072 }
2073 first_declaration = false;
2074 } while (peek() == Token::COMMA);
2075
2076 parsing_result->bindings_loc =
2077 Scanner::Location(bindings_start, scanner()->location().end_pos);
2078
2079 DCHECK(*ok);
2080 return init_block;
2081 }
2082
2083
2084 static bool ContainsLabel(ZoneList<const AstRawString*>* labels, 1941 static bool ContainsLabel(ZoneList<const AstRawString*>* labels,
2085 const AstRawString* label) { 1942 const AstRawString* label) {
2086 DCHECK(label != NULL); 1943 DCHECK(label != NULL);
2087 if (labels != NULL) { 1944 if (labels != NULL) {
2088 for (int i = labels->length(); i-- > 0; ) { 1945 for (int i = labels->length(); i-- > 0; ) {
2089 if (labels->at(i) == label) { 1946 if (labels->at(i) == label) {
2090 return true; 1947 return true;
2091 } 1948 }
2092 } 1949 }
2093 } 1950 }
(...skipping 4537 matching lines...) Expand 10 before | Expand all | Expand 10 after
6631 node->Print(Isolate::Current()); 6488 node->Print(Isolate::Current());
6632 } 6489 }
6633 #endif // DEBUG 6490 #endif // DEBUG
6634 6491
6635 #undef CHECK_OK 6492 #undef CHECK_OK
6636 #undef CHECK_OK_VOID 6493 #undef CHECK_OK_VOID
6637 #undef CHECK_FAILED 6494 #undef CHECK_FAILED
6638 6495
6639 } // namespace internal 6496 } // namespace internal
6640 } // namespace v8 6497 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698