| OLD | NEW |
| (Empty) | |
| 1 library docgen.models.indexable; |
| 2 |
| 3 import 'package:markdown/markdown.dart' as markdown; |
| 4 |
| 5 import '../exports/mirrors_util.dart' as dart2js_util; |
| 6 import '../exports/source_mirrors.dart'; |
| 7 |
| 8 import '../library_helpers.dart'; |
| 9 import 'dummy_mirror.dart'; |
| 10 import 'library.dart'; |
| 11 import 'mirror_based.dart'; |
| 12 import 'model_helpers.dart'; |
| 13 |
| 14 /// An item that is categorized in our mirrorToDocgen map, as a distinct, |
| 15 /// searchable element. |
| 16 /// |
| 17 /// These are items that refer to concrete entities (a Class, for example, |
| 18 /// but not a Type, which is a "pointer" to a class) that we wish to be |
| 19 /// globally resolvable. This includes things such as class methods and |
| 20 /// variables, but parameters for methods are not "Indexable" as we do not want |
| 21 /// the user to be able to search for a method based on its parameter names! |
| 22 /// The set of indexable items also includes Typedefs, since the user can refer |
| 23 /// to them as concrete entities in a particular scope. |
| 24 abstract class Indexable<TMirror extends DeclarationMirror> |
| 25 extends MirrorBased<TMirror> { |
| 26 |
| 27 Library get owningLibrary => owner.owningLibrary; |
| 28 |
| 29 String get qualifiedName => fileName; |
| 30 final TMirror mirror; |
| 31 final bool isPrivate; |
| 32 /// The comment text pre-resolution. We keep this around because inherited |
| 33 /// methods need to resolve links differently from the superclass. |
| 34 String unresolvedComment = ''; |
| 35 |
| 36 Indexable(TMirror mirror) |
| 37 : this.mirror = mirror, |
| 38 this.isPrivate = isHidden(mirror) { |
| 39 |
| 40 var map = mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)]; |
| 41 if (map == null) map = new Map<String, Set<Indexable>>(); |
| 42 |
| 43 var set = map[owner.docName]; |
| 44 if (set == null) set = new Set<Indexable>(); |
| 45 set.add(this); |
| 46 map[owner.docName] = set; |
| 47 mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)] = map; |
| 48 } |
| 49 |
| 50 /// Returns this object's qualified name, but following the conventions |
| 51 /// we're using in Dartdoc, which is that library names with dots in them |
| 52 /// have them replaced with hyphens. |
| 53 String get docName; |
| 54 |
| 55 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 56 markdown.Node fixReference(String name) { |
| 57 // Attempt the look up the whole name up in the scope. |
| 58 String elementName = findElementInScope(name); |
| 59 if (elementName != null) { |
| 60 return new markdown.Element.text('a', elementName); |
| 61 } |
| 62 return fixComplexReference(name); |
| 63 } |
| 64 |
| 65 /// Look for the specified name starting with the current member, and |
| 66 /// progressively working outward to the current library scope. |
| 67 String findElementInScope(String name) => |
| 68 findElementInScopeWithPrefix(name, packagePrefix); |
| 69 |
| 70 /// The reference to this element based on where it is printed as a |
| 71 /// documentation file and also the unique URL to refer to this item. |
| 72 /// |
| 73 /// The qualified name (for URL purposes) and the file name are the same, |
| 74 /// of the form packageName/ClassName or packageName/ClassName.methodName. |
| 75 /// This defines both the URL and the directory structure. |
| 76 String get fileName => packagePrefix + ownerPrefix + name; |
| 77 |
| 78 /// The full docName of the owner element, appended with a '.' for this |
| 79 /// object's name to be appended. |
| 80 String get ownerPrefix => owner.docName != '' ? owner.docName + '.' : ''; |
| 81 |
| 82 /// The prefix String to refer to the package that this item is in, for URLs |
| 83 /// and comment resolution. |
| 84 /// |
| 85 /// The prefix can be prepended to a qualified name to get a fully unique |
| 86 /// name among all packages. |
| 87 String get packagePrefix; |
| 88 |
| 89 /// Documentation comment with converted markdown and all links resolved. |
| 90 String commentField; |
| 91 |
| 92 /// Accessor to documentation comment with markdown converted to html and all |
| 93 /// links resolved. |
| 94 String get comment { |
| 95 if (commentField != null) return commentField; |
| 96 |
| 97 commentField = commentToHtml(); |
| 98 if (commentField.isEmpty) { |
| 99 commentField = getMdnComment(); |
| 100 } |
| 101 return commentField; |
| 102 } |
| 103 |
| 104 void set comment(x) { |
| 105 commentField = x; |
| 106 } |
| 107 |
| 108 /// The simple name to refer to this item. |
| 109 String get name => dart2js_util.nameOf(mirror); |
| 110 |
| 111 /// Accessor to the parent item that owns this item. |
| 112 /// |
| 113 /// "Owning" is defined as the object one scope-level above which this item |
| 114 /// is defined. Ex: The owner for a top level class, would be its enclosing |
| 115 /// library. The owner of a local variable in a method would be the enclosing |
| 116 /// method. |
| 117 Indexable get owner => new DummyMirror(mirror.owner); |
| 118 |
| 119 /// Generates MDN comments from database.json. |
| 120 String getMdnComment(); |
| 121 |
| 122 /// The type of this member to be used in index.txt. |
| 123 String get typeName => ''; |
| 124 |
| 125 /// Creates a [Map] with this [Indexable]'s name and a preview comment. |
| 126 Map get previewMap { |
| 127 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; |
| 128 var pre = preview; |
| 129 if (pre != null) finalMap['preview'] = pre; |
| 130 return finalMap; |
| 131 } |
| 132 |
| 133 String get preview { |
| 134 if (comment != '') { |
| 135 var index = comment.indexOf('</p>'); |
| 136 return index > 0 ? |
| 137 '${comment.substring(0, index)}</p>' : |
| 138 '<p><i>Comment preview not available</i></p>'; |
| 139 } |
| 140 return null; |
| 141 } |
| 142 |
| 143 /// Accessor to obtain the raw comment text for a given item, _without_ any |
| 144 /// of the links resolved. |
| 145 String get _commentText { |
| 146 String commentText; |
| 147 mirror.metadata.forEach((metadata) { |
| 148 if (metadata is CommentInstanceMirror) { |
| 149 CommentInstanceMirror comment = metadata; |
| 150 if (comment.isDocComment) { |
| 151 if (commentText == null) { |
| 152 commentText = comment.trimmedText; |
| 153 } else { |
| 154 commentText = '$commentText\n${comment.trimmedText}'; |
| 155 } |
| 156 } |
| 157 } |
| 158 }); |
| 159 return commentText; |
| 160 } |
| 161 |
| 162 /// Returns any documentation comments associated with a mirror with |
| 163 /// simple markdown converted to html. |
| 164 /// |
| 165 /// By default we resolve any comment references within our own scope. |
| 166 /// However, if a method is inherited, we want the inherited comments, but |
| 167 /// links to the subclasses's version of the methods. |
| 168 String commentToHtml([Indexable resolvingScope]) { |
| 169 if (resolvingScope == null) resolvingScope = this; |
| 170 var commentText = _commentText; |
| 171 unresolvedComment = commentText; |
| 172 |
| 173 commentText = commentText == null ? '' : |
| 174 markdown.markdownToHtml(commentText.trim(), |
| 175 linkResolver: resolvingScope.fixReference, |
| 176 inlineSyntaxes: MARKDOWN_SYNTAXES); |
| 177 return commentText; |
| 178 } |
| 179 |
| 180 /// Return a map representation of this type. |
| 181 Map toMap(); |
| 182 |
| 183 /// Accessor to determine if this item and all of its owners are visible. |
| 184 bool get isVisible => isFullChainVisible(this); |
| 185 |
| 186 /// Returns true if [mirror] is the correct type of mirror that this Docgen |
| 187 /// object wraps. (Workaround for the fact that Types are not first class.) |
| 188 bool isValidMirror(DeclarationMirror mirror); |
| 189 } |
| OLD | NEW |