@@ -25,6 +25,7 @@ import 'package:analyzer/dart/element/type.dart';
2525import 'package:analyzer/dart/element/visitor.dart' ;
2626import 'package:analyzer/file_system/file_system.dart' as file_system;
2727import 'package:analyzer/file_system/physical_file_system.dart' ;
28+ import 'package:analyzer/source/line_info.dart' ;
2829import 'package:analyzer/src/context/builder.dart' ;
2930import 'package:analyzer/src/dart/analysis/byte_store.dart' ;
3031import 'package:analyzer/src/dart/analysis/driver.dart' ;
@@ -50,7 +51,6 @@ import 'package:crypto/crypto.dart';
5051import 'package:dartdoc/src/dartdoc_options.dart' ;
5152import 'package:dartdoc/src/element_type.dart' ;
5253import 'package:dartdoc/src/io_utils.dart' ;
53- import 'package:dartdoc/src/line_number_cache.dart' ;
5454import 'package:dartdoc/src/logging.dart' ;
5555import 'package:dartdoc/src/markdown_processor.dart' show Documentation;
5656import 'package:dartdoc/src/model_utils.dart' as utils;
@@ -1390,6 +1390,17 @@ class Constructor extends ModelElement
13901390 ConstructorElement element, Library library, PackageGraph packageGraph)
13911391 : super (element, library, packageGraph, null );
13921392
1393+ @override
1394+ CharacterLocation get characterLocation {
1395+ if (element.isSynthetic) {
1396+ // Make warnings for a synthetic constructor refer to somewhere reasonable
1397+ // since a synthetic constructor has no definition independent of the
1398+ // parent class.
1399+ return enclosingElement.characterLocation;
1400+ }
1401+ return super .characterLocation;
1402+ }
1403+
13931404 @override
13941405 // TODO(jcollins-g): Revisit this when dart-lang/sdk#31517 is implemented.
13951406 List <TypeParameter > get typeParameters =>
@@ -2057,7 +2068,7 @@ class Field extends ModelElement
20572068}
20582069
20592070/// Mixin for top-level variables and fields (aka properties)
2060- abstract class GetterSetterCombo implements ModelElement {
2071+ mixin GetterSetterCombo on ModelElement {
20612072 Accessor get getter;
20622073
20632074 Iterable <Accessor > get allAccessors sync * {
@@ -2114,6 +2125,20 @@ abstract class GetterSetterCombo implements ModelElement {
21142125 return const HtmlEscape (HtmlEscapeMode .unknown).convert (result);
21152126 }
21162127
2128+ @override
2129+ CharacterLocation get characterLocation {
2130+ // Handle all synthetic possibilities. Ordinarily, warnings for
2131+ // explicit setters/getters will be handled by those objects, but
2132+ // if a warning comes up for an enclosing synthetic field we have to
2133+ // put it somewhere. So pick an accessor.
2134+ if (element.isSynthetic) {
2135+ if (hasExplicitGetter) return getter.characterLocation;
2136+ if (hasExplicitSetter) return setter.characterLocation;
2137+ assert (false , 'Field and accessors can not all be synthetic' );
2138+ }
2139+ return super .characterLocation;
2140+ }
2141+
21172142 String get constantValue => linkifyConstantValue (constantValueBase);
21182143
21192144 String get constantValueTruncated =>
@@ -2367,6 +2392,18 @@ class Library extends ModelElement with Categorization, TopLevelContainer {
23672392
23682393 List <Class > get allClasses => _allClasses;
23692394
2395+ @override
2396+ CharacterLocation get characterLocation {
2397+ if (element.nameOffset == - 1 ) {
2398+ assert (isAnonymous, 'Only anonymous libraries are allowed to have no declared location' );
2399+ return CharacterLocation (1 , 1 );
2400+ }
2401+ return super .characterLocation;
2402+ }
2403+
2404+ @override
2405+ CompilationUnitElement get compilationUnitElement => (element as LibraryElement ).definingCompilationUnit;
2406+
23702407 @override
23712408 Iterable <Class > get classes {
23722409 return _allClasses
@@ -2917,6 +2954,19 @@ class Method extends ModelElement
29172954 }).toList ();
29182955 }
29192956
2957+ @override
2958+ CharacterLocation get characterLocation {
2959+ if (enclosingElement is Enum && name == 'toString' ) {
2960+ // The toString() method on Enums is special, treated as not having
2961+ // a definition location by the analyzer yet not being inherited, either.
2962+ // Just directly override our location with the Enum definition --
2963+ // this is OK because Enums can not inherit from each other nor
2964+ // have their definitions split between files.
2965+ return enclosingElement.characterLocation;
2966+ }
2967+ return super .characterLocation;
2968+ }
2969+
29202970 @override
29212971 ModelElement get enclosingElement {
29222972 if (_enclosingClass == null ) {
@@ -3078,7 +3128,7 @@ abstract class Privacy {
30783128/// ModelElement will reference itself as part of the "wrong" [Library]
30793129/// from the public interface perspective.
30803130abstract class ModelElement extends Canonicalization
3081- with Privacy , Warnable , Nameable , SourceCodeMixin , Indexable
3131+ with Privacy , Warnable , Locatable , Nameable , SourceCodeMixin , Indexable
30823132 implements Comparable , Documentable {
30833133 final Element _element;
30843134
@@ -3715,8 +3765,8 @@ abstract class ModelElement extends Canonicalization
37153765 @override
37163766 String get location {
37173767 // Call nothing from here that can emit warnings or you'll cause stack overflows.
3718- if (lineAndColumn != null ) {
3719- return "(${path .toUri (sourceFileName )}:${lineAndColumn . item1 }:${ lineAndColumn . item2 })" ;
3768+ if (characterLocation != null ) {
3769+ return "(${path .toUri (sourceFileName )}:${characterLocation . toString () })" ;
37203770 }
37213771 return "(${path .toUri (sourceFileName )})" ;
37223772 }
@@ -3751,19 +3801,25 @@ abstract class ModelElement extends Canonicalization
37513801
37523802 String get sourceFileName => element.source.fullName;
37533803
3754- Tuple2 < int , int > _lineAndColumn ;
3755- bool _isLineNumberComputed = false ;
3804+ CharacterLocation _characterLocation ;
3805+ bool _characterLocationIsSet = false ;
37563806
37573807 @override
3758- Tuple2 <int , int > get lineAndColumn {
3759- // TODO(jcollins-g): implement lineAndColumn for explicit fields
3760- if (! _isLineNumberComputed) {
3761- _lineAndColumn = lineNumberCache.lineAndColumn (
3762- element.source.fullName, element.nameOffset);
3808+ CharacterLocation get characterLocation {
3809+ if (! _characterLocationIsSet) {
3810+ LineInfo lineInfo = compilationUnitElement.lineInfo;
3811+ _characterLocationIsSet = true ;
3812+ assert (element.nameOffset >= 0 , 'Invalid location data for element: $fullyQualifiedName ' );
3813+ assert (lineInfo != null , 'No lineInfo data available for element: $fullyQualifiedName ' );
3814+ if (element.nameOffset >= 0 ) {
3815+ _characterLocation = lineInfo? .getLocation (element.nameOffset);
3816+ }
37633817 }
3764- return _lineAndColumn ;
3818+ return _characterLocation ;
37653819 }
37663820
3821+ CompilationUnitElement get compilationUnitElement => element.getAncestor ((e) => e is CompilationUnitElement );
3822+
37673823 bool get hasAnnotations => annotations.isNotEmpty;
37683824
37693825 @override
@@ -4191,8 +4247,8 @@ abstract class ModelElement extends Canonicalization
41914247 warn (PackageWarning .toolError, message: message),
41924248 content: basicMatch[2 ],
41934249 environment: {
4194- 'SOURCE_LINE' : lineAndColumn ? .item1 ? .toString (),
4195- 'SOURCE_COLUMN' : lineAndColumn ? .item2 ? .toString (),
4250+ 'SOURCE_LINE' : characterLocation ? .lineNumber .toString (),
4251+ 'SOURCE_COLUMN' : characterLocation ? .columnNumber .toString (),
41964252 'SOURCE_PATH' : (sourceFileName == null ||
41974253 package? .packagePath == null )
41984254 ? null
@@ -5153,13 +5209,6 @@ class PackageGraph {
51535209 warnable = warnable.enclosingElement;
51545210 }
51555211 }
5156- if (warnable is Accessor ) {
5157- // This might be part of a Field, if so, assign this warning to the field
5158- // rather than the Accessor.
5159- if ((warnable as Accessor ).enclosingCombo != null ) {
5160- warnable = (warnable as Accessor ).enclosingCombo;
5161- }
5162- }
51635212 } else {
51645213 // If we don't have an element, we need a message to disambiguate.
51655214 assert (message != null );
@@ -5224,9 +5273,6 @@ class PackageGraph {
52245273 break ;
52255274 case PackageWarning .unresolvedDocReference:
52265275 warningMessage = "unresolved doc reference [${message }]" ;
5227- if (referredFrom == null ) {
5228- referredFrom = warnable.documentationFrom;
5229- }
52305276 referredFromPrefix = 'in documentation inherited from' ;
52315277 break ;
52325278 case PackageWarning .unknownMacro:
@@ -5273,14 +5319,14 @@ class PackageGraph {
52735319 List <String > messageParts = [warningMessage];
52745320 if (warnable != null ) {
52755321 messageParts
5276- .add ("${ warnablePrefix } ${ warnableName } : ${ warnable .location ?? '' } " );
5322+ .add ("$warnablePrefix $ warnableName : $warnable .location" );
52775323 }
52785324 if (referredFrom != null ) {
52795325 for (Locatable referral in referredFrom) {
52805326 if (referral != warnable) {
52815327 var referredFromStrings = _safeWarnableName (referral);
52825328 messageParts.add (
5283- "${ referredFromPrefix } ${ referredFromStrings } : ${referral .location ?? '' }" );
5329+ "$referredFromPrefix $ referredFromStrings : ${referral .location }" );
52845330 }
52855331 }
52865332 }
@@ -5957,6 +6003,7 @@ abstract class MarkdownFileDocumentation
59576003class Category extends Nameable
59586004 with
59596005 Warnable ,
6006+ Locatable ,
59606007 Canonicalization ,
59616008 MarkdownFileDocumentation ,
59626009 LibraryContainer ,
@@ -6510,7 +6557,7 @@ class Parameter extends ModelElement implements EnclosedElement {
65106557abstract class SourceCodeMixin implements Documentable {
65116558 ModelNode get modelNode;
65126559
6513- Tuple2 < int , int > get lineAndColumn ;
6560+ CharacterLocation get characterLocation ;
65146561
65156562 Element get element;
65166563
0 commit comments