22// for details. All rights reserved. Use of this source code is governed by a
33// BSD-style license that can be found in the LICENSE file.
44
5- import 'package:dartdoc/src/model/model_element.dart' ;
5+ import 'package:dartdoc/src/comment_references/parser.dart' ;
6+ import 'package:dartdoc/src/failure.dart' ;
7+ import 'package:meta/meta.dart' ;
68
7- const _html = 'html' ;
8- const _md = 'md' ;
9+ import '../model/model.dart' ;
910
10- enum FileStructureMode {
11- htmlOriginal,
12- mdOriginal,
13- }
11+ const _validFormats = {'html' , 'md' };
1412
1513/// This class defines an interface to allow [ModelElement] s and [Generator] s
1614/// to get information about the desired on-disk representation of a single
@@ -20,22 +18,58 @@ enum FileStructureMode {
2018/// to lay them out on disk, and how to link different pages in the structure
2119/// together.
2220abstract class FileStructure {
23- factory FileStructure (FileStructureMode mode, ModelElement modelElement) {
24- switch (mode) {
25- case FileStructureMode .htmlOriginal:
26- return _FileStructureHtml (modelElement);
27- case FileStructureMode .mdOriginal:
28- return _FileStructureMd (modelElement);
21+ factory FileStructure .fromDocumentable (Documentable documentable) {
22+ if (! _validFormats.contains (documentable.config.format)) {
23+ throw DartdocFailure (
24+ 'Internal error: unrecognized config.format: ${documentable .config .format }' );
25+ }
26+ switch (documentable) {
27+ case LibraryContainer ():
28+ // [LibraryContainer]s are not ModelElements, but have documentation.
29+ return FileStructure ._fromLibraryContainer (documentable);
30+ case ModelElement ():
31+ // This should be the common case.
32+ return FileStructure ._fromModelElement (documentable);
33+ default :
34+ throw UnimplementedError (
35+ 'Tried to build a FileStructure for an unknown subtype of Documentable: ${documentable .runtimeType }' );
36+ }
37+ }
38+
39+ factory FileStructure ._fromLibraryContainer (
40+ LibraryContainer libraryContainer) {
41+ final format = libraryContainer.config.format;
42+ switch (libraryContainer) {
43+ case Category ():
44+ return FileStructureImpl (format, libraryContainer.name, 'topic' );
45+ case Package ():
46+ return FileStructureImpl (format, 'index' , null );
47+ default :
48+ throw UnimplementedError (
49+ 'Unrecognized LibraryContainer subtype: ${libraryContainer .runtimeType }' );
2950 }
3051 }
3152
32- /// Link to the [ModelElement] the information for this [FileStructure]
33- /// applies to.
34- // TODO(jcollins): consider not carrying a reference to a ModelElement and
35- // calculating necessary bits at construction time. Might be challenging
36- // if we want to calculate [hasIndependentFile] based on documentation
37- // length or other variables not always available.
38- ModelElement get modelElement;
53+ factory FileStructure ._fromModelElement (ModelElement modelElement) {
54+ final format = modelElement.config.format;
55+ switch (modelElement) {
56+ case Library ():
57+ return FileStructureImpl (format, modelElement.dirName, 'library' );
58+ case Mixin ():
59+ return FileStructureImpl (format, modelElement.name, 'mixin' );
60+ case Class ():
61+ return FileStructureImpl (format, modelElement.name, 'class' );
62+ case Operator ():
63+ return FileStructureImpl (format,
64+ 'operator_${operatorNames [modelElement .referenceName ]}' , null );
65+ case GetterSetterCombo ():
66+ return FileStructureImpl (format, modelElement.name,
67+ modelElement.isConst ? 'constant' : null );
68+ default :
69+ return FileStructureImpl (
70+ modelElement.config.format, modelElement.name, null );
71+ }
72+ }
3973
4074 /// True if an independent file should be created for this `ModelElement` .
4175 bool get hasIndependentFile;
@@ -62,50 +96,40 @@ abstract class FileStructure {
6296 String get fileType;
6397}
6498
65- class _FileStructureHtml implements FileStructure {
66- _FileStructureHtml (this .modelElement);
67-
68- @override
69- // TODO: implement fileName
70- String get fileName => throw UnimplementedError ();
71-
72- @override
73- String get fileType => _html;
74-
75- @override
76- // TODO: implement hasIndependentFile
77- bool get hasIndependentFile => throw UnimplementedError ();
78-
79- @override
80- // TODO: implement href
81- String get href => throw UnimplementedError ();
82-
99+ @visibleForTesting
100+ class FileStructureImpl implements FileStructure {
83101 @override
84- // TODO: implement htmlId
85- String get htmlId => throw UnimplementedError ();
102+ final String fileType;
86103
87- @override
88- final ModelElement modelElement;
104+ /// This is a name for the underlying [Documentable] that is free of
105+ /// characters that can not appear in a path (URI, Unix, or Windows).
106+ String pathSafeName;
89107
90- @override
91- // TODO: implement dirName
92- String get dirName => throw UnimplementedError ();
93- }
108+ /// This is a string to disambiguate the filename of the underlying
109+ /// [Documentable] from other files with the same [pathSafeName] in the
110+ /// same directory and is composed with [pathSafeName] to generate [fileName] .
111+ /// It is usually based on [ModelElement.kind] , e.g. `'class'` . If null, no
112+ /// disambiguating string will be added.
113+ // TODO(jcollins-g): Legacy layout doesn't always include this; move toward
114+ // always having a disambiguating string.
115+ final String ? kindAddition;
94116
95- class _FileStructureMd implements FileStructure {
96- _FileStructureMd (this .modelElement);
117+ FileStructureImpl (this .fileType, this .pathSafeName, this .kindAddition);
97118
98119 @override
99- // TODO: implement fileName
100- String get fileName => throw UnimplementedError ();
101120
102- @override
103- // TODO: implement fileType
104- String get fileType => _md;
121+ /// Initial implementation is bug-for-bug compatible with pre-extraction
122+ /// dartdoc. This means that some types will have kindAdditions, and
123+ /// some will not. See [FileStructure._fromModelElement] .
124+ String get fileName {
125+ if (kindAddition != null ) {
126+ return '$pathSafeName -$kindAddition .$fileType ' ;
127+ }
128+ return '$pathSafeName .$fileType ' ;
129+ }
105130
106131 @override
107- // TODO: implement hasIndependentFile
108- bool get hasIndependentFile => throw UnimplementedError ();
132+ bool get hasIndependentFile => true ;
109133
110134 @override
111135 // TODO: implement href
@@ -115,9 +139,6 @@ class _FileStructureMd implements FileStructure {
115139 // TODO: implement htmlId
116140 String get htmlId => throw UnimplementedError ();
117141
118- @override
119- final ModelElement modelElement;
120-
121142 @override
122143 // TODO: implement dirName
123144 String get dirName => throw UnimplementedError ();
0 commit comments