analyzer: Validate doc directive argument formats
Work towards https://github.com/dart-lang/sdk/issues/52705
Change-Id: Ieea17365397eaf9936ea9eaede2d472bd91abbc6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/327300
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Samuel Rawlins <srawlins@google.com>
diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
index 4ae98a3..aae3eea 100644
--- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
+++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml
@@ -3452,22 +3452,29 @@
The fix is to remove `Function` from where it's referenced.
WarningCode.DEPRECATED_NEW_IN_COMMENT_REFERENCE:
status: hasFix
+WarningCode.DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT:
+ status: noFix
WarningCode.DOC_DIRECTIVE_HAS_EXTRA_ARGUMENTS:
status: needsFix
notes: |-
- The fix is to remove the extra arguments..
+ The fix is to remove the extra arguments.
WarningCode.DOC_DIRECTIVE_HAS_UNEXPECTED_NAMED_ARGUMENT:
status: needsFix
notes: |-
The fix is to remove the unexpected named argument.
WarningCode.DOC_DIRECTIVE_MISSING_CLOSING_BRACE:
- status: needsEvaluation
+ status: needsFix
+ notes: Add the closing brace at the end of the line.
WarningCode.DOC_DIRECTIVE_MISSING_CLOSING_TAG:
- status: needsEvaluation
+ status: needsFix
+ notes: Add the appropriate closing tag, perhaps on the line just following.
WarningCode.DOC_DIRECTIVE_MISSING_ONE_ARGUMENT:
status: noFix
WarningCode.DOC_DIRECTIVE_MISSING_OPENING_TAG:
- status: needsEvaluation
+ status: needsFix
+ notes: |-
+ I can think of two: Offer to insert the appropriate starting tag (maybe
+ on the preceding line), and offer to change the end-tag to the start-tag.
WarningCode.DOC_DIRECTIVE_MISSING_THREE_ARGUMENTS:
status: noFix
WarningCode.DOC_DIRECTIVE_MISSING_TWO_ARGUMENTS:
diff --git a/pkg/analyzer/lib/dart/ast/doc_comment.dart b/pkg/analyzer/lib/dart/ast/doc_comment.dart
index 8e6a09f..a662796 100644
--- a/pkg/analyzer/lib/dart/ast/doc_comment.dart
+++ b/pkg/analyzer/lib/dart/ast/doc_comment.dart
@@ -68,6 +68,39 @@
});
}
+/// A parameter in a doc directive, with it's expected format, if it has one.
+@experimental
+final class DocDirectiveParameter {
+ final String name;
+ final DocDirectiveParameterFormat expectedFormat;
+
+ const DocDirectiveParameter(this.name, this.expectedFormat);
+}
+
+/// The expected format of a doc directive parameter, which indicates some
+/// minimal validation that can produce diagnostics.
+@experimental
+enum DocDirectiveParameterFormat {
+ /// A format indicating that arguments are not validated.
+ any('any'),
+
+ /// A format indicating that an argument must be parsable as an integer.
+ integer('an integer'),
+
+ /// A format indicating that an argument must be parsable as a URI.
+ uri('a URI'),
+
+ /// A format indicating that an argument must be parsable as a URI, and be in
+ /// the format of a YouTube video URL.
+ youtubeUrl("a YouTube URL, starting with '$youtubeUrlPrefix'");
+
+ static const youtubeUrlPrefix = 'https://www.youtube.com/watch?v=';
+
+ final String displayString;
+
+ const DocDirectiveParameterFormat(this.displayString);
+}
+
/// A positional argument in a doc directive. See [DocDirective] for their
/// syntax.
@experimental
@@ -126,8 +159,14 @@
/// https://github.com/dart-lang/dartdoc/wiki/Doc-comment-directives#animations.
animation(
'animation',
- positionalParameters: ['width', 'height', 'url'],
- namedParameters: ['id'],
+ positionalParameters: [
+ DocDirectiveParameter('width', DocDirectiveParameterFormat.integer),
+ DocDirectiveParameter('height', DocDirectiveParameterFormat.integer),
+ DocDirectiveParameter('url', DocDirectiveParameterFormat.uri),
+ ],
+ namedParameters: [
+ DocDirectiveParameter('id', DocDirectiveParameterFormat.any),
+ ],
),
/// A [DocDirective] declaring the associated library is the "canonical"
@@ -147,7 +186,9 @@
// directive name is a rare departure from that style. Migrate users to use
// 'canonical-for'.
'canonicalFor',
- positionalParameters: ['element'],
+ positionalParameters: [
+ DocDirectiveParameter('element', DocDirectiveParameterFormat.any),
+ ],
),
/// A [DocDirective] declaring a categorization into a named category.
@@ -191,8 +232,13 @@
/// https://github.com/dart-lang/dartdoc/wiki/Doc-comment-directives#examples.
example(
'example',
- positionalParameters: ['path'],
- namedParameters: ['region', 'lang'],
+ positionalParameters: [
+ DocDirectiveParameter('path', DocDirectiveParameterFormat.any)
+ ],
+ namedParameters: [
+ DocDirectiveParameter('region', DocDirectiveParameterFormat.any),
+ DocDirectiveParameter('lang', DocDirectiveParameterFormat.any),
+ ],
),
/// A [DocDirective] declaring a block of HTML content which is to be inserted
@@ -207,7 +253,12 @@
/// This directive has one required argument: the name. For example:
///
/// `{@macro some-macro}`
- macro('macro', positionalParameters: ['name']),
+ macro(
+ 'macro',
+ positionalParameters: [
+ DocDirectiveParameter('name', DocDirectiveParameterFormat.any),
+ ],
+ ),
/// A [DocDirective] declaring a categorization into a named sub-category.
///
@@ -234,7 +285,13 @@
/// See documentation at
/// https://github.com/dart-lang/dartdoc/wiki/Doc-comment-directives#templates-and-macros.
// TODO(srawlins): Migrate users to use 'end-template'.
- template.block('template', 'endtemplate', positionalParameters: ['name']),
+ template.block(
+ 'template',
+ 'endtemplate',
+ positionalParameters: [
+ DocDirectiveParameter('name', DocDirectiveParameterFormat.any),
+ ],
+ ),
/// A [DocDirective] declaring an embedded YouTube video.
///
@@ -245,7 +302,14 @@
///
/// See documentation at
/// https://github.com/dart-lang/dartdoc/wiki/Doc-comment-directives#youtube-videos.
- youtube('youtube', positionalParameters: ['width', 'height', 'url']);
+ youtube(
+ 'youtube',
+ positionalParameters: [
+ DocDirectiveParameter('width', DocDirectiveParameterFormat.integer),
+ DocDirectiveParameter('height', DocDirectiveParameterFormat.integer),
+ DocDirectiveParameter('url', DocDirectiveParameterFormat.youtubeUrl),
+ ],
+ );
/// Whether this starts a block directive, which must be closed by a specific
/// closing directive.
@@ -262,11 +326,11 @@
/// in the case of a block directive's closing tag, and `null` otherwise.
final String? opposingName;
- /// The positional parameter names, which are each required.
- final List<String> positionalParameters;
+ /// The positional parameters, which are each required.
+ final List<DocDirectiveParameter> positionalParameters;
- /// The named parameter names, which are each optional.
- final List<String> namedParameters;
+ /// The named parameters, which are each optional.
+ final List<DocDirectiveParameter> namedParameters;
/// Whether "rest" parameters are allowed.
///
@@ -276,8 +340,8 @@
const DocDirectiveType(
this.name, {
- this.positionalParameters = const <String>[],
- this.namedParameters = const <String>[],
+ this.positionalParameters = const <DocDirectiveParameter>[],
+ this.namedParameters = const <DocDirectiveParameter>[],
this.restParametersAllowed = false,
}) : isBlock = false,
opposingName = null;
@@ -285,9 +349,9 @@
const DocDirectiveType.block(
this.name,
this.opposingName, {
- this.positionalParameters = const <String>[],
+ this.positionalParameters = const <DocDirectiveParameter>[],
}) : isBlock = true,
- namedParameters = const <String>[],
+ namedParameters = const <DocDirectiveParameter>[],
restParametersAllowed = false;
const DocDirectiveType.end(
@@ -295,8 +359,8 @@
required String openingTag,
}) : opposingName = openingTag,
isBlock = false,
- positionalParameters = const <String>[],
- namedParameters = const <String>[],
+ positionalParameters = const <DocDirectiveParameter>[],
+ namedParameters = const <DocDirectiveParameter>[],
restParametersAllowed = false;
}
diff --git a/pkg/analyzer/lib/src/error/codes.g.dart b/pkg/analyzer/lib/src/error/codes.g.dart
index 19a02da..9dd326f 100644
--- a/pkg/analyzer/lib/src/error/codes.g.dart
+++ b/pkg/analyzer/lib/src/error/codes.g.dart
@@ -6056,6 +6056,15 @@
);
/// Parameters:
+ /// 0: the name of the doc directive argument
+ /// 1: the expected format
+ static const WarningCode DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT = WarningCode(
+ 'DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT',
+ "The '{0}' argument must be formatted as {1}.",
+ correctionMessage: "Try formatting '{0}' as {1}.",
+ );
+
+ /// Parameters:
/// 0: the name of the doc directive
/// 1: the actual number of arguments
/// 2: the expected number of arguments
diff --git a/pkg/analyzer/lib/src/error/doc_comment_verifier.dart b/pkg/analyzer/lib/src/error/doc_comment_verifier.dart
index 32faa15..5fcc176 100644
--- a/pkg/analyzer/lib/src/error/doc_comment_verifier.dart
+++ b/pkg/analyzer/lib/src/error/doc_comment_verifier.dart
@@ -2,6 +2,8 @@
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
+import 'dart:math' as math;
+
import 'package:analyzer/dart/ast/doc_comment.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/error/codes.g.dart';
@@ -13,10 +15,6 @@
DocCommentVerifier(this._errorReporter);
void docDirective(DocDirective docDirective) {
- // TODO(srawlins): Validate format of each parameter. For example, an
- // animation directive's width must be an int, a youtube directive's URL
- // must be a valid YouTube URL, etc.
-
switch (docDirective) {
case SimpleDocDirective():
docDirectiveTag(docDirective.tag);
@@ -29,6 +27,30 @@
}
void docDirectiveTag(DocDirectiveTag tag) {
+ validateArgumentCount(tag);
+ validateArgumentFormat(tag);
+ }
+
+ /// Verifies doc imports, written as `@docImport`.
+ void docImport(DocImport docImport) {
+ var deferredKeyword = docImport.import.deferredKeyword;
+ if (deferredKeyword != null) {
+ _errorReporter.reportErrorForToken(
+ WarningCode.DOC_IMPORT_CANNOT_BE_DEFERRED,
+ deferredKeyword,
+ );
+ }
+ var configurations = docImport.import.configurations;
+ if (configurations.isNotEmpty) {
+ _errorReporter.reportErrorForOffset(
+ WarningCode.DOC_IMPORT_CANNOT_HAVE_CONFIGURATIONS,
+ configurations.first.offset,
+ configurations.last.end - configurations.first.offset,
+ );
+ }
+ }
+
+ void validateArgumentCount(DocDirectiveTag tag) {
var positionalArgumentCount = tag.positionalArguments.length;
var required = tag.type.positionalParameters;
var requiredCount = tag.type.positionalParameters.length;
@@ -40,12 +62,12 @@
WarningCode.DOC_DIRECTIVE_MISSING_ONE_ARGUMENT,
tag.offset,
tag.end - tag.offset,
- [tag.type.name, required.last],
+ [tag.type.name, required.last.name],
);
} else if (gap == 2) {
var missingArguments = [
- required[required.length - 2],
- required.last,
+ required[required.length - 2].name,
+ required.last.name,
];
_errorReporter.reportErrorForOffset(
WarningCode.DOC_DIRECTIVE_MISSING_TWO_ARGUMENTS,
@@ -55,9 +77,9 @@
);
} else if (gap == 3) {
var missingArguments = [
- required[required.length - 3],
- required[required.length - 2],
- required.last,
+ required[required.length - 3].name,
+ required[required.length - 2].name,
+ required.last.name,
];
_errorReporter.reportErrorForOffset(
WarningCode.DOC_DIRECTIVE_MISSING_THREE_ARGUMENTS,
@@ -86,7 +108,7 @@
}
for (var namedArgument in tag.namedArguments) {
- if (!tag.type.namedParameters.contains(namedArgument.name)) {
+ if (!tag.type.namedParameters.containsNamed(namedArgument.name)) {
_errorReporter.reportErrorForOffset(
WarningCode.DOC_DIRECTIVE_HAS_UNEXPECTED_NAMED_ARGUMENT,
namedArgument.offset,
@@ -97,22 +119,45 @@
}
}
- /// Verifies doc imports, written as `@docImport`.
- void docImport(DocImport docImport) {
- var deferredKeyword = docImport.import.deferredKeyword;
- if (deferredKeyword != null) {
- _errorReporter.reportErrorForToken(
- WarningCode.DOC_IMPORT_CANNOT_BE_DEFERRED,
- deferredKeyword,
- );
- }
- var configurations = docImport.import.configurations;
- if (configurations.isNotEmpty) {
- _errorReporter.reportErrorForOffset(
- WarningCode.DOC_IMPORT_CANNOT_HAVE_CONFIGURATIONS,
- configurations.first.offset,
- configurations.last.end - configurations.first.offset,
- );
+ void validateArgumentFormat(DocDirectiveTag tag) {
+ var required = tag.type.positionalParameters;
+ var positionalArgumentCount =
+ math.min(tag.positionalArguments.length, required.length);
+ for (var i = 0; i < positionalArgumentCount; i++) {
+ var parameter = required[i];
+ var argument = tag.positionalArguments[i];
+
+ void reportWrongFormat() {
+ _errorReporter.reportErrorForOffset(
+ WarningCode.DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT,
+ argument.offset,
+ argument.end - argument.offset,
+ [parameter.name, parameter.expectedFormat.displayString],
+ );
+ }
+
+ switch (parameter.expectedFormat) {
+ case DocDirectiveParameterFormat.any:
+ continue;
+ case DocDirectiveParameterFormat.integer:
+ if (int.tryParse(argument.value) == null) {
+ reportWrongFormat();
+ }
+ case DocDirectiveParameterFormat.uri:
+ if (Uri.tryParse(argument.value) == null) {
+ reportWrongFormat();
+ }
+ case DocDirectiveParameterFormat.youtubeUrl:
+ if (Uri.tryParse(argument.value) == null ||
+ !argument.value
+ .startsWith(DocDirectiveParameterFormat.youtubeUrlPrefix)) {
+ reportWrongFormat();
+ }
+ }
}
}
}
+
+extension on List<DocDirectiveParameter> {
+ bool containsNamed(String name) => any((p) => p.name == name);
+}
diff --git a/pkg/analyzer/lib/src/error/error_code_values.g.dart b/pkg/analyzer/lib/src/error/error_code_values.g.dart
index 84ffdc5..eee0503 100644
--- a/pkg/analyzer/lib/src/error/error_code_values.g.dart
+++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart
@@ -950,6 +950,7 @@
WarningCode.DEPRECATED_IMPLEMENTS_FUNCTION,
WarningCode.DEPRECATED_MIXIN_FUNCTION,
WarningCode.DEPRECATED_NEW_IN_COMMENT_REFERENCE,
+ WarningCode.DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT,
WarningCode.DOC_DIRECTIVE_HAS_EXTRA_ARGUMENTS,
WarningCode.DOC_DIRECTIVE_HAS_UNEXPECTED_NAMED_ARGUMENT,
WarningCode.DOC_DIRECTIVE_MISSING_CLOSING_BRACE,
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 350a8b0f..8dd209c 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -22161,6 +22161,14 @@
Parameters:
0: the name of the doc directive
1: the name of the missing argument
+ DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT:
+ problemMessage: "The '{0}' argument must be formatted as {1}."
+ correctionMessage: "Try formatting '{0}' as {1}."
+ hasPublishedDocs: false
+ comment: |-
+ Parameters:
+ 0: the name of the doc directive argument
+ 1: the expected format
DOC_DIRECTIVE_MISSING_OPENING_TAG:
problemMessage: "Doc directive is missing an opening tag."
correctionMessage: "Try opening the directive with the appropriate opening tag, '{0}'."
diff --git a/pkg/analyzer/test/src/diagnostics/doc_directive_argument_wrong_format_test.dart b/pkg/analyzer/test/src/diagnostics/doc_directive_argument_wrong_format_test.dart
new file mode 100644
index 0000000..809e638
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/doc_directive_argument_wrong_format_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/error/codes.g.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/context_collection_resolution.dart';
+
+void main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DocDirectiveArgumentWrongFormatTest);
+ });
+}
+
+@reflectiveTest
+class DocDirectiveArgumentWrongFormatTest extends PubPackageResolutionTest {
+ test_animation_heightWrongFormat() async {
+ await assertErrorsInCode('''
+/// {@animation 600 nan http://google.com}
+class C {}
+''', [
+ error(WarningCode.DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT, 20, 3),
+ ]);
+ }
+
+ test_animation_urlWrongFormat() async {
+ await assertNoErrorsInCode('''
+/// {@animation 600 400 other}
+class C {}
+''');
+ }
+
+ test_animation_widthWrongFormat() async {
+ await assertErrorsInCode('''
+/// {@animation nan 400 http://google.com}
+class C {}
+''', [
+ error(WarningCode.DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT, 16, 3),
+ ]);
+ }
+
+ test_youtube_heightWrongFormat() async {
+ await assertErrorsInCode('''
+/// {@youtube 600 nan https://www.youtube.com/watch?v=123}
+class C {}
+''', [
+ error(WarningCode.DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT, 18, 3),
+ ]);
+ }
+
+ test_youtube_urlWrongFormat() async {
+ await assertErrorsInCode('''
+/// {@youtube 600 400 http://google.com}
+class C {}
+''', [
+ error(WarningCode.DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT, 22, 17),
+ ]);
+ }
+
+ test_youtube_widthWrongFormat() async {
+ await assertErrorsInCode('''
+/// {@youtube nan 400 https://www.youtube.com/watch?v=123}
+class C {}
+''', [
+ error(WarningCode.DOC_DIRECTIVE_ARGUMENT_WRONG_FORMAT, 14, 3),
+ ]);
+ }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/doc_directive_has_extra_arguments_test.dart b/pkg/analyzer/test/src/diagnostics/doc_directive_has_extra_arguments_test.dart
index ea9b703..2cfac36 100644
--- a/pkg/analyzer/test/src/diagnostics/doc_directive_has_extra_arguments_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/doc_directive_has_extra_arguments_test.dart
@@ -49,25 +49,25 @@
test_youtube_hasExtraArgument() async {
await assertErrorsInCode('''
-/// {@youtube 600 400 http://google.com foo}
+/// {@youtube 600 400 https://www.youtube.com/watch?v=123 foo}
class C {}
''', [
- error(WarningCode.DOC_DIRECTIVE_HAS_EXTRA_ARGUMENTS, 40, 3),
+ error(WarningCode.DOC_DIRECTIVE_HAS_EXTRA_ARGUMENTS, 58, 3),
]);
}
test_youtube_hasExtraArgument_trailingWhitespace() async {
await assertErrorsInCode('''
-/// {@youtube 600 400 http://google.com foo }
+/// {@youtube 600 400 https://www.youtube.com/watch?v=123 foo }
class C {}
''', [
- error(WarningCode.DOC_DIRECTIVE_HAS_EXTRA_ARGUMENTS, 40, 3),
+ error(WarningCode.DOC_DIRECTIVE_HAS_EXTRA_ARGUMENTS, 58, 3),
]);
}
test_youtube_noExtraArguments() async {
await assertNoErrorsInCode('''
-/// {@youtube 600 400 http://google.com}
+/// {@youtube 600 400 https://www.youtube.com/watch?v=123}
class C {}
''');
}
diff --git a/pkg/analyzer/test/src/diagnostics/doc_directive_missing_one_argument_test.dart b/pkg/analyzer/test/src/diagnostics/doc_directive_missing_one_argument_test.dart
index 195e162..bbc8bea 100644
--- a/pkg/analyzer/test/src/diagnostics/doc_directive_missing_one_argument_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/doc_directive_missing_one_argument_test.dart
@@ -56,7 +56,7 @@
test_youtube_hasThreeArguments() async {
await assertNoErrorsInCode('''
-/// {@youtube 600 400 http://google.com}
+/// {@youtube 600 400 https://www.youtube.com/watch?v=123}
class C {}
''');
}
diff --git a/pkg/analyzer/test/src/diagnostics/doc_directive_missing_three_arguments_test.dart b/pkg/analyzer/test/src/diagnostics/doc_directive_missing_three_arguments_test.dart
index 1619ede..496631d 100644
--- a/pkg/analyzer/test/src/diagnostics/doc_directive_missing_three_arguments_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/doc_directive_missing_three_arguments_test.dart
@@ -33,7 +33,7 @@
test_youtube_hasWidth() async {
await assertNoErrorsInCode('''
-/// {@youtube 600 400 http://google.com}
+/// {@youtube 600 400 https://www.youtube.com/watch?v=123}
class C {}
''');
}
diff --git a/pkg/analyzer/test/src/diagnostics/doc_directive_missing_two_arguments_test.dart b/pkg/analyzer/test/src/diagnostics/doc_directive_missing_two_arguments_test.dart
index 029efef..6bcc8a8 100644
--- a/pkg/analyzer/test/src/diagnostics/doc_directive_missing_two_arguments_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/doc_directive_missing_two_arguments_test.dart
@@ -40,7 +40,7 @@
test_youtube_hasThreeArguments() async {
await assertNoErrorsInCode('''
-/// {@youtube 600 400 http://google.com}
+/// {@youtube 600 400 https://www.youtube.com/watch?v=123}
class C {}
''');
}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 56ca51a..15a8145 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -167,6 +167,8 @@
import 'deprecated_member_use_test.dart' as deprecated_member_use;
import 'deprecated_mixin_function_test.dart' as deprecated_mixin_function;
import 'division_optimization_test.dart' as division_optimization;
+import 'doc_directive_argument_wrong_format_test.dart'
+ as doc_directive_argument_wrong_format;
import 'doc_directive_has_extra_arguments_test.dart'
as doc_directive_has_extra_arguments;
import 'doc_directive_has_unexpected_named_argument_test.dart'
@@ -1026,6 +1028,7 @@
deprecated_member_use.main();
deprecated_mixin_function.main();
division_optimization.main();
+ doc_directive_argument_wrong_format.main();
doc_directive_has_extra_arguments.main();
doc_directive_has_unexpected_named_argument.main();
doc_directive_missing_one_argument.main();