Version 2.17.0-17.0.dev
Merge commit '2a31ee5530c698329a643ec1f30217a05ff21c55' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
index 74bf73c..9a507f4 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/builders.dart
@@ -30,7 +30,7 @@
/// may be asked to run in this state during the development cycle. It is
/// helpful for users if macros provide a best effort implementation in that
/// case or handle the error in a useful way.
- Future<StaticType> resolve(TypeAnnotation typeAnnotation);
+ Future<StaticType> resolve(covariant TypeAnnotation typeAnnotation);
}
/// The api used to introspect on a [ClassDeclaration].
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
index 09c2de9..c0f8a9f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/api/introspection.dart
@@ -49,10 +49,10 @@
/// compared to other static types.
abstract class StaticType {
/// Returns true if this is a subtype of [other].
- Future<bool> isSubtypeOf(StaticType other);
+ Future<bool> isSubtypeOf(covariant StaticType other);
/// Returns true if this is an identical type to [other].
- Future<bool> isExactly(StaticType other);
+ Future<bool> isExactly(covariant StaticType other);
}
/// A subtype of [StaticType] representing types that can be resolved by name
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
index 332144f..158363f 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/bootstrap.dart
@@ -27,6 +27,7 @@
import 'dart:isolate';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
+import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/response_impls.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/serialization.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/protocol.dart';
@@ -39,27 +40,33 @@
///
/// Supports the client side of the macro expansion protocol.
void main(_, SendPort sendPort) {
+ /// Local function that sends requests and returns responses using [sendPort].
+ Future<Response> sendRequest(Request request) => _sendRequest(request, sendPort);
+
withSerializationMode(SerializationMode.client, () {
ReceivePort receivePort = new ReceivePort();
sendPort.send(receivePort.sendPort);
+
receivePort.listen((message) async {
var deserializer = JsonDeserializer(message as Iterable<Object?>)
..moveNext();
+ int zoneId = deserializer.expectNum();
+ deserializer..moveNext();
var type = MessageType.values[deserializer.expectNum()];
var serializer = JsonSerializer();
switch (type) {
case MessageType.instantiateMacroRequest:
- var request = InstantiateMacroRequest.deserialize(deserializer);
+ var request = new InstantiateMacroRequest.deserialize(deserializer, zoneId);
(await _instantiateMacro(request)).serialize(serializer);
break;
case MessageType.executeDefinitionsPhaseRequest:
- var request = ExecuteDefinitionsPhaseRequest.deserialize(
- deserializer,
- ClientTypeResolver(),
- ClientClassIntrospector(),
- ClientTypeDeclarationsResolver());
- (await _executeDefinitionsPhase(request)).serialize(serializer);
+ var request = new ExecuteDefinitionsPhaseRequest.deserialize(deserializer, zoneId);
+ (await _executeDefinitionsPhase(request, sendRequest)).serialize(serializer);
break;
+ case MessageType.response:
+ var response = new SerializableResponse.deserialize(deserializer, zoneId);
+ _responseCompleters.remove(response.requestId)!.complete(response);
+ return;
default:
throw new StateError('Unhandled event type \$type');
}
@@ -102,31 +109,46 @@
response: identifier,
requestId: request.id,
serializationZoneId: request.serializationZoneId);
- } catch (e) {
+ } catch (e, s) {
return new SerializableResponse(
responseType: MessageType.error,
error: e.toString(),
+ stackTrace: s.toString(),
requestId: request.id,
serializationZoneId: request.serializationZoneId);
}
}
Future<SerializableResponse> _executeDefinitionsPhase(
- ExecuteDefinitionsPhaseRequest request) async {
+ ExecuteDefinitionsPhaseRequest request,
+ Future<Response> Function(Request request) sendRequest) async {
try {
Macro? instance = _macroInstances[request.macro];
if (instance == null) {
throw new StateError('Unrecognized macro instance \${request.macro}\\n'
'Known instances: \$_macroInstances)');
}
+ var typeResolver = ClientTypeResolver(
+ sendRequest,
+ remoteInstance: request.typeResolver,
+ serializationZoneId: request.serializationZoneId);
+ var typeDeclarationResolver = ClientTypeDeclarationResolver(
+ sendRequest,
+ remoteInstance: request.typeDeclarationResolver,
+ serializationZoneId: request.serializationZoneId);
+ var classIntrospector = ClientClassIntrospector(
+ sendRequest,
+ remoteInstance: request.classIntrospector,
+ serializationZoneId: request.serializationZoneId);
+
Declaration declaration = request.declaration;
if (instance is FunctionDefinitionMacro &&
declaration is FunctionDeclarationImpl) {
FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
declaration,
- request.typeResolver,
- request.typeDeclarationResolver,
- request.classIntrospector);
+ typeResolver,
+ typeDeclarationResolver,
+ classIntrospector);
await instance.buildDefinitionForFunction(declaration, builder);
return new SerializableResponse(
responseType: MessageType.macroExecutionResult,
@@ -137,12 +159,28 @@
throw new UnsupportedError(
('Only FunctionDefinitionMacros are supported currently'));
}
- } catch (e) {
+ } catch (e, s) {
return new SerializableResponse(
responseType: MessageType.error,
error: e.toString(),
+ stackTrace: s.toString(),
requestId: request.id,
serializationZoneId: request.serializationZoneId);
}
}
+
+/// Holds on to response completers by request id.
+final _responseCompleters = <int, Completer<Response>>{};
+
+/// Serializes [request], sends it to [sendPort], and sets up a [Completer] in
+/// [_responseCompleters] to handle the response.
+Future<Response> _sendRequest(Request request, SendPort sendPort) {
+ Completer<Response> completer = Completer();
+ _responseCompleters[request.id] = completer;
+ JsonSerializer serializer = JsonSerializer();
+ serializer.addNum(request.serializationZoneId);
+ request.serialize(serializer);
+ sendPort.send(serializer.result);
+ return completer.future;
+}
''';
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
index 68d0f94..3f9e55c 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/protocol.dart
@@ -6,6 +6,8 @@
/// the isolate or process doing the work of macro loading and execution.
library _fe_analyzer_shared.src.macros.executor_shared.protocol;
+import 'package:meta/meta.dart';
+
import '../executor.dart';
import '../api.dart';
import '../executor_shared/response_impls.dart';
@@ -22,13 +24,16 @@
Request({int? id, required this.serializationZoneId})
: this.id = id ?? _next++;
- Request.deserialize(Deserializer deserializer)
- : serializationZoneId = (deserializer..moveNext()).expectNum(),
- id = (deserializer..moveNext()).expectNum();
+ /// The [serializationZoneId] is a part of the header and needs to be parsed
+ /// before deserializing objects, and then passed in here.
+ Request.deserialize(Deserializer deserializer, this.serializationZoneId)
+ : id = (deserializer..moveNext()).expectNum();
- void serialize(Serializer serializer) => serializer
- ..addNum(serializationZoneId)
- ..addNum(id);
+ /// The [serializationZoneId] needs to be separately serialized before the
+ /// rest of the object. This is not done by the instances themselves but by
+ /// the macro implementations.
+ @mustCallSuper
+ void serialize(Serializer serializer) => serializer.addNum(id);
static int _next = 0;
}
@@ -38,10 +43,15 @@
class Response {
final Object? response;
final Object? error;
+ final String? stackTrace;
final int requestId;
- Response({this.response, this.error, required this.requestId})
- : assert(response != null || error != null),
+ Response({
+ this.response,
+ this.error,
+ this.stackTrace,
+ required this.requestId,
+ }) : assert(response != null || error != null),
assert(response == null || error == null);
}
@@ -50,11 +60,13 @@
final Serializable? response;
final MessageType responseType;
final String? error;
+ final String? stackTrace;
final int requestId;
final int serializationZoneId;
SerializableResponse({
this.error,
+ this.stackTrace,
required this.requestId,
this.response,
required this.responseType,
@@ -70,10 +82,13 @@
MessageType responseType = MessageType.values[deserializer.expectNum()];
Serializable? response;
String? error;
+ String? stackTrace;
switch (responseType) {
case MessageType.error:
deserializer.moveNext();
error = deserializer.expectString();
+ deserializer.moveNext();
+ stackTrace = deserializer.expectNullableString();
break;
case MessageType.macroClassIdentifier:
response = new MacroClassIdentifierImpl.deserialize(deserializer);
@@ -84,6 +99,12 @@
case MessageType.macroExecutionResult:
response = new MacroExecutionResultImpl.deserialize(deserializer);
break;
+ case MessageType.staticType:
+ response = RemoteInstance.deserialize(deserializer);
+ break;
+ case MessageType.boolean:
+ response = new BooleanValue.deserialize(deserializer);
+ break;
default:
throw new StateError('Unexpected response type $responseType');
}
@@ -92,6 +113,7 @@
responseType: responseType,
response: response,
error: error,
+ stackTrace: stackTrace,
requestId: (deserializer..moveNext()).expectNum(),
serializationZoneId: serializationZoneId);
}
@@ -99,16 +121,30 @@
void serialize(Serializer serializer) {
serializer
..addNum(serializationZoneId)
+ ..addNum(MessageType.response.index)
..addNum(responseType.index);
if (response != null) {
response!.serialize(serializer);
} else if (error != null) {
serializer.addString(error!.toString());
+ serializer.addNullableString(stackTrace);
}
serializer.addNum(requestId);
}
}
+class BooleanValue implements Serializable {
+ final bool value;
+
+ BooleanValue(this.value);
+
+ BooleanValue.deserialize(Deserializer deserializer)
+ : value = (deserializer..moveNext()).expectBool();
+
+ @override
+ void serialize(Serializer serializer) => serializer..addBool(value);
+}
+
/// A request to load a macro in this isolate.
class LoadMacroRequest extends Request {
final Uri library;
@@ -117,10 +153,11 @@
LoadMacroRequest(this.library, this.name, {required int serializationZoneId})
: super(serializationZoneId: serializationZoneId);
- LoadMacroRequest.deserialize(Deserializer deserializer)
+ LoadMacroRequest.deserialize(
+ Deserializer deserializer, int serializationZoneId)
: library = Uri.parse((deserializer..moveNext()).expectString()),
name = (deserializer..moveNext()).expectString(),
- super.deserialize(deserializer);
+ super.deserialize(deserializer, serializationZoneId);
@override
void serialize(Serializer serializer) {
@@ -142,11 +179,12 @@
{required int serializationZoneId})
: super(serializationZoneId: serializationZoneId);
- InstantiateMacroRequest.deserialize(Deserializer deserializer)
+ InstantiateMacroRequest.deserialize(
+ Deserializer deserializer, int serializationZoneId)
: macroClass = new MacroClassIdentifierImpl.deserialize(deserializer),
constructorName = (deserializer..moveNext()).expectString(),
arguments = new Arguments.deserialize(deserializer),
- super.deserialize(deserializer);
+ super.deserialize(deserializer, serializationZoneId);
@override
void serialize(Serializer serializer) {
@@ -164,14 +202,9 @@
final MacroInstanceIdentifier macro;
final DeclarationImpl declaration;
- /// Client/Server specific implementation, not serialized.
- final TypeResolver typeResolver;
-
- /// Client/Server specific implementation, not serialized.
- final ClassIntrospector classIntrospector;
-
- /// Client/Server specific implementation, not serialized.
- final TypeDeclarationResolver typeDeclarationResolver;
+ final RemoteInstanceImpl typeResolver;
+ final RemoteInstanceImpl classIntrospector;
+ final RemoteInstanceImpl typeDeclarationResolver;
ExecuteDefinitionsPhaseRequest(this.macro, this.declaration,
this.typeResolver, this.classIntrospector, this.typeDeclarationResolver,
@@ -180,51 +213,175 @@
/// When deserializing we have already consumed the message type, so we don't
/// consume it again.
- ExecuteDefinitionsPhaseRequest.deserialize(Deserializer deserializer,
- this.typeResolver, this.classIntrospector, this.typeDeclarationResolver)
+ ExecuteDefinitionsPhaseRequest.deserialize(
+ Deserializer deserializer, int serializationZoneId)
: macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
declaration = RemoteInstance.deserialize(deserializer),
- super.deserialize(deserializer);
+ typeResolver = RemoteInstance.deserialize(deserializer),
+ classIntrospector = RemoteInstance.deserialize(deserializer),
+ typeDeclarationResolver = RemoteInstance.deserialize(deserializer),
+ super.deserialize(deserializer, serializationZoneId);
void serialize(Serializer serializer) {
serializer.addNum(MessageType.executeDefinitionsPhaseRequest.index);
macro.serialize(serializer);
declaration.serialize(serializer);
+ typeResolver.serialize(serializer);
+ classIntrospector.serialize(serializer);
+ typeDeclarationResolver.serialize(serializer);
+
super.serialize(serializer);
}
}
/// A request to reflect on a type annotation
-class ReflectTypeRequest extends Request {
+class ResolveTypeRequest extends Request {
final TypeAnnotationImpl typeAnnotation;
+ final RemoteInstanceImpl typeResolver;
- ReflectTypeRequest(this.typeAnnotation, {required int serializationZoneId})
+ ResolveTypeRequest(this.typeAnnotation, this.typeResolver,
+ {required int serializationZoneId})
: super(serializationZoneId: serializationZoneId);
/// When deserializing we have already consumed the message type, so we don't
/// consume it again.
- ReflectTypeRequest.deserialize(Deserializer deserializer)
+ ResolveTypeRequest.deserialize(
+ Deserializer deserializer, int serializationZoneId)
: typeAnnotation = RemoteInstance.deserialize(deserializer),
- super.deserialize(deserializer);
+ typeResolver = RemoteInstance.deserialize(deserializer),
+ super.deserialize(deserializer, serializationZoneId);
void serialize(Serializer serializer) {
- serializer.addNum(MessageType.reflectTypeRequest.index);
+ serializer.addNum(MessageType.resolveTypeRequest.index);
typeAnnotation.serialize(serializer);
+ typeResolver.serialize(serializer);
super.serialize(serializer);
}
}
-/// TODO: Implement this
+/// A request to check if a type is exactly another type.
+class IsExactlyTypeRequest extends Request {
+ final RemoteInstanceImpl leftType;
+ final RemoteInstanceImpl rightType;
+
+ IsExactlyTypeRequest(this.leftType, this.rightType,
+ {required int serializationZoneId})
+ : super(serializationZoneId: serializationZoneId);
+
+ /// When deserializing we have already consumed the message type, so we don't
+ /// consume it again.
+ IsExactlyTypeRequest.deserialize(
+ Deserializer deserializer, int serializationZoneId)
+ : leftType = RemoteInstance.deserialize(deserializer),
+ rightType = RemoteInstance.deserialize(deserializer),
+ super.deserialize(deserializer, serializationZoneId);
+
+ void serialize(Serializer serializer) {
+ serializer.addNum(MessageType.isExactlyTypeRequest.index);
+ leftType.serialize(serializer);
+ rightType.serialize(serializer);
+ super.serialize(serializer);
+ }
+}
+
+/// A request to check if a type is exactly another type.
+class IsSubtypeOfRequest extends Request {
+ final ClientStaticTypeImpl leftType;
+ final ClientStaticTypeImpl rightType;
+
+ IsSubtypeOfRequest(this.leftType, this.rightType,
+ {required int serializationZoneId})
+ : super(serializationZoneId: serializationZoneId);
+
+ /// When deserializing we have already consumed the message type, so we don't
+ /// consume it again.
+ IsSubtypeOfRequest.deserialize(
+ Deserializer deserializer, int serializationZoneId)
+ : leftType = RemoteInstance.deserialize(deserializer),
+ rightType = RemoteInstance.deserialize(deserializer),
+ super.deserialize(deserializer, serializationZoneId);
+
+ void serialize(Serializer serializer) {
+ serializer.addNum(MessageType.isSubtypeOfRequest.index);
+ leftType.remoteInstance.serialize(serializer);
+ rightType.remoteInstance.serialize(serializer);
+ super.serialize(serializer);
+ }
+}
+
+/// Client side implementation of a [TypeResolver], which creates a
+/// [ResolveTypeRequest] and passes it to a given [sendRequest] function which
+/// can return the [Response].
class ClientTypeResolver implements TypeResolver {
+ /// The actual remote instance of this type resolver.
+ final RemoteInstanceImpl remoteInstance;
+
+ /// The ID of the zone in which to find the original type resolver.
+ final int serializationZoneId;
+
+ /// A function that can send a request and return a response using an
+ /// arbitrary communication channel.
+ final Future<Response> Function(Request request) _sendRequest;
+
+ ClientTypeResolver(this._sendRequest,
+ {required this.remoteInstance, required this.serializationZoneId});
+
@override
- Future<StaticType> resolve(TypeAnnotation typeAnnotation) {
- // TODO: implement resolve
- throw new UnimplementedError();
+ Future<StaticType> resolve(TypeAnnotationImpl typeAnnotation) async {
+ ResolveTypeRequest request = new ResolveTypeRequest(
+ typeAnnotation, remoteInstance,
+ serializationZoneId: serializationZoneId);
+ RemoteInstanceImpl remoteType =
+ _handleResponse(await _sendRequest(request));
+ return new ClientStaticTypeImpl(_sendRequest,
+ remoteInstance: remoteType, serializationZoneId: serializationZoneId);
+ }
+}
+
+class ClientStaticTypeImpl implements StaticType {
+ /// The actual remote instance of this static type.
+ final RemoteInstanceImpl remoteInstance;
+
+ final int serializationZoneId;
+
+ /// A function that can send a request and return a response using an
+ /// arbitrary communication channel.
+ final Future<Response> Function(Request request) sendRequest;
+
+ ClientStaticTypeImpl(this.sendRequest,
+ {required this.remoteInstance, required this.serializationZoneId});
+
+ @override
+ Future<bool> isExactly(ClientStaticTypeImpl other) async {
+ IsExactlyTypeRequest request = new IsExactlyTypeRequest(
+ this.remoteInstance, other.remoteInstance,
+ serializationZoneId: serializationZoneId);
+ return _handleResponse<BooleanValue>(await sendRequest(request)).value;
+ }
+
+ @override
+ Future<bool> isSubtypeOf(ClientStaticTypeImpl other) async {
+ IsSubtypeOfRequest request = new IsSubtypeOfRequest(this, other,
+ serializationZoneId: serializationZoneId);
+ return _handleResponse<BooleanValue>(await sendRequest(request)).value;
}
}
/// TODO: Implement this
class ClientClassIntrospector implements ClassIntrospector {
+ /// The actual remote instance of this type resolver.
+ final RemoteInstanceImpl remoteInstance;
+
+ /// The ID of the zone in which to find the original type resolver.
+ final int serializationZoneId;
+
+ /// A function that can send a request and return a response using an
+ /// arbitrary communication channel.
+ final Future<Response> Function(Request request) sendRequest;
+
+ ClientClassIntrospector(this.sendRequest,
+ {required this.remoteInstance, required this.serializationZoneId});
+
@override
Future<List<ConstructorDeclaration>> constructorsOf(ClassDeclaration clazz) {
// TODO: implement constructorsOf
@@ -263,7 +420,20 @@
}
/// TODO: Implement this
-class ClientTypeDeclarationsResolver implements TypeDeclarationResolver {
+class ClientTypeDeclarationResolver implements TypeDeclarationResolver {
+ /// The actual remote instance of this type resolver.
+ final RemoteInstanceImpl remoteInstance;
+
+ /// The ID of the zone in which to find the original type resolver.
+ final int serializationZoneId;
+
+ /// A function that can send a request and return a response using an
+ /// arbitrary communication channel.
+ final Future<Response> Function(Request request) sendRequest;
+
+ ClientTypeDeclarationResolver(this.sendRequest,
+ {required this.remoteInstance, required this.serializationZoneId});
+
@override
Future<TypeDeclaration> declarationOf(NamedStaticType annotation) {
// TODO: implement declarationOf
@@ -271,13 +441,39 @@
}
}
+/// An exception that occurred remotely, the exception object and stack trace
+/// are serialized as [String]s and both included in the [toString] output.
+class RemoteException implements Exception {
+ final String error;
+ final String? stackTrace;
+
+ RemoteException(this.error, [this.stackTrace]);
+
+ String toString() =>
+ 'RemoteException: $error${stackTrace == null ? '' : '\n\n$stackTrace'}';
+}
+
+/// Either returns the actual response from [response], casted to [T], or throws
+/// a [RemoteException] with the given error and stack trace.
+T _handleResponse<T>(Response response) {
+ if (response.response != null) {
+ return response.response as T;
+ }
+ throw new RemoteException(response.error!.toString(), response.stackTrace);
+}
+
enum MessageType {
+ boolean,
error,
executeDefinitionsPhaseRequest,
instantiateMacroRequest,
+ isExactlyTypeRequest,
+ isSubtypeOfRequest,
loadMacroRequest,
- reflectTypeRequest,
+ resolveTypeRequest,
macroClassIdentifier,
macroInstanceIdentifier,
macroExecutionResult,
+ response,
+ staticType,
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart
index 5dcd1f8..59c26fd 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/remote_instance.dart
@@ -70,6 +70,20 @@
}
}
+/// A remote instance which is just a pointer to some server side instance of
+/// a generic object.
+///
+/// The wrapped object is not serialized.
+class RemoteInstanceImpl extends RemoteInstance {
+ /// Always null on the client side, has an actual instance on the server side.
+ final Object? instance;
+
+ @override
+ RemoteInstanceKind get kind => RemoteInstanceKind.instance;
+
+ RemoteInstanceImpl({required int id, this.instance}) : super(id);
+}
+
// The kinds of instances.
enum RemoteInstanceKind {
classDeclaration,
@@ -83,4 +97,6 @@
typeAliasDeclaration,
typeParameterDeclaration,
variableDeclaration,
+ // A generic instance that is just a pointer to some server side instance.
+ instance,
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
index 1fafb40..c950279 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/executor_shared/serialization_extensions.dart
@@ -11,23 +11,29 @@
case SerializationMode.client:
moveNext();
RemoteInstanceKind kind = RemoteInstanceKind.values[expectNum()];
- moveNext();
switch (kind) {
case RemoteInstanceKind.namedTypeAnnotation:
+ moveNext();
return _expectNamedTypeAnnotation(id) as T;
case RemoteInstanceKind.functionTypeAnnotation:
+ moveNext();
return _expectFunctionTypeAnnotation(id) as T;
case RemoteInstanceKind.functionDeclaration:
+ moveNext();
return _expectFunctionDeclaration(id) as T;
case RemoteInstanceKind.parameterDeclaration:
+ moveNext();
return _expectParameterDeclaration(id) as T;
case RemoteInstanceKind.typeParameterDeclaration:
+ moveNext();
return _expectTypeParameterDeclaration(id) as T;
+ case RemoteInstanceKind.instance:
+ return new RemoteInstanceImpl(id: id) as T;
default:
throw new UnsupportedError('Unsupported remote object kind: $kind');
}
case SerializationMode.server:
- return RemoteInstance.cached(id);
+ return RemoteInstance.cached(id) as T;
}
}
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
index 24c7d80..f5a7287 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart
@@ -9,6 +9,7 @@
import 'isolate_mirrors_impl.dart';
import '../executor_shared/introspection_impls.dart';
import '../executor_shared/protocol.dart';
+import '../executor_shared/remote_instance.dart';
import '../executor.dart';
import '../api.dart';
@@ -106,8 +107,15 @@
TypeResolver typeResolver,
ClassIntrospector classIntrospector,
TypeDeclarationResolver typeDeclarationResolver) =>
- _sendRequest(new ExecuteDefinitionsPhaseRequest(macro, declaration,
- typeResolver, classIntrospector, typeDeclarationResolver,
+ _sendRequest(new ExecuteDefinitionsPhaseRequest(
+ macro,
+ declaration,
+ new RemoteInstanceImpl(
+ instance: typeResolver, id: RemoteInstance.uniqueId),
+ new RemoteInstanceImpl(
+ instance: classIntrospector, id: RemoteInstance.uniqueId),
+ new RemoteInstanceImpl(
+ instance: typeDeclarationResolver, id: RemoteInstance.uniqueId),
// Serialization zones are not necessary in this executor.
serializationZoneId: -1));
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
index fe7e32e..4673d17 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolate_mirrors_executor/isolate_mirrors_impl.dart
@@ -89,9 +89,9 @@
declaration is FunctionDeclarationImpl) {
FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
declaration,
- request.typeResolver,
- request.typeDeclarationResolver,
- request.classIntrospector);
+ request.typeResolver.instance as TypeResolver,
+ request.typeDeclarationResolver.instance as TypeDeclarationResolver,
+ request.classIntrospector.instance as ClassIntrospector);
await instance.buildDefinitionForFunction(declaration, builder);
return new Response(response: builder.result, requestId: request.id);
} else {
diff --git a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
index 4b564b6..b2b3b49 100644
--- a/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/macros/isolated_executor/isolated_executor.dart
@@ -5,6 +5,8 @@
import 'dart:async';
import 'dart:isolate';
+import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
+
import '../api.dart';
import '../executor_shared/introspection_impls.dart';
import '../executor_shared/protocol.dart';
@@ -103,7 +105,7 @@
class _SingleIsolatedMacroExecutor extends MacroExecutor {
/// The stream on which we receive responses.
- final Stream<Response> responseStream;
+ final Stream<Object> messageStream;
/// The send port where we should send requests.
final SendPort sendPort;
@@ -126,16 +128,85 @@
_SingleIsolatedMacroExecutor(
{required this.onClose,
- required this.responseStream,
+ required this.messageStream,
required this.sendPort}) {
- responseStream.listen((event) {
- Completer<Response>? completer =
- responseCompleters.remove(event.requestId);
- if (completer == null) {
- throw new StateError(
- 'Got a response for an unrecognized request id ${event.requestId}');
- }
- completer.complete(event);
+ messageStream.listen((message) {
+ withSerializationMode(SerializationMode.server, () {
+ JsonDeserializer deserializer =
+ new JsonDeserializer(message as List<Object?>);
+ // Every object starts with a zone ID which dictates the zone in which
+ // we should deserialize the message.
+ deserializer.moveNext();
+ int zoneId = deserializer.expectNum();
+ Zone zone = serializationZones[zoneId]!;
+ zone.run(() async {
+ deserializer.moveNext();
+ MessageType messageType =
+ MessageType.values[deserializer.expectNum()];
+ switch (messageType) {
+ case MessageType.response:
+ SerializableResponse response =
+ new SerializableResponse.deserialize(deserializer, zoneId);
+ Completer<Response>? completer =
+ responseCompleters.remove(response.requestId);
+ if (completer == null) {
+ throw new StateError(
+ 'Got a response for an unrecognized request id '
+ '${response.requestId}');
+ }
+ completer.complete(response);
+ break;
+ case MessageType.resolveTypeRequest:
+ ResolveTypeRequest request =
+ new ResolveTypeRequest.deserialize(deserializer, zoneId);
+ SerializableResponse response = new SerializableResponse(
+ response: new RemoteInstanceImpl(
+ id: RemoteInstance.uniqueId,
+ instance:
+ await (request.typeResolver.instance as TypeResolver)
+ .resolve(request.typeAnnotation)),
+ requestId: request.id,
+ responseType: MessageType.staticType,
+ serializationZoneId: zoneId);
+ JsonSerializer serializer = new JsonSerializer();
+ response.serialize(serializer);
+ sendPort.send(serializer.result);
+ break;
+ case MessageType.isExactlyTypeRequest:
+ IsExactlyTypeRequest request =
+ new IsExactlyTypeRequest.deserialize(deserializer, zoneId);
+ StaticType leftType = request.leftType.instance as StaticType;
+ StaticType rightType = request.leftType.instance as StaticType;
+ SerializableResponse response = new SerializableResponse(
+ response:
+ new BooleanValue(await leftType.isExactly(rightType)),
+ requestId: request.id,
+ responseType: MessageType.boolean,
+ serializationZoneId: zoneId);
+ JsonSerializer serializer = new JsonSerializer();
+ response.serialize(serializer);
+ sendPort.send(serializer.result);
+ break;
+ case MessageType.isSubtypeOfRequest:
+ IsExactlyTypeRequest request =
+ new IsExactlyTypeRequest.deserialize(deserializer, zoneId);
+ StaticType leftType = request.leftType.instance as StaticType;
+ StaticType rightType = request.leftType.instance as StaticType;
+ SerializableResponse response = new SerializableResponse(
+ response:
+ new BooleanValue(await leftType.isSubtypeOf(rightType)),
+ requestId: request.id,
+ responseType: MessageType.boolean,
+ serializationZoneId: zoneId);
+ JsonSerializer serializer = new JsonSerializer();
+ response.serialize(serializer);
+ sendPort.send(serializer.result);
+ break;
+ default:
+ throw new StateError('Unexpected message type $messageType');
+ }
+ });
+ });
});
}
@@ -145,31 +216,22 @@
Isolate isolate =
await Isolate.spawnUri(precompiledKernelUri, [], receivePort.sendPort);
Completer<SendPort> sendPortCompleter = new Completer();
- StreamController<Response> responseStreamController =
+ StreamController<Object> messageStreamController =
new StreamController(sync: true);
receivePort.listen((message) {
if (!sendPortCompleter.isCompleted) {
sendPortCompleter.complete(message as SendPort);
} else {
- JsonDeserializer deserializer =
- new JsonDeserializer(message as List<Object?>);
- // Ever object starts with a zone ID which dictates the zone in which we
- // should deserialize the message.
- deserializer.moveNext();
- int zoneId = deserializer.expectNum();
- Zone zone = serializationZones[zoneId]!;
- SerializableResponse response = zone.run(
- () => new SerializableResponse.deserialize(deserializer, zoneId));
- responseStreamController.add(response);
+ messageStreamController.add(message);
}
- }).onDone(responseStreamController.close);
+ }).onDone(messageStreamController.close);
return new _SingleIsolatedMacroExecutor(
onClose: () {
receivePort.close();
isolate.kill();
},
- responseStream: responseStreamController.stream,
+ messageStream: messageStreamController.stream,
sendPort: await sendPortCompleter.future);
}
@@ -199,8 +261,15 @@
TypeResolver typeResolver,
ClassIntrospector classIntrospector,
TypeDeclarationResolver typeDeclarationResolver) =>
- _sendRequest((zoneId) => new ExecuteDefinitionsPhaseRequest(macro,
- declaration, typeResolver, classIntrospector, typeDeclarationResolver,
+ _sendRequest((zoneId) => new ExecuteDefinitionsPhaseRequest(
+ macro,
+ declaration,
+ new RemoteInstanceImpl(
+ instance: typeResolver, id: RemoteInstance.uniqueId),
+ new RemoteInstanceImpl(
+ instance: classIntrospector, id: RemoteInstance.uniqueId),
+ new RemoteInstanceImpl(
+ instance: typeDeclarationResolver, id: RemoteInstance.uniqueId),
serializationZoneId: zoneId));
@override
@@ -225,14 +294,16 @@
{Uri? precompiledKernelUri}) =>
throw new StateError('Unreachable');
- /// Sends a [request] and handles the response, casting it to the expected
- /// type or throwing the error provided.
+ /// Creates a [Request] with a given serialization zone ID, and handles the
+ /// response, casting it to the expected type or throwing the error provided.
Future<T> _sendRequest<T>(Request Function(int) requestFactory) =>
withSerializationMode(SerializationMode.server, () async {
int zoneId = _nextSerializationZoneId++;
serializationZones[zoneId] = Zone.current;
Request request = requestFactory(zoneId);
JsonSerializer serializer = new JsonSerializer();
+ // It is our responsibility to add the zone ID header.
+ serializer.addNum(zoneId);
request.serialize(serializer);
sendPort.send(serializer.result);
Completer<Response> completer = new Completer<Response>();
@@ -241,7 +312,8 @@
Response response = await completer.future;
T? result = response.response as T?;
if (result != null) return result;
- throw response.error!;
+ throw new RemoteException(
+ response.error!.toString(), response.stackTrace);
} finally {
// Clean up the zone after the request is done.
serializationZones.remove(zoneId);
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart
index aae2ad0..c1f7c1d 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolate_mirror_executor/isolate_mirror_executor_test.dart
@@ -4,16 +4,16 @@
import 'dart:io';
-import 'package:_fe_analyzer_shared/src/macros/api.dart';
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/remote_instance.dart';
import 'package:_fe_analyzer_shared/src/macros/isolate_mirrors_executor/isolate_mirrors_executor.dart'
as mirrorExecutor;
-import 'package:test/fake.dart';
import 'package:test/test.dart';
+import '../util.dart';
+
void main() {
late MacroExecutor executor;
late File simpleMacroFile;
@@ -55,6 +55,11 @@
expect(instanceId, isNotNull,
reason: 'Can create an instance with named arguments.');
+ var returnType = NamedTypeAnnotationImpl(
+ id: RemoteInstance.uniqueId,
+ name: 'String',
+ isNullable: false,
+ typeArguments: const []);
var definitionResult = await executor.executeDefinitionsPhase(
instanceId,
FunctionDeclarationImpl(
@@ -66,16 +71,13 @@
name: 'foo',
namedParameters: [],
positionalParameters: [],
- returnType: NamedTypeAnnotationImpl(
- id: RemoteInstance.uniqueId,
- name: 'String',
- isNullable: false,
- typeArguments: const []),
+ returnType: returnType,
typeParameters: [],
),
- _FakeTypeResolver(),
- _FakeClassIntrospector(),
- _FakeTypeDeclarationResolver());
+ TestTypeResolver(
+ {returnType: TestStaticType('dart:core', 'String', [])}),
+ FakeClassIntrospector(),
+ FakeTypeDeclarationResolver());
expect(definitionResult.augmentations, hasLength(1));
expect(definitionResult.augmentations.first.debugString().toString(),
equalsIgnoringWhitespace('''
@@ -85,27 +87,3 @@
}'''));
});
}
-
-class _FakeClassIntrospector with Fake implements ClassIntrospector {}
-
-class _FakeTypeResolver with Fake implements TypeResolver {}
-
-class _FakeTypeDeclarationResolver
- with Fake
- implements TypeDeclarationResolver {}
-
-extension _ on Code {
- StringBuffer debugString([StringBuffer? buffer]) {
- buffer ??= StringBuffer();
- for (var part in parts) {
- if (part is Code) {
- part.debugString(buffer);
- } else if (part is TypeAnnotation) {
- part.code.debugString(buffer);
- } else {
- buffer.write(part.toString());
- }
- }
- return buffer;
- }
-}
diff --git a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
index c4cac8b..1bdb14f 100644
--- a/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/isolated_executor/isolated_executor_test.dart
@@ -5,7 +5,6 @@
import 'dart:io';
import 'dart:isolate';
-import 'package:_fe_analyzer_shared/src/macros/api.dart';
import 'package:_fe_analyzer_shared/src/macros/bootstrap.dart';
import 'package:_fe_analyzer_shared/src/macros/executor.dart';
import 'package:_fe_analyzer_shared/src/macros/executor_shared/introspection_impls.dart';
@@ -13,9 +12,10 @@
import 'package:_fe_analyzer_shared/src/macros/isolated_executor/isolated_executor.dart'
as isolatedExecutor;
-import 'package:test/fake.dart';
import 'package:test/test.dart';
+import '../util.dart';
+
void main() {
late MacroExecutor executor;
late Directory tmpDir;
@@ -40,7 +40,7 @@
executor.close();
});
- test('can load macros and create instances', () async {
+ test('can load and run macros', () async {
var macroUri = simpleMacroFile.absolute.uri;
var macroName = 'SimpleMacro';
@@ -78,6 +78,11 @@
expect(instanceId, isNotNull,
reason: 'Can create an instance with named arguments.');
+ var returnType = NamedTypeAnnotationImpl(
+ id: RemoteInstance.uniqueId,
+ name: 'String',
+ isNullable: false,
+ typeArguments: const []);
var definitionResult = await executor.executeDefinitionsPhase(
instanceId,
FunctionDeclarationImpl(
@@ -89,16 +94,13 @@
name: 'foo',
namedParameters: [],
positionalParameters: [],
- returnType: NamedTypeAnnotationImpl(
- id: RemoteInstance.uniqueId,
- name: 'String',
- isNullable: false,
- typeArguments: const []),
+ returnType: returnType,
typeParameters: [],
),
- _FakeTypeResolver(),
- _FakeClassIntrospector(),
- _FakeTypeDeclarationResolver());
+ TestTypeResolver(
+ {returnType: TestStaticType('dart:core', 'String', [])}),
+ FakeClassIntrospector(),
+ FakeTypeDeclarationResolver());
expect(definitionResult.augmentations, hasLength(1));
expect(definitionResult.augmentations.first.debugString().toString(),
equalsIgnoringWhitespace('''
@@ -108,27 +110,3 @@
}'''));
});
}
-
-class _FakeClassIntrospector with Fake implements ClassIntrospector {}
-
-class _FakeTypeResolver with Fake implements TypeResolver {}
-
-class _FakeTypeDeclarationResolver
- with Fake
- implements TypeDeclarationResolver {}
-
-extension _ on Code {
- StringBuffer debugString([StringBuffer? buffer]) {
- buffer ??= StringBuffer();
- for (var part in parts) {
- if (part is Code) {
- part.debugString(buffer);
- } else if (part is TypeAnnotation) {
- part.code.debugString(buffer);
- } else {
- buffer.write(part.toString());
- }
- }
- return buffer;
- }
-}
diff --git a/pkg/_fe_analyzer_shared/test/macros/simple_macro.dart b/pkg/_fe_analyzer_shared/test/macros/simple_macro.dart
index b95da0b..ff31b12 100644
--- a/pkg/_fe_analyzer_shared/test/macros/simple_macro.dart
+++ b/pkg/_fe_analyzer_shared/test/macros/simple_macro.dart
@@ -18,13 +18,23 @@
@override
FutureOr<void> buildDefinitionForFunction(
- FunctionDeclaration method, FunctionDefinitionBuilder builder) {
+ FunctionDeclaration method, FunctionDefinitionBuilder builder) async {
if (method.namedParameters
.followedBy(method.positionalParameters)
.isNotEmpty) {
throw ArgumentError(
'This macro can only be run on functions with no arguments!');
}
+
+ // Test the type resolver and static type interfaces
+ var staticReturnType = await builder.resolve(method.returnType);
+ if (!(await staticReturnType.isExactly(staticReturnType))) {
+ throw StateError('The return type should be exactly equal to itself!');
+ }
+ if (!(await staticReturnType.isSubtypeOf(staticReturnType))) {
+ throw StateError('The return type should be a subtype of itself!');
+ }
+
builder.augment(FunctionBodyCode.fromString('''{
print('x: $x, y: $y');
return augment super();
diff --git a/pkg/_fe_analyzer_shared/test/macros/util.dart b/pkg/_fe_analyzer_shared/test/macros/util.dart
new file mode 100644
index 0000000..179f50b
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/macros/util.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2022, 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 'package:_fe_analyzer_shared/src/macros/api.dart';
+
+import 'package:test/fake.dart';
+
+class FakeClassIntrospector with Fake implements ClassIntrospector {}
+
+class FakeTypeDeclarationResolver with Fake implements TypeDeclarationResolver {
+}
+
+class TestTypeResolver implements TypeResolver {
+ final Map<TypeAnnotation, StaticType> staticTypes;
+
+ TestTypeResolver(this.staticTypes);
+
+ @override
+ Future<StaticType> resolve(covariant TypeAnnotation typeAnnotation) async {
+ return staticTypes[typeAnnotation]!;
+ }
+}
+
+// Doesn't handle generics etc but thats ok for now
+class TestStaticType implements StaticType {
+ final String library;
+ final String name;
+ final List<TestStaticType> superTypes;
+
+ TestStaticType(this.library, this.name, this.superTypes);
+
+ @override
+ Future<bool> isExactly(TestStaticType other) async => _isExactly(other);
+
+ @override
+ Future<bool> isSubtypeOf(TestStaticType other) async =>
+ _isExactly(other) ||
+ superTypes.any((superType) => superType._isExactly(other));
+
+ bool _isExactly(TestStaticType other) =>
+ identical(other, this) ||
+ (library == other.library && name == other.name);
+}
+
+extension DebugCodeString on Code {
+ StringBuffer debugString([StringBuffer? buffer]) {
+ buffer ??= StringBuffer();
+ for (var part in parts) {
+ if (part is Code) {
+ part.debugString(buffer);
+ } else if (part is TypeAnnotation) {
+ part.code.debugString(buffer);
+ } else {
+ buffer.write(part.toString());
+ }
+ }
+ return buffer;
+ }
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index f5454a5..05653ef 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -7,7 +7,6 @@
import 'package:kernel/ast.dart'
show
Class,
- Constructor,
DartType,
DynamicType,
FutureOrType,
@@ -32,11 +31,8 @@
import 'library_builder.dart';
import 'member_builder.dart';
import 'metadata_builder.dart';
-import 'named_type_builder.dart';
import 'nullability_builder.dart';
-import 'type_alias_builder.dart';
import 'type_builder.dart';
-import 'type_declaration_builder.dart';
import 'type_variable_builder.dart';
abstract class ClassBuilder implements DeclarationBuilder {
@@ -59,8 +55,6 @@
ConstructorScopeBuilder get constructorScopeBuilder;
- abstract ClassBuilder? actualOrigin;
-
@override
Uri get fileUri;
@@ -78,10 +72,6 @@
abstract TypeBuilder? mixedInTypeBuilder;
- /// Registers a constructor redirection for this class and returns true if
- /// this redirection gives rise to a cycle that has not been reported before.
- bool checkConstructorCyclic(String source, String target);
-
MemberBuilder? findConstructorOrFactory(
String name, int charOffset, Uri uri, LibraryBuilder accessingLibrary);
@@ -95,8 +85,6 @@
@override
ClassBuilder get origin;
- Class get actualCls;
-
abstract bool isNullClass;
@override
@@ -135,12 +123,6 @@
Member? lookupInstanceMember(ClassHierarchy hierarchy, Name name,
{bool isSetter: false, bool isSuper: false});
- /// Looks up the constructor by [name] on the class built by this class
- /// builder.
- ///
- /// If [isSuper] is `true`, constructors in the superclass are searched.
- Constructor? lookupConstructor(Name name, {bool isSuper: false});
-
/// Calls [f] for each constructor declared in this class.
///
/// If [includeInjectedConstructors] is `true`, constructors only declared in
@@ -169,11 +151,6 @@
@override
final ConstructorScopeBuilder constructorScopeBuilder;
- Map<String, ConstructorRedirection>? _redirectingConstructors;
-
- @override
- ClassBuilder? actualOrigin;
-
@override
bool isNullClass = false;
@@ -224,35 +201,6 @@
(modifiers & declaresConstConstructorMask) != 0;
@override
- void forEachConstructor(void Function(String, MemberBuilder) f,
- {bool includeInjectedConstructors: false}) {
- if (isPatch) {
- actualOrigin!.forEachConstructor(f,
- includeInjectedConstructors: includeInjectedConstructors);
- } else {
- constructors.forEach(f);
- }
- }
-
- /// Registers a constructor redirection for this class and returns true if
- /// this redirection gives rise to a cycle that has not been reported before.
- @override
- bool checkConstructorCyclic(String source, String target) {
- ConstructorRedirection? redirect = new ConstructorRedirection(target);
- _redirectingConstructors ??= <String, ConstructorRedirection>{};
- _redirectingConstructors![source] = redirect;
- while (redirect != null) {
- if (redirect.cycleReported) return false;
- if (redirect.target == source) {
- redirect.cycleReported = true;
- return true;
- }
- redirect = _redirectingConstructors![redirect.target];
- }
- return false;
- }
-
- @override
Builder? findStaticBuilder(
String name, int charOffset, Uri fileUri, LibraryBuilder accessingLibrary,
{bool isSetter: false}) {
@@ -329,9 +277,6 @@
}
@override
- ClassBuilder get origin => actualOrigin ?? this;
-
- @override
InterfaceType get thisType {
return _thisType ??= new InterfaceType(cls, library.nonNullable,
getAsTypeArguments(cls.typeParameters, library.library));
@@ -477,63 +422,6 @@
}
return target;
}
-
- @override
- Constructor? lookupConstructor(Name name, {bool isSuper: false}) {
- if (name.text == "new") {
- name = new Name("", name.library);
- }
-
- Class? instanceClass = cls;
- if (isSuper) {
- instanceClass = instanceClass.superclass;
- }
- if (instanceClass != null) {
- for (Constructor constructor in instanceClass.constructors) {
- if (constructor.name == name) {
- return constructor;
- }
- }
- }
-
- /// Performs a similar lookup to [lookupConstructor], but using a slower
- /// implementation.
- Constructor? lookupConstructorWithPatches(Name name, bool isSuper) {
- ClassBuilder? builder = this.origin;
-
- ClassBuilder? getSuperclass(ClassBuilder builder) {
- // This way of computing the superclass is slower than using the kernel
- // objects directly.
- TypeBuilder? supertype = builder.supertypeBuilder;
- if (supertype is NamedTypeBuilder) {
- TypeDeclarationBuilder? builder = supertype.declaration;
- if (builder is ClassBuilder) return builder;
- if (builder is TypeAliasBuilder) {
- TypeDeclarationBuilder? declarationBuilder =
- builder.unaliasDeclaration(supertype.arguments,
- isUsedAsClass: true,
- usedAsClassCharOffset: supertype.charOffset,
- usedAsClassFileUri: supertype.fileUri);
- if (declarationBuilder is ClassBuilder) return declarationBuilder;
- }
- }
- return null;
- }
-
- if (isSuper) {
- builder = getSuperclass(builder)?.origin;
- }
- if (builder != null) {
- Class cls = builder.cls;
- for (Constructor constructor in cls.constructors) {
- if (constructor.name == name) return constructor;
- }
- }
- return null;
- }
-
- return lookupConstructorWithPatches(name, isSuper);
- }
}
class ConstructorRedirection {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
index 9ccfd18..18b8478 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_class_builder.dart
@@ -47,6 +47,9 @@
cls.fileOffset);
@override
+ DillClassBuilder get origin => this;
+
+ @override
DillLibraryBuilder get library => super.library as DillLibraryBuilder;
@override
@@ -77,9 +80,6 @@
return supertype;
}
- @override
- Class get actualCls => cls;
-
void addField(Field field) {
DillFieldBuilder builder = new DillFieldBuilder(field, this);
String name = field.name.text;
@@ -171,6 +171,12 @@
return super.interfaceBuilders;
}
+ @override
+ void forEachConstructor(void Function(String, MemberBuilder) f,
+ {bool includeInjectedConstructors: false}) {
+ constructors.forEach(f);
+ }
+
void clearCachedValues() {
supertypeBuilder = null;
interfaceBuilders = null;
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 197632f..fe74b48 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -85,6 +85,7 @@
import '../scope.dart';
import '../source/diet_parser.dart';
import '../source/scope_listener.dart' show JumpTargetKind, ScopeListener;
+import '../source/source_class_builder.dart';
import '../source/source_constructor_builder.dart';
import '../source/source_enum_builder.dart';
import '../source/source_factory_builder.dart';
@@ -139,8 +140,13 @@
/// if any.
final DeclarationBuilder? declarationBuilder;
- /// The class or mixin declaration in which [member] is declared, if any.
- final ClassBuilder? classBuilder;
+ /// The source class or mixin declaration in which [member] is declared, if
+ /// any.
+ ///
+ /// If [member] is a synthesized member for expression evaluation the
+ /// enclosing declaration might be a [DillClassBuilder]. This can be accessed
+ /// through [declarationBuilder].
+ final SourceClassBuilder? sourceClassBuilder;
final ClassHierarchy hierarchy;
@@ -342,8 +348,9 @@
required this.uri,
required this.typeInferrer})
: forest = const Forest(),
- classBuilder =
- declarationBuilder is ClassBuilder ? declarationBuilder : null,
+ sourceClassBuilder = declarationBuilder is SourceClassBuilder
+ ? declarationBuilder
+ : null,
enableNative = libraryBuilder.loader.target.backendTarget
.enableNative(libraryBuilder.importUri),
stringExpectedAfterNative = libraryBuilder
@@ -352,8 +359,9 @@
libraryBuilder.importUri.scheme == 'dart' &&
(libraryBuilder.importUri.path == "_builtin" ||
libraryBuilder.importUri.path == "ui"),
- needsImplicitSuperInitializer = declarationBuilder is ClassBuilder &&
- coreTypes.objectClass != declarationBuilder.cls,
+ needsImplicitSuperInitializer =
+ declarationBuilder is SourceClassBuilder &&
+ coreTypes.objectClass != declarationBuilder.cls,
super(enclosingScope) {
formalParameterScope?.forEach((String name, Builder builder) {
if (builder is VariableBuilder) {
@@ -1763,7 +1771,7 @@
fasta.messageConstructorNotSync, body!.fileOffset, noLength)));
}
if (libraryBuilder.enableEnhancedEnumsInLibrary &&
- classBuilder is SourceEnumBuilder &&
+ sourceClassBuilder is SourceEnumBuilder &&
constructor.initializers.isNotEmpty &&
constructor.initializers.last is RedirectingInitializer) {
RedirectingInitializer redirectingInitializer =
@@ -1806,7 +1814,7 @@
positionalArguments = positionalSuperParametersAsArguments;
namedArguments = namedSuperParametersAsArguments;
}
- if (classBuilder is SourceEnumBuilder) {
+ if (sourceClassBuilder is SourceEnumBuilder) {
assert(constructor.function.positionalParameters.length >= 2 &&
constructor.function.positionalParameters[0].name == "index" &&
constructor.function.positionalParameters[1].name == "name");
@@ -1826,7 +1834,8 @@
checkArgumentsForFunction(superTarget.function, arguments,
builder.charOffset, const <TypeParameter>[]) !=
null) {
- String superclass = classBuilder!.supertypeBuilder!.fullNameForErrors;
+ String superclass =
+ sourceClassBuilder!.supertypeBuilder!.fullNameForErrors;
int length = constructor.name.text.length;
if (length == 0) {
length = (constructor.parent as Class).name.length;
@@ -2563,15 +2572,15 @@
}
@override
- Member? lookupInstanceMember(Name name,
- {bool isSetter: false, bool isSuper: false}) {
- return classBuilder!.lookupInstanceMember(hierarchy, name,
- isSetter: isSetter, isSuper: isSuper);
+ Member? lookupSuperMember(Name name, {bool isSetter: false}) {
+ return (declarationBuilder as ClassBuilder).lookupInstanceMember(
+ hierarchy, name,
+ isSetter: isSetter, isSuper: true);
}
@override
Constructor? lookupConstructor(Name name, {bool isSuper: false}) {
- return classBuilder!.lookupConstructor(name, isSuper: isSuper);
+ return sourceClassBuilder!.lookupConstructor(name, isSuper: isSuper);
}
@override
@@ -2650,9 +2659,9 @@
Builder? declaration = scope.lookup(name, charOffset, uri);
if (declaration == null &&
prefix == null &&
- (classBuilder?.isPatch ?? false)) {
+ (sourceClassBuilder?.isPatch ?? false)) {
// The scope of a patched method includes the origin class.
- declaration = classBuilder!.origin
+ declaration = sourceClassBuilder!.origin
.findStaticBuilder(name, charOffset, uri, libraryBuilder);
}
if (declaration != null &&
@@ -3120,8 +3129,8 @@
constantContext = member.isConst
? ConstantContext.inferred
: !member.isStatic &&
- classBuilder != null &&
- classBuilder!.declaresConstConstructor
+ sourceClassBuilder != null &&
+ sourceClassBuilder!.declaresConstConstructor
? ConstantContext.required
: ConstantContext.none;
if (member is SourceFieldBuilder) {
@@ -3155,8 +3164,8 @@
constantContext = member.isConst
? ConstantContext.inferred
: !member.isStatic &&
- classBuilder != null &&
- classBuilder!.declaresConstConstructor
+ sourceClassBuilder != null &&
+ sourceClassBuilder!.declaresConstConstructor
? ConstantContext.required
: ConstantContext.none;
if (constantContext == ConstantContext.inferred) {
@@ -6968,7 +6977,7 @@
Initializer buildRedirectingInitializer(
Constructor constructor, Arguments arguments,
[int charOffset = -1]) {
- if (classBuilder!
+ if (sourceClassBuilder!
.checkConstructorCyclic(member.name!, constructor.name.text)) {
int length = constructor.name.text.length;
if (length == 0) length = "this".length;
@@ -7188,7 +7197,7 @@
offset,
name.text.length);
}
- Member? target = lookupInstanceMember(name, isSuper: true);
+ Member? target = lookupSuperMember(name);
if (target == null || (target is Procedure && !target.isAccessor)) {
if (target == null) {
@@ -7317,7 +7326,7 @@
String constructorNameForDiagnostics(String name,
{String? className, bool isSuper: false}) {
if (className == null) {
- Class cls = classBuilder!.cls;
+ Class cls = sourceClassBuilder!.cls;
if (isSuper) {
cls = cls.superclass!;
while (cls.isMixinApplication) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
index f792c94..ec5e04c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator.dart
@@ -4492,9 +4492,8 @@
}
} else {
if (isSuper) {
- Member? getter = _helper.lookupInstanceMember(name, isSuper: isSuper);
- Member? setter = _helper.lookupInstanceMember(name,
- isSuper: isSuper, isSetter: true);
+ Member? getter = _helper.lookupSuperMember(name);
+ Member? setter = _helper.lookupSuperMember(name, isSetter: true);
return new SuperPropertyAccessGenerator(
_helper,
// TODO(ahe): This is not the 'super' token.
@@ -4659,10 +4658,8 @@
_helper,
token,
index,
- _helper.lookupInstanceMember(indexGetName, isSuper: true)
- as Procedure?,
- _helper.lookupInstanceMember(indexSetName, isSuper: true)
- as Procedure?);
+ _helper.lookupSuperMember(indexGetName) as Procedure?,
+ _helper.lookupSuperMember(indexSetName) as Procedure?);
} else {
return new ThisIndexedAccessGenerator(_helper, token, index,
thisOffset: fileOffset, isNullAware: isNullAware);
diff --git a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
index 42258ae..4805dac 100644
--- a/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/expression_generator_helper.dart
@@ -55,7 +55,7 @@
Expression toValue(Object? node);
- Member? lookupInstanceMember(Name name, {bool isSetter, bool isSuper});
+ Member? lookupSuperMember(Name name, {bool isSetter});
bool get enableExtensionTypesInLibrary;
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 c95900c..e47921b 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
@@ -88,7 +88,6 @@
class SourceClassBuilder extends ClassBuilderImpl
implements Comparable<SourceClassBuilder> {
- @override
final Class actualCls;
final List<ConstructorReferenceBuilder>? constructorReferences;
@@ -137,6 +136,11 @@
SourceClassBuilder? get patchForTesting => _patchBuilder;
+ SourceClassBuilder? actualOrigin;
+
+ @override
+ SourceClassBuilder get origin => actualOrigin ?? this;
+
@override
Class get cls => origin.actualCls;
@@ -419,6 +423,66 @@
constructors.forEach(callbackFilteringFieldBuilders);
}
+ /// Looks up the constructor by [name] on the class built by this class
+ /// builder.
+ ///
+ /// If [isSuper] is `true`, constructors in the superclass are searched.
+ Constructor? lookupConstructor(Name name, {bool isSuper: false}) {
+ if (name.text == "new") {
+ name = new Name("", name.library);
+ }
+
+ Class? instanceClass = cls;
+ if (isSuper) {
+ instanceClass = instanceClass.superclass;
+ }
+ if (instanceClass != null) {
+ for (Constructor constructor in instanceClass.constructors) {
+ if (constructor.name == name) {
+ return constructor;
+ }
+ }
+ }
+
+ /// Performs a similar lookup to [lookupConstructor], but using a slower
+ /// implementation.
+ Constructor? lookupConstructorWithPatches(Name name, bool isSuper) {
+ ClassBuilder? builder = this.origin;
+
+ ClassBuilder? getSuperclass(ClassBuilder builder) {
+ // This way of computing the superclass is slower than using the kernel
+ // objects directly.
+ TypeBuilder? supertype = builder.supertypeBuilder;
+ if (supertype is NamedTypeBuilder) {
+ TypeDeclarationBuilder? builder = supertype.declaration;
+ if (builder is ClassBuilder) return builder;
+ if (builder is TypeAliasBuilder) {
+ TypeDeclarationBuilder? declarationBuilder =
+ builder.unaliasDeclaration(supertype.arguments,
+ isUsedAsClass: true,
+ usedAsClassCharOffset: supertype.charOffset,
+ usedAsClassFileUri: supertype.fileUri);
+ if (declarationBuilder is ClassBuilder) return declarationBuilder;
+ }
+ }
+ return null;
+ }
+
+ if (isSuper) {
+ builder = getSuperclass(builder)?.origin;
+ }
+ if (builder != null) {
+ Class cls = builder.cls;
+ for (Constructor constructor in cls.constructors) {
+ if (constructor.name == name) return constructor;
+ }
+ }
+ return null;
+ }
+
+ return lookupConstructorWithPatches(name, isSuper);
+ }
+
@override
int get typeVariablesCount => typeVariables?.length ?? 0;
@@ -907,6 +971,25 @@
}
}
+ Map<String, ConstructorRedirection>? _redirectingConstructors;
+
+ /// Registers a constructor redirection for this class and returns true if
+ /// this redirection gives rise to a cycle that has not been reported before.
+ bool checkConstructorCyclic(String source, String target) {
+ ConstructorRedirection? redirect = new ConstructorRedirection(target);
+ _redirectingConstructors ??= <String, ConstructorRedirection>{};
+ _redirectingConstructors![source] = redirect;
+ while (redirect != null) {
+ if (redirect.cycleReported) return false;
+ if (redirect.target == source) {
+ redirect.cycleReported = true;
+ return true;
+ }
+ redirect = _redirectingConstructors![redirect.target];
+ }
+ return false;
+ }
+
TypeBuilder _checkSupertype(TypeBuilder supertype) {
if (typeVariables == null) return supertype;
Message? message;
diff --git a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
index c9f1615..d79e266 100644
--- a/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
@@ -19,7 +19,6 @@
InstanceAccessKind,
InstanceGet,
IntLiteral,
- InterfaceType,
ListLiteral,
Name,
ProcedureKind,
@@ -450,12 +449,6 @@
TypeBuilder? get mixedInTypeBuilder => null;
@override
- InterfaceType buildType(LibraryBuilder library,
- NullabilityBuilder nullabilityBuilder, List<TypeBuilder>? arguments) {
- return rawType(nullabilityBuilder.build(library));
- }
-
- @override
Class build(SourceLibraryBuilder libraryBuilder, LibraryBuilder coreLibrary) {
cls.isEnum = true;
intType.resolveIn(coreLibrary.scope, charOffset, fileUri, libraryBuilder);
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index e105550..ca03543 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -1110,6 +1110,7 @@
reloading
remapped
remedy
+remotely
removal
remover
renames
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 3c9845d..dba09e0 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -325,6 +325,7 @@
ec
echo
edits
+ei
einst
elapse
elegantly
diff --git a/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart
new file mode 100644
index 0000000..971776f
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2022, 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.
+
+enum E<X> {
+ one(1),
+ two("2");
+
+ final X field;
+
+ const E(this.field);
+}
+
+test() {
+ foo(E.one, E.two); // Ok.
+}
+
+foo(E<int> ei, E<String> es) {
+ bar(ei, es); // Ok.
+ bar(E.one, E.two); // Ok.
+ bar(es, ei); // Error.
+ bar(E.two, E.one); // Error.
+}
+
+bar(E<int> ei, E<String> es) {
+ baz(ei, es); // Ok.
+}
+
+baz(E<Object> ei, E<Object> es) {
+ boz(ei, es); // Error.
+ boz(E.one, E.two); // Error.
+}
+
+boz(E<Never> ei, E<Never> es) {}
+
+checkIsType<T>(x) {
+ if (x is! T) {
+ throw "Expected value of type ${x.runtimeType} to also be of type ${T}.";
+ }
+}
+
+checkIsNotType<T>(x) {
+ if (x is T) {
+ throw "Expected value of type ${x.runtimeType} to not be of type ${T}.";
+ }
+}
+
+main() {
+ checkIsType<E<dynamic>>(E.one);
+ checkIsType<E<dynamic>>(E.two);
+ checkIsType<E<int>>(E.one);
+ checkIsType<E<String>>(E.two);
+
+ checkIsNotType<E<Never>>(E.one);
+ checkIsNotType<E<Never>>(E.two);
+ checkIsNotType<E<String>>(E.one);
+ checkIsNotType<E<int>>(E.two);
+}
diff --git a/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.strong.expect
new file mode 100644
index 0000000..7e8bae6
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.strong.expect
@@ -0,0 +1,141 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E<X extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E<dynamic>> values = #C8;
+ static const field self::E<core::int> one = #C4;
+ static const field self::E<core::String> two = #C7;
+ final field self::E::X% field;
+ const constructor •(core::int index, core::String name, self::E::X% field) → self::E<self::E::X%>
+ : self::E::field = field, super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ self::foo(#C4, #C7);
+}
+static method foo(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::bar(ei, es);
+ self::bar(#C4, #C7);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+}
+static method bar(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::baz(ei, es);
+}
+static method baz(self::E<core::Object> ei, self::E<core::Object> es) → dynamic {
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<Never>);
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<Never>);
+}
+static method boz(self::E<Never> ei, self::E<Never> es) → dynamic {}
+static method checkIsType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(!(x is{ForNonNullableByDefault} self::checkIsType::T%)) {
+ throw "Expected value of type ${x.{core::Object::runtimeType}{core::Type}} to also be of type ${self::checkIsType::T%}.";
+ }
+}
+static method checkIsNotType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(x is{ForNonNullableByDefault} self::checkIsNotType::T%) {
+ throw "Expected value of type ${x{self::checkIsNotType::T%}.{core::Object::runtimeType}{core::Type}} to not be of type ${self::checkIsNotType::T%}.";
+ }
+}
+static method main() → dynamic {
+ self::checkIsType<self::E<dynamic>>(#C4);
+ self::checkIsType<self::E<dynamic>>(#C7);
+ self::checkIsType<self::E<core::int>>(#C4);
+ self::checkIsType<self::E<core::String>>(#C7);
+ self::checkIsNotType<self::E<Never>>(#C4);
+ self::checkIsNotType<self::E<Never>>(#C7);
+ self::checkIsNotType<self::E<core::String>>(#C4);
+ self::checkIsNotType<self::E<core::int>>(#C7);
+}
+
+constants {
+ #C1 = 1
+ #C2 = 0
+ #C3 = "one"
+ #C4 = self::E<core::int> {field:#C1, index:#C2, _name:#C3}
+ #C5 = "2"
+ #C6 = "two"
+ #C7 = self::E<core::String> {field:#C5, index:#C1, _name:#C6}
+ #C8 = <self::E<dynamic>>[#C4, #C7]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///instantiated_generic_enum_types.dart:
+- E. (from org-dartlang-testcase:///instantiated_generic_enum_types.dart:11:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.strong.transformed.expect
new file mode 100644
index 0000000..7e8bae6
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.strong.transformed.expect
@@ -0,0 +1,141 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E<X extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E<dynamic>> values = #C8;
+ static const field self::E<core::int> one = #C4;
+ static const field self::E<core::String> two = #C7;
+ final field self::E::X% field;
+ const constructor •(core::int index, core::String name, self::E::X% field) → self::E<self::E::X%>
+ : self::E::field = field, super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ self::foo(#C4, #C7);
+}
+static method foo(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::bar(ei, es);
+ self::bar(#C4, #C7);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+}
+static method bar(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::baz(ei, es);
+}
+static method baz(self::E<core::Object> ei, self::E<core::Object> es) → dynamic {
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<Never>);
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<Never>);
+}
+static method boz(self::E<Never> ei, self::E<Never> es) → dynamic {}
+static method checkIsType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(!(x is{ForNonNullableByDefault} self::checkIsType::T%)) {
+ throw "Expected value of type ${x.{core::Object::runtimeType}{core::Type}} to also be of type ${self::checkIsType::T%}.";
+ }
+}
+static method checkIsNotType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(x is{ForNonNullableByDefault} self::checkIsNotType::T%) {
+ throw "Expected value of type ${x{self::checkIsNotType::T%}.{core::Object::runtimeType}{core::Type}} to not be of type ${self::checkIsNotType::T%}.";
+ }
+}
+static method main() → dynamic {
+ self::checkIsType<self::E<dynamic>>(#C4);
+ self::checkIsType<self::E<dynamic>>(#C7);
+ self::checkIsType<self::E<core::int>>(#C4);
+ self::checkIsType<self::E<core::String>>(#C7);
+ self::checkIsNotType<self::E<Never>>(#C4);
+ self::checkIsNotType<self::E<Never>>(#C7);
+ self::checkIsNotType<self::E<core::String>>(#C4);
+ self::checkIsNotType<self::E<core::int>>(#C7);
+}
+
+constants {
+ #C1 = 1
+ #C2 = 0
+ #C3 = "one"
+ #C4 = self::E<core::int> {field:#C1, index:#C2, _name:#C3}
+ #C5 = "2"
+ #C6 = "two"
+ #C7 = self::E<core::String> {field:#C5, index:#C1, _name:#C6}
+ #C8 = <self::E<dynamic>>[#C4, #C7]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///instantiated_generic_enum_types.dart:
+- E. (from org-dartlang-testcase:///instantiated_generic_enum_types.dart:11:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.textual_outline.expect b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.textual_outline.expect
new file mode 100644
index 0000000..8ce4f0c
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.textual_outline.expect
@@ -0,0 +1,9 @@
+enum E<X> { one(1), two("2"); final X field; const E(this.field); }
+test() {}
+foo(E<int> ei, E<String> es) {}
+bar(E<int> ei, E<String> es) {}
+baz(E<Object> ei, E<Object> es) {}
+boz(E<Never> ei, E<Never> es) {}
+checkIsType<T>(x) {}
+checkIsNotType<T>(x) {}
+main() {}
diff --git a/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.expect
new file mode 100644
index 0000000..fb83333
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.expect
@@ -0,0 +1,141 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E<X extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E<dynamic>> values = #C8;
+ static const field self::E<core::int> one = #C4;
+ static const field self::E<core::String> two = #C7;
+ final field self::E::X% field;
+ const constructor •(core::int index, core::String name, self::E::X% field) → self::E<self::E::X%>
+ : self::E::field = field, super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ self::foo(#C4, #C7);
+}
+static method foo(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::bar(ei, es);
+ self::bar(#C4, #C7);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+}
+static method bar(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::baz(ei, es);
+}
+static method baz(self::E<core::Object> ei, self::E<core::Object> es) → dynamic {
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<Never>);
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<Never>);
+}
+static method boz(self::E<Never> ei, self::E<Never> es) → dynamic {}
+static method checkIsType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(!(x is{ForNonNullableByDefault} self::checkIsType::T%)) {
+ throw "Expected value of type ${x.{core::Object::runtimeType}{core::Type}} to also be of type ${self::checkIsType::T%}.";
+ }
+}
+static method checkIsNotType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(x is{ForNonNullableByDefault} self::checkIsNotType::T%) {
+ throw "Expected value of type ${x{self::checkIsNotType::T%}.{core::Object::runtimeType}{core::Type}} to not be of type ${self::checkIsNotType::T%}.";
+ }
+}
+static method main() → dynamic {
+ self::checkIsType<self::E<dynamic>>(#C4);
+ self::checkIsType<self::E<dynamic>>(#C7);
+ self::checkIsType<self::E<core::int>>(#C4);
+ self::checkIsType<self::E<core::String>>(#C7);
+ self::checkIsNotType<self::E<Never>>(#C4);
+ self::checkIsNotType<self::E<Never>>(#C7);
+ self::checkIsNotType<self::E<core::String>>(#C4);
+ self::checkIsNotType<self::E<core::int>>(#C7);
+}
+
+constants {
+ #C1 = 1
+ #C2 = 0
+ #C3 = "one"
+ #C4 = self::E<core::int*> {field:#C1, index:#C2, _name:#C3}
+ #C5 = "2"
+ #C6 = "two"
+ #C7 = self::E<core::String*> {field:#C5, index:#C1, _name:#C6}
+ #C8 = <self::E<dynamic>*>[#C4, #C7]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///instantiated_generic_enum_types.dart:
+- E. (from org-dartlang-testcase:///instantiated_generic_enum_types.dart:11:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.modular.expect
new file mode 100644
index 0000000..fb83333
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.modular.expect
@@ -0,0 +1,141 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E<X extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E<dynamic>> values = #C8;
+ static const field self::E<core::int> one = #C4;
+ static const field self::E<core::String> two = #C7;
+ final field self::E::X% field;
+ const constructor •(core::int index, core::String name, self::E::X% field) → self::E<self::E::X%>
+ : self::E::field = field, super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ self::foo(#C4, #C7);
+}
+static method foo(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::bar(ei, es);
+ self::bar(#C4, #C7);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+}
+static method bar(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::baz(ei, es);
+}
+static method baz(self::E<core::Object> ei, self::E<core::Object> es) → dynamic {
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<Never>);
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<Never>);
+}
+static method boz(self::E<Never> ei, self::E<Never> es) → dynamic {}
+static method checkIsType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(!(x is{ForNonNullableByDefault} self::checkIsType::T%)) {
+ throw "Expected value of type ${x.{core::Object::runtimeType}{core::Type}} to also be of type ${self::checkIsType::T%}.";
+ }
+}
+static method checkIsNotType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(x is{ForNonNullableByDefault} self::checkIsNotType::T%) {
+ throw "Expected value of type ${x{self::checkIsNotType::T%}.{core::Object::runtimeType}{core::Type}} to not be of type ${self::checkIsNotType::T%}.";
+ }
+}
+static method main() → dynamic {
+ self::checkIsType<self::E<dynamic>>(#C4);
+ self::checkIsType<self::E<dynamic>>(#C7);
+ self::checkIsType<self::E<core::int>>(#C4);
+ self::checkIsType<self::E<core::String>>(#C7);
+ self::checkIsNotType<self::E<Never>>(#C4);
+ self::checkIsNotType<self::E<Never>>(#C7);
+ self::checkIsNotType<self::E<core::String>>(#C4);
+ self::checkIsNotType<self::E<core::int>>(#C7);
+}
+
+constants {
+ #C1 = 1
+ #C2 = 0
+ #C3 = "one"
+ #C4 = self::E<core::int*> {field:#C1, index:#C2, _name:#C3}
+ #C5 = "2"
+ #C6 = "two"
+ #C7 = self::E<core::String*> {field:#C5, index:#C1, _name:#C6}
+ #C8 = <self::E<dynamic>*>[#C4, #C7]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///instantiated_generic_enum_types.dart:
+- E. (from org-dartlang-testcase:///instantiated_generic_enum_types.dart:11:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.outline.expect
new file mode 100644
index 0000000..0f67ffa
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.outline.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+class E<X extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E<dynamic>> values = const <self::E<dynamic>>[self::E::one, self::E::two];
+ static const field self::E<core::int> one = const self::E::•<core::int>(0, "one", 1);
+ static const field self::E<core::String> two = const self::E::•<core::String>(1, "two", "2");
+ final field self::E::X% field;
+ const constructor •(core::int index, core::String name, self::E::X% field) → self::E<self::E::X%>
+ : self::E::field = field, super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic
+ ;
+static method foo(self::E<core::int> ei, self::E<core::String> es) → dynamic
+ ;
+static method bar(self::E<core::int> ei, self::E<core::String> es) → dynamic
+ ;
+static method baz(self::E<core::Object> ei, self::E<core::Object> es) → dynamic
+ ;
+static method boz(self::E<Never> ei, self::E<Never> es) → dynamic
+ ;
+static method checkIsType<T extends core::Object? = dynamic>(dynamic x) → dynamic
+ ;
+static method checkIsNotType<T extends core::Object? = dynamic>(dynamic x) → dynamic
+ ;
+static method main() → dynamic
+ ;
+
+
+Extra constant evaluation status:
+Evaluated: ListLiteral @ org-dartlang-testcase:///instantiated_generic_enum_types.dart:5:6 -> ListConstant(const <E<dynamic>*>[const E<int*>{E.field: 1, _Enum.index: 0, _Enum._name: "one"}, const E<String*>{E.field: "2", _Enum.index: 1, _Enum._name: "two"}])
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///instantiated_generic_enum_types.dart:6:3 -> InstanceConstant(const E<int*>{E.field: 1, _Enum.index: 0, _Enum._name: "one"})
+Evaluated: ConstructorInvocation @ org-dartlang-testcase:///instantiated_generic_enum_types.dart:7:3 -> InstanceConstant(const E<String*>{E.field: "2", _Enum.index: 1, _Enum._name: "two"})
+Extra constant evaluation: evaluated: 9, effectively constant: 3
diff --git a/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.transformed.expect
new file mode 100644
index 0000000..fb83333
--- /dev/null
+++ b/pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart.weak.transformed.expect
@@ -0,0 +1,141 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(es, ei); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// bar(E.two, E.one); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// - 'Object' is from 'dart:core'.
+// boz(ei, es); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+// pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+// - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+// boz(E.one, E.two); // Error.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class E<X extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
+ static const field core::List<self::E<dynamic>> values = #C8;
+ static const field self::E<core::int> one = #C4;
+ static const field self::E<core::String> two = #C7;
+ final field self::E::X% field;
+ const constructor •(core::int index, core::String name, self::E::X% field) → self::E<self::E::X%>
+ : self::E::field = field, super core::_Enum::•(index, name)
+ ;
+ method toString() → core::String
+ return "E.${this.{core::_Enum::_name}{core::String}}";
+}
+static method test() → dynamic {
+ self::foo(#C4, #C7);
+}
+static method foo(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::bar(ei, es);
+ self::bar(#C4, #C7);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:7: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:21:11: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(es, ei); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+ self::bar(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:9: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<int>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<core::int>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:22:16: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<String>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ bar(E.two, E.one); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<core::String>);
+}
+static method bar(self::E<core::int> ei, self::E<core::String> es) → dynamic {
+ self::baz(ei, es);
+}
+static method baz(self::E<core::Object> ei, self::E<core::Object> es) → dynamic {
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:7: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in ei as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:30:11: Error: The argument type 'E<Object>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ - 'Object' is from 'dart:core'.
+ boz(ei, es); // Error.
+ ^" in es as{TypeError,ForNonNullableByDefault} self::E<Never>);
+ self::boz(invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:9: Error: The argument type 'E<int>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C4 as{TypeError,ForNonNullableByDefault} self::E<Never>, invalid-expression "pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart:31:16: Error: The argument type 'E<String>' can't be assigned to the parameter type 'E<Never>'.
+ - 'E' is from 'pkg/front_end/testcases/enhanced_enums/instantiated_generic_enum_types.dart'.
+ boz(E.one, E.two); // Error.
+ ^" in #C7 as{TypeError,ForNonNullableByDefault} self::E<Never>);
+}
+static method boz(self::E<Never> ei, self::E<Never> es) → dynamic {}
+static method checkIsType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(!(x is{ForNonNullableByDefault} self::checkIsType::T%)) {
+ throw "Expected value of type ${x.{core::Object::runtimeType}{core::Type}} to also be of type ${self::checkIsType::T%}.";
+ }
+}
+static method checkIsNotType<T extends core::Object? = dynamic>(dynamic x) → dynamic {
+ if(x is{ForNonNullableByDefault} self::checkIsNotType::T%) {
+ throw "Expected value of type ${x{self::checkIsNotType::T%}.{core::Object::runtimeType}{core::Type}} to not be of type ${self::checkIsNotType::T%}.";
+ }
+}
+static method main() → dynamic {
+ self::checkIsType<self::E<dynamic>>(#C4);
+ self::checkIsType<self::E<dynamic>>(#C7);
+ self::checkIsType<self::E<core::int>>(#C4);
+ self::checkIsType<self::E<core::String>>(#C7);
+ self::checkIsNotType<self::E<Never>>(#C4);
+ self::checkIsNotType<self::E<Never>>(#C7);
+ self::checkIsNotType<self::E<core::String>>(#C4);
+ self::checkIsNotType<self::E<core::int>>(#C7);
+}
+
+constants {
+ #C1 = 1
+ #C2 = 0
+ #C3 = "one"
+ #C4 = self::E<core::int*> {field:#C1, index:#C2, _name:#C3}
+ #C5 = "2"
+ #C6 = "two"
+ #C7 = self::E<core::String*> {field:#C5, index:#C1, _name:#C6}
+ #C8 = <self::E<dynamic>*>[#C4, #C7]
+}
+
+
+Constructor coverage from constants:
+org-dartlang-testcase:///instantiated_generic_enum_types.dart:
+- E. (from org-dartlang-testcase:///instantiated_generic_enum_types.dart:11:9)
+- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart:76:9)
+- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
diff --git a/pkg/front_end/testcases/enhanced_enums/members.dart.strong.expect b/pkg/front_end/testcases/enhanced_enums/members.dart.strong.expect
index d81899d..c358d70 100644
--- a/pkg/front_end/testcases/enhanced_enums/members.dart.strong.expect
+++ b/pkg/front_end/testcases/enhanced_enums/members.dart.strong.expect
@@ -33,7 +33,7 @@
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
- static factory f<X extends core::Object? = dynamic>() → self::E2<dynamic>
+ static factory f<X extends core::Object? = dynamic>() → self::E2<self::E2::f::X%>
return throw 42;
method method(core::int value) → core::int
return value.{core::num::+}(10){(core::num) → core::int};
diff --git a/pkg/front_end/testcases/enhanced_enums/members.dart.strong.transformed.expect b/pkg/front_end/testcases/enhanced_enums/members.dart.strong.transformed.expect
index d81899d..c358d70 100644
--- a/pkg/front_end/testcases/enhanced_enums/members.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/enhanced_enums/members.dart.strong.transformed.expect
@@ -33,7 +33,7 @@
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
- static factory f<X extends core::Object? = dynamic>() → self::E2<dynamic>
+ static factory f<X extends core::Object? = dynamic>() → self::E2<self::E2::f::X%>
return throw 42;
method method(core::int value) → core::int
return value.{core::num::+}(10){(core::num) → core::int};
diff --git a/pkg/front_end/testcases/enhanced_enums/members.dart.weak.expect b/pkg/front_end/testcases/enhanced_enums/members.dart.weak.expect
index 7aa96cc..16019e2 100644
--- a/pkg/front_end/testcases/enhanced_enums/members.dart.weak.expect
+++ b/pkg/front_end/testcases/enhanced_enums/members.dart.weak.expect
@@ -33,7 +33,7 @@
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
- static factory f<X extends core::Object? = dynamic>() → self::E2<dynamic>
+ static factory f<X extends core::Object? = dynamic>() → self::E2<self::E2::f::X%>
return throw 42;
method method(core::int value) → core::int
return value.{core::num::+}(10){(core::num) → core::int};
diff --git a/pkg/front_end/testcases/enhanced_enums/members.dart.weak.modular.expect b/pkg/front_end/testcases/enhanced_enums/members.dart.weak.modular.expect
index 7aa96cc..16019e2 100644
--- a/pkg/front_end/testcases/enhanced_enums/members.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/enhanced_enums/members.dart.weak.modular.expect
@@ -33,7 +33,7 @@
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
- static factory f<X extends core::Object? = dynamic>() → self::E2<dynamic>
+ static factory f<X extends core::Object? = dynamic>() → self::E2<self::E2::f::X%>
return throw 42;
method method(core::int value) → core::int
return value.{core::num::+}(10){(core::num) → core::int};
diff --git a/pkg/front_end/testcases/enhanced_enums/members.dart.weak.outline.expect b/pkg/front_end/testcases/enhanced_enums/members.dart.weak.outline.expect
index f6877f8..65b7311 100644
--- a/pkg/front_end/testcases/enhanced_enums/members.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/enhanced_enums/members.dart.weak.outline.expect
@@ -33,7 +33,7 @@
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
- static factory f<X extends core::Object? = dynamic>() → self::E2<dynamic>
+ static factory f<X extends core::Object? = dynamic>() → self::E2<self::E2::f::X%>
;
method method(core::int value) → core::int
;
diff --git a/pkg/front_end/testcases/enhanced_enums/members.dart.weak.transformed.expect b/pkg/front_end/testcases/enhanced_enums/members.dart.weak.transformed.expect
index 7aa96cc..16019e2 100644
--- a/pkg/front_end/testcases/enhanced_enums/members.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/enhanced_enums/members.dart.weak.transformed.expect
@@ -33,7 +33,7 @@
;
method toString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
- static factory f<X extends core::Object? = dynamic>() → self::E2<dynamic>
+ static factory f<X extends core::Object? = dynamic>() → self::E2<self::E2::f::X%>
return throw 42;
method method(core::int value) → core::int
return value.{core::num::+}(10){(core::num) → core::int};
diff --git a/pkg/front_end/testcases/textual_outline.status b/pkg/front_end/testcases/textual_outline.status
index 35116bf..6afc196 100644
--- a/pkg/front_end/testcases/textual_outline.status
+++ b/pkg/front_end/testcases/textual_outline.status
@@ -30,6 +30,7 @@
dart2js/late_statics: FormatterCrash
enhanced_enums/entries_with_type_arguments: FormatterCrash
enhanced_enums/inference_in_constructor_parameters: FormatterCrash
+enhanced_enums/instantiated_generic_enum_types: FormatterCrash
enhanced_enums/issue48084: FormatterCrash
enhanced_enums/members: FormatterCrash
enhanced_enums/qualified_names_with_no_type_arguments: FormatterCrash
diff --git a/tools/VERSION b/tools/VERSION
index 019f1ab..cb01692 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 17
PATCH 0
-PRERELEASE 16
+PRERELEASE 17
PRERELEASE_PATCH 0
\ No newline at end of file