| 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 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 262 return &result; | 262 return &result; |
| 263 } | 263 } |
| 264 | 264 |
| 265 | 265 |
| 266 // A QualIdent is an optionally qualified identifier. | 266 // A QualIdent is an optionally qualified identifier. |
| 267 struct QualIdent { | 267 struct QualIdent { |
| 268 QualIdent() { | 268 QualIdent() { |
| 269 Clear(); | 269 Clear(); |
| 270 } | 270 } |
| 271 void Clear() { | 271 void Clear() { |
| 272 is_local_scope_ident = false; | |
| 273 lib_prefix = NULL; | 272 lib_prefix = NULL; |
| 274 qualifier = NULL; | 273 qualifier = NULL; |
| 275 ident_pos = 0; | 274 ident_pos = 0; |
| 276 ident = NULL; | 275 ident = NULL; |
| 277 } | 276 } |
| 278 bool is_local_scope_ident; | |
| 279 LibraryPrefix* lib_prefix; | 277 LibraryPrefix* lib_prefix; |
| 280 String* qualifier; | 278 String* qualifier; |
| 281 intptr_t ident_pos; | 279 intptr_t ident_pos; |
| 282 String* ident; | 280 String* ident; |
| 283 }; | 281 }; |
| 284 | 282 |
| 285 | 283 |
| 286 struct ParamDesc { | 284 struct ParamDesc { |
| 287 ParamDesc() | 285 ParamDesc() |
| 288 : type(NULL), | 286 : type(NULL), |
| (...skipping 1613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1902 SkipExpr(); | 1900 SkipExpr(); |
| 1903 SetAllowFunctionLiterals(true); | 1901 SetAllowFunctionLiterals(true); |
| 1904 } | 1902 } |
| 1905 } while (CurrentToken() == Token::kCOMMA); | 1903 } while (CurrentToken() == Token::kCOMMA); |
| 1906 } | 1904 } |
| 1907 | 1905 |
| 1908 | 1906 |
| 1909 void Parser::ParseQualIdent(QualIdent* qual_ident) { | 1907 void Parser::ParseQualIdent(QualIdent* qual_ident) { |
| 1910 ASSERT(IsIdentifier()); | 1908 ASSERT(IsIdentifier()); |
| 1911 if (!is_top_level_) { | 1909 if (!is_top_level_) { |
| 1912 AstNode* var_or_field = NULL; | |
| 1913 bool is_local_ident = ResolveIdentInLocalScope(token_index_, | |
| 1914 *CurrentLiteral(), | |
| 1915 &var_or_field); | |
| 1916 qual_ident->ident_pos = token_index_; | 1910 qual_ident->ident_pos = token_index_; |
| 1917 qual_ident->ident = CurrentLiteral(); | 1911 qual_ident->ident = CurrentLiteral(); |
| 1918 qual_ident->lib_prefix = NULL; | 1912 qual_ident->lib_prefix = NULL; |
| 1919 qual_ident->qualifier = NULL; | 1913 qual_ident->qualifier = NULL; |
| 1920 qual_ident->is_local_scope_ident = is_local_ident; | |
| 1921 ConsumeToken(); | 1914 ConsumeToken(); |
| 1922 if (!is_local_ident && (CurrentToken() == Token::kPERIOD)) { | 1915 if (CurrentToken() == Token::kPERIOD) { |
| 1923 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); | 1916 if (!ResolveIdentInLocalScope(qual_ident->ident_pos, |
| 1924 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); | 1917 *(qual_ident->ident), |
| 1925 if (!lib_prefix.IsNull()) { | 1918 NULL)) { |
| 1926 // We have a library prefix qualified identifier. | 1919 LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle(); |
| 1927 ConsumeToken(); // Consume the kPERIOD token. | 1920 lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident)); |
| 1928 qual_ident->lib_prefix = &lib_prefix; | 1921 if (!lib_prefix.IsNull()) { |
| 1929 qual_ident->qualifier = qual_ident->ident; | 1922 // We have a library prefix qualified identifier. |
| 1930 qual_ident->ident_pos = token_index_; | 1923 ConsumeToken(); // Consume the kPERIOD token. |
| 1931 qual_ident->ident = ExpectIdentifier("identifier expected after '.'"); | 1924 qual_ident->lib_prefix = &lib_prefix; |
| 1925 qual_ident->qualifier = qual_ident->ident; |
| 1926 qual_ident->ident_pos = token_index_; |
| 1927 qual_ident->ident = ExpectIdentifier("identifier expected after '.'"); |
| 1928 } |
| 1932 } | 1929 } |
| 1933 } | 1930 } |
| 1934 } else { | 1931 } else { |
| 1935 qual_ident->ident_pos = token_index_; | 1932 qual_ident->ident_pos = token_index_; |
| 1936 qual_ident->ident = CurrentLiteral(); | 1933 qual_ident->ident = CurrentLiteral(); |
| 1937 qual_ident->lib_prefix = NULL; | 1934 qual_ident->lib_prefix = NULL; |
| 1938 qual_ident->qualifier = NULL; | 1935 qual_ident->qualifier = NULL; |
| 1939 qual_ident->is_local_scope_ident = false; | |
| 1940 ConsumeToken(); | 1936 ConsumeToken(); |
| 1941 if (CurrentToken() == Token::kPERIOD) { | 1937 if (CurrentToken() == Token::kPERIOD) { |
| 1942 ConsumeToken(); // Consume the kPERIOD token. | 1938 ConsumeToken(); // Consume the kPERIOD token. |
| 1943 qual_ident->qualifier = qual_ident->ident; | 1939 qual_ident->qualifier = qual_ident->ident; |
| 1944 qual_ident->ident_pos = token_index_; | 1940 qual_ident->ident_pos = token_index_; |
| 1945 qual_ident->ident = ExpectIdentifier("identifier expected after '.'"); | 1941 qual_ident->ident = ExpectIdentifier("identifier expected after '.'"); |
| 1946 } | 1942 } |
| 1947 } | 1943 } |
| 1948 } | 1944 } |
| 1949 | 1945 |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2349 qualifier ^= member.name->raw(); | 2345 qualifier ^= member.name->raw(); |
| 2350 member.name = ExpectIdentifier("identifier expected"); | 2346 member.name = ExpectIdentifier("identifier expected"); |
| 2351 } | 2347 } |
| 2352 } | 2348 } |
| 2353 // TODO(regis): Remove support for type parameters on factories. | 2349 // TODO(regis): Remove support for type parameters on factories. |
| 2354 // Once done, stop postponing resolution of the factory result type until | 2350 // Once done, stop postponing resolution of the factory result type until |
| 2355 // class finalization. | 2351 // class finalization. |
| 2356 const UnresolvedClass& unresolved_factory_class = | 2352 const UnresolvedClass& unresolved_factory_class = |
| 2357 UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos, | 2353 UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos, |
| 2358 qualifier, | 2354 qualifier, |
| 2359 *(member.name))); | 2355 *member.name)); |
| 2360 const Class& signature_class = Class::Handle( | 2356 const Class& signature_class = Class::Handle( |
| 2361 Class::New(String::Handle(String::NewSymbol(":factory_signature")), | 2357 Class::New(String::Handle(String::NewSymbol(":factory_signature")), |
| 2362 script_)); | 2358 script_)); |
| 2363 signature_class.set_is_finalized(); | 2359 signature_class.set_is_finalized(); |
| 2364 signature_class.set_library(library_); | 2360 signature_class.set_library(library_); |
| 2365 unresolved_factory_class.set_factory_signature_class(signature_class); | 2361 unresolved_factory_class.set_factory_signature_class(signature_class); |
| 2366 // The type arguments of the result type are set during finalization. | 2362 // The type arguments of the result type are set during finalization. |
| 2367 const TypeArguments& args = TypeArguments::Handle(); | 2363 const TypeArguments& args = TypeArguments::Handle(); |
| 2368 member.type = &Type::ZoneHandle( | 2364 member.type = &Type::ZoneHandle( |
| 2369 Type::NewParameterizedType(unresolved_factory_class, args)); | 2365 Type::NewParameterizedType(unresolved_factory_class, args)); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2636 // and the alias name of a function type alias. | 2632 // and the alias name of a function type alias. |
| 2637 // Token position remains unchanged. | 2633 // Token position remains unchanged. |
| 2638 bool Parser::IsFunctionTypeAliasName() { | 2634 bool Parser::IsFunctionTypeAliasName() { |
| 2639 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 2635 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 2640 return true; | 2636 return true; |
| 2641 } | 2637 } |
| 2642 const intptr_t saved_pos = token_index_; | 2638 const intptr_t saved_pos = token_index_; |
| 2643 bool is_alias_name = false; | 2639 bool is_alias_name = false; |
| 2644 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { | 2640 if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) { |
| 2645 ConsumeToken(); | 2641 ConsumeToken(); |
| 2646 if (IsTypeParameter() && (CurrentToken() == Token::kLPAREN)) { | 2642 if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) { |
| 2647 is_alias_name = true; | 2643 is_alias_name = true; |
| 2648 } | 2644 } |
| 2649 } | 2645 } |
| 2650 SetPosition(saved_pos); | 2646 SetPosition(saved_pos); |
| 2651 return is_alias_name; | 2647 return is_alias_name; |
| 2652 } | 2648 } |
| 2653 | 2649 |
| 2654 | 2650 |
| 2655 void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) { | 2651 void Parser::ParseFunctionTypeAlias(GrowableArray<const Class*>* classes) { |
| 2656 TRACE_PARSER("ParseFunctionTypeAlias"); | 2652 TRACE_PARSER("ParseFunctionTypeAlias"); |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2789 if (CurrentToken() == Token::kFACTORY) { | 2785 if (CurrentToken() == Token::kFACTORY) { |
| 2790 Warning("'factory' is obsolete, use 'default' instead."); | 2786 Warning("'factory' is obsolete, use 'default' instead."); |
| 2791 } | 2787 } |
| 2792 ConsumeToken(); | 2788 ConsumeToken(); |
| 2793 if (CurrentToken() != Token::kIDENT) { | 2789 if (CurrentToken() != Token::kIDENT) { |
| 2794 ErrorMsg("class name expected"); | 2790 ErrorMsg("class name expected"); |
| 2795 } | 2791 } |
| 2796 const intptr_t factory_pos = token_index_; | 2792 const intptr_t factory_pos = token_index_; |
| 2797 QualIdent factory_name; | 2793 QualIdent factory_name; |
| 2798 ParseQualIdent(&factory_name); | 2794 ParseQualIdent(&factory_name); |
| 2799 if (factory_name.is_local_scope_ident) { | |
| 2800 ErrorMsg(factory_pos, | |
| 2801 "using '%s' in this context is invalid", | |
| 2802 factory_name.ident->ToCString()); | |
| 2803 } | |
| 2804 String& qualifier = String::Handle(); | 2795 String& qualifier = String::Handle(); |
| 2805 if (factory_name.qualifier != NULL) { | 2796 if (factory_name.qualifier != NULL) { |
| 2806 qualifier ^= factory_name.qualifier->raw(); | 2797 qualifier ^= factory_name.qualifier->raw(); |
| 2807 } | 2798 } |
| 2808 const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle( | 2799 const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle( |
| 2809 UnresolvedClass::New(factory_pos, qualifier, *(factory_name.ident))); | 2800 UnresolvedClass::New(factory_pos, qualifier, *factory_name.ident)); |
| 2810 const Class& factory_class = Class::Handle( | 2801 const Class& factory_class = Class::Handle( |
| 2811 Class::New(String::Handle(String::NewSymbol(":factory_signature")), | 2802 Class::New(String::Handle(String::NewSymbol(":factory_signature")), |
| 2812 script_)); | 2803 script_)); |
| 2813 factory_class.set_library(library_); | 2804 factory_class.set_library(library_); |
| 2814 factory_class.set_is_finalized(); | 2805 factory_class.set_is_finalized(); |
| 2815 ParseTypeParameters(factory_class); | 2806 ParseTypeParameters(factory_class); |
| 2816 unresolved_factory_class.set_factory_signature_class(factory_class); | 2807 unresolved_factory_class.set_factory_signature_class(factory_class); |
| 2817 interface.set_factory_class(unresolved_factory_class); | 2808 interface.set_factory_class(unresolved_factory_class); |
| 2818 // Verify that the type parameters of the factory class and of the interface | 2809 // Verify that the type parameters of the factory class and of the interface |
| 2819 // have identical names. | 2810 // have identical names. |
| (...skipping 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3909 } else { | 3900 } else { |
| 3910 AstNode* initialization = | 3901 AstNode* initialization = |
| 3911 new StoreLocalNode(ident_pos, *function_variable, closure); | 3902 new StoreLocalNode(ident_pos, *function_variable, closure); |
| 3912 return initialization; | 3903 return initialization; |
| 3913 } | 3904 } |
| 3914 } | 3905 } |
| 3915 | 3906 |
| 3916 | 3907 |
| 3917 // Returns true if the current and next tokens can be parsed as type | 3908 // Returns true if the current and next tokens can be parsed as type |
| 3918 // parameters. Current token position is not saved and restored. | 3909 // parameters. Current token position is not saved and restored. |
| 3919 bool Parser::IsTypeParameter() { | 3910 bool Parser::TryParseTypeParameter() { |
| 3920 if (CurrentToken() == Token::kLT) { | 3911 if (CurrentToken() == Token::kLT) { |
| 3921 // We are possibly looking at type parameters. Find closing ">". | 3912 // We are possibly looking at type parameters. Find closing ">". |
| 3922 int nesting_level = 0; | 3913 int nesting_level = 0; |
| 3923 do { | 3914 do { |
| 3924 if (CurrentToken() == Token::kLT) { | 3915 if (CurrentToken() == Token::kLT) { |
| 3925 nesting_level++; | 3916 nesting_level++; |
| 3926 } else if (CurrentToken() == Token::kGT) { | 3917 } else if (CurrentToken() == Token::kGT) { |
| 3927 nesting_level--; | 3918 nesting_level--; |
| 3928 } else if (CurrentToken() == Token::kSHR) { | 3919 } else if (CurrentToken() == Token::kSHR) { |
| 3929 nesting_level -= 2; | 3920 nesting_level -= 2; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 3949 | 3940 |
| 3950 | 3941 |
| 3951 // Returns true if the current token is kIDENT or a pseudo-keyword. | 3942 // Returns true if the current token is kIDENT or a pseudo-keyword. |
| 3952 bool Parser::IsIdentifier() { | 3943 bool Parser::IsIdentifier() { |
| 3953 return Token::IsIdentifier(CurrentToken()); | 3944 return Token::IsIdentifier(CurrentToken()); |
| 3954 } | 3945 } |
| 3955 | 3946 |
| 3956 | 3947 |
| 3957 // Returns true if the next tokens can be parsed as a type with optional | 3948 // Returns true if the next tokens can be parsed as a type with optional |
| 3958 // type parameters. Current token position is not restored. | 3949 // type parameters. Current token position is not restored. |
| 3959 bool Parser::IsOptionalType() { | 3950 bool Parser::TryParseOptionalType() { |
| 3960 if (CurrentToken() == Token::kIDENT) { | 3951 if (CurrentToken() == Token::kIDENT) { |
| 3961 QualIdent type_name; | 3952 QualIdent type_name; |
| 3962 ParseQualIdent(&type_name); | 3953 ParseQualIdent(&type_name); |
| 3963 // Check if the type_name has been defined as a variable in a local scope, | 3954 if ((CurrentToken() == Token::kLT) && !TryParseTypeParameter()) { |
| 3964 // hiding the type. | |
| 3965 if (type_name.is_local_scope_ident) { | |
| 3966 return false; | |
| 3967 } | |
| 3968 if (CurrentToken() == Token::kLT && !IsTypeParameter()) { | |
| 3969 return false; | 3955 return false; |
| 3970 } | 3956 } |
| 3971 } | 3957 } |
| 3972 return true; | 3958 return true; |
| 3973 } | 3959 } |
| 3974 | 3960 |
| 3975 | 3961 |
| 3976 // Returns true if the next tokens can be parsed as a type with optional | 3962 // Returns true if the next tokens can be parsed as a type with optional |
| 3977 // type parameters, or keyword "void". | 3963 // type parameters, or keyword "void". |
| 3978 // Current token position is not restored. | 3964 // Current token position is not restored. |
| 3979 bool Parser::IsReturnType() { | 3965 bool Parser::TryParseReturnType() { |
| 3980 if (CurrentToken() == Token::kVOID) { | 3966 if (CurrentToken() == Token::kVOID) { |
| 3981 ConsumeToken(); | 3967 ConsumeToken(); |
| 3982 return true; | 3968 return true; |
| 3983 } else if (CurrentToken() == Token::kIDENT) { | 3969 } else if (CurrentToken() == Token::kIDENT) { |
| 3984 return IsOptionalType(); | 3970 return TryParseOptionalType(); |
| 3985 } | 3971 } |
| 3986 return false; | 3972 return false; |
| 3987 } | 3973 } |
| 3988 | 3974 |
| 3989 | 3975 |
| 3990 // Look ahead to detect whether the next tokens should be parsed as | 3976 // Look ahead to detect whether the next tokens should be parsed as |
| 3991 // a variable declaration. Returns true if we detect the token pattern: | 3977 // a variable declaration. Returns true if we detect the token pattern: |
| 3992 // ('var' | 'final' | type ident (';' | '=' | ',')) | 3978 // ('var' | 'final' | type ident (';' | '=' | ',')) |
| 3993 // Token position remains unchanged. | 3979 // Token position remains unchanged. |
| 3994 bool Parser::IsVariableDeclaration() { | 3980 bool Parser::IsVariableDeclaration() { |
| 3995 if ((CurrentToken() == Token::kVAR) || | 3981 if ((CurrentToken() == Token::kVAR) || |
| 3996 (CurrentToken() == Token::kFINAL)) { | 3982 (CurrentToken() == Token::kFINAL)) { |
| 3997 return true; | 3983 return true; |
| 3998 } | 3984 } |
| 3999 if (CurrentToken() != Token::kIDENT) { | 3985 if (CurrentToken() != Token::kIDENT) { |
| 4000 // Not a legal type identifier. | 3986 // Not a legal type identifier. |
| 4001 return false; | 3987 return false; |
| 4002 } | 3988 } |
| 4003 const intptr_t saved_pos = token_index_; | 3989 const intptr_t saved_pos = token_index_; |
| 4004 bool is_var_decl = false; | 3990 bool is_var_decl = false; |
| 4005 if (IsOptionalType()) { | 3991 if (TryParseOptionalType()) { |
| 4006 if (IsIdentifier()) { | 3992 if (IsIdentifier()) { |
| 4007 ConsumeToken(); | 3993 ConsumeToken(); |
| 4008 if ((CurrentToken() == Token::kSEMICOLON) || | 3994 if ((CurrentToken() == Token::kSEMICOLON) || |
| 4009 (CurrentToken() == Token::kCOMMA) || | 3995 (CurrentToken() == Token::kCOMMA) || |
| 4010 (CurrentToken() == Token::kASSIGN)) { | 3996 (CurrentToken() == Token::kASSIGN)) { |
| 4011 is_var_decl = true; | 3997 is_var_decl = true; |
| 4012 } | 3998 } |
| 4013 } | 3999 } |
| 4014 } | 4000 } |
| 4015 SetPosition(saved_pos); | 4001 SetPosition(saved_pos); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 4030 return (IsIdentifier() && | 4016 return (IsIdentifier() && |
| 4031 (LookaheadToken(1) == Token::kLPAREN)) || IsFunctionDeclaration(); | 4017 (LookaheadToken(1) == Token::kLPAREN)) || IsFunctionDeclaration(); |
| 4032 } | 4018 } |
| 4033 | 4019 |
| 4034 | 4020 |
| 4035 bool Parser::IsTopLevelAccessor() { | 4021 bool Parser::IsTopLevelAccessor() { |
| 4036 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4022 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4037 return true; | 4023 return true; |
| 4038 } | 4024 } |
| 4039 const intptr_t saved_pos = token_index_; | 4025 const intptr_t saved_pos = token_index_; |
| 4040 if (IsReturnType()) { | 4026 if (TryParseReturnType()) { |
| 4041 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { | 4027 if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) { |
| 4042 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. | 4028 if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name. |
| 4043 SetPosition(saved_pos); | 4029 SetPosition(saved_pos); |
| 4044 return true; | 4030 return true; |
| 4045 } | 4031 } |
| 4046 } | 4032 } |
| 4047 } | 4033 } |
| 4048 SetPosition(saved_pos); | 4034 SetPosition(saved_pos); |
| 4049 return false; | 4035 return false; |
| 4050 } | 4036 } |
| 4051 | 4037 |
| 4052 | 4038 |
| 4053 bool Parser::IsFunctionLiteral() { | 4039 bool Parser::IsFunctionLiteral() { |
| 4054 if (!allow_function_literals_) { | 4040 if (!allow_function_literals_) { |
| 4055 return false; | 4041 return false; |
| 4056 } | 4042 } |
| 4057 const intptr_t saved_pos = token_index_; | 4043 const intptr_t saved_pos = token_index_; |
| 4058 bool is_function_literal = false; | 4044 bool is_function_literal = false; |
| 4059 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { | 4045 if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) { |
| 4060 ConsumeToken(); // Consume function identifier. | 4046 ConsumeToken(); // Consume function identifier. |
| 4061 } else if (IsReturnType()) { | 4047 } else if (TryParseReturnType()) { |
| 4062 if (!IsIdentifier()) { | 4048 if (!IsIdentifier()) { |
| 4063 SetPosition(saved_pos); | 4049 SetPosition(saved_pos); |
| 4064 return false; | 4050 return false; |
| 4065 } | 4051 } |
| 4066 ConsumeToken(); // Comsume function identifier. | 4052 ConsumeToken(); // Comsume function identifier. |
| 4067 } | 4053 } |
| 4068 if (CurrentToken() == Token::kLPAREN) { | 4054 if (CurrentToken() == Token::kLPAREN) { |
| 4069 SkipToMatchingParenthesis(); | 4055 SkipToMatchingParenthesis(); |
| 4070 if ((CurrentToken() == Token::kLBRACE) || | 4056 if ((CurrentToken() == Token::kLBRACE) || |
| 4071 (CurrentToken() == Token::kARROW)) { | 4057 (CurrentToken() == Token::kARROW)) { |
| (...skipping 10 matching lines...) Expand all Loading... |
| 4082 // statement. | 4068 // statement. |
| 4083 bool Parser::IsForInStatement() { | 4069 bool Parser::IsForInStatement() { |
| 4084 const intptr_t saved_pos = token_index_; | 4070 const intptr_t saved_pos = token_index_; |
| 4085 bool result = false; | 4071 bool result = false; |
| 4086 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { | 4072 if (CurrentToken() == Token::kVAR || CurrentToken() == Token::kFINAL) { |
| 4087 ConsumeToken(); | 4073 ConsumeToken(); |
| 4088 } | 4074 } |
| 4089 if (IsIdentifier()) { | 4075 if (IsIdentifier()) { |
| 4090 if (LookaheadToken(1) == Token::kIN) { | 4076 if (LookaheadToken(1) == Token::kIN) { |
| 4091 result = true; | 4077 result = true; |
| 4092 } else if (IsOptionalType()) { | 4078 } else if (TryParseOptionalType()) { |
| 4093 if (IsIdentifier()) { | 4079 if (IsIdentifier()) { |
| 4094 ConsumeToken(); | 4080 ConsumeToken(); |
| 4095 } | 4081 } |
| 4096 result = (CurrentToken() == Token::kIN); | 4082 result = (CurrentToken() == Token::kIN); |
| 4097 } | 4083 } |
| 4098 } | 4084 } |
| 4099 SetPosition(saved_pos); | 4085 SetPosition(saved_pos); |
| 4100 return result; | 4086 return result; |
| 4101 } | 4087 } |
| 4102 | 4088 |
| (...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4679 catch_param->var = ExpectIdentifier("identifier expected"); | 4665 catch_param->var = ExpectIdentifier("identifier expected"); |
| 4680 } | 4666 } |
| 4681 | 4667 |
| 4682 | 4668 |
| 4683 // Populate local scope of the catch block with the catch parameters. | 4669 // Populate local scope of the catch block with the catch parameters. |
| 4684 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, | 4670 void Parser::AddCatchParamsToScope(const CatchParamDesc& exception_param, |
| 4685 const CatchParamDesc& stack_trace_param, | 4671 const CatchParamDesc& stack_trace_param, |
| 4686 LocalScope* scope) { | 4672 LocalScope* scope) { |
| 4687 ASSERT(exception_param.var != NULL); | 4673 ASSERT(exception_param.var != NULL); |
| 4688 LocalVariable* var = new LocalVariable(exception_param.token_index, | 4674 LocalVariable* var = new LocalVariable(exception_param.token_index, |
| 4689 *(exception_param.var), | 4675 *exception_param.var, |
| 4690 *(exception_param.type)); | 4676 *exception_param.type); |
| 4691 if (exception_param.is_final) { | 4677 if (exception_param.is_final) { |
| 4692 var->set_is_final(); | 4678 var->set_is_final(); |
| 4693 } | 4679 } |
| 4694 bool added_to_scope = scope->AddVariable(var); | 4680 bool added_to_scope = scope->AddVariable(var); |
| 4695 ASSERT(added_to_scope); | 4681 ASSERT(added_to_scope); |
| 4696 if (stack_trace_param.var != NULL) { | 4682 if (stack_trace_param.var != NULL) { |
| 4697 var = new LocalVariable(token_index_, | 4683 var = new LocalVariable(token_index_, |
| 4698 *(stack_trace_param.var), | 4684 *stack_trace_param.var, |
| 4699 *(stack_trace_param.type)); | 4685 *stack_trace_param.type); |
| 4700 if (stack_trace_param.is_final) { | 4686 if (stack_trace_param.is_final) { |
| 4701 var->set_is_final(); | 4687 var->set_is_final(); |
| 4702 } | 4688 } |
| 4703 added_to_scope = scope->AddVariable(var); | 4689 added_to_scope = scope->AddVariable(var); |
| 4704 if (!added_to_scope) { | 4690 if (!added_to_scope) { |
| 4705 ErrorMsg(stack_trace_param.token_index, | 4691 ErrorMsg(stack_trace_param.token_index, |
| 4706 "name '%s' already exists in scope", | 4692 "name '%s' already exists in scope", |
| 4707 stack_trace_param.var->ToCString()); | 4693 stack_trace_param.var->ToCString()); |
| 4708 } | 4694 } |
| 4709 } | 4695 } |
| (...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5061 } | 5047 } |
| 5062 if (target->FunctionLevel() != current_block_->scope->function_level()) { | 5048 if (target->FunctionLevel() != current_block_->scope->function_level()) { |
| 5063 ErrorMsg(jump_pos, "'%s' target must be in same function context", | 5049 ErrorMsg(jump_pos, "'%s' target must be in same function context", |
| 5064 Token::Str(jump_kind)); | 5050 Token::Str(jump_kind)); |
| 5065 } | 5051 } |
| 5066 return new JumpNode(jump_pos, jump_kind, target); | 5052 return new JumpNode(jump_pos, jump_kind, target); |
| 5067 } | 5053 } |
| 5068 | 5054 |
| 5069 | 5055 |
| 5070 bool Parser::IsDefinedInLexicalScope(const String& ident) { | 5056 bool Parser::IsDefinedInLexicalScope(const String& ident) { |
| 5071 AstNode* var_or_field = NULL; | 5057 if (ResolveIdentInLocalScope(token_index_, ident, NULL)) { |
| 5072 if (ResolveIdentInLocalScope(token_index_, ident, &var_or_field)) { | |
| 5073 return true; | 5058 return true; |
| 5074 } | 5059 } |
| 5075 Object& obj = Object::Handle(); | 5060 Object& obj = Object::Handle(); |
| 5076 obj = library_.LookupObject(ident); | 5061 obj = library_.LookupObject(ident); |
| 5077 return !obj.IsNull(); | 5062 return !obj.IsNull(); |
| 5078 } | 5063 } |
| 5079 | 5064 |
| 5080 | 5065 |
| 5081 AstNode* Parser::ParseStatement() { | 5066 AstNode* Parser::ParseStatement() { |
| 5082 TRACE_PARSER("ParseStatement"); | 5067 TRACE_PARSER("ParseStatement"); |
| (...skipping 1139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6222 | 6207 |
| 6223 | 6208 |
| 6224 // Return class for type name. If the name cannot be resolved (yet), give an | 6209 // Return class for type name. If the name cannot be resolved (yet), give an |
| 6225 // error (if type_resolution == kMustResolve) or return the unresolved name. | 6210 // error (if type_resolution == kMustResolve) or return the unresolved name. |
| 6226 RawObject* Parser::LookupTypeClass(const QualIdent& type_name, | 6211 RawObject* Parser::LookupTypeClass(const QualIdent& type_name, |
| 6227 TypeResolution type_resolution) { | 6212 TypeResolution type_resolution) { |
| 6228 ASSERT(type_name.ident != NULL); | 6213 ASSERT(type_name.ident != NULL); |
| 6229 Class& type_class = Class::Handle(); | 6214 Class& type_class = Class::Handle(); |
| 6230 if (type_name.lib_prefix != NULL) { | 6215 if (type_name.lib_prefix != NULL) { |
| 6231 Library& lib = Library::Handle(type_name.lib_prefix->library()); | 6216 Library& lib = Library::Handle(type_name.lib_prefix->library()); |
| 6232 type_class ^= lib.LookupLocalClass(*(type_name.ident)); | 6217 type_class ^= lib.LookupLocalClass(*type_name.ident); |
| 6233 } else { | 6218 } else { |
| 6234 type_class ^= LookupClass(*(type_name.ident)); | 6219 type_class ^= LookupClass(*type_name.ident); |
| 6235 } | 6220 } |
| 6236 if (!type_class.IsNull()) { | 6221 if (!type_class.IsNull()) { |
| 6237 return type_class.raw(); | 6222 return type_class.raw(); |
| 6238 } | 6223 } |
| 6239 // Type name could not be resolved (yet). | 6224 // Type name could not be resolved (yet). |
| 6240 if (type_resolution == kMustResolve) { | 6225 if (type_resolution == kMustResolve) { |
| 6241 ErrorMsg(type_name.ident_pos, "type '%s' is not loaded", | 6226 ErrorMsg(type_name.ident_pos, "type '%s' is not loaded", |
| 6242 type_name.ident->ToCString()); | 6227 type_name.ident->ToCString()); |
| 6243 return Object::null_class(); | 6228 return Object::null_class(); |
| 6244 } | 6229 } |
| 6245 // We have an unresolved name, create an UnresolvedClass object | 6230 // We have an unresolved name, create an UnresolvedClass object |
| 6246 // for this case. | 6231 // for this case. |
| 6247 String& qualifier = String::Handle(); | 6232 String& qualifier = String::Handle(); |
| 6248 if (type_name.qualifier != NULL) { | 6233 if (type_name.qualifier != NULL) { |
| 6249 qualifier ^= type_name.qualifier->raw(); | 6234 qualifier ^= type_name.qualifier->raw(); |
| 6250 } | 6235 } |
| 6251 return UnresolvedClass::New(type_name.ident_pos, | 6236 return UnresolvedClass::New(type_name.ident_pos, qualifier, *type_name.ident); |
| 6252 qualifier, | |
| 6253 *(type_name.ident)); | |
| 6254 } | 6237 } |
| 6255 | 6238 |
| 6256 | 6239 |
| 6257 LocalVariable* Parser::LookupLocalScope(const String& ident) { | 6240 LocalVariable* Parser::LookupLocalScope(const String& ident) { |
| 6258 if (current_block_ == NULL) { | 6241 if (current_block_ == NULL) { |
| 6259 return NULL; | 6242 return NULL; |
| 6260 } | 6243 } |
| 6261 // A found name is treated as accessed and possibly marked as captured. | 6244 // A found name is treated as accessed and possibly marked as captured. |
| 6262 const bool kTestOnly = false; | 6245 const bool kTestOnly = false; |
| 6263 return current_block_->scope->LookupVariable(ident, kTestOnly); | 6246 return current_block_->scope->LookupVariable(ident, kTestOnly); |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6430 return instance.raw(); | 6413 return instance.raw(); |
| 6431 } | 6414 } |
| 6432 | 6415 |
| 6433 | 6416 |
| 6434 // Do a lookup for the identifier in the block scope and the class scope | 6417 // Do a lookup for the identifier in the block scope and the class scope |
| 6435 // return true if the identifier is found, false otherwise. | 6418 // return true if the identifier is found, false otherwise. |
| 6436 // If node is non NULL return an AST node corresponding to the identifier. | 6419 // If node is non NULL return an AST node corresponding to the identifier. |
| 6437 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, | 6420 bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos, |
| 6438 const String &ident, | 6421 const String &ident, |
| 6439 AstNode** node) { | 6422 AstNode** node) { |
| 6440 ASSERT(node != NULL); | |
| 6441 TRACE_PARSER("ResolveIdentInLocalScope"); | 6423 TRACE_PARSER("ResolveIdentInLocalScope"); |
| 6442 Isolate* isolate = Isolate::Current(); | 6424 Isolate* isolate = Isolate::Current(); |
| 6443 // First try to find the identifier in the nested local scopes. | 6425 // First try to find the identifier in the nested local scopes. |
| 6444 LocalVariable* local = LookupLocalScope(ident); | 6426 LocalVariable* local = LookupLocalScope(ident); |
| 6445 if (local != NULL) { | 6427 if (local != NULL) { |
| 6446 *node = new LoadLocalNode(ident_pos, *local); | 6428 if (node != NULL) { |
| 6429 *node = new LoadLocalNode(ident_pos, *local); |
| 6430 } |
| 6447 return true; | 6431 return true; |
| 6448 } | 6432 } |
| 6449 | 6433 |
| 6450 // Try to find the identifier in the class scope. | 6434 // Try to find the identifier in the class scope. |
| 6451 Class& cls = Class::Handle(isolate, current_class().raw()); | 6435 Class& cls = Class::Handle(isolate, current_class().raw()); |
| 6452 Function& func = Function::Handle(isolate, Function::null()); | 6436 Function& func = Function::Handle(isolate, Function::null()); |
| 6453 Field& field = Field::Handle(isolate, Field::null()); | 6437 Field& field = Field::Handle(isolate, Field::null()); |
| 6454 while (!cls.IsNull()) { | 6438 while (!cls.IsNull()) { |
| 6455 // First check if a field exists. | 6439 // First check if a field exists. |
| 6456 field = cls.LookupField(ident); | 6440 field = cls.LookupField(ident); |
| 6457 if (!field.IsNull()) { | 6441 if (!field.IsNull()) { |
| 6458 if (!field.is_static()) { | 6442 if (node != NULL) { |
| 6459 CheckInstanceFieldAccess(ident_pos, ident); | 6443 if (!field.is_static()) { |
| 6460 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 6444 CheckInstanceFieldAccess(ident_pos, ident); |
| 6461 } else { | 6445 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 6462 *node = GenerateStaticFieldLookup(field, ident_pos); | 6446 } else { |
| 6447 *node = GenerateStaticFieldLookup(field, ident_pos); |
| 6448 } |
| 6463 } | 6449 } |
| 6464 return true; | 6450 return true; |
| 6465 } | 6451 } |
| 6466 | 6452 |
| 6467 // Check if an instance/static function exists. | 6453 // Check if an instance/static function exists. |
| 6468 func = cls.LookupFunction(ident); | 6454 func = cls.LookupFunction(ident); |
| 6469 if (!func.IsNull() && | 6455 if (!func.IsNull() && |
| 6470 (func.IsDynamicFunction() || func.IsStaticFunction())) { | 6456 (func.IsDynamicFunction() || func.IsStaticFunction())) { |
| 6471 *node = new PrimaryNode(ident_pos, | 6457 if (node != NULL) { |
| 6472 Function::ZoneHandle(isolate, func.raw())); | 6458 *node = new PrimaryNode(ident_pos, |
| 6459 Function::ZoneHandle(isolate, func.raw())); |
| 6460 } |
| 6473 return true; | 6461 return true; |
| 6474 } | 6462 } |
| 6475 | 6463 |
| 6476 // Now check if a getter/setter method exists for it in which case | 6464 // Now check if a getter/setter method exists for it in which case |
| 6477 // it is still a field. | 6465 // it is still a field. |
| 6478 func = cls.LookupGetterFunction(ident); | 6466 func = cls.LookupGetterFunction(ident); |
| 6479 if (!func.IsNull()) { | 6467 if (!func.IsNull()) { |
| 6480 if (func.IsDynamicFunction()) { | 6468 if (func.IsDynamicFunction()) { |
| 6481 CheckInstanceFieldAccess(ident_pos, ident); | 6469 if (node != NULL) { |
| 6482 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 6470 CheckInstanceFieldAccess(ident_pos, ident); |
| 6483 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 6471 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 6472 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 6473 } |
| 6484 return true; | 6474 return true; |
| 6485 } else if (func.IsStaticFunction()) { | 6475 } else if (func.IsStaticFunction()) { |
| 6486 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 6476 if (node != NULL) { |
| 6487 *node = new StaticGetterNode(ident_pos, | 6477 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 6488 Class::ZoneHandle(isolate, cls.raw()), | 6478 *node = new StaticGetterNode(ident_pos, |
| 6489 ident); | 6479 Class::ZoneHandle(isolate, cls.raw()), |
| 6480 ident); |
| 6481 } |
| 6490 return true; | 6482 return true; |
| 6491 } | 6483 } |
| 6492 } | 6484 } |
| 6493 func = cls.LookupSetterFunction(ident); | 6485 func = cls.LookupSetterFunction(ident); |
| 6494 if (!func.IsNull()) { | 6486 if (!func.IsNull()) { |
| 6495 if (func.IsDynamicFunction()) { | 6487 if (func.IsDynamicFunction()) { |
| 6496 // We create a getter node even though a getter doesn't exist as | 6488 if (node != NULL) { |
| 6497 // it could be followed by an assignment which will convert it to | 6489 // We create a getter node even though a getter doesn't exist as |
| 6498 // a setter node. If there is no assignment we will get an error | 6490 // it could be followed by an assignment which will convert it to |
| 6499 // when we try to invoke the getter. | 6491 // a setter node. If there is no assignment we will get an error |
| 6500 CheckInstanceFieldAccess(ident_pos, ident); | 6492 // when we try to invoke the getter. |
| 6501 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); | 6493 CheckInstanceFieldAccess(ident_pos, ident); |
| 6502 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); | 6494 ASSERT(AbstractType::Handle(func.result_type()).IsResolved()); |
| 6495 *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident); |
| 6496 } |
| 6503 return true; | 6497 return true; |
| 6504 } else if (func.IsStaticFunction()) { | 6498 } else if (func.IsStaticFunction()) { |
| 6505 // We create a getter node even though a getter doesn't exist as | 6499 if (node != NULL) { |
| 6506 // it could be followed by an assignment which will convert it to | 6500 // We create a getter node even though a getter doesn't exist as |
| 6507 // a setter node. If there is no assignment we will get an error | 6501 // it could be followed by an assignment which will convert it to |
| 6508 // when we try to invoke the getter. | 6502 // a setter node. If there is no assignment we will get an error |
| 6509 *node = new StaticGetterNode(ident_pos, | 6503 // when we try to invoke the getter. |
| 6510 Class::ZoneHandle(isolate, cls.raw()), | 6504 *node = new StaticGetterNode(ident_pos, |
| 6511 ident); | 6505 Class::ZoneHandle(isolate, cls.raw()), |
| 6506 ident); |
| 6507 } |
| 6512 return true; | 6508 return true; |
| 6513 } | 6509 } |
| 6514 } | 6510 } |
| 6515 | 6511 |
| 6516 cls = cls.SuperClass(); | 6512 cls = cls.SuperClass(); |
| 6517 } | 6513 } |
| 6518 *node = NULL; | 6514 if (node != NULL) { |
| 6515 *node = NULL; |
| 6516 } |
| 6519 return false; // Not an unqualified identifier. | 6517 return false; // Not an unqualified identifier. |
| 6520 } | 6518 } |
| 6521 | 6519 |
| 6522 | 6520 |
| 6523 // Do a lookup for the identifier in the library scope of the specified | 6521 // Do a lookup for the identifier in the library scope of the specified |
| 6524 // library. If resolve_locally is true the lookup does not consider | 6522 // library. If resolve_locally is true the lookup does not consider |
| 6525 // the libraries imported by it for the lookup. | 6523 // the libraries imported by it for the lookup. |
| 6526 AstNode* Parser::ResolveIdentInLibraryScope(const Library& lib, | 6524 AstNode* Parser::ResolveIdentInLibraryScope(const Library& lib, |
| 6527 const QualIdent& qual_ident, | 6525 const QualIdent& qual_ident, |
| 6528 bool resolve_locally) { | 6526 bool resolve_locally) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6651 RawAbstractType* Parser::ParseType(TypeResolution type_resolution) { | 6649 RawAbstractType* Parser::ParseType(TypeResolution type_resolution) { |
| 6652 if (CurrentToken() != Token::kIDENT) { | 6650 if (CurrentToken() != Token::kIDENT) { |
| 6653 ErrorMsg("type name expected"); | 6651 ErrorMsg("type name expected"); |
| 6654 } | 6652 } |
| 6655 QualIdent type_name; | 6653 QualIdent type_name; |
| 6656 const intptr_t type_pos = token_index_; | 6654 const intptr_t type_pos = token_index_; |
| 6657 if (type_resolution == kIgnore) { | 6655 if (type_resolution == kIgnore) { |
| 6658 SkipQualIdent(); | 6656 SkipQualIdent(); |
| 6659 } else { | 6657 } else { |
| 6660 ParseQualIdent(&type_name); | 6658 ParseQualIdent(&type_name); |
| 6661 if (type_name.is_local_scope_ident) { | 6659 if (!is_top_level_ && (type_name.qualifier == NULL) && |
| 6660 ResolveIdentInLocalScope(type_pos, *type_name.ident, NULL)) { |
| 6662 ErrorMsg(type_pos, "using '%s' in this context is invalid", | 6661 ErrorMsg(type_pos, "using '%s' in this context is invalid", |
| 6663 type_name.ident->ToCString()); | 6662 type_name.ident->ToCString()); |
| 6664 } | 6663 } |
| 6665 } | 6664 } |
| 6666 Class& scope_class = Class::Handle(); | 6665 Class& scope_class = Class::Handle(); |
| 6667 Object& type_class = Object::Handle(); | 6666 Object& type_class = Object::Handle(); |
| 6668 if (type_resolution == kIgnore) { | 6667 if (type_resolution == kIgnore) { |
| 6669 // Leave type_class as null. | 6668 // Leave type_class as null. |
| 6670 } else if (type_resolution == kDoNotResolve) { | 6669 } else if (type_resolution == kDoNotResolve) { |
| 6671 String& qualifier = String::Handle(); | 6670 String& qualifier = String::Handle(); |
| 6672 if (type_name.qualifier != NULL) { | 6671 if (type_name.qualifier != NULL) { |
| 6673 qualifier ^= type_name.qualifier->raw(); | 6672 qualifier ^= type_name.qualifier->raw(); |
| 6674 } | 6673 } |
| 6675 type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident)); | 6674 type_class = UnresolvedClass::New(type_pos, qualifier, *type_name.ident); |
| 6676 } else { | 6675 } else { |
| 6677 scope_class = TypeParametersScopeClass(); | 6676 scope_class = TypeParametersScopeClass(); |
| 6678 if (!scope_class.IsNull()) { | 6677 if (!scope_class.IsNull()) { |
| 6679 TypeParameter& type_parameter = TypeParameter::Handle(); | 6678 TypeParameter& type_parameter = TypeParameter::Handle(); |
| 6680 // Check if qualifier is a type parameter in scope. | 6679 // Check if qualifier is a type parameter in scope. |
| 6681 if (type_name.qualifier != NULL) { | 6680 if (type_name.qualifier != NULL) { |
| 6682 type_parameter = scope_class.LookupTypeParameter(*type_name.qualifier); | 6681 type_parameter = scope_class.LookupTypeParameter(*type_name.qualifier); |
| 6683 if (!type_parameter.IsNull()) { | 6682 if (!type_parameter.IsNull()) { |
| 6684 ErrorMsg(type_pos, "type Parameter '%s' cannot be used as qualifier", | 6683 ErrorMsg(type_pos, "type Parameter '%s' cannot be used as qualifier", |
| 6685 type_name.qualifier->ToCString()); | 6684 type_name.qualifier->ToCString()); |
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7132 | 7131 |
| 7133 // The grammar allows for an optional ('.' identifier)?, which is a named | 7132 // The grammar allows for an optional ('.' identifier)?, which is a named |
| 7134 // constructor. For that reason, we cannot unconditionally call | 7133 // constructor. For that reason, we cannot unconditionally call |
| 7135 // ParseType(kMustResolve) after we see an identifier, because the named | 7134 // ParseType(kMustResolve) after we see an identifier, because the named |
| 7136 // constructor would be misinterpreted as a qualified type name. | 7135 // constructor would be misinterpreted as a qualified type name. |
| 7137 // TODO(regis): Revisit once we correctly support qualified identifiers. | 7136 // TODO(regis): Revisit once we correctly support qualified identifiers. |
| 7138 // For now, we inline a customized version of ParseType(kMustResolve). | 7137 // For now, we inline a customized version of ParseType(kMustResolve). |
| 7139 const intptr_t type_pos = token_index_; | 7138 const intptr_t type_pos = token_index_; |
| 7140 QualIdent type_name; | 7139 QualIdent type_name; |
| 7141 ParseQualIdent(&type_name); | 7140 ParseQualIdent(&type_name); |
| 7142 if (type_name.is_local_scope_ident) { | 7141 ASSERT(!is_top_level_); |
| 7142 if ((type_name.qualifier == NULL) && |
| 7143 ResolveIdentInLocalScope(type_pos, *type_name.ident, NULL)) { |
| 7143 ErrorMsg(type_pos, "using '%s' in this context is invalid", | 7144 ErrorMsg(type_pos, "using '%s' in this context is invalid", |
| 7144 type_name.ident->ToCString()); | 7145 type_name.ident->ToCString()); |
| 7145 } | 7146 } |
| 7146 String* named_constructor = NULL; | 7147 String* named_constructor = NULL; |
| 7147 if (CurrentToken() == Token::kPERIOD) { | 7148 if (CurrentToken() == Token::kPERIOD) { |
| 7148 ConsumeToken(); | 7149 ConsumeToken(); |
| 7149 named_constructor = ExpectIdentifier("identifier expected after '.'"); | 7150 named_constructor = ExpectIdentifier("identifier expected after '.'"); |
| 7150 } | 7151 } |
| 7151 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); | 7152 const Class& scope_class = Class::Handle(TypeParametersScopeClass()); |
| 7152 if (!scope_class.IsNull()) { | 7153 if (!scope_class.IsNull()) { |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7373 interpolate_arg->Add(values); | 7374 interpolate_arg->Add(values); |
| 7374 primary = MakeStaticCall(kStringClassName, | 7375 primary = MakeStaticCall(kStringClassName, |
| 7375 kInterpolateName, | 7376 kInterpolateName, |
| 7376 interpolate_arg); | 7377 interpolate_arg); |
| 7377 return primary; | 7378 return primary; |
| 7378 } | 7379 } |
| 7379 | 7380 |
| 7380 | 7381 |
| 7381 AstNode* Parser::ParsePrimary() { | 7382 AstNode* Parser::ParsePrimary() { |
| 7382 TRACE_PARSER("ParsePrimary"); | 7383 TRACE_PARSER("ParsePrimary"); |
| 7384 ASSERT(!is_top_level_); |
| 7383 AstNode* primary = NULL; | 7385 AstNode* primary = NULL; |
| 7384 if (IsFunctionLiteral()) { | 7386 if (IsFunctionLiteral()) { |
| 7385 // The name of a literal function is visible from inside the function, but | 7387 // The name of a literal function is visible from inside the function, but |
| 7386 // must not collide with names in the scope declaring the literal. | 7388 // must not collide with names in the scope declaring the literal. |
| 7387 OpenBlock(); | 7389 OpenBlock(); |
| 7388 primary = ParseFunctionStatement(true); | 7390 primary = ParseFunctionStatement(true); |
| 7389 CloseBlock(); | 7391 CloseBlock(); |
| 7390 } else if (IsIdentifier()) { | 7392 } else if (IsIdentifier()) { |
| 7391 QualIdent qual_ident; | 7393 QualIdent qual_ident; |
| 7392 ParseQualIdent(&qual_ident); | 7394 ParseQualIdent(&qual_ident); |
| 7393 if (qual_ident.is_local_scope_ident) { | 7395 if (qual_ident.qualifier == NULL) { |
| 7394 ResolveIdentInLocalScope(qual_ident.ident_pos, | 7396 if (!ResolveIdentInLocalScope(qual_ident.ident_pos, |
| 7395 *qual_ident.ident, | 7397 *qual_ident.ident, |
| 7396 &primary); | 7398 &primary)) { |
| 7397 } else { | 7399 // This is a non-local unqualified identifier so resolve the identifier |
| 7398 if (qual_ident.qualifier == NULL) { | |
| 7399 // This is an unqualified identifier so resolve the identifier | |
| 7400 // locally in the main app library and all libraries imported by it. | 7400 // locally in the main app library and all libraries imported by it. |
| 7401 primary = ResolveIdentInLibraryScope(library_, | 7401 primary = ResolveIdentInLibraryScope(library_, |
| 7402 qual_ident, | 7402 qual_ident, |
| 7403 kResolveIncludingImports); | 7403 kResolveIncludingImports); |
| 7404 } else { | |
| 7405 // This is a qualified identifier with a library prefix so resolve | |
| 7406 // the identifier locally in that library (we do not include the | |
| 7407 // libraries imported by that library). | |
| 7408 const Library& lib = Library::Handle(qual_ident.lib_prefix->library()); | |
| 7409 primary = ResolveIdentInLibraryScope(lib, | |
| 7410 qual_ident, | |
| 7411 kResolveLocally); | |
| 7412 } | 7404 } |
| 7405 } else { |
| 7406 // This is a qualified identifier with a library prefix so resolve |
| 7407 // the identifier locally in that library (we do not include the |
| 7408 // libraries imported by that library). |
| 7409 const Library& lib = Library::Handle(qual_ident.lib_prefix->library()); |
| 7410 primary = ResolveIdentInLibraryScope(lib, |
| 7411 qual_ident, |
| 7412 kResolveLocally); |
| 7413 } | 7413 } |
| 7414 ASSERT(primary != NULL); | 7414 ASSERT(primary != NULL); |
| 7415 } else if (CurrentToken() == Token::kTHIS) { | 7415 } else if (CurrentToken() == Token::kTHIS) { |
| 7416 const String& this_name = String::Handle(String::NewSymbol(kThisName)); | 7416 const String& this_name = String::Handle(String::NewSymbol(kThisName)); |
| 7417 LocalVariable* local = LookupLocalScope(this_name); | 7417 LocalVariable* local = LookupLocalScope(this_name); |
| 7418 if (local == NULL) { | 7418 if (local == NULL) { |
| 7419 ErrorMsg("unexpected use of 'this' in primary expression"); | 7419 ErrorMsg("unexpected use of 'this' in primary expression"); |
| 7420 } | 7420 } |
| 7421 primary = new LoadLocalNode(token_index_, *local); | 7421 primary = new LoadLocalNode(token_index_, *local); |
| 7422 ConsumeToken(); | 7422 ConsumeToken(); |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7770 void Parser::SkipQualIdent() { | 7770 void Parser::SkipQualIdent() { |
| 7771 ASSERT(IsIdentifier()); | 7771 ASSERT(IsIdentifier()); |
| 7772 ConsumeToken(); | 7772 ConsumeToken(); |
| 7773 if (CurrentToken() == Token::kPERIOD) { | 7773 if (CurrentToken() == Token::kPERIOD) { |
| 7774 ConsumeToken(); // Consume the kPERIOD token. | 7774 ConsumeToken(); // Consume the kPERIOD token. |
| 7775 ExpectIdentifier("identifier expected after '.'"); | 7775 ExpectIdentifier("identifier expected after '.'"); |
| 7776 } | 7776 } |
| 7777 } | 7777 } |
| 7778 | 7778 |
| 7779 } // namespace dart | 7779 } // namespace dart |
| OLD | NEW |