-
Notifications
You must be signed in to change notification settings - Fork 117
/
model_comment_reference.dart
86 lines (74 loc) · 3.09 KB
/
model_comment_reference.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
//
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:dartdoc/src/comment_references/parser.dart';
abstract class ModelCommentReference {
/// Does the structure of the reference itself imply a possible default
/// constructor?
// TODO(jcollins-g): rewrite/discard this once default constructor tear-off
// design process is complete.
bool get allowDefaultConstructor;
String get codeRef;
bool get hasConstructorHint;
List<String> get referenceBy;
Element get staticElement;
/// Construct a [ModelCommentReference] using the analyzer AST.
factory ModelCommentReference(
CommentReference ref, ResourceProvider resourceProvider) =>
_ModelCommentReferenceImpl(ref, resourceProvider);
/// Construct a [ModelCommentReference] given a raw string.
factory ModelCommentReference.synthetic(String codeRef) =>
_ModelCommentReferenceImpl.synthetic(codeRef, null);
}
/// A stripped down analyzer AST [CommentReference] containing only that
/// information needed for Dartdoc. Drops link to the [CommentReference]
/// and [ResourceProvider] after construction.
class _ModelCommentReferenceImpl implements ModelCommentReference {
@override
bool get allowDefaultConstructor {
if (parsed.length >= 2) {
return parsed[parsed.length - 2] == parsed[parsed.length - 1];
}
return false;
}
@override
final String codeRef;
@override
bool get hasConstructorHint =>
parsed.isNotEmpty &&
(parsed.first is ConstructorHintStartNode ||
parsed.last is ConstructorHintEndNode);
@override
List<String> get referenceBy => parsed
.whereType<IdentifierNode>()
.map<String>((i) => i.text)
.toList(growable: false);
@override
final Element staticElement;
_ModelCommentReferenceImpl(
CommentReference ref, ResourceProvider resourceProvider)
: codeRef = _referenceText(ref, resourceProvider),
staticElement = ref.identifier.staticElement;
_ModelCommentReferenceImpl.synthetic(this.codeRef, this.staticElement);
/// "Unparse" the code reference into the raw text associated with the
/// [CommentReference].
static String _referenceText(
CommentReference ref, ResourceProvider resourceProvider) {
var token = (ref.parent as Comment)
.tokens
.firstWhere((t) => t.offset <= ref.offset && t.end >= ref.end);
// This is a little sketchy, but works since comments happen to be a token
// that is fully preserved in its string representation.
// TODO(jcollins-g): replace unparsing in general with lower level changes.
return token
.toString()
.substring(ref.offset - token.offset, ref.end - token.offset);
}
List<CommentReferenceNode> _parsed;
List<CommentReferenceNode> get parsed =>
_parsed ??= CommentReferenceParser(codeRef).parse();
}