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

Side by Side Diff: src/parsing/parser.cc

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

Powered by Google App Engine
This is Rietveld 408576698