Support for mixins in search.getElementDeclarations.

R=brianwilkerson@google.com

Change-Id: I88e90159ae28a2585fdbaacca2c4caab15891b83
Reviewed-on: https://dart-review.googlesource.com/72523
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index b4c45b6..5cfd272 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  1.20.5
+  1.21.0
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -3248,6 +3248,12 @@
           The name of the class enclosing this declaration. If the declaration
           is not a class member, this field will be absent.
         </p>
+      </dd><dt class="field"><b>mixinName: String<span style="color:#999999"> (optional)</span></b></dt><dd>
+        
+        <p>
+          The name of the mixin enclosing this declaration. If the declaration
+          is not a mixin member, this field will be absent.
+        </p>
       </dd><dt class="field"><b>parameters: String<span style="color:#999999"> (optional)</span></b></dt><dd>
         
         <p>
@@ -3264,7 +3270,7 @@
       An enumeration of the kinds of elements.
     </p>
     
-  <dl><dt class="value">CLASS</dt><dt class="value">CLASS_TYPE_ALIAS</dt><dt class="value">COMPILATION_UNIT</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">CONSTRUCTOR_INVOCATION</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dt class="value">FILE</dt><dt class="value">FUNCTION</dt><dt class="value">FUNCTION_INVOCATION</dt><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY</dt><dt class="value">LOCAL_VARIABLE</dt><dt class="value">METHOD</dt><dt class="value">PARAMETER</dt><dt class="value">PREFIX</dt><dt class="value">SETTER</dt><dt class="value">TOP_LEVEL_VARIABLE</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNIT_TEST_GROUP</dt><dt class="value">UNIT_TEST_TEST</dt><dt class="value">UNKNOWN</dt></dl></dd><dt class="typeDefinition"><a name="type_ExecutableFile">ExecutableFile: object</a></dt><dd>
+  <dl><dt class="value">CLASS</dt><dt class="value">CLASS_TYPE_ALIAS</dt><dt class="value">COMPILATION_UNIT</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">CONSTRUCTOR_INVOCATION</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dt class="value">FILE</dt><dt class="value">FUNCTION</dt><dt class="value">FUNCTION_INVOCATION</dt><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY</dt><dt class="value">LOCAL_VARIABLE</dt><dt class="value">METHOD</dt><dt class="value">MIXIN</dt><dt class="value">PARAMETER</dt><dt class="value">PREFIX</dt><dt class="value">SETTER</dt><dt class="value">TOP_LEVEL_VARIABLE</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNIT_TEST_GROUP</dt><dt class="value">UNIT_TEST_TEST</dt><dt class="value">UNKNOWN</dt></dl></dd><dt class="typeDefinition"><a name="type_ExecutableFile">ExecutableFile: object</a></dt><dd>
     <p>
       A description of an executable file.
     </p>
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index a1b9422..b1f5dce 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -9001,6 +9001,7 @@
  *   "codeOffset": int
  *   "codeLength": int
  *   "className": optional String
+ *   "mixinName": optional String
  *   "parameters": optional String
  * }
  *
@@ -9025,6 +9026,8 @@
 
   String _className;
 
+  String _mixinName;
+
   String _parameters;
 
   /**
@@ -9146,6 +9149,20 @@
   }
 
   /**
+   * The name of the mixin enclosing this declaration. If the declaration is
+   * not a mixin member, this field will be absent.
+   */
+  String get mixinName => _mixinName;
+
+  /**
+   * The name of the mixin enclosing this declaration. If the declaration is
+   * not a mixin member, this field will be absent.
+   */
+  void set mixinName(String value) {
+    this._mixinName = value;
+  }
+
+  /**
    * The parameter list for the element. If the element is not a method or
    * function this field will not be defined. If the element doesn't have
    * parameters (e.g. getter), this field will not be defined. If the element
@@ -9169,7 +9186,7 @@
 
   ElementDeclaration(String name, ElementKind kind, int fileIndex, int offset,
       int line, int column, int codeOffset, int codeLength,
-      {String className, String parameters}) {
+      {String className, String mixinName, String parameters}) {
     this.name = name;
     this.kind = kind;
     this.fileIndex = fileIndex;
@@ -9179,6 +9196,7 @@
     this.codeOffset = codeOffset;
     this.codeLength = codeLength;
     this.className = className;
+    this.mixinName = mixinName;
     this.parameters = parameters;
   }
 
@@ -9245,6 +9263,11 @@
         className = jsonDecoder.decodeString(
             jsonPath + ".className", json["className"]);
       }
+      String mixinName;
+      if (json.containsKey("mixinName")) {
+        mixinName = jsonDecoder.decodeString(
+            jsonPath + ".mixinName", json["mixinName"]);
+      }
       String parameters;
       if (json.containsKey("parameters")) {
         parameters = jsonDecoder.decodeString(
@@ -9252,7 +9275,7 @@
       }
       return new ElementDeclaration(
           name, kind, fileIndex, offset, line, column, codeOffset, codeLength,
-          className: className, parameters: parameters);
+          className: className, mixinName: mixinName, parameters: parameters);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "ElementDeclaration", json);
     }
@@ -9272,6 +9295,9 @@
     if (className != null) {
       result["className"] = className;
     }
+    if (mixinName != null) {
+      result["mixinName"] = mixinName;
+    }
     if (parameters != null) {
       result["parameters"] = parameters;
     }
@@ -9293,6 +9319,7 @@
           codeOffset == other.codeOffset &&
           codeLength == other.codeLength &&
           className == other.className &&
+          mixinName == other.mixinName &&
           parameters == other.parameters;
     }
     return false;
@@ -9310,6 +9337,7 @@
     hash = JenkinsSmiHash.combine(hash, codeOffset.hashCode);
     hash = JenkinsSmiHash.combine(hash, codeLength.hashCode);
     hash = JenkinsSmiHash.combine(hash, className.hashCode);
+    hash = JenkinsSmiHash.combine(hash, mixinName.hashCode);
     hash = JenkinsSmiHash.combine(hash, parameters.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index 805344d..65be43a 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -180,6 +180,8 @@
           return protocol.ElementKind.GETTER;
         case search.DeclarationKind.METHOD:
           return protocol.ElementKind.METHOD;
+        case search.DeclarationKind.MIXIN:
+          return protocol.ElementKind.MIXIN;
         case search.DeclarationKind.SETTER:
           return protocol.ElementKind.SETTER;
         case search.DeclarationKind.VARIABLE:
@@ -216,6 +218,7 @@
           declaration.codeOffset,
           declaration.codeLength,
           className: declaration.className,
+          mixinName: declaration.mixinName,
           parameters: declaration.parameters);
     }).toList();
 
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index ad53598..11b741a 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -335,6 +335,7 @@
  *   "codeOffset": int
  *   "codeLength": int
  *   "className": optional String
+ *   "mixinName": optional String
  *   "parameters": optional String
  * }
  */
@@ -350,6 +351,7 @@
           "codeLength": isInt
         }, optionalFields: {
           "className": isString,
+          "mixinName": isString,
           "parameters": isString
         }));
 
@@ -374,6 +376,7 @@
  *   LIBRARY
  *   LOCAL_VARIABLE
  *   METHOD
+ *   MIXIN
  *   PARAMETER
  *   PREFIX
  *   SETTER
@@ -402,6 +405,7 @@
   "LIBRARY",
   "LOCAL_VARIABLE",
   "METHOD",
+  "MIXIN",
   "PARAMETER",
   "PREFIX",
   "SETTER",
diff --git a/pkg/analysis_server/test/search/declarations_test.dart b/pkg/analysis_server/test/search/declarations_test.dart
index d9efa99..8af7bf4 100644
--- a/pkg/analysis_server/test/search/declarations_test.dart
+++ b/pkg/analysis_server/test/search/declarations_test.dart
@@ -23,12 +23,13 @@
   SearchGetElementDeclarationsResult declarationsResult;
 
   ElementDeclaration assertHas(String name, ElementKind kind,
-      {String className}) {
+      {String className, String mixinName}) {
     return declarationsResult.declarations.singleWhere((ElementDeclaration d) =>
         declarationsResult.files[d.fileIndex] == testFile &&
         d.name == name &&
         d.kind == kind &&
-        d.className == className);
+        d.className == className &&
+        d.mixinName == mixinName);
   }
 
   void assertNo(String name) {
@@ -97,6 +98,24 @@
     expect(declarationsResult.declarations, hasLength(4));
   }
 
+  test_mixin() async {
+    addTestFile(r'''
+mixin M {
+  int f;
+  int get g => 0;
+  void set s(_) {}
+  void m() {}
+}
+''');
+    await _getDeclarations();
+
+    assertHas('M', ElementKind.MIXIN);
+    assertHas('f', ElementKind.FIELD, mixinName: 'M');
+    assertHas('g', ElementKind.GETTER, mixinName: 'M');
+    assertHas('s', ElementKind.SETTER, mixinName: 'M');
+    assertHas('m', ElementKind.METHOD, mixinName: 'M');
+  }
+
   test_multipleFiles() async {
     var a = newFile(join(testFolder, 'a.dart'), content: 'class A {}').path;
     var b = newFile(join(testFolder, 'b.dart'), content: 'class B {}').path;
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ElementDeclaration.java b/pkg/analysis_server/tool/spec/generated/java/types/ElementDeclaration.java
index 04da8df..736531f 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ElementDeclaration.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ElementDeclaration.java
@@ -82,6 +82,12 @@
   private final String className;
 
   /**
+   * The name of the mixin enclosing this declaration. If the declaration is not a mixin member, this
+   * field will be absent.
+   */
+  private final String mixinName;
+
+  /**
    * The parameter list for the element. If the element is not a method or function this field will
    * not be defined. If the element doesn't have parameters (e.g. getter), this field will not be
    * defined. If the element has zero parameters, this field will have a value of "()". The value
@@ -93,7 +99,7 @@
   /**
    * Constructor for {@link ElementDeclaration}.
    */
-  public ElementDeclaration(String name, String kind, int fileIndex, int offset, int line, int column, int codeOffset, int codeLength, String className, String parameters) {
+  public ElementDeclaration(String name, String kind, int fileIndex, int offset, int line, int column, int codeOffset, int codeLength, String className, String mixinName, String parameters) {
     this.name = name;
     this.kind = kind;
     this.fileIndex = fileIndex;
@@ -103,6 +109,7 @@
     this.codeOffset = codeOffset;
     this.codeLength = codeLength;
     this.className = className;
+    this.mixinName = mixinName;
     this.parameters = parameters;
   }
 
@@ -120,6 +127,7 @@
         other.codeOffset == codeOffset &&
         other.codeLength == codeLength &&
         ObjectUtilities.equals(other.className, className) &&
+        ObjectUtilities.equals(other.mixinName, mixinName) &&
         ObjectUtilities.equals(other.parameters, parameters);
     }
     return false;
@@ -135,8 +143,9 @@
     int codeOffset = jsonObject.get("codeOffset").getAsInt();
     int codeLength = jsonObject.get("codeLength").getAsInt();
     String className = jsonObject.get("className") == null ? null : jsonObject.get("className").getAsString();
+    String mixinName = jsonObject.get("mixinName") == null ? null : jsonObject.get("mixinName").getAsString();
     String parameters = jsonObject.get("parameters") == null ? null : jsonObject.get("parameters").getAsString();
-    return new ElementDeclaration(name, kind, fileIndex, offset, line, column, codeOffset, codeLength, className, parameters);
+    return new ElementDeclaration(name, kind, fileIndex, offset, line, column, codeOffset, codeLength, className, mixinName, parameters);
   }
 
   public static List<ElementDeclaration> fromJsonArray(JsonArray jsonArray) {
@@ -202,6 +211,14 @@
   }
 
   /**
+   * The name of the mixin enclosing this declaration. If the declaration is not a mixin member, this
+   * field will be absent.
+   */
+  public String getMixinName() {
+    return mixinName;
+  }
+
+  /**
    * The name of the declaration.
    */
   public String getName() {
@@ -238,6 +255,7 @@
     builder.append(codeOffset);
     builder.append(codeLength);
     builder.append(className);
+    builder.append(mixinName);
     builder.append(parameters);
     return builder.toHashCode();
   }
@@ -255,6 +273,9 @@
     if (className != null) {
       jsonObject.addProperty("className", className);
     }
+    if (mixinName != null) {
+      jsonObject.addProperty("mixinName", mixinName);
+    }
     if (parameters != null) {
       jsonObject.addProperty("parameters", parameters);
     }
@@ -283,6 +304,8 @@
     builder.append(codeLength + ", ");
     builder.append("className=");
     builder.append(className + ", ");
+    builder.append("mixinName=");
+    builder.append(mixinName + ", ");
     builder.append("parameters=");
     builder.append(parameters);
     builder.append("]");
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
index f572d75..3991c56 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/ElementKind.java
@@ -49,6 +49,8 @@
 
   public static final String METHOD = "METHOD";
 
+  public static final String MIXIN = "MIXIN";
+
   public static final String PARAMETER = "PARAMETER";
 
   public static final String PREFIX = "PREFIX";
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 3ecf1ea..2334b39 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  <version>1.20.5</version>
+  <version>1.21.0</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -3195,6 +3195,13 @@
           is not a class member, this field will be absent.
         </p>
       </field>
+      <field name="mixinName" optional="true">
+        <ref>String</ref>
+        <p>
+          The name of the mixin enclosing this declaration. If the declaration
+          is not a mixin member, this field will be absent.
+        </p>
+      </field>
       <field name="parameters" optional="true">
         <ref>String</ref>
         <p>
diff --git a/pkg/analyzer/lib/src/dart/analysis/search.dart b/pkg/analyzer/lib/src/dart/analysis/search.dart
index 61ace7d..38b6a6a 100644
--- a/pkg/analyzer/lib/src/dart/analysis/search.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/search.dart
@@ -40,6 +40,7 @@
   final int codeOffset;
   final int codeLength;
   final String className;
+  final String mixinName;
   final String parameters;
 
   Declaration(
@@ -52,6 +53,7 @@
       this.codeOffset,
       this.codeLength,
       this.className,
+      this.mixinName,
       this.parameters);
 }
 
@@ -69,6 +71,7 @@
   FUNCTION_TYPE_ALIAS,
   GETTER,
   METHOD,
+  MIXIN,
   SETTER,
   VARIABLE
 }
@@ -161,7 +164,7 @@
 
         void addDeclaration(String name, DeclarationKind kind, int offset,
             int codeOffset, int codeLength,
-            {String className, String parameters}) {
+            {String className, String mixinName, String parameters}) {
           if (maxResults != null && declarations.length >= maxResults) {
             throw const _MaxNumberOfDeclarationsError();
           }
@@ -189,6 +192,7 @@
               codeOffset,
               codeLength,
               className,
+              mixinName,
               parameters));
         }
 
@@ -208,22 +212,17 @@
           return getParametersString(executable.parameters);
         }
 
-        for (var class_ in unlinkedUnit.classes) {
-          String className = class_.name;
-          addDeclaration(
-              className,
-              class_.isMixinApplication
-                  ? DeclarationKind.CLASS_TYPE_ALIAS
-                  : DeclarationKind.CLASS,
-              class_.nameOffset,
-              class_.codeRange.offset,
-              class_.codeRange.length);
+        void addUnlinkedClass(UnlinkedClass class_, DeclarationKind kind,
+            {String className, String mixinName}) {
+          addDeclaration(class_.name, kind, class_.nameOffset,
+              class_.codeRange.offset, class_.codeRange.length);
+
           parameterComposer.outerTypeParameters = class_.typeParameters;
 
           for (var field in class_.fields) {
             addDeclaration(field.name, DeclarationKind.FIELD, field.nameOffset,
                 field.codeRange.offset, field.codeRange.length,
-                className: className);
+                className: className, mixinName: mixinName);
           }
 
           for (var executable in class_.executables) {
@@ -235,6 +234,7 @@
                 executable.codeRange.offset,
                 executable.codeRange.length,
                 className: className,
+                mixinName: mixinName,
                 parameters: getExecutableParameters(executable));
             parameterComposer.innerTypeParameters = const [];
           }
@@ -242,6 +242,17 @@
           parameterComposer.outerTypeParameters = const [];
         }
 
+        for (var class_ in unlinkedUnit.classes) {
+          var kind = class_.isMixinApplication
+              ? DeclarationKind.CLASS_TYPE_ALIAS
+              : DeclarationKind.CLASS;
+          addUnlinkedClass(class_, kind, className: class_.name);
+        }
+
+        for (var mixin in unlinkedUnit.mixins) {
+          addUnlinkedClass(mixin, DeclarationKind.MIXIN, mixinName: mixin.name);
+        }
+
         for (var enum_ in unlinkedUnit.enums) {
           addDeclaration(enum_.name, DeclarationKind.ENUM, enum_.nameOffset,
               enum_.codeRange.offset, enum_.codeRange.length);
diff --git a/pkg/analyzer/test/src/dart/analysis/search_test.dart b/pkg/analyzer/test/src/dart/analysis/search_test.dart
index bc9268e..9567ef9a 100644
--- a/pkg/analyzer/test/src/dart/analysis/search_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/search_test.dart
@@ -199,6 +199,30 @@
     expect(declarations, hasLength(2));
   }
 
+  test_declarations_mixin() async {
+    await _resolveTestUnit('''
+mixin M {
+  int f;
+  int get g => 0;
+  void set s(_) {}
+  void m() {}
+}
+''');
+    var files = new LinkedHashSet<String>();
+    List<Declaration> declarations =
+        await driver.search.declarations(null, null, files);
+    _assertHasDeclaration(declarations, 'M', DeclarationKind.MIXIN,
+        offset: 6, codeOffset: 0, codeLength: 71);
+    _assertHasDeclaration(declarations, 'f', DeclarationKind.FIELD,
+        offset: 16, codeOffset: 12, codeLength: 5, mixinName: 'M');
+    _assertHasDeclaration(declarations, 'g', DeclarationKind.GETTER,
+        offset: 29, codeOffset: 21, codeLength: 15, mixinName: 'M');
+    _assertHasDeclaration(declarations, 's', DeclarationKind.SETTER,
+        offset: 48, codeOffset: 39, codeLength: 16, mixinName: 'M');
+    _assertHasDeclaration(declarations, 'm', DeclarationKind.METHOD,
+        offset: 63, codeOffset: 58, codeLength: 11, mixinName: 'M');
+  }
+
   test_declarations_onlyForFile() async {
     var a = _p('/test/lib/a.dart');
     var b = _p('/test/lib/b.dart');
@@ -1860,14 +1884,19 @@
 
   Declaration _assertHasDeclaration(
       List<Declaration> declarations, String name, DeclarationKind kind,
-      {int offset, int codeOffset, int codeLength, String className}) {
+      {int offset,
+      int codeOffset,
+      int codeLength,
+      String className,
+      String mixinName}) {
     for (var declaration in declarations) {
       if (declaration.name == name &&
           declaration.kind == kind &&
           (offset == null || declaration.offset == offset) &&
           (codeOffset == null || declaration.codeOffset == codeOffset) &&
           (codeLength == null || declaration.codeLength == codeLength) &&
-          declaration.className == className) {
+          declaration.className == className &&
+          declaration.mixinName == mixinName) {
         return declaration;
       }
     }
diff --git a/pkg/analyzer_plugin/doc/api.html b/pkg/analyzer_plugin/doc/api.html
index dfe6470..6ab809c 100644
--- a/pkg/analyzer_plugin/doc/api.html
+++ b/pkg/analyzer_plugin/doc/api.html
@@ -1265,7 +1265,7 @@
       An enumeration of the kinds of elements.
     </p>
     
-  <dl><dt class="value">CLASS</dt><dt class="value">CLASS_TYPE_ALIAS</dt><dt class="value">COMPILATION_UNIT</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">CONSTRUCTOR_INVOCATION</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dt class="value">FILE</dt><dt class="value">FUNCTION</dt><dt class="value">FUNCTION_INVOCATION</dt><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY</dt><dt class="value">LOCAL_VARIABLE</dt><dt class="value">METHOD</dt><dt class="value">PARAMETER</dt><dt class="value">PREFIX</dt><dt class="value">SETTER</dt><dt class="value">TOP_LEVEL_VARIABLE</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNIT_TEST_GROUP</dt><dt class="value">UNIT_TEST_TEST</dt><dt class="value">UNKNOWN</dt></dl></dd><dt class="typeDefinition"><a name="type_FilePath">FilePath: String</a></dt><dd>
+  <dl><dt class="value">CLASS</dt><dt class="value">CLASS_TYPE_ALIAS</dt><dt class="value">COMPILATION_UNIT</dt><dt class="value">CONSTRUCTOR</dt><dt class="value">CONSTRUCTOR_INVOCATION</dt><dt class="value">ENUM</dt><dt class="value">ENUM_CONSTANT</dt><dt class="value">FIELD</dt><dt class="value">FILE</dt><dt class="value">FUNCTION</dt><dt class="value">FUNCTION_INVOCATION</dt><dt class="value">FUNCTION_TYPE_ALIAS</dt><dt class="value">GETTER</dt><dt class="value">LABEL</dt><dt class="value">LIBRARY</dt><dt class="value">LOCAL_VARIABLE</dt><dt class="value">METHOD</dt><dt class="value">MIXIN</dt><dt class="value">PARAMETER</dt><dt class="value">PREFIX</dt><dt class="value">SETTER</dt><dt class="value">TOP_LEVEL_VARIABLE</dt><dt class="value">TYPE_PARAMETER</dt><dt class="value">UNIT_TEST_GROUP</dt><dt class="value">UNIT_TEST_TEST</dt><dt class="value">UNKNOWN</dt></dl></dd><dt class="typeDefinition"><a name="type_FilePath">FilePath: String</a></dt><dd>
     
     <p>
       The absolute, normalized path of a file.
diff --git a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
index f696947..6d8ea9c 100644
--- a/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
+++ b/pkg/analyzer_plugin/lib/protocol/protocol_common.dart
@@ -1776,6 +1776,7 @@
  *   LIBRARY
  *   LOCAL_VARIABLE
  *   METHOD
+ *   MIXIN
  *   PARAMETER
  *   PREFIX
  *   SETTER
@@ -1829,6 +1830,8 @@
 
   static const ElementKind METHOD = const ElementKind._("METHOD");
 
+  static const ElementKind MIXIN = const ElementKind._("MIXIN");
+
   static const ElementKind PARAMETER = const ElementKind._("PARAMETER");
 
   static const ElementKind PREFIX = const ElementKind._("PREFIX");
@@ -1870,6 +1873,7 @@
     LIBRARY,
     LOCAL_VARIABLE,
     METHOD,
+    MIXIN,
     PARAMETER,
     PREFIX,
     SETTER,
@@ -1921,6 +1925,8 @@
         return LOCAL_VARIABLE;
       case "METHOD":
         return METHOD;
+      case "MIXIN":
+        return MIXIN;
       case "PARAMETER":
         return PARAMETER;
       case "PREFIX":
diff --git a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
index 2d6df20..e28e408 100644
--- a/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
+++ b/pkg/analyzer_plugin/test/integration/support/protocol_matchers.dart
@@ -268,6 +268,7 @@
  *   LIBRARY
  *   LOCAL_VARIABLE
  *   METHOD
+ *   MIXIN
  *   PARAMETER
  *   PREFIX
  *   SETTER
@@ -296,6 +297,7 @@
   "LIBRARY",
   "LOCAL_VARIABLE",
   "METHOD",
+  "MIXIN",
   "PARAMETER",
   "PREFIX",
   "SETTER",
diff --git a/pkg/analyzer_plugin/tool/spec/common_types_spec.html b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
index ba70882..ed8daca 100644
--- a/pkg/analyzer_plugin/tool/spec/common_types_spec.html
+++ b/pkg/analyzer_plugin/tool/spec/common_types_spec.html
@@ -6,7 +6,7 @@
 </head>
 <body>
 <h1>Common Types</h1>
-<version>1.0.3</version>
+<version>1.1.0</version>
 <p>
   This document contains a specification of the types that are common between
   the analysis server wire protocol and the analysis server plugin wire
@@ -507,6 +507,7 @@
       <value><code>LIBRARY</code></value>
       <value><code>LOCAL_VARIABLE</code></value>
       <value><code>METHOD</code></value>
+      <value><code>MIXIN</code></value>
       <value><code>PARAMETER</code></value>
       <value><code>PREFIX</code></value>
       <value><code>SETTER</code></value>