Version 2.11.0-206.0.dev
Merge commit '45a46ca2b8833f62ecfb53f0a8cc63e1802132e1' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index a4af6df..a036ae6 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -2879,8 +2879,7 @@
void check(ClassHierarchyBuilder hierarchy) {
classBuilder.checkGetterSetter(hierarchy.types, getter.getMember(hierarchy),
- setter.getMember(hierarchy),
- isInterfaceCheck: !classBuilder.isMixinApplication);
+ setter.getMember(hierarchy));
}
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index 0899ab4..9dbff26 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -1126,8 +1126,7 @@
// TODO(ahe): Handle other cases: accessors, operators, and fields.
}
- void checkGetterSetter(Types types, Member getter, Member setter,
- {bool isInterfaceCheck = false}) {
+ void checkGetterSetter(Types types, Member getter, Member setter) {
if (getter == setter) {
return;
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index b8d7b3d..867fb41 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -255,6 +255,14 @@
} else if (builder is ProcedureBuilder) {
// Check procedures
library.checkTypesInProcedureBuilder(builder, typeEnvironment);
+ if (builder.isGetter) {
+ Builder setterDeclaration =
+ scope.lookupLocalMember(builder.name, setter: true);
+ if (setterDeclaration != null) {
+ library.checkGetterSetterTypes(
+ builder, setterDeclaration, typeEnvironment);
+ }
+ }
} else {
assert(false, "Unexpected member: $builder.");
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index d142b10..0bd7da5 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -67,7 +67,7 @@
findTypeArgumentIssuesForInvocation,
getGenericTypeName;
-import 'package:kernel/type_algebra.dart' show substitute;
+import 'package:kernel/type_algebra.dart' show Substitution, substitute;
import 'package:kernel/type_environment.dart'
show SubtypeCheckMode, TypeEnvironment;
@@ -1610,6 +1610,100 @@
return typeVariablesByName;
}
+ void checkGetterSetterTypes(ProcedureBuilder getterBuilder,
+ ProcedureBuilder setterBuilder, TypeEnvironment typeEnvironment) {
+ DartType getterType;
+ List<TypeParameter> getterExtensionTypeParameters;
+ if (getterBuilder.isExtensionInstanceMember) {
+ // An extension instance getter
+ //
+ // extension E<T> on A {
+ // T get property => ...
+ // }
+ //
+ // is encoded as a top level method
+ //
+ // T# E#get#property<T#>(A #this) => ...
+ //
+ Procedure procedure = getterBuilder.procedure;
+ getterType = procedure.function.returnType;
+ getterExtensionTypeParameters = procedure.function.typeParameters;
+ } else {
+ getterType = getterBuilder.procedure.getterType;
+ }
+ DartType setterType;
+ if (setterBuilder.isExtensionInstanceMember) {
+ // An extension instance setter
+ //
+ // extension E<T> on A {
+ // void set property(T value) { ... }
+ // }
+ //
+ // is encoded as a top level method
+ //
+ // void E#set#property<T#>(A #this, T# value) { ... }
+ //
+ Procedure procedure = setterBuilder.procedure;
+ setterType = procedure.function.positionalParameters[1].type;
+ if (getterExtensionTypeParameters != null &&
+ getterExtensionTypeParameters.isNotEmpty) {
+ // We substitute the setter type parameters for the getter type
+ // parameters to check them below in a shared context.
+ List<TypeParameter> setterExtensionTypeParameters =
+ procedure.function.typeParameters;
+ assert(getterExtensionTypeParameters.length ==
+ setterExtensionTypeParameters.length);
+ setterType = Substitution.fromPairs(
+ setterExtensionTypeParameters,
+ new List<DartType>.generate(
+ getterExtensionTypeParameters.length,
+ (int index) => new TypeParameterType.forAlphaRenaming(
+ setterExtensionTypeParameters[index],
+ getterExtensionTypeParameters[index])))
+ .substituteType(setterType);
+ }
+ } else {
+ setterType = setterBuilder.procedure.setterType;
+ }
+
+ if (getterType is InvalidType || setterType is InvalidType) {
+ // Don't report a problem as something else is wrong that has already
+ // been reported.
+ } else {
+ bool isValid = typeEnvironment.isSubtypeOf(
+ getterType,
+ setterType,
+ library.isNonNullableByDefault
+ ? SubtypeCheckMode.withNullabilities
+ : SubtypeCheckMode.ignoringNullabilities);
+ if (!isValid && !library.isNonNullableByDefault) {
+ // Allow assignability in legacy libraries.
+ isValid = typeEnvironment.isSubtypeOf(
+ setterType, getterType, SubtypeCheckMode.ignoringNullabilities);
+ }
+ if (!isValid) {
+ String getterMemberName = getterBuilder.fullNameForErrors;
+ String setterMemberName = setterBuilder.fullNameForErrors;
+ Template<Message Function(DartType, String, DartType, String, bool)>
+ template = library.isNonNullableByDefault
+ ? templateInvalidGetterSetterType
+ : templateInvalidGetterSetterTypeLegacy;
+ addProblem(
+ template.withArguments(getterType, getterMemberName, setterType,
+ setterMemberName, library.isNonNullableByDefault),
+ getterBuilder.charOffset,
+ getterBuilder.name.length,
+ getterBuilder.fileUri,
+ context: [
+ templateInvalidGetterSetterTypeSetterContext
+ .withArguments(setterMemberName)
+ .withLocation(setterBuilder.fileUri, setterBuilder.charOffset,
+ setterBuilder.name.length)
+ ]);
+ }
+ }
+ }
+
void addExtensionDeclaration(
String documentationComment,
List<MetadataBuilder> metadata,
@@ -3579,6 +3673,14 @@
checkTypesInField(declaration, typeEnvironment);
} else if (declaration is ProcedureBuilder) {
checkTypesInProcedureBuilder(declaration, typeEnvironment);
+ if (declaration.isGetter) {
+ Builder setterDeclaration =
+ scope.lookupLocalMember(declaration.name, setter: true);
+ if (setterDeclaration != null) {
+ checkGetterSetterTypes(
+ declaration, setterDeclaration, typeEnvironment);
+ }
+ }
} else if (declaration is SourceClassBuilder) {
declaration.checkTypesInOutline(typeEnvironment);
} else if (declaration is SourceExtensionBuilder) {
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index b3c7774..164bb07 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -508,6 +508,14 @@
profile
profiler
propagated
+property2a
+property2b
+property4a
+property4b
+property5a
+property5b
+property8a
+property8b
protected
proved
provider
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart b/pkg/front_end/testcases/extensions/extension_member_conflict.dart
new file mode 100644
index 0000000..ef4e4de
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart
@@ -0,0 +1,66 @@
+// 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.
+
+extension Extension<T> on int {
+ int get duplicateInstanceGetter => 0;
+ int get duplicateInstanceGetter => 0;
+
+ void set duplicateInstanceSetter(int value) {}
+ void set duplicateInstanceSetter(int value) {}
+
+ void duplicateInstanceMethod() {}
+ void duplicateInstanceMethod() {}
+
+ static int duplicateStaticField = 0;
+ static int duplicateStaticField = 0;
+
+ static int get duplicateStaticGetter => 0;
+ static int get duplicateStaticGetter => 0;
+
+ static void set duplicateStaticSetter(int value) {}
+ static void set duplicateStaticSetter(int value) {}
+
+ static void duplicateStaticMethod() {}
+ static void duplicateStaticMethod() {}
+
+ int get duplicateInstanceGetterPlusSetter => 0;
+ int get duplicateInstanceGetterPlusSetter => 0;
+ void set duplicateInstanceGetterPlusSetter(int value) {}
+
+ int get duplicateInstanceSetterPlusGetter => 0;
+ void set duplicateInstanceSetterPlusGetter(int value) {}
+ void set duplicateInstanceSetterPlusGetter(int value) {}
+
+ int get duplicateInstanceGetterAndSetter => 0;
+ int get duplicateInstanceGetterAndSetter => 0;
+ void set duplicateInstanceGetterAndSetter(int value) {}
+ void set duplicateInstanceGetterAndSetter(int value) {}
+
+ static int get duplicateStaticGetterPlusSetter => 0;
+ static int get duplicateStaticGetterPlusSetter => 0;
+ static void set duplicateStaticGetterPlusSetter(int value) {}
+
+ static int get duplicateStaticSetterPlusGetter => 0;
+ static void set duplicateStaticSetterPlusGetter(int value) {}
+ static void set duplicateStaticSetterPlusGetter(int value) {}
+
+ static int get duplicateStaticGetterAndSetter => 0;
+ static int get duplicateStaticGetterAndSetter => 0;
+ static void set duplicateStaticGetterAndSetter(int value) {}
+ static void set duplicateStaticGetterAndSetter(int value) {}
+
+ int get instanceGetterAndStaticSetter => 0;
+ static void set instanceGetterAndStaticSetter(int value) {}
+
+ static int get instanceSetterAndStaticGetter => 0;
+ void set instanceSetterAndStaticGetter(int value) {}
+
+ int get instanceGetterAndStaticField => 0;
+ static int instanceGetterAndStaticField = 0;
+
+ void set instanceSetterAndStaticField(int value) {}
+ static final int instanceGetterAndStaticField = 0;
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.outline.expect b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.outline.expect
new file mode 100644
index 0000000..78e8afc
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.outline.expect
@@ -0,0 +1,223 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:7:11: Error: 'duplicateInstanceGetter' is already declared in this scope.
+// int get duplicateInstanceGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:6:11: Context: Previous declaration of 'duplicateInstanceGetter'.
+// int get duplicateInstanceGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:10:12: Error: 'duplicateInstanceSetter' is already declared in this scope.
+// void set duplicateInstanceSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:9:12: Context: Previous declaration of 'duplicateInstanceSetter'.
+// void set duplicateInstanceSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:13:8: Error: 'duplicateInstanceMethod' is already declared in this scope.
+// void duplicateInstanceMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:12:8: Context: Previous declaration of 'duplicateInstanceMethod'.
+// void duplicateInstanceMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:16:14: Error: 'duplicateStaticField' is already declared in this scope.
+// static int duplicateStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:15:14: Context: Previous declaration of 'duplicateStaticField'.
+// static int duplicateStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:19:18: Error: 'duplicateStaticGetter' is already declared in this scope.
+// static int get duplicateStaticGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:18:18: Context: Previous declaration of 'duplicateStaticGetter'.
+// static int get duplicateStaticGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:22:19: Error: 'duplicateStaticSetter' is already declared in this scope.
+// static void set duplicateStaticSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:21:19: Context: Previous declaration of 'duplicateStaticSetter'.
+// static void set duplicateStaticSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:25:15: Error: 'duplicateStaticMethod' is already declared in this scope.
+// static void duplicateStaticMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:24:15: Context: Previous declaration of 'duplicateStaticMethod'.
+// static void duplicateStaticMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:28:11: Error: 'duplicateInstanceGetterPlusSetter' is already declared in this scope.
+// int get duplicateInstanceGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:27:11: Context: Previous declaration of 'duplicateInstanceGetterPlusSetter'.
+// int get duplicateInstanceGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:33:12: Error: 'duplicateInstanceSetterPlusGetter' is already declared in this scope.
+// void set duplicateInstanceSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:32:12: Context: Previous declaration of 'duplicateInstanceSetterPlusGetter'.
+// void set duplicateInstanceSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:36:11: Error: 'duplicateInstanceGetterAndSetter' is already declared in this scope.
+// int get duplicateInstanceGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:35:11: Context: Previous declaration of 'duplicateInstanceGetterAndSetter'.
+// int get duplicateInstanceGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:38:12: Error: 'duplicateInstanceGetterAndSetter' is already declared in this scope.
+// void set duplicateInstanceGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:37:12: Context: Previous declaration of 'duplicateInstanceGetterAndSetter'.
+// void set duplicateInstanceGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:41:18: Error: 'duplicateStaticGetterPlusSetter' is already declared in this scope.
+// static int get duplicateStaticGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:40:18: Context: Previous declaration of 'duplicateStaticGetterPlusSetter'.
+// static int get duplicateStaticGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:46:19: Error: 'duplicateStaticSetterPlusGetter' is already declared in this scope.
+// static void set duplicateStaticSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:45:19: Context: Previous declaration of 'duplicateStaticSetterPlusGetter'.
+// static void set duplicateStaticSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:49:18: Error: 'duplicateStaticGetterAndSetter' is already declared in this scope.
+// static int get duplicateStaticGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:48:18: Context: Previous declaration of 'duplicateStaticGetterAndSetter'.
+// static int get duplicateStaticGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:51:19: Error: 'duplicateStaticGetterAndSetter' is already declared in this scope.
+// static void set duplicateStaticGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:50:19: Context: Previous declaration of 'duplicateStaticGetterAndSetter'.
+// static void set duplicateStaticGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:60:14: Error: 'instanceGetterAndStaticField' is already declared in this scope.
+// static int instanceGetterAndStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:59:11: Context: Previous declaration of 'instanceGetterAndStaticField'.
+// int get instanceGetterAndStaticField => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:63:20: Error: 'instanceGetterAndStaticField' is already declared in this scope.
+// static final int instanceGetterAndStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:60:14: Context: Previous declaration of 'instanceGetterAndStaticField'.
+// static int instanceGetterAndStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:54:19: Error: Conflicts with member 'instanceGetterAndStaticSetter'.
+// static void set instanceGetterAndStaticSetter(int value) {}
+// ^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:53:11: Error: Conflicts with setter 'instanceGetterAndStaticSetter'.
+// int get instanceGetterAndStaticSetter => 0;
+// ^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:57:12: Error: Conflicts with member 'instanceSetterAndStaticGetter'.
+// void set instanceSetterAndStaticGetter(int value) {}
+// ^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:56:18: Error: Conflicts with setter 'instanceSetterAndStaticGetter'.
+// static int get instanceSetterAndStaticGetter => 0;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+extension Extension<T extends core::Object* = dynamic> on core::int* {
+ get duplicateInstanceGetter = self::Extension|get#duplicateInstanceGetter;
+ method duplicateInstanceMethod = self::Extension|duplicateInstanceMethod;
+ tearoff duplicateInstanceMethod = self::Extension|get#duplicateInstanceMethod;
+ static field duplicateStaticField = self::Extension|duplicateStaticField;
+ static get duplicateStaticGetter = get self::Extension|duplicateStaticGetter;
+ static method duplicateStaticMethod = self::Extension|duplicateStaticMethod;
+ get duplicateInstanceGetterPlusSetter = self::Extension|get#duplicateInstanceGetterPlusSetter;
+ get duplicateInstanceSetterPlusGetter = self::Extension|get#duplicateInstanceSetterPlusGetter;
+ get duplicateInstanceGetterAndSetter = self::Extension|get#duplicateInstanceGetterAndSetter;
+ static get duplicateStaticGetterPlusSetter = get self::Extension|duplicateStaticGetterPlusSetter;
+ static get duplicateStaticSetterPlusGetter = get self::Extension|duplicateStaticSetterPlusGetter;
+ static get duplicateStaticGetterAndSetter = get self::Extension|duplicateStaticGetterAndSetter;
+ get instanceGetterAndStaticSetter = self::Extension|get#instanceGetterAndStaticSetter;
+ static get instanceSetterAndStaticGetter = get self::Extension|instanceSetterAndStaticGetter;
+ get instanceGetterAndStaticField = self::Extension|get#instanceGetterAndStaticField;
+ set duplicateInstanceSetter = self::Extension|set#duplicateInstanceSetter;
+ static set duplicateStaticSetter = set self::Extension|duplicateStaticSetter;
+ set duplicateInstanceGetterPlusSetter = self::Extension|set#duplicateInstanceGetterPlusSetter;
+ set duplicateInstanceSetterPlusGetter = self::Extension|set#duplicateInstanceSetterPlusGetter;
+ set duplicateInstanceGetterAndSetter = self::Extension|set#duplicateInstanceGetterAndSetter;
+ static set duplicateStaticGetterPlusSetter = set self::Extension|duplicateStaticGetterPlusSetter;
+ static set duplicateStaticSetterPlusGetter = set self::Extension|duplicateStaticSetterPlusGetter;
+ static set duplicateStaticGetterAndSetter = set self::Extension|duplicateStaticGetterAndSetter;
+ static set instanceGetterAndStaticSetter = set self::Extension|instanceGetterAndStaticSetter;
+ set instanceSetterAndStaticGetter = self::Extension|set#instanceSetterAndStaticGetter;
+ set instanceSetterAndStaticField = self::Extension|set#instanceSetterAndStaticField;
+}
+static field core::int* Extension|duplicateStaticField;
+static method Extension|get#duplicateInstanceGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ ;
+static method Extension|set#duplicateInstanceSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+ ;
+static method Extension|duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → void
+ ;
+static method Extension|get#duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → () →* void
+ return () → void => self::Extension|duplicateInstanceMethod<self::Extension|get#duplicateInstanceMethod::T*>(#this);
+static get Extension|duplicateStaticGetter() → core::int*
+ ;
+static set Extension|duplicateStaticSetter(core::int* value) → void
+ ;
+static method Extension|duplicateStaticMethod() → void
+ ;
+static method Extension|get#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ ;
+static method Extension|set#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+ ;
+static method Extension|get#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ ;
+static method Extension|set#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+ ;
+static method Extension|get#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ ;
+static method Extension|set#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+ ;
+static get Extension|duplicateStaticGetterPlusSetter() → core::int*
+ ;
+static set Extension|duplicateStaticGetterPlusSetter(core::int* value) → void
+ ;
+static get Extension|duplicateStaticSetterPlusGetter() → core::int*
+ ;
+static set Extension|duplicateStaticSetterPlusGetter(core::int* value) → void
+ ;
+static get Extension|duplicateStaticGetterAndSetter() → core::int*
+ ;
+static set Extension|duplicateStaticGetterAndSetter(core::int* value) → void
+ ;
+static method Extension|get#instanceGetterAndStaticSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ ;
+static set Extension|instanceGetterAndStaticSetter(core::int* value) → void
+ ;
+static get Extension|instanceSetterAndStaticGetter() → core::int*
+ ;
+static method Extension|set#instanceSetterAndStaticGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+ ;
+static method Extension|get#instanceGetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ ;
+static method Extension|set#instanceSetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.expect b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.expect
new file mode 100644
index 0000000..52aa6f4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.expect
@@ -0,0 +1,209 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:7:11: Error: 'duplicateInstanceGetter' is already declared in this scope.
+// int get duplicateInstanceGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:6:11: Context: Previous declaration of 'duplicateInstanceGetter'.
+// int get duplicateInstanceGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:10:12: Error: 'duplicateInstanceSetter' is already declared in this scope.
+// void set duplicateInstanceSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:9:12: Context: Previous declaration of 'duplicateInstanceSetter'.
+// void set duplicateInstanceSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:13:8: Error: 'duplicateInstanceMethod' is already declared in this scope.
+// void duplicateInstanceMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:12:8: Context: Previous declaration of 'duplicateInstanceMethod'.
+// void duplicateInstanceMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:16:14: Error: 'duplicateStaticField' is already declared in this scope.
+// static int duplicateStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:15:14: Context: Previous declaration of 'duplicateStaticField'.
+// static int duplicateStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:19:18: Error: 'duplicateStaticGetter' is already declared in this scope.
+// static int get duplicateStaticGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:18:18: Context: Previous declaration of 'duplicateStaticGetter'.
+// static int get duplicateStaticGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:22:19: Error: 'duplicateStaticSetter' is already declared in this scope.
+// static void set duplicateStaticSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:21:19: Context: Previous declaration of 'duplicateStaticSetter'.
+// static void set duplicateStaticSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:25:15: Error: 'duplicateStaticMethod' is already declared in this scope.
+// static void duplicateStaticMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:24:15: Context: Previous declaration of 'duplicateStaticMethod'.
+// static void duplicateStaticMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:28:11: Error: 'duplicateInstanceGetterPlusSetter' is already declared in this scope.
+// int get duplicateInstanceGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:27:11: Context: Previous declaration of 'duplicateInstanceGetterPlusSetter'.
+// int get duplicateInstanceGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:33:12: Error: 'duplicateInstanceSetterPlusGetter' is already declared in this scope.
+// void set duplicateInstanceSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:32:12: Context: Previous declaration of 'duplicateInstanceSetterPlusGetter'.
+// void set duplicateInstanceSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:36:11: Error: 'duplicateInstanceGetterAndSetter' is already declared in this scope.
+// int get duplicateInstanceGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:35:11: Context: Previous declaration of 'duplicateInstanceGetterAndSetter'.
+// int get duplicateInstanceGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:38:12: Error: 'duplicateInstanceGetterAndSetter' is already declared in this scope.
+// void set duplicateInstanceGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:37:12: Context: Previous declaration of 'duplicateInstanceGetterAndSetter'.
+// void set duplicateInstanceGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:41:18: Error: 'duplicateStaticGetterPlusSetter' is already declared in this scope.
+// static int get duplicateStaticGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:40:18: Context: Previous declaration of 'duplicateStaticGetterPlusSetter'.
+// static int get duplicateStaticGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:46:19: Error: 'duplicateStaticSetterPlusGetter' is already declared in this scope.
+// static void set duplicateStaticSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:45:19: Context: Previous declaration of 'duplicateStaticSetterPlusGetter'.
+// static void set duplicateStaticSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:49:18: Error: 'duplicateStaticGetterAndSetter' is already declared in this scope.
+// static int get duplicateStaticGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:48:18: Context: Previous declaration of 'duplicateStaticGetterAndSetter'.
+// static int get duplicateStaticGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:51:19: Error: 'duplicateStaticGetterAndSetter' is already declared in this scope.
+// static void set duplicateStaticGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:50:19: Context: Previous declaration of 'duplicateStaticGetterAndSetter'.
+// static void set duplicateStaticGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:60:14: Error: 'instanceGetterAndStaticField' is already declared in this scope.
+// static int instanceGetterAndStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:59:11: Context: Previous declaration of 'instanceGetterAndStaticField'.
+// int get instanceGetterAndStaticField => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:63:20: Error: 'instanceGetterAndStaticField' is already declared in this scope.
+// static final int instanceGetterAndStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:60:14: Context: Previous declaration of 'instanceGetterAndStaticField'.
+// static int instanceGetterAndStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:54:19: Error: Conflicts with member 'instanceGetterAndStaticSetter'.
+// static void set instanceGetterAndStaticSetter(int value) {}
+// ^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:53:11: Error: Conflicts with setter 'instanceGetterAndStaticSetter'.
+// int get instanceGetterAndStaticSetter => 0;
+// ^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:57:12: Error: Conflicts with member 'instanceSetterAndStaticGetter'.
+// void set instanceSetterAndStaticGetter(int value) {}
+// ^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:56:18: Error: Conflicts with setter 'instanceSetterAndStaticGetter'.
+// static int get instanceSetterAndStaticGetter => 0;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+extension Extension<T extends core::Object* = dynamic> on core::int* {
+ get duplicateInstanceGetter = self::Extension|get#duplicateInstanceGetter;
+ method duplicateInstanceMethod = self::Extension|duplicateInstanceMethod;
+ tearoff duplicateInstanceMethod = self::Extension|get#duplicateInstanceMethod;
+ static field duplicateStaticField = self::Extension|duplicateStaticField;
+ static get duplicateStaticGetter = get self::Extension|duplicateStaticGetter;
+ static method duplicateStaticMethod = self::Extension|duplicateStaticMethod;
+ get duplicateInstanceGetterPlusSetter = self::Extension|get#duplicateInstanceGetterPlusSetter;
+ get duplicateInstanceSetterPlusGetter = self::Extension|get#duplicateInstanceSetterPlusGetter;
+ get duplicateInstanceGetterAndSetter = self::Extension|get#duplicateInstanceGetterAndSetter;
+ static get duplicateStaticGetterPlusSetter = get self::Extension|duplicateStaticGetterPlusSetter;
+ static get duplicateStaticSetterPlusGetter = get self::Extension|duplicateStaticSetterPlusGetter;
+ static get duplicateStaticGetterAndSetter = get self::Extension|duplicateStaticGetterAndSetter;
+ get instanceGetterAndStaticSetter = self::Extension|get#instanceGetterAndStaticSetter;
+ static get instanceSetterAndStaticGetter = get self::Extension|instanceSetterAndStaticGetter;
+ get instanceGetterAndStaticField = self::Extension|get#instanceGetterAndStaticField;
+ set duplicateInstanceSetter = self::Extension|set#duplicateInstanceSetter;
+ static set duplicateStaticSetter = set self::Extension|duplicateStaticSetter;
+ set duplicateInstanceGetterPlusSetter = self::Extension|set#duplicateInstanceGetterPlusSetter;
+ set duplicateInstanceSetterPlusGetter = self::Extension|set#duplicateInstanceSetterPlusGetter;
+ set duplicateInstanceGetterAndSetter = self::Extension|set#duplicateInstanceGetterAndSetter;
+ static set duplicateStaticGetterPlusSetter = set self::Extension|duplicateStaticGetterPlusSetter;
+ static set duplicateStaticSetterPlusGetter = set self::Extension|duplicateStaticSetterPlusGetter;
+ static set duplicateStaticGetterAndSetter = set self::Extension|duplicateStaticGetterAndSetter;
+ static set instanceGetterAndStaticSetter = set self::Extension|instanceGetterAndStaticSetter;
+ set instanceSetterAndStaticGetter = self::Extension|set#instanceSetterAndStaticGetter;
+ set instanceSetterAndStaticField = self::Extension|set#instanceSetterAndStaticField;
+}
+static field core::int* Extension|duplicateStaticField;
+static method Extension|get#duplicateInstanceGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#duplicateInstanceSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → void {}
+static method Extension|get#duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → () →* void
+ return () → void => self::Extension|duplicateInstanceMethod<self::Extension|get#duplicateInstanceMethod::T*>(#this);
+static get Extension|duplicateStaticGetter() → core::int*
+ return 0;
+static set Extension|duplicateStaticSetter(core::int* value) → void {}
+static method Extension|duplicateStaticMethod() → void {}
+static method Extension|get#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|get#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|get#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static get Extension|duplicateStaticGetterPlusSetter() → core::int*
+ return 0;
+static set Extension|duplicateStaticGetterPlusSetter(core::int* value) → void {}
+static get Extension|duplicateStaticSetterPlusGetter() → core::int*
+ return 0;
+static set Extension|duplicateStaticSetterPlusGetter(core::int* value) → void {}
+static get Extension|duplicateStaticGetterAndSetter() → core::int*
+ return 0;
+static set Extension|duplicateStaticGetterAndSetter(core::int* value) → void {}
+static method Extension|get#instanceGetterAndStaticSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static set Extension|instanceGetterAndStaticSetter(core::int* value) → void {}
+static get Extension|instanceSetterAndStaticGetter() → core::int*
+ return 0;
+static method Extension|set#instanceSetterAndStaticGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|get#instanceGetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#instanceSetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.transformed.expect b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.transformed.expect
new file mode 100644
index 0000000..52aa6f4
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.strong.transformed.expect
@@ -0,0 +1,209 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:7:11: Error: 'duplicateInstanceGetter' is already declared in this scope.
+// int get duplicateInstanceGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:6:11: Context: Previous declaration of 'duplicateInstanceGetter'.
+// int get duplicateInstanceGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:10:12: Error: 'duplicateInstanceSetter' is already declared in this scope.
+// void set duplicateInstanceSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:9:12: Context: Previous declaration of 'duplicateInstanceSetter'.
+// void set duplicateInstanceSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:13:8: Error: 'duplicateInstanceMethod' is already declared in this scope.
+// void duplicateInstanceMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:12:8: Context: Previous declaration of 'duplicateInstanceMethod'.
+// void duplicateInstanceMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:16:14: Error: 'duplicateStaticField' is already declared in this scope.
+// static int duplicateStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:15:14: Context: Previous declaration of 'duplicateStaticField'.
+// static int duplicateStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:19:18: Error: 'duplicateStaticGetter' is already declared in this scope.
+// static int get duplicateStaticGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:18:18: Context: Previous declaration of 'duplicateStaticGetter'.
+// static int get duplicateStaticGetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:22:19: Error: 'duplicateStaticSetter' is already declared in this scope.
+// static void set duplicateStaticSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:21:19: Context: Previous declaration of 'duplicateStaticSetter'.
+// static void set duplicateStaticSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:25:15: Error: 'duplicateStaticMethod' is already declared in this scope.
+// static void duplicateStaticMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:24:15: Context: Previous declaration of 'duplicateStaticMethod'.
+// static void duplicateStaticMethod() {}
+// ^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:28:11: Error: 'duplicateInstanceGetterPlusSetter' is already declared in this scope.
+// int get duplicateInstanceGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:27:11: Context: Previous declaration of 'duplicateInstanceGetterPlusSetter'.
+// int get duplicateInstanceGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:33:12: Error: 'duplicateInstanceSetterPlusGetter' is already declared in this scope.
+// void set duplicateInstanceSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:32:12: Context: Previous declaration of 'duplicateInstanceSetterPlusGetter'.
+// void set duplicateInstanceSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:36:11: Error: 'duplicateInstanceGetterAndSetter' is already declared in this scope.
+// int get duplicateInstanceGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:35:11: Context: Previous declaration of 'duplicateInstanceGetterAndSetter'.
+// int get duplicateInstanceGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:38:12: Error: 'duplicateInstanceGetterAndSetter' is already declared in this scope.
+// void set duplicateInstanceGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:37:12: Context: Previous declaration of 'duplicateInstanceGetterAndSetter'.
+// void set duplicateInstanceGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:41:18: Error: 'duplicateStaticGetterPlusSetter' is already declared in this scope.
+// static int get duplicateStaticGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:40:18: Context: Previous declaration of 'duplicateStaticGetterPlusSetter'.
+// static int get duplicateStaticGetterPlusSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:46:19: Error: 'duplicateStaticSetterPlusGetter' is already declared in this scope.
+// static void set duplicateStaticSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:45:19: Context: Previous declaration of 'duplicateStaticSetterPlusGetter'.
+// static void set duplicateStaticSetterPlusGetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:49:18: Error: 'duplicateStaticGetterAndSetter' is already declared in this scope.
+// static int get duplicateStaticGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:48:18: Context: Previous declaration of 'duplicateStaticGetterAndSetter'.
+// static int get duplicateStaticGetterAndSetter => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:51:19: Error: 'duplicateStaticGetterAndSetter' is already declared in this scope.
+// static void set duplicateStaticGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:50:19: Context: Previous declaration of 'duplicateStaticGetterAndSetter'.
+// static void set duplicateStaticGetterAndSetter(int value) {}
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:60:14: Error: 'instanceGetterAndStaticField' is already declared in this scope.
+// static int instanceGetterAndStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:59:11: Context: Previous declaration of 'instanceGetterAndStaticField'.
+// int get instanceGetterAndStaticField => 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:63:20: Error: 'instanceGetterAndStaticField' is already declared in this scope.
+// static final int instanceGetterAndStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:60:14: Context: Previous declaration of 'instanceGetterAndStaticField'.
+// static int instanceGetterAndStaticField = 0;
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:54:19: Error: Conflicts with member 'instanceGetterAndStaticSetter'.
+// static void set instanceGetterAndStaticSetter(int value) {}
+// ^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:53:11: Error: Conflicts with setter 'instanceGetterAndStaticSetter'.
+// int get instanceGetterAndStaticSetter => 0;
+// ^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:57:12: Error: Conflicts with member 'instanceSetterAndStaticGetter'.
+// void set instanceSetterAndStaticGetter(int value) {}
+// ^
+//
+// pkg/front_end/testcases/extensions/extension_member_conflict.dart:56:18: Error: Conflicts with setter 'instanceSetterAndStaticGetter'.
+// static int get instanceSetterAndStaticGetter => 0;
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+extension Extension<T extends core::Object* = dynamic> on core::int* {
+ get duplicateInstanceGetter = self::Extension|get#duplicateInstanceGetter;
+ method duplicateInstanceMethod = self::Extension|duplicateInstanceMethod;
+ tearoff duplicateInstanceMethod = self::Extension|get#duplicateInstanceMethod;
+ static field duplicateStaticField = self::Extension|duplicateStaticField;
+ static get duplicateStaticGetter = get self::Extension|duplicateStaticGetter;
+ static method duplicateStaticMethod = self::Extension|duplicateStaticMethod;
+ get duplicateInstanceGetterPlusSetter = self::Extension|get#duplicateInstanceGetterPlusSetter;
+ get duplicateInstanceSetterPlusGetter = self::Extension|get#duplicateInstanceSetterPlusGetter;
+ get duplicateInstanceGetterAndSetter = self::Extension|get#duplicateInstanceGetterAndSetter;
+ static get duplicateStaticGetterPlusSetter = get self::Extension|duplicateStaticGetterPlusSetter;
+ static get duplicateStaticSetterPlusGetter = get self::Extension|duplicateStaticSetterPlusGetter;
+ static get duplicateStaticGetterAndSetter = get self::Extension|duplicateStaticGetterAndSetter;
+ get instanceGetterAndStaticSetter = self::Extension|get#instanceGetterAndStaticSetter;
+ static get instanceSetterAndStaticGetter = get self::Extension|instanceSetterAndStaticGetter;
+ get instanceGetterAndStaticField = self::Extension|get#instanceGetterAndStaticField;
+ set duplicateInstanceSetter = self::Extension|set#duplicateInstanceSetter;
+ static set duplicateStaticSetter = set self::Extension|duplicateStaticSetter;
+ set duplicateInstanceGetterPlusSetter = self::Extension|set#duplicateInstanceGetterPlusSetter;
+ set duplicateInstanceSetterPlusGetter = self::Extension|set#duplicateInstanceSetterPlusGetter;
+ set duplicateInstanceGetterAndSetter = self::Extension|set#duplicateInstanceGetterAndSetter;
+ static set duplicateStaticGetterPlusSetter = set self::Extension|duplicateStaticGetterPlusSetter;
+ static set duplicateStaticSetterPlusGetter = set self::Extension|duplicateStaticSetterPlusGetter;
+ static set duplicateStaticGetterAndSetter = set self::Extension|duplicateStaticGetterAndSetter;
+ static set instanceGetterAndStaticSetter = set self::Extension|instanceGetterAndStaticSetter;
+ set instanceSetterAndStaticGetter = self::Extension|set#instanceSetterAndStaticGetter;
+ set instanceSetterAndStaticField = self::Extension|set#instanceSetterAndStaticField;
+}
+static field core::int* Extension|duplicateStaticField;
+static method Extension|get#duplicateInstanceGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#duplicateInstanceSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → void {}
+static method Extension|get#duplicateInstanceMethod<T extends core::Object* = dynamic>(final core::int* #this) → () →* void
+ return () → void => self::Extension|duplicateInstanceMethod<self::Extension|get#duplicateInstanceMethod::T*>(#this);
+static get Extension|duplicateStaticGetter() → core::int*
+ return 0;
+static set Extension|duplicateStaticSetter(core::int* value) → void {}
+static method Extension|duplicateStaticMethod() → void {}
+static method Extension|get#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#duplicateInstanceGetterPlusSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|get#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#duplicateInstanceSetterPlusGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|get#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#duplicateInstanceGetterAndSetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static get Extension|duplicateStaticGetterPlusSetter() → core::int*
+ return 0;
+static set Extension|duplicateStaticGetterPlusSetter(core::int* value) → void {}
+static get Extension|duplicateStaticSetterPlusGetter() → core::int*
+ return 0;
+static set Extension|duplicateStaticSetterPlusGetter(core::int* value) → void {}
+static get Extension|duplicateStaticGetterAndSetter() → core::int*
+ return 0;
+static set Extension|duplicateStaticGetterAndSetter(core::int* value) → void {}
+static method Extension|get#instanceGetterAndStaticSetter<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static set Extension|instanceGetterAndStaticSetter(core::int* value) → void {}
+static get Extension|instanceSetterAndStaticGetter() → core::int*
+ return 0;
+static method Extension|set#instanceSetterAndStaticGetter<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method Extension|get#instanceGetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#instanceSetterAndStaticField<T extends core::Object* = dynamic>(final core::int* #this, core::int* value) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline.expect b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline.expect
new file mode 100644
index 0000000..6d262f3
--- /dev/null
+++ b/pkg/front_end/testcases/extensions/extension_member_conflict.dart.textual_outline.expect
@@ -0,0 +1,3 @@
+extension Extension<T> (){}
+on int (){}
+main() {}
diff --git a/pkg/front_end/testcases/general/getter_vs_setter_type.dart b/pkg/front_end/testcases/general/getter_vs_setter_type.dart
index 2f92b93..4be746d 100644
--- a/pkg/front_end/testcases/general/getter_vs_setter_type.dart
+++ b/pkg/front_end/testcases/general/getter_vs_setter_type.dart
@@ -6,8 +6,11 @@
int get property1; // ok
void set property1(int i);
- int get property2; // ok
- void set property2(int i);
+ num get property2a; // ok
+ void set property2a(int i);
+
+ int get property2b; // ok
+ void set property2b(num i);
String get property3; // error
void set property3(int i);
@@ -17,6 +20,18 @@
int property5; // ok
covariant String property6; // ok
+
+ static int get property7 => 0; // ok
+ static void set property7(int value) {}
+
+ static int get property8a => 0; // ok
+ static void set property8a(num value) {}
+
+ static num get property8b => 0; // ok
+ static void set property8b(int value) {}
+
+ static num get property9 => 0; // error
+ static void set property9(String value) {}
}
abstract class B1 {
@@ -102,4 +117,42 @@
abstract class D4
implements D3 /* no need for error on property2 and property3 */ {}
+extension Extension<T extends num, S extends T> on int {
+ int get property1 => 0; // ok
+ void set property1(int i) {}
+
+ num get property2a => 0; // ok
+ void set property2a(int i) {}
+
+ int get property2b => 0; // ok
+ void set property2b(num i) {}
+
+ String get property3 => ''; // error
+ void set property3(int i) {}
+
+ S get property4 => 0; // ok
+ void set property4(S i) {}
+
+ S get property5a => 0; // ok
+ void set property5a(T i) {}
+
+ T get property5b => 0; // ok
+ void set property5b(S i) {}
+
+ String get property6 => ''; // error
+ void set property6(S i) {}
+
+ static int get property7 => 0; // ok
+ static void set property7(int value) {}
+
+ static int get property8a => 0; // ok
+ static void set property8a(num value) {}
+
+ static num get property8b => 0; // ok
+ static void set property8b(int value) {}
+
+ static num get property9 => 0; // error
+ static void set property9(String value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.outline.expect b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.outline.expect
index d0db1ea..f255528 100644
--- a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.outline.expect
+++ b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.outline.expect
@@ -2,125 +2,153 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:12:14: Error: The type 'String' of the getter 'A.property3' is not assignable to the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:15:14: Error: The type 'String' of the getter 'A.property3' is not assignable to the type 'int' of the setter 'A.property3'.
// String get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:13:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:16:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:41:12: Error: The type 'int' of the inherited getter 'B1.property2' is not assignable to the type 'String' of the setter 'B2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:33:18: Error: The type 'num' of the getter 'A.property9' is not assignable to the type 'String' of the setter 'A.property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:34:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(String value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:56:12: Error: The type 'int' of the inherited getter 'B1.property2' is not assignable to the type 'String' of the setter 'B2.property2'.
// void set property2(String i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:25:11: Context: This is the declaration of the getter 'B1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:40:11: Context: This is the declaration of the getter 'B1.property2'.
// int get property2;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:43:12: Error: The type 'String' of the inherited getter 'B1.property3' is not assignable to the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:58:12: Error: The type 'String' of the inherited getter 'B1.property3' is not assignable to the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:27:14: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:42:14: Context: This is the declaration of the getter 'B1.property3'.
// String get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:47:12: Error: The type 'int' of the inherited field 'B1.property5' is not assignable to the type 'String' of the setter 'B2.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:62:12: Error: The type 'int' of the inherited field 'B1.property5' is not assignable to the type 'String' of the setter 'B2.property5'.
// void set property5(String i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:31:13: Context: This is the declaration of the field 'B1.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:46:13: Context: This is the declaration of the field 'B1.property5'.
// final int property5;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:49:12: Error: The type 'String' of the inherited field 'B1.property6' is not assignable to the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:64:12: Error: The type 'String' of the inherited field 'B1.property6' is not assignable to the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:33:16: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:48:16: Context: This is the declaration of the field 'B1.property6'.
// final String property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:69:11: Error: The type 'int' of the getter 'C2.property2' is not assignable to the type 'String' of the inherited setter 'C1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:84:11: Error: The type 'int' of the getter 'C2.property2' is not assignable to the type 'String' of the inherited setter 'C1.property2'.
// int get property2; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:55:12: Context: This is the declaration of the setter 'C1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:70:12: Context: This is the declaration of the setter 'C1.property2'.
// void set property2(String i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:71:14: Error: The type 'String' of the getter 'C2.property3' is not assignable to the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:86:14: Error: The type 'String' of the getter 'C2.property3' is not assignable to the type 'int' of the inherited setter 'C1.property3'.
// String get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:57:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:72:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:77:11: Error: The return type of the method 'C2.property5' is 'int', which does not match the return type, 'String', of the overridden method, 'C1.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:92:11: Error: The return type of the method 'C2.property5' is 'int', which does not match the return type, 'String', of the overridden method, 'C1.property5'.
// Change to a subtype of 'String'.
// int get property5; // error
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:61:10: Context: This is the overridden method ('property5').
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:76:10: Context: This is the overridden method ('property5').
// String property5;
// ^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:77:11: Error: The type 'int' of the getter 'C2.property5' is not assignable to the type 'String' of the inherited setter 'C1.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:92:11: Error: The type 'int' of the getter 'C2.property5' is not assignable to the type 'String' of the inherited setter 'C1.property5'.
// int get property5; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:61:10: Context: This is the declaration of the setter 'C1.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:76:10: Context: This is the declaration of the setter 'C1.property5'.
// String property5;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:81:14: Error: The return type of the method 'C2.property6' is 'String', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:96:14: Error: The return type of the method 'C2.property6' is 'String', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// String get property6; // error
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:63:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:78:7: Context: This is the overridden method ('property6').
// int property6;
// ^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:81:14: Error: The type 'String' of the getter 'C2.property6' is not assignable to the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:96:14: Error: The type 'String' of the getter 'C2.property6' is not assignable to the type 'int' of the inherited setter 'C1.property6'.
// String get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:63:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:78:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:100:16: Error: The type 'int' of the inherited getter 'D1.property2' is not assignable to the type 'String' of the inherited setter 'D2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:115:16: Error: The type 'int' of the inherited getter 'D1.property2' is not assignable to the type 'String' of the inherited setter 'D2.property2'.
// abstract class D3 implements D1, D2 /* error on property2 and property3 */ {}
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:102:11: Context: This is the declaration of the getter 'D1.property2'.
// int get property2;
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:110:12: Context: This is the declaration of the setter 'D2.property2'.
// void set property2(String i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:100:16: Error: The type 'String' of the inherited getter 'D1.property3' is not assignable to the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:115:16: Error: The type 'String' of the inherited getter 'D1.property3' is not assignable to the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property2 and property3 */ {}
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:89:14: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:104:14: Context: This is the declaration of the getter 'D1.property3'.
// String get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:97:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:112:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:102:16: Error: The type 'int' of the inherited getter 'D1.property2' is not assignable to the type 'String' of the inherited setter 'D2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:117:16: Error: The type 'int' of the inherited getter 'D1.property2' is not assignable to the type 'String' of the inherited setter 'D2.property2'.
// abstract class D4
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:102:11: Context: This is the declaration of the getter 'D1.property2'.
// int get property2;
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:110:12: Context: This is the declaration of the setter 'D2.property2'.
// void set property2(String i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:102:16: Error: The type 'String' of the inherited getter 'D1.property3' is not assignable to the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:117:16: Error: The type 'String' of the inherited getter 'D1.property3' is not assignable to the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:89:14: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:104:14: Context: This is the declaration of the getter 'D1.property3'.
// String get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:97:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:112:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:130:14: Error: The type 'String' of the getter 'property3' is not assignable to the type 'int' of the setter 'property3'.
+// String get property3 => ''; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:131:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:142:14: Error: The type 'String' of the getter 'property6' is not assignable to the type 'S' of the setter 'property6'.
+// String get property6 => ''; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:143:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(S i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:154:18: Error: The type 'num' of the getter 'property9' is not assignable to the type 'String' of the setter 'property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:155:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(String value) {}
+// ^^^^^^^^^
+//
import self as self;
import "dart:core" as core;
@@ -132,10 +160,28 @@
;
abstract get property1() → core::int*;
abstract set property1(core::int* i) → void;
- abstract get property2() → core::int*;
- abstract set property2(core::int* i) → void;
+ abstract get property2a() → core::num*;
+ abstract set property2a(core::int* i) → void;
+ abstract get property2b() → core::int*;
+ abstract set property2b(core::num* i) → void;
abstract get property3() → core::String*;
abstract set property3(core::int* i) → void;
+ static get property7() → core::int*
+ ;
+ static set property7(core::int* value) → void
+ ;
+ static get property8a() → core::int*
+ ;
+ static set property8a(core::num* value) → void
+ ;
+ static get property8b() → core::num*
+ ;
+ static set property8b(core::int* value) → void
+ ;
+ static get property9() → core::num*
+ ;
+ static set property9(core::String* value) → void
+ ;
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
@@ -289,5 +335,79 @@
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
+extension Extension<T extends core::num* = core::num*, S extends T* = core::num*> on core::int* {
+ get property1 = self::Extension|get#property1;
+ get property2a = self::Extension|get#property2a;
+ get property2b = self::Extension|get#property2b;
+ get property3 = self::Extension|get#property3;
+ get property4 = self::Extension|get#property4;
+ get property5a = self::Extension|get#property5a;
+ get property5b = self::Extension|get#property5b;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8a = get self::Extension|property8a;
+ static get property8b = get self::Extension|property8b;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2a = self::Extension|set#property2a;
+ set property2b = self::Extension|set#property2b;
+ set property3 = self::Extension|set#property3;
+ set property4 = self::Extension|set#property4;
+ set property5a = self::Extension|set#property5a;
+ set property5b = self::Extension|set#property5b;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8a = set self::Extension|property8a;
+ static set property8b = set self::Extension|property8b;
+ static set property9 = set self::Extension|property9;
+}
+static method Extension|get#property1<T extends core::num* = core::num*, S extends self::Extension|get#property1::T* = core::num*>(final core::int* #this) → core::int*
+ ;
+static method Extension|set#property1<T extends core::num* = core::num*, S extends self::Extension|set#property1::T* = core::num*>(final core::int* #this, core::int* i) → void
+ ;
+static method Extension|get#property2a<T extends core::num* = core::num*, S extends self::Extension|get#property2a::T* = core::num*>(final core::int* #this) → core::num*
+ ;
+static method Extension|set#property2a<T extends core::num* = core::num*, S extends self::Extension|set#property2a::T* = core::num*>(final core::int* #this, core::int* i) → void
+ ;
+static method Extension|get#property2b<T extends core::num* = core::num*, S extends self::Extension|get#property2b::T* = core::num*>(final core::int* #this) → core::int*
+ ;
+static method Extension|set#property2b<T extends core::num* = core::num*, S extends self::Extension|set#property2b::T* = core::num*>(final core::int* #this, core::num* i) → void
+ ;
+static method Extension|get#property3<T extends core::num* = core::num*, S extends self::Extension|get#property3::T* = core::num*>(final core::int* #this) → core::String*
+ ;
+static method Extension|set#property3<T extends core::num* = core::num*, S extends self::Extension|set#property3::T* = core::num*>(final core::int* #this, core::int* i) → void
+ ;
+static method Extension|get#property4<T extends core::num* = core::num*, S extends self::Extension|get#property4::T* = core::num*>(final core::int* #this) → self::Extension|get#property4::S*
+ ;
+static method Extension|set#property4<T extends core::num* = core::num*, S extends self::Extension|set#property4::T* = core::num*>(final core::int* #this, self::Extension|set#property4::S* i) → void
+ ;
+static method Extension|get#property5a<T extends core::num* = core::num*, S extends self::Extension|get#property5a::T* = core::num*>(final core::int* #this) → self::Extension|get#property5a::S*
+ ;
+static method Extension|set#property5a<T extends core::num* = core::num*, S extends self::Extension|set#property5a::T* = core::num*>(final core::int* #this, self::Extension|set#property5a::T* i) → void
+ ;
+static method Extension|get#property5b<T extends core::num* = core::num*, S extends self::Extension|get#property5b::T* = core::num*>(final core::int* #this) → self::Extension|get#property5b::T*
+ ;
+static method Extension|set#property5b<T extends core::num* = core::num*, S extends self::Extension|set#property5b::T* = core::num*>(final core::int* #this, self::Extension|set#property5b::S* i) → void
+ ;
+static method Extension|get#property6<T extends core::num* = core::num*, S extends self::Extension|get#property6::T* = core::num*>(final core::int* #this) → core::String*
+ ;
+static method Extension|set#property6<T extends core::num* = core::num*, S extends self::Extension|set#property6::T* = core::num*>(final core::int* #this, self::Extension|set#property6::S* i) → void
+ ;
+static get Extension|property7() → core::int*
+ ;
+static set Extension|property7(core::int* value) → void
+ ;
+static get Extension|property8a() → core::int*
+ ;
+static set Extension|property8a(core::num* value) → void
+ ;
+static get Extension|property8b() → core::num*
+ ;
+static set Extension|property8b(core::int* value) → void
+ ;
+static get Extension|property9() → core::num*
+ ;
+static set Extension|property9(core::String* value) → void
+ ;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.strong.expect b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.strong.expect
index eb497ad..0ab82ac 100644
--- a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.strong.expect
+++ b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.strong.expect
@@ -2,125 +2,165 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:12:14: Error: The type 'String' of the getter 'A.property3' is not assignable to the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:15:14: Error: The type 'String' of the getter 'A.property3' is not assignable to the type 'int' of the setter 'A.property3'.
// String get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:13:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:16:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:41:12: Error: The type 'int' of the inherited getter 'B1.property2' is not assignable to the type 'String' of the setter 'B2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:33:18: Error: The type 'num' of the getter 'A.property9' is not assignable to the type 'String' of the setter 'A.property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:34:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(String value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:56:12: Error: The type 'int' of the inherited getter 'B1.property2' is not assignable to the type 'String' of the setter 'B2.property2'.
// void set property2(String i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:25:11: Context: This is the declaration of the getter 'B1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:40:11: Context: This is the declaration of the getter 'B1.property2'.
// int get property2;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:43:12: Error: The type 'String' of the inherited getter 'B1.property3' is not assignable to the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:58:12: Error: The type 'String' of the inherited getter 'B1.property3' is not assignable to the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:27:14: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:42:14: Context: This is the declaration of the getter 'B1.property3'.
// String get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:47:12: Error: The type 'int' of the inherited field 'B1.property5' is not assignable to the type 'String' of the setter 'B2.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:62:12: Error: The type 'int' of the inherited field 'B1.property5' is not assignable to the type 'String' of the setter 'B2.property5'.
// void set property5(String i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:31:13: Context: This is the declaration of the field 'B1.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:46:13: Context: This is the declaration of the field 'B1.property5'.
// final int property5;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:49:12: Error: The type 'String' of the inherited field 'B1.property6' is not assignable to the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:64:12: Error: The type 'String' of the inherited field 'B1.property6' is not assignable to the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:33:16: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:48:16: Context: This is the declaration of the field 'B1.property6'.
// final String property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:69:11: Error: The type 'int' of the getter 'C2.property2' is not assignable to the type 'String' of the inherited setter 'C1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:84:11: Error: The type 'int' of the getter 'C2.property2' is not assignable to the type 'String' of the inherited setter 'C1.property2'.
// int get property2; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:55:12: Context: This is the declaration of the setter 'C1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:70:12: Context: This is the declaration of the setter 'C1.property2'.
// void set property2(String i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:71:14: Error: The type 'String' of the getter 'C2.property3' is not assignable to the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:86:14: Error: The type 'String' of the getter 'C2.property3' is not assignable to the type 'int' of the inherited setter 'C1.property3'.
// String get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:57:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:72:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:77:11: Error: The return type of the method 'C2.property5' is 'int', which does not match the return type, 'String', of the overridden method, 'C1.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:92:11: Error: The return type of the method 'C2.property5' is 'int', which does not match the return type, 'String', of the overridden method, 'C1.property5'.
// Change to a subtype of 'String'.
// int get property5; // error
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:61:10: Context: This is the overridden method ('property5').
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:76:10: Context: This is the overridden method ('property5').
// String property5;
// ^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:77:11: Error: The type 'int' of the getter 'C2.property5' is not assignable to the type 'String' of the inherited setter 'C1.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:92:11: Error: The type 'int' of the getter 'C2.property5' is not assignable to the type 'String' of the inherited setter 'C1.property5'.
// int get property5; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:61:10: Context: This is the declaration of the setter 'C1.property5'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:76:10: Context: This is the declaration of the setter 'C1.property5'.
// String property5;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:81:14: Error: The return type of the method 'C2.property6' is 'String', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:96:14: Error: The return type of the method 'C2.property6' is 'String', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// String get property6; // error
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:63:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:78:7: Context: This is the overridden method ('property6').
// int property6;
// ^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:81:14: Error: The type 'String' of the getter 'C2.property6' is not assignable to the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:96:14: Error: The type 'String' of the getter 'C2.property6' is not assignable to the type 'int' of the inherited setter 'C1.property6'.
// String get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:63:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:78:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:100:16: Error: The type 'int' of the inherited getter 'D1.property2' is not assignable to the type 'String' of the inherited setter 'D2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:115:16: Error: The type 'int' of the inherited getter 'D1.property2' is not assignable to the type 'String' of the inherited setter 'D2.property2'.
// abstract class D3 implements D1, D2 /* error on property2 and property3 */ {}
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:102:11: Context: This is the declaration of the getter 'D1.property2'.
// int get property2;
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:110:12: Context: This is the declaration of the setter 'D2.property2'.
// void set property2(String i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:100:16: Error: The type 'String' of the inherited getter 'D1.property3' is not assignable to the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:115:16: Error: The type 'String' of the inherited getter 'D1.property3' is not assignable to the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property2 and property3 */ {}
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:89:14: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:104:14: Context: This is the declaration of the getter 'D1.property3'.
// String get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:97:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:112:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:102:16: Error: The type 'int' of the inherited getter 'D1.property2' is not assignable to the type 'String' of the inherited setter 'D2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:117:16: Error: The type 'int' of the inherited getter 'D1.property2' is not assignable to the type 'String' of the inherited setter 'D2.property2'.
// abstract class D4
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:102:11: Context: This is the declaration of the getter 'D1.property2'.
// int get property2;
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property2'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:110:12: Context: This is the declaration of the setter 'D2.property2'.
// void set property2(String i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:102:16: Error: The type 'String' of the inherited getter 'D1.property3' is not assignable to the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:117:16: Error: The type 'String' of the inherited getter 'D1.property3' is not assignable to the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4
// ^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:89:14: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:104:14: Context: This is the declaration of the getter 'D1.property3'.
// String get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/general/getter_vs_setter_type.dart:97:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:112:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:130:14: Error: The type 'String' of the getter 'property3' is not assignable to the type 'int' of the setter 'property3'.
+// String get property3 => ''; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:131:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:142:14: Error: The type 'String' of the getter 'property6' is not assignable to the type 'S' of the setter 'property6'.
+// String get property6 => ''; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:143:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(S i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:154:18: Error: The type 'num' of the getter 'property9' is not assignable to the type 'String' of the setter 'property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:155:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(String value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:133:22: Error: A value of type 'int' can't be assigned to a variable of type 'S'.
+// S get property4 => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:136:23: Error: A value of type 'int' can't be assigned to a variable of type 'S'.
+// S get property5a => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/general/getter_vs_setter_type.dart:139:23: Error: A value of type 'int' can't be assigned to a variable of type 'T'.
+// T get property5b => 0; // ok
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -133,10 +173,24 @@
;
abstract get property1() → core::int*;
abstract set property1(core::int* i) → void;
- abstract get property2() → core::int*;
- abstract set property2(core::int* i) → void;
+ abstract get property2a() → core::num*;
+ abstract set property2a(core::int* i) → void;
+ abstract get property2b() → core::int*;
+ abstract set property2b(core::num* i) → void;
abstract get property3() → core::String*;
abstract set property3(core::int* i) → void;
+ static get property7() → core::int*
+ return 0;
+ static set property7(core::int* value) → void {}
+ static get property8a() → core::int*
+ return 0;
+ static set property8a(core::num* value) → void {}
+ static get property8b() → core::num*
+ return 0;
+ static set property8b(core::int* value) → void {}
+ static get property9() → core::num*
+ return 0;
+ static set property9(core::String* value) → void {}
abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
@@ -298,4 +352,72 @@
abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
}
+extension Extension<T extends core::num* = core::num*, S extends T* = core::num*> on core::int* {
+ get property1 = self::Extension|get#property1;
+ get property2a = self::Extension|get#property2a;
+ get property2b = self::Extension|get#property2b;
+ get property3 = self::Extension|get#property3;
+ get property4 = self::Extension|get#property4;
+ get property5a = self::Extension|get#property5a;
+ get property5b = self::Extension|get#property5b;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8a = get self::Extension|property8a;
+ static get property8b = get self::Extension|property8b;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2a = self::Extension|set#property2a;
+ set property2b = self::Extension|set#property2b;
+ set property3 = self::Extension|set#property3;
+ set property4 = self::Extension|set#property4;
+ set property5a = self::Extension|set#property5a;
+ set property5b = self::Extension|set#property5b;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8a = set self::Extension|property8a;
+ static set property8b = set self::Extension|property8b;
+ static set property9 = set self::Extension|property9;
+}
+static method Extension|get#property1<T extends core::num* = core::num*, S extends self::Extension|get#property1::T* = core::num*>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#property1<T extends core::num* = core::num*, S extends self::Extension|set#property1::T* = core::num*>(final core::int* #this, core::int* i) → void {}
+static method Extension|get#property2a<T extends core::num* = core::num*, S extends self::Extension|get#property2a::T* = core::num*>(final core::int* #this) → core::num*
+ return 0;
+static method Extension|set#property2a<T extends core::num* = core::num*, S extends self::Extension|set#property2a::T* = core::num*>(final core::int* #this, core::int* i) → void {}
+static method Extension|get#property2b<T extends core::num* = core::num*, S extends self::Extension|get#property2b::T* = core::num*>(final core::int* #this) → core::int*
+ return 0;
+static method Extension|set#property2b<T extends core::num* = core::num*, S extends self::Extension|set#property2b::T* = core::num*>(final core::int* #this, core::num* i) → void {}
+static method Extension|get#property3<T extends core::num* = core::num*, S extends self::Extension|get#property3::T* = core::num*>(final core::int* #this) → core::String*
+ return "";
+static method Extension|set#property3<T extends core::num* = core::num*, S extends self::Extension|set#property3::T* = core::num*>(final core::int* #this, core::int* i) → void {}
+static method Extension|get#property4<T extends core::num* = core::num*, S extends self::Extension|get#property4::T* = core::num*>(final core::int* #this) → self::Extension|get#property4::S*
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/general/getter_vs_setter_type.dart:133:22: Error: A value of type 'int' can't be assigned to a variable of type 'S'.
+ S get property4 => 0; // ok
+ ^" in 0 as{TypeError} <BottomType>;
+static method Extension|set#property4<T extends core::num* = core::num*, S extends self::Extension|set#property4::T* = core::num*>(final core::int* #this, self::Extension|set#property4::S* i) → void {}
+static method Extension|get#property5a<T extends core::num* = core::num*, S extends self::Extension|get#property5a::T* = core::num*>(final core::int* #this) → self::Extension|get#property5a::S*
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/general/getter_vs_setter_type.dart:136:23: Error: A value of type 'int' can't be assigned to a variable of type 'S'.
+ S get property5a => 0; // ok
+ ^" in 0 as{TypeError} <BottomType>;
+static method Extension|set#property5a<T extends core::num* = core::num*, S extends self::Extension|set#property5a::T* = core::num*>(final core::int* #this, self::Extension|set#property5a::T* i) → void {}
+static method Extension|get#property5b<T extends core::num* = core::num*, S extends self::Extension|get#property5b::T* = core::num*>(final core::int* #this) → self::Extension|get#property5b::T*
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/general/getter_vs_setter_type.dart:139:23: Error: A value of type 'int' can't be assigned to a variable of type 'T'.
+ T get property5b => 0; // ok
+ ^" in 0 as{TypeError} <BottomType>;
+static method Extension|set#property5b<T extends core::num* = core::num*, S extends self::Extension|set#property5b::T* = core::num*>(final core::int* #this, self::Extension|set#property5b::S* i) → void {}
+static method Extension|get#property6<T extends core::num* = core::num*, S extends self::Extension|get#property6::T* = core::num*>(final core::int* #this) → core::String*
+ return "";
+static method Extension|set#property6<T extends core::num* = core::num*, S extends self::Extension|set#property6::T* = core::num*>(final core::int* #this, self::Extension|set#property6::S* i) → void {}
+static get Extension|property7() → core::int*
+ return 0;
+static set Extension|property7(core::int* value) → void {}
+static get Extension|property8a() → core::int*
+ return 0;
+static set Extension|property8a(core::num* value) → void {}
+static get Extension|property8b() → core::num*
+ return 0;
+static set Extension|property8b(core::int* value) → void {}
+static get Extension|property9() → core::num*
+ return 0;
+static set Extension|property9(core::String* value) → void {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline.expect b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline.expect
index 2018462..47e2d86 100644
--- a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline.expect
@@ -1,15 +1,24 @@
abstract class A {
int get property1;
void set property1(int i);
- int get property2;
- void set property2(int i);
+ num get property2a;
+ void set property2a(int i);
+ int get property2b;
+ void set property2b(num i);
String get property3;
void set property3(int i);
int property4;
int property5;
covariant String property6;
+ static int get property7 => 0;
+ static void set property7(int value) {}
+ static int get property8a => 0;
+ static void set property8a(num value) {}
+ static num get property8b => 0;
+ static void set property8b(int value) {}
+ static num get property9 => 0;
+ static void set property9(String value) {}
}
-
abstract class B1 {
int get property1;
int get property2;
@@ -19,7 +28,6 @@
final String property6;
B1(this.property4, this.property5, this.property6);
}
-
abstract class B2 implements B1 {
void set property1(int i);
void set property2(String i);
@@ -28,7 +36,6 @@
void set property5(String i);
void set property6(int i);
}
-
abstract class C1 {
void set property1(int i);
void set property2(String i);
@@ -37,7 +44,6 @@
String property5;
int property6;
}
-
abstract class C2 implements C1 {
int get property1;
int get property2;
@@ -46,21 +52,18 @@
int get property5;
String get property6;
}
-
abstract class D1 {
int get property1;
int get property2;
String get property3;
}
-
abstract class D2 {
void set property1(int i);
void set property2(String i);
void set property3(int i);
}
-
abstract class D3 implements D1, D2 {}
-
abstract class D4 implements D3 {}
-
+extension Extension<T extends num, S extends T> (){}
+on int (){}
main() {}
diff --git a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline_modelled.expect
index 22c0c24..e2ee020 100644
--- a/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/general/getter_vs_setter_type.dart.textual_outline_modelled.expect
@@ -2,11 +2,21 @@
String get property3;
covariant String property6;
int get property1;
- int get property2;
+ int get property2b;
int property4;
int property5;
+ num get property2a;
+ static int get property7 => 0;
+ static int get property8a => 0;
+ static num get property8b => 0;
+ static num get property9 => 0;
+ static void set property7(int value) {}
+ static void set property8a(num value) {}
+ static void set property8b(int value) {}
+ static void set property9(String value) {}
void set property1(int i);
- void set property2(int i);
+ void set property2a(int i);
+ void set property2b(num i);
void set property3(int i);
}
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.outline.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.outline.expect
index 2bd2465..bd2765e 100644
--- a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.outline.expect
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.outline.expect
@@ -1,4 +1,16 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/static_assign_combiner.dart:28:7: Error: The type 'A' of the getter 'target' is not assignable to the type 'B' of the setter 'target'.
+// - 'A' is from 'pkg/front_end/testcases/inference_new/static_assign_combiner.dart'.
+// - 'B' is from 'pkg/front_end/testcases/inference_new/static_assign_combiner.dart'.
+// A get target => null;
+// ^^^^^^
+// pkg/front_end/testcases/inference_new/static_assign_combiner.dart:30:10: Context: This is the declaration of the setter 'target'.
+// void set target(B value) {}
+// ^^^^^^
+//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.expect
index c956d22..a2976ca 100644
--- a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.expect
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.expect
@@ -1,4 +1,16 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/static_assign_combiner.dart:28:7: Error: The type 'A' of the getter 'target' is not assignable to the type 'B' of the setter 'target'.
+// - 'A' is from 'pkg/front_end/testcases/inference_new/static_assign_combiner.dart'.
+// - 'B' is from 'pkg/front_end/testcases/inference_new/static_assign_combiner.dart'.
+// A get target => null;
+// ^^^^^^
+// pkg/front_end/testcases/inference_new/static_assign_combiner.dart:30:10: Context: This is the declaration of the setter 'target'.
+// void set target(B value) {}
+// ^^^^^^
+//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect
index c956d22..a2976ca 100644
--- a/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference_new/static_assign_combiner.dart.strong.transformed.expect
@@ -1,4 +1,16 @@
library test;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/inference_new/static_assign_combiner.dart:28:7: Error: The type 'A' of the getter 'target' is not assignable to the type 'B' of the setter 'target'.
+// - 'A' is from 'pkg/front_end/testcases/inference_new/static_assign_combiner.dart'.
+// - 'B' is from 'pkg/front_end/testcases/inference_new/static_assign_combiner.dart'.
+// A get target => null;
+// ^^^^^^
+// pkg/front_end/testcases/inference_new/static_assign_combiner.dart:30:10: Context: This is the declaration of the setter 'target'.
+// void set target(B value) {}
+// ^^^^^^
+//
import self as self;
import "dart:core" as core;
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart
index aaba82c..1aaaf23 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart
@@ -2,6 +2,15 @@
// 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.
+int get property1 => 0; // ok
+void set property1(int value) {}
+
+int get property2 => 0; // ok
+void set property2(num value) {}
+
+num get property3 => 0; // error
+void set property3(int value) {}
+
abstract class A {
int get property1; // ok
void set property1(int i);
@@ -17,6 +26,15 @@
int property5 = 0; // ok
covariant num property6 = 0; // ok
+
+ static int get property7 => 0; // ok
+ static void set property7(int value) {}
+
+ static int get property8 => 0; // ok
+ static void set property8(num value) {}
+
+ static num get property9 => 0; // error
+ static void set property9(int value) {}
}
abstract class B1 {
@@ -99,4 +117,33 @@
abstract class D4 implements D3 /* no need for error on property3 */ {}
+extension Extension<T, S extends T> on int {
+ int get property1 => 0; // ok
+ void set property1(int i) {}
+
+ int get property2 => 0; // ok
+ void set property2(num i) {}
+
+ num get property3 => 0; // error
+ void set property3(int i) {}
+
+ S get property4 => 0; // ok
+ void set property4(S i) {}
+
+ S get property5 => 0; // ok
+ void set property5(T i) {}
+
+ T get property6 => 0; // error
+ void set property6(S i) {}
+
+ static int get property7 => 0; // ok
+ static void set property7(int value) {}
+
+ static int get property8 => 0; // ok
+ static void set property8(num value) {}
+
+ static num get property9 => 0; // error
+ static void set property9(int value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.outline.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.outline.expect
index e7d6448..fb834d9 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.outline.expect
@@ -2,69 +2,104 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:12:11: Error: The type 'num' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:21:11: Error: The type 'num' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
// num get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:13:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:22:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:43:12: Error: The type 'num' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:36:18: Error: The type 'num' of the getter 'A.property9' is not a subtype of the type 'int' of the setter 'A.property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:37:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:61:12: Error: The type 'num' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:27:11: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:45:11: Context: This is the declaration of the getter 'B1.property3'.
// num get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:49:12: Error: The type 'num' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:67:12: Error: The type 'num' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:33:13: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:51:13: Context: This is the declaration of the field 'B1.property6'.
// final num property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:71:11: Error: The type 'num' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:89:11: Error: The type 'num' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
// num get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:57:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:75:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:79:11: Error: The return type of the method 'C2.property6' is 'num', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:97:11: Error: The return type of the method 'C2.property6' is 'num', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// num get property6; // error
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:63:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:81:7: Context: This is the overridden method ('property6').
// int property6 = 0;
// ^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:79:11: Error: The type 'num' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:97:11: Error: The type 'num' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
// num get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:63:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:81:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6 = 0;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:98:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:116:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:105:11: Context: This is the declaration of the getter 'D1.property3'.
// num get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:113:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:100:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:118:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4 implements D3 /* no need for error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:105:11: Context: This is the declaration of the getter 'D1.property3'.
// num get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:113:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:11:9: Error: The type 'num' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// num get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:12:10: Context: This is the declaration of the setter 'property3'.
+// void set property3(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:127:11: Error: The type 'num' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// num get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:128:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:136:9: Error: The type 'T' of the getter 'property6' is not a subtype of the type 'S' of the setter 'property6'.
+// T get property6 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:137:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(S i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:145:18: Error: The type 'num' of the getter 'property9' is not a subtype of the type 'int' of the setter 'property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:146:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
import self as self;
import "dart:core" as core;
@@ -80,6 +115,18 @@
abstract set property2(core::int i) → void;
abstract get property3() → core::num;
abstract set property3(core::int i) → void;
+ static get property7() → core::int
+ ;
+ static set property7(core::int value) → void
+ ;
+ static get property8() → core::int
+ ;
+ static set property8(core::num value) → void
+ ;
+ static get property9() → core::num
+ ;
+ static set property9(core::int value) → void
+ ;
}
abstract class B1 extends core::Object {
final field core::int property4;
@@ -143,5 +190,73 @@
synthetic constructor •() → self::D4
;
}
+extension Extension<T extends core::Object? = dynamic, S extends T% = dynamic> on core::int {
+ get property1 = self::Extension|get#property1;
+ get property2 = self::Extension|get#property2;
+ get property3 = self::Extension|get#property3;
+ get property4 = self::Extension|get#property4;
+ get property5 = self::Extension|get#property5;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8 = get self::Extension|property8;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2 = self::Extension|set#property2;
+ set property3 = self::Extension|set#property3;
+ set property4 = self::Extension|set#property4;
+ set property5 = self::Extension|set#property5;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8 = set self::Extension|property8;
+ static set property9 = set self::Extension|property9;
+}
+static get property1() → core::int
+ ;
+static set property1(core::int value) → void
+ ;
+static get property2() → core::int
+ ;
+static set property2(core::num value) → void
+ ;
+static get property3() → core::num
+ ;
+static set property3(core::int value) → void
+ ;
+static method Extension|get#property1<T extends core::Object? = dynamic, S extends self::Extension|get#property1::T% = dynamic>(final core::int #this) → core::int
+ ;
+static method Extension|set#property1<T extends core::Object? = dynamic, S extends self::Extension|set#property1::T% = dynamic>(final core::int #this, core::int i) → void
+ ;
+static method Extension|get#property2<T extends core::Object? = dynamic, S extends self::Extension|get#property2::T% = dynamic>(final core::int #this) → core::int
+ ;
+static method Extension|set#property2<T extends core::Object? = dynamic, S extends self::Extension|set#property2::T% = dynamic>(final core::int #this, core::num i) → void
+ ;
+static method Extension|get#property3<T extends core::Object? = dynamic, S extends self::Extension|get#property3::T% = dynamic>(final core::int #this) → core::num
+ ;
+static method Extension|set#property3<T extends core::Object? = dynamic, S extends self::Extension|set#property3::T% = dynamic>(final core::int #this, core::int i) → void
+ ;
+static method Extension|get#property4<T extends core::Object? = dynamic, S extends self::Extension|get#property4::T% = dynamic>(final core::int #this) → self::Extension|get#property4::S%
+ ;
+static method Extension|set#property4<T extends core::Object? = dynamic, S extends self::Extension|set#property4::T% = dynamic>(final core::int #this, self::Extension|set#property4::S% i) → void
+ ;
+static method Extension|get#property5<T extends core::Object? = dynamic, S extends self::Extension|get#property5::T% = dynamic>(final core::int #this) → self::Extension|get#property5::S%
+ ;
+static method Extension|set#property5<T extends core::Object? = dynamic, S extends self::Extension|set#property5::T% = dynamic>(final core::int #this, self::Extension|set#property5::T% i) → void
+ ;
+static method Extension|get#property6<T extends core::Object? = dynamic, S extends self::Extension|get#property6::T% = dynamic>(final core::int #this) → self::Extension|get#property6::T%
+ ;
+static method Extension|set#property6<T extends core::Object? = dynamic, S extends self::Extension|set#property6::T% = dynamic>(final core::int #this, self::Extension|set#property6::S% i) → void
+ ;
+static get Extension|property7() → core::int
+ ;
+static set Extension|property7(core::int value) → void
+ ;
+static get Extension|property8() → core::int
+ ;
+static set Extension|property8(core::num value) → void
+ ;
+static get Extension|property9() → core::num
+ ;
+static set Extension|property9(core::int value) → void
+ ;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.strong.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.strong.expect
index 5c5052b..f346415 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.strong.expect
@@ -2,69 +2,116 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:12:11: Error: The type 'num' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:21:11: Error: The type 'num' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
// num get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:13:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:22:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:43:12: Error: The type 'num' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:36:18: Error: The type 'num' of the getter 'A.property9' is not a subtype of the type 'int' of the setter 'A.property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:37:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:61:12: Error: The type 'num' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:27:11: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:45:11: Context: This is the declaration of the getter 'B1.property3'.
// num get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:49:12: Error: The type 'num' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:67:12: Error: The type 'num' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:33:13: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:51:13: Context: This is the declaration of the field 'B1.property6'.
// final num property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:71:11: Error: The type 'num' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:89:11: Error: The type 'num' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
// num get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:57:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:75:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:79:11: Error: The return type of the method 'C2.property6' is 'num', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:97:11: Error: The return type of the method 'C2.property6' is 'num', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// num get property6; // error
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:63:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:81:7: Context: This is the overridden method ('property6').
// int property6 = 0;
// ^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:79:11: Error: The type 'num' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:97:11: Error: The type 'num' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
// num get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:63:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:81:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6 = 0;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:98:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:116:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:105:11: Context: This is the declaration of the getter 'D1.property3'.
// num get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:113:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:100:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:118:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4 implements D3 /* no need for error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:105:11: Context: This is the declaration of the getter 'D1.property3'.
// num get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:113:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:11:9: Error: The type 'num' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// num get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:12:10: Context: This is the declaration of the setter 'property3'.
+// void set property3(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:127:11: Error: The type 'num' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// num get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:128:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:136:9: Error: The type 'T' of the getter 'property6' is not a subtype of the type 'S' of the setter 'property6'.
+// T get property6 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:137:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(S i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:145:18: Error: The type 'num' of the getter 'property9' is not a subtype of the type 'int' of the setter 'property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:146:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:130:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
+// S get property4 => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:133:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
+// S get property5 => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:136:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property6 => 0; // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -81,6 +128,15 @@
abstract set property2(core::int i) → void;
abstract get property3() → core::num;
abstract set property3(core::int i) → void;
+ static get property7() → core::int
+ return 0;
+ static set property7(core::int value) → void {}
+ static get property8() → core::int
+ return 0;
+ static set property8(core::num value) → void {}
+ static get property9() → core::num
+ return 0;
+ static set property9(core::int value) → void {}
}
abstract class B1 extends core::Object {
final field core::int property4;
@@ -152,4 +208,66 @@
: super core::Object::•()
;
}
+extension Extension<T extends core::Object? = dynamic, S extends T% = dynamic> on core::int {
+ get property1 = self::Extension|get#property1;
+ get property2 = self::Extension|get#property2;
+ get property3 = self::Extension|get#property3;
+ get property4 = self::Extension|get#property4;
+ get property5 = self::Extension|get#property5;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8 = get self::Extension|property8;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2 = self::Extension|set#property2;
+ set property3 = self::Extension|set#property3;
+ set property4 = self::Extension|set#property4;
+ set property5 = self::Extension|set#property5;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8 = set self::Extension|property8;
+ static set property9 = set self::Extension|property9;
+}
+static get property1() → core::int
+ return 0;
+static set property1(core::int value) → void {}
+static get property2() → core::int
+ return 0;
+static set property2(core::num value) → void {}
+static get property3() → core::num
+ return 0;
+static set property3(core::int value) → void {}
+static method Extension|get#property1<T extends core::Object? = dynamic, S extends self::Extension|get#property1::T% = dynamic>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property1<T extends core::Object? = dynamic, S extends self::Extension|set#property1::T% = dynamic>(final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::Object? = dynamic, S extends self::Extension|get#property2::T% = dynamic>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property2<T extends core::Object? = dynamic, S extends self::Extension|set#property2::T% = dynamic>(final core::int #this, core::num i) → void {}
+static method Extension|get#property3<T extends core::Object? = dynamic, S extends self::Extension|get#property3::T% = dynamic>(final core::int #this) → core::num
+ return 0;
+static method Extension|set#property3<T extends core::Object? = dynamic, S extends self::Extension|set#property3::T% = dynamic>(final core::int #this, core::int i) → void {}
+static method Extension|get#property4<T extends core::Object? = dynamic, S extends self::Extension|get#property4::T% = dynamic>(final core::int #this) → self::Extension|get#property4::S%
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:130:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
+ S get property4 => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4<T extends core::Object? = dynamic, S extends self::Extension|set#property4::T% = dynamic>(final core::int #this, self::Extension|set#property4::S% i) → void {}
+static method Extension|get#property5<T extends core::Object? = dynamic, S extends self::Extension|get#property5::T% = dynamic>(final core::int #this) → self::Extension|get#property5::S%
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:133:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
+ S get property5 => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property5<T extends core::Object? = dynamic, S extends self::Extension|set#property5::T% = dynamic>(final core::int #this, self::Extension|set#property5::T% i) → void {}
+static method Extension|get#property6<T extends core::Object? = dynamic, S extends self::Extension|get#property6::T% = dynamic>(final core::int #this) → self::Extension|get#property6::T%
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:136:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property6 => 0; // error
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property6<T extends core::Object? = dynamic, S extends self::Extension|set#property6::T% = dynamic>(final core::int #this, self::Extension|set#property6::S% i) → void {}
+static get Extension|property7() → core::int
+ return 0;
+static set Extension|property7(core::int value) → void {}
+static get Extension|property8() → core::int
+ return 0;
+static set Extension|property8(core::num value) → void {}
+static get Extension|property9() → core::num
+ return 0;
+static set Extension|property9(core::int value) → void {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline.expect
index bc0af57..806128e 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline.expect
@@ -1,3 +1,9 @@
+int get property1 => 0;
+void set property1(int value) {}
+int get property2 => 0;
+void set property2(num value) {}
+num get property3 => 0;
+void set property3(int value) {}
abstract class A {
int get property1;
void set property1(int i);
@@ -8,8 +14,13 @@
int property4 = 0;
int property5 = 0;
covariant num property6 = 0;
+ static int get property7 => 0;
+ static void set property7(int value) {}
+ static int get property8 => 0;
+ static void set property8(num value) {}
+ static num get property9 => 0;
+ static void set property9(int value) {}
}
-
abstract class B1 {
int get property1;
int get property2;
@@ -19,7 +30,6 @@
final num property6;
B1(this.property4, this.property5, this.property6);
}
-
abstract class B2 implements B1 {
void set property1(int i);
void set property2(num i);
@@ -28,7 +38,6 @@
void set property5(num i);
void set property6(int i);
}
-
abstract class C1 {
void set property1(int i);
void set property2(num i);
@@ -37,7 +46,6 @@
num property5 = 0;
int property6 = 0;
}
-
abstract class C2 implements C1 {
int get property1;
int get property2;
@@ -46,21 +54,18 @@
int get property5;
num get property6;
}
-
abstract class D1 {
int get property1;
int get property2;
num get property3;
}
-
abstract class D2 {
void set property1(int i);
void set property2(num i);
void set property3(int i);
}
-
abstract class D3 implements D1, D2 {}
-
abstract class D4 implements D3 {}
-
+extension Extension<T, S extends T> (){}
+on int (){}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline_modelled.expect
index 43c1a56..feb0a3a 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.textual_outline_modelled.expect
@@ -5,6 +5,12 @@
int property4 = 0;
int property5 = 0;
num get property3;
+ static int get property7 => 0;
+ static int get property8 => 0;
+ static num get property9 => 0;
+ static void set property7(int value) {}
+ static void set property8(num value) {}
+ static void set property9(int value) {}
void set property1(int i);
void set property2(int i);
void set property3(int i);
@@ -63,4 +69,10 @@
abstract class D4 implements D3 {}
+int get property1 => 0;
+int get property2 => 0;
main() {}
+num get property3 => 0;
+void set property1(int value) {}
+void set property2(num value) {}
+void set property3(int value) {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.weak.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.weak.expect
index 5c5052b..f346415 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart.weak.expect
@@ -2,69 +2,116 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:12:11: Error: The type 'num' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:21:11: Error: The type 'num' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
// num get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:13:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:22:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:43:12: Error: The type 'num' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:36:18: Error: The type 'num' of the getter 'A.property9' is not a subtype of the type 'int' of the setter 'A.property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:37:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:61:12: Error: The type 'num' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:27:11: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:45:11: Context: This is the declaration of the getter 'B1.property3'.
// num get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:49:12: Error: The type 'num' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:67:12: Error: The type 'num' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:33:13: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:51:13: Context: This is the declaration of the field 'B1.property6'.
// final num property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:71:11: Error: The type 'num' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:89:11: Error: The type 'num' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
// num get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:57:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:75:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:79:11: Error: The return type of the method 'C2.property6' is 'num', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:97:11: Error: The return type of the method 'C2.property6' is 'num', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// num get property6; // error
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:63:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:81:7: Context: This is the overridden method ('property6').
// int property6 = 0;
// ^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:79:11: Error: The type 'num' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:97:11: Error: The type 'num' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
// num get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:63:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:81:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6 = 0;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:98:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:116:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:105:11: Context: This is the declaration of the getter 'D1.property3'.
// num get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:113:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:100:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:118:16: Error: The type 'num' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4 implements D3 /* no need for error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:87:11: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:105:11: Context: This is the declaration of the getter 'D1.property3'.
// num get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:95:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:113:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:11:9: Error: The type 'num' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// num get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:12:10: Context: This is the declaration of the setter 'property3'.
+// void set property3(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:127:11: Error: The type 'num' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// num get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:128:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:136:9: Error: The type 'T' of the getter 'property6' is not a subtype of the type 'S' of the setter 'property6'.
+// T get property6 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:137:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(S i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:145:18: Error: The type 'num' of the getter 'property9' is not a subtype of the type 'int' of the setter 'property9'.
+// static num get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:146:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:130:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
+// S get property4 => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:133:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
+// S get property5 => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:136:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property6 => 0; // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -81,6 +128,15 @@
abstract set property2(core::int i) → void;
abstract get property3() → core::num;
abstract set property3(core::int i) → void;
+ static get property7() → core::int
+ return 0;
+ static set property7(core::int value) → void {}
+ static get property8() → core::int
+ return 0;
+ static set property8(core::num value) → void {}
+ static get property9() → core::num
+ return 0;
+ static set property9(core::int value) → void {}
}
abstract class B1 extends core::Object {
final field core::int property4;
@@ -152,4 +208,66 @@
: super core::Object::•()
;
}
+extension Extension<T extends core::Object? = dynamic, S extends T% = dynamic> on core::int {
+ get property1 = self::Extension|get#property1;
+ get property2 = self::Extension|get#property2;
+ get property3 = self::Extension|get#property3;
+ get property4 = self::Extension|get#property4;
+ get property5 = self::Extension|get#property5;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8 = get self::Extension|property8;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2 = self::Extension|set#property2;
+ set property3 = self::Extension|set#property3;
+ set property4 = self::Extension|set#property4;
+ set property5 = self::Extension|set#property5;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8 = set self::Extension|property8;
+ static set property9 = set self::Extension|property9;
+}
+static get property1() → core::int
+ return 0;
+static set property1(core::int value) → void {}
+static get property2() → core::int
+ return 0;
+static set property2(core::num value) → void {}
+static get property3() → core::num
+ return 0;
+static set property3(core::int value) → void {}
+static method Extension|get#property1<T extends core::Object? = dynamic, S extends self::Extension|get#property1::T% = dynamic>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property1<T extends core::Object? = dynamic, S extends self::Extension|set#property1::T% = dynamic>(final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::Object? = dynamic, S extends self::Extension|get#property2::T% = dynamic>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property2<T extends core::Object? = dynamic, S extends self::Extension|set#property2::T% = dynamic>(final core::int #this, core::num i) → void {}
+static method Extension|get#property3<T extends core::Object? = dynamic, S extends self::Extension|get#property3::T% = dynamic>(final core::int #this) → core::num
+ return 0;
+static method Extension|set#property3<T extends core::Object? = dynamic, S extends self::Extension|set#property3::T% = dynamic>(final core::int #this, core::int i) → void {}
+static method Extension|get#property4<T extends core::Object? = dynamic, S extends self::Extension|get#property4::T% = dynamic>(final core::int #this) → self::Extension|get#property4::S%
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:130:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
+ S get property4 => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4<T extends core::Object? = dynamic, S extends self::Extension|set#property4::T% = dynamic>(final core::int #this, self::Extension|set#property4::S% i) → void {}
+static method Extension|get#property5<T extends core::Object? = dynamic, S extends self::Extension|get#property5::T% = dynamic>(final core::int #this) → self::Extension|get#property5::S%
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:133:22: Error: A value of type 'int' can't be returned from a function with return type 'S'.
+ S get property5 => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property5<T extends core::Object? = dynamic, S extends self::Extension|set#property5::T% = dynamic>(final core::int #this, self::Extension|set#property5::T% i) → void {}
+static method Extension|get#property6<T extends core::Object? = dynamic, S extends self::Extension|get#property6::T% = dynamic>(final core::int #this) → self::Extension|get#property6::T%
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type.dart:136:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property6 => 0; // error
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property6<T extends core::Object? = dynamic, S extends self::Extension|set#property6::T% = dynamic>(final core::int #this, self::Extension|set#property6::S% i) → void {}
+static get Extension|property7() → core::int
+ return 0;
+static set Extension|property7(core::int value) → void {}
+static get Extension|property8() → core::int
+ return 0;
+static set Extension|property8(core::num value) → void {}
+static get Extension|property9() → core::num
+ return 0;
+static set Extension|property9(core::int value) → void {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart
index 364f0c6..2156307 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart
@@ -2,17 +2,23 @@
// 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.
+int get property1 => 0; // ok
+void set property1(int value) {}
+
+int get property2 => 0; // ok
+void set property2(int? value) {}
+
+int? get property3 => 0; // error
+void set property3(int value) {}
+
abstract class A {
int get property1; // ok
-
void set property1(int i);
int get property2; // ok
-
void set property2(int? i);
int? get property3; // error
-
void set property3(int i);
int property4; // ok
@@ -22,6 +28,15 @@
covariant int property6; // ok
A(this.property4, this.property5, this.property6);
+
+ static int get property7 => 0; // ok
+ static void set property7(int value) {}
+
+ static int get property8 => 0; // ok
+ static void set property8(int? value) {}
+
+ static int? get property9 => 0; // error
+ static void set property9(int value) {}
}
abstract class B1 {
@@ -106,4 +121,36 @@
abstract class D4 implements D3 /* no need for error on property3 */ {}
+extension Extension<T extends num> on int {
+ int get property1 => 0; // ok
+ void set property1(int i) {}
+
+ int get property2 => 0; // ok
+ void set property2(int? i) {}
+
+ int? get property3 => 0; // error
+ void set property3(int i) {}
+
+ T get property4a => 0; // ok
+ void set property4a(T i) {}
+
+ T? get property4b => 0; // ok
+ void set property4b(T? i) {}
+
+ T get property5 => 0; // ok
+ void set property5(T? i) {}
+
+ T? get property6 => 0; // error
+ void set property6(T i) {}
+
+ static int get property7 => 0; // ok
+ static void set property7(int value) {}
+
+ static int get property8 => 0; // ok
+ static void set property8(int? value) {}
+
+ static int? get property9 => 0; // error
+ static void set property9(int value) {}
+}
+
main() {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.outline.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.outline.expect
index 30e3ae5..763d5e7 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.outline.expect
@@ -2,69 +2,104 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:14:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:21:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:16:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:22:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:48:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:19: Error: The type 'int?' of the getter 'A.property9' is not a subtype of the type 'int' of the setter 'A.property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:39:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:63:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:32:12: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:47:12: Context: This is the declaration of the getter 'B1.property3'.
// int? get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:54:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:69:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:14: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:53:14: Context: This is the declaration of the field 'B1.property6'.
// final int? property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:78:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:93:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:62:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:77:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// int? get property6; // error
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the overridden method ('property6').
// int property6;
// ^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
// int? get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:105:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:120:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:107:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:122:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4 implements D3 /* no need for error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:11:10: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:12:10: Context: This is the declaration of the setter 'property3'.
+// void set property3(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:131:12: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:132:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:10: Error: The type 'T?' of the getter 'property6' is not a subtype of the type 'T' of the setter 'property6'.
+// T? get property6 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:144:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(T i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:152:19: Error: The type 'int?' of the getter 'property9' is not a subtype of the type 'int' of the setter 'property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:153:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
import self as self;
import "dart:core" as core;
@@ -80,6 +115,18 @@
abstract set property2(core::int? i) → void;
abstract get property3() → core::int?;
abstract set property3(core::int i) → void;
+ static get property7() → core::int
+ ;
+ static set property7(core::int value) → void
+ ;
+ static get property8() → core::int
+ ;
+ static set property8(core::int? value) → void
+ ;
+ static get property9() → core::int?
+ ;
+ static set property9(core::int value) → void
+ ;
}
abstract class B1 extends core::Object {
final field core::int property4;
@@ -143,5 +190,79 @@
synthetic constructor •() → self::D4
;
}
+extension Extension<T extends core::num = core::num> on core::int {
+ get property1 = self::Extension|get#property1;
+ get property2 = self::Extension|get#property2;
+ get property3 = self::Extension|get#property3;
+ get property4a = self::Extension|get#property4a;
+ get property4b = self::Extension|get#property4b;
+ get property5 = self::Extension|get#property5;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8 = get self::Extension|property8;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2 = self::Extension|set#property2;
+ set property3 = self::Extension|set#property3;
+ set property4a = self::Extension|set#property4a;
+ set property4b = self::Extension|set#property4b;
+ set property5 = self::Extension|set#property5;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8 = set self::Extension|property8;
+ static set property9 = set self::Extension|property9;
+}
+static get property1() → core::int
+ ;
+static set property1(core::int value) → void
+ ;
+static get property2() → core::int
+ ;
+static set property2(core::int? value) → void
+ ;
+static get property3() → core::int?
+ ;
+static set property3(core::int value) → void
+ ;
+static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+ ;
+static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void
+ ;
+static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+ ;
+static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void
+ ;
+static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+ ;
+static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void
+ ;
+static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+ ;
+static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void
+ ;
+static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+ ;
+static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void
+ ;
+static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+ ;
+static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void
+ ;
+static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+ ;
+static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void
+ ;
+static get Extension|property7() → core::int
+ ;
+static set Extension|property7(core::int value) → void
+ ;
+static get Extension|property8() → core::int
+ ;
+static set Extension|property8(core::int? value) → void
+ ;
+static get Extension|property9() → core::int?
+ ;
+static set Extension|property9(core::int value) → void
+ ;
static method main() → dynamic
;
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.expect
index 89fd1f6..40207f8 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.expect
@@ -2,69 +2,120 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:14:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:21:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:16:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:22:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:48:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:19: Error: The type 'int?' of the getter 'A.property9' is not a subtype of the type 'int' of the setter 'A.property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:39:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:63:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:32:12: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:47:12: Context: This is the declaration of the getter 'B1.property3'.
// int? get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:54:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:69:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:14: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:53:14: Context: This is the declaration of the field 'B1.property6'.
// final int? property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:78:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:93:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:62:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:77:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// int? get property6; // error
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the overridden method ('property6').
// int property6;
// ^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
// int? get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:105:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:120:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:107:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:122:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4 implements D3 /* no need for error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:11:10: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:12:10: Context: This is the declaration of the setter 'property3'.
+// void set property3(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:131:12: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:132:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:10: Error: The type 'T?' of the getter 'property6' is not a subtype of the type 'T' of the setter 'property6'.
+// T? get property6 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:144:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(T i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:152:19: Error: The type 'int?' of the getter 'property9' is not a subtype of the type 'int' of the setter 'property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:153:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property4a => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+// T? get property4b => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property5 => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+// T? get property6 => 0; // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -81,6 +132,15 @@
abstract set property2(core::int? i) → void;
abstract get property3() → core::int?;
abstract set property3(core::int i) → void;
+ static get property7() → core::int
+ return 0;
+ static set property7(core::int value) → void {}
+ static get property8() → core::int
+ return 0;
+ static set property8(core::int? value) → void {}
+ static get property9() → core::int?
+ return 0;
+ static set property9(core::int value) → void {}
}
abstract class B1 extends core::Object {
final field core::int property4;
@@ -152,4 +212,73 @@
: super core::Object::•()
;
}
+extension Extension<T extends core::num = core::num> on core::int {
+ get property1 = self::Extension|get#property1;
+ get property2 = self::Extension|get#property2;
+ get property3 = self::Extension|get#property3;
+ get property4a = self::Extension|get#property4a;
+ get property4b = self::Extension|get#property4b;
+ get property5 = self::Extension|get#property5;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8 = get self::Extension|property8;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2 = self::Extension|set#property2;
+ set property3 = self::Extension|set#property3;
+ set property4a = self::Extension|set#property4a;
+ set property4b = self::Extension|set#property4b;
+ set property5 = self::Extension|set#property5;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8 = set self::Extension|property8;
+ static set property9 = set self::Extension|property9;
+}
+static get property1() → core::int
+ return 0;
+static set property1(core::int value) → void {}
+static get property2() → core::int
+ return 0;
+static set property2(core::int? value) → void {}
+static get property3() → core::int?
+ return 0;
+static set property3(core::int value) → void {}
+static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void {}
+static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+ return 0;
+static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
+static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property4a => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void {}
+static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+ T? get property4b => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void {}
+static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property5 => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void {}
+static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+ T? get property6 => 0; // error
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void {}
+static get Extension|property7() → core::int
+ return 0;
+static set Extension|property7(core::int value) → void {}
+static get Extension|property8() → core::int
+ return 0;
+static set Extension|property8(core::int? value) → void {}
+static get Extension|property9() → core::int?
+ return 0;
+static set Extension|property9(core::int value) → void {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.transformed.expect
index 89fd1f6..40207f8 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.strong.transformed.expect
@@ -2,69 +2,120 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:14:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:21:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:16:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:22:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:48:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:19: Error: The type 'int?' of the getter 'A.property9' is not a subtype of the type 'int' of the setter 'A.property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:39:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:63:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:32:12: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:47:12: Context: This is the declaration of the getter 'B1.property3'.
// int? get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:54:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:69:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:14: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:53:14: Context: This is the declaration of the field 'B1.property6'.
// final int? property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:78:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:93:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:62:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:77:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// int? get property6; // error
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the overridden method ('property6').
// int property6;
// ^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
// int? get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:105:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:120:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:107:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:122:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4 implements D3 /* no need for error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:11:10: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:12:10: Context: This is the declaration of the setter 'property3'.
+// void set property3(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:131:12: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:132:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:10: Error: The type 'T?' of the getter 'property6' is not a subtype of the type 'T' of the setter 'property6'.
+// T? get property6 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:144:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(T i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:152:19: Error: The type 'int?' of the getter 'property9' is not a subtype of the type 'int' of the setter 'property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:153:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property4a => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+// T? get property4b => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property5 => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+// T? get property6 => 0; // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -81,6 +132,15 @@
abstract set property2(core::int? i) → void;
abstract get property3() → core::int?;
abstract set property3(core::int i) → void;
+ static get property7() → core::int
+ return 0;
+ static set property7(core::int value) → void {}
+ static get property8() → core::int
+ return 0;
+ static set property8(core::int? value) → void {}
+ static get property9() → core::int?
+ return 0;
+ static set property9(core::int value) → void {}
}
abstract class B1 extends core::Object {
final field core::int property4;
@@ -152,4 +212,73 @@
: super core::Object::•()
;
}
+extension Extension<T extends core::num = core::num> on core::int {
+ get property1 = self::Extension|get#property1;
+ get property2 = self::Extension|get#property2;
+ get property3 = self::Extension|get#property3;
+ get property4a = self::Extension|get#property4a;
+ get property4b = self::Extension|get#property4b;
+ get property5 = self::Extension|get#property5;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8 = get self::Extension|property8;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2 = self::Extension|set#property2;
+ set property3 = self::Extension|set#property3;
+ set property4a = self::Extension|set#property4a;
+ set property4b = self::Extension|set#property4b;
+ set property5 = self::Extension|set#property5;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8 = set self::Extension|property8;
+ static set property9 = set self::Extension|property9;
+}
+static get property1() → core::int
+ return 0;
+static set property1(core::int value) → void {}
+static get property2() → core::int
+ return 0;
+static set property2(core::int? value) → void {}
+static get property3() → core::int?
+ return 0;
+static set property3(core::int value) → void {}
+static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void {}
+static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+ return 0;
+static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
+static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property4a => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void {}
+static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+ T? get property4b => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void {}
+static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property5 => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void {}
+static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+ T? get property6 => 0; // error
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void {}
+static get Extension|property7() → core::int
+ return 0;
+static set Extension|property7(core::int value) → void {}
+static get Extension|property8() → core::int
+ return 0;
+static set Extension|property8(core::int? value) → void {}
+static get Extension|property9() → core::int?
+ return 0;
+static set Extension|property9(core::int value) → void {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline.expect
index b6be33e..1bfebe7 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline.expect
@@ -1,3 +1,9 @@
+int get property1 => 0;
+void set property1(int value) {}
+int get property2 => 0;
+void set property2(int? value) {}
+int? get property3 => 0;
+void set property3(int value) {}
abstract class A {
int get property1;
void set property1(int i);
@@ -9,8 +15,13 @@
int? property5;
covariant int property6;
A(this.property4, this.property5, this.property6);
+ static int get property7 => 0;
+ static void set property7(int value) {}
+ static int get property8 => 0;
+ static void set property8(int? value) {}
+ static int? get property9 => 0;
+ static void set property9(int value) {}
}
-
abstract class B1 {
int get property1;
int get property2;
@@ -20,7 +31,6 @@
final int? property6;
B1(this.property4, this.property5, this.property6);
}
-
abstract class B2 implements B1 {
void set property1(int i);
void set property2(int? i);
@@ -29,7 +39,6 @@
void set property5(int? i);
void set property6(int i);
}
-
abstract class C1 {
void set property1(int i);
void set property2(int? i);
@@ -39,7 +48,6 @@
int property6;
C1(this.property4, this.property5, this.property6);
}
-
abstract class C2 implements C1 {
int get property1;
int get property2;
@@ -48,21 +56,18 @@
int get property5;
int? get property6;
}
-
abstract class D1 {
int get property1;
int get property2;
int? get property3;
}
-
abstract class D2 {
void set property1(int i);
void set property2(int? i);
void set property3(int i);
}
-
abstract class D3 implements D1, D2 {}
-
abstract class D4 implements D3 {}
-
+extension Extension<T extends num> (){}
+on int (){}
main() {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline_modelled.expect
index a071d28..30cbfa9 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.textual_outline_modelled.expect
@@ -6,6 +6,12 @@
int get property1;
int get property2;
int property4;
+ static int? get property9 => 0;
+ static int get property7 => 0;
+ static int get property8 => 0;
+ static void set property7(int value) {}
+ static void set property8(int? value) {}
+ static void set property9(int value) {}
void set property1(int i);
void set property2(int? i);
void set property3(int i);
@@ -65,4 +71,10 @@
abstract class D4 implements D3 {}
+int? get property3 => 0;
+int get property1 => 0;
+int get property2 => 0;
main() {}
+void set property1(int value) {}
+void set property2(int? value) {}
+void set property3(int value) {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.expect
index 89fd1f6..40207f8 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.expect
@@ -2,69 +2,120 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:14:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:21:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:16:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:22:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:48:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:19: Error: The type 'int?' of the getter 'A.property9' is not a subtype of the type 'int' of the setter 'A.property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:39:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:63:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:32:12: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:47:12: Context: This is the declaration of the getter 'B1.property3'.
// int? get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:54:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:69:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:14: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:53:14: Context: This is the declaration of the field 'B1.property6'.
// final int? property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:78:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:93:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:62:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:77:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// int? get property6; // error
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the overridden method ('property6').
// int property6;
// ^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
// int? get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:105:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:120:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:107:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:122:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4 implements D3 /* no need for error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:11:10: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:12:10: Context: This is the declaration of the setter 'property3'.
+// void set property3(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:131:12: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:132:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:10: Error: The type 'T?' of the getter 'property6' is not a subtype of the type 'T' of the setter 'property6'.
+// T? get property6 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:144:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(T i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:152:19: Error: The type 'int?' of the getter 'property9' is not a subtype of the type 'int' of the setter 'property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:153:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property4a => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+// T? get property4b => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property5 => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+// T? get property6 => 0; // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -81,6 +132,15 @@
abstract set property2(core::int? i) → void;
abstract get property3() → core::int?;
abstract set property3(core::int i) → void;
+ static get property7() → core::int
+ return 0;
+ static set property7(core::int value) → void {}
+ static get property8() → core::int
+ return 0;
+ static set property8(core::int? value) → void {}
+ static get property9() → core::int?
+ return 0;
+ static set property9(core::int value) → void {}
}
abstract class B1 extends core::Object {
final field core::int property4;
@@ -152,4 +212,73 @@
: super core::Object::•()
;
}
+extension Extension<T extends core::num = core::num> on core::int {
+ get property1 = self::Extension|get#property1;
+ get property2 = self::Extension|get#property2;
+ get property3 = self::Extension|get#property3;
+ get property4a = self::Extension|get#property4a;
+ get property4b = self::Extension|get#property4b;
+ get property5 = self::Extension|get#property5;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8 = get self::Extension|property8;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2 = self::Extension|set#property2;
+ set property3 = self::Extension|set#property3;
+ set property4a = self::Extension|set#property4a;
+ set property4b = self::Extension|set#property4b;
+ set property5 = self::Extension|set#property5;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8 = set self::Extension|property8;
+ static set property9 = set self::Extension|property9;
+}
+static get property1() → core::int
+ return 0;
+static set property1(core::int value) → void {}
+static get property2() → core::int
+ return 0;
+static set property2(core::int? value) → void {}
+static get property3() → core::int?
+ return 0;
+static set property3(core::int value) → void {}
+static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void {}
+static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+ return 0;
+static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
+static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property4a => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void {}
+static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+ T? get property4b => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void {}
+static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property5 => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void {}
+static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+ T? get property6 => 0; // error
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void {}
+static get Extension|property7() → core::int
+ return 0;
+static set Extension|property7(core::int value) → void {}
+static get Extension|property8() → core::int
+ return 0;
+static set Extension|property8(core::int? value) → void {}
+static get Extension|property9() → core::int?
+ return 0;
+static set Extension|property9(core::int value) → void {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.transformed.expect
index 89fd1f6..40207f8 100644
--- a/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart.weak.transformed.expect
@@ -2,69 +2,120 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:14:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:21:12: Error: The type 'int?' of the getter 'A.property3' is not a subtype of the type 'int' of the setter 'A.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:16:12: Context: This is the declaration of the setter 'A.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:22:12: Context: This is the declaration of the setter 'A.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:48:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:19: Error: The type 'int?' of the getter 'A.property9' is not a subtype of the type 'int' of the setter 'A.property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:39:19: Context: This is the declaration of the setter 'A.property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:63:12: Error: The type 'int?' of the inherited getter 'B1.property3' is not a subtype of the type 'int' of the setter 'B2.property3'.
// void set property3(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:32:12: Context: This is the declaration of the getter 'B1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:47:12: Context: This is the declaration of the getter 'B1.property3'.
// int? get property3;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:54:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:69:12: Error: The type 'int?' of the inherited field 'B1.property6' is not a subtype of the type 'int' of the setter 'B2.property6'.
// void set property6(int i); // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:38:14: Context: This is the declaration of the field 'B1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:53:14: Context: This is the declaration of the field 'B1.property6'.
// final int? property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:78:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:93:12: Error: The type 'int?' of the getter 'C2.property3' is not a subtype of the type 'int' of the inherited setter 'C1.property3'.
// int? get property3; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:62:12: Context: This is the declaration of the setter 'C1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:77:12: Context: This is the declaration of the setter 'C1.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The return type of the method 'C2.property6' is 'int?', which does not match the return type, 'int', of the overridden method, 'C1.property6'.
// Change to a subtype of 'int'.
// int? get property6; // error
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the overridden method ('property6').
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the overridden method ('property6').
// int property6;
// ^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:86:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:101:12: Error: The type 'int?' of the getter 'C2.property6' is not a subtype of the type 'int' of the inherited setter 'C1.property6'.
// int? get property6; // error
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:68:7: Context: This is the declaration of the setter 'C1.property6'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:83:7: Context: This is the declaration of the setter 'C1.property6'.
// int property6;
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:105:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:120:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D3 implements D1, D2 /* error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:107:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:122:16: Error: The type 'int?' of the inherited getter 'D1.property3' is not a subtype of the type 'int' of the inherited setter 'D2.property3'.
// abstract class D4 implements D3 /* no need for error on property3 */ {}
// ^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:94:12: Context: This is the declaration of the getter 'D1.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:109:12: Context: This is the declaration of the getter 'D1.property3'.
// int? get property3;
// ^^^^^^^^^
-// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:102:12: Context: This is the declaration of the setter 'D2.property3'.
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:117:12: Context: This is the declaration of the setter 'D2.property3'.
// void set property3(int i);
// ^^^^^^^^^
//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:11:10: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:12:10: Context: This is the declaration of the setter 'property3'.
+// void set property3(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:131:12: Error: The type 'int?' of the getter 'property3' is not a subtype of the type 'int' of the setter 'property3'.
+// int? get property3 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:132:12: Context: This is the declaration of the setter 'property3'.
+// void set property3(int i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:10: Error: The type 'T?' of the getter 'property6' is not a subtype of the type 'T' of the setter 'property6'.
+// T? get property6 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:144:12: Context: This is the declaration of the setter 'property6'.
+// void set property6(T i) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:152:19: Error: The type 'int?' of the getter 'property9' is not a subtype of the type 'int' of the setter 'property9'.
+// static int? get property9 => 0; // error
+// ^^^^^^^^^
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:153:19: Context: This is the declaration of the setter 'property9'.
+// static void set property9(int value) {}
+// ^^^^^^^^^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property4a => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+// T? get property4b => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+// T get property5 => 0; // ok
+// ^
+//
+// pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+// T? get property6 => 0; // error
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -81,6 +132,15 @@
abstract set property2(core::int? i) → void;
abstract get property3() → core::int?;
abstract set property3(core::int i) → void;
+ static get property7() → core::int
+ return 0;
+ static set property7(core::int value) → void {}
+ static get property8() → core::int
+ return 0;
+ static set property8(core::int? value) → void {}
+ static get property9() → core::int?
+ return 0;
+ static set property9(core::int value) → void {}
}
abstract class B1 extends core::Object {
final field core::int property4;
@@ -152,4 +212,73 @@
: super core::Object::•()
;
}
+extension Extension<T extends core::num = core::num> on core::int {
+ get property1 = self::Extension|get#property1;
+ get property2 = self::Extension|get#property2;
+ get property3 = self::Extension|get#property3;
+ get property4a = self::Extension|get#property4a;
+ get property4b = self::Extension|get#property4b;
+ get property5 = self::Extension|get#property5;
+ get property6 = self::Extension|get#property6;
+ static get property7 = get self::Extension|property7;
+ static get property8 = get self::Extension|property8;
+ static get property9 = get self::Extension|property9;
+ set property1 = self::Extension|set#property1;
+ set property2 = self::Extension|set#property2;
+ set property3 = self::Extension|set#property3;
+ set property4a = self::Extension|set#property4a;
+ set property4b = self::Extension|set#property4b;
+ set property5 = self::Extension|set#property5;
+ set property6 = self::Extension|set#property6;
+ static set property7 = set self::Extension|property7;
+ static set property8 = set self::Extension|property8;
+ static set property9 = set self::Extension|property9;
+}
+static get property1() → core::int
+ return 0;
+static set property1(core::int value) → void {}
+static get property2() → core::int
+ return 0;
+static set property2(core::int? value) → void {}
+static get property3() → core::int?
+ return 0;
+static set property3(core::int value) → void {}
+static method Extension|get#property1<T extends core::num = core::num>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property1<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
+static method Extension|get#property2<T extends core::num = core::num>(final core::int #this) → core::int
+ return 0;
+static method Extension|set#property2<T extends core::num = core::num>(final core::int #this, core::int? i) → void {}
+static method Extension|get#property3<T extends core::num = core::num>(final core::int #this) → core::int?
+ return 0;
+static method Extension|set#property3<T extends core::num = core::num>(final core::int #this, core::int i) → void {}
+static method Extension|get#property4a<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4a::T
+ return let final<BottomType> #t1 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:134:23: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property4a => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4a<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4a::T i) → void {}
+static method Extension|get#property4b<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property4b::T?
+ return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:137:24: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+ T? get property4b => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property4b<T extends core::num = core::num>(final core::int #this, self::Extension|set#property4b::T? i) → void {}
+static method Extension|get#property5<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property5::T
+ return let final<BottomType> #t3 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:140:22: Error: A value of type 'int' can't be returned from a function with return type 'T'.
+ T get property5 => 0; // ok
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property5<T extends core::num = core::num>(final core::int #this, self::Extension|set#property5::T? i) → void {}
+static method Extension|get#property6<T extends core::num = core::num>(final core::int #this) → self::Extension|get#property6::T?
+ return let final<BottomType> #t4 = invalid-expression "pkg/front_end/testcases/nnbd/getter_vs_setter_type_nnbd.dart:143:23: Error: A value of type 'int' can't be returned from a function with return type 'T?'.
+ T? get property6 => 0; // error
+ ^" in 0 as{TypeError,ForNonNullableByDefault} <BottomType>;
+static method Extension|set#property6<T extends core::num = core::num>(final core::int #this, self::Extension|set#property6::T i) → void {}
+static get Extension|property7() → core::int
+ return 0;
+static set Extension|property7(core::int value) → void {}
+static get Extension|property8() → core::int
+ return 0;
+static set Extension|property8(core::int? value) → void {}
+static get Extension|property9() → core::int?
+ return 0;
+static set Extension|property9(core::int value) → void {}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index b53cc5e..17eae7c 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -41,6 +41,7 @@
extensions/extension_call: FormatterCrash
extensions/extension_constructor: FormatterCrash
extensions/extension_field_with_type_parameter_usage: FormatterCrash
+extensions/extension_member_conflict: FormatterCrash
extensions/extension_methods: FormatterCrash
extensions/extension_setter: FormatterCrash
extensions/extension_setter_error: FormatterCrash
@@ -108,6 +109,7 @@
general/error_recovery/issue_39230.crash: FormatterCrash
general/error_recovery/issue_39958_01: FormatterCrash
general/function_type_default_value: FormatterCrash
+general/getter_vs_setter_type: FormatterCrash
general/incomplete_field_formal_parameter: FormatterCrash
general/invalid_operator2: FormatterCrash
general/invalid_operator: FormatterCrash
@@ -171,7 +173,9 @@
nnbd/external_field_errors: FormatterCrash
nnbd/external_fields: FormatterCrash
nnbd/forbidden_supers: FormatterCrash
+nnbd/getter_vs_setter_type: FormatterCrash
nnbd/getter_vs_setter_type_late: FormatterCrash
+nnbd/getter_vs_setter_type_nnbd: FormatterCrash
nnbd/infer_if_null: FormatterCrash
nnbd/inheritance_from_opt_in: FormatterCrash
nnbd/issue40805: FormatterCrash
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index 57bb31a..baa4ff4 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -387,29 +387,6 @@
return ((mask >> position) & 1) != 0;
}
- // Decode integer in SLEB128 format from |data| and update |byte_index|.
- template <typename ValueType>
- static ValueType DecodeSLEB128(const uint8_t* data,
- const intptr_t data_length,
- intptr_t* byte_index) {
- using Unsigned = typename std::make_unsigned<ValueType>::type;
- ASSERT(*byte_index < data_length);
- uword shift = 0;
- Unsigned value = 0;
- uint8_t part = 0;
- do {
- part = data[(*byte_index)++];
- value |= static_cast<Unsigned>(part & 0x7f) << shift;
- shift += 7;
- } while ((part & 0x80) != 0);
-
- if ((shift < (sizeof(ValueType) * CHAR_BIT)) && ((part & 0x40) != 0)) {
- const Unsigned kMax = std::numeric_limits<Unsigned>::max();
- value |= static_cast<Unsigned>(kMax << shift);
- }
- return static_cast<ValueType>(value);
- }
-
static char* StrError(int err, char* buffer, size_t bufsize);
// Not all platforms support strndup.
diff --git a/runtime/vm/bitmap.cc b/runtime/vm/bitmap.cc
index d5e25dd..334c46b 100644
--- a/runtime/vm/bitmap.cc
+++ b/runtime/vm/bitmap.cc
@@ -77,7 +77,7 @@
}
}
-void BitmapBuilder::AppendAsBytesTo(GrowableArray<uint8_t>* bytes) const {
+void BitmapBuilder::AppendAsBytesTo(BaseWriteStream* stream) const {
// Early return if there are no bits in the payload to copy.
if (Length() == 0) return;
@@ -94,19 +94,20 @@
payload_size = total_size;
extra_size = 0;
}
+#if defined(DEBUG)
+ // Make sure any bits in the payload beyond the bit length if we're not
+ // appending trailing zeroes are cleared to ensure deterministic snapshots.
+ if (extra_size == 0 && Length() % kBitsPerByte != 0) {
+ const int8_t mask = (1 << (Length() % kBitsPerByte)) - 1;
+ ASSERT_EQUAL(data_[payload_size - 1], (data_[payload_size - 1] & mask));
+ }
+#endif
for (intptr_t i = 0; i < payload_size; i++) {
- bytes->Add(data_[i]);
+ stream->WriteByte(data_[i]);
}
for (intptr_t i = 0; i < extra_size; i++) {
- bytes->Add(0U);
+ stream->WriteByte(0U);
}
- // Make sure any bits in the payload beyond the bit length are cleared to
- // ensure deterministic snapshots.
-#if defined(DEBUG)
- if (Length() % kBitsPerByte == 0) return;
- const int8_t mask = (1 << (Length() % kBitsPerByte)) - 1;
- ASSERT(bytes->Last() == (bytes->Last() & mask));
-#endif
}
bool BitmapBuilder::GetBit(intptr_t bit_offset) const {
diff --git a/runtime/vm/bitmap.h b/runtime/vm/bitmap.h
index 878a834..ed08009 100644
--- a/runtime/vm/bitmap.h
+++ b/runtime/vm/bitmap.h
@@ -6,7 +6,7 @@
#define RUNTIME_VM_BITMAP_H_
#include "vm/allocation.h"
-#include "vm/growable_array.h"
+#include "vm/datastream.h"
#include "vm/thread_state.h"
#include "vm/zone.h"
@@ -44,7 +44,7 @@
void SetRange(intptr_t min, intptr_t max, bool value);
void Print() const;
- void AppendAsBytesTo(GrowableArray<uint8_t>* bytes) const;
+ void AppendAsBytesTo(BaseWriteStream* stream) const;
private:
static const intptr_t kInitialSizeInBytes = 16;
diff --git a/runtime/vm/bitmap_test.cc b/runtime/vm/bitmap_test.cc
index 2c7f3d9..c3cd203 100644
--- a/runtime/vm/bitmap_test.cc
+++ b/runtime/vm/bitmap_test.cc
@@ -16,8 +16,8 @@
static const uint32_t kTestPcOffset = 0x4;
static const intptr_t kTestSpillSlotBitCount = 0;
-static CompressedStackMapsPtr MapsFromBuilder(BitmapBuilder* bmap) {
- CompressedStackMapsBuilder builder;
+static CompressedStackMapsPtr MapsFromBuilder(Zone* zone, BitmapBuilder* bmap) {
+ CompressedStackMapsBuilder builder(zone);
builder.AddEntry(kTestPcOffset, bmap, kTestSpillSlotBitCount);
return builder.Finalize();
}
@@ -51,8 +51,9 @@
}
// Create a CompressedStackMaps object and verify its contents.
- const auto& maps1 = CompressedStackMaps::Handle(MapsFromBuilder(builder1));
- CompressedStackMapsIterator it1(maps1);
+ const auto& maps1 = CompressedStackMaps::Handle(
+ thread->zone(), MapsFromBuilder(thread->zone(), builder1));
+ CompressedStackMaps::Iterator it1(thread, maps1);
EXPECT(it1.MoveNext());
EXPECT_EQ(kTestPcOffset, it1.pc_offset());
@@ -83,8 +84,9 @@
EXPECT(!builder1->Get(i));
}
- const auto& maps2 = CompressedStackMaps::Handle(MapsFromBuilder(builder1));
- CompressedStackMapsIterator it2(maps2);
+ const auto& maps2 = CompressedStackMaps::Handle(
+ thread->zone(), MapsFromBuilder(thread->zone(), builder1));
+ CompressedStackMaps::Iterator it2(thread, maps2);
EXPECT(it2.MoveNext());
EXPECT_EQ(kTestPcOffset, it2.pc_offset());
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index 2dc5584..edce815 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -35,14 +35,13 @@
PcDescriptorsLayout::KindAndMetadata::Encode(kind, try_index,
yield_index);
- PcDescriptors::EncodeInteger(&encoded_data_, kind_and_metadata);
- PcDescriptors::EncodeInteger(&encoded_data_, pc_offset - prev_pc_offset);
+ encoded_data_.WriteSLEB128(kind_and_metadata);
+ encoded_data_.WriteSLEB128(pc_offset - prev_pc_offset);
prev_pc_offset = pc_offset;
if (!FLAG_precompiled_mode) {
- PcDescriptors::EncodeInteger(&encoded_data_, deopt_id - prev_deopt_id);
- PcDescriptors::EncodeInteger(&encoded_data_,
- token_pos.value() - prev_token_pos);
+ encoded_data_.WriteSLEB128(deopt_id - prev_deopt_id);
+ encoded_data_.WriteSLEB128(token_pos.value() - prev_token_pos);
prev_deopt_id = deopt_id;
prev_token_pos = token_pos.value();
}
@@ -50,22 +49,11 @@
}
PcDescriptorsPtr DescriptorList::FinalizePcDescriptors(uword entry_point) {
- if (encoded_data_.length() == 0) {
+ if (encoded_data_.bytes_written() == 0) {
return Object::empty_descriptors().raw();
}
- return PcDescriptors::New(&encoded_data_);
-}
-
-// Encode unsigned integer |value| in LEB128 format and store into |data|.
-void CompressedStackMapsBuilder::EncodeLEB128(GrowableArray<uint8_t>* data,
- uintptr_t value) {
- while (true) {
- uint8_t part = value & 0x7f;
- value >>= 7;
- if (value != 0) part |= 0x80;
- data->Add(part);
- if (value == 0) break;
- }
+ return PcDescriptors::New(encoded_data_.buffer(),
+ encoded_data_.bytes_written());
}
void CompressedStackMapsBuilder::AddEntry(intptr_t pc_offset,
@@ -74,179 +62,22 @@
ASSERT(bitmap != nullptr);
ASSERT(pc_offset > last_pc_offset_);
ASSERT(spill_slot_bit_count >= 0 && spill_slot_bit_count <= bitmap->Length());
- auto const pc_delta = pc_offset - last_pc_offset_;
- auto const non_spill_slot_bit_count = bitmap->Length() - spill_slot_bit_count;
- EncodeLEB128(&encoded_bytes_, pc_delta);
- EncodeLEB128(&encoded_bytes_, spill_slot_bit_count);
- EncodeLEB128(&encoded_bytes_, non_spill_slot_bit_count);
+ const uword pc_delta = pc_offset - last_pc_offset_;
+ const uword non_spill_slot_bit_count =
+ bitmap->Length() - spill_slot_bit_count;
+ encoded_bytes_.WriteLEB128(pc_delta);
+ encoded_bytes_.WriteLEB128(spill_slot_bit_count);
+ encoded_bytes_.WriteLEB128(non_spill_slot_bit_count);
bitmap->AppendAsBytesTo(&encoded_bytes_);
last_pc_offset_ = pc_offset;
}
CompressedStackMapsPtr CompressedStackMapsBuilder::Finalize() const {
- if (encoded_bytes_.length() == 0) return CompressedStackMaps::null();
- return CompressedStackMaps::NewInlined(encoded_bytes_);
-}
-
-CompressedStackMapsIterator::CompressedStackMapsIterator(
- const CompressedStackMaps& maps,
- const CompressedStackMaps& global_table)
- : maps_(maps),
- bits_container_(maps_.UsesGlobalTable() ? global_table : maps_) {
- ASSERT(!maps_.IsGlobalTable());
- ASSERT(!maps_.UsesGlobalTable() || bits_container_.IsGlobalTable());
-}
-
-CompressedStackMapsIterator::CompressedStackMapsIterator(
- const CompressedStackMaps& maps)
- : CompressedStackMapsIterator(
- maps,
- // Only look up the global table if the map will end up using it.
- maps.UsesGlobalTable() ? CompressedStackMaps::Handle(
- Thread::Current()
- ->isolate()
- ->object_store()
- ->canonicalized_stack_map_entries())
- : Object::null_compressed_stack_maps()) {}
-
-CompressedStackMapsIterator::CompressedStackMapsIterator(
- const CompressedStackMapsIterator& it)
- : maps_(it.maps_),
- bits_container_(it.bits_container_),
- next_offset_(it.next_offset_),
- current_pc_offset_(it.current_pc_offset_),
- current_global_table_offset_(it.current_global_table_offset_),
- current_spill_slot_bit_count_(it.current_spill_slot_bit_count_),
- current_non_spill_slot_bit_count_(it.current_spill_slot_bit_count_),
- current_bits_offset_(it.current_bits_offset_) {}
-
-// Decode unsigned integer in LEB128 format from the payload of |maps| and
-// update |byte_index|.
-uintptr_t CompressedStackMapsIterator::DecodeLEB128(
- const CompressedStackMaps& maps,
- uintptr_t* byte_index) {
- uword shift = 0;
- uintptr_t value = 0;
- uint8_t part = 0;
- do {
- ASSERT(*byte_index < maps.payload_size());
- part = maps.PayloadByte((*byte_index)++);
- value |= static_cast<uintptr_t>(part & 0x7f) << shift;
- shift += 7;
- } while ((part & 0x80) != 0);
-
- return value;
-}
-
-bool CompressedStackMapsIterator::MoveNext() {
- // Empty CompressedStackMaps are represented as null values.
- if (maps_.IsNull() || next_offset_ >= maps_.payload_size()) return false;
- uintptr_t offset = next_offset_;
-
- auto const pc_delta = DecodeLEB128(maps_, &offset);
- ASSERT(pc_delta <= (kMaxUint32 - current_pc_offset_));
- current_pc_offset_ += pc_delta;
-
- // Table-using CSMs have a table offset after the PC offset delta, whereas
- // the post-delta part of inlined entries has the same information as
- // global table entries.
- if (maps_.UsesGlobalTable()) {
- current_global_table_offset_ = DecodeLEB128(maps_, &offset);
- ASSERT(current_global_table_offset_ < bits_container_.payload_size());
-
- // Since generally we only use entries in the GC and the GC only needs
- // the rest of the entry information if the PC offset matches, we lazily
- // load and cache the information stored in the global object when it is
- // actually requested.
- current_spill_slot_bit_count_ = -1;
- current_non_spill_slot_bit_count_ = -1;
- current_bits_offset_ = -1;
- } else {
- current_spill_slot_bit_count_ = DecodeLEB128(maps_, &offset);
- ASSERT(current_spill_slot_bit_count_ >= 0);
-
- current_non_spill_slot_bit_count_ = DecodeLEB128(maps_, &offset);
- ASSERT(current_non_spill_slot_bit_count_ >= 0);
-
- const auto stackmap_bits =
- current_spill_slot_bit_count_ + current_non_spill_slot_bit_count_;
- const uintptr_t stackmap_size =
- Utils::RoundUp(stackmap_bits, kBitsPerByte) >> kBitsPerByteLog2;
- ASSERT(stackmap_size <= (maps_.payload_size() - offset));
-
- current_bits_offset_ = offset;
- offset += stackmap_size;
+ if (encoded_bytes_.bytes_written() == 0) {
+ return Object::empty_compressed_stackmaps().raw();
}
-
- next_offset_ = offset;
- return true;
-}
-
-intptr_t CompressedStackMapsIterator::Length() {
- EnsureFullyLoadedEntry();
- return current_spill_slot_bit_count_ + current_non_spill_slot_bit_count_;
-}
-intptr_t CompressedStackMapsIterator::SpillSlotBitCount() {
- EnsureFullyLoadedEntry();
- return current_spill_slot_bit_count_;
-}
-
-bool CompressedStackMapsIterator::IsObject(intptr_t bit_index) {
- EnsureFullyLoadedEntry();
- ASSERT(!bits_container_.IsNull());
- ASSERT(bit_index >= 0 && bit_index < Length());
- const intptr_t byte_index = bit_index >> kBitsPerByteLog2;
- const intptr_t bit_remainder = bit_index & (kBitsPerByte - 1);
- uint8_t byte_mask = 1U << bit_remainder;
- const intptr_t byte_offset = current_bits_offset_ + byte_index;
- return (bits_container_.PayloadByte(byte_offset) & byte_mask) != 0;
-}
-
-void CompressedStackMapsIterator::LazyLoadGlobalTableEntry() {
- ASSERT(maps_.UsesGlobalTable() && bits_container_.IsGlobalTable());
- ASSERT(HasLoadedEntry());
- ASSERT(current_global_table_offset_ < bits_container_.payload_size());
-
- uintptr_t offset = current_global_table_offset_;
- current_spill_slot_bit_count_ = DecodeLEB128(bits_container_, &offset);
- ASSERT(current_spill_slot_bit_count_ >= 0);
-
- current_non_spill_slot_bit_count_ = DecodeLEB128(bits_container_, &offset);
- ASSERT(current_non_spill_slot_bit_count_ >= 0);
-
- const auto stackmap_bits = Length();
- const uintptr_t stackmap_size =
- Utils::RoundUp(stackmap_bits, kBitsPerByte) >> kBitsPerByteLog2;
- ASSERT(stackmap_size <= (bits_container_.payload_size() - offset));
-
- current_bits_offset_ = offset;
-}
-
-const char* CompressedStackMapsIterator::ToCString(Zone* zone) const {
- ZoneTextBuffer b(zone, 100);
- CompressedStackMapsIterator it(*this);
- // If we haven't loaded an entry yet, do so (but don't skip the current
- // one if we have!)
- if (!it.HasLoadedEntry()) {
- if (!it.MoveNext()) return b.buffer();
- }
- bool first_entry = true;
- do {
- if (first_entry) {
- first_entry = false;
- } else {
- b.AddString("\n");
- }
- b.Printf("0x%08x: ", it.pc_offset());
- for (intptr_t i = 0, n = it.Length(); i < n; i++) {
- b.AddString(it.IsObject(i) ? "1" : "0");
- }
- } while (it.MoveNext());
- return b.buffer();
-}
-
-const char* CompressedStackMapsIterator::ToCString() const {
- return ToCString(Thread::Current()->zone());
+ return CompressedStackMaps::NewInlined(encoded_bytes_.buffer(),
+ encoded_bytes_.bytes_written());
}
ExceptionHandlersPtr ExceptionHandlerList::FinalizeExceptionHandlers(
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index bef3ef8..f42190b 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -18,8 +18,8 @@
class DescriptorList : public ZoneAllocated {
public:
- explicit DescriptorList(intptr_t initial_capacity)
- : encoded_data_(initial_capacity),
+ explicit DescriptorList(Zone* zone)
+ : encoded_data_(zone, kInitialStreamSize),
prev_pc_offset(0),
prev_deopt_id(0),
prev_token_pos(0) {}
@@ -36,7 +36,9 @@
PcDescriptorsPtr FinalizePcDescriptors(uword entry_point);
private:
- GrowableArray<uint8_t> encoded_data_;
+ static constexpr intptr_t kInitialStreamSize = 64;
+
+ ZoneWriteStream encoded_data_;
intptr_t prev_pc_offset;
intptr_t prev_deopt_id;
@@ -47,9 +49,8 @@
class CompressedStackMapsBuilder : public ZoneAllocated {
public:
- CompressedStackMapsBuilder() : encoded_bytes_() {}
-
- static void EncodeLEB128(GrowableArray<uint8_t>* data, uintptr_t value);
+ explicit CompressedStackMapsBuilder(Zone* zone)
+ : encoded_bytes_(zone, kInitialStreamSize) {}
void AddEntry(intptr_t pc_offset,
BitmapBuilder* bitmap,
@@ -58,82 +59,13 @@
CompressedStackMapsPtr Finalize() const;
private:
+ static constexpr intptr_t kInitialStreamSize = 16;
+
+ ZoneWriteStream encoded_bytes_;
intptr_t last_pc_offset_ = 0;
- GrowableArray<uint8_t> encoded_bytes_;
DISALLOW_COPY_AND_ASSIGN(CompressedStackMapsBuilder);
};
-class CompressedStackMapsIterator : public ValueObject {
- public:
- // We use the null value to represent CompressedStackMaps with no
- // entries, so any CompressedStackMaps arguments to constructors can be null.
- CompressedStackMapsIterator(const CompressedStackMaps& maps,
- const CompressedStackMaps& global_table);
- explicit CompressedStackMapsIterator(const CompressedStackMaps& maps);
-
- explicit CompressedStackMapsIterator(const CompressedStackMapsIterator& it);
-
- // Loads the next entry from [maps_], if any. If [maps_] is the null
- // value, this always returns false.
- bool MoveNext();
-
- // Finds the entry with the given PC offset starting at the current
- // position of the iterator. If [maps_] is the null value, this always
- // returns false.
- bool Find(uint32_t pc_offset) {
- // We should never have an entry with a PC offset of 0 inside an
- // non-empty CSM, so fail.
- if (pc_offset == 0) return false;
- do {
- if (current_pc_offset_ >= pc_offset) break;
- } while (MoveNext());
- return current_pc_offset_ == pc_offset;
- }
-
- // Methods for accessing parts of an entry should not be called until
- // a successful MoveNext() or Find() call has been made.
-
- uint32_t pc_offset() const {
- ASSERT(HasLoadedEntry());
- return current_pc_offset_;
- }
- // We lazily load and cache information from the global table if the
- // CSM uses it, so these methods cannot be const.
- intptr_t Length();
- intptr_t SpillSlotBitCount();
- bool IsObject(intptr_t bit_offset);
-
- void EnsureFullyLoadedEntry() {
- ASSERT(HasLoadedEntry());
- if (current_spill_slot_bit_count_ < 0) {
- LazyLoadGlobalTableEntry();
- }
- ASSERT(current_spill_slot_bit_count_ >= 0);
- }
-
- const char* ToCString(Zone* zone) const;
- const char* ToCString() const;
-
- private:
- static uintptr_t DecodeLEB128(const CompressedStackMaps& data,
- uintptr_t* byte_index);
- bool HasLoadedEntry() const { return next_offset_ > 0; }
- void LazyLoadGlobalTableEntry();
-
- const CompressedStackMaps& maps_;
- const CompressedStackMaps& bits_container_;
-
- uintptr_t next_offset_ = 0;
- uint32_t current_pc_offset_ = 0;
- // Only used when looking up non-PC information in the global table.
- uintptr_t current_global_table_offset_ = 0;
- intptr_t current_spill_slot_bit_count_ = -1;
- intptr_t current_non_spill_slot_bit_count_ = -1;
- intptr_t current_bits_offset_ = -1;
-
- friend class StackMapEntry;
-};
-
class ExceptionHandlerList : public ZoneAllocated {
public:
struct HandlerDesc {
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 8c192b5..d8e2c41 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -100,7 +100,7 @@
int call_count = 0;
PcDescriptors::Iterator iter(descriptors,
PcDescriptorsLayout::kUnoptStaticCall);
- CompressedStackMapsBuilder compressed_maps_builder;
+ CompressedStackMapsBuilder compressed_maps_builder(thread->zone());
while (iter.MoveNext()) {
compressed_maps_builder.AddEntry(iter.PcOffset(), stack_bitmap, 0);
++call_count;
@@ -121,7 +121,7 @@
}
ISOLATE_UNIT_TEST_CASE(DescriptorList_TokenPositions) {
- DescriptorList* descriptors = new DescriptorList(64);
+ DescriptorList* descriptors = new DescriptorList(thread->zone());
ASSERT(descriptors != NULL);
const intptr_t token_positions[] = {
kMinInt32,
diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc
index 0edfb70..e7e73a5 100644
--- a/runtime/vm/compiler/assembler/disassembler.cc
+++ b/runtime/vm/compiler/assembler/disassembler.cc
@@ -220,7 +220,8 @@
const char* function_info,
const Code& code,
bool optimized) {
- Zone* zone = Thread::Current()->zone();
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
LocalVarDescriptors& var_descriptors = LocalVarDescriptors::Handle(zone);
if (FLAG_print_variable_descriptors) {
var_descriptors = code.GetLocalVarDescriptors();
@@ -290,13 +291,16 @@
}
#endif // !defined(DART_PRECOMPILED_RUNTIME)
- THR_Print("StackMaps for function '%s' {\n", function_fullname);
- if (code.compressed_stackmaps() != CompressedStackMaps::null()) {
+ {
const auto& stackmaps =
CompressedStackMaps::Handle(zone, code.compressed_stackmaps());
- THR_Print("%s\n", stackmaps.ToCString());
+ CompressedStackMaps::Iterator it(thread, stackmaps);
+ TextBuffer buffer(100);
+ buffer.Printf("StackMaps for function '%s' {\n", function_fullname);
+ it.WriteToBuffer(&buffer, "\n");
+ buffer.AddString("}\n");
+ THR_Print("%s", buffer.buffer());
}
- THR_Print("}\n");
if (FLAG_print_variable_descriptors) {
THR_Print("Variable Descriptors for function '%s' {\n", function_fullname);
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 361ccbe..6a01f8a 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -195,7 +195,9 @@
}
void FlowGraphCompiler::InitCompiler() {
- pc_descriptors_list_ = new (zone()) DescriptorList(64);
+ compressed_stackmaps_builder_ =
+ new (zone()) CompressedStackMapsBuilder(zone());
+ pc_descriptors_list_ = new (zone()) DescriptorList(zone());
exception_handlers_list_ = new (zone()) ExceptionHandlerList();
#if defined(DART_PRECOMPILER)
catch_entry_moves_maps_builder_ = new (zone()) CatchEntryMovesMapBuilder();
@@ -1001,8 +1003,8 @@
bitmap->Set(bitmap->Length(), true);
}
- compressed_stackmaps_builder()->AddEntry(assembler()->CodeSize(), bitmap,
- spill_area_size);
+ compressed_stackmaps_builder_->AddEntry(assembler()->CodeSize(), bitmap,
+ spill_area_size);
}
}
@@ -1157,15 +1159,11 @@
}
void FlowGraphCompiler::FinalizeStackMaps(const Code& code) {
- if (compressed_stackmaps_builder_ == NULL) {
- code.set_compressed_stackmaps(
- CompressedStackMaps::Handle(CompressedStackMaps::null()));
- } else {
- // Finalize the compressed stack maps and add it to the code object.
- const auto& maps =
- CompressedStackMaps::Handle(compressed_stackmaps_builder_->Finalize());
- code.set_compressed_stackmaps(maps);
- }
+ ASSERT(compressed_stackmaps_builder_ != NULL);
+ // Finalize the compressed stack maps and add it to the code object.
+ const auto& maps =
+ CompressedStackMaps::Handle(compressed_stackmaps_builder_->Finalize());
+ code.set_compressed_stackmaps(maps);
}
void FlowGraphCompiler::FinalizeVarDescriptors(const Code& code) {
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.h b/runtime/vm/compiler/backend/flow_graph_compiler.h
index 9b1764e..cff19a26 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.h
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.h
@@ -1108,13 +1108,6 @@
intptr_t GetOptimizationThreshold() const;
- CompressedStackMapsBuilder* compressed_stackmaps_builder() {
- if (compressed_stackmaps_builder_ == NULL) {
- compressed_stackmaps_builder_ = new CompressedStackMapsBuilder();
- }
- return compressed_stackmaps_builder_;
- }
-
#if defined(DEBUG)
void FrameStateUpdateWith(Instruction* instr);
void FrameStatePush(Definition* defn);
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index e0d3ea9..f130a7a 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -973,7 +973,7 @@
const ObjectPool& pool = ObjectPool::Handle(Z, bytecode.object_pool());
AbstractType& handler_type = AbstractType::Handle(Z);
Array& handler_types = Array::Handle(Z);
- DescriptorList* pc_descriptors_list = new (Z) DescriptorList(64);
+ DescriptorList* pc_descriptors_list = new (Z) DescriptorList(Z);
ExceptionHandlerList* exception_handlers_list =
new (Z) ExceptionHandlerList();
diff --git a/runtime/vm/datastream.h b/runtime/vm/datastream.h
index 81f2c82..7da4532 100644
--- a/runtime/vm/datastream.h
+++ b/runtime/vm/datastream.h
@@ -23,16 +23,38 @@
static const uint8_t kEndByteMarker = (255 - kMaxDataPerByte);
static const uint8_t kEndUnsignedByteMarker = (255 - kMaxUnsignedDataPerByte);
+struct LEB128Constants : AllStatic {
+ // Convenience template for ensuring non-signed types trigger SFINAE.
+ template <typename T, typename S>
+ using only_if_signed =
+ typename std::enable_if<std::is_signed<T>::value, S>::type;
+
+ // Convenience template for ensuring signed types trigger SFINAE.
+ template <typename T, typename S>
+ using only_if_unsigned =
+ typename std::enable_if<std::is_unsigned<T>::value, S>::type;
+
+ // (S)LEB128 encodes 7 bits of data per byte (hence 128).
+ static constexpr uint8_t kDataBitsPerByte = 7;
+ static constexpr uint8_t kDataByteMask = (1 << kDataBitsPerByte) - 1;
+ // If more data follows a given data byte, the high bit is set.
+ static constexpr uint8_t kMoreDataMask = (1 << kDataBitsPerByte);
+ // For SLEB128, the high bit in the data of the last byte is the sign bit.
+ static constexpr uint8_t kSignMask = (1 << (kDataBitsPerByte - 1));
+};
+
+class NonStreamingWriteStream;
+
// Stream for reading various types from a buffer.
class ReadStream : public ValueObject {
public:
ReadStream(const uint8_t* buffer, intptr_t size)
: buffer_(buffer), current_(buffer), end_(buffer + size) {}
- void SetStream(const uint8_t* buffer, intptr_t size) {
- buffer_ = buffer;
- current_ = buffer;
- end_ = buffer + size;
+ // Creates a ReadStream that starts at a given position in the buffer.
+ ReadStream(const uint8_t* buffer, intptr_t size, intptr_t pos)
+ : ReadStream(buffer, size) {
+ SetPosition(pos);
}
template <int N, typename T>
@@ -78,7 +100,7 @@
intptr_t Position() const { return current_ - buffer_; }
void SetPosition(intptr_t value) {
- ASSERT((end_ - buffer_) > value);
+ ASSERT((end_ - buffer_) >= value);
current_ = buffer_ + value;
}
@@ -106,19 +128,72 @@
}
uword ReadWordWith32BitReads() {
- constexpr intptr_t kNumBytesPerRead32 = sizeof(uint32_t);
- constexpr intptr_t kNumRead32PerWord = sizeof(uword) / kNumBytesPerRead32;
- constexpr intptr_t kNumBitsPerRead32 = kNumBytesPerRead32 * kBitsPerByte;
+ constexpr intptr_t kNumRead32PerWord = kBitsPerWord / kBitsPerInt32;
uword value = 0;
for (intptr_t j = 0; j < kNumRead32PerWord; j++) {
- const auto partial_value = Raw<kNumBytesPerRead32, uint32_t>::Read(this);
- value |= (static_cast<uword>(partial_value) << (j * kNumBitsPerRead32));
+ const auto partial_value = Raw<kInt32Size, uint32_t>::Read(this);
+ value |= (static_cast<uword>(partial_value) << (j * kBitsPerInt32));
}
return value;
}
private:
+ using C = LEB128Constants;
+
+ public:
+ template <typename T = uintptr_t>
+ C::only_if_unsigned<T, T> ReadLEB128() {
+ constexpr intptr_t kBitsPerT = kBitsPerByte * sizeof(T);
+ T r = 0;
+ uint8_t s = 0;
+ uint8_t b;
+ do {
+ ASSERT(s < kBitsPerT);
+ b = ReadByte();
+ r |= static_cast<T>(b & C::kDataByteMask) << s;
+ s += C::kDataBitsPerByte;
+ } while ((b & C::kMoreDataMask) != 0);
+ ASSERT(s < C::kDataBitsPerByte + kBitsPerT);
+ return r;
+ }
+
+ template <typename T>
+ C::only_if_signed<T, T> ReadLEB128() {
+ return bit_cast<T>(ReadLEB128<typename std::make_unsigned<T>::type>());
+ }
+
+ template <typename T>
+ C::only_if_unsigned<T, T> ReadSLEB128() {
+ constexpr intptr_t kBitsPerT = kBitsPerByte * sizeof(T);
+ T r = 0;
+ uint8_t s = 0;
+ uint8_t b;
+ do {
+ ASSERT(s < kBitsPerT);
+ b = ReadByte();
+ r |= static_cast<T>(b & C::kDataByteMask) << s;
+ s += C::kDataBitsPerByte;
+ } while ((b & C::kMoreDataMask) != 0);
+ ASSERT(s < C::kDataBitsPerByte + kBitsPerT);
+ // At this point, [s] contains how many data bits have made it into the
+ // value. If the value is negative and the count of data bits is less than
+ // the size of the value, then we need to extend the sign by setting the
+ // remaining (unset) most significant bits (MSBs).
+ T sign_bits = 0;
+ if ((b & C::kSignMask) != 0 && s < kBitsPerT) {
+ // Create a bitmask for the current data bits and invert it.
+ sign_bits = ~((static_cast<T>(1) << s) - 1);
+ }
+ return r | sign_bits;
+ }
+
+ template <typename T = intptr_t>
+ C::only_if_signed<T, T> ReadSLEB128() {
+ return bit_cast<T>(ReadSLEB128<typename std::make_unsigned<T>::type>());
+ }
+
+ private:
uint16_t Read16() { return Read16(kEndByteMarker); }
uint32_t Read32() { return Read32(kEndByteMarker); }
@@ -128,11 +203,8 @@
template <typename T>
T Read(uint8_t end_byte_marker) {
using Unsigned = typename std::make_unsigned<T>::type;
- const uint8_t* c = current_;
- ASSERT(c < end_);
- Unsigned b = *c++;
+ Unsigned b = ReadByte();
if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
return b - end_byte_marker;
}
T r = 0;
@@ -140,159 +212,78 @@
do {
r |= static_cast<Unsigned>(b) << s;
s += kDataBitsPerByte;
- ASSERT(c < end_);
- b = *c++;
+ b = ReadByte();
} while (b <= kMaxUnsignedDataPerByte);
- current_ = c;
return r | (static_cast<Unsigned>(b - end_byte_marker) << s);
}
- uint16_t Read16(uint8_t end_byte_marker) {
- const uint8_t* c = current_;
- ASSERT(c < end_);
- uint16_t b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return b - end_byte_marker;
- }
- uint16_t r = b;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint16_t>(b - end_byte_marker) << 7);
- }
+// Setting up needed variables for the unrolled loop sections below.
+#define UNROLLED_INIT() \
+ using Unsigned = typename std::make_unsigned<T>::type; \
+ Unsigned b = ReadByte(); \
+ if (b > kMaxUnsignedDataPerByte) { \
+ return b - end_byte_marker; \
+ } \
+ T r = b;
- r |= b << 7;
- ASSERT(c < end_);
- b = *c++;
- ASSERT(b > kMaxUnsignedDataPerByte);
- current_ = c;
- return r | (static_cast<uint16_t>(b - end_byte_marker) << 14);
+// Part of the unrolled loop where the loop may stop, having read the last part,
+// or continue reading.
+#define UNROLLED_BODY(bit_start) \
+ static_assert(bit_start % kDataBitsPerByte == 0, \
+ "Bit start must be a multiple of the data bits per byte"); \
+ static_assert(bit_start >= 0 && bit_start < kBitsPerByte * sizeof(T), \
+ "Starting unrolled body at invalid bit position"); \
+ static_assert(bit_start + kDataBitsPerByte < kBitsPerByte * sizeof(T), \
+ "Unrolled body should not contain final bits in value"); \
+ b = ReadByte(); \
+ if (b > kMaxUnsignedDataPerByte) { \
+ return r | (static_cast<T>(b - end_byte_marker) << bit_start); \
+ } \
+ r |= b << bit_start;
+
+// The end of the unrolled loop.
+#define UNROLLED_END(bit_start) \
+ static_assert(bit_start % kDataBitsPerByte == 0, \
+ "Bit start must be a multiple of the data bits per byte"); \
+ static_assert(bit_start >= 0 && bit_start < kBitsPerByte * sizeof(T), \
+ "Starting unrolled end at invalid bit position"); \
+ static_assert(bit_start + kDataBitsPerByte >= kBitsPerByte * sizeof(T), \
+ "Unrolled end does not contain final bits in value"); \
+ b = ReadByte(); \
+ ASSERT(b > kMaxUnsignedDataPerByte); \
+ return r | (static_cast<T>(b - end_byte_marker) << bit_start);
+
+ uint16_t Read16(uint8_t end_byte_marker) {
+ using T = uint16_t;
+ UNROLLED_INIT();
+ UNROLLED_BODY(7);
+ UNROLLED_END(14);
}
uint32_t Read32(uint8_t end_byte_marker) {
- const uint8_t* c = current_;
- ASSERT(c < end_);
- uint32_t b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return b - end_byte_marker;
- }
-
- uint32_t r = b;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint32_t>(b - end_byte_marker) << 7);
- }
-
- r |= b << 7;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint32_t>(b - end_byte_marker) << 14);
- }
-
- r |= b << 14;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint32_t>(b - end_byte_marker) << 21);
- }
-
- r |= b << 21;
- ASSERT(c < end_);
- b = *c++;
- ASSERT(b > kMaxUnsignedDataPerByte);
- current_ = c;
- return r | (static_cast<uint32_t>(b - end_byte_marker) << 28);
+ using T = uint32_t;
+ UNROLLED_INIT();
+ UNROLLED_BODY(7);
+ UNROLLED_BODY(14);
+ UNROLLED_BODY(21);
+ UNROLLED_END(28);
}
uint64_t Read64(uint8_t end_byte_marker) {
- const uint8_t* c = current_;
- ASSERT(c < end_);
- uint64_t b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return b - end_byte_marker;
- }
- uint64_t r = b;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint64_t>(b - end_byte_marker) << 7);
- }
-
- r |= b << 7;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint64_t>(b - end_byte_marker) << 14);
- }
-
- r |= b << 14;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint64_t>(b - end_byte_marker) << 21);
- }
-
- r |= b << 21;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint64_t>(b - end_byte_marker) << 28);
- }
-
- r |= b << 28;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint64_t>(b - end_byte_marker) << 35);
- }
-
- r |= b << 35;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint64_t>(b - end_byte_marker) << 42);
- }
-
- r |= b << 42;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint64_t>(b - end_byte_marker) << 49);
- }
-
- r |= b << 49;
- ASSERT(c < end_);
- b = *c++;
- if (b > kMaxUnsignedDataPerByte) {
- current_ = c;
- return r | (static_cast<uint64_t>(b - end_byte_marker) << 56);
- }
-
- r |= b << 56;
- ASSERT(c < end_);
- b = *c++;
- ASSERT(b > kMaxUnsignedDataPerByte);
- current_ = c;
- return r | (static_cast<uint64_t>(b - end_byte_marker) << 63);
+ using T = uint64_t;
+ UNROLLED_INIT();
+ UNROLLED_BODY(7);
+ UNROLLED_BODY(14);
+ UNROLLED_BODY(21);
+ UNROLLED_BODY(28);
+ UNROLLED_BODY(35);
+ UNROLLED_BODY(42);
+ UNROLLED_BODY(49);
+ UNROLLED_BODY(56);
+ UNROLLED_END(63);
}
- uint8_t ReadByte() {
+ DART_FORCE_INLINE uint8_t ReadByte() {
ASSERT(current_ < end_);
return *current_++;
}
@@ -320,9 +311,11 @@
const intptr_t position_before = Position();
const intptr_t position_after = Utils::RoundUp(position_before, alignment);
const intptr_t length = position_after - position_before;
- EnsureSpace(length);
- memset(current_, 0, length);
- SetPosition(position_after);
+ if (length != 0) {
+ EnsureSpace(length);
+ memset(current_, 0, length);
+ SetPosition(position_after);
+ }
return length;
}
@@ -362,14 +355,12 @@
};
void WriteWordWith32BitWrites(uword value) {
- constexpr intptr_t kNumBytesPerWrite32 = sizeof(uint32_t);
- constexpr intptr_t kNumWrite32PerWord = sizeof(uword) / kNumBytesPerWrite32;
- constexpr intptr_t kNumBitsPerWrite32 = kNumBytesPerWrite32 * kBitsPerByte;
+ constexpr intptr_t kNumWrite32PerWord = kBitsPerWord / kBitsPerInt32;
- const uint32_t mask = Utils::NBitMask(kNumBitsPerWrite32);
+ const uint32_t mask = Utils::NBitMask(kBitsPerInt32);
for (intptr_t j = 0; j < kNumWrite32PerWord; j++) {
- const uint32_t shifted_value = (value >> (j * kNumBitsPerWrite32));
- Raw<kNumBytesPerWrite32, uint32_t>::Write(this, shifted_value & mask);
+ const uint32_t shifted_value = (value >> (j * kBitsPerInt32));
+ Raw<kInt32Size, uint32_t>::Write(this, shifted_value & mask);
}
}
@@ -384,11 +375,11 @@
}
void WriteBytes(const void* addr, intptr_t len) {
- EnsureSpace(len);
if (len != 0) {
+ EnsureSpace(len);
memmove(current_, addr, len);
+ current_ += len;
}
- current_ += len;
}
void WriteWord(uword value) { WriteFixed(value); }
@@ -406,7 +397,7 @@
// Measure.
va_list measure_args;
va_copy(measure_args, args);
- intptr_t len = Utils::VSNPrint(NULL, 0, format, measure_args);
+ intptr_t len = Utils::VSNPrint(nullptr, 0, format, measure_args);
va_end(measure_args);
// Alloc.
@@ -443,6 +434,85 @@
void WriteString(const char* cstr) { WriteBytes(cstr, strlen(cstr)); }
+ private:
+ using C = LEB128Constants;
+
+ public:
+ template <typename T>
+ C::only_if_unsigned<T, void> WriteLEB128(T value) {
+ T remainder = value;
+ bool is_last_part;
+ do {
+ uint8_t part = static_cast<uint8_t>(remainder & C::kDataByteMask);
+ remainder >>= C::kDataBitsPerByte;
+ // For unsigned types, we're done when the remainder has no bits set.
+ is_last_part = remainder == static_cast<T>(0);
+ if (!is_last_part) {
+ // Mark this part as a non-final part for this value.
+ part |= C::kMoreDataMask;
+ }
+ WriteByte(part);
+ } while (!is_last_part);
+ }
+
+ template <typename T>
+ C::only_if_signed<T, void> WriteLEB128(T value) {
+ // If we're trying to LEB128 encode a negative value, chances are we should
+ // be using SLEB128 instead.
+ ASSERT(value >= 0);
+ return WriteLEB128(bit_cast<typename std::make_unsigned<T>::type>(value));
+ }
+
+ template <typename T>
+ C::only_if_signed<T, void> WriteSLEB128(T value) {
+ constexpr intptr_t kBitsPerT = kBitsPerByte * sizeof(T);
+ using Unsigned = typename std::make_unsigned<T>::type;
+ // Record whether the original value was negative.
+ const bool is_negative = value < 0;
+ T remainder = value;
+ bool is_last_part;
+ do {
+ uint8_t part = static_cast<uint8_t>(remainder & C::kDataByteMask);
+ remainder >>= C::kDataBitsPerByte;
+ // For signed types, we're done when either:
+ // - the remainder has all bits set and the part's sign bit is set
+ // for negative values, or
+ // - the remainder has no bits set and the part's sign bit is unset for
+ // non-negative values.
+ // If the remainder matches but the sign bit does not, we need one more
+ // part to set the sign bit correctly when decoding.
+ if (is_negative) {
+ // Right shifts of negative values in C are not guaranteed to be
+ // arithmetic. For negative values, set the [kDataBitsPerByte] most
+ // significant bits after shifting to ensure the value stays negative.
+ constexpr intptr_t preserved_bits = kBitsPerT - C::kDataBitsPerByte;
+ // The sign extension mask is the inverse of the preserved bits mask.
+ constexpr T sign_extend =
+ ~static_cast<T>((static_cast<Unsigned>(1) << preserved_bits) - 1);
+ // Sign extend for negative values just in case a non-arithmetic right
+ // shift is used by the compiler.
+ remainder |= sign_extend;
+ ASSERT(remainder < 0); // Remainder should still be negative.
+ is_last_part =
+ remainder == ~static_cast<T>(0) && (part & C::kSignMask) != 0;
+ } else {
+ ASSERT(remainder >= 0); // Remainder should still be non-negative.
+ is_last_part =
+ (remainder == static_cast<T>(0) && (part & C::kSignMask) == 0);
+ }
+ if (!is_last_part) {
+ // Mark this part as a non-final part for this value.
+ part |= C::kMoreDataMask;
+ }
+ WriteByte(part);
+ } while (!is_last_part);
+ }
+
+ template <typename T>
+ C::only_if_unsigned<T, void> WriteSLEB128(T value) {
+ return WriteSLEB128(bit_cast<typename std::make_signed<T>::type>(value));
+ }
+
protected:
void EnsureSpace(intptr_t size_needed) {
if (Remaining() >= size_needed) return;
@@ -508,10 +578,7 @@
class MallocWriteStream : public NonStreamingWriteStream {
public:
explicit MallocWriteStream(intptr_t initial_size)
- : NonStreamingWriteStream(initial_size) {
- // Go ahead and allocate initial space at construction.
- EnsureSpace(initial_size_);
- }
+ : NonStreamingWriteStream(initial_size) {}
~MallocWriteStream();
// Resets the stream and returns the original buffer, which is now considered
@@ -537,10 +604,7 @@
class ZoneWriteStream : public NonStreamingWriteStream {
public:
ZoneWriteStream(Zone* zone, intptr_t initial_size)
- : NonStreamingWriteStream(initial_size), zone_(zone) {
- // Go ahead and allocate initial space at construction.
- EnsureSpace(initial_size_);
- }
+ : NonStreamingWriteStream(initial_size), zone_(zone) {}
private:
virtual void Realloc(intptr_t new_size);
@@ -562,10 +626,7 @@
void* callback_data)
: BaseWriteStream(initial_capacity),
callback_(callback),
- callback_data_(callback_data) {
- // Go ahead and allocate initial space at construction.
- EnsureSpace(initial_capacity);
- }
+ callback_data_(callback_data) {}
~StreamingWriteStream();
private:
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 5098285..138d02e 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -1106,35 +1106,8 @@
stream_(ASSERT_NOTNULL(stream)),
table_(table) {}
- void sleb128(intptr_t value) {
- bool is_last_part = false;
- while (!is_last_part) {
- uint8_t part = value & 0x7F;
- value >>= 7;
- if ((value == 0 && (part & 0x40) == 0) ||
- (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) {
- is_last_part = true;
- } else {
- part |= 0x80;
- }
- stream_->WriteByte(part);
- }
- }
-
- void uleb128(uintptr_t value) {
- bool is_last_part = false;
- while (!is_last_part) {
- uint8_t part = value & 0x7F;
- value >>= 7;
- if (value == 0) {
- is_last_part = true;
- } else {
- part |= 0x80;
- }
- stream_->WriteByte(part);
- }
- }
-
+ void sleb128(intptr_t value) { stream_->WriteSLEB128(value); }
+ void uleb128(uintptr_t value) { stream_->WriteLEB128(value); }
void u1(uint8_t value) { stream_->WriteByte(value); }
void u2(uint16_t value) { stream_->WriteFixed(value); }
void u4(uint32_t value) { stream_->WriteFixed(value); }
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index e794427..1b53aaa 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -290,13 +290,17 @@
}
intptr_t ReadSLEB128() {
- const uint8_t* buffer = this->buffer();
- return Utils::DecodeSLEB128<intptr_t>(buffer, size_, &offset_);
+ ReadStream stream(this->buffer(), size_, offset_);
+ const intptr_t result = stream.ReadSLEB128();
+ offset_ = stream.Position();
+ return result;
}
int64_t ReadSLEB128AsInt64() {
- const uint8_t* buffer = this->buffer();
- return Utils::DecodeSLEB128<int64_t>(buffer, size_, &offset_);
+ ReadStream stream(this->buffer(), size_, offset_);
+ const int64_t result = stream.ReadSLEB128<int64_t>();
+ offset_ = stream.Position();
+ return result;
}
/**
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 25776cd..bbbca69 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -707,7 +707,7 @@
*null_type_arguments_ = TypeArguments::null();
*empty_type_arguments_ = TypeArguments::null();
*null_abstract_type_ = AbstractType::null();
- *null_compressed_stack_maps_ = CompressedStackMaps::null();
+ *null_compressed_stackmaps_ = CompressedStackMaps::null();
*bool_true_ = true_;
*bool_false_ = false_;
@@ -999,6 +999,19 @@
empty_object_pool_->SetCanonical();
}
+ // Allocate and initialize the empty_compressed_stackmaps instance.
+ {
+ const intptr_t instance_size = CompressedStackMaps::InstanceSize(0);
+ uword address = heap->Allocate(instance_size, Heap::kOld);
+ InitializeObject(address, kCompressedStackMapsCid, instance_size);
+ CompressedStackMaps::initializeHandle(
+ empty_compressed_stackmaps_,
+ static_cast<CompressedStackMapsPtr>(address + kHeapObjectTag));
+ empty_compressed_stackmaps_->StoreNonPointer(
+ &empty_compressed_stackmaps_->raw_ptr()->flags_and_size_, 0);
+ empty_compressed_stackmaps_->SetCanonical();
+ }
+
// Allocate and initialize the empty_descriptors instance.
{
uword address = heap->Allocate(PcDescriptors::InstanceSize(0), Heap::kOld);
@@ -1184,14 +1197,16 @@
ASSERT(null_function_->IsFunction());
ASSERT(!null_type_arguments_->IsSmi());
ASSERT(null_type_arguments_->IsTypeArguments());
- ASSERT(!null_compressed_stack_maps_->IsSmi());
- ASSERT(null_compressed_stack_maps_->IsCompressedStackMaps());
+ ASSERT(!null_compressed_stackmaps_->IsSmi());
+ ASSERT(null_compressed_stackmaps_->IsCompressedStackMaps());
ASSERT(!empty_array_->IsSmi());
ASSERT(empty_array_->IsArray());
ASSERT(!zero_array_->IsSmi());
ASSERT(zero_array_->IsArray());
ASSERT(!empty_context_scope_->IsSmi());
ASSERT(empty_context_scope_->IsContextScope());
+ ASSERT(!empty_compressed_stackmaps_->IsSmi());
+ ASSERT(empty_compressed_stackmaps_->IsCompressedStackMaps());
ASSERT(!empty_descriptors_->IsSmi());
ASSERT(empty_descriptors_->IsPcDescriptors());
ASSERT(!empty_var_descriptors_->IsSmi());
@@ -14159,35 +14174,6 @@
return "InstructionsSection";
}
-// Encode integer |value| in SLEB128 format and store into |data|.
-static void EncodeSLEB128(GrowableArray<uint8_t>* data, intptr_t value) {
- bool is_last_part = false;
- while (!is_last_part) {
- uint8_t part = value & 0x7f;
- value >>= 7;
- if ((value == 0 && (part & 0x40) == 0) ||
- (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) {
- is_last_part = true;
- } else {
- part |= 0x80;
- }
- data->Add(part);
- }
-}
-
-// Encode integer in SLEB128 format.
-void PcDescriptors::EncodeInteger(GrowableArray<uint8_t>* data,
- intptr_t value) {
- return EncodeSLEB128(data, value);
-}
-
-// Decode SLEB128 encoded integer. Update byte_index to the next integer.
-intptr_t PcDescriptors::DecodeInteger(intptr_t* byte_index) const {
- NoSafepointScope no_safepoint;
- const uint8_t* data = raw_ptr()->data();
- return Utils::DecodeSLEB128<intptr_t>(data, Length(), byte_index);
-}
-
ObjectPoolPtr ObjectPool::New(intptr_t len) {
ASSERT(Object::object_pool_class() != Class::null());
if (len < 0 || len > kMaxElements) {
@@ -14300,25 +14286,25 @@
StoreNonPointer(&raw_ptr()->length_, value);
}
-void PcDescriptors::CopyData(GrowableArray<uint8_t>* delta_encoded_data) {
+void PcDescriptors::CopyData(const void* bytes, intptr_t size) {
NoSafepointScope no_safepoint;
uint8_t* data = UnsafeMutableNonPointer(&raw_ptr()->data()[0]);
- for (intptr_t i = 0; i < delta_encoded_data->length(); ++i) {
- data[i] = (*delta_encoded_data)[i];
- }
+ // We're guaranted these memory spaces do not overlap.
+ memcpy(data, bytes, size); // NOLINT
}
-PcDescriptorsPtr PcDescriptors::New(GrowableArray<uint8_t>* data) {
+PcDescriptorsPtr PcDescriptors::New(const void* delta_encoded_data,
+ intptr_t size) {
ASSERT(Object::pc_descriptors_class() != Class::null());
Thread* thread = Thread::Current();
PcDescriptors& result = PcDescriptors::Handle(thread->zone());
{
- uword size = PcDescriptors::InstanceSize(data->length());
- ObjectPtr raw = Object::Allocate(PcDescriptors::kClassId, size, Heap::kOld);
+ ObjectPtr raw = Object::Allocate(
+ PcDescriptors::kClassId, PcDescriptors::InstanceSize(size), Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
- result.SetLength(data->length());
- result.CopyData(data);
+ result.SetLength(size);
+ result.CopyData(delta_encoded_data, size);
}
return result.raw();
}
@@ -14474,45 +14460,195 @@
}
intptr_t CompressedStackMaps::Hashcode() const {
+ NoSafepointScope scope;
+ uint8_t* data = UnsafeMutableNonPointer(&raw_ptr()->data()[0]);
+ uint8_t* end = data + payload_size();
uint32_t hash = payload_size();
- for (uintptr_t i = 0; i < payload_size(); i++) {
- uint8_t byte = PayloadByte(i);
- hash = CombineHashes(hash, byte);
+ for (uint8_t* cursor = data; cursor < end; cursor++) {
+ hash = CombineHashes(hash, *cursor);
}
return FinalizeHash(hash, kHashBits);
}
-CompressedStackMapsPtr CompressedStackMaps::New(
- const GrowableArray<uint8_t>& payload,
- bool is_global_table,
- bool uses_global_table) {
+CompressedStackMaps::Iterator::Iterator(const CompressedStackMaps& maps,
+ const CompressedStackMaps& global_table)
+ : maps_(maps),
+ bits_container_(maps_.UsesGlobalTable() ? global_table : maps_) {
+ ASSERT(!maps_.IsNull());
+ ASSERT(!bits_container_.IsNull());
+ ASSERT(!maps_.IsGlobalTable());
+ ASSERT(!maps_.UsesGlobalTable() || bits_container_.IsGlobalTable());
+}
+
+CompressedStackMaps::Iterator::Iterator(Thread* thread,
+ const CompressedStackMaps& maps)
+ : CompressedStackMaps::Iterator(
+ maps,
+ // Only look up the global table if the map will end up using it.
+ maps.UsesGlobalTable() ? CompressedStackMaps::Handle(
+ thread->zone(),
+ thread->isolate()
+ ->object_store()
+ ->canonicalized_stack_map_entries())
+ : Object::null_compressed_stackmaps()) {}
+
+CompressedStackMaps::Iterator::Iterator(const CompressedStackMaps::Iterator& it)
+ : maps_(it.maps_),
+ bits_container_(it.bits_container_),
+ next_offset_(it.next_offset_),
+ current_pc_offset_(it.current_pc_offset_),
+ current_global_table_offset_(it.current_global_table_offset_),
+ current_spill_slot_bit_count_(it.current_spill_slot_bit_count_),
+ current_non_spill_slot_bit_count_(it.current_spill_slot_bit_count_),
+ current_bits_offset_(it.current_bits_offset_) {}
+
+bool CompressedStackMaps::Iterator::MoveNext() {
+ if (next_offset_ >= maps_.payload_size()) {
+ return false;
+ }
+
+ NoSafepointScope scope;
+ ReadStream stream(maps_.raw_ptr()->data(), maps_.payload_size(),
+ next_offset_);
+
+ auto const pc_delta = stream.ReadLEB128();
+ ASSERT(pc_delta <= (kMaxUint32 - current_pc_offset_));
+ current_pc_offset_ += pc_delta;
+
+ // Table-using CSMs have a table offset after the PC offset delta, whereas
+ // the post-delta part of inlined entries has the same information as
+ // global table entries.
+ if (maps_.UsesGlobalTable()) {
+ current_global_table_offset_ = stream.ReadLEB128();
+ ASSERT(current_global_table_offset_ < bits_container_.payload_size());
+
+ // Since generally we only use entries in the GC and the GC only needs
+ // the rest of the entry information if the PC offset matches, we lazily
+ // load and cache the information stored in the global object when it is
+ // actually requested.
+ current_spill_slot_bit_count_ = -1;
+ current_non_spill_slot_bit_count_ = -1;
+ current_bits_offset_ = -1;
+
+ next_offset_ = stream.Position();
+ } else {
+ current_spill_slot_bit_count_ = stream.ReadLEB128();
+ ASSERT(current_spill_slot_bit_count_ >= 0);
+
+ current_non_spill_slot_bit_count_ = stream.ReadLEB128();
+ ASSERT(current_non_spill_slot_bit_count_ >= 0);
+
+ const auto stackmap_bits =
+ current_spill_slot_bit_count_ + current_non_spill_slot_bit_count_;
+ const uintptr_t stackmap_size =
+ Utils::RoundUp(stackmap_bits, kBitsPerByte) >> kBitsPerByteLog2;
+ ASSERT(stackmap_size <= (maps_.payload_size() - stream.Position()));
+
+ current_bits_offset_ = stream.Position();
+ next_offset_ = current_bits_offset_ + stackmap_size;
+ }
+
+ return true;
+}
+
+intptr_t CompressedStackMaps::Iterator::Length() const {
+ EnsureFullyLoadedEntry();
+ return current_spill_slot_bit_count_ + current_non_spill_slot_bit_count_;
+}
+intptr_t CompressedStackMaps::Iterator::SpillSlotBitCount() const {
+ EnsureFullyLoadedEntry();
+ return current_spill_slot_bit_count_;
+}
+
+bool CompressedStackMaps::Iterator::IsObject(intptr_t bit_index) const {
+ EnsureFullyLoadedEntry();
+ ASSERT(bit_index >= 0 && bit_index < Length());
+ const intptr_t byte_index = bit_index >> kBitsPerByteLog2;
+ const intptr_t bit_remainder = bit_index & (kBitsPerByte - 1);
+ uint8_t byte_mask = 1U << bit_remainder;
+ const intptr_t byte_offset = current_bits_offset_ + byte_index;
+ NoSafepointScope scope;
+ return (bits_container_.raw_ptr()->data()[byte_offset] & byte_mask) != 0;
+}
+
+void CompressedStackMaps::Iterator::LazyLoadGlobalTableEntry() const {
+ ASSERT(maps_.UsesGlobalTable());
+ ASSERT(HasLoadedEntry());
+ ASSERT(current_global_table_offset_ < bits_container_.payload_size());
+
+ NoSafepointScope scope;
+ ReadStream stream(bits_container_.raw_ptr()->data(),
+ bits_container_.payload_size(),
+ current_global_table_offset_);
+
+ current_spill_slot_bit_count_ = stream.ReadLEB128();
+ ASSERT(current_spill_slot_bit_count_ >= 0);
+
+ current_non_spill_slot_bit_count_ = stream.ReadLEB128();
+ ASSERT(current_non_spill_slot_bit_count_ >= 0);
+
+ const auto stackmap_bits = Length();
+ const uintptr_t stackmap_size =
+ Utils::RoundUp(stackmap_bits, kBitsPerByte) >> kBitsPerByteLog2;
+ ASSERT(stackmap_size <= (bits_container_.payload_size() - stream.Position()));
+
+ current_bits_offset_ = stream.Position();
+}
+
+void CompressedStackMaps::Iterator::WriteToBuffer(BaseTextBuffer* buffer,
+ const char* separator) const {
+ CompressedStackMaps::Iterator it(*this);
+ // If we haven't loaded an entry yet, do so (but don't skip the current
+ // one if we have!)
+ if (!it.HasLoadedEntry()) {
+ if (!it.MoveNext()) return;
+ }
+ bool first_entry = true;
+ do {
+ if (!first_entry) {
+ buffer->AddString(separator);
+ }
+ buffer->Printf("0x%0.8" Px32 ": ", it.pc_offset());
+ for (intptr_t i = 0, n = it.Length(); i < n; i++) {
+ buffer->AddString(it.IsObject(i) ? "1" : "0");
+ }
+ first_entry = false;
+ } while (it.MoveNext());
+}
+
+CompressedStackMapsPtr CompressedStackMaps::New(const void* payload,
+ intptr_t size,
+ bool is_global_table,
+ bool uses_global_table) {
ASSERT(Object::compressed_stackmaps_class() != Class::null());
// We don't currently allow both flags to be true.
ASSERT(!is_global_table || !uses_global_table);
- auto& result = CompressedStackMaps::Handle();
+ // The canonical empty instance should be used instead.
+ ASSERT(size != 0);
- const uintptr_t payload_size = payload.length();
- if (!CompressedStackMapsLayout::SizeField::is_valid(payload_size)) {
+ if (!CompressedStackMapsLayout::SizeField::is_valid(size)) {
FATAL1(
"Fatal error in CompressedStackMaps::New: "
"invalid payload size %" Pu "\n",
- payload_size);
+ size);
}
+
+ auto& result = CompressedStackMaps::Handle();
{
// CompressedStackMaps data objects are associated with a code object,
// allocate them in old generation.
- ObjectPtr raw = Object::Allocate(
- CompressedStackMaps::kClassId,
- CompressedStackMaps::InstanceSize(payload_size), Heap::kOld);
+ ObjectPtr raw =
+ Object::Allocate(CompressedStackMaps::kClassId,
+ CompressedStackMaps::InstanceSize(size), Heap::kOld);
NoSafepointScope no_safepoint;
result ^= raw;
result.StoreNonPointer(
&result.raw_ptr()->flags_and_size_,
CompressedStackMapsLayout::GlobalTableBit::encode(is_global_table) |
CompressedStackMapsLayout::UsesTableBit::encode(uses_global_table) |
- CompressedStackMapsLayout::SizeField::encode(payload_size));
+ CompressedStackMapsLayout::SizeField::encode(size));
auto cursor = result.UnsafeMutableNonPointer(result.raw_ptr()->data());
- memcpy(cursor, payload.data(), payload.length()); // NOLINT
+ memcpy(cursor, payload, size); // NOLINT
}
ASSERT(!result.IsGlobalTable() || !result.UsesGlobalTable());
@@ -14522,12 +14658,16 @@
const char* CompressedStackMaps::ToCString() const {
ASSERT(!IsGlobalTable());
+ if (payload_size() == 0) {
+ return "CompressedStackMaps()";
+ }
auto const t = Thread::Current();
- auto zone = t->zone();
- const auto& global_table = CompressedStackMaps::Handle(
- zone, t->isolate()->object_store()->canonicalized_stack_map_entries());
- CompressedStackMapsIterator it(*this, global_table);
- return it.ToCString(zone);
+ CompressedStackMaps::Iterator it(t, *this);
+ ZoneTextBuffer buffer(t->zone(), 100);
+ buffer.AddString("CompressedStackMaps(");
+ it.WriteToBuffer(&buffer, ", ");
+ buffer.AddString(")");
+ return buffer.buffer();
}
StringPtr LocalVarDescriptors::GetName(intptr_t var_index) const {
@@ -16479,6 +16619,7 @@
NOT_IN_PRODUCT(result.set_comments(Comments::New(0)));
NOT_IN_PRODUCT(result.set_compile_timestamp(0));
result.set_pc_descriptors(Object::empty_descriptors());
+ result.set_compressed_stackmaps(Object::empty_compressed_stackmaps());
}
return result.raw();
}
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index e9a388b..230312a 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -417,12 +417,13 @@
V(Instance, null_instance) \
V(Function, null_function) \
V(TypeArguments, null_type_arguments) \
- V(CompressedStackMaps, null_compressed_stack_maps) \
+ V(CompressedStackMaps, null_compressed_stackmaps) \
V(TypeArguments, empty_type_arguments) \
V(Array, empty_array) \
V(Array, zero_array) \
V(ContextScope, empty_context_scope) \
V(ObjectPool, empty_object_pool) \
+ V(CompressedStackMaps, empty_compressed_stackmaps) \
V(PcDescriptors, empty_descriptors) \
V(LocalVarDescriptors, empty_var_descriptors) \
V(ExceptionHandlers, empty_exception_handlers) \
@@ -5705,7 +5706,7 @@
return RoundedAllocationSize(UnroundedSize(len));
}
- static PcDescriptorsPtr New(GrowableArray<uint8_t>* delta_encoded_data);
+ static PcDescriptorsPtr New(const void* delta_encoded_data, intptr_t size);
// Verify (assert) assumptions about pc descriptors in debug mode.
void Verify(const Function& function) const;
@@ -5714,12 +5715,6 @@
void PrintToJSONObject(JSONObject* jsobj, bool ref) const;
- // Encode integer in SLEB128 format.
- static void EncodeInteger(GrowableArray<uint8_t>* data, intptr_t value);
-
- // Decode SLEB128 encoded integer. Update byte_index to the next integer.
- intptr_t DecodeInteger(intptr_t* byte_index) const;
-
// We would have a VisitPointers function here to traverse the
// pc descriptors table to visit objects if any in the table.
// Note: never return a reference to a PcDescriptorsLayout::PcDescriptorRec
@@ -5738,10 +5733,12 @@
cur_yield_index_(PcDescriptorsLayout::kInvalidYieldIndex) {}
bool MoveNext() {
+ NoSafepointScope scope;
+ ReadStream stream(descriptors_.raw_ptr()->data(), descriptors_.Length(),
+ byte_index_);
// Moves to record that matches kind_mask_.
while (byte_index_ < descriptors_.Length()) {
- const int32_t kind_and_metadata =
- descriptors_.DecodeInteger(&byte_index_);
+ const int32_t kind_and_metadata = stream.ReadSLEB128<int32_t>();
cur_kind_ =
PcDescriptorsLayout::KindAndMetadata::DecodeKind(kind_and_metadata);
cur_try_index_ = PcDescriptorsLayout::KindAndMetadata::DecodeTryIndex(
@@ -5750,12 +5747,13 @@
PcDescriptorsLayout::KindAndMetadata::DecodeYieldIndex(
kind_and_metadata);
- cur_pc_offset_ += descriptors_.DecodeInteger(&byte_index_);
+ cur_pc_offset_ += stream.ReadSLEB128();
if (!FLAG_precompiled_mode) {
- cur_deopt_id_ += descriptors_.DecodeInteger(&byte_index_);
- cur_token_pos_ += descriptors_.DecodeInteger(&byte_index_);
+ cur_deopt_id_ += stream.ReadSLEB128();
+ cur_token_pos_ += stream.ReadSLEB128();
}
+ byte_index_ = stream.Position();
if ((cur_kind_ & kind_mask_) != 0) {
return true; // Current is valid.
@@ -5816,7 +5814,7 @@
static PcDescriptorsPtr New(intptr_t length);
void SetLength(intptr_t value) const;
- void CopyData(GrowableArray<uint8_t>* data);
+ void CopyData(const void* bytes, intptr_t size);
FINAL_HEAP_OBJECT_IMPLEMENTATION(PcDescriptors, Object);
friend class Class;
@@ -5908,46 +5906,117 @@
return RoundedAllocationSize(UnroundedSize(length));
}
- bool UsesGlobalTable() const { return !IsNull() && UsesGlobalTable(raw()); }
+ bool UsesGlobalTable() const { return UsesGlobalTable(raw()); }
static bool UsesGlobalTable(const CompressedStackMapsPtr raw) {
return CompressedStackMapsLayout::UsesTableBit::decode(
raw->ptr()->flags_and_size_);
}
- bool IsGlobalTable() const { return !IsNull() && IsGlobalTable(raw()); }
+ bool IsGlobalTable() const { return IsGlobalTable(raw()); }
static bool IsGlobalTable(const CompressedStackMapsPtr raw) {
return CompressedStackMapsLayout::GlobalTableBit::decode(
raw->ptr()->flags_and_size_);
}
- static CompressedStackMapsPtr NewInlined(
- const GrowableArray<uint8_t>& bytes) {
- return New(bytes, /*is_global_table=*/false, /*uses_global_table=*/false);
+ static CompressedStackMapsPtr NewInlined(const void* payload, intptr_t size) {
+ return New(payload, size, /*is_global_table=*/false,
+ /*uses_global_table=*/false);
}
- static CompressedStackMapsPtr NewUsingTable(
- const GrowableArray<uint8_t>& bytes) {
- return New(bytes, /*is_global_table=*/false, /*uses_global_table=*/true);
+ static CompressedStackMapsPtr NewUsingTable(const void* payload,
+ intptr_t size) {
+ return New(payload, size, /*is_global_table=*/false,
+ /*uses_global_table=*/true);
}
- static CompressedStackMapsPtr NewGlobalTable(
- const GrowableArray<uint8_t>& bytes) {
- return New(bytes, /*is_global_table=*/true, /*uses_global_table=*/false);
+ static CompressedStackMapsPtr NewGlobalTable(const void* payload,
+ intptr_t size) {
+ return New(payload, size, /*is_global_table=*/true,
+ /*uses_global_table=*/false);
}
+ class Iterator : public ValueObject {
+ public:
+ Iterator(const CompressedStackMaps& maps,
+ const CompressedStackMaps& global_table);
+ Iterator(Thread* thread, const CompressedStackMaps& maps);
+
+ explicit Iterator(const CompressedStackMaps::Iterator& it);
+
+ // Loads the next entry from [maps_], if any. If [maps_] is the null value,
+ // this always returns false.
+ bool MoveNext();
+
+ // Finds the entry with the given PC offset starting at the current position
+ // of the iterator. If [maps_] is the null value, this always returns false.
+ bool Find(uint32_t pc_offset) {
+ // We should never have an entry with a PC offset of 0 inside an
+ // non-empty CSM, so fail.
+ if (pc_offset == 0) return false;
+ do {
+ if (current_pc_offset_ >= pc_offset) break;
+ } while (MoveNext());
+ return current_pc_offset_ == pc_offset;
+ }
+
+ // Methods for accessing parts of an entry should not be called until
+ // a successful MoveNext() or Find() call has been made.
+
+ // Returns the PC offset of the loaded entry.
+ uint32_t pc_offset() const {
+ ASSERT(HasLoadedEntry());
+ return current_pc_offset_;
+ }
+
+ // Returns the bit length of the loaded entry.
+ intptr_t Length() const;
+ // Returns the number of spill slot bits of the loaded entry.
+ intptr_t SpillSlotBitCount() const;
+ // Returns whether the stack entry represented by the offset contains
+ // a tagged objecet.
+ bool IsObject(intptr_t bit_offset) const;
+
+ void WriteToBuffer(BaseTextBuffer* buffer, const char* separator) const;
+
+ private:
+ bool HasLoadedEntry() const { return next_offset_ > 0; }
+
+ // Caches the corresponding values from the global table in the mutable
+ // fields. We lazily load these as some clients only need the PC offset.
+ void LazyLoadGlobalTableEntry() const;
+
+ void EnsureFullyLoadedEntry() const {
+ ASSERT(HasLoadedEntry());
+ if (current_spill_slot_bit_count_ < 0) {
+ LazyLoadGlobalTableEntry();
+ ASSERT(current_spill_slot_bit_count_ >= 0);
+ }
+ }
+
+ const CompressedStackMaps& maps_;
+ const CompressedStackMaps& bits_container_;
+
+ uintptr_t next_offset_ = 0;
+ uint32_t current_pc_offset_ = 0;
+ // Only used when looking up non-PC information in the global table.
+ uintptr_t current_global_table_offset_ = 0;
+ // Marked as mutable as these fields may be updated with lazily loaded
+ // values from the global table when their associated accessor is called,
+ // but those values will never change for a given entry once loaded..
+ mutable intptr_t current_spill_slot_bit_count_ = -1;
+ mutable intptr_t current_non_spill_slot_bit_count_ = -1;
+ mutable intptr_t current_bits_offset_ = -1;
+
+ friend class StackMapEntry;
+ };
+
private:
- static CompressedStackMapsPtr New(const GrowableArray<uint8_t>& bytes,
+ static CompressedStackMapsPtr New(const void* payload,
+ intptr_t size,
bool is_global_table,
bool uses_global_table);
- uint8_t PayloadByte(uintptr_t offset) const {
- ASSERT(offset < payload_size());
- return raw_ptr()->data()[offset];
- }
-
FINAL_HEAP_OBJECT_IMPLEMENTATION(CompressedStackMaps, Object);
friend class Class;
- friend class CompressedStackMapsIterator; // For PayloadByte
- friend class StackMapEntry; // For PayloadByte
};
class ExceptionHandlers : public Object {
@@ -10277,7 +10346,6 @@
FINAL_HEAP_OBJECT_IMPLEMENTATION(TypedData, TypedDataBase);
friend class Class;
- friend class CompressedStackMapsIterator;
friend class ExternalTypedData;
friend class TypedDataView;
};
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 060f484..b0eff0e 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -2788,7 +2788,7 @@
}
ISOLATE_UNIT_TEST_CASE(PcDescriptors) {
- DescriptorList* builder = new DescriptorList(0);
+ DescriptorList* builder = new DescriptorList(thread->zone());
// kind, pc_offset, deopt_id, token_pos, try_index, yield_index
builder->AddDescriptor(PcDescriptorsLayout::kOther, 10, 1, TokenPosition(20),
@@ -2858,7 +2858,7 @@
}
ISOLATE_UNIT_TEST_CASE(PcDescriptorsLargeDeltas) {
- DescriptorList* builder = new DescriptorList(0);
+ DescriptorList* builder = new DescriptorList(thread->zone());
// kind, pc_offset, deopt_id, token_pos, try_index
builder->AddDescriptor(PcDescriptorsLayout::kOther, 100, 1,
diff --git a/runtime/vm/program_visitor.cc b/runtime/vm/program_visitor.cc
index d2e13d2..483ce9b 100644
--- a/runtime/vm/program_visitor.cc
+++ b/runtime/vm/program_visitor.cc
@@ -451,20 +451,18 @@
class StackMapEntry : public ZoneAllocated {
public:
- StackMapEntry(Zone* zone, const CompressedStackMapsIterator& it)
+ StackMapEntry(Zone* zone, const CompressedStackMaps::Iterator& it)
: maps_(CompressedStackMaps::Handle(zone, it.maps_.raw())),
bits_container_(
CompressedStackMaps::Handle(zone, it.bits_container_.raw())),
- spill_slot_bit_count_(it.current_spill_slot_bit_count_),
- non_spill_slot_bit_count_(it.current_non_spill_slot_bit_count_),
+ // If the map uses the global table, this accessor call ensures the
+ // entry is fully loaded before we retrieve [it.current_bits_offset_].
+ spill_slot_bit_count_(it.SpillSlotBitCount()),
+ non_spill_slot_bit_count_(it.Length() - it.SpillSlotBitCount()),
bits_offset_(it.current_bits_offset_) {
ASSERT(!maps_.IsNull() && !maps_.IsGlobalTable());
ASSERT(!bits_container_.IsNull());
ASSERT(!maps_.UsesGlobalTable() || bits_container_.IsGlobalTable());
- // Check that the iterator was fully loaded when we ran the initializing
- // expressions above. By this point we enter the body of the constructor,
- // it's too late to run EnsureFullyLoadedEntry().
- ASSERT(it.HasLoadedEntry());
ASSERT(it.current_spill_slot_bit_count_ >= 0);
}
@@ -475,8 +473,13 @@
uint32_t hash = 0;
hash = CombineHashes(hash, spill_slot_bit_count_);
hash = CombineHashes(hash, non_spill_slot_bit_count_);
- for (intptr_t i = 0; i < PayloadLength(); i++) {
- hash = CombineHashes(hash, PayloadByte(i));
+ {
+ NoSafepointScope scope;
+ auto const start = PayloadData();
+ auto const end = start + PayloadLength();
+ for (auto cursor = start; cursor < end; cursor++) {
+ hash = CombineHashes(hash, *cursor);
+ }
}
hash_ = FinalizeHash(hash, kHashBits);
return hash_;
@@ -490,20 +493,19 @@
// Since we ensure that bits in the payload that are not part of the
// actual stackmap data are cleared, we can just compare payloads by byte
// instead of calling IsObject for each bit.
- for (intptr_t i = 0; i < PayloadLength(); i++) {
- if (PayloadByte(i) != other->PayloadByte(i)) return false;
- }
- return true;
+ NoSafepointScope scope;
+ return memcmp(PayloadData(), other->PayloadData(), PayloadLength()) == 0;
}
// Encodes this StackMapEntry to the given array of bytes and returns the
// initial offset of the entry in the array.
- intptr_t EncodeTo(GrowableArray<uint8_t>* array) {
- auto const current_offset = array->length();
- CompressedStackMapsBuilder::EncodeLEB128(array, spill_slot_bit_count_);
- CompressedStackMapsBuilder::EncodeLEB128(array, non_spill_slot_bit_count_);
- for (intptr_t i = 0; i < PayloadLength(); i++) {
- array->Add(PayloadByte(i));
+ intptr_t EncodeTo(NonStreamingWriteStream* stream) {
+ auto const current_offset = stream->Position();
+ stream->WriteLEB128(spill_slot_bit_count_);
+ stream->WriteLEB128(non_spill_slot_bit_count_);
+ {
+ NoSafepointScope scope;
+ stream->WriteBytes(PayloadData(), PayloadLength());
}
return current_offset;
}
@@ -518,8 +520,9 @@
intptr_t PayloadLength() const {
return Utils::RoundUp(Length(), kBitsPerByte) >> kBitsPerByteLog2;
}
- intptr_t PayloadByte(intptr_t offset) const {
- return bits_container_.PayloadByte(bits_offset_ + offset);
+ const uint8_t* PayloadData() const {
+ ASSERT(!Thread::Current()->IsAtSafepoint());
+ return bits_container_.raw()->ptr()->data() + bits_offset_;
}
const CompressedStackMaps& maps_;
@@ -577,9 +580,9 @@
void VisitCode(const Code& code) {
compressed_stackmaps_ = code.compressed_stackmaps();
- CompressedStackMapsIterator it(compressed_stackmaps_, old_global_table_);
+ CompressedStackMaps::Iterator it(compressed_stackmaps_,
+ old_global_table_);
while (it.MoveNext()) {
- it.EnsureFullyLoadedEntry();
auto const entry = new (zone_) StackMapEntry(zone_, it);
auto const index = entry_indices_.LookupValue(entry);
if (index < 0) {
@@ -598,7 +601,9 @@
CompressedStackMapsPtr CreateGlobalTable(
StackMapEntryIntMap* entry_offsets) {
ASSERT(entry_offsets->IsEmpty());
- if (collected_entries_.length() == 0) return CompressedStackMaps::null();
+ if (collected_entries_.length() == 0) {
+ return CompressedStackMaps::null();
+ }
// First, sort the entries from most used to least used. This way,
// the most often used CSMs will have the lowest offsets, which means
// they will be smaller when LEB128 encoded.
@@ -606,16 +611,17 @@
[](StackMapEntry* const* e1, StackMapEntry* const* e2) {
return static_cast<int>((*e2)->UsageCount() - (*e1)->UsageCount());
});
- GrowableArray<uint8_t> bytes;
+ MallocWriteStream stream(128);
// Encode the entries and record their offset in the payload. Sorting the
// entries may have changed their indices, so update those as well.
for (intptr_t i = 0, n = collected_entries_.length(); i < n; i++) {
auto const entry = collected_entries_.At(i);
entry_indices_.Update({entry, i});
- entry_offsets->Insert({entry, entry->EncodeTo(&bytes)});
+ entry_offsets->Insert({entry, entry->EncodeTo(&stream)});
}
const auto& data = CompressedStackMaps::Handle(
- zone_, CompressedStackMaps::NewGlobalTable(bytes));
+ zone_, CompressedStackMaps::NewGlobalTable(stream.buffer(),
+ stream.bytes_written()));
return data.raw();
}
@@ -690,19 +696,23 @@
private:
// Creates a normalized CSM from the given non-normalized CSM.
CompressedStackMapsPtr NormalizeEntries(const CompressedStackMaps& maps) {
- GrowableArray<uint8_t> new_payload;
- CompressedStackMapsIterator it(maps, old_global_table_);
+ if (maps.payload_size() == 0) {
+ // No entries, so use the canonical empty map.
+ return Object::empty_compressed_stackmaps().raw();
+ }
+ MallocWriteStream new_payload(maps.payload_size());
+ CompressedStackMaps::Iterator it(maps, old_global_table_);
intptr_t last_offset = 0;
while (it.MoveNext()) {
- it.EnsureFullyLoadedEntry();
StackMapEntry entry(zone_, it);
- auto const entry_offset = entry_offsets_.LookupValue(&entry);
- auto const pc_delta = it.pc_offset() - last_offset;
- CompressedStackMapsBuilder::EncodeLEB128(&new_payload, pc_delta);
- CompressedStackMapsBuilder::EncodeLEB128(&new_payload, entry_offset);
+ const intptr_t entry_offset = entry_offsets_.LookupValue(&entry);
+ const intptr_t pc_delta = it.pc_offset() - last_offset;
+ new_payload.WriteLEB128(pc_delta);
+ new_payload.WriteLEB128(entry_offset);
last_offset = it.pc_offset();
}
- return CompressedStackMaps::NewUsingTable(new_payload);
+ return CompressedStackMaps::NewUsingTable(new_payload.buffer(),
+ new_payload.bytes_written());
}
const CompressedStackMaps& old_global_table_;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 5f03f71..498fd5d 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1847,7 +1847,9 @@
sizeof(flags_and_size_) * kBitsPerByte -
UsesTableBit::kNextBit> {};
+ friend class Object;
friend class ImageWriter;
+ friend class StackMapEntry;
};
class LocalVarDescriptorsLayout : public ObjectLayout {
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 9c14f6e..9df6e3c 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -284,7 +284,7 @@
auto isolate = isolate_group()->isolates_.First();
global_table = isolate->object_store()->canonicalized_stack_map_entries();
- CompressedStackMapsIterator it(maps, global_table);
+ CompressedStackMaps::Iterator it(maps, global_table);
const uword start = code.PayloadStart();
const uint32_t pc_offset = pc() - start;
if (it.Find(pc_offset)) {
diff --git a/tests/language/least_upper_bound/least_upper_bound_futureor_test.dart b/tests/language/least_upper_bound/least_upper_bound_futureor_test.dart
new file mode 100644
index 0000000..57954ea
--- /dev/null
+++ b/tests/language/least_upper_bound/least_upper_bound_futureor_test.dart
@@ -0,0 +1,531 @@
+// 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.
+
+import 'dart:async';
+import '../static_type_helper.dart';
+
+// Test least upper bound for types involving `FutureOr`.
+
+bool condition = true;
+
+class A {}
+
+class B {}
+
+class C extends B {}
+
+class D extends B {}
+
+class E<T> {}
+
+class F<T> extends E<T> {}
+
+void main() {
+ // Approach: First test operand types (with no occurrence of `FutureOr`)
+ // then test those operands used as type arguments according to the
+ // rules about **UP**(T1, T2) where T1 or T2 is of the form `FutureOr<S>`.
+
+ void f1(int a, String b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<Object>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<Object>>();
+ }
+
+ void f2(FutureOr<int> a, FutureOr<String> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ void f3(Future<int> a, FutureOr<String> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ void f4(int a, FutureOr<String> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ void f5(int a, num b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<num>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<num>>();
+ }
+
+ void f6(FutureOr<int> a, FutureOr<num> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<num>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<num>>>();
+ }
+
+ void f7(Future<int> a, FutureOr<num> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<num>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<num>>>();
+ }
+
+ void f8(int a, FutureOr<num> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<num>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<num>>>();
+ }
+
+ void f9(List<int> a, List<String> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<List<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<List<Object>>>();
+ }
+
+ void f10(FutureOr<List<int>> a, FutureOr<List<String>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<List<Object>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<List<Object>>>>();
+ }
+
+ void f11(Future<List<int>> a, FutureOr<List<String>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<List<Object>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<List<Object>>>>();
+ }
+
+ void f12(List<int> a, FutureOr<List<String>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<List<Object>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<List<Object>>>>();
+ }
+
+ void f13(List<int> a, List<num> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<List<num>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<List<num>>>();
+ }
+
+ void f14(FutureOr<List<int>> a, FutureOr<List<num>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<List<num>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<List<num>>>>();
+ }
+
+ void f15(Future<List<int>> a, FutureOr<List<num>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<List<num>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<List<num>>>>();
+ }
+
+ void f16(List<int> a, FutureOr<List<num>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<List<num>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<List<num>>>>();
+ }
+
+ void f17(dynamic a, void b) {
+ var x = condition ? a : b;
+ /**/ x.toString();
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
+ // [cfe] This expression has type 'void' and can't be used.
+
+ var y = condition ? b : a;
+ /**/ y.toString();
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
+ // [cfe] This expression has type 'void' and can't be used.
+ }
+
+ void f18(FutureOr<dynamic> a, FutureOr<void> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<void>>>();
+ if (x is Future) throw 0;
+ /**/ x.toString();
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
+ // [cfe] This expression has type 'void' and can't be used.
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<void>>>();
+ if (y is Future) throw 0;
+ /**/ y.toString();
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
+ // [cfe] This expression has type 'void' and can't be used.
+ }
+
+ void f19(Future<dynamic> a, FutureOr<void> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<void>>>();
+ if (x is Future) throw 0;
+ /**/ x.toString();
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
+ // [cfe] This expression has type 'void' and can't be used.
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<void>>>();
+ if (y is Future) throw 0;
+ /**/ y.toString();
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
+ // [cfe] This expression has type 'void' and can't be used.
+ }
+
+ void f20(dynamic a, FutureOr<void> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<void>>>();
+ if (x is Future) throw 0;
+ /**/ x.toString();
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
+ // [cfe] This expression has type 'void' and can't be used.
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<void>>>();
+ if (y is Future) throw 0;
+ /**/ y.toString();
+ // ^
+ // [analyzer] COMPILE_TIME_ERROR.USE_OF_VOID_RESULT
+ // [cfe] This expression has type 'void' and can't be used.
+ }
+
+ void f21(A a, B b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<Object>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<Object>>();
+ }
+
+ void f22(FutureOr<A> a, FutureOr<B> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ void f23(Future<A> a, FutureOr<B> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ void f24(A a, FutureOr<B> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ void f25(B a, C b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<B>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<B>>();
+ }
+
+ void f26(FutureOr<B> a, FutureOr<C> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<B>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<B>>>();
+ }
+
+ void f27(Future<B> a, FutureOr<C> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<B>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<B>>>();
+ }
+
+ void f28(B a, FutureOr<C> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<B>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<B>>>();
+ }
+
+ void f29(C a, D b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<B>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<B>>();
+ }
+
+ void f30(FutureOr<C> a, FutureOr<D> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<B>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<B>>>();
+ }
+
+ void f31(Future<C> a, FutureOr<D> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<B>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<B>>>();
+ }
+
+ void f32(C a, FutureOr<D> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<B>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<B>>>();
+ }
+
+ void f33(E<B> a, E<C> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<E<B>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<E<B>>>();
+ }
+
+ void f34(FutureOr<E<B>> a, FutureOr<E<C>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<E<B>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<E<B>>>>();
+ }
+
+ void f35(Future<E<B>> a, FutureOr<E<C>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<E<B>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<E<B>>>>();
+ }
+
+ void f36(E<B> a, FutureOr<E<C>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<E<B>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<E<B>>>>();
+ }
+
+ void f37(E<B> a, F<C> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<E<B>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<E<B>>>();
+ }
+
+ void f38(FutureOr<E<B>> a, FutureOr<F<C>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<E<B>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<E<B>>>>();
+ }
+
+ void f39(Future<E<B>> a, FutureOr<F<C>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<E<B>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<E<B>>>>();
+ }
+
+ void f40(E<B> a, FutureOr<F<C>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<E<B>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<E<B>>>>();
+ }
+
+ void f41(int a, String? b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<Object?>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<Object?>>();
+ }
+
+ void f42(FutureOr<int> a, FutureOr<String?> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object?>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object?>>>();
+ }
+
+ void f43(Future<int> a, FutureOr<String?> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object?>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object?>>>();
+ }
+
+ void f44(int a, FutureOr<String?> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object?>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object?>>>();
+ }
+
+ void f45(List<int> a, List<String>? b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<List<Object>?>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<List<Object>?>>();
+ }
+
+ void f46(FutureOr<List<int>> a, FutureOr<List<String>?> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<List<Object>?>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<List<Object>?>>>();
+ }
+
+ void f47(Future<List<int>> a, FutureOr<List<String>?> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<List<Object>?>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<List<Object>?>>>();
+ }
+
+ void f48(List<int> a, FutureOr<List<String>?> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<List<Object>?>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<List<Object>?>>>();
+ }
+
+ void f49(E<C> a, F<B> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<Object>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<Object>>();
+ }
+
+ void f50(FutureOr<E<C>> a, FutureOr<F<B>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ void f51(Future<E<C>> a, FutureOr<F<B>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ void f52(E<C> a, FutureOr<F<B>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ // A sample of cases involving nested futures and nullable types.
+
+ void f53(int a, FutureOr<Future<int>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ // Could soundly have been `FutureOr<Future<int>>`.
+ void f54(Future<int> a, FutureOr<Future<int>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Object>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Object>>>();
+ }
+
+ void f55(Future<Future<int>> a, FutureOr<Future<int>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<Future<int>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<Future<int>>>>();
+ }
+
+ void f56(Future<FutureOr<int>> a, FutureOr<Future<int>> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<FutureOr<int>>>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<FutureOr<int>>>>();
+ }
+
+ void f57(Future<int?> a, FutureOr<int>? b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<int?>?>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<int?>?>>();
+ }
+
+ void f58(Future<int>? a, FutureOr<int?> b) {
+ var x = condition ? a : b;
+ x.expectStaticType<Exactly<FutureOr<int?>?>>();
+
+ var y = condition ? b : a;
+ y.expectStaticType<Exactly<FutureOr<int?>?>>();
+ }
+}
diff --git a/tests/language/setter/declaration_test.dart b/tests/language/setter/declaration_test.dart
index 617fc2c..78d5e81 100644
--- a/tests/language/setter/declaration_test.dart
+++ b/tests/language/setter/declaration_test.dart
@@ -21,119 +21,119 @@
/*space*/ int? set wrongReturnType1(_) => 1;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_VOID_RETURN_FOR_SETTER
-// [cfe] unspecified
+// [cfe] The return type of the setter must be 'void' or absent.
/*space*/ FutureOr<void> set wrongReturnType2(_) {}
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_VOID_RETURN_FOR_SETTER
-// [cfe] unspecified
+// [cfe] The return type of the setter must be 'void' or absent.
/*space*/ Never set wrongReturnType3(_) => throw 1;
// ^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_VOID_RETURN_FOR_SETTER
-// [cfe] unspecified
+// [cfe] The return type of the setter must be 'void' or absent.
int get nonSubtypes1 => 1;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
-// [cfe] unspecified
+// [cfe] The type 'int' of the getter 'nonSubtypes1' is not a subtype of the type 'String' of the setter 'nonSubtypes1'.
set nonSubtypes1(String _) {}
int? get nonSubtypes2 => 1;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
-// [cfe] unspecified
+// [cfe] The type 'int?' of the getter 'nonSubtypes2' is not a subtype of the type 'int' of the setter 'nonSubtypes2'.
set nonSubtypes2(int _) {}
FutureOr<int> get nonSubtypes3 => 1;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
-// [cfe] unspecified
+// [cfe] The type 'FutureOr<int>' of the getter 'nonSubtypes3' is not a subtype of the type 'int' of the setter 'nonSubtypes3'.
set nonSubtypes3(int _) {}
dynamic get nonSubtypes4 => 1;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
-// [cfe] unspecified
+// [cfe] The type 'dynamic' of the getter 'nonSubtypes4' is not a subtype of the type 'int' of the setter 'nonSubtypes4'.
set nonSubtypes4(int _) {}
class C {
static int? set staticWrongReturnType1(_) => 1;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_VOID_RETURN_FOR_SETTER
- // [cfe] unspecified
+ // [cfe] The return type of the setter must be 'void' or absent.
static FutureOr<void> set staticWrongReturnType2(_) {}
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_VOID_RETURN_FOR_SETTER
- // [cfe] unspecified
+ // [cfe] The return type of the setter must be 'void' or absent.
static Never set staticWrongReturnType3(_) => throw 1;
// ^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_VOID_RETURN_FOR_SETTER
- // [cfe] unspecified
+ // [cfe] The return type of the setter must be 'void' or absent.
/*space*/ int? set wrongReturnType1(_) => 1;
// ^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_VOID_RETURN_FOR_SETTER
- // [cfe] unspecified
+ // [cfe] The return type of the setter must be 'void' or absent.
/*space*/ FutureOr<void> set wrongReturnType2(_) {}
// ^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_VOID_RETURN_FOR_SETTER
- // [cfe] unspecified
+ // [cfe] The return type of the setter must be 'void' or absent.
/*space*/ Never set wrongReturnType3(_) => throw 1;
// ^^^^^
// [analyzer] COMPILE_TIME_ERROR.NON_VOID_RETURN_FOR_SETTER
- // [cfe] unspecified
+ // [cfe] The return type of the setter must be 'void' or absent.
static int get staticNonSubtypes1 => 1;
// ^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
- // [cfe] unspecified
+ // [cfe] The type 'int' of the getter 'C.staticNonSubtypes1' is not a subtype of the type 'String' of the setter 'C.staticNonSubtypes1'.
static set staticNonSubtypes1(String _) {}
static int? get staticNonSubtypes2 => 1;
// ^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
- // [cfe] unspecified
+ // [cfe] The type 'int?' of the getter 'C.staticNonSubtypes2' is not a subtype of the type 'int' of the setter 'C.staticNonSubtypes2'.
static set staticNonSubtypes2(int _) {}
static FutureOr<int> get staticNonSubtypes3 => 1;
// ^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
- // [cfe] unspecified
+ // [cfe] The type 'FutureOr<int>' of the getter 'C.staticNonSubtypes3' is not a subtype of the type 'int' of the setter 'C.staticNonSubtypes3'.
static set staticNonSubtypes3(int _) {}
static dynamic get staticNonSubtypes4 => 1;
// ^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
- // [cfe] unspecified
+ // [cfe] The type 'dynamic' of the getter 'C.staticNonSubtypes4' is not a subtype of the type 'int' of the setter 'C.staticNonSubtypes4'.
static set staticNonSubtypes4(int _) {}
int get nonSubtypes1 => 1;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
- // [cfe] unspecified
+ // [cfe] The type 'int' of the getter 'C.nonSubtypes1' is not a subtype of the type 'String' of the setter 'C.nonSubtypes1'.
set nonSubtypes1(String _) {}
int? get nonSubtypes2 => 1;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
- // [cfe] unspecified
+ // [cfe] The type 'int?' of the getter 'C.nonSubtypes2' is not a subtype of the type 'int' of the setter 'C.nonSubtypes2'.
set nonSubtypes2(int _) {}
FutureOr<int> get nonSubtypes3 => 1;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
- // [cfe] unspecified
+ // [cfe] The type 'FutureOr<int>' of the getter 'C.nonSubtypes3' is not a subtype of the type 'int' of the setter 'C.nonSubtypes3'.
set nonSubtypes3(int _) {}
dynamic get nonSubtypes4 => 1;
// ^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_SUBTYPE_SETTER_TYPES
- // [cfe] unspecified
+ // [cfe] The type 'dynamic' of the getter 'C.nonSubtypes4' is not a subtype of the type 'int' of the setter 'C.nonSubtypes4'.
set nonSubtypes4(int _) {}
}
diff --git a/tests/language_2/getter/setter_type_test.dart b/tests/language_2/getter/setter_type_test.dart
index a7caee4..c813ca8 100644
--- a/tests/language_2/getter/setter_type_test.dart
+++ b/tests/language_2/getter/setter_type_test.dart
@@ -11,6 +11,7 @@
int get foo => bar;
// ^^^
// [analyzer] COMPILE_TIME_ERROR.GETTER_NOT_ASSIGNABLE_SETTER_TYPES
+// [cfe] The type 'int' of the getter 'foo' is not assignable to the type 'String' of the setter 'foo'.
void set foo(String str) {
bar = str.length;
diff --git a/tools/VERSION b/tools/VERSION
index 4bf35e7..005e49e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 11
PATCH 0
-PRERELEASE 205
+PRERELEASE 206
PRERELEASE_PATCH 0
\ No newline at end of file