[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>
This commit is contained in:
Jens Johansen 2020-03-11 07:48:49 +00:00 committed by commit-bot@chromium.org
parent 37530145ff
commit e6a1e70960
18 changed files with 105 additions and 20 deletions

View file

@ -252,7 +252,7 @@ class SourceFieldBuilder extends MemberBuilderImpl implements FieldBuilder {
void build(SourceLibraryBuilder libraryBuilder) {
if (type != null) {
fieldType = type.build(libraryBuilder);
fieldType = type.build(libraryBuilder, null, isStatic);
}
_fieldEncoding.build(libraryBuilder, this);
}

View file

@ -28,7 +28,10 @@ class FixedTypeBuilder extends TypeBuilder {
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) {

View file

@ -71,7 +71,8 @@ class FunctionTypeBuilder extends TypeBuilder {
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>[];

View file

@ -43,7 +43,8 @@ class MixinApplicationBuilder extends TypeBuilder {
}
@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);

View file

@ -6,18 +6,31 @@ library fasta.named_type_builder;
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 @@ class NamedTypeBuilder extends TypeBuilder {
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 @@ class NamedTypeBuilder extends TypeBuilder {
}
// 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);
}

View file

@ -55,7 +55,8 @@ abstract class TypeBuilder {
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);

View file

@ -127,7 +127,8 @@ class TypeVariableBuilder extends TypeDeclarationBuilderImpl {
}
TypeBuilder asTypeBuilder() {
return new NamedTypeBuilder(name, const NullabilityBuilder.omitted(), null)
return new NamedTypeBuilder(
name, const NullabilityBuilder.omitted(), null, fileUri, charOffset)
..bind(this);
}

View file

@ -3090,8 +3090,12 @@ class BodyBuilder extends ScopeListener<JumpTarget>
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 @@ class BodyBuilder extends ScopeListener<JumpTarget>
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));

View file

@ -1865,7 +1865,11 @@ class OutlineBuilder extends StackListenerImpl {
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(

View file

@ -1262,7 +1262,9 @@ class SourceLibraryBuilder extends LibraryBuilderImpl {
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(

View file

@ -19,6 +19,7 @@ class Foo<U> {
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() {}

View file

@ -30,10 +30,15 @@ library;
// 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

View file

@ -30,6 +30,10 @@ library;
// 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 self as self;
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::•()
;

View file

@ -30,6 +30,10 @@ library;
// 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 self as self;
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::•()
;

View file

@ -19,6 +19,7 @@ extension Foo<U> on List {
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() {}

View file

@ -30,6 +30,10 @@ library;
// 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 @@ extension Foo<U extends core::Object* = dynamic> on core::List<dynamic>* {
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

View file

@ -30,6 +30,10 @@ library;
// 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 @@ extension Foo<U extends core::Object* = dynamic> on core::List<dynamic>* {
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;
}

View file

@ -30,6 +30,10 @@ library;
// 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 @@ extension Foo<U extends core::Object* = dynamic> on core::List<dynamic>* {
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;
}