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

Side by Side Diff: runtime/vm/parser.cc

Issue 9271023: Optimize parsing of qualified identifiers. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: '' Created 8 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698