diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart index 736f66abf204..905d1554b968 100644 --- a/pkg/analyzer/lib/src/dart/ast/ast.dart +++ b/pkg/analyzer/lib/src/dart/ast/ast.dart @@ -3870,9 +3870,6 @@ class ExtensionDeclarationImpl extends CompilationUnitMemberImpl _members = new NodeListImpl(this, members); } - @override - Token get beginToken => extensionKeyword; - @override Iterable get childEntities => new ChildEntities() ..add(extensionKeyword) diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart index 8497919b68f0..eeefa426e17a 100644 --- a/pkg/analyzer/lib/src/dart/element/element.dart +++ b/pkg/analyzer/lib/src/dart/element/element.dart @@ -5013,6 +5013,28 @@ class ExtensionElementImpl extends ElementImpl _accessors = accessors; } + @override + int get codeLength { + if (linkedNode != null) { + return linkedContext.getCodeLength(linkedNode); + } + if (_unlinkedExtension != null) { + return _unlinkedExtension.codeRange?.length; + } + return super.codeLength; + } + + @override + int get codeOffset { + if (linkedNode != null) { + return linkedContext.getCodeOffset(linkedNode); + } + if (_unlinkedExtension != null) { + return _unlinkedExtension.codeRange?.offset; + } + return super.codeOffset; + } + @override String get displayName => name; diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart index 407f315965a3..8bbfdfd2f09d 100644 --- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart +++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart @@ -150,6 +150,8 @@ class LinkedUnitContext { return LazyConstructorDeclaration.getCodeLength(this, node); } else if (node is EnumDeclaration) { return LazyEnumDeclaration.getCodeLength(this, node); + } else if (node is ExtensionDeclaration) { + return LazyExtensionDeclaration.getCodeLength(this, node); } else if (node is FormalParameter) { return LazyFormalParameter.getCodeLength(this, node); } else if (node is FunctionDeclaration) { @@ -181,6 +183,8 @@ class LinkedUnitContext { return LazyConstructorDeclaration.getCodeOffset(this, node); } else if (node is EnumDeclaration) { return LazyEnumDeclaration.getCodeOffset(this, node); + } else if (node is ExtensionDeclaration) { + return LazyExtensionDeclaration.getCodeOffset(this, node); } else if (node is FormalParameter) { return LazyFormalParameter.getCodeOffset(this, node); } else if (node is FunctionDeclaration) { diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart index 5262772b55e4..ded834beee9d 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart @@ -27,6 +27,12 @@ class ApplyCheckElementTextReplacements { @reflectiveTest class ResynthesizeAstStrongTest extends ResynthesizeTestStrategyTwoPhase with ResynthesizeTestCases, GetElementTestCases, ResynthesizeTestHelpers { + @override + @failingTest + test_codeRange_extensions() async { + await super.test_codeRange_extensions(); + } + @failingTest // See dartbug.com/32290 test_const_constructor_inferred_args() => super.test_const_constructor_inferred_args(); @@ -58,6 +64,12 @@ class ResynthesizeAstStrongTest extends ResynthesizeTestStrategyTwoPhase await super.test_infer_generic_typedef_complex(); } + @override + @failingTest + test_metadata_extensionDeclaration() async { + await super.test_metadata_extensionDeclaration(); + } + @override @failingTest test_syntheticFunctionType_inGenericClass() async { diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart index 05d984a1607b..aed4cfa8695b 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_common.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart @@ -2022,6 +2022,68 @@ class C/*codeOffset=0, codeLength=462*/ { withConstElements: false); } + test_codeRange_extensions() async { + featureSet = enableExtensionMethods; + var library = await checkLibrary(''' +class A {} + +extension Raw on A {} + +/// Comment 1. +/// Comment 2. +extension HasDocComment on A {} + +@Object() +extension HasAnnotation on A {} + +@Object() +/// Comment 1. +/// Comment 2. +extension AnnotationThenComment on A {} + +/// Comment 1. +/// Comment 2. +@Object() +extension CommentThenAnnotation on A {} + +/// Comment 1. +@Object() +/// Comment 2. +extension CommentAroundAnnotation on A {} +'''); + checkElementText( + library, + r''' +class A/*codeOffset=0, codeLength=10*/ { +} +extension Raw/*codeOffset=12, codeLength=21*/ on A { +} +/// Comment 1. +/// Comment 2. +extension HasDocComment/*codeOffset=35, codeLength=61*/ on A { +} +@Object() +extension HasAnnotation/*codeOffset=98, codeLength=41*/ on A { +} +/// Comment 1. +/// Comment 2. +@Object() +extension AnnotationThenComment/*codeOffset=141, codeLength=79*/ on A { +} +/// Comment 1. +/// Comment 2. +@Object() +extension CommentThenAnnotation/*codeOffset=222, codeLength=79*/ on A { +} +/// Comment 2. +@Object() +extension CommentAroundAnnotation/*codeOffset=318, codeLength=66*/ on A { +} +''', + withCodeRanges: true, + withConstElements: false); + } + test_codeRange_field() async { var library = await checkLibrary(''' class C { @@ -8263,6 +8325,27 @@ const dynamic a = null; '''); } + test_metadata_extensionDeclaration() async { + featureSet = enableExtensionMethods; + var library = await checkLibrary(r''' +const a = null; +class A {} +@a +@Object() +extension E on A {}'''); + checkElementText(library, r''' +class A { +} +@ + a/*location: test.dart;a?*/ +@ + Object/*location: dart:core;Object*/() +extension E on A { +} +const dynamic a = null; +'''); + } + test_metadata_fieldDeclaration() async { var library = await checkLibrary('const a = null; class C { @a int x; }'); checkElementText(library, r'''