@@ -8,9 +8,8 @@ library dartdoc.markdown_processor;
8
8
import 'dart:convert' ;
9
9
import 'dart:math' ;
10
10
11
- import 'package:analyzer/dart/ast/ast.dart' ;
11
+ import 'package:analyzer/dart/ast/ast.dart' hide TypeParameter ;
12
12
import 'package:analyzer/dart/element/element.dart' ;
13
- import 'package:analyzer/src/dart/element/member.dart' show Member;
14
13
import 'package:dartdoc/src/model_utils.dart' ;
15
14
import 'package:html/parser.dart' show parse;
16
15
import 'package:markdown/markdown.dart' as md;
@@ -254,46 +253,42 @@ MatchingLinkResult _getMatchingLinkElement(
254
253
return new MatchingLinkResult (null , null , warn: false );
255
254
}
256
255
257
- Element refElement ;
256
+ ModelElement refModelElement ;
258
257
259
258
// Try expensive not-scoped lookup.
260
- if (refElement == null ) {
259
+ if (refModelElement == null ) {
261
260
Class preferredClass = _getPreferredClass (element);
262
- refElement =
261
+ refModelElement =
263
262
_findRefElementInLibrary (codeRef, element, commentRefs, preferredClass);
264
263
}
265
264
266
- // This is faster but does not take canonicalization into account; try
267
- // only as a last resort. TODO(jcollins-g): make analyzer comment references
268
- // dartdoc-canonicalization-aware?
269
- if (refElement == null ) {
270
- refElement = _getRefElementFromCommentRefs (commentRefs, codeRef);
265
+ // This is faster but does not know about libraries without imports in the
266
+ // current context; try only as a last resort.
267
+ // TODO(jcollins-g): make analyzer comment references dartdoc-canonicalization-aware?
268
+ if (refModelElement == null ) {
269
+ Element refElement = _getRefElementFromCommentRefs (commentRefs, codeRef);
270
+ if (refElement != null ) {
271
+ refModelElement = new ModelElement .fromElement (
272
+ _getRefElementFromCommentRefs (commentRefs, codeRef), element.package);
273
+ refModelElement =
274
+ refModelElement.canonicalModelElement ?? refModelElement;
275
+ }
271
276
} else {
272
- assert (refElement is ! PropertyAccessorElement );
273
- assert (refElement is ! PrefixElement );
277
+ assert (refModelElement is ! Accessor );
274
278
}
275
279
276
280
// Did not find it anywhere.
277
- if (refElement == null ) {
281
+ if (refModelElement == null ) {
278
282
// TODO(jcollins-g): remove squelching of non-canonical warnings here
279
283
// once we no longer process full markdown for
280
284
// oneLineDocs (#1417)
281
285
return new MatchingLinkResult (null , null , warn: element.isCanonical);
282
286
}
283
287
284
288
// Ignore all parameters.
285
- if (refElement is ParameterElement || refElement is TypeParameterElement )
289
+ if (refModelElement is Parameter || refModelElement is TypeParameter )
286
290
return new MatchingLinkResult (null , null , warn: false );
287
291
288
- Library refLibrary = element.package.findOrCreateLibraryFor (refElement);
289
- Element searchElement = refElement;
290
- if (searchElement is Member )
291
- searchElement = Package .getBasestElement (refElement);
292
-
293
- final Class preferredClass = _getPreferredClass (element);
294
- ModelElement refModelElement = element.package.findCanonicalModelElementFor (
295
- searchElement,
296
- preferredClass: preferredClass);
297
292
// There have been places in the code which helpfully cache entities
298
293
// regardless of what package they are associated with. This assert
299
294
// will protect us from reintroducing that.
@@ -302,23 +297,8 @@ MatchingLinkResult _getMatchingLinkElement(
302
297
return new MatchingLinkResult (refModelElement, null );
303
298
}
304
299
// From this point on, we haven't been able to find a canonical ModelElement.
305
- // So in this case, just find any ModelElement we can.
306
- Accessor getter;
307
- Accessor setter;
308
- if (searchElement is FieldElement ) {
309
- // TODO(jcollins-g): consolidate field element construction with inheritance
310
- // checking.
311
- if (searchElement.getter != null ) {
312
- getter = new ModelElement .from (searchElement.getter, refLibrary);
313
- }
314
- if (searchElement.setter != null ) {
315
- setter = new ModelElement .from (searchElement.setter, refLibrary);
316
- }
317
- }
318
- refModelElement = new ModelElement .from (searchElement, refLibrary,
319
- getter: getter, setter: setter);
320
300
if (! refModelElement.isCanonical) {
321
- if (refLibrary .isPublicAndPackageDocumented) {
301
+ if (refModelElement.library .isPublicAndPackageDocumented) {
322
302
refModelElement
323
303
.warn (PackageWarning .noCanonicalFound, referredFrom: [element]);
324
304
}
@@ -393,7 +373,7 @@ Map<String, Set<ModelElement>> _findRefElementCache;
393
373
// TODO(jcollins-g): Subcomponents of this function shouldn't be adding nulls to results, strip the
394
374
// removes out that are gratuitous and debug the individual pieces.
395
375
// TODO(jcollins-g): A complex package winds up spending a lot of cycles in here. Optimize.
396
- Element _findRefElementInLibrary (String codeRef, Warnable element,
376
+ ModelElement _findRefElementInLibrary (String codeRef, Warnable element,
397
377
List <CommentReference > commentRefs, Class preferredClass) {
398
378
assert (element != null );
399
379
assert (element.package.allLibrariesAdded);
@@ -507,10 +487,17 @@ Element _findRefElementInLibrary(String codeRef, Warnable element,
507
487
if (results.isEmpty &&
508
488
codeRefChomped.contains ('.' ) &&
509
489
_findRefElementCache.containsKey (codeRefChomped)) {
510
- for (final modelElement in _findRefElementCache[codeRefChomped]) {
490
+ for (final ModelElement modelElement
491
+ in _findRefElementCache[codeRefChomped]) {
511
492
if (! _ConsiderIfConstructor (codeRef, modelElement)) continue ;
493
+ // For fully qualified matches, the original preferredClass passed
494
+ // might make no sense. Instead, use the enclosing class from the
495
+ // element in [_findRefElementCache], because that element's enclosing
496
+ // class will be preferred from [codeRefChomped]'s perspective.
512
497
results.add (package.findCanonicalModelElementFor (modelElement.element,
513
- preferredClass: preferredClass));
498
+ preferredClass: modelElement.enclosingElement is Class
499
+ ? modelElement.enclosingElement
500
+ : null ));
514
501
}
515
502
}
516
503
results.remove (null );
@@ -563,8 +550,6 @@ Element _findRefElementInLibrary(String codeRef, Warnable element,
563
550
}
564
551
results.remove (null );
565
552
566
- Element result;
567
-
568
553
if (results.length > 1 ) {
569
554
// If this name could refer to a class or a constructor, prefer the class.
570
555
if (results.any ((r) => r is Class )) {
@@ -626,11 +611,12 @@ Element _findRefElementInLibrary(String codeRef, Warnable element,
626
611
}
627
612
}
628
613
614
+ ModelElement result;
629
615
// TODO(jcollins-g): further disambiguations based on package information?
630
616
if (results.isEmpty) {
631
617
result = null ;
632
618
} else if (results.length == 1 ) {
633
- result = results.first.element ;
619
+ result = results.first;
634
620
} else {
635
621
// Squelch ambiguous doc reference warnings for parameters, because we
636
622
// don't link those anyway.
@@ -639,7 +625,7 @@ Element _findRefElementInLibrary(String codeRef, Warnable element,
639
625
message:
640
626
"[$codeRef ] => ${results .map ((r ) => "'${r .fullyQualifiedName }'" ).join (", " )}" );
641
627
}
642
- result = results.first.element ;
628
+ result = results.first;
643
629
}
644
630
return result;
645
631
}
0 commit comments