| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |