Rename 'application' back to 'module', and make 'app' the default again for templates. (#22888)

We decided that redefining the default for templates was premature. We're going to go back to having "module" in experimental land again, and we'll try again when we have the feature set fully baked.

This keeps the writing of the .metadata files, and writing the template type to them, because that was a good improvement, and there are still a bunch of added tests that improve our coverage.
diff --git a/packages/flutter_tools/lib/executable.dart b/packages/flutter_tools/lib/executable.dart
index 6d62a5e..d8c8c1a 100644
--- a/packages/flutter_tools/lib/executable.dart
+++ b/packages/flutter_tools/lib/executable.dart
@@ -56,7 +56,7 @@
     ChannelCommand(verboseHelp: verboseHelp),
     CleanCommand(),
     ConfigCommand(verboseHelp: verboseHelp),
-    CreateCommand(verboseHelp: verboseHelp),
+    CreateCommand(),
     DaemonCommand(hidden: !verboseHelp),
     DevicesCommand(),
     DoctorCommand(verbose: verbose),
diff --git a/packages/flutter_tools/lib/src/commands/create.dart b/packages/flutter_tools/lib/src/commands/create.dart
index 0fec5f0..a99b75c 100644
--- a/packages/flutter_tools/lib/src/commands/create.dart
+++ b/packages/flutter_tools/lib/src/commands/create.dart
@@ -25,15 +25,13 @@
 import '../version.dart';
 
 enum _ProjectType {
-  /// This is the legacy "app" module type that was created before the default
-  /// was "application". It is kept around to allow users to recreate files that
-  /// have been removed in old projects.
+  /// This is the default project with the user-managed host code.
+  /// It is different than the "module" template in that it exposes and doesn't
+  /// manage the platform code.
   app,
-  /// The is the default type of project created. It is an application with
+  /// The is a project that has managed platform host code. It is an application with
   /// ephemeral .ios and .android directories that can be updated automatically.
-  application,
-  /// This is the old name for the [application] style project.
-  module, // TODO(gspencer): deprecated -- should be removed once IntelliJ no longer uses it.
+  module,
   /// This is a Flutter Dart package project. It doesn't have any native
   /// components, only Dart.
   package,
@@ -43,11 +41,6 @@
 
 _ProjectType _stringToProjectType(String value) {
   _ProjectType result;
-  // TODO(gspencer): remove module when it is no longer used by IntelliJ plugin.
-  // Module is just an alias for application.
-  if (value == 'module') {
-    value = 'application';
-  }
   for (_ProjectType type in _ProjectType.values) {
     if (value == getEnumName(type)) {
       result = type;
@@ -58,7 +51,7 @@
 }
 
 class CreateCommand extends FlutterCommand {
-  CreateCommand({bool verboseHelp = false }) {
+  CreateCommand() {
     argParser.addFlag('pub',
       defaultsTo: true,
       help: 'Whether to run "flutter packages get" after the project has been created.'
@@ -82,23 +75,13 @@
       help: 'Specify the type of project to create.',
       valueHelp: 'type',
       allowedHelp: <String, String>{
-        getEnumName(_ProjectType.application): '(default) Generate a Flutter application.',
+        getEnumName(_ProjectType.app): '(default) Generate a Flutter application.',
         getEnumName(_ProjectType.package): 'Generate a shareable Flutter project containing modular '
             'Dart code.',
         getEnumName(_ProjectType.plugin): 'Generate a shareable Flutter project containing an API '
             'in Dart code with a platform-specific implementation for Android, for iOS code, or '
             'for both.',
-      }..addAll(verboseHelp
-          ? <String, String>{
-        getEnumName(_ProjectType.app): 'Generate the legacy form of an application project. Use '
-            '"application" instead, unless you are working with an existing legacy app project. '
-            'This is not just an alias for the "application" template, it produces different '
-            'output.',
-        getEnumName(_ProjectType.module): 'Legacy, deprecated form of an application project. Use '
-            '"application" instead. This is just an alias for the "application" template, it '
-            'produces the same output. It will be removed in a future release.',
-            }
-          : <String, String>{}),
+      },
       defaultsTo: null,
     );
     argParser.addOption(
@@ -227,7 +210,7 @@
         }
       }
     }
-    template ??= detectedProjectType ?? _ProjectType.application;
+    template ??= detectedProjectType ?? _ProjectType.app;
     if (detectedProjectType != null && template != detectedProjectType && metadataExists) {
       // We can only be definitive that this is the wrong type if the .metadata file
       // exists and contains a type that doesn't match.
@@ -235,7 +218,7 @@
           "existing template type of '${getEnumName(detectedProjectType)}'.");
     }
 
-    final bool generateApplication = template == _ProjectType.application;
+    final bool generateModule = template == _ProjectType.module;
     final bool generatePlugin = template == _ProjectType.plugin;
     final bool generatePackage = template == _ProjectType.package;
 
@@ -283,11 +266,10 @@
     int generatedFileCount = 0;
     switch (template) {
       case _ProjectType.app:
-        generatedFileCount += await _generateLegacyApp(relativeDir, templateContext);
+        generatedFileCount += await _generateApp(relativeDir, templateContext);
         break;
       case _ProjectType.module:
-      case _ProjectType.application:
-        generatedFileCount += await _generateApplication(relativeDir, templateContext);
+        generatedFileCount += await _generateModule(relativeDir, templateContext);
         break;
       case _ProjectType.package:
         generatedFileCount += await _generatePackage(relativeDir, templateContext);
@@ -305,13 +287,13 @@
         '${templateContext['projectName']}.dart',
       ));
       printStatus('Your package code is in $relativeMainPath');
-    } else if (generateApplication) {
+    } else if (generateModule) {
       final String relativeMainPath = fs.path.normalize(fs.path.join(
           relativeDirPath,
           'lib',
           'main.dart',
       ));
-      printStatus('Your application code is in $relativeMainPath.');
+      printStatus('Your module code is in $relativeMainPath.');
     } else {
       // Run doctor; tell the user the next steps.
       final FlutterProject project = await FlutterProject.fromPath(projectDirPath);
@@ -359,13 +341,13 @@
     return null;
   }
 
-  Future<int> _generateApplication(Directory directory, Map<String, dynamic> templateContext) async {
+  Future<int> _generateModule(Directory directory, Map<String, dynamic> templateContext) async {
     int generatedCount = 0;
     final String description = argResults.wasParsed('description')
         ? argResults['description']
-        : 'A new flutter application project.';
+        : 'A new flutter module project.';
     templateContext['description'] = description;
-    generatedCount += _renderTemplate(fs.path.join('application', 'common'), directory, templateContext);
+    generatedCount += _renderTemplate(fs.path.join('module', 'common'), directory, templateContext);
     if (argResults['pub']) {
       await pubGet(
         context: PubContext.create,
@@ -382,7 +364,7 @@
     int generatedCount = 0;
     final String description = argResults.wasParsed('description')
         ? argResults['description']
-        : 'A new flutter package project.';
+        : 'A new Flutter package project.';
     templateContext['description'] = description;
     generatedCount += _renderTemplate('package', directory, templateContext);
     if (argResults['pub']) {
@@ -423,11 +405,11 @@
     templateContext['pluginProjectName'] = projectName;
     templateContext['androidPluginIdentifier'] = androidPluginIdentifier;
 
-    generatedCount += await _generateLegacyApp(project.example.directory, templateContext);
+    generatedCount += await _generateApp(project.example.directory, templateContext);
     return generatedCount;
   }
 
-  Future<int> _generateLegacyApp(Directory directory, Map<String, dynamic> templateContext) async {
+  Future<int> _generateApp(Directory directory, Map<String, dynamic> templateContext) async {
     int generatedCount = 0;
     generatedCount += _renderTemplate('app', directory, templateContext);
     final FlutterProject project = await FlutterProject.fromDirectory(directory);
diff --git a/packages/flutter_tools/lib/src/commands/make_host_app_editable.dart b/packages/flutter_tools/lib/src/commands/make_host_app_editable.dart
index 2eee49b..d40dcd6 100644
--- a/packages/flutter_tools/lib/src/commands/make_host_app_editable.dart
+++ b/packages/flutter_tools/lib/src/commands/make_host_app_editable.dart
@@ -37,8 +37,8 @@
   Future<void> validateCommand() async {
     await super.validateCommand();
     _project = await FlutterProject.current();
-    if (!_project.isApplication)
-      throw ToolExit("Only projects created using 'flutter create -t application' can have their host apps made editable.");
+    if (!_project.isModule)
+      throw ToolExit("Only projects created using 'flutter create -t module' can have their host apps made editable.");
   }
 
   @override
diff --git a/packages/flutter_tools/lib/src/flutter_manifest.dart b/packages/flutter_tools/lib/src/flutter_manifest.dart
index 7e4068e..bb731d8 100644
--- a/packages/flutter_tools/lib/src/flutter_manifest.dart
+++ b/packages/flutter_tools/lib/src/flutter_manifest.dart
@@ -110,14 +110,14 @@
     return _flutterDescriptor['uses-material-design'] ?? false;
   }
 
-  /// True if this manifest declares a Flutter application project.
+  /// True if this manifest declares a Flutter module project.
   ///
-  /// A Flutter project is considered an application when it has a `application:`
-  /// descriptor. A Flutter application project supports integration into an
-  /// existing host app.
+  /// A Flutter project is considered a module when it has a `module:`
+  /// descriptor. A Flutter module project supports integration into an
+  /// existing host app, and has managed platform host code.
   ///
-  /// Such a project can be created using `flutter create -t application`.
-  bool get isApplication => _flutterDescriptor.containsKey('application');
+  /// Such a project can be created using `flutter create -t module`.
+  bool get isModule => _flutterDescriptor.containsKey('module');
 
   /// True if this manifest declares a Flutter plugin project.
   ///
@@ -130,21 +130,21 @@
   bool get isPlugin => _flutterDescriptor.containsKey('plugin');
 
   /// Returns the Android package declared by this manifest in its
-  /// application or plugin descriptor. Returns null, if there is no
+  /// module or plugin descriptor. Returns null, if there is no
   /// such declaration.
   String get androidPackage {
-    if (isApplication)
-      return _flutterDescriptor['application']['androidPackage'];
+    if (isModule)
+      return _flutterDescriptor['module']['androidPackage'];
     if (isPlugin)
       return _flutterDescriptor['plugin']['androidPackage'];
     return null;
   }
 
   /// Returns the iOS bundle identifier declared by this manifest in its
-  /// application descriptor. Returns null, if there is no such declaration.
+  /// module descriptor. Returns null if there is no such declaration.
   String get iosBundleIdentifier {
-    if (isApplication)
-      return _flutterDescriptor['application']['iosBundleIdentifier'];
+    if (isModule)
+      return _flutterDescriptor['module']['iosBundleIdentifier'];
     return null;
   }
 
diff --git a/packages/flutter_tools/lib/src/ios/mac.dart b/packages/flutter_tools/lib/src/ios/mac.dart
index ea367fb..346392a 100644
--- a/packages/flutter_tools/lib/src/ios/mac.dart
+++ b/packages/flutter_tools/lib/src/ios/mac.dart
@@ -335,7 +335,7 @@
     buildInfo: buildInfo,
   );
   refreshPluginsList(project);
-  if (hasPlugins(project) || (project.isApplication && project.ios.podfile.existsSync())) {
+  if (hasPlugins(project) || (project.isModule && project.ios.podfile.existsSync())) {
     // If the Xcode project, Podfile, or Generated.xcconfig have changed since
     // last run, pods should be updated.
     final Fingerprinter fingerprinter = Fingerprinter(
diff --git a/packages/flutter_tools/lib/src/ios/xcodeproj.dart b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
index 4b99549..2bb2a20 100644
--- a/packages/flutter_tools/lib/src/ios/xcodeproj.dart
+++ b/packages/flutter_tools/lib/src/ios/xcodeproj.dart
@@ -57,8 +57,8 @@
 
   localsBuffer.writeln('SYMROOT=\${SOURCE_ROOT}/../${getIosBuildDirectory()}');
 
-  if (!project.isApplication) {
-    // For application projects we do not want to write the FLUTTER_FRAMEWORK_DIR
+  if (!project.isModule) {
+    // For module projects we do not want to write the FLUTTER_FRAMEWORK_DIR
     // explicitly. Rather we rely on the xcode backend script and the Podfile
     // logic to derive it from FLUTTER_ROOT and FLUTTER_BUILD_MODE.
     localsBuffer.writeln('FLUTTER_FRAMEWORK_DIR=${flutterFrameworkDir(buildInfo.mode)}');
diff --git a/packages/flutter_tools/lib/src/plugins.dart b/packages/flutter_tools/lib/src/plugins.dart
index ba274eb..cd4827b 100644
--- a/packages/flutter_tools/lib/src/plugins.dart
+++ b/packages/flutter_tools/lib/src/plugins.dart
@@ -248,7 +248,7 @@
   };
 
   final String registryDirectory = project.ios.pluginRegistrantHost.path;
-  if (project.isApplication) {
+  if (project.isModule) {
     final String registryClassesDirectory = fs.path.join(registryDirectory, 'Classes');
     _renderTemplateToFile(
       _iosPluginRegistrantPodspecTemplate,
@@ -297,7 +297,7 @@
   final List<Plugin> plugins = findPlugins(project);
   await _writeAndroidPluginRegistrant(project, plugins);
   await _writeIOSPluginRegistrant(project, plugins);
-  if (!project.isApplication && project.ios.hostAppRoot.existsSync()) {
+  if (!project.isModule && project.ios.hostAppRoot.existsSync()) {
     final CocoaPods cocoaPods = CocoaPods();
     if (plugins.isNotEmpty)
       cocoaPods.setupPodfile(project.ios);
diff --git a/packages/flutter_tools/lib/src/project.dart b/packages/flutter_tools/lib/src/project.dart
index aade35b..9e9904d 100644
--- a/packages/flutter_tools/lib/src/project.dart
+++ b/packages/flutter_tools/lib/src/project.dart
@@ -110,10 +110,10 @@
     FlutterManifest.empty(),
   );
 
-  /// True, if this project is a Flutter application.
-  bool get isApplication => manifest.isApplication;
+  /// True if this project is a Flutter module project.
+  bool get isModule => manifest.isModule;
 
-  /// True, if this project has an example application.
+  /// True if this project has an example application.
   bool get hasExampleApp => _exampleDirectory(directory).existsSync();
 
   /// The directory that will contain the example if an example exists.
@@ -132,7 +132,7 @@
   }
 
   /// Generates project files necessary to make Gradle builds work on Android
-  /// and CocoaPods+Xcode work on iOS, for app and application projects only.
+  /// and CocoaPods+Xcode work on iOS, for app and module projects only.
   Future<void> ensureReadyForPlatformSpecificTooling() async {
     if (!directory.existsSync() || hasExampleApp)
       return;
@@ -146,7 +146,7 @@
 /// Represents the iOS sub-project of a Flutter project.
 ///
 /// Instances will reflect the contents of the `ios/` sub-folder of
-/// Flutter applications and the `.ios/` sub-folder of Flutter applications.
+/// Flutter applications and the `.ios/` sub-folder of Flutter module projects.
 class IosProject {
   IosProject._(this.parent);
 
@@ -162,7 +162,7 @@
 
   /// This parent folder of `Runner.xcodeproj`.
   Directory get hostAppRoot {
-    if (!isApplication || _editableDirectory.existsSync())
+    if (!isModule || _editableDirectory.existsSync())
       return _editableDirectory;
     return _ephemeralDirectory;
   }
@@ -172,14 +172,14 @@
   /// during build.
   ///
   /// This is the same as [hostAppRoot] except when the project is
-  /// a Flutter application with an editable host app.
-  Directory get _flutterLibRoot => isApplication ? _ephemeralDirectory : _editableDirectory;
+  /// a Flutter module with an editable host app.
+  Directory get _flutterLibRoot => isModule ? _ephemeralDirectory : _editableDirectory;
 
   /// The bundle name of the host app, `Runner.app`.
   String get hostAppBundleName => '$_hostAppBundleName.app';
 
-  /// True, if the parent Flutter project is an application.
-  bool get isApplication => parent.isApplication;
+  /// True, if the parent Flutter project is a module project.
+  bool get isModule => parent.isModule;
 
   /// The xcode config file for [mode].
   File xcodeConfigFor(String mode) => _flutterLibRoot.childDirectory('Flutter').childFile('$mode.xcconfig');
@@ -264,32 +264,32 @@
   }
 
   void _regenerateFromTemplateIfNeeded() {
-    if (!isApplication)
+    if (!isModule)
       return;
     final bool pubspecChanged = isOlderThanReference(entity: _ephemeralDirectory, referenceFile: parent.pubspecFile);
     final bool toolingChanged = Cache.instance.isOlderThanToolsStamp(_ephemeralDirectory);
     if (!pubspecChanged && !toolingChanged)
       return;
     _deleteIfExistsSync(_ephemeralDirectory);
-    _overwriteFromTemplate(fs.path.join('application', 'ios', 'library'), _ephemeralDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'ios', 'library'), _ephemeralDirectory);
     // Add ephemeral host app, if a editable host app does not already exist.
     if (!_editableDirectory.existsSync()) {
-      _overwriteFromTemplate(fs.path.join('application', 'ios', 'host_app_ephemeral'), _ephemeralDirectory);
+      _overwriteFromTemplate(fs.path.join('module', 'ios', 'host_app_ephemeral'), _ephemeralDirectory);
       if (hasPlugins(parent)) {
-        _overwriteFromTemplate(fs.path.join('application', 'ios', 'host_app_ephemeral_cocoapods'), _ephemeralDirectory);
+        _overwriteFromTemplate(fs.path.join('module', 'ios', 'host_app_ephemeral_cocoapods'), _ephemeralDirectory);
       }
     }
   }
 
   Future<void> makeHostAppEditable() async {
-    assert(isApplication);
+    assert(isModule);
     if (_editableDirectory.existsSync())
       throwToolExit('iOS host app is already editable. To start fresh, delete the ios/ folder.');
     _deleteIfExistsSync(_ephemeralDirectory);
-    _overwriteFromTemplate(fs.path.join('application', 'ios', 'library'), _ephemeralDirectory);
-    _overwriteFromTemplate(fs.path.join('application', 'ios', 'host_app_ephemeral'), _editableDirectory);
-    _overwriteFromTemplate(fs.path.join('application', 'ios', 'host_app_ephemeral_cocoapods'), _editableDirectory);
-    _overwriteFromTemplate(fs.path.join('application', 'ios', 'host_app_editable_cocoapods'), _editableDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'ios', 'library'), _ephemeralDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'ios', 'host_app_ephemeral'), _editableDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'ios', 'host_app_ephemeral_cocoapods'), _editableDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'ios', 'host_app_editable_cocoapods'), _editableDirectory);
     await _updateGeneratedXcodeConfigIfNeeded();
     await injectPlugins(parent);
   }
@@ -297,7 +297,7 @@
   File get generatedXcodePropertiesFile => _flutterLibRoot.childDirectory('Flutter').childFile('Generated.xcconfig');
 
   Directory get pluginRegistrantHost {
-    return isApplication
+    return isModule
         ? _flutterLibRoot.childDirectory('Flutter').childDirectory('FlutterPluginRegistrant')
         : hostAppRoot.childDirectory(_hostAppBundleName);
   }
@@ -319,7 +319,7 @@
 /// Represents the Android sub-project of a Flutter project.
 ///
 /// Instances will reflect the contents of the `android/` sub-folder of
-/// Flutter applications and the `.android/` sub-folder of Flutter applications.
+/// Flutter applications and the `.android/` sub-folder of Flutter module projects.
 class AndroidProject {
   AndroidProject._(this.parent);
 
@@ -333,21 +333,21 @@
   /// containing the `app/` subdirectory and the `settings.gradle` file that
   /// includes it in the overall Gradle project.
   Directory get hostAppGradleRoot {
-    if (!isApplication || _editableHostAppDirectory.existsSync())
+    if (!isModule || _editableHostAppDirectory.existsSync())
       return _editableHostAppDirectory;
     return _ephemeralDirectory;
   }
 
   /// The Gradle root directory of the Android wrapping of Flutter and plugins.
   /// This is the same as [hostAppGradleRoot] except when the project is
-  /// a Flutter application with an editable host app.
-  Directory get _flutterLibGradleRoot => isApplication ? _ephemeralDirectory : _editableHostAppDirectory;
+  /// a Flutter module with an editable host app.
+  Directory get _flutterLibGradleRoot => isModule ? _ephemeralDirectory : _editableHostAppDirectory;
 
   Directory get _ephemeralDirectory => parent.directory.childDirectory('.android');
   Directory get _editableHostAppDirectory => parent.directory.childDirectory('android');
 
-  /// True, if the parent Flutter project is an application.
-  bool get isApplication => parent.isApplication;
+  /// True if the parent Flutter project is a module.
+  bool get isModule => parent.isModule;
 
   File get appManifestFile {
     return isUsingGradle
@@ -376,12 +376,12 @@
   }
 
   Future<void> ensureReadyForPlatformSpecificTooling() async {
-    if (isApplication && _shouldRegenerateFromTemplate()) {
+    if (isModule && _shouldRegenerateFromTemplate()) {
       _regenerateLibrary();
       // Add ephemeral host app, if an editable host app does not already exist.
       if (!_editableHostAppDirectory.existsSync()) {
-        _overwriteFromTemplate(fs.path.join('application', 'android', 'host_app_common'), _ephemeralDirectory);
-        _overwriteFromTemplate(fs.path.join('application', 'android', 'host_app_ephemeral'), _ephemeralDirectory);
+        _overwriteFromTemplate(fs.path.join('module', 'android', 'host_app_common'), _ephemeralDirectory);
+        _overwriteFromTemplate(fs.path.join('module', 'android', 'host_app_ephemeral'), _ephemeralDirectory);
       }
     }
     if (!hostAppGradleRoot.existsSync()) {
@@ -396,13 +396,13 @@
   }
 
   Future<void> makeHostAppEditable() async {
-    assert(isApplication);
+    assert(isModule);
     if (_editableHostAppDirectory.existsSync())
       throwToolExit('Android host app is already editable. To start fresh, delete the android/ folder.');
     _regenerateLibrary();
-    _overwriteFromTemplate(fs.path.join('application', 'android', 'host_app_common'), _editableHostAppDirectory);
-    _overwriteFromTemplate(fs.path.join('application', 'android', 'host_app_editable'), _editableHostAppDirectory);
-    _overwriteFromTemplate(fs.path.join('application', 'android', 'gradle'), _editableHostAppDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'android', 'host_app_common'), _editableHostAppDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'android', 'host_app_editable'), _editableHostAppDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'android', 'gradle'), _editableHostAppDirectory);
     gradle.injectGradleWrapper(_editableHostAppDirectory);
     gradle.writeLocalProperties(_editableHostAppDirectory.childFile('local.properties'));
     await injectPlugins(parent);
@@ -410,12 +410,12 @@
 
   File get localPropertiesFile => _flutterLibGradleRoot.childFile('local.properties');
 
-  Directory get pluginRegistrantHost => _flutterLibGradleRoot.childDirectory(isApplication ? 'Flutter' : 'app');
+  Directory get pluginRegistrantHost => _flutterLibGradleRoot.childDirectory(isModule ? 'Flutter' : 'app');
 
   void _regenerateLibrary() {
     _deleteIfExistsSync(_ephemeralDirectory);
-    _overwriteFromTemplate(fs.path.join('application', 'android', 'library'), _ephemeralDirectory);
-    _overwriteFromTemplate(fs.path.join('application', 'android', 'gradle'), _ephemeralDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'android', 'library'), _ephemeralDirectory);
+    _overwriteFromTemplate(fs.path.join('module', 'android', 'gradle'), _ephemeralDirectory);
     gradle.injectGradleWrapper(_ephemeralDirectory);
   }