Unverified Commit a3186fba authored by Greg Spencer's avatar Greg Spencer Committed by GitHub

Analyze dartpad (#45124)

This fixes the sample code analysis to treat dartpad snippets in the same way as snippet snippets, which it wasn't until now (the snippet generator was treating them as "samples"), and some errors crept in. This PR also fixes those errors.

Also, added a --verbose option to the sample analyzer.
parent 1f296ad7
...@@ -63,6 +63,12 @@ void main(List<String> arguments) { ...@@ -63,6 +63,12 @@ void main(List<String> arguments) {
'directory in the system temp folder. If specified, will not be ' 'directory in the system temp folder. If specified, will not be '
'automatically removed at the end of execution.', 'automatically removed at the end of execution.',
); );
argParser.addFlag(
'verbose',
defaultsTo: false,
negatable: false,
help: 'Print verbose output for the analysis process.',
);
argParser.addFlag( argParser.addFlag(
'help', 'help',
defaultsTo: false, defaultsTo: false,
...@@ -100,7 +106,7 @@ void main(List<String> arguments) { ...@@ -100,7 +106,7 @@ void main(List<String> arguments) {
tempDirectory.createSync(); tempDirectory.createSync();
} }
try { try {
exitCode = SampleChecker(flutterPackage, tempDirectory: tempDirectory).checkSamples(); exitCode = SampleChecker(flutterPackage, tempDirectory: tempDirectory, verbose: parsedArguments['verbose']).checkSamples();
} on SampleCheckerException catch (e) { } on SampleCheckerException catch (e) {
stderr.write(e); stderr.write(e);
exit(1); exit(1);
...@@ -140,7 +146,7 @@ class SampleCheckerException implements Exception { ...@@ -140,7 +146,7 @@ class SampleCheckerException implements Exception {
/// don't necessarily match. It does, however, print the source of the /// don't necessarily match. It does, however, print the source of the
/// problematic line. /// problematic line.
class SampleChecker { class SampleChecker {
SampleChecker(this._flutterPackage, {Directory tempDirectory}) SampleChecker(this._flutterPackage, {Directory tempDirectory, this.verbose = false})
: _tempDirectory = tempDirectory, : _tempDirectory = tempDirectory,
_keepTmp = tempDirectory != null { _keepTmp = tempDirectory != null {
_tempDirectory ??= Directory.systemTemp.createTempSync('flutter_analyze_sample_code.'); _tempDirectory ??= Directory.systemTemp.createTempSync('flutter_analyze_sample_code.');
...@@ -153,7 +159,7 @@ class SampleChecker { ...@@ -153,7 +159,7 @@ class SampleChecker {
static const String _dartDocPrefixWithSpace = '$_dartDocPrefix '; static const String _dartDocPrefixWithSpace = '$_dartDocPrefix ';
/// A RegExp that matches the beginning of a dartdoc snippet or sample. /// A RegExp that matches the beginning of a dartdoc snippet or sample.
static final RegExp _dartDocSampleBeginRegex = RegExp(r'{@tool (sample|snippet)(?:| ([^}]*))}'); static final RegExp _dartDocSampleBeginRegex = RegExp(r'{@tool (sample|snippet|dartpad)(?:| ([^}]*))}');
/// A RegExp that matches the end of a dartdoc snippet or sample. /// A RegExp that matches the end of a dartdoc snippet or sample.
static final RegExp _dartDocSampleEndRegex = RegExp(r'{@end-tool}'); static final RegExp _dartDocSampleEndRegex = RegExp(r'{@end-tool}');
...@@ -167,6 +173,9 @@ class SampleChecker { ...@@ -167,6 +173,9 @@ class SampleChecker {
/// A RegExp that matches a Dart constructor. /// A RegExp that matches a Dart constructor.
static final RegExp _constructorRegExp = RegExp(r'(const\s+)?_*[A-Z][a-zA-Z0-9<>._]*\('); static final RegExp _constructorRegExp = RegExp(r'(const\s+)?_*[A-Z][a-zA-Z0-9<>._]*\(');
/// Whether or not to print verbose output.
final bool verbose;
/// Whether or not to keep the temp directory around after running. /// Whether or not to keep the temp directory around after running.
/// ///
/// Defaults to false. /// Defaults to false.
...@@ -313,6 +322,9 @@ class SampleChecker { ...@@ -313,6 +322,9 @@ class SampleChecker {
]; ];
print('Generating snippet for ${snippet.start?.filename}:${snippet.start?.line}'); print('Generating snippet for ${snippet.start?.filename}:${snippet.start?.line}');
final ProcessResult process = _runSnippetsScript(args); final ProcessResult process = _runSnippetsScript(args);
if (verbose) {
stderr.write('${process.stderr}');
}
if (process.exitCode != 0) { if (process.exitCode != 0) {
throw SampleCheckerException( throw SampleCheckerException(
'Unable to create snippet for ${snippet.start.filename}:${snippet.start.line} ' 'Unable to create snippet for ${snippet.start.filename}:${snippet.start.line} '
...@@ -427,7 +439,7 @@ class SampleChecker { ...@@ -427,7 +439,7 @@ class SampleChecker {
startLine = Line('', filename: relativeFilePath, line: lineNumber + 1, indent: 3); startLine = Line('', filename: relativeFilePath, line: lineNumber + 1, indent: 3);
inPreamble = true; inPreamble = true;
} else if (sampleMatch != null) { } else if (sampleMatch != null) {
inSnippet = sampleMatch != null && sampleMatch[1] == 'snippet'; inSnippet = sampleMatch != null && (sampleMatch[1] == 'snippet' || sampleMatch[1] == 'dartpad');
if (inSnippet) { if (inSnippet) {
startLine = Line( startLine = Line(
'', '',
......
...@@ -34,6 +34,26 @@ ...@@ -34,6 +34,26 @@
/// ``` /// ```
/// {@end-tool} /// {@end-tool}
/// ///
/// {@tool dartpad --template=stateless_widget_material}
/// Bla blabla blabla some [Text] when the `_blabla` blabla blabla is true, and
/// blabla it when it is blabla:
///
/// ```dart preamble
/// bool _visible = true;
/// final GlobalKey globalKey = GlobalKey();
/// ```
///
/// ```dart
/// Widget build(BuildContext context) {
/// return Opacity(
/// key: globalKey,
/// opacity: _visible ? 1.0 : 0.0,
/// child: const Text('Poor wandering ones!'),
/// );
/// }
/// ```
/// {@end-tool}
///
/// {@tool sample} /// {@tool sample}
/// Bla blabla blabla some [Text] when the `_blabla` blabla blabla is true, and /// Bla blabla blabla some [Text] when the `_blabla` blabla blabla is true, and
/// blabla finale blabla: /// blabla finale blabla:
......
...@@ -19,12 +19,17 @@ void main() { ...@@ -19,12 +19,17 @@ void main() {
expect(stderrLines, <String>[ expect(stderrLines, <String>[
'known_broken_documentation.dart:30:9: new Opacity(', 'known_broken_documentation.dart:30:9: new Opacity(',
'>>> Unnecessary new keyword (unnecessary_new)', '>>> Unnecessary new keyword (unnecessary_new)',
'known_broken_documentation.dart:42:9: new Opacity(', 'known_broken_documentation.dart:62:9: new Opacity(',
'>>> Unnecessary new keyword (unnecessary_new)', '>>> Unnecessary new keyword (unnecessary_new)',
'', '',
'Found 1 sample code errors.', 'Found 1 sample code errors.',
'', '',
]); ]);
expect(stdoutLines, <String>['Found 7 sample code sections.', 'Starting analysis of samples.', '']); expect(stdoutLines, <String>[
'Found 7 sample code sections.',
'Generating snippet for known_broken_documentation.dart:38',
'Starting analysis of samples.',
'',
]);
}, skip: Platform.isWindows); }, skip: Platform.isWindows);
} }
...@@ -79,10 +79,13 @@ enum _ContextMenuLocation { ...@@ -79,10 +79,13 @@ enum _ContextMenuLocation {
/// This sample shows a very simple CupertinoContextMenu for an empty red /// This sample shows a very simple CupertinoContextMenu for an empty red
/// 100x100 Container. Simply long press on it to open. /// 100x100 Container. Simply long press on it to open.
/// ///
/// ```dart imports
/// import 'package:flutter/cupertino.dart';
/// ```
///
/// ```dart /// ```dart
/// Widget build(BuildContext context) { /// Widget build(BuildContext context) {
/// return Scaffold( /// return Scaffold(
/// key: scaffoldKey,
/// body: Center( /// body: Center(
/// child: Container( /// child: Container(
/// width: 100, /// width: 100,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment