| Index: runtime/vm/parser.cc
|
| ===================================================================
|
| --- runtime/vm/parser.cc (revision 11565)
|
| +++ runtime/vm/parser.cc (working copy)
|
| @@ -497,7 +497,6 @@
|
| : clazz_(cls),
|
| class_name_(cls_name),
|
| is_interface_(is_interface),
|
| - is_abstract_(false),
|
| token_pos_(token_pos),
|
| functions_(GrowableObjectArray::Handle(GrowableObjectArray::New())),
|
| fields_(GrowableObjectArray::Handle(GrowableObjectArray::New())) {
|
| @@ -573,14 +572,6 @@
|
| return is_interface_;
|
| }
|
|
|
| - void set_is_abstract() {
|
| - is_abstract_ = true;
|
| - }
|
| -
|
| - bool is_abstract() const {
|
| - return is_abstract_;
|
| - }
|
| -
|
| bool has_constructor() const {
|
| Function& func = Function::Handle();
|
| for (int i = 0; i < functions_.Length(); i++) {
|
| @@ -631,7 +622,6 @@
|
| const Class& clazz_;
|
| const String& class_name_;
|
| const bool is_interface_;
|
| - bool is_abstract_;
|
| intptr_t token_pos_; // Token index of "class" keyword.
|
| GrowableObjectArray& functions_;
|
| GrowableObjectArray& fields_;
|
| @@ -2485,42 +2475,29 @@
|
| "Constructor with redirection may not have a function body");
|
| }
|
| ParseNativeDeclaration();
|
| - } else {
|
| - // We haven't found a method body. Issue error if one is required.
|
| - const bool must_have_body =
|
| - !members->is_interface() &&
|
| - method->has_static && !method->has_external;
|
| - if (must_have_body) {
|
| + } else if (CurrentToken() == Token::kSEMICOLON) {
|
| + if (members->is_interface() ||
|
| + method->has_abstract ||
|
| + method->has_external ||
|
| + (method->redirect_name != NULL) ||
|
| + method->IsConstructor()) {
|
| + ConsumeToken();
|
| + } else {
|
| ErrorMsg(method->name_pos,
|
| "function body expected for method '%s'",
|
| method->name->ToCString());
|
| }
|
| -
|
| - if (CurrentToken() == Token::kSEMICOLON) {
|
| - ConsumeToken();
|
| - if (!members->is_interface() &&
|
| - !method->has_static &&
|
| - !method->has_external &&
|
| - !method->IsConstructor()) {
|
| - // Methods, getters and setters without a body are
|
| - // implicitly abstract.
|
| - method->has_abstract = true;
|
| - }
|
| + } else {
|
| + if (members->is_interface() ||
|
| + method->has_abstract ||
|
| + method->has_external ||
|
| + (method->redirect_name != NULL) ||
|
| + (method->IsConstructor() && method->has_const)) {
|
| + ExpectSemicolon();
|
| } else {
|
| - // Signature is not followed by semicolon or body. Issue an
|
| - // appropriate error.
|
| - const bool must_have_semicolon =
|
| - members->is_interface() ||
|
| - (method->redirect_name != NULL) ||
|
| - (method->IsConstructor() && method->has_const) ||
|
| - method->has_external;
|
| - if (must_have_semicolon) {
|
| - ExpectSemicolon();
|
| - } else {
|
| - ErrorMsg(method->name_pos,
|
| - "function body or semicolon expected for method '%s'",
|
| - method->name->ToCString());
|
| - }
|
| + ErrorMsg(method->name_pos,
|
| + "function body expected for method '%s'",
|
| + method->name->ToCString());
|
| }
|
| }
|
|
|
| @@ -2550,9 +2527,6 @@
|
| ASSERT(is_top_level_);
|
| AddFormalParamsToFunction(&method->params, func);
|
| members->AddFunction(func);
|
| - if (method->has_abstract) {
|
| - members->set_is_abstract();
|
| - }
|
| }
|
|
|
|
|
| @@ -2956,18 +2930,14 @@
|
|
|
| void Parser::ParseClassDefinition(const GrowableObjectArray& pending_classes) {
|
| TRACE_PARSER("ParseClassDefinition");
|
| + const intptr_t class_pos = TokenPos();
|
| bool is_patch = false;
|
| - bool is_abstract = false;
|
| if (is_patch_source() &&
|
| (CurrentToken() == Token::kIDENT) &&
|
| CurrentLiteral()->Equals("patch")) {
|
| ConsumeToken();
|
| is_patch = true;
|
| - } else if (CurrentToken() == Token::kABSTRACT) {
|
| - is_abstract = true;
|
| - ConsumeToken();
|
| }
|
| - const intptr_t class_pos = TokenPos();
|
| ExpectToken(Token::kCLASS);
|
| const intptr_t classname_pos = TokenPos();
|
| String& class_name = *ExpectClassIdentifier("class name expected");
|
| @@ -3055,10 +3025,6 @@
|
| }
|
| ExpectToken(Token::kRBRACE);
|
|
|
| - if (is_abstract || members.is_abstract()) {
|
| - cls.set_is_abstract();
|
| - }
|
| -
|
| // Add an implicit constructor if no explicit constructor is present. No
|
| // implicit constructors are needed for patch classes.
|
| if (!members.has_constructor() && !is_patch) {
|
| @@ -4107,6 +4073,7 @@
|
| ParseInterfaceDefinition(pending_classes);
|
| } else if ((CurrentToken() == Token::kABSTRACT) &&
|
| (LookaheadToken(1) == Token::kCLASS)) {
|
| + ConsumeToken(); // Consume and ignore 'abstract'.
|
| ParseClassDefinition(pending_classes);
|
| } else if (is_patch_source() && IsLiteral("patch") &&
|
| (LookaheadToken(1) == Token::kCLASS)) {
|
| @@ -8489,8 +8456,8 @@
|
| if (type.IsDynamicType()) {
|
| ErrorMsg(type_pos, "Dynamic cannot be instantiated");
|
| }
|
| - const Class& type_class = Class::Handle(type.type_class());
|
| - const String& type_class_name = String::Handle(type_class.Name());
|
| + Class& type_class = Class::Handle(type.type_class());
|
| + String& type_class_name = String::Handle(type_class.Name());
|
| AbstractTypeArguments& type_arguments =
|
| AbstractTypeArguments::ZoneHandle(type.arguments());
|
|
|
| @@ -8595,14 +8562,6 @@
|
| String::Handle(constructor_class.Name()).ToCString(),
|
| external_constructor_name.ToCString());
|
| }
|
| -
|
| - // It is ok to call a factory method of an abstract class, but it is
|
| - // an error to instantiate an abstract class.
|
| - if (constructor_class.is_abstract() && !constructor.IsFactory()) {
|
| - ErrorMsg(type_pos, "Cannot instantiate abstract class %s",
|
| - constructor_class_name.ToCString());
|
| - }
|
| -
|
| String& error_message = String::Handle();
|
| if (!constructor.AreValidArguments(arguments_length,
|
| arguments->names(),
|
|
|