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

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

Issue 2339453002: [parser] Refactor of Parse*Statement*, part 7 (Closed)
Patch Set: Change in comment 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 1767 matching lines...) Expand 10 before | Expand all | Expand 10 after
1778 1778
1779 Expression* tag_read = factory()->NewVariableProxy(tag_variable); 1779 Expression* tag_read = factory()->NewVariableProxy(tag_variable);
1780 switch_statement->Initialize(tag_read, cases); 1780 switch_statement->Initialize(tag_read, cases);
1781 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); 1781 Block* cases_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition);
1782 cases_block->statements()->Add(switch_statement, zone()); 1782 cases_block->statements()->Add(switch_statement, zone());
1783 cases_block->set_scope(scope); 1783 cases_block->set_scope(scope);
1784 switch_block->statements()->Add(cases_block, zone()); 1784 switch_block->statements()->Add(cases_block, zone());
1785 return switch_block; 1785 return switch_block;
1786 } 1786 }
1787 1787
1788 TryStatement* Parser::ParseTryStatement(bool* ok) { 1788 void Parser::RewriteCatchPattern(CatchInfo* catch_info, bool* ok) {
1789 // TryStatement :: 1789 if (catch_info->name == nullptr) {
1790 // 'try' Block Catch 1790 DCHECK_NOT_NULL(catch_info->pattern);
1791 // 'try' Block Finally 1791 catch_info->name = ast_value_factory()->dot_catch_string();
1792 // 'try' Block Catch Finally 1792 }
1793 // 1793 catch_info->variable = catch_info->scope->DeclareLocal(
1794 // Catch :: 1794 catch_info->name, VAR, kCreatedInitialized, NORMAL_VARIABLE);
1795 // 'catch' '(' Identifier ')' Block 1795 if (catch_info->pattern != nullptr) {
1796 // 1796 DeclarationDescriptor descriptor;
1797 // Finally :: 1797 descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1798 // 'finally' Block 1798 descriptor.scope = scope();
1799 descriptor.hoist_scope = nullptr;
1800 descriptor.mode = LET;
1801 descriptor.declaration_pos = catch_info->pattern->position();
1802 descriptor.initialization_pos = catch_info->pattern->position();
1799 1803
1800 Expect(Token::TRY, CHECK_OK); 1804 // Initializer position for variables declared by the pattern.
1801 int pos = position(); 1805 const int initializer_position = position();
1802 1806
1803 Block* try_block; 1807 DeclarationParsingResult::Declaration decl(
1804 { 1808 catch_info->pattern, initializer_position,
1805 ReturnExprScope no_tail_calls(function_state_, 1809 factory()->NewVariableProxy(catch_info->variable));
1806 ReturnExprContext::kInsideTryBlock); 1810
1807 try_block = ParseBlock(NULL, CHECK_OK); 1811 catch_info->init_block =
1812 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
1813 PatternRewriter::DeclareAndInitializeVariables(
1814 this, catch_info->init_block, &descriptor, &decl,
1815 &catch_info->bound_names, ok);
1816 } else {
1817 catch_info->bound_names.Add(catch_info->name, zone());
1808 } 1818 }
1819 }
1809 1820
1810 Token::Value tok = peek(); 1821 void Parser::ValidateCatchBlock(const CatchInfo& catch_info, bool* ok) {
1822 // Check for `catch(e) { let e; }` and similar errors.
1823 Scope* inner_block_scope = catch_info.inner_block->scope();
1824 if (inner_block_scope != nullptr) {
1825 Declaration* decl = inner_block_scope->CheckLexDeclarationsConflictingWith(
1826 catch_info.bound_names);
1827 if (decl != nullptr) {
1828 const AstRawString* name = decl->proxy()->raw_name();
1829 int position = decl->proxy()->position();
1830 Scanner::Location location =
1831 position == kNoSourcePosition
1832 ? Scanner::Location::invalid()
1833 : Scanner::Location(position, position + 1);
1834 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1835 *ok = false;
1836 }
1837 }
1838 }
1811 1839
1812 bool catch_for_promise_reject = false; 1840 Statement* Parser::RewriteTryStatement(Block* try_block, Block* catch_block,
1813 if (allow_natives() && tok == Token::MOD) { 1841 Block* finally_block,
1814 Consume(Token::MOD); 1842 const CatchInfo& catch_info, int pos) {
1815 catch_for_promise_reject = true;
1816 tok = peek();
1817 }
1818
1819 if (tok != Token::CATCH && tok != Token::FINALLY) {
1820 ReportMessage(MessageTemplate::kNoCatchOrFinally);
1821 *ok = false;
1822 return NULL;
1823 }
1824
1825 Scope* catch_scope = NULL;
1826 Variable* catch_variable = NULL;
1827 Block* catch_block = NULL;
1828 TailCallExpressionList tail_call_expressions_in_catch_block(zone());
1829 if (tok == Token::CATCH) {
1830 Consume(Token::CATCH);
1831
1832 Expect(Token::LPAREN, CHECK_OK);
1833 catch_scope = NewScope(CATCH_SCOPE);
1834 catch_scope->set_start_position(scanner()->location().beg_pos);
1835
1836 {
1837 CollectExpressionsInTailPositionToListScope
1838 collect_tail_call_expressions_scope(
1839 function_state_, &tail_call_expressions_in_catch_block);
1840 BlockState block_state(&scope_state_, catch_scope);
1841
1842 catch_block = factory()->NewBlock(nullptr, 16, false, kNoSourcePosition);
1843
1844 // Create a block scope to hold any lexical declarations created
1845 // as part of destructuring the catch parameter.
1846 {
1847 BlockState block_state(&scope_state_);
1848 block_state.set_start_position(scanner()->location().beg_pos);
1849 ParserTarget target(this, catch_block);
1850
1851 const AstRawString* name = ast_value_factory()->dot_catch_string();
1852 Expression* pattern = nullptr;
1853 if (peek_any_identifier()) {
1854 name = ParseIdentifier(kDontAllowRestrictedIdentifiers, CHECK_OK);
1855 } else {
1856 ExpressionClassifier pattern_classifier(this);
1857 pattern = ParsePrimaryExpression(CHECK_OK);
1858 ValidateBindingPattern(CHECK_OK);
1859 }
1860 catch_variable = catch_scope->DeclareLocal(
1861 name, VAR, kCreatedInitialized, NORMAL_VARIABLE);
1862
1863 Expect(Token::RPAREN, CHECK_OK);
1864
1865 ZoneList<const AstRawString*> bound_names(1, zone());
1866 if (pattern != nullptr) {
1867 DeclarationDescriptor descriptor;
1868 descriptor.declaration_kind = DeclarationDescriptor::NORMAL;
1869 descriptor.scope = scope();
1870 descriptor.hoist_scope = nullptr;
1871 descriptor.mode = LET;
1872 descriptor.declaration_pos = pattern->position();
1873 descriptor.initialization_pos = pattern->position();
1874
1875 // Initializer position for variables declared by the pattern.
1876 const int initializer_position = position();
1877
1878 DeclarationParsingResult::Declaration decl(
1879 pattern, initializer_position,
1880 factory()->NewVariableProxy(catch_variable));
1881
1882 Block* init_block =
1883 factory()->NewBlock(nullptr, 8, true, kNoSourcePosition);
1884 PatternRewriter::DeclareAndInitializeVariables(
1885 this, init_block, &descriptor, &decl, &bound_names, CHECK_OK);
1886 catch_block->statements()->Add(init_block, zone());
1887 } else {
1888 bound_names.Add(name, zone());
1889 }
1890
1891 Block* inner_block = ParseBlock(nullptr, CHECK_OK);
1892 catch_block->statements()->Add(inner_block, zone());
1893
1894 // Check for `catch(e) { let e; }` and similar errors.
1895 Scope* inner_block_scope = inner_block->scope();
1896 if (inner_block_scope != nullptr) {
1897 Declaration* decl =
1898 inner_block_scope->CheckLexDeclarationsConflictingWith(
1899 bound_names);
1900 if (decl != nullptr) {
1901 const AstRawString* name = decl->proxy()->raw_name();
1902 int position = decl->proxy()->position();
1903 Scanner::Location location =
1904 position == kNoSourcePosition
1905 ? Scanner::Location::invalid()
1906 : Scanner::Location(position, position + 1);
1907 ReportMessageAt(location, MessageTemplate::kVarRedeclaration, name);
1908 *ok = false;
1909 return nullptr;
1910 }
1911 }
1912 block_state.set_end_position(scanner()->location().end_pos);
1913 catch_block->set_scope(block_state.FinalizedBlockScope());
1914 }
1915 }
1916
1917 catch_scope->set_end_position(scanner()->location().end_pos);
1918 tok = peek();
1919 }
1920
1921 Block* finally_block = NULL;
1922 DCHECK(tok == Token::FINALLY || catch_block != NULL);
1923 if (tok == Token::FINALLY) {
1924 Consume(Token::FINALLY);
1925 finally_block = ParseBlock(NULL, CHECK_OK);
1926 }
1927
1928 // Simplify the AST nodes by converting: 1843 // Simplify the AST nodes by converting:
1929 // 'try B0 catch B1 finally B2' 1844 // 'try B0 catch B1 finally B2'
1930 // to: 1845 // to:
1931 // 'try { try B0 catch B1 } finally B2' 1846 // 'try { try B0 catch B1 } finally B2'
1932 1847
1933 if (catch_block != NULL && finally_block != NULL) { 1848 if (catch_block != nullptr && finally_block != nullptr) {
1934 // If we have both, create an inner try/catch. 1849 // If we have both, create an inner try/catch.
1935 DCHECK(catch_scope != NULL && catch_variable != NULL); 1850 DCHECK_NOT_NULL(catch_info.scope);
1851 DCHECK_NOT_NULL(catch_info.variable);
1936 TryCatchStatement* statement; 1852 TryCatchStatement* statement;
1937 if (catch_for_promise_reject) { 1853 if (catch_info.for_promise_reject) {
1938 statement = factory()->NewTryCatchStatementForPromiseReject( 1854 statement = factory()->NewTryCatchStatementForPromiseReject(
1939 try_block, catch_scope, catch_variable, catch_block, 1855 try_block, catch_info.scope, catch_info.variable, catch_block,
1940 kNoSourcePosition); 1856 kNoSourcePosition);
1941 } else { 1857 } else {
1942 statement = factory()->NewTryCatchStatement(try_block, catch_scope, 1858 statement = factory()->NewTryCatchStatement(
1943 catch_variable, catch_block, 1859 try_block, catch_info.scope, catch_info.variable, catch_block,
1944 kNoSourcePosition); 1860 kNoSourcePosition);
1945 } 1861 }
1946 1862
1947 try_block = factory()->NewBlock(NULL, 1, false, kNoSourcePosition); 1863 try_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
1948 try_block->statements()->Add(statement, zone()); 1864 try_block->statements()->Add(statement, zone());
1949 catch_block = NULL; // Clear to indicate it's been handled. 1865 catch_block = nullptr; // Clear to indicate it's been handled.
1950 } 1866 }
1951 1867
1952 TryStatement* result = NULL; 1868 if (catch_block != nullptr) {
1953 if (catch_block != NULL) {
1954 // For a try-catch construct append return expressions from the catch block 1869 // For a try-catch construct append return expressions from the catch block
1955 // to the list of return expressions. 1870 // to the list of return expressions.
1956 function_state_->tail_call_expressions().Append( 1871 function_state_->tail_call_expressions().Append(
1957 tail_call_expressions_in_catch_block); 1872 catch_info.tail_call_expressions);
1958 1873
1959 DCHECK(finally_block == NULL); 1874 DCHECK_NULL(finally_block);
1960 DCHECK(catch_scope != NULL && catch_variable != NULL); 1875 DCHECK_NOT_NULL(catch_info.scope);
1961 result = factory()->NewTryCatchStatement(try_block, catch_scope, 1876 DCHECK_NOT_NULL(catch_info.variable);
1962 catch_variable, catch_block, pos); 1877 return factory()->NewTryCatchStatement(
1878 try_block, catch_info.scope, catch_info.variable, catch_block, pos);
1963 } else { 1879 } else {
1964 if (FLAG_harmony_explicit_tailcalls && 1880 DCHECK_NOT_NULL(finally_block);
1965 tail_call_expressions_in_catch_block.has_explicit_tail_calls()) { 1881 return factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1966 // TODO(ishell): update chapter number.
1967 // ES8 XX.YY.ZZ
1968 ReportMessageAt(tail_call_expressions_in_catch_block.location(),
1969 MessageTemplate::kUnexpectedTailCallInCatchBlock);
1970 *ok = false;
1971 return NULL;
1972 }
1973 DCHECK(finally_block != NULL);
1974 result = factory()->NewTryFinallyStatement(try_block, finally_block, pos);
1975 } 1882 }
1976
1977 return result;
1978 } 1883 }
1979 1884
1980
1981 // !%_IsJSReceiver(result = iterator.next()) && 1885 // !%_IsJSReceiver(result = iterator.next()) &&
1982 // %ThrowIteratorResultNotAnObject(result) 1886 // %ThrowIteratorResultNotAnObject(result)
1983 Expression* Parser::BuildIteratorNextResult(Expression* iterator, 1887 Expression* Parser::BuildIteratorNextResult(Expression* iterator,
1984 Variable* result, int pos) { 1888 Variable* result, int pos) {
1985 Expression* next_literal = factory()->NewStringLiteral( 1889 Expression* next_literal = factory()->NewStringLiteral(
1986 ast_value_factory()->next_string(), kNoSourcePosition); 1890 ast_value_factory()->next_string(), kNoSourcePosition);
1987 Expression* next_property = 1891 Expression* next_property =
1988 factory()->NewProperty(iterator, next_literal, kNoSourcePosition); 1892 factory()->NewProperty(iterator, next_literal, kNoSourcePosition);
1989 ZoneList<Expression*>* next_arguments = 1893 ZoneList<Expression*>* next_arguments =
1990 new (zone()) ZoneList<Expression*>(0, zone()); 1894 new (zone()) ZoneList<Expression*>(0, zone());
(...skipping 3629 matching lines...) Expand 10 before | Expand all | Expand 10 after
5620 node->Print(Isolate::Current()); 5524 node->Print(Isolate::Current());
5621 } 5525 }
5622 #endif // DEBUG 5526 #endif // DEBUG
5623 5527
5624 #undef CHECK_OK 5528 #undef CHECK_OK
5625 #undef CHECK_OK_VOID 5529 #undef CHECK_OK_VOID
5626 #undef CHECK_FAILED 5530 #undef CHECK_FAILED
5627 5531
5628 } // namespace internal 5532 } // namespace internal
5629 } // namespace v8 5533 } // 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