diff --git a/bin/dartdoc.dart b/bin/dartdoc.dart index 41b32f7f9c..0645c14e85 100644 --- a/bin/dartdoc.dart +++ b/bin/dartdoc.dart @@ -121,7 +121,7 @@ main(List arguments) async { try { DartDocResults results = await dartdoc.generateDocs(); - print('\nSuccess! Open file://${results.outDir.absolute.path}/index.html'); + print('\nSuccess! Docs generated into ${results.outDir.absolute.path}'); } catch (e, st) { if (e is DartDocFailure) { stderr.writeln('Generation failed: ${e}.'); @@ -152,23 +152,27 @@ ArgParser _createArgsParser() { parser.addFlag('version', help: 'Display the version for $name.', negatable: false); parser.addOption('dart-sdk', - help: "Location of the Dart SDK. Use if SDK isn't automatically located."); + help: + "Location of the Dart SDK. Use if SDK isn't automatically located."); parser.addFlag('sdk-docs', help: 'Generate ONLY the docs for the Dart SDK.', negatable: false); parser.addOption('sdk-readme', - help: 'Path to the SDK description file. Use if generating Dart SDK docs.'); + help: + 'Path to the SDK description file. Use if generating Dart SDK docs.'); parser.addOption('input', help: 'Path to source directory', defaultsTo: Directory.current.path); parser.addOption('output', help: 'Path to output directory.', defaultsTo: defaultOutDir); parser.addOption('header', - help: 'path to file containing HTML text, inserted into the header of every page.'); + help: + 'path to file containing HTML text, inserted into the header of every page.'); parser.addOption('footer', - help: 'path to file containing HTML text, inserted into the footer of every page.'); + help: + 'path to file containing HTML text, inserted into the footer of every page.'); parser.addOption('package-root', help: 'The path to the package root.'); parser.addOption('url-mapping', help: '--url-mapping=libraryUri,/path/to/library.dart directs dartdoc to ' - 'use "library.dart" as the source for an import of "libraryUri"', + 'use "library.dart" as the source for an import of "libraryUri"', allowMultiple: true, splitCommas: false); parser.addOption('exclude', @@ -176,7 +180,8 @@ ArgParser _createArgsParser() { parser.addOption('include', help: 'Comma-separated list of library names to generate docs for.'); parser.addOption('hosted-url', - help: 'URL where the docs will be hosted (used to generate the sitemap).'); + help: + 'URL where the docs will be hosted (used to generate the sitemap).'); return parser; } diff --git a/lib/resources/script.js b/lib/resources/script.js index a92277d85a..4a62ba683b 100644 --- a/lib/resources/script.js +++ b/lib/resources/script.js @@ -187,6 +187,9 @@ function initSearch() { searchIndex = JSON.parse(jsonReq.responseText); initTypeahead(); }); + jsonReq.addEventListener('error', function() { + $('#search-box').prop('placeholder', 'Error loading search index'); + }); jsonReq.send(); } diff --git a/lib/resources/styles.css b/lib/resources/styles.css index 5a36cff901..34d2e04acd 100644 --- a/lib/resources/styles.css +++ b/lib/resources/styles.css @@ -51,7 +51,7 @@ nav .container { } header { - background-color: #2196F3; + background-color: rgb(0, 102, 152); color: white; box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.37); } @@ -138,7 +138,7 @@ p.no-docs { } a, a:hover { - color: #1976D2; + color: rgb(0, 102, 152); } pre.prettyprint { diff --git a/lib/src/html_generator.dart b/lib/src/html_generator.dart index 32f20b55fc..b437c1736d 100644 --- a/lib/src/html_generator.dart +++ b/lib/src/html_generator.dart @@ -97,7 +97,9 @@ class Templates { 'source_code', 'sidebar_for_library', 'name_link', - 'has_more_docs' + 'has_more_docs', + 'accessor_getter', + 'accessor_setter' ]; for (String partial in partials) { diff --git a/lib/src/model.dart b/lib/src/model.dart index efd3d4ef06..ea1a4e8fa6 100644 --- a/lib/src/model.dart +++ b/lib/src/model.dart @@ -141,6 +141,12 @@ abstract class ModelElement implements Comparable, Nameable, Documentable { String get _computeDocumentationComment => element.computeDocumentationComment(); + /// Returns the docs, stripped of their + /// leading comments syntax. + /// + /// This getter will walk up the inheritance hierarchy + /// to find docs, if the current class doesn't have docs + /// for this element. String get documentation { if (_rawDocs != null) return _rawDocs; @@ -1384,8 +1390,8 @@ class Field extends ModelElement bool get hasSetter => _field.setter != null; - PropertyAccessorElement get getter => _field.getter; - PropertyAccessorElement get setter => _field.setter; + PropertyAccessorElement get _getter => _field.getter; + PropertyAccessorElement get _setter => _field.setter; String computeDocumentationComment() => _field.computeDocumentationComment(); @@ -1610,38 +1616,40 @@ class Accessor extends ModelElement implements EnclosedElement { abstract class GetterSetterCombo { bool get hasGetter; bool get hasSetter; + Library get library; - PropertyAccessorElement get getter; - PropertyAccessorElement get setter; + PropertyAccessorElement get _getter; + PropertyAccessorElement get _setter; - String computeDocumentationComment(); + Accessor get getter { + return _getter == null ? null : new ModelElement.from(_getter, library); + } + + Accessor get setter { + return _setter == null ? null : new ModelElement.from(_setter, library); + } + // TODO: now that we have explicit getter and setters, we probably + // want a cleaner way to do this. Only the one-liner is using this + // now. The detail pages should be using getter and setter directly. String get _computeDocumentationComment { var buffer = new StringBuffer(); if (hasGetter) { - String docs = stripComments(getter.computeDocumentationComment()); + String docs = stripComments(_getter.computeDocumentationComment()); if (docs != null) buffer.write(docs); } - if (hasSetter && !setter.isSynthetic) { - String docs = stripComments(setter.computeDocumentationComment()); + if (hasSetter && !_setter.isSynthetic) { + String docs = stripComments(_setter.computeDocumentationComment()); if (docs != null) { if (buffer.isNotEmpty) buffer.write('\n\n'); buffer.write(docs); } } - if (buffer.isNotEmpty) return buffer.toString(); - - // TODO: check that we'd ever get here. Doesn't seem like we would. - // This is old. - return computeDocumentationComment(); + return buffer.toString(); } - - String get getterDocsAsHtml => ''; - - String get setterDocsAsHtml => ''; } /// Top-level variables. But also picks up getters and setters? @@ -1685,8 +1693,8 @@ class TopLevelVariable extends ModelElement bool get hasGetter => _variable.getter != null; bool get hasSetter => _variable.setter != null; - PropertyAccessorElement get getter => _variable.getter; - PropertyAccessorElement get setter => _variable.setter; + PropertyAccessorElement get _getter => _variable.getter; + PropertyAccessorElement get _setter => _variable.setter; String computeDocumentationComment() { return _variable.computeDocumentationComment(); diff --git a/lib/templates/_accessor_getter.html b/lib/templates/_accessor_getter.html new file mode 100644 index 0000000000..123bc635b4 --- /dev/null +++ b/lib/templates/_accessor_getter.html @@ -0,0 +1,9 @@ +
+ +
+ {{{ linkedReturnType }}} + {{>name_summary}} +
+ +{{>documentation}} +
diff --git a/lib/templates/_accessor_setter.html b/lib/templates/_accessor_setter.html new file mode 100644 index 0000000000..1e0b9e230f --- /dev/null +++ b/lib/templates/_accessor_setter.html @@ -0,0 +1,9 @@ +
+ +
+ void + {{>name_summary}}({{{ linkedParamsNoMetadata }}}) +
+ +{{>documentation}} +
diff --git a/lib/templates/property.html b/lib/templates/property.html index c046e4a766..5ba78778de 100644 --- a/lib/templates/property.html +++ b/lib/templates/property.html @@ -11,18 +11,13 @@
{{name}}
-
- {{#property}} - {{{ linkedReturnType }}} - {{>name_summary}} - - {{>readable_writable}} - {{/property}} -
- - {{#property}} - {{>documentation}} - {{/property}} + {{#property.getter}} + {{>accessor_getter}} + {{/property.getter}} + + {{#property.setter}} + {{>accessor_setter}} + {{/property.setter}}
diff --git a/lib/templates/top_level_property.html b/lib/templates/top_level_property.html index f744bb0350..753284043e 100644 --- a/lib/templates/top_level_property.html +++ b/lib/templates/top_level_property.html @@ -9,18 +9,13 @@
{{name}}
-
- {{#property}} - {{{ linkedReturnType }}} - {{>name_summary}} + {{#property.getter}} + {{>accessor_getter}} + {{/property.getter}} - {{>readable_writable}} - {{/property}} -
- - {{#property}} - {{>documentation}} - {{/property}} + {{#property.setter}} + {{>accessor_setter}} + {{/property.setter}}
diff --git a/test/model_test.dart b/test/model_test.dart index 0e828cae1c..557c6187a8 100644 --- a/test/model_test.dart +++ b/test/model_test.dart @@ -845,6 +845,45 @@ String topLevelFunction(int param1, bool param2, Cool coolBeans, () { expect(sFromApple.documentationAsHtml.contains('/**'), isFalse); }); + + test('explicit getter/setter has a getter accessor', () { + expect(lengthX.getter, isNotNull); + expect(lengthX.getter.name, equals('lengthX')); + }); + + test('explicit getter/setter has a setter accessor', () { + expect(lengthX.setter, isNotNull); + expect(lengthX.setter.name, equals('lengthX=')); + }); + + test('a stand-alone setter does not have a getter', () { + expect(onlySetter.getter, isNull); + }); + }); + + group('Accessor', () { + Accessor onlyGetterGetter, + onlyGetterSetter, + onlySetterGetter, + onlySetterSetter; + + setUp(() { + TopLevelVariable justGetter = + fakeLibrary.properties.firstWhere((p) => p.name == 'justGetter'); + onlyGetterGetter = justGetter.getter; + onlyGetterSetter = justGetter.setter; + TopLevelVariable justSetter = + fakeLibrary.properties.firstWhere((p) => p.name == 'justSetter'); + onlySetterSetter = justSetter.setter; + onlySetterGetter = justSetter.getter; + }); + + test('are available on top-level variables', () { + expect(onlyGetterGetter.name, equals('justGetter')); + expect(onlyGetterSetter, isNull); + expect(onlySetterGetter, isNull); + expect(onlySetterSetter.name, equals('justSetter=')); + }); }); group('Top-level Variable', () { @@ -879,12 +918,12 @@ String topLevelFunction(int param1, bool param2, Cool coolBeans, expect(v3.linkedReturnType, 'dynamic'); }); - test('getter documentation', () { + test('just a getter has documentation', () { expect(justGetter.documentation, equals('Just a getter. No partner setter.')); }); - test('setter documentation', () { + test('just a setter has documentation', () { expect(justSetter.documentation, equals('Just a setter. No partner getter.')); }); @@ -893,6 +932,16 @@ String topLevelFunction(int param1, bool param2, Cool coolBeans, expect(setAndGet.documentation, contains('The getter for setAndGet.')); expect(setAndGet.documentation, contains('The setter for setAndGet.')); }); + + test('has a getter accessor', () { + expect(setAndGet.getter, isNotNull); + expect(setAndGet.getter.name, equals('setAndGet')); + }); + + test('has a setter accessor', () { + expect(setAndGet.setter, isNotNull); + expect(setAndGet.setter.name, equals('setAndGet=')); + }); }); group('Constant', () {