use analyzer to help resolve commentRefs (#1398)
* use analyzer to help resolve commentRefs
* change comment on _getRefElementFromCommentRefs
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0e6f305..4eca2f3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,6 @@
## 0.11.0
+* Fix resolution of ambiguous classes where the analyzer can help us. #1397
* Many cleanups to dartdoc stdout/stderr, error messages, and warnings:
* Display fatal errors with 'fatal error' string to distinguish them from ordinary errors
* Upgrades to new Package.warn system.
diff --git a/lib/src/markdown_processor.dart b/lib/src/markdown_processor.dart
index eaa2589..6b63ee1 100644
--- a/lib/src/markdown_processor.dart
+++ b/lib/src/markdown_processor.dart
@@ -236,24 +236,14 @@
// Try expensive not-scoped lookup.
if (refElement == null) {
- refElement = _findRefElementInLibrary(codeRef, element);
+ refElement = _findRefElementInLibrary(codeRef, element, commentRefs);
}
// This is faster but does not take canonicalization into account; try
// only as a last resort. TODO(jcollins-g): make analyzer comment references
// dartdoc-canonicalization-aware?
if (refElement == null) {
- for (CommentReference ref in commentRefs) {
- if (ref.identifier.name == codeRef) {
- bool isConstrElement =
- ref.identifier.staticElement is ConstructorElement;
- // Constructors are now handled by library search.
- if (!isConstrElement) {
- refElement = ref.identifier.staticElement;
- break;
- }
- }
- }
+ refElement = _getRefElementFromCommentRefs(commentRefs, codeRef);
}
// Did not find it anywhere.
@@ -302,6 +292,21 @@
return new MatchingLinkResult(refModelElement, null);
}
+/// Given a set of commentRefs, return the one whose name matches the codeRef.
+Element _getRefElementFromCommentRefs(List<CommentReference> commentRefs, String codeRef) {
+ for (CommentReference ref in commentRefs) {
+ if (ref.identifier.name == codeRef) {
+ bool isConstrElement =
+ ref.identifier.staticElement is ConstructorElement;
+ // Constructors are now handled by library search.
+ if (!isConstrElement) {
+ return ref.identifier.staticElement;
+ }
+ }
+ }
+ return null;
+}
+
/// Returns true if this is a constructor we should consider in
/// _findRefElementInLibrary, or if this isn't a constructor.
bool _ConsiderIfConstructor(String codeRef, ModelElement modelElement) {
@@ -333,7 +338,7 @@
// TODO(jcollins-g): Subcomponents of this function shouldn't be adding nulls to results, strip the
// removes out that are gratuitous and debug the individual pieces.
// TODO(jcollins-g): A complex package winds up spending a lot of cycles in here. Optimize.
-Element _findRefElementInLibrary(String codeRef, ModelElement element) {
+Element _findRefElementInLibrary(String codeRef, ModelElement element, List<CommentReference> commentRefs) {
assert(element.package.allLibrariesAdded);
String codeRefChomped = codeRef.replaceFirst(isConstructor, '');
@@ -345,21 +350,21 @@
// This might be an operator. Strip the operator prefix and try again.
if (results.isEmpty && codeRef.startsWith('operator')) {
String newCodeRef = codeRef.replaceFirst('operator', '');
- return _findRefElementInLibrary(newCodeRef, element);
+ return _findRefElementInLibrary(newCodeRef, element, commentRefs);
}
results.remove(null);
// Oh, and someone might have some type parameters or other garbage.
if (results.isEmpty && codeRef.contains(trailingIgnoreStuff)) {
String newCodeRef = codeRef.replaceFirst(trailingIgnoreStuff, '');
- return _findRefElementInLibrary(newCodeRef, element);
+ return _findRefElementInLibrary(newCodeRef, element, commentRefs);
}
results.remove(null);
// Oh, and someone might have thrown on a 'const' or 'final' in front.
if (results.isEmpty && codeRef.contains(leadingIgnoreStuff)) {
String newCodeRef = codeRef.replaceFirst(leadingIgnoreStuff, '');
- return _findRefElementInLibrary(newCodeRef, element);
+ return _findRefElementInLibrary(newCodeRef, element, commentRefs);
}
// Maybe this ModelElement has parameters, and this is one of them.
@@ -515,8 +520,20 @@
results.removeWhere((r) => !r.fullyQualifiedName.startsWith(startName));
}
}
- // TODO(jcollins-g): further disambiguations based on package information?
+ // TODO(jcollins-g): As a last resort, try disambiguation with commentRefs.
+ // Maybe one of these is the same as what's resolvable with
+ // the analyzer, and if so, drop the others. We can't
+ // do this in reverse order because commentRefs don't know
+ // about dartdoc canonicalization.
+ if (results.length > 1) {
+ Element refElement = _getRefElementFromCommentRefs(commentRefs, codeRef);
+ if (results.any((me) => me.element == refElement)) {
+ results.removeWhere((me) => me.element != refElement);
+ }
+ }
+
+ // TODO(jcollins-g): further disambiguations based on package information?
if (results.isEmpty) {
result = null;
} else if (results.length == 1) {
diff --git a/lib/src/model.dart b/lib/src/model.dart
index c461f01..3dc7db0 100644
--- a/lib/src/model.dart
+++ b/lib/src/model.dart
@@ -3027,11 +3027,6 @@
warningMessage = 'generic type handled as HTML: """${message}"""';
break;
}
- // warningMessage should not contain "file:" or "dart:" -- confuses IntelliJ.
- ['file:', 'dart:'].forEach((s) {
- // message can contain user text; nothing we can do about that.
- assert(!warningMessage.contains(s) || message.contains(s));
- });
String fullMessage =
"${warningMessage} ${modelElement != null ? modelElement.elementLocation : ''}";
packageWarningCounter.addWarning(