Version 1.13.0-dev.7.12

Cherry-pick 879cf82b6b29fe3669d48e75a4ecb9bc6b7f8b3a to dev
Cherry-pick aaaf7c2de8708e534acaeee60b692ba2bb08e4d1 to dev
diff --git a/pkg/analysis_server/lib/plugin/analysis/analyzed_files.dart b/pkg/analysis_server/lib/plugin/analysis/analyzed_files.dart
index b05bc97..cf728ae 100644
--- a/pkg/analysis_server/lib/plugin/analysis/analyzed_files.dart
+++ b/pkg/analysis_server/lib/plugin/analysis/analyzed_files.dart
@@ -6,41 +6,35 @@
  * Support for client code that extends the set of files being analyzed by the
  * analysis server.
  *
- * Plugins can register a function that takes a [File] and returns a [bool]
- * indicating whether the plugin is interested in having that file be analyzed.
- * The analysis server will invoke the contributed functions and analyze the
- * file if at least one of the functions returns `true`. (The server is not
- * required to invoke every function with every file.)
+ * Plugins can contribute a list of file patterns. Any file whose path matches
+ * one or more of the contributed patterns will be analyzed. The file patterns
+ * are interpreted as glob patterns as defined by the 'glob' package.
  *
- * If a plugin is interested in analyzing a certain kind of files, it needs to
- * ensure that files of that kind will be analyzed. It should register a
- * function by including code like the following in the plugin's
+ * If a plugin is interested in analyzing a certain kind of file, it needs to
+ * ensure that files of that kind will be analyzed. It should register a list of
+ * file patterns by including code like the following in the plugin's
  * registerExtensions method:
  *
  *     @override
  *     void registerExtensions(RegisterExtension registerExtension) {
  *       ...
  *       registerExtension(
- *           ANALYZE_FILE_EXTENSION_POINT_ID,
- *           (File file) => file.path.endsWith(...));
+ *           ANALYZED_FILE_PATTERNS_EXTENSION_POINT_ID,
+ *           ['*.yaml']);
  *       ...
  *     }
  */
 library analysis_server.plugin.analysis.analyzed_files;
 
 import 'package:analysis_server/src/plugin/server_plugin.dart';
-import 'package:analyzer/file_system/file_system.dart';
 import 'package:plugin/plugin.dart';
 
 /**
- * The identifier of the extension point that allows plugins to register
- * functions that can cause files to be analyzed. The object used as an
- * extension must be a [ShouldAnalyzeFile] function.
+ * The identifier of the extension point that allows plugins to cause certain
+ * kinds of files to be analyzed. The object used as an extension must be a list
+ * of strings. The strings are interpreted as glob patterns as defined by the
+ * 'glob' package.
  */
-final String ANALYZE_FILE_EXTENSION_POINT_ID = Plugin.join(
-    ServerPlugin.UNIQUE_IDENTIFIER, ServerPlugin.ANALYZE_FILE_EXTENSION_POINT);
-
-/**
- * A function that returns `true` if the given [file] should be analyzed.
- */
-typedef bool ShouldAnalyzeFile(File file);
+final String ANALYZED_FILE_PATTERNS_EXTENSION_POINT_ID = Plugin.join(
+    ServerPlugin.UNIQUE_IDENTIFIER,
+    ServerPlugin.ANALYZED_FILE_PATTERNS_EXTENSION_POINT);
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index c42b327..60f8d8c 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -28,10 +28,12 @@
 import 'package:analyzer/src/generated/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
+import 'package:glob/glob.dart';
 import 'package:plugin/plugin.dart';
 
 typedef void OptionUpdater(AnalysisOptionsImpl options);
@@ -1410,8 +1412,35 @@
    */
   final ResourceProvider resourceProvider;
 
+  /**
+   * A list of the globs used to determine which files should be analyzed. The
+   * list is lazily created and should be accessed using [analyzedFilesGlobs].
+   */
+  List<Glob> _analyzedFilesGlobs = null;
+
   ServerContextManagerCallbacks(this.analysisServer, this.resourceProvider);
 
+  /**
+   * Return a list of the globs used to determine which files should be analyzed.
+   */
+  List<Glob> get analyzedFilesGlobs {
+    if (_analyzedFilesGlobs == null) {
+      _analyzedFilesGlobs = <Glob>[];
+      List<String> patterns = analysisServer.serverPlugin.analyzedFilePatterns;
+      for (String pattern in patterns) {
+        try {
+          _analyzedFilesGlobs
+              .add(new Glob(pattern, context: JavaFile.pathContext));
+        } catch (exception, stackTrace) {
+          AnalysisEngine.instance.logger.logError(
+              'Invalid glob pattern: "$pattern"',
+              new CaughtException(exception, stackTrace));
+        }
+      }
+    }
+    return _analyzedFilesGlobs;
+  }
+
   @override
   AnalysisContext addContext(Folder folder, FolderDisposition disposition) {
     InternalAnalysisContext context =
@@ -1469,10 +1498,8 @@
 
   @override
   bool shouldFileBeAnalyzed(File file) {
-    List<ShouldAnalyzeFile> functions =
-        analysisServer.serverPlugin.analyzeFileFunctions;
-    for (ShouldAnalyzeFile shouldAnalyzeFile in functions) {
-      if (shouldAnalyzeFile(file)) {
+    for (Glob glob in analyzedFilesGlobs) {
+      if (glob.matches(file.path)) {
         // Emacs creates dummy links to track the fact that a file is open for
         // editing and has unsaved changes (e.g. having unsaved changes to
         // 'foo.dart' causes a link '.#foo.dart' to be created, which points to
diff --git a/pkg/analysis_server/lib/src/plugin/server_plugin.dart b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
index c008c1c..b4de83f 100644
--- a/pkg/analysis_server/lib/src/plugin/server_plugin.dart
+++ b/pkg/analysis_server/lib/src/plugin/server_plugin.dart
@@ -31,7 +31,6 @@
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
 import 'package:analysis_server/src/services/index/index_contributor.dart';
-import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:plugin/plugin.dart';
 
@@ -48,9 +47,10 @@
 class ServerPlugin implements Plugin {
   /**
    * The simple identifier of the extension point that allows plugins to
-   * register functions that can cause files to be analyzed.
+   * register file patterns that will cause files to be analyzed.
    */
-  static const String ANALYZE_FILE_EXTENSION_POINT = 'analyzeFile';
+  static const String ANALYZED_FILE_PATTERNS_EXTENSION_POINT =
+      'analyzedFilePatterns';
 
   /**
    * The simple identifier of the extension point that allows plugins to
@@ -109,10 +109,10 @@
   static const String UNIQUE_IDENTIFIER = 'analysis_server.core';
 
   /**
-   * The extension point that allows plugins to register functions that can
+   * The extension point that allows plugins to register file patterns that will
    * cause files to be analyzed.
    */
-  ExtensionPoint analyzeFileExtensionPoint;
+  ExtensionPoint analyzedFilePatternsExtensionPoint;
 
   /**
    * The extension point that allows plugins to register assist contributors.
@@ -166,11 +166,17 @@
   ServerPlugin();
 
   /**
-   * Return a list containing all of the functions that can cause files to be
-   * analyzed.
+   * Return a list containing all of the file patterns that can cause files to
+   * be analyzed.
    */
-  List<ShouldAnalyzeFile> get analyzeFileFunctions =>
-      analyzeFileExtensionPoint.extensions;
+  List<String> get analyzedFilePatterns {
+    List<String> patterns = <String>[];
+    for (List<String> extension
+        in analyzedFilePatternsExtensionPoint.extensions) {
+      patterns.addAll(extension);
+    }
+    return patterns;
+  }
 
   /**
    * Return a list containing all of the assist contributors that were
@@ -241,8 +247,9 @@
     setAnalysisDomainExtensionPoint = registerExtensionPoint(
         SET_ANALISYS_DOMAIN_EXTENSION_POINT,
         _validateSetAnalysisDomainFunction);
-    analyzeFileExtensionPoint = registerExtensionPoint(
-        ANALYZE_FILE_EXTENSION_POINT, _validateAnalyzeFileExtension);
+    analyzedFilePatternsExtensionPoint = registerExtensionPoint(
+        ANALYZED_FILE_PATTERNS_EXTENSION_POINT,
+        _validateAnalyzedFilePatternsExtension);
     assistContributorExtensionPoint = registerExtensionPoint(
         ASSIST_CONTRIBUTOR_EXTENSION_POINT,
         _validateAssistContributorExtension);
@@ -266,13 +273,15 @@
   @override
   void registerExtensions(RegisterExtension registerExtension) {
     //
-    // Register analyze file functions.
+    // Register analyzed file patterns.
     //
-    registerExtension(
-        ANALYZE_FILE_EXTENSION_POINT_ID,
-        (File file) => AnalysisEngine.isDartFileName(file.path) ||
-            AnalysisEngine.isHtmlFileName(file.path) ||
-            AnalysisEngine.isAnalysisOptionsFileName(file.path));
+    List<String> patterns = <String>[
+      '{*:/,/}**/*.${AnalysisEngine.SUFFIX_DART}',
+      '{*:/,/}**/*.${AnalysisEngine.SUFFIX_HTML}',
+      '{*:/,/}**/*.${AnalysisEngine.SUFFIX_HTM}',
+      '{*:/,/}**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}'
+    ];
+    registerExtension(ANALYZED_FILE_PATTERNS_EXTENSION_POINT_ID, patterns);
     //
     // Register assist contributors.
     //
@@ -318,18 +327,29 @@
     //
     registerExtension(
         INDEX_CONTRIBUTOR_EXTENSION_POINT_ID, new DartIndexContributor());
+  }
 
+  /**
+   * Return `true` if the list being used as an [extension] contains any
+   * elements that are not strings.
+   */
+  bool _containsNonString(List extension) {
+    for (Object element in extension) {
+      if (element is! String) {
+        return true;
+      }
+    }
+    return false;
   }
 
   /**
    * Validate the given extension by throwing an [ExtensionError] if it is not a
-   * valid assist contributor.
+   * valid list of analyzed file patterns.
    */
-  void _validateAnalyzeFileExtension(Object extension) {
-    if (extension is! ShouldAnalyzeFile) {
-      String id = analyzeFileExtensionPoint.uniqueIdentifier;
-      throw new ExtensionError(
-          'Extensions to $id must be a ShouldAnalyzeFile function');
+  void _validateAnalyzedFilePatternsExtension(Object extension) {
+    if (extension is! List || _containsNonString(extension)) {
+      String id = analyzedFilePatternsExtensionPoint.uniqueIdentifier;
+      throw new ExtensionError('Extensions to $id must be a List of Strings');
     }
   }
 
diff --git a/tools/VERSION b/tools/VERSION
index ba645bc..8f8b388 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
 MINOR 13
 PATCH 0
 PRERELEASE 7
-PRERELEASE_PATCH 11
+PRERELEASE_PATCH 12