From d2e5d475bc1e176091b8ed240d6e1a2dea17c721 Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Mon, 14 Dec 2020 05:37:37 +0000 Subject: [PATCH] Fix for crash when annotation references synthtic constructor of a generic class alias. FAILURE: mixi@:class (package:analyzer/src/dart/analysis/library_analyzer.dart:139:7) #19 _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:387:8) #20 LibraryAnalyzer.analyzeSync (package:analyzer/src/dart/analysis/library_analyzer.dart:138:11) #21 LibraryAnalyzer.analyze (package:analyzer/src/dart/analysis/library_analyzer.dart:107:12) #22 AnalysisDriver._computeResolvedLibrary2. (package:analyzer/src/dart/analysis/driver.dart:1414:65) #23 PerformanceLog.run (package:analyzer/src/dart/analysis/performance_logger.dart:32:15) #24 AnalysisDriver._computeResolvedLibrary2 (package:analyzer/src/dart/analysis/driver.dart:1400:20) #25 AnalysisDriver._computeResolvedLibrary. (package:analyzer/src/dart/analysis/driver.dart:1393:15) Change-Id: I6f04a325b30d9dc61e7eb1a4bba91ed8b9bcd1d3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/176060 Reviewed-by: Brian Wilkerson Commit-Queue: Konstantin Shcheglov --- .../lib/src/dart/element/element.dart | 8 +- .../test/src/summary/resynthesize_common.dart | 100 ++++++++++++++++++ 2 files changed, 106 insertions(+), 2 deletions(-) diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 5c726991df94f..d23a5ab40b253 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -956,9 +956,13 @@ class ClassElementImpl extends AbstractClassElementImpl // substituting type parameters as appropriate. return constructorsToForward .map((ConstructorElement superclassConstructor) { - ConstructorElementImpl implicitConstructor = - ConstructorElementImpl(superclassConstructor.name, -1); + var containerRef = reference.getChild('@constructor'); + var name = superclassConstructor.name; + var implicitConstructor = ConstructorElementImpl.forLinkedNode( + this, containerRef.getChild(name), null); implicitConstructor.isSynthetic = true; + implicitConstructor.name = name; + implicitConstructor.nameOffset = -1; implicitConstructor.redirectedConstructor = superclassConstructor; var hasMixinWithInstanceVariables = mixins.any(typeHasInstanceVariables); implicitConstructor.isConst = diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart index 85bf82785271e..ebb8c92dca4e9 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_common.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart @@ -9547,6 +9547,62 @@ class C { '''); } + test_metadata_constructor_call_named_synthetic_ofClassAlias_generic() async { + var library = await checkLibrary(''' +class A { + const A.named(); +} + +mixin B {} + +class C = A with B; + +@C.named() +class D {} +'''); + checkElementText( + library, + r''' +class A { + const A.named(); +} +class alias C extends A with B { + synthetic const C.named() = A.named; +} + typeParameters + T + bound: null + defaultType: dynamic +class D { +} + metadata + Annotation + arguments: ArgumentList + element: ConstructorMember + base: self::@class::C::@constructor::named + substitution: {T: dynamic} + name: PrefixedIdentifier + identifier: SimpleIdentifier + staticElement: ConstructorMember + base: self::@class::C::@constructor::named + substitution: {T: dynamic} + staticType: null + token: named + period: . + prefix: SimpleIdentifier + staticElement: self::@class::C + staticType: null + token: C + staticElement: ConstructorMember + base: self::@class::C::@constructor::named + substitution: {T: dynamic} + staticType: null +mixin B on Object { +} +''', + withFullyResolvedAst: true); + } + test_metadata_constructor_call_unnamed() async { var library = await checkLibrary('class A { const A(); } @A() class C {}'); checkElementText(library, r''' @@ -9574,6 +9630,50 @@ class C { '''); } + test_metadata_constructor_call_unnamed_synthetic_ofClassAlias_generic() async { + var library = await checkLibrary(''' +class A { + const A(); +} + +mixin B {} + +class C = A with B; + +@C() +class D {} +'''); + checkElementText( + library, + r''' +class A { + const A(); +} +class alias C extends A with B { + synthetic const C() = A; +} + typeParameters + T + bound: null + defaultType: dynamic +class D { +} + metadata + Annotation + arguments: ArgumentList + element: ConstructorMember + base: self::@class::C::@constructor::• + substitution: {T: dynamic} + name: SimpleIdentifier + staticElement: self::@class::C + staticType: null + token: C +mixin B on Object { +} +''', + withFullyResolvedAst: true); + } + test_metadata_constructor_call_with_args() async { var library = await checkLibrary('class A { const A(x); } @A(null) class C {}');