| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 library docgen.models.indexable; | 5 library docgen.models.indexable; |
| 6 | 6 |
| 7 import 'package:markdown/markdown.dart' as markdown; | 7 import 'package:markdown/markdown.dart' as markdown; |
| 8 | 8 |
| 9 import '../exports/mirrors_util.dart' as dart2js_util; | 9 import '../exports/mirrors_util.dart' as dart2js_util; |
| 10 import '../exports/source_mirrors.dart'; | 10 import '../exports/source_mirrors.dart'; |
| 11 | 11 |
| 12 import '../library_helpers.dart'; | 12 import '../library_helpers.dart'; |
| 13 import 'dummy_mirror.dart'; | |
| 14 import 'library.dart'; | 13 import 'library.dart'; |
| 15 import 'mirror_based.dart'; | 14 import 'mirror_based.dart'; |
| 16 import 'model_helpers.dart'; | 15 import 'model_helpers.dart'; |
| 17 | 16 |
| 18 /// An item that is categorized in our mirrorToDocgen map, as a distinct, | 17 /// An item that is categorized in our mirrorToDocgen map, as a distinct, |
| 19 /// searchable element. | 18 /// searchable element. |
| 20 /// | 19 /// |
| 21 /// These are items that refer to concrete entities (a Class, for example, | 20 /// These are items that refer to concrete entities (a Class, for example, |
| 22 /// but not a Type, which is a "pointer" to a class) that we wish to be | 21 /// but not a Type, which is a "pointer" to a class) that we wish to be |
| 23 /// globally resolvable. This includes things such as class methods and | 22 /// globally resolvable. This includes things such as class methods and |
| 24 /// variables, but parameters for methods are not "Indexable" as we do not want | 23 /// variables, but parameters for methods are not "Indexable" as we do not want |
| 25 /// the user to be able to search for a method based on its parameter names! | 24 /// the user to be able to search for a method based on its parameter names! |
| 26 /// The set of indexable items also includes Typedefs, since the user can refer | 25 /// The set of indexable items also includes Typedefs, since the user can refer |
| 27 /// to them as concrete entities in a particular scope. | 26 /// to them as concrete entities in a particular scope. |
| 28 abstract class Indexable<TMirror extends DeclarationMirror> | 27 abstract class Indexable<TMirror extends DeclarationMirror> |
| 29 extends MirrorBased<TMirror> { | 28 extends MirrorBased<TMirror> { |
| 30 | 29 |
| 31 Library get owningLibrary => owner.owningLibrary; | 30 Library get owningLibrary => owner.owningLibrary; |
| 32 | 31 |
| 33 String get qualifiedName => fileName; | 32 /// The reference to this element based on where it is printed as a |
| 33 /// documentation file and also the unique URL to refer to this item. |
| 34 /// |
| 35 /// The qualified name (for URL purposes) and the file name are the same, |
| 36 /// of the form packageName/ClassName or packageName/ClassName.methodName. |
| 37 /// This defines both the URL and the directory structure. |
| 38 String get qualifiedName => packagePrefix + ownerPrefix + name; |
| 39 |
| 34 final TMirror mirror; | 40 final TMirror mirror; |
| 35 final bool isPrivate; | 41 final bool isPrivate; |
| 36 /// The comment text pre-resolution. We keep this around because inherited | 42 /// The comment text pre-resolution. We keep this around because inherited |
| 37 /// methods need to resolve links differently from the superclass. | 43 /// methods need to resolve links differently from the superclass. |
| 38 String unresolvedComment = ''; | 44 String unresolvedComment = ''; |
| 39 | 45 |
| 40 Indexable(TMirror mirror) | 46 Indexable(TMirror mirror) |
| 41 : this.mirror = mirror, | 47 : this.mirror = mirror, |
| 42 this.isPrivate = isHidden(mirror) { | 48 this.isPrivate = isHidden(mirror) { |
| 43 | 49 |
| 44 var map = mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)]; | 50 var mirrorQualifiedName = dart2js_util.qualifiedNameOf(this.mirror); |
| 45 if (map == null) map = new Map<String, Set<Indexable>>(); | |
| 46 | 51 |
| 47 var set = map[owner.docName]; | 52 var map = _mirrorToDocgen.putIfAbsent(mirrorQualifiedName, |
| 48 if (set == null) set = new Set<Indexable>(); | 53 () => new Map<String, Indexable>()); |
| 49 set.add(this); | 54 |
| 50 map[owner.docName] = set; | 55 var added = false; |
| 51 mirrorToDocgen[dart2js_util.qualifiedNameOf(this.mirror)] = map; | 56 map.putIfAbsent(owner.docName, () { |
| 57 added = true; |
| 58 return this; |
| 59 }); |
| 60 |
| 61 if (!added) { |
| 62 throw new StateError('An indexable has already been stored for ' |
| 63 '${owner.docName}'); |
| 64 } |
| 52 } | 65 } |
| 53 | 66 |
| 54 /// Returns this object's qualified name, but following the conventions | 67 /// Returns this object's qualified name, but following the conventions |
| 55 /// we're using in Dartdoc, which is that library names with dots in them | 68 /// we're using in Dartdoc, which is that library names with dots in them |
| 56 /// have them replaced with hyphens. | 69 /// have them replaced with hyphens. |
| 57 String get docName; | 70 String get docName; |
| 58 | 71 |
| 59 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. | 72 /// Converts all [foo] references in comments to <a>libraryName.foo</a>. |
| 60 markdown.Node fixReference(String name) { | 73 markdown.Node fixReference(String name) { |
| 61 // Attempt the look up the whole name up in the scope. | 74 // Attempt the look up the whole name up in the scope. |
| 62 String elementName = findElementInScope(name); | 75 String elementName = findElementInScope(name); |
| 63 if (elementName != null) { | 76 if (elementName != null) { |
| 64 return new markdown.Element.text('a', elementName); | 77 return new markdown.Element.text('a', elementName); |
| 65 } | 78 } |
| 66 return fixComplexReference(name); | 79 return fixComplexReference(name); |
| 67 } | 80 } |
| 68 | 81 |
| 69 /// Look for the specified name starting with the current member, and | 82 /// Look for the specified name starting with the current member, and |
| 70 /// progressively working outward to the current library scope. | 83 /// progressively working outward to the current library scope. |
| 71 String findElementInScope(String name) => | 84 String findElementInScope(String name) => |
| 72 findElementInScopeWithPrefix(name, packagePrefix); | 85 findElementInScopeWithPrefix(name, packagePrefix); |
| 73 | 86 |
| 74 /// The reference to this element based on where it is printed as a | |
| 75 /// documentation file and also the unique URL to refer to this item. | |
| 76 /// | |
| 77 /// The qualified name (for URL purposes) and the file name are the same, | |
| 78 /// of the form packageName/ClassName or packageName/ClassName.methodName. | |
| 79 /// This defines both the URL and the directory structure. | |
| 80 String get fileName => packagePrefix + ownerPrefix + name; | |
| 81 | |
| 82 /// The full docName of the owner element, appended with a '.' for this | 87 /// The full docName of the owner element, appended with a '.' for this |
| 83 /// object's name to be appended. | 88 /// object's name to be appended. |
| 84 String get ownerPrefix => owner.docName != '' ? owner.docName + '.' : ''; | 89 String get ownerPrefix => owner.docName != '' ? owner.docName + '.' : ''; |
| 85 | 90 |
| 86 /// The prefix String to refer to the package that this item is in, for URLs | 91 /// The prefix String to refer to the package that this item is in, for URLs |
| 87 /// and comment resolution. | 92 /// and comment resolution. |
| 88 /// | 93 /// |
| 89 /// The prefix can be prepended to a qualified name to get a fully unique | 94 /// The prefix can be prepended to a qualified name to get a fully unique |
| 90 /// name among all packages. | 95 /// name among all packages. |
| 91 String get packagePrefix; | 96 String get packagePrefix; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 111 | 116 |
| 112 /// The simple name to refer to this item. | 117 /// The simple name to refer to this item. |
| 113 String get name => dart2js_util.nameOf(mirror); | 118 String get name => dart2js_util.nameOf(mirror); |
| 114 | 119 |
| 115 /// Accessor to the parent item that owns this item. | 120 /// Accessor to the parent item that owns this item. |
| 116 /// | 121 /// |
| 117 /// "Owning" is defined as the object one scope-level above which this item | 122 /// "Owning" is defined as the object one scope-level above which this item |
| 118 /// is defined. Ex: The owner for a top level class, would be its enclosing | 123 /// is defined. Ex: The owner for a top level class, would be its enclosing |
| 119 /// library. The owner of a local variable in a method would be the enclosing | 124 /// library. The owner of a local variable in a method would be the enclosing |
| 120 /// method. | 125 /// method. |
| 121 Indexable get owner => new DummyMirror(mirror.owner); | 126 Indexable get owner; |
| 122 | 127 |
| 123 /// Generates MDN comments from database.json. | 128 /// Generates MDN comments from database.json. |
| 124 String getMdnComment(); | 129 String getMdnComment(); |
| 125 | 130 |
| 126 /// The type of this member to be used in index.txt. | 131 /// The type of this member to be used in index.txt. |
| 127 String get typeName; | 132 String get typeName; |
| 128 | 133 |
| 129 /// Creates a [Map] with this [Indexable]'s name and a preview comment. | 134 /// Creates a [Map] with this [Indexable]'s name and a preview comment. |
| 130 Map get previewMap { | 135 Map get previewMap { |
| 131 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; | 136 var finalMap = { 'name' : name, 'qualifiedName' : qualifiedName }; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 /// Return a map representation of this type. | 189 /// Return a map representation of this type. |
| 185 Map toMap(); | 190 Map toMap(); |
| 186 | 191 |
| 187 /// Accessor to determine if this item and all of its owners are visible. | 192 /// Accessor to determine if this item and all of its owners are visible. |
| 188 bool get isVisible => isFullChainVisible(this); | 193 bool get isVisible => isFullChainVisible(this); |
| 189 | 194 |
| 190 /// Returns true if [mirror] is the correct type of mirror that this Docgen | 195 /// Returns true if [mirror] is the correct type of mirror that this Docgen |
| 191 /// object wraps. (Workaround for the fact that Types are not first class.) | 196 /// object wraps. (Workaround for the fact that Types are not first class.) |
| 192 bool isValidMirror(DeclarationMirror mirror); | 197 bool isValidMirror(DeclarationMirror mirror); |
| 193 } | 198 } |
| 199 |
| 200 /// Index of all the dart2js mirrors examined to corresponding MirrorBased |
| 201 /// docgen objects. |
| 202 /// |
| 203 /// Used for lookup because of the dart2js mirrors exports |
| 204 /// issue. The second level map is indexed by owner docName for faster lookup. |
| 205 /// Why two levels of lookup? Speed, man. Speed. |
| 206 final Map<String, Map<String, Indexable>> _mirrorToDocgen = |
| 207 new Map<String, Map<String, Indexable>>(); |
| 208 |
| 209 Iterable<Indexable> get allIndexables => |
| 210 _mirrorToDocgen.values.expand((map) => map.values); |
| 211 |
| 212 Map<String, Indexable> lookupIndexableMap(DeclarationMirror mirror) { |
| 213 return _mirrorToDocgen[dart2js_util.qualifiedNameOf(mirror)]; |
| 214 } |
| OLD | NEW |