From a516a24e794d4f1f0e886e40ae8a57d4828b4066 Mon Sep 17 00:00:00 2001 From: Ian Hickson Date: Mon, 16 Dec 2019 12:33:01 -0800 Subject: [PATCH] Update internal dartdoc snippet documentation (#47017) --- dev/bots/analyze-sample-code.dart | 60 ++++----------------- dev/bots/test/analyze-sample-code_test.dart | 5 +- dev/snippets/README.md | 58 +++++++++++++++++++- 3 files changed, 70 insertions(+), 53 deletions(-) diff --git a/dev/bots/analyze-sample-code.dart b/dev/bots/analyze-sample-code.dart index 445871a1e8..f4422340f7 100644 --- a/dev/bots/analyze-sample-code.dart +++ b/dev/bots/analyze-sample-code.dart @@ -2,54 +2,16 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -// This script analyzes all the sample code in API docs in the Flutter source. -// -// It uses the following conventions: -// -// Code is denoted by markdown ```dart / ``` markers. -// -// Only code in "## Sample code" or "### Sample code" sections is examined. -// Subheadings can also be specified, as in "## Sample code: foo". -// -// Additionally, code inside of dartdoc snippet and sample blocks -// ({@tool snippet ...}{@end-tool}, and {@tool sample ...}{@end-tool}) -// is recognized as sample code. Snippets are processed as separate programs, -// and samples are processed in the same way as "## Sample code" blocks are. -// -// There are several kinds of sample code you can specify: -// -// * Constructor calls, typically showing what might exist in a build method. -// These start with "new" or "const", and will be inserted into an assignment -// expression assigning to a variable of type "dynamic" and followed by a -// semicolon, for the purposes of analysis. -// -// * Class definitions. These start with "class", and are analyzed verbatim. -// -// * Other code. It gets included verbatim, though any line that says "// ..." -// is considered to separate the block into multiple blocks to be processed -// individually. -// -// In addition, you can declare code that should be included in the analysis but -// not shown in the API docs by adding a comment "// Examples can assume:" to -// the file (usually at the top of the file, after the imports), following by -// one or more commented-out lines of code. That code is included verbatim in -// the analysis. -// -// All the sample code of every file is analyzed together. This means you can't -// have two pieces of sample code that define the same example class. -// -// Also, the above means that it's tricky to include verbatim imperative code -// (e.g. a call to a method), since it won't be valid to have such code at the -// top level. Instead, wrap it in a function or even a whole class, or make it a -// valid variable declaration. +// See ../snippets/README.md for documentation. + +// To run this, from the root of the Flutter repository: +// bin/cache/dart-sdk/bin/dart dev/bots/analyze-sample-code.dart import 'dart:io'; import 'package:args/args.dart'; import 'package:path/path.dart' as path; -// To run this: bin/cache/dart-sdk/bin/dart dev/bots/analyze-sample-code.dart - final String _flutterRoot = path.dirname(path.dirname(path.dirname(path.fromUri(Platform.script)))); final String _defaultFlutterPackage = path.join(_flutterRoot, 'packages', 'flutter', 'lib'); final String _flutter = path.join(_flutterRoot, 'bin', Platform.isWindows ? 'flutter.bat' : 'flutter'); @@ -60,8 +22,8 @@ void main(List arguments) { 'temp', defaultsTo: null, help: 'A location where temporary files may be written. Defaults to a ' - 'directory in the system temp folder. If specified, will not be ' - 'automatically removed at the end of execution.', + 'directory in the system temp folder. If specified, will not be ' + 'automatically removed at the end of execution.', ); argParser.addFlag( 'verbose', @@ -80,6 +42,7 @@ void main(List arguments) { if (parsedArguments['help'] as bool) { print(argParser.usage); + print('See dev/snippets/README.md for documentation.'); exit(0); } @@ -325,11 +288,11 @@ class SampleChecker { '--input=${inputFile.absolute.path}', ...snippet.args, ]; - print('Generating snippet for ${snippet.start?.filename}:${snippet.start?.line}'); + if (verbose) + print('Generating snippet for ${snippet.start?.filename}:${snippet.start?.line}'); final ProcessResult process = _runSnippetsScript(args); - if (verbose) { + if (verbose) stderr.write('${process.stderr}'); - } if (process.exitCode != 0) { throw SampleCheckerException( 'Unable to create snippet for ${snippet.start.filename}:${snippet.start.line} ' @@ -831,8 +794,7 @@ class Line { String toString() => '$filename:$line: $code'; } -/// A class to represent a section of sample code, either marked by -/// "/// ## Sample code" in the comment, or by "{@tool sample}...{@end-tool}". +/// A class to represent a section of sample code, marked by "{@tool sample}...{@end-tool}". class Section { const Section(this.code); factory Section.combine(List
sections) { diff --git a/dev/bots/test/analyze-sample-code_test.dart b/dev/bots/test/analyze-sample-code_test.dart index 1e18691e59..487f5dd3e3 100644 --- a/dev/bots/test/analyze-sample-code_test.dart +++ b/dev/bots/test/analyze-sample-code_test.dart @@ -1,4 +1,4 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. + // Copyright 2014 The Flutter Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -27,8 +27,7 @@ void main() { ]); expect(stdoutLines, [ 'Found 7 sample code sections.', - 'Generating snippet for known_broken_documentation.dart:38', - 'Starting analysis of samples.', + 'Starting analysis of samples.', '', ]); }, skip: Platform.isWindows); diff --git a/dev/snippets/README.md b/dev/snippets/README.md index 6d4fa62b0d..87fe24ea0d 100644 --- a/dev/snippets/README.md +++ b/dev/snippets/README.md @@ -13,8 +13,17 @@ in the source code into API documentation, as seen on https://api.flutter.dev/. - [Snippet tool](#snippet-tool) - [Skeletons](#skeletons) - [Test Doc Generation Workflow](#test-doc-generation-workflow) + ## Types of code blocks +There's two kinds of code blocks. + +* samples, which are more or less context-free snippets that we + magically determine how to analyze, and + +* snippets, which get placed into a full-fledged application, and can + be actually executed inline in the documentation using DartPad. + ### Sample Tool ![Code sample image](assets/code_sample.png) @@ -39,7 +48,48 @@ code. Here is an example of the code `sample` tool in use: This will generate sample code that can be copied to the clipboard and added to existing applications. -This uses the skeleton for [sample](config/skeletons/sample.html) snippets. +This uses the skeleton for [sample](config/skeletons/sample.html) +snippets when generating the HTML to put into the Dart docs. + +#### Analysis + +The `../bots/analyze-sample-code.dart` script finds code inside the +`@tool sample` sections and uses the Dart analyzer to check them. + +There are several kinds of sample code you can specify: + +* Constructor calls, typically showing what might exist in a build + method. These will be inserted into an assignment expression + assigning to a variable of type "dynamic" and followed by a + semicolon, for the purposes of analysis. + +* Class definitions. These start with "class", and are analyzed + verbatim. + +* Other code. It gets included verbatim, though any line that says + `// ...` is considered to separate the block into multiple blocks + to be processed individually. + +The above means that it's tricky to include verbatim imperative code +(e.g. a call to a method), since it won't be valid to have such code +at the top level. Instead, wrap it in a function or even a whole +class, or make it a valid variable declaration. + +You can declare code that should be included in the analysis but not +shown in the API docs by adding a comment "// Examples can assume:" to +the file (usually at the top of the file, after the imports), +following by one or more commented-out lines of code. That code is +included verbatim in the analysis. For example: + +```dart +// Examples can assume: +// final BuildContext context; +// final String userAvatarUrl; +``` + +You can assume that the entire Flutter framework and most common +`dart:*` packages are imported and in scope; `dart:math` as `math` and +`dart:ui` as `ui`. ### Snippet Tool @@ -99,6 +149,12 @@ flutter app package. For more information about how to create, use, or update templates, see [config/templates/README.md](config/templates/README.md). +#### Analysis + +The `../bots/analyze-sample-code.dart` script finds code inside the +`@tool snippet` sections and uses the Dart analyzer to check them +after applying the specified template. + ## Skeletons A skeleton (in relation to this tool) is an HTML template into which the Dart