OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/parser.h" | 5 #include "vm/parser.h" |
6 | 6 |
7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
(...skipping 15 matching lines...) Expand all Loading... |
26 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); | 26 DEFINE_FLAG(bool, enable_type_checks, false, "Enable type checks."); |
27 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); | 27 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations."); |
28 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); | 28 DEFINE_FLAG(bool, warning_as_error, false, "Treat warnings as errors."); |
29 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); | 29 DEFINE_FLAG(bool, silent_warnings, false, "Silence warnings."); |
30 DEFINE_FLAG(bool, warn_legacy_map_literal, false, | 30 DEFINE_FLAG(bool, warn_legacy_map_literal, false, |
31 "Warning on legacy map literal syntax (single type argument)"); | 31 "Warning on legacy map literal syntax (single type argument)"); |
32 DEFINE_FLAG(bool, warn_legacy_dynamic, false, | 32 DEFINE_FLAG(bool, warn_legacy_dynamic, false, |
33 "Warning on legacy type Dynamic)"); | 33 "Warning on legacy type Dynamic)"); |
34 DEFINE_FLAG(bool, warn_legacy_getters, false, | 34 DEFINE_FLAG(bool, warn_legacy_getters, false, |
35 "Warning on legacy getter syntax"); | 35 "Warning on legacy getter syntax"); |
| 36 DEFINE_FLAG(bool, strict_function_literals, false, |
| 37 "enforce new function literal rules"); |
36 DECLARE_FLAG(bool, use_cha); | 38 DECLARE_FLAG(bool, use_cha); |
37 | 39 |
38 static void CheckedModeHandler(bool value) { | 40 static void CheckedModeHandler(bool value) { |
39 FLAG_enable_asserts = value; | 41 FLAG_enable_asserts = value; |
40 FLAG_enable_type_checks = value; | 42 FLAG_enable_type_checks = value; |
41 } | 43 } |
42 | 44 |
43 // --enable-checked-mode and --checked both enable checked mode which is | 45 // --enable-checked-mode and --checked both enable checked mode which is |
44 // equivalent to setting --enable-asserts and --enable-type-checks. | 46 // equivalent to setting --enable-asserts and --enable-type-checks. |
45 DEFINE_FLAG_HANDLER(CheckedModeHandler, | 47 DEFINE_FLAG_HANDLER(CheckedModeHandler, |
(...skipping 4907 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4953 } | 4955 } |
4954 | 4956 |
4955 | 4957 |
4956 AstNode* Parser::ParseFunctionStatement(bool is_literal) { | 4958 AstNode* Parser::ParseFunctionStatement(bool is_literal) { |
4957 TRACE_PARSER("ParseFunctionStatement"); | 4959 TRACE_PARSER("ParseFunctionStatement"); |
4958 AbstractType& result_type = AbstractType::Handle(); | 4960 AbstractType& result_type = AbstractType::Handle(); |
4959 const String* variable_name = NULL; | 4961 const String* variable_name = NULL; |
4960 const String* function_name = NULL; | 4962 const String* function_name = NULL; |
4961 | 4963 |
4962 result_type = Type::DynamicType(); | 4964 result_type = Type::DynamicType(); |
4963 if (CurrentToken() == Token::kVOID) { | 4965 |
4964 ConsumeToken(); | 4966 intptr_t ident_pos = TokenPos(); |
4965 result_type = Type::VoidType(); | 4967 if (FLAG_strict_function_literals) { |
4966 } else if ((CurrentToken() == Token::kIDENT) && | 4968 if (is_literal) { |
4967 (LookaheadToken(1) != Token::kLPAREN)) { | 4969 ASSERT(CurrentToken() == Token::kLPAREN); |
4968 result_type = ParseType(ClassFinalizer::kCanonicalize); | 4970 function_name = &String::ZoneHandle(Symbols::AnonymousClosure()); |
| 4971 } else { |
| 4972 if (CurrentToken() == Token::kVOID) { |
| 4973 ConsumeToken(); |
| 4974 result_type = Type::VoidType(); |
| 4975 } else if ((CurrentToken() == Token::kIDENT) && |
| 4976 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4977 result_type = ParseType(ClassFinalizer::kCanonicalize); |
| 4978 } |
| 4979 ident_pos = TokenPos(); |
| 4980 variable_name = ExpectIdentifier("function name expected"); |
| 4981 function_name = variable_name; |
| 4982 } |
| 4983 } else { |
| 4984 // TODO(hausner) remove this block once support for old-style function |
| 4985 // literals is gone. |
| 4986 if (CurrentToken() == Token::kVOID) { |
| 4987 ConsumeToken(); |
| 4988 result_type = Type::VoidType(); |
| 4989 } else if ((CurrentToken() == Token::kIDENT) && |
| 4990 (LookaheadToken(1) != Token::kLPAREN)) { |
| 4991 result_type = ParseType(ClassFinalizer::kCanonicalize); |
| 4992 } |
| 4993 ident_pos = TokenPos(); |
| 4994 if (IsIdentifier()) { |
| 4995 variable_name = CurrentLiteral(); |
| 4996 function_name = variable_name; |
| 4997 ConsumeToken(); |
| 4998 } else { |
| 4999 if (!is_literal) { |
| 5000 ErrorMsg("function name expected"); |
| 5001 } |
| 5002 function_name = &String::ZoneHandle(Symbols::AnonymousClosure()); |
| 5003 } |
4969 } | 5004 } |
4970 const intptr_t ident_pos = TokenPos(); | |
4971 if (IsIdentifier()) { | |
4972 variable_name = CurrentLiteral(); | |
4973 function_name = variable_name; | |
4974 ConsumeToken(); | |
4975 } else { | |
4976 if (!is_literal) { | |
4977 ErrorMsg("function name expected"); | |
4978 } | |
4979 function_name = &String::ZoneHandle(Symbols::AnonymousClosure()); | |
4980 } | |
4981 ASSERT(ident_pos >= 0); | |
4982 | 5005 |
4983 if (CurrentToken() != Token::kLPAREN) { | 5006 if (CurrentToken() != Token::kLPAREN) { |
4984 ErrorMsg("'(' expected"); | 5007 ErrorMsg("'(' expected"); |
4985 } | 5008 } |
4986 intptr_t function_pos = TokenPos(); | 5009 intptr_t function_pos = TokenPos(); |
4987 | 5010 |
4988 // Check whether we have parsed this closure function before, in a previous | 5011 // Check whether we have parsed this closure function before, in a previous |
4989 // compilation. If so, reuse the function object, else create a new one | 5012 // compilation. If so, reuse the function object, else create a new one |
4990 // and register it in the current class. | 5013 // and register it in the current class. |
4991 // Note that we cannot share the same closure function between the closurized | 5014 // Note that we cannot share the same closure function between the closurized |
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5373 return true; | 5396 return true; |
5374 } | 5397 } |
5375 } | 5398 } |
5376 } | 5399 } |
5377 SetPosition(saved_pos); | 5400 SetPosition(saved_pos); |
5378 return false; | 5401 return false; |
5379 } | 5402 } |
5380 | 5403 |
5381 | 5404 |
5382 bool Parser::IsFunctionLiteral() { | 5405 bool Parser::IsFunctionLiteral() { |
5383 if (!allow_function_literals_) { | 5406 // TODO(hausner): Remove code block that supports old-style function |
5384 return false; | 5407 // literals. |
5385 } | 5408 if (FLAG_strict_function_literals) { |
5386 const intptr_t saved_pos = TokenPos(); | 5409 if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) { |
5387 bool is_function_literal = false; | |
5388 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | |
5389 ConsumeToken(); // Consume function identifier. | |
5390 } else if (TryParseReturnType()) { | |
5391 if (!IsIdentifier()) { | |
5392 SetPosition(saved_pos); | |
5393 return false; | 5410 return false; |
5394 } | 5411 } |
5395 ConsumeToken(); // Comsume function identifier. | 5412 const intptr_t saved_pos = TokenPos(); |
5396 } | 5413 bool is_function_literal = false; |
5397 if (CurrentToken() == Token::kLPAREN) { | |
5398 SkipToMatchingParenthesis(); | 5414 SkipToMatchingParenthesis(); |
5399 if ((CurrentToken() == Token::kLBRACE) || | 5415 if ((CurrentToken() == Token::kLBRACE) || |
5400 (CurrentToken() == Token::kARROW)) { | 5416 (CurrentToken() == Token::kARROW)) { |
5401 is_function_literal = true; | 5417 is_function_literal = true; |
5402 } | 5418 } |
| 5419 SetPosition(saved_pos); |
| 5420 return is_function_literal; |
| 5421 } else { |
| 5422 if (!allow_function_literals_) { |
| 5423 return false; |
| 5424 } |
| 5425 const intptr_t saved_pos = TokenPos(); |
| 5426 bool is_function_literal = false; |
| 5427 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 5428 ConsumeToken(); // Consume function identifier. |
| 5429 } else if (TryParseReturnType()) { |
| 5430 if (!IsIdentifier()) { |
| 5431 SetPosition(saved_pos); |
| 5432 return false; |
| 5433 } |
| 5434 ConsumeToken(); // Comsume function identifier. |
| 5435 } |
| 5436 if (CurrentToken() == Token::kLPAREN) { |
| 5437 SkipToMatchingParenthesis(); |
| 5438 if ((CurrentToken() == Token::kLBRACE) || |
| 5439 (CurrentToken() == Token::kARROW)) { |
| 5440 is_function_literal = true; |
| 5441 } |
| 5442 } |
| 5443 SetPosition(saved_pos); |
| 5444 return is_function_literal; |
5403 } | 5445 } |
5404 SetPosition(saved_pos); | |
5405 return is_function_literal; | |
5406 } | 5446 } |
5407 | 5447 |
5408 | 5448 |
5409 // Current token position is the token after the opening ( of the for | 5449 // Current token position is the token after the opening ( of the for |
5410 // statement. Returns true if we recognize a for ( .. in expr) | 5450 // statement. Returns true if we recognize a for ( .. in expr) |
5411 // statement. | 5451 // statement. |
5412 bool Parser::IsForInStatement() { | 5452 bool Parser::IsForInStatement() { |
5413 const intptr_t saved_pos = TokenPos(); | 5453 const intptr_t saved_pos = TokenPos(); |
5414 bool result = false; | 5454 bool result = false; |
5415 // Allow const modifier as well when recognizing a for-in statement | 5455 // Allow const modifier as well when recognizing a for-in statement |
(...skipping 4558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9974 void Parser::SkipQualIdent() { | 10014 void Parser::SkipQualIdent() { |
9975 ASSERT(IsIdentifier()); | 10015 ASSERT(IsIdentifier()); |
9976 ConsumeToken(); | 10016 ConsumeToken(); |
9977 if (CurrentToken() == Token::kPERIOD) { | 10017 if (CurrentToken() == Token::kPERIOD) { |
9978 ConsumeToken(); // Consume the kPERIOD token. | 10018 ConsumeToken(); // Consume the kPERIOD token. |
9979 ExpectIdentifier("identifier expected after '.'"); | 10019 ExpectIdentifier("identifier expected after '.'"); |
9980 } | 10020 } |
9981 } | 10021 } |
9982 | 10022 |
9983 } // namespace dart | 10023 } // namespace dart |
OLD | NEW |