[CFE] Error in outline and recover from type parameter in static field in class
Change-Id: I7127a6acd85c3133912d70abb28285989aeeae61
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138809
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 97b2ede..df4c39b 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -252,7 +252,7 @@
void build(SourceLibraryBuilder libraryBuilder) {
if (type != null) {
- fieldType = type.build(libraryBuilder);
+ fieldType = type.build(libraryBuilder, null, isStatic);
}
_fieldEncoding.build(libraryBuilder, this);
}
diff --git a/pkg/front_end/lib/src/fasta/builder/fixed_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/fixed_type_builder.dart
index 8d18032..7675648 100644
--- a/pkg/front_end/lib/src/fasta/builder/fixed_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/fixed_type_builder.dart
@@ -28,7 +28,10 @@
return buffer;
}
- DartType build(LibraryBuilder library, [TypedefType origin]) => type;
+ DartType build(LibraryBuilder library,
+ [TypedefType origin, bool notInstanceContext]) {
+ return type;
+ }
Supertype buildSupertype(
LibraryBuilder library, int charOffset, Uri fileUri) {
diff --git a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
index c1aa78c1..521e537 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_type_builder.dart
@@ -71,7 +71,8 @@
return buffer;
}
- FunctionType build(LibraryBuilder library, [TypedefType origin]) {
+ FunctionType build(LibraryBuilder library,
+ [TypedefType origin, bool notInstanceContext]) {
DartType builtReturnType =
returnType?.build(library) ?? const DynamicType();
List<DartType> positionalParameters = <DartType>[];
diff --git a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
index 4387c8e..1991aed 100644
--- a/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/mixin_application_builder.dart
@@ -43,7 +43,8 @@
}
@override
- InterfaceType build(LibraryBuilder library, [TypedefType origin]) {
+ InterfaceType build(LibraryBuilder library,
+ [TypedefType origin, bool notInstanceContext]) {
int charOffset = -1; // TODO(ahe): Provide these.
Uri fileUri = null; // TODO(ahe): Provide these.
return unsupported("build", charOffset, fileUri);
diff --git a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
index 46e5327..d4601f5 100644
--- a/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/named_type_builder.dart
@@ -6,18 +6,31 @@
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-import 'package:kernel/ast.dart' show DartType, Supertype, TypedefType;
+import 'package:kernel/ast.dart'
+ show
+ Class,
+ DartType,
+ Extension,
+ InvalidType,
+ Supertype,
+ TreeNode,
+ TypeParameter,
+ TypedefType;
import '../fasta_codes.dart'
show
- Message,
- Template,
- noLength,
- templateMissingExplicitTypeArguments,
- messageNotATypeContext,
LocatedMessage,
+ Message,
+ Severity,
+ Template,
+ messageNotATypeContext,
+ messageTypeVariableInStaticContext,
+ noLength,
templateExtendingRestricted,
+ templateMissingExplicitTypeArguments,
templateNotAType,
+ templateSupertypeIsIllegal,
+ templateSupertypeIsTypeVariable,
templateTypeArgumentMismatch,
templateTypeArgumentsOnTypeVariable,
templateTypeNotFound;
@@ -50,14 +63,18 @@
final NullabilityBuilder nullabilityBuilder;
+ final Uri fileUri;
+ final int charOffset;
+
@override
TypeDeclarationBuilder declaration;
- NamedTypeBuilder(this.name, this.nullabilityBuilder, this.arguments);
+ NamedTypeBuilder(this.name, this.nullabilityBuilder, this.arguments,
+ [this.fileUri, this.charOffset]);
NamedTypeBuilder.fromTypeDeclarationBuilder(
this.declaration, this.nullabilityBuilder,
- [this.arguments])
+ [this.arguments, this.fileUri, this.charOffset])
: this.name = declaration.name;
@override
@@ -218,8 +235,23 @@
}
// TODO(johnniwinther): Store [origin] on the built type.
- DartType build(LibraryBuilder library, [TypedefType origin]) {
+ DartType build(LibraryBuilder library,
+ [TypedefType origin, bool notInstanceContext]) {
assert(declaration != null, "Declaration has not been resolved on $this.");
+ if (notInstanceContext == true && declaration.isTypeVariable) {
+ TypeVariableBuilder typeParameterBuilder = declaration;
+ TypeParameter typeParameter = typeParameterBuilder.parameter;
+ if (typeParameter.parent is Class || typeParameter.parent is Extension) {
+ messageTypeVariableInStaticContext;
+ library.addProblem(
+ messageTypeVariableInStaticContext,
+ charOffset ?? TreeNode.noOffset,
+ noLength,
+ fileUri ?? library.fileUri);
+ return const InvalidType();
+ }
+ }
+
return declaration.buildType(library, nullabilityBuilder, arguments);
}
diff --git a/pkg/front_end/lib/src/fasta/builder/type_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
index d3e7c8e..01d5a33 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_builder.dart
@@ -55,7 +55,8 @@
String get fullNameForErrors => "${printOn(new StringBuffer())}";
- DartType build(LibraryBuilder library, [TypedefType origin]);
+ DartType build(LibraryBuilder library,
+ [TypedefType origin, bool notInstanceContext]);
Supertype buildSupertype(LibraryBuilder library, int charOffset, Uri fileUri);
diff --git a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
index c34ef54..277e05c 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
@@ -127,7 +127,8 @@
}
TypeBuilder asTypeBuilder() {
- return new NamedTypeBuilder(name, const NullabilityBuilder.omitted(), null)
+ return new NamedTypeBuilder(
+ name, const NullabilityBuilder.omitted(), null, fileUri, charOffset)
..bind(this);
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 82b8342..7cadadf 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -3090,8 +3090,12 @@
libraryBuilder.addProblem(
message, offset, lengthOfSpan(beginToken, suffix), uri);
push(new UnresolvedType(
- new NamedTypeBuilder(name,
- libraryBuilder.nullableBuilderIfTrue(isMarkedAsNullable), null)
+ new NamedTypeBuilder(
+ name,
+ libraryBuilder.nullableBuilderIfTrue(isMarkedAsNullable),
+ null,
+ uri,
+ offset)
..bind(new InvalidTypeDeclarationBuilder(
name,
message.withLocation(
@@ -3180,7 +3184,8 @@
int offset = offsetForToken(token);
// "void" is always nullable.
push(new UnresolvedType(
- new NamedTypeBuilder("void", const NullabilityBuilder.nullable(), null)
+ new NamedTypeBuilder(
+ "void", const NullabilityBuilder.nullable(), null, uri, offset)
..bind(new VoidTypeBuilder(const VoidType(), libraryBuilder, offset)),
offset,
uri));
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 33555b8..b2a1e9e 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -1865,7 +1865,11 @@
builder.name, via.join("', '"));
addProblem(message, builder.charOffset, builder.name.length);
builder.bound = new NamedTypeBuilder(
- builder.name, const NullabilityBuilder.omitted(), null)
+ builder.name,
+ const NullabilityBuilder.omitted(),
+ null,
+ uri,
+ builder.charOffset)
..bind(new InvalidTypeDeclarationBuilder(
builder.name,
message.withLocation(
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 618f8c2..8f4d344 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
@@ -1262,7 +1262,9 @@
TypeBuilder addNamedType(Object name, NullabilityBuilder nullabilityBuilder,
List<TypeBuilder> arguments, int charOffset) {
return addType(
- new NamedTypeBuilder(name, nullabilityBuilder, arguments), charOffset);
+ new NamedTypeBuilder(
+ name, nullabilityBuilder, arguments, fileUri, charOffset),
+ charOffset);
}
TypeBuilder addMixinApplication(
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart
index 4ff87d7..9a01ce1 100644
--- a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart
@@ -19,6 +19,7 @@
static void foo12(void Function(U) b) { return null; }
// old syntax: variable named "b" of type "U" of a function called 'Function'.
static void foo13(void Function(U b)) { return null; }
+ static U foo14 = null;
}
main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.outline.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.outline.expect
index b8ae066..5db43ea 100644
--- a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.outline.expect
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.outline.expect
@@ -30,10 +30,15 @@
// static void foo13(void Function(U b)) { return null; }
// ^
//
+// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart:22:10: Error: Type variables can't be used in static members.
+// static U foo14 = null;
+// ^
+//
import self as self;
import "dart:core" as core;
class Foo<U extends core::Object* = dynamic> extends core::Object {
+ static field invalid-type foo14;
synthetic constructor •() → self::Foo<self::Foo::U*>*
;
static method foo1() → dynamic
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.strong.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.strong.expect
index ff33285..966ed95 100644
--- a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.strong.expect
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.strong.expect
@@ -30,6 +30,10 @@
// static void foo13(void Function(U b)) { return null; }
// ^
//
+// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart:22:10: Error: Type variables can't be used in static members.
+// static U foo14 = null;
+// ^
+//
// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart:7:20: Error: Type variables can't be used in static members.
// static void foo2(U x) { return null; }
// ^
@@ -78,6 +82,7 @@
import "dart:core" as core;
class Foo<U extends core::Object* = dynamic> extends core::Object {
+ static field invalid-type foo14 = null;
synthetic constructor •() → self::Foo<self::Foo::U*>*
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.strong.transformed.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.strong.transformed.expect
index ff33285..966ed95 100644
--- a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart.strong.transformed.expect
@@ -30,6 +30,10 @@
// static void foo13(void Function(U b)) { return null; }
// ^
//
+// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart:22:10: Error: Type variables can't be used in static members.
+// static U foo14 = null;
+// ^
+//
// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_class.dart:7:20: Error: Type variables can't be used in static members.
// static void foo2(U x) { return null; }
// ^
@@ -78,6 +82,7 @@
import "dart:core" as core;
class Foo<U extends core::Object* = dynamic> extends core::Object {
+ static field invalid-type foo14 = null;
synthetic constructor •() → self::Foo<self::Foo::U*>*
: super core::Object::•()
;
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart
index 2cbab2d..7c56bec 100644
--- a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart
@@ -19,6 +19,7 @@
static void foo12(void Function(U) b) { return null; }
// old syntax: variable named "b" of type "U" of a function called 'Function'.
static void foo13(void Function(U b)) { return null; }
+ static U foo14 = null;
}
main() {}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.outline.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.outline.expect
index b74feb4..ef530f4 100644
--- a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.outline.expect
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.outline.expect
@@ -30,6 +30,10 @@
// static void foo13(void Function(U b)) { return null; }
// ^
//
+// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart:22:10: Error: Type variables can't be used in static members.
+// static U foo14 = null;
+// ^
+//
import self as self;
import "dart:core" as core;
@@ -43,7 +47,9 @@
static method foo11 = self::Foo|foo11;
static method foo12 = self::Foo|foo12;
static method foo13 = self::Foo|foo13;
+ static field foo14 = self::Foo|foo14;
}
+static field invalid-type Foo|foo14;
static method Foo|foo1() → dynamic
;
static method Foo|foo2(dynamic x) → void
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.strong.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.strong.expect
index 8c2c382..e6a1aa9 100644
--- a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.strong.expect
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.strong.expect
@@ -30,6 +30,10 @@
// static void foo13(void Function(U b)) { return null; }
// ^
//
+// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart:22:10: Error: Type variables can't be used in static members.
+// static U foo14 = null;
+// ^
+//
// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart:7:20: Error: Type variables can't be used in static members.
// static void foo2(U x) { return null; }
// ^
@@ -87,7 +91,9 @@
static method foo11 = self::Foo|foo11;
static method foo12 = self::Foo|foo12;
static method foo13 = self::Foo|foo13;
+ static field foo14 = self::Foo|foo14;
}
+static field invalid-type Foo|foo14 = null;
static method Foo|foo1() → dynamic {
return null;
}
diff --git a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.strong.transformed.expect b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.strong.transformed.expect
index 8c2c382..e6a1aa9 100644
--- a/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart.strong.transformed.expect
@@ -30,6 +30,10 @@
// static void foo13(void Function(U b)) { return null; }
// ^
//
+// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart:22:10: Error: Type variables can't be used in static members.
+// static U foo14 = null;
+// ^
+//
// pkg/front_end/testcases/general/type_parameter_usage_in_static_method_in_extension.dart:7:20: Error: Type variables can't be used in static members.
// static void foo2(U x) { return null; }
// ^
@@ -87,7 +91,9 @@
static method foo11 = self::Foo|foo11;
static method foo12 = self::Foo|foo12;
static method foo13 = self::Foo|foo13;
+ static field foo14 = self::Foo|foo14;
}
+static field invalid-type Foo|foo14 = null;
static method Foo|foo1() → dynamic {
return null;
}