Skip to content

Commit 1d91811

Browse files
authored
Prepare dartdoc_options for migration (#2745)
* more specific imports in options * do not allow autoinitialization * dartfmt * parameterize the valueWithContext type * Use alternative constructors instead of externalizing, didn't realize the autodetect was so widely used * more subclasses
1 parent a7322c2 commit 1d91811

File tree

5 files changed

+75
-66
lines changed

5 files changed

+75
-66
lines changed

lib/options.dart

+13-3
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,22 @@ import 'dart:io' show stderr, exitCode;
22

33
import 'package:analyzer/file_system/file_system.dart';
44
import 'package:args/args.dart';
5-
import 'package:dartdoc/dartdoc.dart';
5+
import 'package:dartdoc/dartdoc.dart' show dartdocVersion, programName;
6+
import 'package:dartdoc/src/dartdoc_options.dart';
7+
import 'package:dartdoc/src/generator/generator.dart';
68
import 'package:dartdoc/src/logging.dart';
9+
import 'package:dartdoc/src/package_meta.dart';
710

811
/// Helper class that consolidates option contexts for instantiating generators.
912
class DartdocGeneratorOptionContext extends DartdocOptionContext {
1013
DartdocGeneratorOptionContext(
1114
DartdocOptionSet optionSet, Folder dir, ResourceProvider resourceProvider)
1215
: super(optionSet, dir, resourceProvider);
1316

17+
DartdocGeneratorOptionContext.fromDefaultContextLocation(
18+
DartdocOptionSet optionSet, ResourceProvider resourceProvider)
19+
: super.fromDefaultContextLocation(optionSet, resourceProvider);
20+
1421
// TODO(migration): Make late final with initializer when Null Safe.
1522
String _header;
1623

@@ -57,6 +64,9 @@ class DartdocProgramOptionContext extends DartdocGeneratorOptionContext
5764
DartdocProgramOptionContext(
5865
DartdocOptionSet optionSet, Folder dir, ResourceProvider resourceProvider)
5966
: super(optionSet, dir, resourceProvider);
67+
DartdocProgramOptionContext.fromDefaultContextLocation(
68+
DartdocOptionSet optionSet, ResourceProvider resourceProvider)
69+
: super.fromDefaultContextLocation(optionSet, resourceProvider);
6070

6171
bool get generateDocs => optionSet['generateDocs'].valueAt(context);
6272
bool get help => optionSet['help'].valueAt(context);
@@ -118,8 +128,8 @@ Future<DartdocProgramOptionContext> parseOptions(
118128

119129
DartdocProgramOptionContext config;
120130
try {
121-
config = DartdocProgramOptionContext(
122-
optionSet, null, packageMetaProvider.resourceProvider);
131+
config = DartdocProgramOptionContext.fromDefaultContextLocation(
132+
optionSet, packageMetaProvider.resourceProvider);
123133
} on DartdocOptionError catch (e) {
124134
stderr.writeln(' fatal error: ${e.message}');
125135
stderr.writeln('');

lib/src/dartdoc_options.dart

+56-54
Original file line numberDiff line numberDiff line change
@@ -396,10 +396,10 @@ abstract class DartdocOption<T> {
396396

397397
bool get _isDouble => _kDoubleVal is T;
398398

399-
DartdocOption<Object> _parent;
399+
DartdocOption _parent;
400400

401401
/// The parent of this DartdocOption, or null if this is the root.
402-
DartdocOption<Object> get parent => _parent;
402+
DartdocOption get parent => _parent;
403403

404404
final Map<String, _YamlFileData> __yamlAtCanonicalPathCache = {};
405405

@@ -424,18 +424,18 @@ abstract class DartdocOption<T> {
424424
/// Throw [DartdocFileMissing] with a detailed error message indicating where
425425
/// the error came from when a file or directory option is missing.
426426
void _onMissing(
427-
_OptionValueWithContext<Object> valueWithContext, String missingFilename);
427+
_OptionValueWithContext<T> valueWithContext, String missingFilename);
428428

429429
/// Call [_onMissing] for every path that does not exist.
430-
void _validatePaths(_OptionValueWithContext<Object> valueWithContext) {
430+
void _validatePaths(_OptionValueWithContext<T> valueWithContext) {
431431
if (!mustExist) return;
432432
assert(isDir || isFile);
433433
List<String> resolvedPaths;
434434
var value = valueWithContext.value;
435435
if (value is String) {
436-
resolvedPaths = [valueWithContext.resolvedValue];
436+
resolvedPaths = [valueWithContext.resolvedValue as String];
437437
} else if (value is List<String>) {
438-
resolvedPaths = valueWithContext.resolvedValue as List;
438+
resolvedPaths = valueWithContext.resolvedValue as List<String>;
439439
} else if (value is Map<String, String>) {
440440
resolvedPaths = (valueWithContext.resolvedValue as Map).values.toList();
441441
} else {
@@ -456,7 +456,7 @@ abstract class DartdocOption<T> {
456456

457457
/// For a [List<String>] or [String] value, if [isDir] or [isFile] is set,
458458
/// resolve paths in value relative to canonicalPath.
459-
T _handlePathsInContext(_OptionValueWithContext<Object> valueWithContext) {
459+
T _handlePathsInContext(_OptionValueWithContext<T> valueWithContext) {
460460
if (valueWithContext?.value == null || !(isDir || isFile || isGlob)) {
461461
return valueWithContext?.value;
462462
}
@@ -472,15 +472,15 @@ abstract class DartdocOption<T> {
472472
ArgResults get _argResults => root.__argResults;
473473

474474
/// Set the parent of this [DartdocOption]. Do not call more than once.
475-
set parent(DartdocOption<Object> newParent) {
475+
set parent(DartdocOption newParent) {
476476
assert(_parent == null);
477477
_parent = newParent;
478478
}
479479

480480
/// The root [DartdocOption] containing this object, or [this] if the object
481481
/// has no parent.
482-
DartdocOption<Object> get root {
483-
DartdocOption<Object> p = this;
482+
DartdocOption get root {
483+
DartdocOption p = this;
484484
while (p.parent != null) {
485485
p = p.parent;
486486
}
@@ -490,7 +490,7 @@ abstract class DartdocOption<T> {
490490
/// All object names starting at the root.
491491
Iterable<String> get keys {
492492
var keyList = <String>[];
493-
DartdocOption<Object> option = this;
493+
DartdocOption option = this;
494494
while (option?.name != null) {
495495
keyList.add(option.name);
496496
option = option.parent;
@@ -499,7 +499,7 @@ abstract class DartdocOption<T> {
499499
}
500500

501501
/// Direct children of this node, mapped by name.
502-
final Map<String, DartdocOption<Object>> _children = {};
502+
final Map<String, DartdocOption> _children = {};
503503

504504
/// Return the calculated value of this option, given the directory as
505505
/// context.
@@ -531,7 +531,7 @@ abstract class DartdocOption<T> {
531531
resourceProvider.pathContext.basename(element.source.fullName))));
532532

533533
/// Adds a DartdocOption to the children of this DartdocOption.
534-
void add(DartdocOption<Object> option) {
534+
void add(DartdocOption option) {
535535
if (_children.containsKey(option.name)) {
536536
throw DartdocOptionError(
537537
'Tried to add two children with the same name: ${option.name}');
@@ -545,15 +545,15 @@ abstract class DartdocOption<T> {
545545
void _onAdd() {}
546546

547547
/// Adds a list of dartdoc options to the children of this DartdocOption.
548-
void addAll(Iterable<DartdocOption<Object>> options) => options.forEach(add);
548+
void addAll(Iterable<DartdocOption> options) => options.forEach(add);
549549

550550
/// Get the immediate child of this node named [name].
551551
DartdocOption<dynamic> operator [](String name) {
552552
return _children[name];
553553
}
554554

555555
/// Apply the function [visit] to [this] and all children.
556-
void traverse(void Function(DartdocOption<Object> option) visit) {
556+
void traverse(void Function(DartdocOption option) visit) {
557557
visit(this);
558558
_children.values.forEach((d) => d.traverse(visit));
559559
}
@@ -590,7 +590,7 @@ class DartdocOptionFileSynth<T> extends DartdocOption<T>
590590

591591
@override
592592
void _onMissing(
593-
_OptionValueWithContext<Object> valueWithContext, String missingPath) {
593+
_OptionValueWithContext<T> valueWithContext, String missingPath) {
594594
if (valueWithContext.definingFile != null) {
595595
_onMissingFromFiles(valueWithContext, missingPath);
596596
} else {
@@ -632,7 +632,7 @@ class DartdocOptionArgSynth<T> extends DartdocOption<T>
632632

633633
@override
634634
void _onMissing(
635-
_OptionValueWithContext<Object> valueWithContext, String missingPath) {
635+
_OptionValueWithContext<T> valueWithContext, String missingPath) {
636636
_onMissingFromArgs(valueWithContext, missingPath);
637637
}
638638

@@ -687,20 +687,20 @@ abstract class DartdocSyntheticOption<T> implements DartdocOption<T> {
687687
}
688688

689689
@override
690-
void _onMissing(_OptionValueWithContext<Object> valueWithContext,
691-
String missingPath) =>
690+
void _onMissing(
691+
_OptionValueWithContext<T> valueWithContext, String missingPath) =>
692692
_onMissingFromSynthetic(valueWithContext, missingPath);
693693

694694
void _onMissingFromSynthetic(
695-
_OptionValueWithContext<Object> valueWithContext, String missingPath) {
695+
_OptionValueWithContext<T> valueWithContext, String missingPath) {
696696
var description = 'Synthetic configuration option $name from <internal>';
697697
throw DartdocFileMissing(
698698
'$description, computed as ${valueWithContext.value}, resolves to '
699699
'missing path: "$missingPath"');
700700
}
701701
}
702702

703-
typedef OptionGenerator = Future<List<DartdocOption<Object>>> Function(
703+
typedef OptionGenerator = Future<List<DartdocOption>> Function(
704704
PackageMetaProvider);
705705

706706
/// A [DartdocOption] that only contains other [DartdocOption]s and is not an
@@ -734,13 +734,13 @@ class DartdocOptionSet extends DartdocOption<void> {
734734

735735
/// Since we have no value, [_onMissing] does nothing.
736736
@override
737-
void _onMissing(_OptionValueWithContext<Object> valueWithContext,
738-
String missingFilename) {}
737+
void _onMissing(
738+
_OptionValueWithContext<void> valueWithContext, String missingFilename) {}
739739

740740
/// Traverse skips this node, because it doesn't represent a real
741741
/// configuration object.
742742
@override
743-
void traverse(void Function(DartdocOption<Object> option) visitor) {
743+
void traverse(void Function(DartdocOption option) visitor) {
744744
_children.values.forEach((d) => d.traverse(visitor));
745745
}
746746
}
@@ -815,7 +815,7 @@ class DartdocOptionArgFile<T> extends DartdocOption<T>
815815

816816
@override
817817
void _onMissing(
818-
_OptionValueWithContext<Object> valueWithContext, String missingPath) {
818+
_OptionValueWithContext<T> valueWithContext, String missingPath) {
819819
if (valueWithContext.definingFile != null) {
820820
_onMissingFromFiles(valueWithContext, missingPath);
821821
} else {
@@ -887,12 +887,12 @@ abstract class _DartdocFileOption<T> implements DartdocOption<T> {
887887
String get fieldName => keys.join('.');
888888

889889
@override
890-
void _onMissing(_OptionValueWithContext<Object> valueWithContext,
891-
String missingPath) =>
890+
void _onMissing(
891+
_OptionValueWithContext<T> valueWithContext, String missingPath) =>
892892
_onMissingFromFiles(valueWithContext, missingPath);
893893

894894
void _onMissingFromFiles(
895-
_OptionValueWithContext<Object> valueWithContext, String missingPath) {
895+
_OptionValueWithContext<T> valueWithContext, String missingPath) {
896896
var dartdocYaml = resourceProvider.pathContext.join(
897897
valueWithContext.canonicalDirectoryPath, valueWithContext.definingFile);
898898
throw DartdocFileMissing('Field $fieldName from $dartdocYaml, set to '
@@ -914,7 +914,7 @@ abstract class _DartdocFileOption<T> implements DartdocOption<T> {
914914
T _valueAtFromFiles(Folder dir) {
915915
var key = resourceProvider.pathContext.canonicalize(dir.path);
916916
if (!__valueAtFromFiles.containsKey(key)) {
917-
_OptionValueWithContext<Object> valueWithContext;
917+
_OptionValueWithContext<T> valueWithContext;
918918
if (parentDirOverridesChild) {
919919
valueWithContext = _valueAtFromFilesLastFound(dir);
920920
} else {
@@ -927,8 +927,8 @@ abstract class _DartdocFileOption<T> implements DartdocOption<T> {
927927

928928
/// Searches all dartdoc_options files through parent directories, starting at
929929
/// [dir], for the option and returns one once found.
930-
_OptionValueWithContext<Object> _valueAtFromFilesFirstFound(Folder folder) {
931-
_OptionValueWithContext<Object> value;
930+
_OptionValueWithContext<T> _valueAtFromFilesFirstFound(Folder folder) {
931+
_OptionValueWithContext<T> value;
932932
for (var dir in folder.withAncestors) {
933933
value = _valueAtFromFile(dir);
934934
if (value != null) break;
@@ -939,8 +939,8 @@ abstract class _DartdocFileOption<T> implements DartdocOption<T> {
939939
/// Searches all dartdoc_options files for the option, and returns the value
940940
/// in the top-most parent directory `dartdoc_options.yaml` file it is
941941
/// mentioned in.
942-
_OptionValueWithContext<Object> _valueAtFromFilesLastFound(Folder folder) {
943-
_OptionValueWithContext<Object> value;
942+
_OptionValueWithContext<T> _valueAtFromFilesLastFound(Folder folder) {
943+
_OptionValueWithContext<T> value;
944944
for (var dir in folder.withAncestors) {
945945
var tmpValue = _valueAtFromFile(dir);
946946
if (tmpValue != null) value = tmpValue;
@@ -950,7 +950,7 @@ abstract class _DartdocFileOption<T> implements DartdocOption<T> {
950950

951951
/// Returns null if not set in the YAML file in this directory (or its
952952
/// parents).
953-
_OptionValueWithContext<Object> _valueAtFromFile(Folder dir) {
953+
_OptionValueWithContext<T> _valueAtFromFile(Folder dir) {
954954
var yamlFileData = _yamlAtDirectory(dir);
955955
var contextPath = yamlFileData.canonicalDirectoryPath;
956956
Object yamlData = yamlFileData.data ?? {};
@@ -1081,12 +1081,12 @@ abstract class _DartdocArgOption<T> implements DartdocOption<T> {
10811081
}
10821082

10831083
@override
1084-
void _onMissing(_OptionValueWithContext<Object> valueWithContext,
1085-
String missingPath) =>
1084+
void _onMissing(
1085+
_OptionValueWithContext<T> valueWithContext, String missingPath) =>
10861086
_onMissingFromArgs(valueWithContext, missingPath);
10871087

10881088
void _onMissingFromArgs(
1089-
_OptionValueWithContext<Object> valueWithContext, String missingPath) {
1089+
_OptionValueWithContext<T> valueWithContext, String missingPath) {
10901090
throw DartdocFileMissing(
10911091
'Argument --$argName, set to ${valueWithContext.value}, resolves to '
10921092
'missing path: "$missingPath"');
@@ -1096,7 +1096,7 @@ abstract class _DartdocArgOption<T> implements DartdocOption<T> {
10961096
/// the [argParser] and the working directory from [_directoryCurrent].
10971097
///
10981098
/// Throws [UnsupportedError] if [T] is not a supported type.
1099-
_OptionValueWithContext<Object> _valueAtFromArgsWithContext() {
1099+
_OptionValueWithContext<T> _valueAtFromArgsWithContext() {
11001100
if (!_argResults.wasParsed(argName)) return null;
11011101

11021102
T retval;
@@ -1215,21 +1215,23 @@ class DartdocOptionContext extends DartdocOptionContextBase
12151215
// TODO(jcollins-g): Allow passing in structured data to initialize a
12161216
// [DartdocOptionContext]'s arguments instead of having to parse strings
12171217
// via optionSet.
1218-
/// If [entity] is null, assume this is the initialization case and use
1219-
/// the inputDir flag to determine the context.
1220-
DartdocOptionContext(
1221-
this.optionSet, Resource resource, ResourceProvider resourceProvider) {
1222-
if (resource == null) {
1223-
var current = resourceProvider.pathContext.current;
1224-
String inputDir =
1225-
optionSet['inputDir'].valueAt(resourceProvider.getFolder(current)) ??
1226-
current;
1227-
context = resourceProvider.getFolder(inputDir);
1228-
} else {
1229-
context = resourceProvider.getFolder(resourceProvider.pathContext
1230-
.canonicalize(
1231-
resource is File ? resource.parent2.path : resource.path));
1232-
}
1218+
DartdocOptionContext(this.optionSet, Resource contextLocation,
1219+
ResourceProvider resourceProvider) {
1220+
assert(contextLocation != null);
1221+
context = resourceProvider.getFolder(resourceProvider.pathContext
1222+
.canonicalize(contextLocation is File
1223+
? contextLocation.parent2.path
1224+
: contextLocation.path));
1225+
}
1226+
1227+
/// Build a DartdocOptionContext via the 'inputDir' command line option.
1228+
DartdocOptionContext.fromDefaultContextLocation(
1229+
this.optionSet, ResourceProvider resourceProvider) {
1230+
var current = resourceProvider.pathContext.current;
1231+
String inputDir =
1232+
optionSet['inputDir'].valueAt(resourceProvider.getFolder(current)) ??
1233+
current;
1234+
context = resourceProvider.getFolder(inputDir);
12331235
}
12341236

12351237
/// Build a DartdocOptionContext from an analyzer element (using its source
@@ -1366,7 +1368,7 @@ class DartdocOptionContext extends DartdocOptionContextBase
13661368

13671369
/// Instantiate dartdoc's configuration file and options parser with the
13681370
/// given command line arguments.
1369-
Future<List<DartdocOption<Object>>> createDartdocOptions(
1371+
Future<List<DartdocOption>> createDartdocOptions(
13701372
PackageMetaProvider packageMetaProvider,
13711373
) async {
13721374
var resourceProvider = packageMetaProvider.resourceProvider;

test/end2end/dartdoc_test.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ Future<DartdocGeneratorOptionContext> _generatorContextFromArgv(
5555
],
5656
pubPackageMetaProvider);
5757
optionSet.parseArguments(argv);
58-
return DartdocGeneratorOptionContext(
59-
optionSet, null, pubPackageMetaProvider.resourceProvider);
58+
return DartdocGeneratorOptionContext.fromDefaultContextLocation(
59+
optionSet, pubPackageMetaProvider.resourceProvider);
6060
}
6161

6262
class DartdocLoggingOptionContext extends DartdocGeneratorOptionContext

test/mustachio/renderers_output_test.dart

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ Future<DartdocGeneratorOptionContext> _generatorContextFromArgv(
2727
],
2828
pubPackageMetaProvider);
2929
optionSet.parseArguments(argv);
30-
return DartdocGeneratorOptionContext(
31-
optionSet, null, pubPackageMetaProvider.resourceProvider);
30+
return DartdocGeneratorOptionContext.fromDefaultContextLocation(
31+
optionSet, pubPackageMetaProvider.resourceProvider);
3232
}
3333

3434
void main() {

test/src/utils.dart

+2-5
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,11 @@ final Folder testPackageToolError = _resourceProvider.getFolder(_pathContext
3434
/// [DartdocOptionSet] based on the current working directory.
3535
Future<DartdocOptionContext> contextFromArgv(
3636
List<String> argv, PackageMetaProvider packageMetaProvider) async {
37-
var resourceProvider = packageMetaProvider.resourceProvider;
3837
var optionSet = await DartdocOptionSet.fromOptionGenerators(
3938
'dartdoc', [createDartdocOptions], packageMetaProvider);
4039
optionSet.parseArguments(argv);
41-
return DartdocOptionContext(
42-
optionSet,
43-
resourceProvider.getFolder(resourceProvider.pathContext.current),
44-
pubPackageMetaProvider.resourceProvider);
40+
return DartdocOptionContext.fromDefaultContextLocation(
41+
optionSet, pubPackageMetaProvider.resourceProvider);
4542
}
4643

4744
Future<PackageGraph> bootBasicPackage(

0 commit comments

Comments
 (0)