Skip to content

Commit fa37be7

Browse files
committed
write a JSON index of all elements
1 parent a09867b commit fa37be7

File tree

4 files changed

+140
-34
lines changed

4 files changed

+140
-34
lines changed

lib/src/html_generator.dart

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
library dartdoc.html_generator;
66

77
import 'dart:async' show Future;
8-
import 'dart:io';
8+
import 'dart:io' show Directory, File;
9+
import 'dart:convert' show JSON;
910
import 'dart:typed_data' show Uint8List;
1011

1112
import 'package:mustache4dart/mustache4dart.dart';
@@ -17,6 +18,7 @@ import 'resources.g.dart' as resources;
1718
import '../generator.dart';
1819
import '../markdown_processor.dart';
1920
import '../resource_loader.dart' as loader;
21+
import 'io_utils.dart' show createOutputFile;
2022

2123
String dartdocVersion = 'unknown';
2224

@@ -156,7 +158,7 @@ class HtmlGeneratorInstance {
156158
final Package package;
157159
final Directory out;
158160

159-
final List<String> _htmlFiles = [];
161+
final List<ModelElement> documentedElements = [];
160162

161163
HtmlGeneratorInstance(this.url, this._templates, this.package, this.out);
162164

@@ -166,13 +168,25 @@ class HtmlGeneratorInstance {
166168

167169
if (package != null) {
168170
_generateDocs();
171+
_generateJson();
172+
// TODO: generate sitemap
169173
}
170174

171-
//if (url != null) generateSiteMap();
172-
173175
await _copyResources();
174176
}
175177

178+
void _generateJson() {
179+
File jsonFile = createOutputFile(out, 'index.json');
180+
String json = JSON.encode(documentedElements.map((ModelElement e) {
181+
Map data = {'name': e.name, 'href': e.href};
182+
if (e is EnclosedElement) {
183+
data['enclosedElementName'] =
184+
(e as EnclosedElement).enclosingElement.name;
185+
}
186+
}).toList());
187+
jsonFile.writeAsStringSync(json);
188+
}
189+
176190
void _generateDocs() {
177191
if (package == null) return;
178192

@@ -354,22 +368,16 @@ class HtmlGeneratorInstance {
354368
}
355369
}
356370

357-
File _createOutputFile(String filename) {
358-
File f = new File(path.join(out.path, filename));
359-
if (!f.existsSync()) f.createSync(recursive: true);
360-
_htmlFiles.add(filename);
361-
return f;
362-
}
363-
364371
void _build(String filename, TemplateRenderer template, TemplateData data) {
365372
String content = template(data,
366373
assumeNullNonExistingProperty: false, errorOnMissingProperty: true);
367374

368375
_writeFile(filename, content);
376+
if (data.self is ModelElement) documentedElements.add(data.self);
369377
}
370378

371379
void _writeFile(String filename, String content) {
372-
File f = _createOutputFile(filename);
380+
File f = createOutputFile(out, filename);
373381
f.writeAsStringSync(content);
374382
}
375383
}

lib/src/io_utils.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ import 'dart:io';
99

1010
import 'package:path/path.dart' as path;
1111

12+
File createOutputFile(Directory destination, String filename) {
13+
File f = new File(path.join(destination.path, filename));
14+
if (!f.existsSync()) f.createSync(recursive: true);
15+
return f;
16+
}
17+
1218
/// Lists the contents of [dir].
1319
///
1420
/// If [recursive] is `true`, lists subdirectory contents (defaults to `false`).

lib/src/model.dart

Lines changed: 74 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,21 @@
55
/// The models used to represent Dart code
66
library dartdoc.models;
77

8-
import 'package:analyzer/src/generated/ast.dart';
8+
import 'package:analyzer/src/generated/ast.dart' show AnnotatedNode, Annotation;
99
import 'package:analyzer/src/generated/element.dart';
10-
import 'package:analyzer/src/generated/resolver.dart';
10+
import 'package:analyzer/src/generated/resolver.dart'
11+
show Namespace, NamespaceBuilder, InheritanceManager, MemberMap;
1112
import 'package:analyzer/src/generated/utilities_dart.dart' show ParameterKind;
12-
import 'package:quiver/core.dart';
13+
import 'package:quiver/core.dart' show hash3;
1314

14-
import 'html_utils.dart';
15-
import 'model_utils.dart';
16-
import 'package_meta.dart';
15+
import 'html_utils.dart' show stripComments, htmlEscape;
16+
import 'model_utils.dart' show isPrivate, isPublic, getAllSupertypes;
17+
import 'package_meta.dart' show PackageMeta, FileContents;
1718

18-
import '../markdown_processor.dart';
19+
import '../markdown_processor.dart' show Documentation, renderMarkdownToHtml;
1920

20-
int byName(a, b) => a.name.toUpperCase().compareTo(b.name.toUpperCase());
21+
int byName(Nameable a, Nameable b) =>
22+
a.name.toUpperCase().compareTo(b.name.toUpperCase());
2123

2224
final Map<Class, List<Class>> _implementors = new Map();
2325

@@ -48,7 +50,19 @@ void _addToImplementors(Class c) {
4850
}
4951
}
5052

51-
abstract class ModelElement implements Comparable {
53+
/// An element that is enclosed by some other element.
54+
///
55+
/// Libraries are not enclosed.
56+
abstract class EnclosedElement {
57+
ModelElement get enclosingElement;
58+
}
59+
60+
/// Something that has a name.
61+
abstract class Nameable {
62+
String get name;
63+
}
64+
65+
abstract class ModelElement implements Comparable, Nameable {
5266
final Element element;
5367
final Library library;
5468

@@ -359,14 +373,17 @@ abstract class ModelElement implements Comparable {
359373
}
360374
}
361375

376+
// TODO: how do we get rid of this class?
362377
class Dynamic extends ModelElement {
363378
Dynamic(DynamicElementImpl element, Library library)
364379
: super(element, library);
365380

381+
ModelElement get enclosingElement => throw new UnsupportedError('');
382+
366383
String get _href => throw new StateError('dynamic should not have an href');
367384
}
368385

369-
class Package {
386+
class Package implements Nameable {
370387
final List<Library> _libraries = [];
371388
final PackageMeta packageMeta;
372389
String _docsAsHtml;
@@ -503,6 +520,9 @@ class Library extends ModelElement {
503520
return library;
504521
}
505522

523+
/// Libraries are not enclosed by anything.
524+
ModelElement get enclosingElement => null;
525+
506526
Library get library => this;
507527

508528
Iterable<Element> get _exportedNamespace {
@@ -729,7 +749,7 @@ class Library extends ModelElement {
729749
String get _href => '$dirName/$fileName';
730750
}
731751

732-
class Class extends ModelElement {
752+
class Class extends ModelElement implements EnclosedElement {
733753
List<ElementType> _mixins;
734754
ElementType _supertype;
735755
List<ElementType> _interfaces;
@@ -797,6 +817,9 @@ class Class extends ModelElement {
797817
}).where((it) => it != null).toList(growable: false);
798818
}
799819

820+
/// Returns the library that encloses this element.
821+
ModelElement get enclosingElement => library;
822+
800823
String get nameWithGenerics {
801824
if (!modelType.isParameterizedType) return name;
802825
return '$name&lt${_typeParameters.map((t) => t.name).join(', ')}&gt';
@@ -1271,12 +1294,16 @@ abstract class SourceCodeMixin {
12711294
Element get element;
12721295
}
12731296

1274-
class ModelFunction extends ModelElement with SourceCodeMixin {
1297+
class ModelFunction extends ModelElement
1298+
with SourceCodeMixin
1299+
implements EnclosedElement {
12751300
ModelFunction(FunctionElement element, Library library)
12761301
: super(element, library) {
12771302
_modelType = new ElementType(_func.type, this);
12781303
}
12791304

1305+
ModelElement get enclosingElement => library;
1306+
12801307
FunctionElement get _func => (element as FunctionElement);
12811308

12821309
bool get isStatic => _func.isStatic;
@@ -1289,7 +1316,7 @@ class ModelFunction extends ModelElement with SourceCodeMixin {
12891316
String get _href => '${library.dirName}/$fileName';
12901317
}
12911318

1292-
class Typedef extends ModelElement {
1319+
class Typedef extends ModelElement implements EnclosedElement {
12931320
FunctionTypeAliasElement get _typedef =>
12941321
(element as FunctionTypeAliasElement);
12951322

@@ -1300,6 +1327,9 @@ class Typedef extends ModelElement {
13001327
}
13011328
}
13021329

1330+
@override
1331+
ModelElement get enclosingElement => library;
1332+
13031333
String get fileName => '$name.html';
13041334

13051335
String get linkedReturnType => modelType != null
@@ -1309,7 +1339,7 @@ class Typedef extends ModelElement {
13091339
String get _href => '${library.dirName}/$fileName';
13101340
}
13111341

1312-
class Field extends ModelElement {
1342+
class Field extends ModelElement implements EnclosedElement {
13131343
String _constantValue;
13141344
bool _isInherited = false;
13151345

@@ -1325,6 +1355,10 @@ class Field extends ModelElement {
13251355
_setModelType();
13261356
}
13271357

1358+
@override
1359+
ModelElement get enclosingElement =>
1360+
new ModelElement.from(_field.enclosingElement, library);
1361+
13281362
@override
13291363
String get _computeDocumentationComment {
13301364
var buffer = new StringBuffer();
@@ -1436,12 +1470,16 @@ class EnumField extends Field {
14361470
String get linkedName => name;
14371471
}
14381472

1439-
class Constructor extends ModelElement {
1473+
class Constructor extends ModelElement implements EnclosedElement {
14401474
ConstructorElement get _constructor => (element as ConstructorElement);
14411475

14421476
Constructor(ConstructorElement element, Library library)
14431477
: super(element, library);
14441478

1479+
@override
1480+
ModelElement get enclosingElement =>
1481+
new ModelElement.from(_constructor.enclosingElement, library);
1482+
14451483
@override
14461484
String get _href =>
14471485
'${library.dirName}/${_constructor.enclosingElement.name}/$name.html';
@@ -1468,7 +1506,9 @@ class Constructor extends ModelElement {
14681506
}
14691507
}
14701508

1471-
class Method extends ModelElement with SourceCodeMixin {
1509+
class Method extends ModelElement
1510+
with SourceCodeMixin
1511+
implements EnclosedElement {
14721512
bool _isInherited = false;
14731513

14741514
MethodElement get _method => (element as MethodElement);
@@ -1483,6 +1523,10 @@ class Method extends ModelElement with SourceCodeMixin {
14831523
_isInherited = true;
14841524
}
14851525

1526+
@override
1527+
ModelElement get enclosingElement =>
1528+
new ModelElement.from(_method.enclosingElement, library);
1529+
14861530
Method get overriddenElement {
14871531
ClassElement parent = element.enclosingElement;
14881532
for (InterfaceType t in getAllSupertypes(parent)) {
@@ -1563,12 +1607,16 @@ class Operator extends Method {
15631607
}
15641608

15651609
/// Getters and setters.
1566-
class Accessor extends ModelElement {
1610+
class Accessor extends ModelElement implements EnclosedElement {
15671611
PropertyAccessorElement get _accessor => (element as PropertyAccessorElement);
15681612

15691613
Accessor(PropertyAccessorElement element, Library library)
15701614
: super(element, library);
15711615

1616+
@override
1617+
ModelElement get enclosingElement =>
1618+
new ModelElement.from(_accessor.enclosingElement, library);
1619+
15721620
bool get isGetter => _accessor.isGetter;
15731621

15741622
@override
@@ -1577,7 +1625,7 @@ class Accessor extends ModelElement {
15771625
}
15781626

15791627
/// Top-level variables. But also picks up getters and setters?
1580-
class TopLevelVariable extends ModelElement {
1628+
class TopLevelVariable extends ModelElement implements EnclosedElement {
15811629
TopLevelVariableElement get _variable => (element as TopLevelVariableElement);
15821630

15831631
TopLevelVariable(TopLevelVariableElement element, Library library)
@@ -1594,6 +1642,9 @@ class TopLevelVariable extends ModelElement {
15941642
}
15951643
}
15961644

1645+
@override
1646+
ModelElement get enclosingElement => library;
1647+
15971648
bool get isFinal => _variable.isFinal;
15981649

15991650
bool get isConst => _variable.isConst;
@@ -1631,14 +1682,18 @@ class TopLevelVariable extends ModelElement {
16311682
String get _href => '${library.dirName}/${name}.html';
16321683
}
16331684

1634-
class Parameter extends ModelElement {
1685+
class Parameter extends ModelElement implements EnclosedElement {
16351686
Parameter(ParameterElement element, Library library)
16361687
: super(element, library) {
16371688
var t = _parameter.type;
16381689
_modelType = new ElementType(
16391690
t, new ModelElement.from(t.element, package._getLibraryFor(t.element)));
16401691
}
16411692

1693+
@override
1694+
ModelElement get enclosingElement =>
1695+
new ModelElement.from(_parameter.enclosingElement, library);
1696+
16421697
ParameterElement get _parameter => element as ParameterElement;
16431698

16441699
bool get isOptional => _parameter.parameterKind.isOptional;

0 commit comments

Comments
 (0)