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

Unified Diff: runtime/vm/parser.cc

Issue 10821076: - Allow parsing of external methods. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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_test.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 10018)
+++ runtime/vm/parser.cc (working copy)
@@ -452,6 +452,7 @@
}
void Clear() {
has_abstract = false;
+ has_external = false;
has_final = false;
has_const = false;
has_static = false;
@@ -480,6 +481,7 @@
return kind == RawFunction::kSetterFunction;
}
bool has_abstract;
+ bool has_external;
bool has_final;
bool has_const;
bool has_static;
@@ -1067,6 +1069,7 @@
RawFunction::kSignatureFunction,
/* is_static = */ false,
/* is_const = */ false,
+ /* is_external = */ false,
parameter.name_pos));
signature_function.set_owner(current_class());
signature_function.set_result_type(result_type);
@@ -2167,6 +2170,13 @@
current_block_->statements->Add(new ReturnNode(expr_pos, expr));
} else if (IsLiteral("native")) {
ParseNativeFunctionBlock(&params, func);
+ } else if (func.is_external()) {
+ // Body of an external method contains a single throw.
+ current_block_->statements->Add(
+ new ThrowNode(TokenPos(),
+ new LiteralNode(TokenPos(),
+ String::ZoneHandle(
+ Symbols::New("External implementation missing."))), NULL));
} else {
UnexpectedToken();
}
@@ -2295,6 +2305,10 @@
ErrorMsg(method->name_pos,
"'abstract' method only allowed in class definition");
}
+ if (method->has_external && members->is_interface()) {
+ ErrorMsg(method->name_pos,
+ "'external' method only allowed in class definition");
+ }
if (members->FunctionNameExists(*method->name, method->kind)) {
ErrorMsg(method->name_pos,
@@ -2386,6 +2400,10 @@
ErrorMsg(method->name_pos,
"abstract method '%s' may not have a function body",
method->name->ToCString());
+ } else if (method->has_external) {
+ ErrorMsg(method->name_pos,
+ "external method '%s' may not have a function body",
+ method->name->ToCString());
} else if (method->IsConstructor() && method->has_const) {
ErrorMsg(method->name_pos,
"const constructor '%s' may not have a function body",
@@ -2431,6 +2449,7 @@
} else if (CurrentToken() == Token::kSEMICOLON) {
if (members->is_interface() ||
method->has_abstract ||
+ method->has_external ||
(method->redirect_name != NULL) ||
method->IsConstructor()) {
ConsumeToken();
@@ -2442,6 +2461,7 @@
} else {
if (members->is_interface() ||
method->has_abstract ||
+ method->has_external ||
(method->redirect_name != NULL) ||
(method->IsConstructor() && method->has_const)) {
ExpectSemicolon();
@@ -2469,6 +2489,7 @@
function_kind,
method->has_static,
method->has_const,
+ method->has_external,
method_pos));
func.set_result_type(*method->type);
func.set_end_token_pos(method_end_pos);
@@ -2495,6 +2516,9 @@
if (field->has_abstract) {
ErrorMsg("keyword 'abstract' not allowed in field declaration");
}
+ if (field->has_external) {
+ ErrorMsg("keyword 'external' not allowed in field declaration");
+ }
if (field->has_factory) {
ErrorMsg("keyword 'factory' not allowed in field declaration");
}
@@ -2543,7 +2567,7 @@
class_field.set_value(Instance::Handle(Object::sentinel()));
String& getter_name = String::Handle(Field::GetterSymbol(*field->name));
getter = Function::New(getter_name, RawFunction::kConstImplicitGetter,
- field->has_static, field->has_final,
+ field->has_static, field->has_final, false,
field->name_pos);
getter.set_result_type(*field->type);
members->AddFunction(getter);
@@ -2553,7 +2577,7 @@
if (!field->has_static) {
String& getter_name = String::Handle(Field::GetterSymbol(*field->name));
getter = Function::New(getter_name, RawFunction::kImplicitGetter,
- field->has_static, field->has_final,
+ field->has_static, field->has_final, false,
field->name_pos);
ParamList params;
params.AddReceiver(TokenPos());
@@ -2564,7 +2588,7 @@
// Build a setter accessor for non-const fields.
String& setter_name = String::Handle(Field::SetterSymbol(*field->name));
setter = Function::New(setter_name, RawFunction::kImplicitSetter,
- field->has_static, field->has_final,
+ field->has_static, field->has_final, false,
field->name_pos);
ParamList params;
params.AddReceiver(TokenPos());
@@ -2618,6 +2642,11 @@
ConsumeToken();
member.has_abstract = true;
}
+ if ((CurrentToken() == Token::kEXTERNAL) &&
+ (LookaheadToken(1) != Token::kLPAREN)) {
+ ConsumeToken();
+ member.has_external = true;
+ }
if ((CurrentToken() == Token::kSTATIC) &&
(LookaheadToken(1) != Token::kLPAREN)) {
ConsumeToken();
@@ -2939,6 +2968,7 @@
RawFunction::kConstructor,
/* is_static = */ false,
/* is_const = */ false,
+ /* is_external = */ false,
class_desc->token_pos()));
ParamList params;
// Add implicit 'this' parameter.
@@ -3057,6 +3087,7 @@
RawFunction::kSignatureFunction,
/* is_static = */ false,
/* is_const = */ false,
+ /* is_external = */ false,
alias_name_pos));
signature_function.set_owner(alias_owner);
signature_function.set_result_type(result_type);
@@ -3488,7 +3519,7 @@
// Create a static const getter.
String& getter_name = String::ZoneHandle(Field::GetterSymbol(var_name));
getter = Function::New(getter_name, RawFunction::kConstImplicitGetter,
- is_static, is_final, name_pos);
+ is_static, is_final, false, name_pos);
getter.set_result_type(type);
top_level->functions.Add(getter);
} else if (is_final || is_const) {
@@ -3511,6 +3542,11 @@
TRACE_PARSER("ParseTopLevelFunction");
AbstractType& result_type = Type::Handle(Type::DynamicType());
const bool is_static = true;
+ bool is_external = false;
+ if (CurrentToken() == Token::kEXTERNAL) {
+ ConsumeToken();
+ is_external = true;
+ }
if (CurrentToken() == Token::kVOID) {
ConsumeToken();
result_type = Type::VoidType();
@@ -3547,7 +3583,9 @@
ParseFormalParameterList(allow_explicit_default_values, &params);
intptr_t function_end_pos = function_pos;
- if (CurrentToken() == Token::kLBRACE) {
+ if (is_external) {
+ ExpectSemicolon();
+ } else if (CurrentToken() == Token::kLBRACE) {
SkipBlock();
function_end_pos = TokenPos();
} else if (CurrentToken() == Token::kARROW) {
@@ -3562,7 +3600,7 @@
}
Function& func = Function::Handle(
Function::New(func_name, RawFunction::kRegularFunction,
- is_static, false, function_pos));
+ is_static, false, is_external, function_pos));
func.set_result_type(result_type);
func.set_end_token_pos(function_end_pos);
AddFormalParamsToFunction(&params, func);
@@ -3644,7 +3682,7 @@
Function::New(accessor_name,
is_getter? RawFunction::kGetterFunction :
RawFunction::kSetterFunction,
- is_static, false, accessor_pos));
+ is_static, false, false, accessor_pos));
func.set_result_type(result_type);
AddFormalParamsToFunction(&params, func);
top_level->functions.Add(func);
@@ -4513,6 +4551,12 @@
// a function declaration. Token position remains unchanged.
bool Parser::IsFunctionDeclaration() {
const intptr_t saved_pos = TokenPos();
+ bool is_external = false;
+ if (is_top_level_ && (CurrentToken() == Token::kEXTERNAL)) {
+ // Skip over 'external' for top-level function declarations.
+ is_external = true;
+ ConsumeToken();
+ }
if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
// Possibly a function without explicit return type.
ConsumeToken(); // Consume function identifier.
@@ -4531,7 +4575,8 @@
SkipToMatchingParenthesis();
if ((CurrentToken() == Token::kLBRACE) ||
(CurrentToken() == Token::kARROW) ||
- (is_top_level_ && IsLiteral("native"))) {
+ (is_top_level_ && IsLiteral("native")) ||
+ is_external) {
SetPosition(saved_pos);
return true;
}
« no previous file with comments | « runtime/vm/object_test.cc ('k') | runtime/vm/raw_object.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698