diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart index 3a97f7df48e..258c80511f2 100644 --- a/pkg/analyzer/lib/src/dart/analysis/driver.dart +++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart @@ -109,7 +109,7 @@ testFineAfterLibraryAnalyzerHook; // TODO(scheglov): Clean up the list of implicitly analyzed files. class AnalysisDriver { /// The version of data format, should be incremented on every format change. - static const int DATA_VERSION = 634; + static const int DATA_VERSION = 636; /// The number of exception contexts allowed to write. Once this field is /// zero, we stop writing any new exception contexts in this process. diff --git a/pkg/analyzer/lib/src/fine/manifest_ast.dart b/pkg/analyzer/lib/src/fine/manifest_ast.dart index efa35f2f7b6..9b2581a37f6 100644 --- a/pkg/analyzer/lib/src/fine/manifest_ast.dart +++ b/pkg/analyzer/lib/src/fine/manifest_ast.dart @@ -215,6 +215,7 @@ class _ElementCollector extends GeneralizingAstVisitor { bool isValid = true; final int Function(TypeParameterElementImpl) indexOfTypeParameter; final int Function(FormalParameterElementImpl) indexOfFormalParameter; + final List _localTypeParameters = []; final Map map = Map.identity(); final List elementIndexList = []; @@ -289,7 +290,22 @@ class _ElementCollector extends GeneralizingAstVisitor { @override void visitGenericFunctionType(GenericFunctionType node) { - node.visitChildren(this); + var localTypeParameters = []; + if (node.typeParameters case var typeParameters?) { + for (var typeParameter in typeParameters.typeParameters) { + var element = typeParameter.declaredFragment!.element; + localTypeParameters.add(element); + } + } + + _localTypeParameters.addAll(localTypeParameters); + try { + node.visitChildren(this); + } finally { + for (var i = 0; i < localTypeParameters.length; i++) { + _localTypeParameters.removeLast(); + } + } } @override @@ -433,6 +449,16 @@ class _ElementCollector extends GeneralizingAstVisitor { node.visitChildren(this); } + @override + void visitTypeParameter(TypeParameter node) { + node.visitChildren(this); + } + + @override + void visitTypeParameterList(TypeParameterList node) { + node.visitChildren(this); + } + void _addElement(Element? element) { ManifestAstElementKind kind; int rawIndex; @@ -454,7 +480,13 @@ class _ElementCollector extends GeneralizingAstVisitor { rawIndex = indexOfFormalParameter(element); case TypeParameterElementImpl(): kind = ManifestAstElementKind.typeParameter; - rawIndex = indexOfTypeParameter(element); + var localIndex = _localTypeParameters.lastIndexOf(element); + if (localIndex != -1) { + rawIndex = _localTypeParameters.length - 1 - localIndex; + } else { + rawIndex = + _localTypeParameters.length + indexOfTypeParameter(element); + } case PrefixElement(): kind = ManifestAstElementKind.importPrefix; rawIndex = 0; diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart index 4e605ec4bc3..f6cc9d23902 100644 --- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart +++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart @@ -85272,6 +85272,198 @@ int get a => 0; ); } + test_manifest_metadata_genericFunctionType() async { + configuration.withElementManifests = true; + await _runLibraryManifestScenario( + initialCode: r''' +class A { + const A(a); +} +@A((T)>[]) +void foo() {} +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + hashForRequirements: #H0 + declaredClasses + A: #M0 + flags: isSimplyBounded + supertype: Object @ dart:core + interface: #M1 + declaredFunctions + foo: #M2 + flags: isOriginDeclaration isSimplyBounded isStatic + metadata + [0] + tokenBuffer: @A((T)>[]) + tokenLengthList: [1, 1, 1, 1, 4, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + elements + [0] (package:test/test.dart, class_, A) + [1] (package:test/test.dart, interfaceConstructor, A, new) + elementIndexList + 7 = element 0 + 0 = null + 6 = typeParameter 0 + 23 = element 1 + functionType: FunctionType + returnType: void + exportMapId: #M3 + exportMap + A: #M0 + foo: #M2 +''', + updatedCode: r''' +class A { + const A(a); +} +@A((T)>[]) +void foo() {} +final b = 0; +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + hashForRequirements: #H1 + declaredClasses + A: #M0 + flags: isSimplyBounded + supertype: Object @ dart:core + interface: #M1 + declaredGetters + b: #M4 + flags: isOriginVariable isSimplyBounded isStatic + returnType: int @ dart:core + declaredFunctions + foo: #M2 + flags: isOriginDeclaration isSimplyBounded isStatic + metadata + [0] + tokenBuffer: @A((T)>[]) + tokenLengthList: [1, 1, 1, 1, 4, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + elements + [0] (package:test/test.dart, class_, A) + [1] (package:test/test.dart, interfaceConstructor, A, new) + elementIndexList + 7 = element 0 + 0 = null + 6 = typeParameter 0 + 23 = element 1 + functionType: FunctionType + returnType: void + declaredVariables + b: #M5 + flags: hasImplicitType hasInitializer isFinal isOriginDeclaration isStatic isTypeInferredFromInitializer + type: int @ dart:core + exportMapId: #M6 + exportMap + A: #M0 + b: #M4 + foo: #M2 +''', + ); + } + + test_manifest_metadata_genericFunctionType_nested() async { + configuration.withElementManifests = true; + await _runLibraryManifestScenario( + initialCode: r''' +class A { + const A(a); +} +@A((void Function(T, U))>[]) +void foo() {} +''', + expectedInitialEvents: r''' +[operation] linkLibraryCycle SDK +[operation] linkLibraryCycle + package:test/test.dart + hashForRequirements: #H0 + declaredClasses + A: #M0 + flags: isSimplyBounded + supertype: Object @ dart:core + interface: #M1 + declaredFunctions + foo: #M2 + flags: isOriginDeclaration isSimplyBounded isStatic + metadata + [0] + tokenBuffer: @A((voidFunction(T,U))>[]) + tokenLengthList: [1, 1, 1, 1, 4, 8, 1, 1, 1, 1, 4, 8, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + elements + [0] (package:test/test.dart, class_, A) + [1] (package:test/test.dart, interfaceConstructor, A, new) + elementIndexList + 7 = element 0 + 0 = null + 0 = null + 22 = typeParameter 1 + 22 = typeParameter 1 + 6 = typeParameter 0 + 23 = element 1 + functionType: FunctionType + returnType: void + exportMapId: #M3 + exportMap + A: #M0 + foo: #M2 +''', + updatedCode: r''' +class A { + const A(a); +} +@A((void Function(T, U))>[]) +void foo() {} +final b = 0; +''', + expectedUpdatedEvents: r''' +[operation] linkLibraryCycle + package:test/test.dart + hashForRequirements: #H1 + declaredClasses + A: #M0 + flags: isSimplyBounded + supertype: Object @ dart:core + interface: #M1 + declaredGetters + b: #M4 + flags: isOriginVariable isSimplyBounded isStatic + returnType: int @ dart:core + declaredFunctions + foo: #M2 + flags: isOriginDeclaration isSimplyBounded isStatic + metadata + [0] + tokenBuffer: @A((voidFunction(T,U))>[]) + tokenLengthList: [1, 1, 1, 1, 4, 8, 1, 1, 1, 1, 4, 8, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] + elements + [0] (package:test/test.dart, class_, A) + [1] (package:test/test.dart, interfaceConstructor, A, new) + elementIndexList + 7 = element 0 + 0 = null + 0 = null + 22 = typeParameter 1 + 22 = typeParameter 1 + 6 = typeParameter 0 + 23 = element 1 + functionType: FunctionType + returnType: void + declaredVariables + b: #M5 + flags: hasImplicitType hasInitializer isFinal isOriginDeclaration isStatic isTypeInferredFromInitializer + type: int @ dart:core + exportMapId: #M6 + exportMap + A: #M0 + b: #M4 + foo: #M2 +''', + ); + } + test_manifest_metadata_remove() async { await _runLibraryManifestScenario( initialCode: r'''