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 |