@@ -12,6 +12,7 @@ import 'package:analyzer/dart/analysis/results.dart';
1212import 'package:analyzer/dart/analysis/utilities.dart' ;
1313import 'package:analyzer/dart/ast/ast.dart' ;
1414import 'package:analyzer/dart/ast/visitor.dart' ;
15+ import 'package:collection/equality.dart' ;
1516import 'package:crypto/crypto.dart' ;
1617import 'package:meta/meta.dart' ;
1718import 'package:path/path.dart' as path;
@@ -252,6 +253,10 @@ Future<void> run(List<String> arguments) async {
252253 printProgress ('Correct file names in gen_defaults.dart...' );
253254 await verifyTokenTemplatesUpdateCorrectFiles (flutterRoot);
254255
256+ // Ensure material library files are up-to-date with the token template files.
257+ printProgress ('Material library files are up-to-date with token template files...' );
258+ await verifyMaterialFilesAreUpToDateWithTemplateFiles (flutterRoot, dart);
259+
255260 // Ensure integration test files are up-to-date with the app template.
256261 printProgress ('Up to date integration test template files...' );
257262 await verifyIntegrationTestTemplateFiles (flutterRoot);
@@ -399,6 +404,78 @@ Future<void> verifyTokenTemplatesUpdateCorrectFiles(String workingDirectory) asy
399404 }
400405}
401406
407+ /// Verify Material library files are up-to-date with the token template files
408+ /// when running /dev/tools/gen_defaults/bin/gen_defaults.dart.
409+ Future <void > verifyMaterialFilesAreUpToDateWithTemplateFiles (String workingDirectory, String dartExecutable) async {
410+ final List <String > errors = < String > [];
411+ const String beginGeneratedComment = '// BEGIN GENERATED TOKEN PROPERTIES' ;
412+
413+ String getMaterialDirPath (List <String > lines) {
414+ final String line = lines.firstWhere ((String line) => line.contains ('String materialLib' ));
415+ final String relativePath = line.substring (line.indexOf ("'" ) + 1 , line.lastIndexOf ("'" ));
416+ return path.join (workingDirectory, relativePath);
417+ }
418+
419+ String getFileName (String line) {
420+ const String materialLibString = r"'$materialLib/" ;
421+ final String leftClamp = line.substring (line.indexOf (materialLibString) + materialLibString.length);
422+ return leftClamp.substring (0 , leftClamp.indexOf ("'" ));
423+ }
424+
425+ // Get the template generated code from the file.
426+ List <String > getGeneratedCode (List <String > lines) {
427+ return lines.skipWhile ((String line) => ! line.contains (beginGeneratedComment)).toList ();
428+ }
429+
430+ final String genDefaultsBinDir = '$workingDirectory /dev/tools/gen_defaults/bin' ;
431+ final File file = File (path.join (genDefaultsBinDir, 'gen_defaults.dart' ));
432+ final List <String > lines = file.readAsLinesSync ();
433+ final String materialDirPath = getMaterialDirPath (lines);
434+ final Map <String , List <String >> beforeGeneratedCode = < String , List <String >> {};
435+ final Map <String , List <String >> afterGeneratedCode = < String , List <String >> {};
436+
437+ for (final String line in lines) {
438+ if (line.contains ('updateFile();' )) {
439+ final String fileName = getFileName (line);
440+ final String filePath = path.join (materialDirPath, fileName);
441+ final File file = File (filePath);
442+ beforeGeneratedCode[fileName] = getGeneratedCode (file.readAsLinesSync ());
443+ }
444+ }
445+
446+ // Run gen_defaults.dart to generate the token template files.
447+ await runCommand (dartExecutable,
448+ < String > ['--enable-asserts' , path.join ('dev' , 'tools' , 'gen_defaults' , 'bin' , 'gen_defaults.dart' )],
449+ workingDirectory: workingDirectory,
450+ );
451+
452+ for (final String line in lines) {
453+ if (line.contains ('updateFile();' )) {
454+ final String fileName = getFileName (line);
455+ final String filePath = path.join (materialDirPath, fileName);
456+ final File file = File (filePath);
457+ afterGeneratedCode[fileName] = getGeneratedCode (file.readAsLinesSync ());
458+ }
459+ }
460+
461+ // Compare the generated code before and after running gen_defaults.dart.
462+ for (final String fileName in beforeGeneratedCode.keys) {
463+ final List <String > before = beforeGeneratedCode[fileName]! ;
464+ final List <String > after = afterGeneratedCode[fileName]! ;
465+ if (! const IterableEquality <String >().equals (before, after)) {
466+ errors.add ('$fileName is not up-to-date with the token template file.' );
467+ }
468+ }
469+
470+ // Fail if any errors.
471+ if (errors.isNotEmpty) {
472+ foundError (< String > [
473+ ...errors,
474+ '${bold }See: https://github.com/flutter/flutter/blob/master/dev/tools/gen_defaults to update the token template files.$reset ' ,
475+ ]);
476+ }
477+ }
478+
402479/// Verify tool test files end in `_test.dart` .
403480///
404481/// The test runner will only recognize files ending in `_test.dart` as tests to
0 commit comments