mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 00:39:49 +00:00
Support patched generic methods.
R=sigmund@google.com Review URL: https://codereview.chromium.org/2535213003 .
This commit is contained in:
parent
3af747810f
commit
44bdc75827
|
@ -385,6 +385,7 @@ enum MessageKind {
|
|||
PATCH_POINT_TO_SETTER,
|
||||
PATCH_REQUIRED_PARAMETER_COUNT_MISMATCH,
|
||||
PATCH_RETURN_TYPE_MISMATCH,
|
||||
PATCH_TYPE_VARIABLES_MISMATCH,
|
||||
PLEASE_REPORT_THE_CRASH,
|
||||
POSITIONAL_PARAMETER_WITH_EQUALS,
|
||||
POTENTIAL_MUTATION,
|
||||
|
@ -1239,12 +1240,14 @@ main() => f<int>(42);
|
|||
]),
|
||||
|
||||
MessageKind.TYPE_VARIABLE_FROM_METHOD_CONSIDERED_DYNAMIC:
|
||||
const MessageTemplate(
|
||||
MessageKind.TYPE_VARIABLE_FROM_METHOD_CONSIDERED_DYNAMIC,
|
||||
"Method type variables are treated as `dynamic` in `as` expressions.",
|
||||
howToFix: "Try using the upper bound of the type variable, or check "
|
||||
"that the blind success of the test does not introduce bugs.",
|
||||
examples: const [
|
||||
const MessageTemplate(
|
||||
MessageKind.TYPE_VARIABLE_FROM_METHOD_CONSIDERED_DYNAMIC,
|
||||
"Method type variables are treated as `dynamic` in `as` "
|
||||
"expressions.",
|
||||
howToFix:
|
||||
"Try using the upper bound of the type variable, or check "
|
||||
"that the blind success of the test does not introduce bugs.",
|
||||
examples: const [
|
||||
"""
|
||||
// Method type variables are not reified, so they cannot be tested dynamically.
|
||||
bool f<T>(Object o) => o as T;
|
||||
|
@ -3530,6 +3533,11 @@ part of test.main;
|
|||
// Patch errors start.
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MessageKind.PATCH_TYPE_VARIABLES_MISMATCH: const MessageTemplate(
|
||||
MessageKind.PATCH_TYPE_VARIABLES_MISMATCH,
|
||||
"Patch type variables do not match "
|
||||
"type variables on origin method '#{methodName}'."),
|
||||
|
||||
MessageKind.PATCH_RETURN_TYPE_MISMATCH: const MessageTemplate(
|
||||
MessageKind.PATCH_RETURN_TYPE_MISMATCH,
|
||||
"Patch return type '#{patchReturnType}' does not match "
|
||||
|
|
|
@ -1417,6 +1417,14 @@ abstract class ConstructorBodyElement extends MethodElement {
|
|||
/// [GenericElement] defines the common interface for generic functions and
|
||||
/// [TypeDeclarationElement].
|
||||
abstract class GenericElement extends Element implements AstElement {
|
||||
/// Do not use [computeType] outside of the resolver.
|
||||
///
|
||||
/// Trying to access a type that has not been computed in resolution is an
|
||||
/// error and calling [computeType] covers that error.
|
||||
/// This method will go away!
|
||||
@deprecated
|
||||
DartType computeType(Resolution resolution);
|
||||
|
||||
/**
|
||||
* The type variables declared on this declaration. The type variables are not
|
||||
* available until the type of the element has been computed through
|
||||
|
|
|
@ -106,10 +106,24 @@ class PatchResolverTask extends CompilerTask {
|
|||
void checkMatchingPatchSignatures(
|
||||
FunctionElement origin, FunctionElement patch) {
|
||||
// TODO(johnniwinther): Show both origin and patch locations on errors.
|
||||
FunctionExpression originTree = origin.node;
|
||||
FunctionSignature originSignature = origin.functionSignature;
|
||||
FunctionExpression patchTree = patch.node;
|
||||
FunctionSignature patchSignature = patch.functionSignature;
|
||||
|
||||
if ('${originTree.typeVariables}' != '${patchTree.typeVariables}') {
|
||||
reporter.withCurrentElement(patch, () {
|
||||
Node errorNode = patchTree.typeVariables != null
|
||||
? patchTree.typeVariables
|
||||
: patchTree;
|
||||
reporter.reportError(
|
||||
reporter.createMessage(
|
||||
errorNode,
|
||||
MessageKind.PATCH_TYPE_VARIABLES_MISMATCH,
|
||||
{'methodName': origin.name}),
|
||||
[reporter.createMessage(origin, MessageKind.THIS_IS_THE_METHOD)]);
|
||||
});
|
||||
}
|
||||
if (originSignature.type.returnType != patchSignature.type.returnType) {
|
||||
reporter.withCurrentElement(patch, () {
|
||||
Node errorNode =
|
||||
|
|
|
@ -149,7 +149,8 @@ class PatchParserTask extends CompilerTask {
|
|||
DiagnosticReporter get reporter => compiler.reporter;
|
||||
|
||||
PatchParserTask(Compiler compiler)
|
||||
: compiler = compiler, super(compiler.measurer);
|
||||
: compiler = compiler,
|
||||
super(compiler.measurer);
|
||||
|
||||
/**
|
||||
* Scans a library patch file, applies the method patches and
|
||||
|
@ -248,7 +249,7 @@ class PatchMemberListener extends MemberListener {
|
|||
* declarations.
|
||||
*/
|
||||
class PatchClassElementParser extends PartialParser {
|
||||
PatchClassElementParser(Listener listener): super(listener);
|
||||
PatchClassElementParser(Listener listener) : super(listener);
|
||||
|
||||
Token parseClassBody(Token token) => fullParseClassBody(token);
|
||||
}
|
||||
|
|
|
@ -307,6 +307,11 @@ class SignatureResolver extends MappingVisitor<FormalElementX> {
|
|||
DiagnosticReporter reporter = resolution.reporter;
|
||||
|
||||
List<DartType> createTypeVariables(NodeList typeVariableNodes) {
|
||||
if (element.isPatch) {
|
||||
FunctionTypedElement origin = element.origin;
|
||||
origin.computeType(resolution);
|
||||
return origin.typeVariables;
|
||||
}
|
||||
if (typeVariableNodes == null) return const <DartType>[];
|
||||
|
||||
// Create the types and elements corresponding to [typeVariableNodes].
|
||||
|
|
|
@ -166,6 +166,59 @@ Future testPatchFunctionMetadata() async {
|
|||
"Unexpected patch metadata: ${patch.metadata}.");
|
||||
}
|
||||
|
||||
Future testPatchFunctionGeneric() async {
|
||||
var compiler = await applyPatch(
|
||||
"external T test<T>();", "@patch T test<T>() { return null; } ");
|
||||
Element origin = ensure(
|
||||
compiler, "test", compiler.commonElements.coreLibrary.find,
|
||||
expectIsPatched: true, checkHasBody: true);
|
||||
ensure(compiler, "test", compiler.commonElements.coreLibrary.patch.find,
|
||||
expectIsPatch: true, checkHasBody: true);
|
||||
compiler.resolver.resolve(origin);
|
||||
|
||||
DiagnosticCollector collector = compiler.diagnosticCollector;
|
||||
Expect.isTrue(
|
||||
collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}");
|
||||
Expect.isTrue(
|
||||
collector.errors.isEmpty, "Unexpected errors: ${collector.errors}");
|
||||
}
|
||||
|
||||
Future testPatchFunctionGenericExtraTypeVariable() async {
|
||||
var compiler = await applyPatch(
|
||||
"external T test<T>();", "@patch T test<T, S>() { return null; } ");
|
||||
Element origin = ensure(
|
||||
compiler, "test", compiler.commonElements.coreLibrary.find,
|
||||
expectIsPatched: true, checkHasBody: true);
|
||||
ensure(compiler, "test", compiler.commonElements.coreLibrary.patch.find,
|
||||
expectIsPatch: true, checkHasBody: true);
|
||||
compiler.resolver.resolve(origin);
|
||||
|
||||
DiagnosticCollector collector = compiler.diagnosticCollector;
|
||||
Expect.isTrue(
|
||||
collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}");
|
||||
Expect.equals(1, collector.errors.length);
|
||||
Expect.isTrue(collector.errors.first.message.kind ==
|
||||
MessageKind.PATCH_TYPE_VARIABLES_MISMATCH);
|
||||
}
|
||||
|
||||
Future testPatchFunctionGenericDifferentNames() async {
|
||||
var compiler = await applyPatch(
|
||||
"external T test<T, S>();", "@patch T test<S, T>() { return null; } ");
|
||||
Element origin = ensure(
|
||||
compiler, "test", compiler.commonElements.coreLibrary.find,
|
||||
expectIsPatched: true, checkHasBody: true);
|
||||
ensure(compiler, "test", compiler.commonElements.coreLibrary.patch.find,
|
||||
expectIsPatch: true, checkHasBody: true);
|
||||
compiler.resolver.resolve(origin);
|
||||
|
||||
DiagnosticCollector collector = compiler.diagnosticCollector;
|
||||
Expect.isTrue(
|
||||
collector.warnings.isEmpty, "Unexpected warnings: ${collector.warnings}");
|
||||
Expect.equals(1, collector.errors.length);
|
||||
Expect.isTrue(collector.errors.first.message.kind ==
|
||||
MessageKind.PATCH_TYPE_VARIABLES_MISMATCH);
|
||||
}
|
||||
|
||||
Future testPatchVersioned() async {
|
||||
String fullPatch = "test(){return 'string';}";
|
||||
String lazyPatch = "test(){return 'new and improved string';}";
|
||||
|
@ -1086,6 +1139,9 @@ main() {
|
|||
await testPatchRedirectingConstructor();
|
||||
await testPatchFunction();
|
||||
await testPatchFunctionMetadata();
|
||||
await testPatchFunctionGeneric();
|
||||
await testPatchFunctionGenericExtraTypeVariable();
|
||||
await testPatchFunctionGenericDifferentNames();
|
||||
await testPatchMember();
|
||||
await testPatchGetter();
|
||||
await testRegularMember();
|
||||
|
|
Loading…
Reference in a new issue