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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/parser.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/parser.cc
===================================================================
--- runtime/vm/parser.cc (revision 3508)
+++ runtime/vm/parser.cc (working copy)
@@ -269,13 +269,11 @@
Clear();
}
void Clear() {
- is_local_scope_ident = false;
lib_prefix = NULL;
qualifier = NULL;
ident_pos = 0;
ident = NULL;
}
- bool is_local_scope_ident;
LibraryPrefix* lib_prefix;
String* qualifier;
intptr_t ident_pos;
@@ -1909,26 +1907,25 @@
void Parser::ParseQualIdent(QualIdent* qual_ident) {
ASSERT(IsIdentifier());
if (!is_top_level_) {
- AstNode* var_or_field = NULL;
- bool is_local_ident = ResolveIdentInLocalScope(token_index_,
- *CurrentLiteral(),
- &var_or_field);
qual_ident->ident_pos = token_index_;
qual_ident->ident = CurrentLiteral();
qual_ident->lib_prefix = NULL;
qual_ident->qualifier = NULL;
- qual_ident->is_local_scope_ident = is_local_ident;
ConsumeToken();
- if (!is_local_ident && (CurrentToken() == Token::kPERIOD)) {
- LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle();
- lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident));
- if (!lib_prefix.IsNull()) {
- // We have a library prefix qualified identifier.
- ConsumeToken(); // Consume the kPERIOD token.
- qual_ident->lib_prefix = &lib_prefix;
- qual_ident->qualifier = qual_ident->ident;
- qual_ident->ident_pos = token_index_;
- qual_ident->ident = ExpectIdentifier("identifier expected after '.'");
+ if (CurrentToken() == Token::kPERIOD) {
+ if (!ResolveIdentInLocalScope(qual_ident->ident_pos,
+ *(qual_ident->ident),
+ NULL)) {
+ LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle();
+ lib_prefix = current_class().LookupLibraryPrefix(*(qual_ident->ident));
+ if (!lib_prefix.IsNull()) {
+ // We have a library prefix qualified identifier.
+ ConsumeToken(); // Consume the kPERIOD token.
+ qual_ident->lib_prefix = &lib_prefix;
+ qual_ident->qualifier = qual_ident->ident;
+ qual_ident->ident_pos = token_index_;
+ qual_ident->ident = ExpectIdentifier("identifier expected after '.'");
+ }
}
}
} else {
@@ -1936,7 +1933,6 @@
qual_ident->ident = CurrentLiteral();
qual_ident->lib_prefix = NULL;
qual_ident->qualifier = NULL;
- qual_ident->is_local_scope_ident = false;
ConsumeToken();
if (CurrentToken() == Token::kPERIOD) {
ConsumeToken(); // Consume the kPERIOD token.
@@ -2356,7 +2352,7 @@
const UnresolvedClass& unresolved_factory_class =
UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos,
qualifier,
- *(member.name)));
+ *member.name));
const Class& signature_class = Class::Handle(
Class::New(String::Handle(String::NewSymbol(":factory_signature")),
script_));
@@ -2643,7 +2639,7 @@
bool is_alias_name = false;
if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
ConsumeToken();
- if (IsTypeParameter() && (CurrentToken() == Token::kLPAREN)) {
+ if (TryParseTypeParameter() && (CurrentToken() == Token::kLPAREN)) {
is_alias_name = true;
}
}
@@ -2796,17 +2792,12 @@
const intptr_t factory_pos = token_index_;
QualIdent factory_name;
ParseQualIdent(&factory_name);
- if (factory_name.is_local_scope_ident) {
- ErrorMsg(factory_pos,
- "using '%s' in this context is invalid",
- factory_name.ident->ToCString());
- }
String& qualifier = String::Handle();
if (factory_name.qualifier != NULL) {
qualifier ^= factory_name.qualifier->raw();
}
const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle(
- UnresolvedClass::New(factory_pos, qualifier, *(factory_name.ident)));
+ UnresolvedClass::New(factory_pos, qualifier, *factory_name.ident));
const Class& factory_class = Class::Handle(
Class::New(String::Handle(String::NewSymbol(":factory_signature")),
script_));
@@ -3916,7 +3907,7 @@
// Returns true if the current and next tokens can be parsed as type
// parameters. Current token position is not saved and restored.
-bool Parser::IsTypeParameter() {
+bool Parser::TryParseTypeParameter() {
if (CurrentToken() == Token::kLT) {
// We are possibly looking at type parameters. Find closing ">".
int nesting_level = 0;
@@ -3956,18 +3947,13 @@
// Returns true if the next tokens can be parsed as a type with optional
// type parameters. Current token position is not restored.
-bool Parser::IsOptionalType() {
+bool Parser::TryParseOptionalType() {
if (CurrentToken() == Token::kIDENT) {
QualIdent type_name;
ParseQualIdent(&type_name);
- // Check if the type_name has been defined as a variable in a local scope,
- // hiding the type.
- if (type_name.is_local_scope_ident) {
+ if ((CurrentToken() == Token::kLT) && !TryParseTypeParameter()) {
return false;
}
- if (CurrentToken() == Token::kLT && !IsTypeParameter()) {
- return false;
- }
}
return true;
}
@@ -3976,12 +3962,12 @@
// Returns true if the next tokens can be parsed as a type with optional
// type parameters, or keyword "void".
// Current token position is not restored.
-bool Parser::IsReturnType() {
+bool Parser::TryParseReturnType() {
if (CurrentToken() == Token::kVOID) {
ConsumeToken();
return true;
} else if (CurrentToken() == Token::kIDENT) {
- return IsOptionalType();
+ return TryParseOptionalType();
}
return false;
}
@@ -4002,7 +3988,7 @@
}
const intptr_t saved_pos = token_index_;
bool is_var_decl = false;
- if (IsOptionalType()) {
+ if (TryParseOptionalType()) {
if (IsIdentifier()) {
ConsumeToken();
if ((CurrentToken() == Token::kSEMICOLON) ||
@@ -4037,7 +4023,7 @@
return true;
}
const intptr_t saved_pos = token_index_;
- if (IsReturnType()) {
+ if (TryParseReturnType()) {
if ((CurrentToken() == Token::kGET) || (CurrentToken() == Token::kSET)) {
if (Token::IsIdentifier(LookaheadToken(1))) { // Accessor name.
SetPosition(saved_pos);
@@ -4058,7 +4044,7 @@
bool is_function_literal = false;
if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
ConsumeToken(); // Consume function identifier.
- } else if (IsReturnType()) {
+ } else if (TryParseReturnType()) {
if (!IsIdentifier()) {
SetPosition(saved_pos);
return false;
@@ -4089,7 +4075,7 @@
if (IsIdentifier()) {
if (LookaheadToken(1) == Token::kIN) {
result = true;
- } else if (IsOptionalType()) {
+ } else if (TryParseOptionalType()) {
if (IsIdentifier()) {
ConsumeToken();
}
@@ -4686,8 +4672,8 @@
LocalScope* scope) {
ASSERT(exception_param.var != NULL);
LocalVariable* var = new LocalVariable(exception_param.token_index,
- *(exception_param.var),
- *(exception_param.type));
+ *exception_param.var,
+ *exception_param.type);
if (exception_param.is_final) {
var->set_is_final();
}
@@ -4695,8 +4681,8 @@
ASSERT(added_to_scope);
if (stack_trace_param.var != NULL) {
var = new LocalVariable(token_index_,
- *(stack_trace_param.var),
- *(stack_trace_param.type));
+ *stack_trace_param.var,
+ *stack_trace_param.type);
if (stack_trace_param.is_final) {
var->set_is_final();
}
@@ -5068,8 +5054,7 @@
bool Parser::IsDefinedInLexicalScope(const String& ident) {
- AstNode* var_or_field = NULL;
- if (ResolveIdentInLocalScope(token_index_, ident, &var_or_field)) {
+ if (ResolveIdentInLocalScope(token_index_, ident, NULL)) {
return true;
}
Object& obj = Object::Handle();
@@ -6229,9 +6214,9 @@
Class& type_class = Class::Handle();
if (type_name.lib_prefix != NULL) {
Library& lib = Library::Handle(type_name.lib_prefix->library());
- type_class ^= lib.LookupLocalClass(*(type_name.ident));
+ type_class ^= lib.LookupLocalClass(*type_name.ident);
} else {
- type_class ^= LookupClass(*(type_name.ident));
+ type_class ^= LookupClass(*type_name.ident);
}
if (!type_class.IsNull()) {
return type_class.raw();
@@ -6248,9 +6233,7 @@
if (type_name.qualifier != NULL) {
qualifier ^= type_name.qualifier->raw();
}
- return UnresolvedClass::New(type_name.ident_pos,
- qualifier,
- *(type_name.ident));
+ return UnresolvedClass::New(type_name.ident_pos, qualifier, *type_name.ident);
}
@@ -6437,13 +6420,14 @@
bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
const String &ident,
AstNode** node) {
- ASSERT(node != NULL);
TRACE_PARSER("ResolveIdentInLocalScope");
Isolate* isolate = Isolate::Current();
// First try to find the identifier in the nested local scopes.
LocalVariable* local = LookupLocalScope(ident);
if (local != NULL) {
- *node = new LoadLocalNode(ident_pos, *local);
+ if (node != NULL) {
+ *node = new LoadLocalNode(ident_pos, *local);
+ }
return true;
}
@@ -6455,11 +6439,13 @@
// First check if a field exists.
field = cls.LookupField(ident);
if (!field.IsNull()) {
- if (!field.is_static()) {
- CheckInstanceFieldAccess(ident_pos, ident);
- *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
- } else {
- *node = GenerateStaticFieldLookup(field, ident_pos);
+ if (node != NULL) {
+ if (!field.is_static()) {
+ CheckInstanceFieldAccess(ident_pos, ident);
+ *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
+ } else {
+ *node = GenerateStaticFieldLookup(field, ident_pos);
+ }
}
return true;
}
@@ -6468,8 +6454,10 @@
func = cls.LookupFunction(ident);
if (!func.IsNull() &&
(func.IsDynamicFunction() || func.IsStaticFunction())) {
- *node = new PrimaryNode(ident_pos,
- Function::ZoneHandle(isolate, func.raw()));
+ if (node != NULL) {
+ *node = new PrimaryNode(ident_pos,
+ Function::ZoneHandle(isolate, func.raw()));
+ }
return true;
}
@@ -6478,44 +6466,54 @@
func = cls.LookupGetterFunction(ident);
if (!func.IsNull()) {
if (func.IsDynamicFunction()) {
- CheckInstanceFieldAccess(ident_pos, ident);
- ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
- *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
+ if (node != NULL) {
+ CheckInstanceFieldAccess(ident_pos, ident);
+ ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
+ *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
+ }
return true;
} else if (func.IsStaticFunction()) {
- ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
- *node = new StaticGetterNode(ident_pos,
- Class::ZoneHandle(isolate, cls.raw()),
- ident);
+ if (node != NULL) {
+ ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
+ *node = new StaticGetterNode(ident_pos,
+ Class::ZoneHandle(isolate, cls.raw()),
+ ident);
+ }
return true;
}
}
func = cls.LookupSetterFunction(ident);
if (!func.IsNull()) {
if (func.IsDynamicFunction()) {
- // We create a getter node even though a getter doesn't exist as
- // it could be followed by an assignment which will convert it to
- // a setter node. If there is no assignment we will get an error
- // when we try to invoke the getter.
- CheckInstanceFieldAccess(ident_pos, ident);
- ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
- *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
+ if (node != NULL) {
+ // We create a getter node even though a getter doesn't exist as
+ // it could be followed by an assignment which will convert it to
+ // a setter node. If there is no assignment we will get an error
+ // when we try to invoke the getter.
+ CheckInstanceFieldAccess(ident_pos, ident);
+ ASSERT(AbstractType::Handle(func.result_type()).IsResolved());
+ *node = CallGetter(ident_pos, LoadReceiver(ident_pos), ident);
+ }
return true;
} else if (func.IsStaticFunction()) {
- // We create a getter node even though a getter doesn't exist as
- // it could be followed by an assignment which will convert it to
- // a setter node. If there is no assignment we will get an error
- // when we try to invoke the getter.
- *node = new StaticGetterNode(ident_pos,
- Class::ZoneHandle(isolate, cls.raw()),
- ident);
+ if (node != NULL) {
+ // We create a getter node even though a getter doesn't exist as
+ // it could be followed by an assignment which will convert it to
+ // a setter node. If there is no assignment we will get an error
+ // when we try to invoke the getter.
+ *node = new StaticGetterNode(ident_pos,
+ Class::ZoneHandle(isolate, cls.raw()),
+ ident);
+ }
return true;
}
}
cls = cls.SuperClass();
}
- *node = NULL;
+ if (node != NULL) {
+ *node = NULL;
+ }
return false; // Not an unqualified identifier.
}
@@ -6658,7 +6656,8 @@
SkipQualIdent();
} else {
ParseQualIdent(&type_name);
- if (type_name.is_local_scope_ident) {
+ if (!is_top_level_ && (type_name.qualifier == NULL) &&
+ ResolveIdentInLocalScope(type_pos, *type_name.ident, NULL)) {
ErrorMsg(type_pos, "using '%s' in this context is invalid",
type_name.ident->ToCString());
}
@@ -6672,7 +6671,7 @@
if (type_name.qualifier != NULL) {
qualifier ^= type_name.qualifier->raw();
}
- type_class = UnresolvedClass::New(type_pos, qualifier, *(type_name.ident));
+ type_class = UnresolvedClass::New(type_pos, qualifier, *type_name.ident);
} else {
scope_class = TypeParametersScopeClass();
if (!scope_class.IsNull()) {
@@ -7139,7 +7138,9 @@
const intptr_t type_pos = token_index_;
QualIdent type_name;
ParseQualIdent(&type_name);
- if (type_name.is_local_scope_ident) {
+ ASSERT(!is_top_level_);
+ if ((type_name.qualifier == NULL) &&
+ ResolveIdentInLocalScope(type_pos, *type_name.ident, NULL)) {
ErrorMsg(type_pos, "using '%s' in this context is invalid",
type_name.ident->ToCString());
}
@@ -7380,6 +7381,7 @@
AstNode* Parser::ParsePrimary() {
TRACE_PARSER("ParsePrimary");
+ ASSERT(!is_top_level_);
AstNode* primary = NULL;
if (IsFunctionLiteral()) {
// The name of a literal function is visible from inside the function, but
@@ -7390,26 +7392,24 @@
} else if (IsIdentifier()) {
QualIdent qual_ident;
ParseQualIdent(&qual_ident);
- if (qual_ident.is_local_scope_ident) {
- ResolveIdentInLocalScope(qual_ident.ident_pos,
- *qual_ident.ident,
- &primary);
- } else {
- if (qual_ident.qualifier == NULL) {
- // This is an unqualified identifier so resolve the identifier
+ if (qual_ident.qualifier == NULL) {
+ if (!ResolveIdentInLocalScope(qual_ident.ident_pos,
+ *qual_ident.ident,
+ &primary)) {
+ // This is a non-local unqualified identifier so resolve the identifier
// locally in the main app library and all libraries imported by it.
primary = ResolveIdentInLibraryScope(library_,
qual_ident,
kResolveIncludingImports);
- } else {
- // This is a qualified identifier with a library prefix so resolve
- // the identifier locally in that library (we do not include the
- // libraries imported by that library).
- const Library& lib = Library::Handle(qual_ident.lib_prefix->library());
- primary = ResolveIdentInLibraryScope(lib,
- qual_ident,
- kResolveLocally);
}
+ } else {
+ // This is a qualified identifier with a library prefix so resolve
+ // the identifier locally in that library (we do not include the
+ // libraries imported by that library).
+ const Library& lib = Library::Handle(qual_ident.lib_prefix->library());
+ primary = ResolveIdentInLibraryScope(lib,
+ qual_ident,
+ kResolveLocally);
}
ASSERT(primary != NULL);
} else if (CurrentToken() == Token::kTHIS) {
« 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