Skip to content

Commit bd11290

Browse files
authored
Integrate new parser with new lookup code (dart-lang#2637)
* Flatten * rebuild
1 parent 62e25f1 commit bd11290

File tree

7 files changed

+106
-18
lines changed

7 files changed

+106
-18
lines changed

lib/src/comment_references/model_comment_reference.dart

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,14 @@ import 'package:dartdoc/src/comment_references/parser.dart';
99
import 'package:dartdoc/src/model_utils.dart';
1010

1111
abstract class ModelCommentReference {
12+
/// Does the structure of the reference itself imply a possible default
13+
/// constructor?
14+
// TODO(jcollins-g): rewrite/discard this once default constructor tear-off
15+
// design process is complete.
16+
bool get allowDefaultConstructor;
1217
String get codeRef;
18+
bool get hasConstructorHint;
19+
List<String> get referenceBy;
1320
Element get staticElement;
1421

1522
/// Construct a [ModelCommentReference] using the analyzer AST.
@@ -18,16 +25,37 @@ abstract class ModelCommentReference {
1825
_ModelCommentReferenceImpl(ref, resourceProvider);
1926

2027
/// Construct a [ModelCommentReference] given a raw string.
21-
factory ModelCommentReference.synthetic(String codeRef, Element element) =>
22-
_ModelCommentReferenceImpl.synthetic(codeRef, element);
28+
factory ModelCommentReference.synthetic(String codeRef) =>
29+
_ModelCommentReferenceImpl.synthetic(codeRef, null);
2330
}
2431

2532
/// A stripped down analyzer AST [CommentReference] containing only that
2633
/// information needed for Dartdoc. Drops link to the [CommentReference]
2734
/// and [ResourceProvider] after construction.
2835
class _ModelCommentReferenceImpl implements ModelCommentReference {
36+
@override
37+
bool get allowDefaultConstructor {
38+
if (parsed.length >= 2) {
39+
return parsed[parsed.length - 2] == parsed[parsed.length - 1];
40+
}
41+
return false;
42+
}
43+
2944
@override
3045
final String codeRef;
46+
47+
@override
48+
bool get hasConstructorHint =>
49+
parsed.isNotEmpty &&
50+
(parsed.first is ConstructorHintStartNode ||
51+
parsed.last is ConstructorHintEndNode);
52+
53+
@override
54+
List<String> get referenceBy => parsed
55+
.whereType<IdentifierNode>()
56+
.map<String>((i) => i.text)
57+
.toList(growable: false);
58+
3159
@override
3260
final Element staticElement;
3361

@@ -47,5 +75,7 @@ class _ModelCommentReferenceImpl implements ModelCommentReference {
4775
return contents.substring(ref.offset, ref.end);
4876
}
4977

50-
List<CommentReferenceNode> parse() => CommentReferenceParser(codeRef).parse();
78+
List<CommentReferenceNode> _parsed;
79+
List<CommentReferenceNode> get parsed =>
80+
_parsed ??= CommentReferenceParser(codeRef).parse();
5181
}

lib/src/generator/templates.renderers.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2146,6 +2146,18 @@ class _Renderer_Class extends RendererBase<Class> {
21462146
parent: r));
21472147
},
21482148
),
2149+
'referenceParents': Property(
2150+
getValue: (CT_ c) => c.referenceParents,
2151+
renderVariable: (CT_ c, Property<CT_> self,
2152+
List<String> remainingNames) =>
2153+
self.renderSimpleVariable(
2154+
c, remainingNames, 'Iterable<CommentReferable>'),
2155+
renderIterable:
2156+
(CT_ c, RendererBase<CT_> r, List<MustachioNode> ast) {
2157+
return c.referenceParents.map(
2158+
(e) => renderSimple(e, ast, r.template, parent: r));
2159+
},
2160+
),
21492161
'superChain': Property(
21502162
getValue: (CT_ c) => c.superChain,
21512163
renderVariable: (CT_ c, Property<CT_> self,

lib/src/logging.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@ void startLogging(LoggingContext config) {
105105
stdout.write('${ansi.backspace} ${ansi.backspace}');
106106
}
107107
var message = record.message;
108-
assert(message == message.trimRight());
109108
assert(message.isNotEmpty);
110109

111110
if (record.level < Level.WARNING) {

lib/src/markdown_processor.dart

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'dart:convert';
99
import 'dart:math';
1010

1111
import 'package:analyzer/dart/element/element.dart';
12+
import 'package:dartdoc/src/comment_references/model_comment_reference.dart';
1213
import 'package:dartdoc/src/element_type.dart';
1314
import 'package:dartdoc/src/model/comment_referable.dart';
1415
import 'package:dartdoc/src/model/model.dart';
@@ -275,19 +276,39 @@ ModelElement _getPreferredClass(ModelElement modelElement) {
275276
return null;
276277
}
277278

279+
/// Return false if the passed [referable] is a default [Constructor].
280+
bool _rejectDefaultConstructors(CommentReferable referable) {
281+
if (referable is Constructor &&
282+
referable.name == referable.enclosingElement.name) {
283+
return false;
284+
}
285+
return true;
286+
}
287+
288+
/// Return false unless the passed [referable] is a [Constructor].
289+
bool _requireConstructor(CommentReferable referable) =>
290+
referable is Constructor;
291+
278292
/// Implements _getMatchingLinkElement via [CommentReferable.referenceBy].
279293
MatchingLinkResult _getMatchingLinkElementCommentReferable(
280294
String codeRef, Warnable warnable) {
281-
if (!codeRef.contains(_constructorIndicationPattern) &&
282-
codeRef.contains(notARealDocReference)) {
283-
// Don't waste our time on things we won't ever find.
284-
return MatchingLinkResult(null, warn: false);
295+
var commentReference =
296+
warnable.commentRefs[codeRef] ?? ModelCommentReference.synthetic(codeRef);
297+
var filter = commentReference.hasConstructorHint
298+
? _requireConstructor
299+
: _rejectDefaultConstructors;
300+
301+
/// Neither reject, nor require, a default constructor in the event
302+
/// the comment reference structure implies one. (We can not require it
303+
/// in case a library name is the same as a member class name and the class
304+
/// is the intended lookup).
305+
if (commentReference.allowDefaultConstructor) {
306+
filter = null;
285307
}
308+
var lookupResult =
309+
warnable.referenceBy(commentReference.referenceBy, filter: filter);
286310

287-
// TODO(jcollins-g): implement implied constructor?
288-
var codeRefChompedParts =
289-
codeRef.replaceAll(_constructorIndicationPattern, '').split('.');
290-
var lookupResult = warnable.referenceBy(codeRefChompedParts);
311+
// TODO(jcollins-g): Consider prioritizing analyzer resolution before custom.
291312
return MatchingLinkResult(lookupResult);
292313
}
293314

lib/src/model/class.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import 'package:dartdoc/src/model_utils.dart' as model_utils;
1111
import 'package:dartdoc/src/quiver.dart' as quiver;
1212
import 'package:meta/meta.dart';
1313

14+
import 'comment_referable.dart';
15+
1416
/// A [Container] defined with a `class` declaration in Dart.
1517
///
1618
/// Members follow similar naming rules to [Container], with the following
@@ -602,4 +604,10 @@ class Class extends Container
602604

603605
@override
604606
Iterable<Field> get constantFields => allFields.where((f) => f.isConst);
607+
608+
@override
609+
Iterable<CommentReferable> get referenceParents => <CommentReferable>[
610+
...super.referenceParents,
611+
...superChain.map((m) => m.modelElement)
612+
];
605613
}

lib/src/model/comment_referable.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,12 @@ class ReferenceChildrenLookup {
2323
mixin CommentReferable implements Nameable {
2424
/// Look up a comment reference by its component parts. If [tryParents] is
2525
/// true, try looking up the same reference in any parents of [this].
26+
/// Will skip over results that do not pass a given [filter] and keep
27+
/// searching.
2628
@nonVirtual
2729
CommentReferable referenceBy(List<String> reference,
28-
{bool tryParents = true}) {
30+
{bool tryParents = true, bool Function(CommentReferable) filter}) {
31+
filter ??= (r) => true;
2932
if (reference.isEmpty) {
3033
if (tryParents == false) return this;
3134
return null;
@@ -37,16 +40,22 @@ mixin CommentReferable implements Nameable {
3740
if (referenceChildren.containsKey(referenceLookup.lookup)) {
3841
result = referenceChildren[referenceLookup.lookup];
3942
if (referenceLookup.remaining.isNotEmpty) {
40-
result =
41-
result?.referenceBy(referenceLookup.remaining, tryParents: false);
43+
result = result?.referenceBy(referenceLookup.remaining,
44+
tryParents: false, filter: filter);
45+
} else if (!filter(result)) {
46+
result = result?.referenceBy([referenceLookup.lookup],
47+
tryParents: false, filter: filter);
48+
}
49+
if (!filter(result)) {
50+
result = null;
4251
}
4352
}
4453
if (result != null) break;
4554
}
4655
// If we can't find it in children, try searching parents if allowed.
4756
if (result == null && tryParents) {
4857
for (var parent in referenceParents) {
49-
result = parent.referenceBy(reference);
58+
result = parent.referenceBy(reference, filter: filter);
5059
if (result != null) break;
5160
}
5261
}

test/comment_referable/comment_referable_test.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ abstract class Base extends Nameable with CommentReferable {
1717
/// Returns the added (or already existing) [Base].
1818
Base add(String newName);
1919

20-
Base lookup(String value) => referenceBy(value.split(_separator));
20+
T lookup<T extends CommentReferable>(String value,
21+
{bool Function(CommentReferable) filter}) =>
22+
referenceBy(value.split(_separator), filter: filter);
2123

2224
@override
2325
Element get element => throw UnimplementedError();
2426
}
2527

26-
class Top extends Base {
28+
class Top extends Base with CommentReferable {
2729
@override
2830
final String name;
2931
final List<TopChild> children;
@@ -124,6 +126,7 @@ void main() {
124126
referable.add('lib1.class2.member1');
125127
referable.add('lib2');
126128
referable.add('lib2.class3');
129+
referable.add('lib3.lib3.lib3');
127130
});
128131

129132
test('Check that basic lookups work', () {
@@ -132,5 +135,11 @@ void main() {
132135
expect(referable.lookup('lib1.class2.member1').name, equals('member1'));
133136
expect(referable.lookup('lib2.class3').name, equals('class3'));
134137
});
138+
139+
test('Check that filters work', () {
140+
expect(referable.lookup('lib3'), isA<TopChild>());
141+
expect(referable.lookup('lib3', filter: ((r) => r is GenericChild)),
142+
isA<GenericChild>());
143+
});
135144
});
136145
}

0 commit comments

Comments
 (0)