[cfe] Don't mark external methods as abstract

Closes #31233
Related to flutter/flutter#62887

Change-Id: I96e5a1b8045f75f1ad02fb47e5e41fe402dc3dc1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/157481
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Jens Johansen <jensj@google.com>
This commit is contained in:
Johnni Winther 2020-08-06 16:29:09 +00:00 committed by commit-bot@chromium.org
parent 5276973b22
commit b9c5118c73
25 changed files with 175 additions and 79 deletions

View file

@ -1410,7 +1410,7 @@ class AbstractOrExternalFieldEncoding implements FieldEncoding {
_getter
..isStatic = !isInstanceMember
..isExtensionMember = isExtensionMember
..isAbstract = isAbstract
..isAbstract = isAbstract && !isExternal
..isExternal = isExternal;
// TODO(johnniwinther): How can the name already have been computed?
_getter.name ??= new Name(getterName, libraryBuilder.library);
@ -1428,7 +1428,7 @@ class AbstractOrExternalFieldEncoding implements FieldEncoding {
_setter
..isStatic = !isInstanceMember
..isExtensionMember = isExtensionMember
..isAbstract = isAbstract
..isAbstract = isAbstract && !isExternal
..isExternal = isExternal;
// TODO(johnniwinther): How can the name already have been computed?
_setter?.name ??= new Name(setterName, libraryBuilder.library);

View file

@ -51,7 +51,7 @@ const int initializingFormalMask = hasInitializerMask << 1;
const int declaresConstConstructorMask = initializingFormalMask << 1;
/// Not a real modifier, and by setting it to zero, it is automatically ignored
/// by [Modifier.validate] below.
/// by [Modifier.toMask] below.
const int varMask = 0;
const Modifier Abstract = const Modifier(ModifierEnum.Abstract, abstractMask);
@ -90,10 +90,8 @@ class Modifier {
toString() => "modifier(${'$kind'.substring('ModifierEnum.'.length)})";
static int validate(List<Modifier> modifiers, {bool isAbstract: false}) {
// TODO(ahe): Rename this method, validation is now taken care of by the
// parser.
int result = isAbstract ? abstractMask : 0;
static int toMask(List<Modifier> modifiers) {
int result = 0;
if (modifiers == null) return result;
for (Modifier modifier in modifiers) {
result |= modifier.mask;
@ -108,4 +106,13 @@ class Modifier {
if (identical('var', lexeme)) return Var.mask;
return unhandled(lexeme, "Modifier.validateVarFinalOrConst", -1, null);
}
/// Returns [modifier] with [abstractMask] added if [isAbstract] and
/// [modifiers] doesn't contain [externalMask].
static int addAbstractMask(int modifiers, {bool isAbstract: false}) {
if (isAbstract && (modifiers & externalMask) == 0) {
modifiers |= abstractMask;
}
return modifiers;
}
}

View file

@ -813,9 +813,7 @@ class OutlineBuilder extends StackListenerImpl {
}
}
int modifiers = pop();
if (isAbstract) {
modifiers |= abstractMask;
}
modifiers = Modifier.addAbstractMask(modifiers, isAbstract: isAbstract);
if (nativeMethodName != null) {
modifiers |= externalMask;
}
@ -1059,13 +1057,11 @@ class OutlineBuilder extends StackListenerImpl {
isAbstract = false;
}
}
int modifiers = Modifier.validate(pop(), isAbstract: isAbstract);
int modifiers = Modifier.toMask(pop());
modifiers = Modifier.addAbstractMask(modifiers, isAbstract: isAbstract);
if (nativeMethodName != null) {
modifiers |= externalMask;
}
if ((modifiers & externalMask) != 0) {
modifiers &= ~abstractMask;
}
bool isConst = (modifiers & constMask) != 0;
int varFinalOrConstOffset = pop();
List<MetadataBuilder> metadata = pop();

View file

@ -0,0 +1,11 @@
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
external void externalMethod();
class Class {
external void externalMethod();
}
void main() {}

View file

@ -0,0 +1,22 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
synthetic constructor •() → self::Class*
;
external method externalMethod() → void;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
external static method externalMethod() → void;
static method main() → void
;

View file

@ -0,0 +1,22 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
synthetic constructor •() → self::Class*
: super core::Object::•()
;
external method externalMethod() → void;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
external static method externalMethod() → void;
static method main() → void {}

View file

@ -0,0 +1,22 @@
library;
import self as self;
import "dart:core" as core;
class Class extends core::Object {
synthetic constructor •() → self::Class*
: super core::Object::•()
;
external method externalMethod() → void;
abstract member-signature get _identityHashCode() → core::int*;
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*;
abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*;
abstract member-signature operator ==(dynamic other) → core::bool*;
abstract member-signature get hashCode() → core::int*;
abstract member-signature method toString() → core::String*;
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
external static method externalMethod() → void;
static method main() → void {}

View file

@ -0,0 +1,7 @@
external void externalMethod();
class Class {
external void externalMethod();
}
void main() {}

View file

@ -0,0 +1,6 @@
class Class {
external void externalMethod();
}
external void externalMethod();
void main() {}

View file

@ -115,8 +115,8 @@ class DynamicReceiver2 extends core::Object {
}
static method staticMethod() → dynamic
;
external static abstract method externalStatic() → core::bool*;
external static abstract method createBar() → self::Bar*;
external static method externalStatic() → core::bool*;
external static method createBar() → self::Bar*;
static method stringArgument(dynamic x) → dynamic
;
static method intArgument(dynamic x) → dynamic

View file

@ -123,8 +123,8 @@ class DynamicReceiver2 extends core::Object {
static method staticMethod() → dynamic {
return "sdfg";
}
external static abstract method externalStatic() → core::bool*;
external static abstract method createBar() → self::Bar*;
external static method externalStatic() → core::bool*;
external static method createBar() → self::Bar*;
static method stringArgument(dynamic x) → dynamic {}
static method intArgument(dynamic x) → dynamic {}
static method makeDynamicCall(dynamic receiver) → void {

View file

@ -123,8 +123,8 @@ class DynamicReceiver2 extends core::Object {
static method staticMethod() → dynamic {
return "sdfg";
}
external static abstract method externalStatic() → core::bool*;
external static abstract method createBar() → self::Bar*;
external static method externalStatic() → core::bool*;
external static method createBar() → self::Bar*;
static method stringArgument(dynamic x) → dynamic {}
static method intArgument(dynamic x) → dynamic {}
static method makeDynamicCall(dynamic receiver) → void {

View file

@ -77,6 +77,6 @@ class InvalidListener extends core::Object {
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
external static abstract method createExternal() → self::External*;
external static method createExternal() → self::External*;
static method main() → dynamic
;

View file

@ -108,7 +108,7 @@ class InvalidListener extends core::Object {
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
external static abstract method createExternal() → self::External*;
external static method createExternal() → self::External*;
static method main() → dynamic {
self::Foo* foo = new self::Foo::•();
dynamic string1 = foo.{self::Foo::method}(1);

View file

@ -123,8 +123,8 @@ class DynamicReceiver2 extends core::Object {
static method staticMethod() → dynamic {
return "sdfg";
}
external static abstract method externalStatic() → core::bool*;
external static abstract method createBar() → self::Bar*;
external static method externalStatic() → core::bool*;
external static method createBar() → self::Bar*;
static method stringArgument(dynamic x) → dynamic {}
static method intArgument(dynamic x) → dynamic {}
static method makeDynamicCall(dynamic receiver) → void {

View file

@ -123,8 +123,8 @@ class DynamicReceiver2 extends core::Object {
static method staticMethod() → dynamic {
return "sdfg";
}
external static abstract method externalStatic() → core::bool*;
external static abstract method createBar() → self::Bar*;
external static method externalStatic() → core::bool*;
external static method createBar() → self::Bar*;
static method stringArgument(dynamic x) → dynamic {}
static method intArgument(dynamic x) → dynamic {}
static method makeDynamicCall(dynamic receiver) → void {

View file

@ -108,7 +108,7 @@ class InvalidListener extends core::Object {
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
abstract member-signature get runtimeType() → core::Type*;
}
external static abstract method createExternal() → self::External*;
external static method createExternal() → self::External*;
static method main() → dynamic {
self::Foo* foo = new self::Foo::•();
dynamic string1 = foo.{self::Foo::method}(1);

View file

@ -193,22 +193,22 @@ abstract class A extends core::Object {
abstract set initializedField1(core::int #t2) → void;
abstract get initializedField2() → core::int;
abstract set initializedField2(core::int #t3) → void;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t4) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t5) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t4) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t5) → void;
external get externalLateInstanceField() → core::int;
external set externalLateInstanceField(core::int #t6) → void;
}
abstract class B extends core::Object /*isMixinDeclaration*/ {
static field core::int staticField;
static final field core::int finalStaticField;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t7) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t8) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t7) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t8) → void;
}
extension Extension on self::A {
get extensionInstanceField = get self::Extension|extensionInstanceField;

View file

@ -225,22 +225,22 @@ Try removing the field initializer or the 'abstract' keyword from the field decl
abstract set initializedField1(core::int #t4) → void;
abstract get initializedField2() → core::int;
abstract set initializedField2(core::int #t5) → void;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t6) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t7) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t6) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t7) → void;
external get externalLateInstanceField() → core::int;
external set externalLateInstanceField(core::int #t8) → void;
}
abstract class B extends core::Object /*isMixinDeclaration*/ {
static field core::int staticField = null;
static final field core::int finalStaticField = null;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t9) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t10) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t9) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t10) → void;
}
extension Extension on self::A {
get extensionInstanceField = get self::Extension|extensionInstanceField;

View file

@ -225,22 +225,22 @@ Try removing the field initializer or the 'abstract' keyword from the field decl
abstract set initializedField1(core::int #t4) → void;
abstract get initializedField2() → core::int;
abstract set initializedField2(core::int #t5) → void;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t6) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t7) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t6) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t7) → void;
external get externalLateInstanceField() → core::int;
external set externalLateInstanceField(core::int #t8) → void;
}
abstract class B extends core::Object /*isMixinDeclaration*/ {
static field core::int staticField = null;
static final field core::int finalStaticField = null;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t9) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t10) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t9) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t10) → void;
}
extension Extension on self::A {
get extensionInstanceField = get self::Extension|extensionInstanceField;

View file

@ -225,22 +225,22 @@ Try removing the field initializer or the 'abstract' keyword from the field decl
abstract set initializedField1(core::int #t4) → void;
abstract get initializedField2() → core::int;
abstract set initializedField2(core::int #t5) → void;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t6) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t7) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t6) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t7) → void;
external get externalLateInstanceField() → core::int;
external set externalLateInstanceField(core::int #t8) → void;
}
abstract class B extends core::Object /*isMixinDeclaration*/ {
static field core::int staticField = null;
static final field core::int finalStaticField = null;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t9) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t10) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t9) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t10) → void;
}
extension Extension on self::A {
get extensionInstanceField = get self::Extension|extensionInstanceField;

View file

@ -225,22 +225,22 @@ Try removing the field initializer or the 'abstract' keyword from the field decl
abstract set initializedField1(core::int #t4) → void;
abstract get initializedField2() → core::int;
abstract set initializedField2(core::int #t5) → void;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t6) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t7) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t6) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t7) → void;
external get externalLateInstanceField() → core::int;
external set externalLateInstanceField(core::int #t8) → void;
}
abstract class B extends core::Object /*isMixinDeclaration*/ {
static field core::int staticField = null;
static final field core::int finalStaticField = null;
external abstract get externalInstanceField() → core::int;
external abstract set externalInstanceField(core::int #t9) → void;
external abstract get externalFinalInstanceField() → core::int;
external abstract get externalCovariantInstanceField() → core::num;
external abstract set externalCovariantInstanceField(covariant core::num #t10) → void;
external get externalInstanceField() → core::int;
external set externalInstanceField(core::int #t9) → void;
external get externalFinalInstanceField() → core::int;
external get externalCovariantInstanceField() → core::num;
external set externalCovariantInstanceField(covariant core::num #t10) → void;
}
extension Extension on self::A {
get extensionInstanceField = get self::Extension|extensionInstanceField;

View file

@ -35,6 +35,6 @@ class Class<T extends core::num = core::num> extends core::Object /*hasConstCons
static method method(core::int a) → core::int
;
@_in::patch
external static abstract method patchedMethod(core::int a) → void;
external static method patchedMethod(core::int a) → void;
static method /* from org-dartlang-testcase:///patch_lib.dart */ _injectedMethod(core::int i) → core::int
;

View file

@ -58,6 +58,6 @@ class Class extends core::Object {
static method method([core::int i]) → void
;
@_in::patch
external static abstract method patchedMethod([core::int i]) → void;
external static method patchedMethod([core::int i]) → void;
static method /* from org-dartlang-testcase:///patch_lib.dart */ _injectedMethod([core::int i]) → void
;

View file

@ -293,6 +293,9 @@ class VerifyingVisitor extends RecursiveVisitor<void> {
currentMember = node;
var oldParent = enterParent(node);
classTypeParametersAreInScope = !node.isStatic;
if (node.isAbstract && node.isExternal) {
problem(node, "Procedure cannot be both abstract and external.");
}
node.function.accept(this);
classTypeParametersAreInScope = false;
visitList(node.annotations, this);