@@ -134,82 +134,66 @@ class ToolConfiguration {
134
134
for (var entry in yamlMap.entries) {
135
135
var name = entry.key.toString ();
136
136
var toolMap = entry.value;
137
- String ? description;
138
- List <String >? compileArgs;
139
- List <String >? command;
140
- List <String >? setupCommand;
141
- if (toolMap is Map ) {
142
- description = toolMap['description' ].toString ();
143
- List <String >? findCommand ([String prefix = '' ]) {
144
- List <String >? command;
145
- // If the command key is given, then it applies to all platforms.
146
- var commandFromKey = toolMap.containsKey ('${prefix }command' )
147
- ? '${prefix }command'
148
- : '$prefix ${Platform .operatingSystem }' ;
149
- if (toolMap.containsKey (commandFromKey)) {
150
- var commandFrom = toolMap[commandFromKey] as YamlNode ;
151
- if (commandFrom.value is String ) {
152
- command = [commandFrom.toString ()];
153
- if (command[0 ].isEmpty) {
154
- throw DartdocOptionError (
155
- 'Tool commands must not be empty. Tool $name command entry '
156
- '"$commandFromKey " must contain at least one path.' );
157
- }
158
- } else if (commandFrom is YamlList ) {
159
- command =
160
- commandFrom.map <String >((node) => node.toString ()).toList ();
161
- if (command.isEmpty) {
162
- throw DartdocOptionError (
163
- 'Tool commands must not be empty. Tool $name command entry '
164
- '"$commandFromKey " must contain at least one path.' );
165
- }
166
- } else {
167
- throw DartdocOptionError (
168
- 'Tool commands must be a path to an executable, or a list of '
169
- 'strings that starts with a path to an executable. '
170
- 'The tool $name has a $commandFromKey entry that is a '
171
- '${commandFrom .runtimeType }' );
172
- }
173
- }
174
- return command;
175
- }
176
-
177
- command = findCommand ();
178
- setupCommand = findCommand ('setup_' );
179
-
180
- List <String >? findArgs () {
181
- List <String >? args;
182
- if (toolMap.containsKey (compileArgsTagName)) {
183
- var compileArgs = toolMap[compileArgsTagName];
184
- if (compileArgs is String ) {
185
- args = [toolMap[compileArgsTagName].toString ()];
186
- } else if (compileArgs is YamlList ) {
187
- args = compileArgs
188
- .map <String >((node) => node.toString ())
189
- .toList (growable: false );
190
- } else {
191
- throw DartdocOptionError (
192
- 'Tool compile arguments must be a list of strings. The tool '
193
- '$name has a $compileArgsTagName entry that is a '
194
- '${compileArgs .runtimeType }' );
195
- }
196
- }
197
- return args;
198
- }
199
-
200
- compileArgs = findArgs ();
201
- } else {
137
+ if (toolMap is ! Map ) {
202
138
throw DartdocOptionError (
203
139
'Tools must be defined as a map of tool names to definitions. Tool '
204
140
'$name is not a map.' );
205
141
}
142
+
143
+ var description = toolMap['description' ].toString ();
144
+
145
+ List <String >? findCommand ([String prefix = '' ]) {
146
+ // If the command key is given, then it applies to all platforms.
147
+ var commandFromKey = toolMap.containsKey ('${prefix }command' )
148
+ ? '${prefix }command'
149
+ : '$prefix ${Platform .operatingSystem }' ;
150
+ if (! toolMap.containsKey (commandFromKey)) {
151
+ return null ;
152
+ }
153
+ var commandFrom = toolMap[commandFromKey] as YamlNode ;
154
+ List <String > command;
155
+ if (commandFrom.value is String ) {
156
+ command = [commandFrom.toString ()];
157
+ } else if (commandFrom is YamlList ) {
158
+ command = commandFrom.map ((node) => node.toString ()).toList ();
159
+ } else {
160
+ throw DartdocOptionError (
161
+ 'Tool commands must be a path to an executable, or a list of '
162
+ 'strings that starts with a path to an executable. The tool '
163
+ "'$name ' has a '$commandFromKey ' entry that is a "
164
+ '${commandFrom .runtimeType }' );
165
+ }
166
+ if (command.isEmpty || command[0 ].isEmpty) {
167
+ throw DartdocOptionError (
168
+ 'Tool commands must not be empty. Tool $name command entry '
169
+ '"$commandFromKey " must contain at least one path.' );
170
+ }
171
+ return command;
172
+ }
173
+
174
+ var command = findCommand ();
206
175
if (command == null ) {
207
176
throw DartdocOptionError (
208
177
'At least one of "command" or "${Platform .operatingSystem }" must '
209
178
'be defined for the tool $name .' );
210
179
}
211
-
212
- bool validateExecutable (String executable) {
180
+ var setupCommand = findCommand ('setup_' );
181
+
182
+ var rawCompileArgs = toolMap[compileArgsTagName];
183
+ var compileArgs = switch (rawCompileArgs) {
184
+ null => const < String > [],
185
+ String () => [toolMap[compileArgsTagName].toString ()],
186
+ YamlList () =>
187
+ rawCompileArgs.map ((node) => node.toString ()).toList (growable: false ),
188
+ _ => throw DartdocOptionError (
189
+ 'Tool compile arguments must be a list of strings. The tool '
190
+ "'$name ' has a '$compileArgsTagName ' entry that is a "
191
+ '${rawCompileArgs .runtimeType }' ,
192
+ ),
193
+ };
194
+
195
+ /// Validates [executable] and returns whether it is a Dart script.
196
+ bool isDartScript (String executable) {
213
197
var executableFile = resourceProvider.getFile (executable);
214
198
if (resourceProvider.isNotFound (executableFile)) {
215
199
throw DartdocOptionError ('Command executables must exist. '
@@ -230,24 +214,24 @@ class ToolConfiguration {
230
214
var executableRelativePath = command.removeAt (0 );
231
215
var executable = pathContext.canonicalize (
232
216
pathContext.join (canonicalYamlPath, executableRelativePath));
233
- validateExecutable (executable);
217
+ var isDartSetupScript = isDartScript (executable);
234
218
if (setupCommand != null ) {
235
219
var setupExecutableRelativePath = setupCommand.removeAt (0 );
236
220
var setupExecutable = pathContext.canonicalize (
237
221
pathContext.join (canonicalYamlPath, setupExecutableRelativePath));
238
- var isDartSetupCommand = validateExecutable (executable);
239
222
// Setup commands aren't snapshotted, since they're only run once.
240
- setupCommand = (isDartSetupCommand
241
- ? [Platform .resolvedExecutable, setupExecutable]
242
- : [setupExecutable]) +
243
- setupCommand;
223
+ setupCommand = [
224
+ if (isDartSetupScript) Platform .resolvedExecutable,
225
+ setupExecutable,
226
+ ...setupCommand,
227
+ ];
244
228
}
245
229
newToolDefinitions[name] = ToolDefinition .fromCommand (
246
- [executable] + command,
230
+ [executable, ... command] ,
247
231
setupCommand ?? const [],
248
232
description,
249
233
resourceProvider,
250
- compileArgs: compileArgs ?? const [] );
234
+ compileArgs: compileArgs);
251
235
}
252
236
return ToolConfiguration ._(newToolDefinitions, resourceProvider);
253
237
}
@@ -267,12 +251,19 @@ class _YamlFileData {
267
251
/// An enum to specify the multiple different kinds of data an option might
268
252
/// represent.
269
253
enum OptionKind {
270
- other, // Make no assumptions about the option data; it may be of any type
271
- // or semantic.
272
- file, // Option data references a filename or filenames with strings.
273
- dir, // Option data references a directory name or names with strings.
274
- glob, // Option data references globs with strings that may cover many
275
- // filenames and/or directories.
254
+ /// Make no assumptions about the option data; it may be of any type or
255
+ /// semantic.
256
+ other,
257
+
258
+ /// Option data references a filename or filenames with strings.
259
+ file,
260
+
261
+ /// Option data references a directory name or names with strings.
262
+ dir,
263
+
264
+ /// Option data references globs with strings that may cover many filenames
265
+ /// and/or directories.
266
+ glob,
276
267
}
277
268
278
269
/// Some DartdocOption subclasses need to keep track of where they
@@ -289,7 +280,7 @@ class _OptionValueWithContext<T> {
289
280
/// If non-null, the basename of the configuration file the value came from.
290
281
String ? definingFile;
291
282
292
- /// A [pathLib.Context] variable initialized with canonicalDirectoryPath.
283
+ /// A [pathLib.Context] variable initialized with ' canonicalDirectoryPath' .
293
284
p.Context pathContext;
294
285
295
286
/// Build a _OptionValueWithContext.
@@ -507,7 +498,6 @@ abstract class DartdocOption<T extends Object?> {
507
498
dynamic valueAt (Folder dir);
508
499
509
500
/// Calls [valueAt] with the working directory at the start of the program.
510
- // TODO(jcollins-g): use of dynamic. https://github.com/dart-lang/dartdoc/issues/2814
511
501
Object ? valueAtCurrent () => valueAt (_directoryCurrent);
512
502
513
503
late final Folder _directoryCurrent =
@@ -539,7 +529,7 @@ abstract class DartdocOption<T extends Object?> {
539
529
}
540
530
541
531
/// Get the immediate child of this node named [name] and its value at [dir] .
542
- U getValueAs <U extends Object ? >(String name, Folder dir) =>
532
+ U getValueAs <U >(String name, Folder dir) =>
543
533
_children[name]? .valueAt (dir) as U ;
544
534
545
535
/// Apply the function [visit] to [this] and all children.
@@ -556,19 +546,16 @@ abstract class DartdocOption<T extends Object?> {
556
546
class DartdocOptionFileSynth <T > extends DartdocOption <T >
557
547
with DartdocSyntheticOption <T >, _DartdocFileOption <T > {
558
548
@override
559
- final bool parentDirOverridesChild;
560
- @override
561
549
final T Function (DartdocSyntheticOption <T >, Folder ) _compute;
562
550
563
551
DartdocOptionFileSynth (
564
552
String name, this ._compute, ResourceProvider resourceProvider,
565
- {bool mustExist = false ,
566
- String help = '' ,
567
- OptionKind optionIs = OptionKind .other,
568
- this .parentDirOverridesChild = false ,
569
- ConvertYamlToType <T >? convertYamlToType})
570
- : super (name, null , help, optionIs, mustExist, convertYamlToType,
571
- resourceProvider);
553
+ {String help = '' })
554
+ : super (
555
+ name, null , help, OptionKind .other, false , null , resourceProvider);
556
+
557
+ @override
558
+ bool get parentDirOverridesChild => false ;
572
559
573
560
@override
574
561
T ? valueAt (Folder dir) {
@@ -580,7 +567,7 @@ class DartdocOptionFileSynth<T> extends DartdocOption<T>
580
567
}
581
568
582
569
@override
583
- void _onMissing (
570
+ Never _onMissing (
584
571
_OptionValueWithContext <T > valueWithContext, String missingPath) {
585
572
if (valueWithContext.definingFile != null ) {
586
573
_onMissingFromFiles (valueWithContext, missingPath);
@@ -597,11 +584,7 @@ class DartdocOptionArgSynth<T> extends DartdocOption<T>
597
584
@override
598
585
final String ? abbr;
599
586
@override
600
- final bool hide;
601
- @override
602
587
final bool negatable;
603
- @override
604
- final bool splitCommas;
605
588
606
589
@override
607
590
final T Function (DartdocSyntheticOption <T >, Folder ) _compute;
@@ -611,15 +594,19 @@ class DartdocOptionArgSynth<T> extends DartdocOption<T>
611
594
{this .abbr,
612
595
bool mustExist = false ,
613
596
String help = '' ,
614
- this .hide = false ,
615
597
OptionKind optionIs = OptionKind .other,
616
- this .negatable = false ,
617
- this .splitCommas = false })
618
- : assert (T is ! Iterable || splitCommas == true ),
598
+ this .negatable = false })
599
+ : assert (T is ! Iterable ),
619
600
super (name, null , help, optionIs, mustExist, null , resourceProvider);
620
601
621
602
@override
622
- void _onMissing (
603
+ bool get hide => false ;
604
+
605
+ @override
606
+ bool get splitCommas => false ;
607
+
608
+ @override
609
+ Never _onMissing (
623
610
_OptionValueWithContext <T > valueWithContext, String missingPath) {
624
611
_onMissingFromArgs (valueWithContext, missingPath);
625
612
}
@@ -663,11 +650,11 @@ mixin DartdocSyntheticOption<T> implements DartdocOption<T> {
663
650
}
664
651
665
652
@override
666
- void _onMissing (
653
+ Never _onMissing (
667
654
_OptionValueWithContext <T > valueWithContext, String missingPath) =>
668
655
_onMissingFromSynthetic (valueWithContext, missingPath);
669
656
670
- void _onMissingFromSynthetic (
657
+ Never _onMissingFromSynthetic (
671
658
_OptionValueWithContext <T > valueWithContext, String missingPath) {
672
659
var description = 'Synthetic configuration option $name from <internal>' ;
673
660
throw DartdocFileMissing (
@@ -784,31 +771,31 @@ class DartdocOptionArgOnly<T> extends DartdocOption<T>
784
771
class DartdocOptionArgFile <T > extends DartdocOption <T >
785
772
with _DartdocArgOption <T >, _DartdocFileOption <T > {
786
773
@override
787
- final String ? abbr;
788
- @override
789
- final bool hide;
790
- @override
791
774
final bool negatable;
792
775
@override
793
- final bool parentDirOverridesChild;
794
- @override
795
776
final bool splitCommas;
796
777
797
778
DartdocOptionArgFile (
798
779
String name, T defaultsTo, ResourceProvider resourceProvider,
799
- {this .abbr,
800
- bool mustExist = false ,
780
+ {bool mustExist = false ,
801
781
String help = '' ,
802
- this .hide = false ,
803
782
OptionKind optionIs = OptionKind .other,
804
783
this .negatable = false ,
805
- this .parentDirOverridesChild = false ,
806
784
this .splitCommas = false })
807
785
: super (name, defaultsTo, help, optionIs, mustExist, null ,
808
786
resourceProvider);
809
787
810
788
@override
811
- void _onMissing (
789
+ String ? get abbr => null ;
790
+
791
+ @override
792
+ bool get hide => false ;
793
+
794
+ @override
795
+ bool get parentDirOverridesChild => false ;
796
+
797
+ @override
798
+ Never _onMissing (
812
799
_OptionValueWithContext <T > valueWithContext, String missingPath) {
813
800
if (valueWithContext.definingFile != null ) {
814
801
_onMissingFromFiles (valueWithContext, missingPath);
@@ -858,22 +845,21 @@ mixin _DartdocFileOption<T> implements DartdocOption<T> {
858
845
String get fieldName => keys.join ('.' );
859
846
860
847
@override
861
- void _onMissing (
848
+ Never _onMissing (
862
849
_OptionValueWithContext <T > valueWithContext, String missingPath) =>
863
850
_onMissingFromFiles (valueWithContext, missingPath);
864
851
865
- void _onMissingFromFiles (
852
+ Never _onMissingFromFiles (
866
853
_OptionValueWithContext <T > valueWithContext, String missingPath) {
867
854
var dartdocYaml = resourceProvider.pathContext.join (
868
855
valueWithContext.canonicalDirectoryPath, valueWithContext.definingFile);
869
856
throw DartdocFileMissing ('Field $fieldName from $dartdocYaml , set to '
870
857
'${valueWithContext .value }, resolves to missing path: "$missingPath "' );
871
858
}
872
859
873
- @override
874
-
875
860
/// Searches for a value in configuration files relative to [dir] , and if not
876
861
/// found, returns [defaultsTo] .
862
+ @override
877
863
T ? valueAt (Folder dir) => _valueAtFromFiles (dir) ?? defaultsTo;
878
864
879
865
/// The backing store for [_valueAtFromFiles] .
@@ -1064,11 +1050,11 @@ mixin _DartdocArgOption<T> implements DartdocOption<T> {
1064
1050
}
1065
1051
1066
1052
@override
1067
- void _onMissing (
1053
+ Never _onMissing (
1068
1054
_OptionValueWithContext <T > valueWithContext, String missingPath) =>
1069
1055
_onMissingFromArgs (valueWithContext, missingPath);
1070
1056
1071
- void _onMissingFromArgs (
1057
+ Never _onMissingFromArgs (
1072
1058
_OptionValueWithContext <T > valueWithContext, String missingPath) {
1073
1059
throw DartdocFileMissing (
1074
1060
'Argument --$argName , set to ${valueWithContext .value }, resolves to '
0 commit comments