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 1886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 |
OLD | NEW |