@@ -266,21 +266,31 @@ class AstRewriter {
266
266
return node;
267
267
}
268
268
var receiver = node.target! ;
269
- if (receiver is ! FunctionReference ) {
270
- return node;
271
- }
272
269
var propertyName = node.propertyName;
273
270
if (propertyName.isSynthetic) {
274
271
// This isn't a constructor reference.
275
272
return node;
276
273
}
277
- // A [ConstructorReference] with explicit type arguments is initially parsed
278
- // as a [PropertyAccess] with a [FunctionReference] target; for example:
279
- // `List<int>.filled` or `core.List<int>.filled`.
280
- var receiverIdentifier = receiver.function;
281
- if (receiverIdentifier is ! Identifier ) {
282
- // If [receiverIdentifier] is not an Identifier then [node] is not a
283
- // ConstructorReference.
274
+
275
+ Identifier receiverIdentifier;
276
+ TypeArgumentList ? typeArguments;
277
+ if (receiver is PrefixedIdentifier ) {
278
+ receiverIdentifier = receiver;
279
+ } else if (receiver is FunctionReference ) {
280
+ // A [ConstructorReference] with explicit type arguments is initially
281
+ // parsed as a [PropertyAccess] with a [FunctionReference] target; for
282
+ // example: `List<int>.filled` or `core.List<int>.filled`.
283
+ var function = receiver.function;
284
+ if (function is ! Identifier ) {
285
+ // If [receiverIdentifier] is not an Identifier then [node] is not a
286
+ // ConstructorReference.
287
+ return node;
288
+ }
289
+ receiverIdentifier = function;
290
+ typeArguments = receiver.typeArguments;
291
+ } else {
292
+ // If the receiver is not (initially) a prefixed identifier or a function
293
+ // reference, then [node] is not a constructor reference.
284
294
return node;
285
295
}
286
296
@@ -310,7 +320,7 @@ class AstRewriter {
310
320
return _toConstructorReference_propertyAccess (
311
321
node: node,
312
322
receiver: receiverIdentifier,
313
- typeArguments: receiver. typeArguments! ,
323
+ typeArguments: typeArguments,
314
324
classElement: element,
315
325
);
316
326
} else if (element is TypeAliasElement ) {
@@ -323,7 +333,7 @@ class AstRewriter {
323
333
return _toConstructorReference_propertyAccess (
324
334
node: node,
325
335
receiver: receiverIdentifier,
326
- typeArguments: receiver. typeArguments! ,
336
+ typeArguments: typeArguments,
327
337
classElement: aliasedType.element,
328
338
);
329
339
}
@@ -393,12 +403,24 @@ class AstRewriter {
393
403
return constructorReference;
394
404
}
395
405
396
- ConstructorReference _toConstructorReference_propertyAccess ({
406
+ AstNode _toConstructorReference_propertyAccess ({
397
407
required PropertyAccess node,
398
408
required Identifier receiver,
399
- required TypeArgumentList typeArguments,
409
+ required TypeArgumentList ? typeArguments,
400
410
required ClassElement classElement,
401
411
}) {
412
+ var name = node.propertyName.name;
413
+ var constructorElement = name == 'new'
414
+ ? classElement.unnamedConstructor
415
+ : classElement.getNamedConstructor (name);
416
+ if (constructorElement == null && typeArguments == null ) {
417
+ // If there is no constructor by this name, and no type arguments,
418
+ // do not rewrite the node. If there _are_ type arguments (like
419
+ // `prefix.C<int>.name`, then it looks more like a constructor tearoff
420
+ // than anything else, so continue with the rewrite.
421
+ return node;
422
+ }
423
+
402
424
var operator = node.operator ;
403
425
404
426
var typeName = astFactory.typeName (receiver, typeArguments);
0 commit comments