generateCode method
The main routine for generating code samples from the source code doc comments.
The sample
is the block of sample code from a dartdoc comment.
The optional output
is the file to write the generated sample code to.
If addSectionMarkers
is true, then markers will be added before and
after each template section in the output. This is intended to facilitate
editing of the sample during the authoring process.
If includeAssumptions
is true, then the block in the "Examples can
assume:" block will also be included in the output.
Returns a string containing the resulting code sample.
Implementation
String generateCode(
CodeSample sample, {
File? output,
String? copyright,
String? description,
bool formatOutput = true,
bool addSectionMarkers = false,
bool includeAssumptions = false,
}) {
sample.metadata['copyright'] ??= copyright;
final List<TemplateInjection> snippetData = parseInput(sample);
sample.description = description ?? sample.description;
sample.metadata['description'] = _getDescription(sample);
switch (sample.runtimeType) {
case DartpadSample:
case ApplicationSample:
String app;
if (sample.sourceFile == null) {
final String templateName = sample.template;
if (templateName.isEmpty) {
io.stderr
.writeln('Non-linked samples must have a --template argument.');
io.exit(1);
}
final Directory templatesDir = configuration.templatesDirectory;
File? templateFile;
templateFile =
getTemplatePath(templateName, templatesDir: templatesDir);
if (templateFile == null) {
io.stderr.writeln(
'The template $templateName was not found in the templates '
'directory ${templatesDir.path}');
io.exit(1);
}
final String templateContents = _loadFileAsUtf8(templateFile);
final String templateRelativePath =
templateFile.absolute.path.contains(flutterRoot.absolute.path)
? path.relative(templateFile.absolute.path,
from: flutterRoot.absolute.path)
: templateFile.absolute.path;
final String templateHeader = '''
// Template: $templateRelativePath
//
// Comment lines marked with "▼▼▼" and "▲▲▲" are used for authoring
// of samples, and may be ignored if you are just exploring the sample.
''';
app = interpolateTemplate(
snippetData,
addSectionMarkers
? '$templateHeader\n$templateContents'
: templateContents,
sample.metadata,
addSectionMarkers: addSectionMarkers,
addCopyright: copyright != null,
);
} else {
app = sample.sourceFileContents;
}
sample.output = app;
if (formatOutput) {
final DartFormatter formatter =
DartFormatter(pageWidth: 80, fixes: StyleFix.all);
try {
sample.output = formatter.format(sample.output);
} on FormatterException catch (exception) {
io.stderr
.write('Code to format:\n${_addLineNumbers(sample.output)}\n');
errorExit('Unable to format sample code: $exception');
}
sample.output = sortImports(sample.output);
}
if (output != null) {
output.writeAsStringSync(sample.output);
final File metadataFile = configuration.filesystem.file(path.join(
path.dirname(output.path),
'${path.basenameWithoutExtension(output.path)}.json'));
sample.metadata['file'] = path.basename(output.path);
final Map<String, Object?> metadata = sample.metadata;
if (metadata.containsKey('description')) {
metadata['description'] = (metadata['description']! as String)
.replaceAll(RegExp(r'^// ?', multiLine: true), '');
}
metadataFile.writeAsStringSync(jsonEncoder.convert(metadata));
}
break;
case SnippetSample:
if (sample is SnippetSample) {
String app;
if (sample.sourceFile == null) {
String templateContents;
if (includeAssumptions) {
templateContents =
'${headers.map<String>((SourceLine line) => line.text).join('\n')}\n{{#assumptions}}\n{{description}}\n{{code}}';
} else {
templateContents = '{{description}}\n{{code}}';
}
app = interpolateTemplate(
snippetData,
templateContents,
sample.metadata,
addSectionMarkers: addSectionMarkers,
addCopyright: copyright != null,
);
} else {
app = sample.inputAsString;
}
sample.output = app;
}
break;
}
return sample.output;
}