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

Unified Diff: runtime/vm/parser.cc

Issue 9233039: Store resolved library prefix in unresolved class object in order not to repeat (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/object.cc ('k') | runtime/vm/raw_object.h » ('j') | 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 3699)
+++ runtime/vm/parser.cc (working copy)
@@ -270,12 +270,10 @@
}
void Clear() {
lib_prefix = NULL;
- qualifier = NULL;
ident_pos = 0;
ident = NULL;
}
LibraryPrefix* lib_prefix;
- String* qualifier;
intptr_t ident_pos;
String* ident;
};
@@ -1906,47 +1904,33 @@
void Parser::ParseQualIdent(QualIdent* qual_ident) {
ASSERT(IsIdentifier());
- if (!is_top_level_) {
- qual_ident->ident_pos = token_index_;
- qual_ident->ident = CurrentLiteral();
- qual_ident->lib_prefix = NULL;
- qual_ident->qualifier = NULL;
- ConsumeToken();
- 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, unless the prefix is
- // shadowed by a type parameter in scope.
- const Class& scope_class = Class::Handle(TypeParametersScopeClass());
- if (scope_class.IsNull() ||
- (scope_class.LookupTypeParameter(*(qual_ident->ident)) ==
- TypeParameter::null())) {
- 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 '.'");
- }
+ qual_ident->ident_pos = token_index_;
+ qual_ident->ident = CurrentLiteral();
+ qual_ident->lib_prefix = NULL;
+ ConsumeToken();
+ if (CurrentToken() == Token::kPERIOD) {
+ // An identifier cannot be resolved in a local scope when top level parsing.
+ if (is_top_level_ ||
+ !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, unless the prefix is
+ // shadowed by a type parameter in scope.
+ const Class& scope_class = Class::Handle(TypeParametersScopeClass());
+ if (scope_class.IsNull() ||
+ (scope_class.LookupTypeParameter(*(qual_ident->ident)) ==
+ TypeParameter::null())) {
+ ConsumeToken(); // Consume the kPERIOD token.
+ qual_ident->lib_prefix = &lib_prefix;
+ qual_ident->ident_pos = token_index_;
+ qual_ident->ident =
+ ExpectIdentifier("identifier expected after '.'");
}
}
}
- } else {
- qual_ident->ident_pos = token_index_;
- qual_ident->ident = CurrentLiteral();
- qual_ident->lib_prefix = NULL;
- qual_ident->qualifier = NULL;
- ConsumeToken();
- if (CurrentToken() == Token::kPERIOD) {
- ConsumeToken(); // Consume the kPERIOD token.
- qual_ident->qualifier = qual_ident->ident;
- qual_ident->ident_pos = token_index_;
- qual_ident->ident = ExpectIdentifier("identifier expected after '.'");
- }
}
}
@@ -2338,33 +2322,22 @@
// Optionally parse a (possibly named) constructor name or factory.
if (IsIdentifier() &&
(CurrentLiteral()->Equals(members->class_name()) || member.has_factory)) {
- member.name = CurrentLiteral();
- member.name_pos = this->token_index_;
- // TODO(regis): Simplify the following code by calling ParseQualIdent().
- ConsumeToken();
if (member.has_factory) {
- String& qualifier = String::Handle();
- if (CurrentToken() == Token::kPERIOD) {
- LibraryPrefix& lib_prefix = LibraryPrefix::ZoneHandle();
- lib_prefix = current_class().LookupLibraryPrefix(*member.name);
- if (!lib_prefix.IsNull()) {
- // We have a library prefix qualified identifier.
- ConsumeToken(); // Consume the kPERIOD token.
- qualifier ^= member.name->raw();
- member.name = ExpectIdentifier("identifier expected");
- }
- }
- // TODO(regis): Stop postponing resolution of the factory result type
- // until class finalization. Use ResolveTypeFromClass instead.
- // Factory result type is the same as the type name of the factory.
- const UnresolvedClass& unresolved_factory_class =
- UnresolvedClass::Handle(UnresolvedClass::New(member.name_pos,
- qualifier,
- *member.name));
+ // The factory name may be qualified.
+ QualIdent factory_name;
+ ParseQualIdent(&factory_name);
+ member.name_pos = factory_name.ident_pos;
+ member.name = factory_name.ident; // Unqualified identifier.
+ // The class of the factory result type is specified by the factory name.
+ const Object& result_type_class = Object::Handle(
+ LookupTypeClass(factory_name, kCanResolve));
// The type arguments of the result type are set during finalization.
member.type = &Type::ZoneHandle(
- Type::NewParameterizedType(unresolved_factory_class,
- TypeArguments::Handle()));
+ Type::New(result_type_class, TypeArguments::Handle()));
+ } else {
+ member.name_pos = token_index_;
+ member.name = CurrentLiteral();
+ ConsumeToken();
}
// We must be dealing with a constructor or named constructor.
member.kind = RawFunction::kConstructor;
@@ -2646,6 +2619,16 @@
TRACE_PARSER("ParseFunctionTypeAlias");
ExpectToken(Token::kTYPEDEF);
+ // Allocate an interface to hold the type parameters and their 'extends'
+ // constraints. Make it the owner of the function type descriptor.
+ const Class& alias_owner = Class::Handle(
+ Class::New(String::Handle(String::NewSymbol(":alias_owner")),
+ Script::Handle()));
+ alias_owner.set_is_interface();
+ alias_owner.set_library(library_);
+ set_current_class(alias_owner);
+
+ // Parse the result type of the function type.
AbstractType& result_type = Type::Handle(Type::DynamicType());
const intptr_t result_type_pos = token_index_;
if (CurrentToken() == Token::kVOID) {
@@ -2661,18 +2644,8 @@
const String* alias_name =
ExpectTypeIdentifier("function alias name expected");
- // Allocate an interface to hold the type parameters and their 'extends'
- // constraints. Make it the owner of the function type descriptor.
- const Class& alias_owner = Class::Handle(
- Class::New(String::Handle(String::NewSymbol(":alias_owner")),
- Script::Handle()));
- alias_owner.set_is_interface();
- set_current_class(alias_owner);
+ // Parse the type parameters of the function type.
ParseTypeParameters(alias_owner);
- if (CurrentToken() != Token::kLPAREN) {
- ErrorMsg("formal parameter list expected");
- }
-
// At this point, the type parameters have been parsed, so we can resolve the
// result type.
if (!result_type.IsNull()) {
@@ -2681,6 +2654,10 @@
kCanResolve,
&result_type);
}
+ // Parse the formal parameters of the function type.
+ if (CurrentToken() != Token::kLPAREN) {
+ ErrorMsg("formal parameter list expected");
+ }
ParamList func_params;
const bool no_explicit_default_values = false;
ParseFormalParameterList(no_explicit_default_values, &func_params);
@@ -2784,12 +2761,12 @@
const intptr_t factory_pos = token_index_;
QualIdent factory_name;
ParseQualIdent(&factory_name);
- String& qualifier = String::Handle();
- if (factory_name.qualifier != NULL) {
- qualifier ^= factory_name.qualifier->raw();
+ LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
+ if (factory_name.lib_prefix != NULL) {
+ lib_prefix = factory_name.lib_prefix->raw();
}
const UnresolvedClass& unresolved_factory_class = UnresolvedClass::Handle(
- UnresolvedClass::New(factory_pos, qualifier, *factory_name.ident));
+ UnresolvedClass::New(factory_pos, lib_prefix, *factory_name.ident));
const Class& factory_class = Class::Handle(
Class::New(String::Handle(String::NewSymbol(":factory_signature")),
script_));
@@ -3772,8 +3749,7 @@
// We temporarily use the class of the Function interface.
const Class& unknown_signature_class = Class::Handle(
Type::Handle(Type::FunctionInterface()).type_class());
- function_type = Type::New(unknown_signature_class,
- TypeArguments::Handle());
+ function_type = Type::New(unknown_signature_class, TypeArguments::Handle());
function_type.set_is_finalized(); // No real finalization needed.
// Add the function variable to the scope before parsing the function in
@@ -6140,18 +6116,18 @@
}
-// Resolve the given type and its type arguments from the given class according
-// to the given type_resolution.
+// Resolve the given type and its type arguments from the given scope class
+// according to the given type_resolution.
+// If the given scope class is null, use the current library, but do not try to
+// resolve type parameters.
// Not all involved type classes may get resolved yet, but at least the type
// parameters of the given class will get resolved, thereby relieving the class
// finalizer from resolving type parameters out of context.
void Parser::ResolveTypeFromClass(intptr_t type_pos,
- const Class& cls,
+ const Class& scope_class,
TypeResolution type_resolution,
AbstractType* type) {
- // TODO(regis): Implement kMustResolve functionality and consolidate with
- // other resolution code. For now, only support kCanResolve functionality.
- ASSERT(type_resolution == kCanResolve);
+ ASSERT((type_resolution == kCanResolve) || (type_resolution == kMustResolve));
ASSERT(type != NULL);
// Resolve class.
if (!type->HasResolvedTypeClass()) {
@@ -6159,28 +6135,46 @@
UnresolvedClass::Handle(type->unresolved_class());
const String& unresolved_class_name =
String::Handle(unresolved_class.ident());
- // First check if the type is a type parameter of the given class.
- const TypeParameter& type_parameter = TypeParameter::Handle(
- cls.LookupTypeParameter(unresolved_class_name));
- if (!type_parameter.IsNull()) {
- // A type parameter cannot be parameterized, so report an error if type
- // arguments have previously been parsed.
- if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) {
- ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized",
- type_parameter.ToCString());
+ // First resolve library prefix if any.
+ Library& lib = Library::Handle();
+ if (unresolved_class.library_prefix() == LibraryPrefix::null()) {
+ if (scope_class.IsNull()) {
+ lib = library_.raw();
+ } else {
+ lib = scope_class.library();
+ // First check if the type is a type parameter of the given scope class.
+ const TypeParameter& type_parameter = TypeParameter::Handle(
+ scope_class.LookupTypeParameter(unresolved_class_name));
+ if (!type_parameter.IsNull()) {
+ // A type parameter cannot be parameterized, so report an error if
+ // type arguments have previously been parsed.
+ if (!AbstractTypeArguments::Handle(type->arguments()).IsNull()) {
+ ErrorMsg(type_pos, "type parameter '%s' cannot be parameterized",
+ String::Handle(type_parameter.Name()).ToCString());
+ }
+ *type = type_parameter.raw();
+ return;
+ }
}
- *type = type_parameter.raw();
- return;
+ } else {
+ LibraryPrefix& lib_prefix =
+ LibraryPrefix::Handle(unresolved_class.library_prefix());
+ lib = lib_prefix.library();
}
- const Class& resolved_type_class =
- Class::Handle(LookupClass(unresolved_class_name));
- if (!resolved_type_class.IsNull()) {
- Object& type_class = Object::Handle(resolved_type_class.raw());
- ASSERT(type->IsType());
- // Replace unresolved class with resolved type class.
- Type& parameterized_type = Type::Handle();
- parameterized_type ^= type->raw();
- parameterized_type.set_type_class(type_class);
+ if (!lib.IsNull()) {
+ const Class& resolved_type_class = Class::Handle(
+ lib.LookupLocalClass(unresolved_class_name));
+ if (!resolved_type_class.IsNull()) {
+ Object& type_class = Object::Handle(resolved_type_class.raw());
+ ASSERT(type->IsType());
+ // Replace unresolved class with resolved type class.
+ Type& parameterized_type = Type::Handle();
+ parameterized_type ^= type->raw();
+ parameterized_type.set_type_class(type_class);
+ } else if (type_resolution == kMustResolve) {
+ ErrorMsg(type_pos, "type '%s' is not loaded",
+ String::Handle(type->Name()).ToCString());
+ }
}
}
// Resolve type arguments, if any.
@@ -6190,7 +6184,10 @@
const intptr_t num_arguments = arguments.Length();
for (intptr_t i = 0; i < num_arguments; i++) {
AbstractType& type_argument = AbstractType::Handle(arguments.TypeAt(i));
- ResolveTypeFromClass(type_pos, cls, type_resolution, &type_argument);
+ ResolveTypeFromClass(type_pos,
+ scope_class,
+ type_resolution,
+ &type_argument);
arguments.SetTypeAt(i, type_argument);
}
}
@@ -6219,13 +6216,14 @@
type_name.ident->ToCString());
return Object::null_class();
}
- // We have an unresolved name, create an UnresolvedClass object
- // for this case.
- String& qualifier = String::Handle();
- if (type_name.qualifier != NULL) {
- qualifier ^= type_name.qualifier->raw();
+ // We have an unresolved name, create an UnresolvedClass object for this case.
+ LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
+ if (type_name.lib_prefix != NULL) {
+ lib_prefix = type_name.lib_prefix->raw();
}
- return UnresolvedClass::New(type_name.ident_pos, qualifier, *type_name.ident);
+ return UnresolvedClass::New(type_name.ident_pos,
+ lib_prefix,
+ *type_name.ident);
}
@@ -6545,12 +6543,12 @@
Class::ZoneHandle(func.owner()),
*qual_ident.ident);
}
- if (qual_ident.qualifier != NULL) {
+ if (qual_ident.lib_prefix != NULL) {
// This is an unresolved prefixed primary identifier, need to report
// an error.
ErrorMsg(qual_ident.ident_pos, "identifier '%s.%s' cannot be resolved",
- (qual_ident.qualifier)->ToCString(),
- (qual_ident.ident)->ToCString());
+ String::Handle(qual_ident.lib_prefix->name()).ToCString(),
+ qual_ident.ident->ToCString());
}
// Lexically unresolved primary identifiers are referenced by their name.
return new PrimaryNode(qual_ident.ident_pos, *qual_ident.ident);
@@ -6572,7 +6570,6 @@
// Not found in the local scope, so try finding the variable in the
// library scope (current library and all libraries imported by it).
QualIdent qual_ident;
- qual_ident.qualifier = NULL;
qual_ident.lib_prefix = NULL;
qual_ident.ident_pos = ident_pos;
qual_ident.ident = &(String::ZoneHandle(ident.raw()));
@@ -6621,7 +6618,9 @@
SkipQualIdent();
} else {
ParseQualIdent(&type_name);
- if (!is_top_level_ && (type_name.qualifier == NULL) &&
+ // An identifier cannot be resolved in a local scope when top level parsing.
+ if (!is_top_level_ &&
+ (type_name.lib_prefix == NULL) &&
ResolveIdentInLocalScope(type_pos, *type_name.ident, NULL)) {
ErrorMsg(type_pos, "using '%s' in this context is invalid",
type_name.ident->ToCString());
@@ -6632,29 +6631,18 @@
if (type_resolution == kIgnore) {
// Leave type_class as null.
} else if (type_resolution == kDoNotResolve) {
- String& qualifier = String::Handle();
- if (type_name.qualifier != NULL) {
- qualifier ^= type_name.qualifier->raw();
+ LibraryPrefix& lib_prefix = LibraryPrefix::Handle();
+ if (type_name.lib_prefix != NULL) {
+ lib_prefix = type_name.lib_prefix->raw();
}
- type_class = UnresolvedClass::New(type_pos, qualifier, *type_name.ident);
+ type_class = UnresolvedClass::New(type_pos, lib_prefix, *type_name.ident);
} else {
+ // TODO(regis): Use ResolveTypeFromClass().
ASSERT((type_resolution == kCanResolve) ||
(type_resolution == kMustResolve));
scope_class = TypeParametersScopeClass();
if (!scope_class.IsNull()) {
- if (type_name.qualifier != NULL) {
- // Check if qualifier is a type parameter in scope, unless it was
- // already checked by ParseQualIdent when !is_top_level_.
- if (is_top_level_) {
- const TypeParameter& type_parameter = TypeParameter::Handle(
- scope_class.LookupTypeParameter(*type_name.qualifier));
- if (!type_parameter.IsNull()) {
- ErrorMsg(type_pos,
- "type Parameter '%s' cannot be used as qualifier",
- type_name.qualifier->ToCString());
- }
- }
- } else {
+ if (type_name.lib_prefix == NULL) {
// Check if ident is a type parameter in scope.
TypeParameter& type_parameter = TypeParameter::Handle(
scope_class.LookupTypeParameter(*type_name.ident));
@@ -6686,8 +6674,7 @@
if (type_resolution == kIgnore) {
return Type::DynamicType();
}
- Type& type = Type::Handle(
- Type::NewParameterizedType(type_class, type_arguments));
+ Type& type = Type::Handle(Type::New(type_class, type_arguments));
if (type_resolution == kMustResolve) {
ASSERT(type_class.IsClass()); // Must be resolved.
Error& error = Error::Handle();
@@ -7234,7 +7221,7 @@
}
// TODO(regis): Temporary type should be allocated in new gen heap.
Type& temp_type = Type::Handle(
- Type::NewParameterizedType(constructor_class, temp_type_arguments));
+ Type::New(constructor_class, temp_type_arguments));
Error& error = Error::Handle();
const Class& scope_class = Class::Handle(TypeParametersScopeClass());
temp_type ^= ClassFinalizer::FinalizeAndCanonicalizeType(scope_class,
@@ -7351,7 +7338,7 @@
} else if (IsIdentifier()) {
QualIdent qual_ident;
ParseQualIdent(&qual_ident);
- if (qual_ident.qualifier == NULL) {
+ if (qual_ident.lib_prefix == NULL) {
if (!ResolveIdentInLocalScope(qual_ident.ident_pos,
*qual_ident.ident,
&primary)) {
« no previous file with comments | « runtime/vm/object.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698