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

Unified Diff: src/parser.cc

Issue 9615009: Basic interface inference for modules. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Eps. Created 8 years, 9 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 | « src/parser.h ('k') | src/scopes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/parser.cc
diff --git a/src/parser.cc b/src/parser.cc
index 5f04cabee3d81c3cd2779c0584870bfc2dd67fab..a253854d6e4a054c55e3f427a3840594f6a1e861 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -757,6 +757,12 @@ void Parser::ReportMessage(const char* type, Vector<const char*> args) {
}
+void Parser::ReportMessage(const char* type, Vector<Handle<String> > args) {
+ Scanner::Location source_location = scanner().location();
+ ReportMessageAt(source_location, type, args);
+}
+
+
void Parser::ReportMessageAt(Scanner::Location source_location,
const char* type,
Vector<const char*> args) {
@@ -1163,6 +1169,7 @@ void* Parser::ParseSourceElements(ZoneList<Statement*>* processor,
this_property_assignment_finder.GetThisPropertyAssignments());
}
}
+
return 0;
}
@@ -1221,12 +1228,28 @@ Block* Parser::ParseModuleDeclaration(ZoneStringList* names, bool* ok) {
// Create new block with one expected declaration.
Block* block = factory()->NewBlock(NULL, 1, true);
Handle<String> name = ParseIdentifier(CHECK_OK);
+
+#ifdef DEBUG
+ if (FLAG_print_interface_details)
+ PrintF("# Module %s...\n", name->ToAsciiArray());
+#endif
+
Module* module = ParseModule(CHECK_OK);
- VariableProxy* proxy = NewUnresolved(name, LET);
+ VariableProxy* proxy = NewUnresolved(name, LET, module->interface());
Declaration* declaration =
factory()->NewModuleDeclaration(proxy, module, top_scope_);
Declare(declaration, true, CHECK_OK);
+#ifdef DEBUG
+ if (FLAG_print_interface_details)
+ PrintF("# Module %s.\n", name->ToAsciiArray());
+
+ if (FLAG_print_interfaces) {
+ PrintF("module %s : ", name->ToAsciiArray());
+ module->interface()->Print();
+ }
+#endif
+
// TODO(rossberg): Add initialization statement to block.
if (names) names->Add(name);
@@ -1267,6 +1290,9 @@ Module* Parser::ParseModuleLiteral(bool* ok) {
// Construct block expecting 16 statements.
Block* body = factory()->NewBlock(NULL, 16, false);
+#ifdef DEBUG
+ if (FLAG_print_interface_details) PrintF("# Literal ");
+#endif
Scope* scope = NewScope(top_scope_, MODULE_SCOPE);
Expect(Token::LBRACE, CHECK_OK);
@@ -1292,7 +1318,10 @@ Module* Parser::ParseModuleLiteral(bool* ok) {
Expect(Token::RBRACE, CHECK_OK);
scope->set_end_position(scanner().location().end_pos);
body->set_block_scope(scope);
- return factory()->NewModuleLiteral(body);
+
+ scope->interface()->Freeze(ok);
+ ASSERT(ok);
+ return factory()->NewModuleLiteral(body, scope->interface());
}
@@ -1302,10 +1331,28 @@ Module* Parser::ParseModulePath(bool* ok) {
// ModulePath '.' Identifier
Module* result = ParseModuleVariable(CHECK_OK);
-
while (Check(Token::PERIOD)) {
Handle<String> name = ParseIdentifierName(CHECK_OK);
- result = factory()->NewModulePath(result, name);
+#ifdef DEBUG
+ if (FLAG_print_interface_details)
+ PrintF("# Path .%s ", name->ToAsciiArray());
+#endif
+ Module* member = factory()->NewModulePath(result, name);
+ result->interface()->Add(name, member->interface(), ok);
+ if (!*ok) {
+#ifdef DEBUG
+ if (FLAG_print_interfaces) {
+ PrintF("PATH TYPE ERROR at '%s'\n", name->ToAsciiArray());
+ PrintF("result: ");
+ result->interface()->Print();
+ PrintF("member: ");
+ member->interface()->Print();
+ }
+#endif
+ ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
+ return NULL;
+ }
+ result = member;
}
return result;
@@ -1317,8 +1364,13 @@ Module* Parser::ParseModuleVariable(bool* ok) {
// Identifier
Handle<String> name = ParseIdentifier(CHECK_OK);
+#ifdef DEBUG
+ if (FLAG_print_interface_details)
+ PrintF("# Module variable %s ", name->ToAsciiArray());
+#endif
VariableProxy* proxy = top_scope_->NewUnresolved(
- factory(), name, scanner().location().beg_pos);
+ factory(), name, scanner().location().beg_pos, Interface::NewModule());
+
return factory()->NewModuleVariable(proxy);
}
@@ -1330,6 +1382,11 @@ Module* Parser::ParseModuleUrl(bool* ok) {
Expect(Token::STRING, CHECK_OK);
Handle<String> symbol = GetSymbol(CHECK_OK);
+ // TODO(ES6): Request JS resource from environment...
+
+#ifdef DEBUG
+ if (FLAG_print_interface_details) PrintF("# Url ");
+#endif
return factory()->NewModuleUrl(symbol);
}
@@ -1357,6 +1414,7 @@ Block* Parser::ParseImportDeclaration(bool* ok) {
ZoneStringList names(1);
Handle<String> name = ParseIdentifierName(CHECK_OK);
+ names.Add(name);
while (peek() == Token::COMMA) {
Consume(Token::COMMA);
name = ParseIdentifierName(CHECK_OK);
@@ -1371,14 +1429,30 @@ Block* Parser::ParseImportDeclaration(bool* ok) {
// TODO(ES6): once we implement destructuring, make that one declaration.
Block* block = factory()->NewBlock(NULL, 1, true);
for (int i = 0; i < names.length(); ++i) {
- VariableProxy* proxy = NewUnresolved(names[i], LET);
+#ifdef DEBUG
+ if (FLAG_print_interface_details)
+ PrintF("# Import %s ", names[i]->ToAsciiArray());
+#endif
+ Interface* interface = Interface::NewUnknown();
+ module->interface()->Add(names[i], interface, ok);
+ if (!*ok) {
+#ifdef DEBUG
+ if (FLAG_print_interfaces) {
+ PrintF("IMPORT TYPE ERROR at '%s'\n", names[i]->ToAsciiArray());
+ PrintF("module: ");
+ module->interface()->Print();
+ }
+#endif
+ ReportMessage("invalid_module_path", Vector<Handle<String> >(&name, 1));
+ return NULL;
+ }
+ VariableProxy* proxy = NewUnresolved(names[i], LET, interface);
Declaration* declaration =
factory()->NewImportDeclaration(proxy, module, top_scope_);
Declare(declaration, true, CHECK_OK);
// TODO(rossberg): Add initialization statement to block.
}
-
return block;
}
@@ -1431,12 +1505,22 @@ Statement* Parser::ParseExportDeclaration(bool* ok) {
return NULL;
}
- // Extract declared names into export declarations.
+ // Extract declared names into export declarations and interface.
+ Interface* interface = top_scope_->interface();
for (int i = 0; i < names.length(); ++i) {
- VariableProxy* proxy = NewUnresolved(names[i], LET);
- Declaration* declaration =
- factory()->NewExportDeclaration(proxy, top_scope_);
- top_scope_->AddDeclaration(declaration);
+#ifdef DEBUG
+ if (FLAG_print_interface_details)
+ PrintF("# Export %s ", names[i]->ToAsciiArray());
+#endif
+ Interface* inner = Interface::NewUnknown();
+ interface->Add(names[i], inner, CHECK_OK);
+ VariableProxy* proxy = NewUnresolved(names[i], LET, inner);
+ USE(proxy);
+ // TODO(rossberg): Rethink whether we actually need to store export
+ // declarations (for compilation?).
+ // ExportDeclaration* declaration =
+ // factory()->NewExportDeclaration(proxy, top_scope_);
+ // top_scope_->AddDeclaration(declaration);
}
ASSERT(result != NULL);
@@ -1597,19 +1681,21 @@ Statement* Parser::ParseStatement(ZoneStringList* labels, bool* ok) {
}
-VariableProxy* Parser::NewUnresolved(Handle<String> name, VariableMode mode) {
+VariableProxy* Parser::NewUnresolved(
+ Handle<String> name, VariableMode mode, Interface* interface) {
// If we are inside a function, a declaration of a var/const variable is a
// truly local variable, and the scope of the variable is always the function
// scope.
// Let/const variables in harmony mode are always added to the immediately
// enclosing scope.
return DeclarationScope(mode)->NewUnresolved(
- factory(), name, scanner().location().beg_pos);
+ factory(), name, scanner().location().beg_pos, interface);
}
void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
- Handle<String> name = declaration->proxy()->name();
+ VariableProxy* proxy = declaration->proxy();
+ Handle<String> name = proxy->name();
VariableMode mode = declaration->mode();
Scope* declaration_scope = DeclarationScope(mode);
Variable* var = NULL;
@@ -1627,13 +1713,14 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
if (declaration_scope->is_function_scope() ||
declaration_scope->is_strict_or_extended_eval_scope() ||
declaration_scope->is_block_scope() ||
- declaration_scope->is_module_scope()) {
+ declaration_scope->is_module_scope() ||
+ declaration->AsModuleDeclaration() != NULL) {
// Declare the variable in the function scope.
var = declaration_scope->LocalLookup(name);
if (var == NULL) {
// Declare the name.
var = declaration_scope->DeclareLocal(
- name, mode, declaration->initialization());
+ name, mode, declaration->initialization(), proxy->interface());
} else {
// The name was declared in this scope before; check for conflicting
// re-declarations. We have a conflict if either of the declarations is
@@ -1743,7 +1830,30 @@ void Parser::Declare(Declaration* declaration, bool resolve, bool* ok) {
// initialization code. Thus, inside the 'with' statement, we need
// both access to the static and the dynamic context chain; the
// runtime needs to provide both.
- if (resolve && var != NULL) declaration->proxy()->BindTo(var);
+ if (resolve && var != NULL) {
+ proxy->BindTo(var);
+
+ if (FLAG_harmony_modules) {
+ bool ok;
+#ifdef DEBUG
+ if (FLAG_print_interface_details)
+ PrintF("# Declare %s\n", var->name()->ToAsciiArray());
+#endif
+ proxy->interface()->Unify(var->interface(), &ok);
+ if (!ok) {
+#ifdef DEBUG
+ if (FLAG_print_interfaces) {
+ PrintF("DECLARE TYPE ERROR\n");
+ PrintF("proxy: ");
+ proxy->interface()->Print();
+ PrintF("var: ");
+ var->interface()->Print();
+ }
+#endif
+ ReportMessage("module_type_error", Vector<Handle<String> >(&name, 1));
+ }
+ }
+ }
}
@@ -3498,8 +3608,14 @@ Expression* Parser::ParsePrimaryExpression(bool* ok) {
case Token::FUTURE_STRICT_RESERVED_WORD: {
Handle<String> name = ParseIdentifier(CHECK_OK);
if (fni_ != NULL) fni_->PushVariableName(name);
+ // The name may refer to a module instance object, so its type is unknown.
+#ifdef DEBUG
+ if (FLAG_print_interface_details)
+ PrintF("# Variable %s ", name->ToAsciiArray());
+#endif
+ Interface* interface = Interface::NewUnknown();
result = top_scope_->NewUnresolved(
- factory(), name, scanner().location().beg_pos);
+ factory(), name, scanner().location().beg_pos, interface);
break;
}
« no previous file with comments | « src/parser.h ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698