Version 2.11.0-193.0.dev

Merge commit '2a649d3ef03870308ea945c1c7a873dfe19c54a1' into 'dev'
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
index b7b9be9..f90a68a 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/flow_analysis_test.dart
@@ -2954,7 +2954,7 @@
         var unreachable = reachable.setUnreachable();
         expect(reachable.restrict(h, reachable, Set()), same(reachable));
         expect(reachable.restrict(h, unreachable, Set()), same(unreachable));
-        expect(unreachable.restrict(h, unreachable, Set()), same(unreachable));
+        expect(unreachable.restrict(h, reachable, Set()), same(unreachable));
         expect(unreachable.restrict(h, unreachable, Set()), same(unreachable));
       });
 
diff --git a/pkg/analysis_server/lib/src/cider/completion.dart b/pkg/analysis_server/lib/src/cider/completion.dart
index 26e9582..7864fa2 100644
--- a/pkg/analysis_server/lib/src/cider/completion.dart
+++ b/pkg/analysis_server/lib/src/cider/completion.dart
@@ -107,7 +107,7 @@
           });
 
           performance.getDataInt('count').add(result.length);
-          return result;
+          return result.toList();
         },
       );
 
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 70db8db..8cd4882 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -493,6 +493,7 @@
   HintCode.INFERENCE_FAILURE_ON_UNTYPED_PARAMETER,
   HintCode.INVALID_ANNOTATION_TARGET,
   HintCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT,
+  HintCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY,
   HintCode.INVALID_FACTORY_ANNOTATION,
   HintCode.INVALID_FACTORY_METHOD_DECL,
   HintCode.INVALID_FACTORY_METHOD_IMPL,
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 77c0646..a87e07a 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -42,6 +42,7 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
 import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/linked_element_builder.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/util/comment.dart';
@@ -1297,16 +1298,15 @@
     if (_enums != null) return _enums;
 
     if (linkedNode != null) {
-      var containerRef = reference.getChild('@enum');
       CompilationUnit linkedNode = this.linkedNode;
-      _enums = linkedNode.declarations.whereType<EnumDeclaration>().map((node) {
-        var name = node.name.name;
-        var reference = containerRef.getChild(name);
-        if (reference.hasElementFor(node)) {
-          return reference.element as EnumElementImpl;
+      _enums = <ClassElement>[];
+      for (var node in linkedNode.declarations) {
+        if (node is EnumDeclaration) {
+          var element = _elementBuilder.enumDeclaration(node);
+          _enums.add(element);
         }
-        return EnumElementImpl.forLinkedNode(this, reference, node);
-      }).toList();
+      }
+      return _enums;
     }
 
     return _enums ??= const <ClassElement>[];
@@ -1328,19 +1328,11 @@
 
     if (linkedNode != null) {
       CompilationUnit linkedNode = this.linkedNode;
-      var containerRef = reference.getChild('@extension');
       _extensions = <ExtensionElement>[];
       for (var node in linkedNode.declarations) {
         if (node is ExtensionDeclaration) {
-          var refName = linkedContext.getExtensionRefName(node);
-          var reference = containerRef.getChild(refName);
-          if (reference.hasElementFor(node)) {
-            _extensions.add(reference.element);
-          } else {
-            _extensions.add(
-              ExtensionElementImpl.forLinkedNode(this, reference, node),
-            );
-          }
+          var element = _elementBuilder.extensionDeclaration(node);
+          _extensions.add(element);
         }
       }
       return _extensions;
@@ -1363,18 +1355,14 @@
 
     if (linkedNode != null) {
       CompilationUnit linkedNode = this.linkedNode;
-      var containerRef = reference.getChild('@function');
-      return _functions = linkedNode.declarations
-          .whereType<FunctionDeclaration>()
-          .where((node) => !node.isGetter && !node.isSetter)
-          .map((node) {
-        var name = node.name.name;
-        var reference = containerRef.getChild(name);
-        if (reference.hasElementFor(node)) {
-          return reference.element as FunctionElementImpl;
+      _functions = <FunctionElement>[];
+      for (var node in linkedNode.declarations) {
+        if (node is FunctionDeclaration && node.propertyKeyword == null) {
+          var element = _elementBuilder.functionDeclaration(node);
+          _functions.add(element as FunctionElement);
         }
-        return FunctionElementImpl.forLinkedNode(this, reference, node);
-      }).toList();
+      }
+      return _functions;
     }
     return _functions ?? const <FunctionElement>[];
   }
@@ -1394,23 +1382,17 @@
 
     if (linkedNode != null) {
       CompilationUnit linkedNode = this.linkedNode;
-      var containerRef = reference.getChild('@typeAlias');
-      return _typeAliases = linkedNode.declarations.where((node) {
-        return node is FunctionTypeAlias || node is GenericTypeAlias;
-      }).map((node) {
-        String name;
+      _typeAliases = <FunctionTypeAliasElement>[];
+      for (var node in linkedNode.declarations) {
         if (node is FunctionTypeAlias) {
-          name = node.name.name;
-        } else {
-          name = (node as GenericTypeAlias).name.name;
+          var element = _elementBuilder.functionTypeAlias(node);
+          _typeAliases.add(element);
+        } else if (node is GenericTypeAlias) {
+          var element = _elementBuilder.genericTypeAlias(node);
+          _typeAliases.add(element);
         }
-
-        var reference = containerRef.getChild(name);
-        if (reference.hasElementFor(node)) {
-          return reference.element as GenericTypeAliasElementImpl;
-        }
-        return GenericTypeAliasElementImpl.forLinkedNode(this, reference, node);
-      }).toList();
+      }
+      return _typeAliases;
     }
 
     return _typeAliases ?? const <FunctionTypeAliasElement>[];
@@ -1442,16 +1424,14 @@
 
     if (linkedNode != null) {
       CompilationUnit linkedNode = this.linkedNode;
-      var containerRef = reference.getChild('@mixin');
-      var declarations = linkedNode.declarations;
-      return _mixins = declarations.whereType<MixinDeclaration>().map((node) {
-        var name = node.name.name;
-        var reference = containerRef.getChild(name);
-        if (reference.hasElementFor(node)) {
-          return reference.element as MixinElementImpl;
+      _mixins = <ClassElement>[];
+      for (var node in linkedNode.declarations) {
+        if (node is MixinDeclaration) {
+          var element = _elementBuilder.mixinDeclaration(node);
+          _mixins.add(element);
         }
-        return MixinElementImpl.forLinkedNode(this, reference, node);
-      }).toList();
+      }
+      return _mixins;
     }
 
     return _mixins ?? const <ClassElement>[];
@@ -1503,24 +1483,14 @@
 
     if (linkedNode != null) {
       CompilationUnit linkedNode = this.linkedNode;
-      var containerRef = reference.getChild('@class');
       _types = <ClassElement>[];
       for (var node in linkedNode.declarations) {
-        String name;
         if (node is ClassDeclaration) {
-          name = node.name.name;
+          var element = _elementBuilder.classDeclaration(node);
+          _types.add(element);
         } else if (node is ClassTypeAlias) {
-          name = node.name.name;
-        } else {
-          continue;
-        }
-        var reference = containerRef.getChild(name);
-        if (reference.hasElementFor(node)) {
-          _types.add(reference.element);
-        } else {
-          _types.add(
-            ClassElementImpl.forLinkedNode(this, reference, node),
-          );
+          var element = _elementBuilder.classTypeAlias(node);
+          _types.add(element);
         }
       }
       return _types;
@@ -1653,18 +1623,13 @@
       var variableList = <TopLevelVariableElement>[];
       variableMap[unit] = variableList;
 
+      var elementBuilder = unit._elementBuilder;
       var unitNode = unit.linkedContext.unit_withDeclarations;
       var unitDeclarations = unitNode.declarations;
 
       var variables = context.topLevelVariables(unitNode);
       for (var variable in variables) {
-        var name = variable.name.name;
-        var reference = unit.reference.getChild('@variable').getChild(name);
-        var variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory(
-          unit,
-          reference,
-          variable,
-        );
+        var variableElement = elementBuilder.topLevelVariable(variable);
         variableList.add(variableElement);
 
         accessorList.add(variableElement.getter);
@@ -1680,15 +1645,9 @@
           if (!isGetter && !isSetter) continue;
 
           var name = node.name.name;
-          var containerRef = isGetter
-              ? unit.reference.getChild('@getter')
-              : unit.reference.getChild('@setter');
 
-          var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
-            unit,
-            containerRef.getChild(name),
-            node,
-          );
+          var accessorElement = elementBuilder.functionDeclaration(node)
+              as PropertyAccessorElementImpl;
           accessorList.add(accessorElement);
 
           var fieldRef = unit.reference.getChild('@field').getChild(name);
@@ -3029,6 +2988,10 @@
     return _enclosingElement?.typeParameterContext;
   }
 
+  LinkedElementBuilder get _elementBuilder {
+    return linkedContext.elementBuilder;
+  }
+
   NullabilitySuffix get _noneOrStarSuffix {
     return library?.isNonNullableByDefault == true
         ? NullabilitySuffix.none
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 1e0761f..1d0e15f4 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -590,6 +590,19 @@
       correction: "Try using a hide clause to hide '{0}'.");
 
   /**
+   * This hint is generated anywhere where an element annotated with `@internal`
+   * is exported indirectly as a part of a package's public API.
+   *
+   * Parameters:
+   * 0: the name of the element
+   */
+  static const HintCode INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY = HintCode(
+      'INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY',
+      "The member '{0}' can't be exported as a part of a package's public "
+          "API, but is indirectly exported as part of the signature of '{1}'.",
+      correction: "Try using a hide clause to hide '{0}'.");
+
+  /**
    * This hint is generated anywhere a @factory annotation is associated with
    * anything other than a method.
    */
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index 4b12e9d..1547218 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -153,9 +153,7 @@
     // Remove libraries represented by removed files.
     // If we need these libraries later, we will relink and reattach them.
     if (libraryContext != null) {
-      libraryContext.elementFactory.removeLibraries(
-        removedFiles.map((e) => e.uriStr).toList(),
-      );
+      libraryContext.remove(removedFiles);
     }
   }
 
@@ -591,8 +589,11 @@
     this.contextObjects,
     this.librariesLog,
   ) {
-    // TODO(scheglov) remove it?
-    _createElementFactory();
+    elementFactory = LinkedElementFactory(
+      contextObjects.analysisContext,
+      contextObjects.analysisSession,
+      Reference.root(),
+    );
   }
 
   /// Load data required to access elements of the given [targetLibrary].
@@ -693,8 +694,9 @@
       // the element factory - it is empty anyway.
       if (!elementFactory.hasDartCore) {
         contextObjects.analysisContext.clearTypeProvider();
-        _createElementFactory();
+        elementFactory.declareDartCoreDynamicNever();
       }
+
       var cBundle = CiderLinkedLibraryCycle.fromBuffer(bytes);
       inputBundles.add(cBundle.bundle);
       elementFactory.addBundle(
@@ -722,29 +724,19 @@
         '[librariesLinkedTimer: ${librariesLinkedTimer.elapsedMilliseconds} ms]',
       );
     });
-
-    // There might be a rare (and wrong) situation, when the external summaries
-    // already include the [targetLibrary]. When this happens, [loadBundle]
-    // exists without doing any work. But the type provider must be created.
-    _createElementFactoryTypeProvider();
   }
 
-  void _createElementFactory() {
-    elementFactory = LinkedElementFactory(
-      contextObjects.analysisContext,
-      contextObjects.analysisSession,
-      Reference.root(),
+  /// Remove libraries represented by the [removed] files.
+  /// If we need these libraries later, we will relink and reattach them.
+  void remove(List<FileState> removed) {
+    elementFactory.removeLibraries(
+      removed.map((e) => e.uriStr).toList(),
     );
-  }
 
-  /// Ensure that type provider is created.
-  void _createElementFactoryTypeProvider() {
-    var analysisContext = contextObjects.analysisContext;
-    if (analysisContext.typeProviderNonNullableByDefault == null) {
-      var dartCore = elementFactory.libraryOfUri('dart:core');
-      var dartAsync = elementFactory.libraryOfUri('dart:async');
-      elementFactory.createTypeProviders(dartCore, dartAsync);
-    }
+    var removedSet = removed.toSet();
+    loadedBundles.removeWhere((cycle) {
+      return cycle.libraries.any(removedSet.contains);
+    });
   }
 
   static CiderLinkedLibraryCycleBuilder serializeBundle(
diff --git a/pkg/analyzer/lib/src/error/best_practices_verifier.dart b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
index 66e0d5c..7b3407fd 100644
--- a/pkg/analyzer/lib/src/error/best_practices_verifier.dart
+++ b/pkg/analyzer/lib/src/error/best_practices_verifier.dart
@@ -1072,6 +1072,22 @@
             HintCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT,
             node,
             [element.displayName]);
+      } else if (element is FunctionElement) {
+        var signatureTypes = [
+          ...element.parameters.map((p) => p.type),
+          element.returnType,
+          ...element.typeParameters.map((tp) => tp.bound),
+        ];
+        for (var type in signatureTypes) {
+          var typeElement = type?.element?.enclosingElement;
+          if (typeElement is GenericTypeAliasElement &&
+              typeElement.hasInternal) {
+            _errorReporter.reportErrorForNode(
+                HintCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY,
+                node,
+                [typeElement.name, element.displayName]);
+          }
+        }
       }
     });
   }
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_builder.dart b/pkg/analyzer/lib/src/summary2/linked_element_builder.dart
new file mode 100644
index 0000000..fcfc0d3
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/linked_element_builder.dart
@@ -0,0 +1,198 @@
+// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+
+class LinkedElementBuilder {
+  final CompilationUnitElementImpl _unitElement;
+  final Reference _classRef;
+  final Reference _enumRef;
+  final Reference _extensionRef;
+  final Reference _functionRef;
+  final Reference _getterRef;
+  final Reference _mixinRef;
+  final Reference _setterRef;
+  final Reference _typeAliasRef;
+  final Reference _variableRef;
+
+  var _nextUnnamedExtensionId = 0;
+
+  LinkedElementBuilder(LinkedUnitContext unitContext)
+      : _unitElement = unitContext.reference.element,
+        _classRef = unitContext.reference.getChild('@class'),
+        _enumRef = unitContext.reference.getChild('@enum'),
+        _extensionRef = unitContext.reference.getChild('@extension'),
+        _functionRef = unitContext.reference.getChild('@function'),
+        _getterRef = unitContext.reference.getChild('@getter'),
+        _mixinRef = unitContext.reference.getChild('@mixin'),
+        _setterRef = unitContext.reference.getChild('@setter'),
+        _typeAliasRef = unitContext.reference.getChild('@typeAlias'),
+        _variableRef = unitContext.reference.getChild('@variable');
+
+  ClassElementImpl classDeclaration(ClassDeclaration node) {
+    var element = node.declaredElement as ClassElementImpl;
+    if (element != null) {
+      return element;
+    }
+
+    var nameNode = node.name;
+    element = ClassElementImpl.forLinkedNode(
+      _unitElement,
+      _classRef.getChild(nameNode.name),
+      node,
+    );
+    nameNode.staticElement = element;
+    return element;
+  }
+
+  ClassElementImpl classTypeAlias(ClassTypeAlias node) {
+    var element = node.declaredElement as ClassElementImpl;
+    if (element != null) {
+      return element;
+    }
+
+    var nameNode = node.name;
+    element = ClassElementImpl.forLinkedNode(
+      _unitElement,
+      _classRef.getChild(nameNode.name),
+      node,
+    );
+    nameNode.staticElement = element;
+    return element;
+  }
+
+  EnumElementImpl enumDeclaration(EnumDeclaration node) {
+    var element = node.declaredElement as EnumElementImpl;
+    if (element != null) {
+      return element;
+    }
+
+    var nameNode = node.name;
+    element = EnumElementImpl.forLinkedNode(
+      _unitElement,
+      _enumRef.getChild(nameNode.name),
+      node,
+    );
+    nameNode.staticElement = element;
+    return element;
+  }
+
+  ExtensionElementImpl extensionDeclaration(ExtensionDeclarationImpl node) {
+    var element = node.declaredElement as ExtensionElementImpl;
+    if (element != null) {
+      return element;
+    }
+
+    var name = node.name?.name;
+    var refName = name ?? 'extension-${_nextUnnamedExtensionId++}';
+    element = ExtensionElementImpl.forLinkedNode(
+      _unitElement,
+      _extensionRef.getChild(refName),
+      node,
+    );
+    node.declaredElement = element;
+    return element;
+  }
+
+  ExecutableElementImpl functionDeclaration(FunctionDeclaration node) {
+    var element = node.declaredElement as ExecutableElementImpl;
+    if (element != null) {
+      return element;
+    }
+
+    var nameNode = node.name;
+    var name = nameNode.name;
+
+    if (node.isGetter) {
+      element = PropertyAccessorElementImpl.forLinkedNode(
+        _unitElement,
+        _getterRef.getChild(name),
+        node,
+      );
+    } else if (node.isSetter) {
+      element = PropertyAccessorElementImpl.forLinkedNode(
+        _unitElement,
+        _setterRef.getChild(name),
+        node,
+      );
+    } else {
+      element = FunctionElementImpl.forLinkedNode(
+        _unitElement,
+        _functionRef.getChild(name),
+        node,
+      );
+    }
+
+    nameNode.staticElement = element;
+    return element;
+  }
+
+  GenericTypeAliasElementImpl functionTypeAlias(FunctionTypeAlias node) {
+    var element = node.declaredElement as GenericTypeAliasElementImpl;
+    if (element != null) {
+      return element;
+    }
+
+    var nameNode = node.name;
+    element = GenericTypeAliasElementImpl.forLinkedNode(
+      _unitElement,
+      _typeAliasRef.getChild(nameNode.name),
+      node,
+    );
+    nameNode.staticElement = element;
+    return element;
+  }
+
+  GenericTypeAliasElementImpl genericTypeAlias(GenericTypeAlias node) {
+    var element = node.declaredElement as GenericTypeAliasElementImpl;
+    if (element != null) {
+      return element;
+    }
+
+    var nameNode = node.name;
+    element = GenericTypeAliasElementImpl.forLinkedNode(
+      _unitElement,
+      _typeAliasRef.getChild(nameNode.name),
+      node,
+    );
+    nameNode.staticElement = element;
+    return element;
+  }
+
+  MixinElementImpl mixinDeclaration(MixinDeclaration node) {
+    var element = node.declaredElement as MixinElementImpl;
+    if (element != null) {
+      return element;
+    }
+
+    var nameNode = node.name;
+    element = MixinElementImpl.forLinkedNode(
+      _unitElement,
+      _mixinRef.getChild(nameNode.name),
+      node,
+    );
+    nameNode.staticElement = element;
+    return element;
+  }
+
+  TopLevelVariableElementImpl topLevelVariable(VariableDeclaration node) {
+    var element = node.declaredElement as TopLevelVariableElementImpl;
+    if (element != null) {
+      return element;
+    }
+
+    var nameNode = node.name;
+    element = TopLevelVariableElementImpl.forLinkedNodeFactory(
+      _unitElement,
+      _variableRef.getChild(nameNode.name),
+      node,
+    );
+    nameNode.staticElement = element;
+    return element;
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index caeb168..b47435a 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -31,9 +31,7 @@
   ) {
     ArgumentError.checkNotNull(analysisContext, 'analysisContext');
     ArgumentError.checkNotNull(analysisSession, 'analysisSession');
-    var dartCoreRef = rootReference.getChild('dart:core');
-    dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
-    dartCoreRef.getChild('Never').element = NeverElementImpl.instance;
+    declareDartCoreDynamicNever();
   }
 
   CoreTypes get coreTypes {
@@ -104,6 +102,12 @@
     }
   }
 
+  void declareDartCoreDynamicNever() {
+    var dartCoreRef = rootReference.getChild('dart:core');
+    dartCoreRef.getChild('dynamic').element = DynamicElementImpl.instance;
+    dartCoreRef.getChild('Never').element = NeverElementImpl.instance;
+  }
+
   Element elementOfReference(Reference reference) {
     if (reference.element != null) {
       return reference.element;
@@ -333,8 +337,14 @@
       _indexUnitElementDeclarations(unit);
       assert(reference.node != null, '$reference');
     }
-    ClassElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
+
+    var elementBuilder = unit.linkedContext.elementBuilder;
+    var node = reference.node;
+    if (node is ClassDeclaration) {
+      return elementBuilder.classDeclaration(node);
+    } else {
+      return elementBuilder.classTypeAlias(node);
+    }
   }
 
   ConstructorElementImpl _constructor(
@@ -410,8 +420,8 @@
       _indexUnitElementDeclarations(unit);
       assert(reference.node != null, '$reference');
     }
-    EnumElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
+    var elementBuilder = unit.linkedContext.elementBuilder;
+    return elementBuilder.enumDeclaration(reference.node);
   }
 
   ExtensionElementImpl _extension(
@@ -420,8 +430,8 @@
       _indexUnitElementDeclarations(unit);
       assert(reference.node != null, '$reference');
     }
-    ExtensionElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
+    var elementBuilder = unit.linkedContext.elementBuilder;
+    return elementBuilder.extensionDeclaration(reference.node);
   }
 
   FieldElementImpl _field(ClassElementImpl enclosing, Reference reference) {
@@ -463,8 +473,8 @@
       _indexUnitElementDeclarations(unit);
       assert(reference.node != null, '$reference');
     }
-    MixinElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
+    var elementBuilder = unit.linkedContext.elementBuilder;
+    return elementBuilder.mixinDeclaration(reference.node);
   }
 
   Element _parameter(ExecutableElementImpl enclosing, Reference reference) {
@@ -487,8 +497,14 @@
       _indexUnitElementDeclarations(unit);
       assert(reference.node != null, '$reference');
     }
-    GenericTypeAliasElementImpl.forLinkedNode(unit, reference, reference.node);
-    return reference.element;
+
+    var elementBuilder = unit.linkedContext.elementBuilder;
+    var node = reference.node;
+    if (node is FunctionTypeAlias) {
+      return elementBuilder.functionTypeAlias(node);
+    } else {
+      return elementBuilder.genericTypeAlias(node);
+    }
   }
 
   /// Index nodes for which we choose to create elements individually,
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 24a749f..73c1f77 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/src/summary2/ast_binary_reader.dart';
 import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/linked_element_builder.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 
@@ -38,6 +39,8 @@
 
   AstBinaryReader _astReader;
 
+  LinkedElementBuilder _elementBuilder;
+
   CompilationUnit _unit;
   bool _hasDirectivesRead = false;
 
@@ -66,6 +69,10 @@
     _hasDirectivesRead = _unit != null;
   }
 
+  LinkedElementBuilder get elementBuilder {
+    return _elementBuilder ??= LinkedElementBuilder(this);
+  }
+
   bool get hasPartOfDirective {
     for (var directive in unit_withDirectives.directives) {
       if (directive is PartOfDirective) {
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_export_of_internal_element_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_export_of_internal_element_test.dart
index 542262d..b960a44 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_export_of_internal_element_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_export_of_internal_element_test.dart
@@ -375,6 +375,88 @@
     ]);
   }
 
+  void test_indirectlyViaFunction_parameter() async {
+    newFile(testPackageImplementationFilePath, content: r'''
+import 'package:meta/meta.dart';
+@internal typedef int IntFunc(int x);
+int func(IntFunc f, int x) => f(x);
+''');
+
+    await assertErrorsInCode(r'''
+export 'src/foo.dart' show func;
+''', [
+      error(HintCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY, 0, 32),
+    ]);
+  }
+
+  void test_indirectlyViaFunction_parameter_generic() async {
+    newFile(testPackageImplementationFilePath, content: r'''
+import 'package:meta/meta.dart';
+@internal typedef IntFunc = int Function(int);
+int func(IntFunc f, int x) => f(x);
+''');
+
+    await assertErrorsInCode(r'''
+export 'src/foo.dart' show func;
+''', [
+      error(HintCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY, 0, 32),
+    ]);
+  }
+
+  void test_indirectlyViaFunction_parameter_generic_typeArg() async {
+    newFile(testPackageImplementationFilePath, content: r'''
+import 'package:meta/meta.dart';
+@internal typedef IntFunc<T> = int Function(T);
+int func(IntFunc<num> f, int x) => f(x);
+''');
+
+    await assertErrorsInCode(r'''
+export 'src/foo.dart' show func;
+''', [
+      error(HintCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY, 0, 32),
+    ]);
+  }
+
+  void test_indirectlyViaFunction_returnType() async {
+    newFile(testPackageImplementationFilePath, content: r'''
+import 'package:meta/meta.dart';
+@internal typedef int IntFunc(int x);
+IntFunc func() => (int x) => x;
+''');
+
+    await assertErrorsInCode(r'''
+export 'src/foo.dart' show func;
+''', [
+      error(HintCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY, 0, 32),
+    ]);
+  }
+
+  void test_indirectlyViaFunction_typeArgument_bounded() async {
+    newFile(testPackageImplementationFilePath, content: r'''
+import 'package:meta/meta.dart';
+@internal typedef int IntFunc(int x);
+void func<T extends IntFunc>() {}
+''');
+
+    await assertErrorsInCode(r'''
+export 'src/foo.dart' show func;
+''', [
+      error(HintCode.INVALID_EXPORT_OF_INTERNAL_ELEMENT_INDIRECTLY, 0, 32),
+    ]);
+  }
+
+  void test_indirectlyViaFunction_typeArgument_unbounded() async {
+    newFile(testPackageImplementationFilePath, content: r'''
+import 'package:meta/meta.dart';
+@internal typedef int IntFunc(int x);
+void func<T>() {}
+''');
+
+    await assertNoErrorsInCode(r'''
+export 'src/foo.dart' show func;
+''');
+  }
+
   void test_noCombinators() async {
     newFile(testPackageImplementationFilePath, content: r'''
 import 'package:meta/meta.dart';
diff --git a/pkg/compiler/README.md b/pkg/compiler/README.md
index f4e2a49..6c9621a 100644
--- a/pkg/compiler/README.md
+++ b/pkg/compiler/README.md
@@ -327,36 +327,14 @@
   AI: consider deleting this file.
 
 
-* Constants: the compiler has a constant system that delays evaluation of
-  constants and provides different semantics depending on the embedder, this
-  abstraction was especially necessary when dart2js was used as a front-end for
-  non-JS systems like dart2dart and dartino.
+* Constants: the compiler has a constant system that evaluates constant
+  expressions based on JS semantics.
 
   * `lib/src/constants/value.dart`: this is the represented value of a constant
-    after it has been evaluated. The resulting value is specific to the target
-    of the compiler and will no longer have environment placeholders. For
-    example, when the target is Dart (dart2dart) `1 == 1.0` is evaluated to
-    `false`, and when the target is JavaScript it is evaluated to `true`. This
-    specific example is a result of the way dart2js compiles numbers as
-    JavaScript Numbers.
+    after it has been evaluated.
 
-  * `lib/src/constants/constant_system.dart`: an abstraction that defines how
-    expressions may be folded. Different implementations of the constant system
-    are used to target Dart or JavaScript.
-
-  * `lib/src/compile_time_constants.dart`: defines how constant expressions are
-    created from a parsed AST.
-
-  * `lib/src/constant_system_dart.dart`: defines an implementation of a constant
-    system with the Dart semantics (where `1 == 1.0` is true).
-
-  * `lib/src/js_backend/constant_system_javascript.dart`: defines an
-    implementation of a constant system with the JavaScript semantics (where
-    `1 == 1.0` is false).
-
-  AI: consider deleting `constant_system_dart.dart` now that it is no longer
-  used, or move under testing, if it might be used for unittests of the constant
-  expressions.
+  * `lib/src/constants/constant_system.dart`: implements evaluating constant
+    Dart expressions and produces values.
 
 * Common elements: the compiler often refers to certain elements during
   compilation either because they are first-class in the language or because
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 31522ce..153240b 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -560,7 +560,10 @@
 
     var body = <js_ast.Statement>[];
     _emitSuperHelperSymbols(body);
-    var deferredSupertypes = <js_ast.Statement>[];
+    // Deferred supertypes must be evaluated lazily while emitting classes to
+    // prevent evaluating a JS expression for a deferred type from influencing
+    // class declaration order (such as when calling 'emitDeferredType').
+    var deferredSupertypes = <js_ast.Statement Function()>[];
 
     // Emit the class, e.g. `core.Object = class Object { ... }`
     _defineClass(c, className, jsMethods, body, deferredSupertypes);
@@ -591,11 +594,13 @@
 
     var classDef = js_ast.Statement.from(body);
     var typeFormals = c.typeParameters;
+    var evaluatedDeferredSupertypes =
+        deferredSupertypes.map<js_ast.Statement>((f) => f()).toList();
     if (typeFormals.isNotEmpty) {
       classDef = _defineClassTypeArguments(
-          c, typeFormals, classDef, className, deferredSupertypes);
+          c, typeFormals, classDef, className, evaluatedDeferredSupertypes);
     } else {
-      afterClassDefItems.addAll(deferredSupertypes);
+      afterClassDefItems.addAll(evaluatedDeferredSupertypes);
     }
 
     body = [classDef];
@@ -745,7 +750,7 @@
       js_ast.Expression className,
       List<js_ast.Method> methods,
       List<js_ast.Statement> body,
-      List<js_ast.Statement> deferredSupertypes) {
+      List<js_ast.Statement Function()> deferredSupertypes) {
     if (c == _coreTypes.objectClass) {
       body.add(_emitClassStatement(c, className, null, methods));
       return;
@@ -884,10 +889,14 @@
 
     // Unroll mixins.
     if (shouldDefer(supertype)) {
-      deferredSupertypes.add(runtimeStatement('setBaseClass(#, #)', [
-        getBaseClass(isMixinAliasClass(c) ? 0 : mixinApplications.length),
-        emitDeferredType(supertype),
-      ]));
+      var originalSupertype = supertype;
+      deferredSupertypes.add(() => runtimeStatement('setBaseClass(#, #)', [
+            getBaseClass(isMixinAliasClass(c) ? 0 : mixinApplications.length),
+            emitDeferredType(originalSupertype),
+          ]));
+      // Refers to 'supertype' without type parameters. We remove these from
+      // the 'extends' clause for generics for cyclic dependencies and append
+      // them later with 'setBaseClass'.
       supertype =
           _coreTypes.rawType(supertype.classNode, _currentLibrary.nonNullable);
     }
@@ -903,12 +912,16 @@
 
       var m = c.mixedInType.asInterfaceType;
       var deferMixin = shouldDefer(m);
-      var mixinBody = deferMixin ? deferredSupertypes : body;
       var mixinClass = deferMixin ? emitDeferredType(m) : emitClassRef(m);
       var classExpr = deferMixin ? getBaseClass(0) : className;
 
-      mixinBody
-          .add(runtimeStatement('applyMixin(#, #)', [classExpr, mixinClass]));
+      var mixinApplication =
+          runtimeStatement('applyMixin(#, #)', [classExpr, mixinClass]);
+      if (deferMixin) {
+        deferredSupertypes.add(() => mixinApplication);
+      } else {
+        body.add(mixinApplication);
+      }
 
       if (methods.isNotEmpty) {
         // However we may need to add some methods to this class that call
@@ -917,11 +930,16 @@
         // We do this with the following pattern:
         //
         //     applyMixin(C, class C$ extends M { <methods>  });
-        mixinBody.add(runtimeStatement('applyMixin(#, #)', [
+        var mixinApplicationWithMethods = runtimeStatement('applyMixin(#, #)', [
           classExpr,
           js_ast.ClassExpression(
               _emitTemporaryId(getLocalClassName(c)), mixinClass, methods)
-        ]));
+        ]);
+        if (deferMixin) {
+          deferredSupertypes.add(() => mixinApplicationWithMethods);
+        } else {
+          body.add(mixinApplicationWithMethods);
+        }
       }
 
       emitMixinConstructors(className, m);
@@ -964,10 +982,10 @@
       hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(mixinClass);
 
       if (shouldDefer(mixinType)) {
-        deferredSupertypes.add(runtimeStatement('applyMixin(#, #)', [
-          getBaseClass(mixinApplications.length - i),
-          emitDeferredType(mixinType)
-        ]));
+        deferredSupertypes.add(() => runtimeStatement('applyMixin(#, #)', [
+              getBaseClass(mixinApplications.length - i),
+              emitDeferredType(mixinType)
+            ]));
       } else {
         body.add(runtimeStatement(
             'applyMixin(#, #)', [mixinId, emitClassRef(mixinType)]));
diff --git a/tests/language/mixin/regress_flutter_66859_1_test.dart b/tests/language/mixin/regress_flutter_66859_1_test.dart
new file mode 100644
index 0000000..544da53
--- /dev/null
+++ b/tests/language/mixin/regress_flutter_66859_1_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verifies that mixin supertypes are properly maintained even if marked as
+// deferred (e.g., in a circular hierarchy).
+// Regression test for: https://github.com/flutter/flutter/issues/66859
+
+import "package:expect/expect.dart";
+
+mixin M {}
+
+mixin N {}
+
+class A extends B<C> with M, N {}
+
+class B<T> {}
+
+class C extends A {}
+
+class Z extends B<Z> with M {}
+
+main() {
+  var z = Z();
+  Expect.isTrue(z is B<Z>);
+  Expect.isTrue(z is M);
+  var a = A();
+  Expect.isTrue(a is M);
+  Expect.isTrue(a is N);
+  Expect.isTrue(a is B<C>);
+}
diff --git a/tests/language/mixin/regress_flutter_66859_2_test.dart b/tests/language/mixin/regress_flutter_66859_2_test.dart
new file mode 100644
index 0000000..7a3ee64
--- /dev/null
+++ b/tests/language/mixin/regress_flutter_66859_2_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verifies that mixin supertypes are properly maintained even if marked as
+// deferred (e.g., in a circular hierarchy).
+// Regression test for: https://github.com/flutter/flutter/issues/66859
+
+import "package:expect/expect.dart";
+
+mixin X {}
+mixin Y {}
+mixin Z {}
+
+class A extends B<C> with X {}
+
+class C extends A with Z {}
+
+class B<T> extends Object with Y {}
+
+main() {
+  var a = A();
+  var b = B();
+  var c = C();
+  Expect.isTrue(a is A);
+  Expect.isTrue(a is B<C>);
+  Expect.isTrue(a is X);
+  Expect.isTrue(a is Y);
+  Expect.isTrue(c is C);
+  Expect.isTrue(c is A);
+  Expect.isTrue(c is B<C>);
+  Expect.isTrue(c is X);
+  Expect.isTrue(c is Y);
+  Expect.isTrue(c is Z);
+  Expect.isTrue(b is B);
+  Expect.isTrue(b is Y);
+}
diff --git a/tests/language_2/mixin/regress_flutter_66859_1_test.dart b/tests/language_2/mixin/regress_flutter_66859_1_test.dart
new file mode 100644
index 0000000..544da53
--- /dev/null
+++ b/tests/language_2/mixin/regress_flutter_66859_1_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verifies that mixin supertypes are properly maintained even if marked as
+// deferred (e.g., in a circular hierarchy).
+// Regression test for: https://github.com/flutter/flutter/issues/66859
+
+import "package:expect/expect.dart";
+
+mixin M {}
+
+mixin N {}
+
+class A extends B<C> with M, N {}
+
+class B<T> {}
+
+class C extends A {}
+
+class Z extends B<Z> with M {}
+
+main() {
+  var z = Z();
+  Expect.isTrue(z is B<Z>);
+  Expect.isTrue(z is M);
+  var a = A();
+  Expect.isTrue(a is M);
+  Expect.isTrue(a is N);
+  Expect.isTrue(a is B<C>);
+}
diff --git a/tests/language_2/mixin/regress_flutter_66859_2_test.dart b/tests/language_2/mixin/regress_flutter_66859_2_test.dart
new file mode 100644
index 0000000..7a3ee64
--- /dev/null
+++ b/tests/language_2/mixin/regress_flutter_66859_2_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Verifies that mixin supertypes are properly maintained even if marked as
+// deferred (e.g., in a circular hierarchy).
+// Regression test for: https://github.com/flutter/flutter/issues/66859
+
+import "package:expect/expect.dart";
+
+mixin X {}
+mixin Y {}
+mixin Z {}
+
+class A extends B<C> with X {}
+
+class C extends A with Z {}
+
+class B<T> extends Object with Y {}
+
+main() {
+  var a = A();
+  var b = B();
+  var c = C();
+  Expect.isTrue(a is A);
+  Expect.isTrue(a is B<C>);
+  Expect.isTrue(a is X);
+  Expect.isTrue(a is Y);
+  Expect.isTrue(c is C);
+  Expect.isTrue(c is A);
+  Expect.isTrue(c is B<C>);
+  Expect.isTrue(c is X);
+  Expect.isTrue(c is Y);
+  Expect.isTrue(c is Z);
+  Expect.isTrue(b is B);
+  Expect.isTrue(b is Y);
+}
diff --git a/tools/VERSION b/tools/VERSION
index cc68fb0..ac97587 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 11
 PATCH 0
-PRERELEASE 192
+PRERELEASE 193
 PRERELEASE_PATCH 0
\ No newline at end of file