Move SourceLibraryBuilder builder, support for typedef(s), some type parameters.

R=brianwilkerson@google.com, paulberry@google.com

Change-Id: I5c78a165d9d4c60bb268dccd4ace47985d98529c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/96221
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 2ff8321..35fe269 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1007,7 +1007,6 @@
   InterfaceType get supertype {
     if (_supertype == null) {
       if (linkedNode != null) {
-        var context = enclosingUnit.linkedContext;
         LinkedNode superclass;
         if (linkedNode.kind == LinkedNodeKind.classDeclaration) {
           superclass = linkedNode
@@ -1016,7 +1015,10 @@
           superclass = linkedNode.classTypeAlias_superclass;
         }
         if (superclass != null) {
+          var context = enclosingUnit.linkedContext;
           _supertype = context.getInterfaceType(superclass.typeName_type);
+        } else if (!linkedNode.classDeclaration_isDartObject) {
+          _supertype = context.typeProvider.objectType;
         }
       } else if (_unlinkedClass != null) {
         if (_unlinkedClass.supertype != null) {
@@ -1759,8 +1761,22 @@
 
   @override
   List<FunctionTypeAliasElement> get functionTypeAliases {
+    if (_typeAliases != null) return _typeAliases;
+
+    if (linkedNode != null) {
+      var context = enclosingUnit.linkedContext;
+      var containerRef = reference.getChild('@typeAlias');
+      _typeAliases = linkedNode.compilationUnit_declarations
+          .where((node) => node.kind == LinkedNodeKind.functionTypeAlias)
+          .map((node) {
+        var name = context.getUnitMemberName(node);
+        var reference = containerRef.getChild(name);
+        return GenericTypeAliasElementImpl.forLinkedNode(this, reference, node);
+      }).toList();
+    }
+
     if (_unlinkedUnit != null) {
-      _typeAliases ??= _unlinkedUnit.typedefs.map((t) {
+      _typeAliases = _unlinkedUnit.typedefs.map((t) {
         return new GenericTypeAliasElementImpl.forSerialized(t, this);
       }).toList(growable: false);
     }
@@ -5126,6 +5142,13 @@
       : _unlinkedTypedef = null,
         super(name, offset);
 
+  GenericTypeAliasElementImpl.forLinkedNode(
+      CompilationUnitElementImpl enclosingUnit,
+      Reference reference,
+      LinkedNode linkedNode)
+      : _unlinkedTypedef = null,
+        super.forLinkedNode(enclosingUnit, reference, linkedNode);
+
   /// Initialize a newly created type alias element to have the given [name].
   GenericTypeAliasElementImpl.forNode(Identifier name)
       : _unlinkedTypedef = null,
@@ -5157,6 +5180,11 @@
 
   @override
   String get documentationComment {
+    if (linkedNode != null) {
+      return enclosingUnit.linkedContext.getCommentText(
+        linkedNode.annotatedNode_comment,
+      );
+    }
     if (_unlinkedTypedef != null) {
       return _unlinkedTypedef.documentationComment?.text;
     }
@@ -5176,31 +5204,53 @@
 
   @override
   GenericFunctionTypeElementImpl get function {
-    if (_function == null) {
-      if (_unlinkedTypedef != null) {
-        if (_unlinkedTypedef.style == TypedefStyle.genericFunctionType) {
-          DartType type = enclosingUnit.resynthesizerContext.resolveTypeRef(
-              this, _unlinkedTypedef.returnType,
-              declaredType: true);
-          if (type is FunctionType) {
-            Element element = type.element;
-            if (element is GenericFunctionTypeElement) {
-              (element as GenericFunctionTypeElementImpl).enclosingElement =
-                  this;
-              _function = element;
-            }
+    if (_function != null) return _function;
+
+    if (linkedNode != null) {
+      var context = enclosingUnit.linkedContext;
+      _function = new GenericFunctionTypeElementImpl.forOffset(-1);
+      _function.enclosingElement = this;
+      _function.returnType = context.getType(
+        linkedNode.functionTypeAlias_returnType2,
+      );
+      var containerRef = reference.getChild('@parameter');
+      var formalParameters = context.getFormalParameters(linkedNode);
+      _function.parameters = formalParameters.map((node) {
+        var name = context.getFormalParameterName(node);
+        var reference = containerRef.getChild(name);
+        reference.node = node;
+        return ParameterElementImpl.forLinkedNodeFactory(
+          this,
+          reference,
+          node,
+        );
+      }).toList();
+      return _function;
+    }
+
+    if (_unlinkedTypedef != null) {
+      if (_unlinkedTypedef.style == TypedefStyle.genericFunctionType) {
+        DartType type = enclosingUnit.resynthesizerContext.resolveTypeRef(
+            this, _unlinkedTypedef.returnType,
+            declaredType: true);
+        if (type is FunctionType) {
+          Element element = type.element;
+          if (element is GenericFunctionTypeElement) {
+            (element as GenericFunctionTypeElementImpl).enclosingElement = this;
+            _function = element;
           }
-        } else {
-          _function = new GenericFunctionTypeElementImpl.forOffset(-1);
-          _function.enclosingElement = this;
-          _function.returnType = enclosingUnit.resynthesizerContext
-              .resolveTypeRef(_function, _unlinkedTypedef.returnType,
-                  declaredType: true);
-          _function.parameters = ParameterElementImpl.resynthesizeList(
-              _unlinkedTypedef.parameters, _function);
         }
+      } else {
+        _function = new GenericFunctionTypeElementImpl.forOffset(-1);
+        _function.enclosingElement = this;
+        _function.returnType = enclosingUnit.resynthesizerContext
+            .resolveTypeRef(_function, _unlinkedTypedef.returnType,
+                declaredType: true);
+        _function.parameters = ParameterElementImpl.resynthesizeList(
+            _unlinkedTypedef.parameters, _function);
       }
     }
+
     return _function;
   }
 
@@ -5228,6 +5278,9 @@
 
   @override
   String get name {
+    if (linkedNode != null) {
+      return reference.name;
+    }
     if (_unlinkedTypedef != null) {
       return _unlinkedTypedef.name;
     }
@@ -8547,16 +8600,27 @@
   }
 
   DartType get bound {
-    if (_bound == null) {
-      if (_unlinkedTypeParam != null) {
-        if (_unlinkedTypeParam.bound == null) {
-          return null;
-        }
-        _bound = enclosingUnit.resynthesizerContext.resolveTypeRef(
-            this, _unlinkedTypeParam.bound,
-            instantiateToBoundsAllowed: false, declaredType: true);
+    if (_bound != null) return _bound;
+
+    if (linkedNode != null) {
+      var bound = linkedNode.typeParameter_bound;
+      if (bound != null) {
+        var context = enclosingUnit.linkedContext;
+        return _bound = context.getTypeAnnotationType(bound);
+      } else {
+        return _bound = context.typeProvider.objectType;
       }
     }
+
+    if (_unlinkedTypeParam != null) {
+      if (_unlinkedTypeParam.bound == null) {
+        return null;
+      }
+      return _bound = enclosingUnit.resynthesizerContext.resolveTypeRef(
+          this, _unlinkedTypeParam.bound,
+          instantiateToBoundsAllowed: false, declaredType: true);
+    }
+
     return _bound;
   }
 
@@ -8617,6 +8681,9 @@
   }
 
   TypeParameterType get type {
+    if (linkedNode != null) {
+      _type ??= new TypeParameterTypeImpl(this);
+    }
     if (_unlinkedTypeParam != null) {
       _type ??= new TypeParameterTypeImpl(this);
     }
@@ -8667,19 +8734,34 @@
 
   @override
   List<TypeParameterElement> get typeParameters {
-    if (_typeParameterElements == null) {
-      List<UnlinkedTypeParam> unlinkedParams = unlinkedTypeParams;
-      if (unlinkedParams != null) {
-        int numTypeParameters = unlinkedParams.length;
-        _typeParameterElements =
-            new List<TypeParameterElement>(numTypeParameters);
-        for (int i = 0; i < numTypeParameters; i++) {
-          _typeParameterElements[i] =
-              new TypeParameterElementImpl.forSerialized(
-                  unlinkedParams[i], this);
-        }
+    if (_typeParameterElements != null) return _typeParameterElements;
+
+    if (linkedNode != null) {
+      var context = enclosingUnit.linkedContext;
+      var containerRef = reference.getChild('@typeParameter');
+      var typeParameters = context.getTypeParameters(linkedNode);
+      if (typeParameters == null) {
+        return _typeParameterElements = const [];
+      }
+      return _typeParameterElements = typeParameters.map((node) {
+        var name = context.getSimpleName(node.typeParameter_name);
+        var reference = containerRef.getChild(name);
+        reference.node = node;
+        return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+      }).toList();
+    }
+
+    List<UnlinkedTypeParam> unlinkedParams = unlinkedTypeParams;
+    if (unlinkedParams != null) {
+      int numTypeParameters = unlinkedParams.length;
+      _typeParameterElements =
+          new List<TypeParameterElement>(numTypeParameters);
+      for (int i = 0; i < numTypeParameters; i++) {
+        _typeParameterElements[i] =
+            new TypeParameterElementImpl.forSerialized(unlinkedParams[i], this);
       }
     }
+
     return _typeParameterElements ?? const <TypeParameterElement>[];
   }
 
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 2143074..ca27841f 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -8931,6 +8931,18 @@
   }
 
   @override
+  LinkedNodeTypeBuilder get functionTypeAlias_returnType2 {
+    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
+    return _variantField_24;
+  }
+
+  @override
+  LinkedNodeTypeBuilder get genericFunctionType_returnType2 {
+    assert(kind == idl.LinkedNodeKind.genericFunctionType);
+    return _variantField_24;
+  }
+
+  @override
   LinkedNodeTypeBuilder get invocationExpression_invokeType {
     assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
         kind == idl.LinkedNodeKind.methodInvocation);
@@ -8976,6 +8988,16 @@
     _variantField_24 = value;
   }
 
+  void set functionTypeAlias_returnType2(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
+    _variantField_24 = value;
+  }
+
+  void set genericFunctionType_returnType2(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.genericFunctionType);
+    _variantField_24 = value;
+  }
+
   void set invocationExpression_invokeType(LinkedNodeTypeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
         kind == idl.LinkedNodeKind.methodInvocation);
@@ -9009,6 +9031,12 @@
   }
 
   @override
+  bool get classDeclaration_isDartObject {
+    assert(kind == idl.LinkedNodeKind.classDeclaration);
+    return _variantField_27 ??= false;
+  }
+
+  @override
   bool get defaultFormalParameter_isNamed {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     return _variantField_27 ??= false;
@@ -9033,6 +9061,11 @@
     _variantField_27 = value;
   }
 
+  void set classDeclaration_isDartObject(bool value) {
+    assert(kind == idl.LinkedNodeKind.classDeclaration);
+    _variantField_27 = value;
+  }
+
   void set defaultFormalParameter_isNamed(bool value) {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     _variantField_27 = value;
@@ -9870,6 +9903,7 @@
     int classDeclaration_classKeyword,
     int classOrMixinDeclaration_rightBracket,
     int classOrMixinDeclaration_leftBracket,
+    bool classDeclaration_isDartObject,
     LinkedNodeBuilder classOrMixinDeclaration_implementsClause,
     List<LinkedNodeBuilder> classOrMixinDeclaration_members,
     LinkedNodeBuilder classOrMixinDeclaration_typeParameters,
@@ -9883,6 +9917,7 @@
         _variantField_16 = classDeclaration_classKeyword,
         _variantField_18 = classOrMixinDeclaration_rightBracket,
         _variantField_19 = classOrMixinDeclaration_leftBracket,
+        _variantField_27 = classDeclaration_isDartObject,
         _variantField_12 = classOrMixinDeclaration_implementsClause,
         _variantField_5 = classOrMixinDeclaration_members,
         _variantField_13 = classOrMixinDeclaration_typeParameters,
@@ -9977,6 +10012,7 @@
     LinkedNodeBuilder functionTypeAlias_typeParameters,
     int typeAlias_typedefKeyword,
     int typeAlias_semicolon,
+    LinkedNodeTypeBuilder functionTypeAlias_returnType2,
     LinkedNodeBuilder namedCompilationUnitMember_name,
   })  : _kind = idl.LinkedNodeKind.functionTypeAlias,
         _variantField_11 = annotatedNode_comment,
@@ -9986,6 +10022,7 @@
         _variantField_8 = functionTypeAlias_typeParameters,
         _variantField_18 = typeAlias_typedefKeyword,
         _variantField_19 = typeAlias_semicolon,
+        _variantField_24 = functionTypeAlias_returnType2,
         _variantField_14 = namedCompilationUnitMember_name;
 
   LinkedNodeBuilder.genericTypeAlias({
@@ -10603,12 +10640,14 @@
     LinkedNodeBuilder genericFunctionType_returnType,
     LinkedNodeBuilder genericFunctionType_formalParameters,
     int genericFunctionType_question,
+    LinkedNodeTypeBuilder genericFunctionType_returnType2,
   })  : _kind = idl.LinkedNodeKind.genericFunctionType,
         _variantField_6 = genericFunctionType_typeParameters,
         _variantField_15 = genericFunctionType_functionKeyword,
         _variantField_7 = genericFunctionType_returnType,
         _variantField_8 = genericFunctionType_formalParameters,
-        _variantField_16 = genericFunctionType_question;
+        _variantField_16 = genericFunctionType_question,
+        _variantField_24 = genericFunctionType_returnType2;
 
   LinkedNodeBuilder.ifElement({
     LinkedNodeBuilder ifMixin_condition,
@@ -14379,6 +14418,22 @@
   }
 
   @override
+  idl.LinkedNodeType get functionTypeAlias_returnType2 {
+    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
+    _variantField_24 ??=
+        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
+    return _variantField_24;
+  }
+
+  @override
+  idl.LinkedNodeType get genericFunctionType_returnType2 {
+    assert(kind == idl.LinkedNodeKind.genericFunctionType);
+    _variantField_24 ??=
+        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
+    return _variantField_24;
+  }
+
+  @override
   idl.LinkedNodeType get invocationExpression_invokeType {
     assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
         kind == idl.LinkedNodeKind.methodInvocation);
@@ -14428,6 +14483,14 @@
   }
 
   @override
+  bool get classDeclaration_isDartObject {
+    assert(kind == idl.LinkedNodeKind.classDeclaration);
+    _variantField_27 ??=
+        const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
+    return _variantField_27;
+  }
+
+  @override
   bool get defaultFormalParameter_isNamed {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     _variantField_27 ??=
@@ -15206,6 +15269,9 @@
       if (classOrMixinDeclaration_leftBracket != 0)
         _result["classOrMixinDeclaration_leftBracket"] =
             classOrMixinDeclaration_leftBracket;
+      if (classDeclaration_isDartObject != false)
+        _result["classDeclaration_isDartObject"] =
+            classDeclaration_isDartObject;
       if (classOrMixinDeclaration_implementsClause != null)
         _result["classOrMixinDeclaration_implementsClause"] =
             classOrMixinDeclaration_implementsClause.toJson();
@@ -15337,6 +15403,9 @@
         _result["typeAlias_typedefKeyword"] = typeAlias_typedefKeyword;
       if (typeAlias_semicolon != 0)
         _result["typeAlias_semicolon"] = typeAlias_semicolon;
+      if (functionTypeAlias_returnType2 != null)
+        _result["functionTypeAlias_returnType2"] =
+            functionTypeAlias_returnType2.toJson();
       if (namedCompilationUnitMember_name != null)
         _result["namedCompilationUnitMember_name"] =
             namedCompilationUnitMember_name.toJson();
@@ -16054,6 +16123,9 @@
             genericFunctionType_formalParameters.toJson();
       if (genericFunctionType_question != 0)
         _result["genericFunctionType_question"] = genericFunctionType_question;
+      if (genericFunctionType_returnType2 != null)
+        _result["genericFunctionType_returnType2"] =
+            genericFunctionType_returnType2.toJson();
     }
     if (kind == idl.LinkedNodeKind.ifElement) {
       if (ifMixin_condition != null)
@@ -16741,6 +16813,7 @@
             classOrMixinDeclaration_rightBracket,
         "classOrMixinDeclaration_leftBracket":
             classOrMixinDeclaration_leftBracket,
+        "classDeclaration_isDartObject": classDeclaration_isDartObject,
         "classOrMixinDeclaration_implementsClause":
             classOrMixinDeclaration_implementsClause,
         "classOrMixinDeclaration_members": classOrMixinDeclaration_members,
@@ -16827,6 +16900,7 @@
         "functionTypeAlias_typeParameters": functionTypeAlias_typeParameters,
         "typeAlias_typedefKeyword": typeAlias_typedefKeyword,
         "typeAlias_semicolon": typeAlias_semicolon,
+        "functionTypeAlias_returnType2": functionTypeAlias_returnType2,
         "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
         "isSynthetic": isSynthetic,
         "kind": kind,
@@ -17375,6 +17449,7 @@
         "genericFunctionType_formalParameters":
             genericFunctionType_formalParameters,
         "genericFunctionType_question": genericFunctionType_question,
+        "genericFunctionType_returnType2": genericFunctionType_returnType2,
         "isSynthetic": isSynthetic,
         "kind": kind,
       };
@@ -17919,6 +17994,9 @@
     with _LinkedNodeLibraryMixin
     implements idl.LinkedNodeLibrary {
   List<int> _exports;
+  String _name;
+  int _nameLength;
+  int _nameOffset;
   List<LinkedNodeUnitBuilder> _units;
   String _uriStr;
 
@@ -17931,6 +18009,29 @@
   }
 
   @override
+  String get name => _name ??= '';
+
+  void set name(String value) {
+    this._name = value;
+  }
+
+  @override
+  int get nameLength => _nameLength ??= 0;
+
+  void set nameLength(int value) {
+    assert(value == null || value >= 0);
+    this._nameLength = value;
+  }
+
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
+  void set nameOffset(int value) {
+    assert(value == null || value >= 0);
+    this._nameOffset = value;
+  }
+
+  @override
   List<LinkedNodeUnitBuilder> get units => _units ??= <LinkedNodeUnitBuilder>[];
 
   void set units(List<LinkedNodeUnitBuilder> value) {
@@ -17945,8 +18046,16 @@
   }
 
   LinkedNodeLibraryBuilder(
-      {List<int> exports, List<LinkedNodeUnitBuilder> units, String uriStr})
+      {List<int> exports,
+      String name,
+      int nameLength,
+      int nameOffset,
+      List<LinkedNodeUnitBuilder> units,
+      String uriStr})
       : _exports = exports,
+        _name = name,
+        _nameLength = nameLength,
+        _nameOffset = nameOffset,
         _units = units,
         _uriStr = uriStr;
 
@@ -17978,15 +18087,22 @@
         signature.addInt(x);
       }
     }
+    signature.addString(this._name ?? '');
+    signature.addInt(this._nameOffset ?? 0);
+    signature.addInt(this._nameLength ?? 0);
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
     fb.Offset offset_exports;
+    fb.Offset offset_name;
     fb.Offset offset_units;
     fb.Offset offset_uriStr;
     if (!(_exports == null || _exports.isEmpty)) {
       offset_exports = fbBuilder.writeListUint32(_exports);
     }
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
     if (!(_units == null || _units.isEmpty)) {
       offset_units =
           fbBuilder.writeList(_units.map((b) => b.finish(fbBuilder)).toList());
@@ -17998,6 +18114,15 @@
     if (offset_exports != null) {
       fbBuilder.addOffset(2, offset_exports);
     }
+    if (offset_name != null) {
+      fbBuilder.addOffset(3, offset_name);
+    }
+    if (_nameLength != null && _nameLength != 0) {
+      fbBuilder.addUint32(5, _nameLength);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addUint32(4, _nameOffset);
+    }
     if (offset_units != null) {
       fbBuilder.addOffset(1, offset_units);
     }
@@ -18025,6 +18150,9 @@
   _LinkedNodeLibraryImpl(this._bc, this._bcOffset);
 
   List<int> _exports;
+  String _name;
+  int _nameLength;
+  int _nameOffset;
   List<idl.LinkedNodeUnit> _units;
   String _uriStr;
 
@@ -18036,6 +18164,24 @@
   }
 
   @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
+    return _name;
+  }
+
+  @override
+  int get nameLength {
+    _nameLength ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
+    return _nameLength;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0);
+    return _nameOffset;
+  }
+
+  @override
   List<idl.LinkedNodeUnit> get units {
     _units ??=
         const fb.ListReader<idl.LinkedNodeUnit>(const _LinkedNodeUnitReader())
@@ -18055,6 +18201,9 @@
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
     if (exports.isNotEmpty) _result["exports"] = exports;
+    if (name != '') _result["name"] = name;
+    if (nameLength != 0) _result["nameLength"] = nameLength;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
     if (units.isNotEmpty)
       _result["units"] = units.map((_value) => _value.toJson()).toList();
     if (uriStr != '') _result["uriStr"] = uriStr;
@@ -18064,6 +18213,9 @@
   @override
   Map<String, Object> toMap() => {
         "exports": exports,
+        "name": name,
+        "nameLength": nameLength,
+        "nameOffset": nameOffset,
         "units": units,
         "uriStr": uriStr,
       };
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 56e0d73..29ee198 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -398,6 +398,8 @@
 
   function,
 
+  genericTypeAlias,
+
   interface,
 
   typeParameter,
@@ -1808,6 +1810,12 @@
 table LinkedNodeLibrary {
   exports:[uint] (id: 2);
 
+  name:string (id: 3);
+
+  nameLength:uint (id: 5);
+
+  nameOffset:uint (id: 4);
+
   units:[LinkedNodeUnit] (id: 1);
 
   uriStr:string (id: 0);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 94b4c25..c97cf91 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -987,6 +987,9 @@
   @VariantId(6, variant: LinkedNodeKind.classDeclaration)
   LinkedNode get classDeclaration_extendsClause;
 
+  @VariantId(27, variant: LinkedNodeKind.classDeclaration)
+  bool get classDeclaration_isDartObject;
+
   @VariantId(7, variant: LinkedNodeKind.classDeclaration)
   LinkedNode get classDeclaration_withClause;
 
@@ -1486,6 +1489,9 @@
   @VariantId(7, variant: LinkedNodeKind.functionTypeAlias)
   LinkedNode get functionTypeAlias_returnType;
 
+  @VariantId(24, variant: LinkedNodeKind.functionTypeAlias)
+  LinkedNodeType get functionTypeAlias_returnType2;
+
   @VariantId(8, variant: LinkedNodeKind.functionTypeAlias)
   LinkedNode get functionTypeAlias_typeParameters;
 
@@ -1510,6 +1516,9 @@
   @VariantId(7, variant: LinkedNodeKind.genericFunctionType)
   LinkedNode get genericFunctionType_returnType;
 
+  @VariantId(24, variant: LinkedNodeKind.genericFunctionType)
+  LinkedNodeType get genericFunctionType_returnType2;
+
   @VariantId(6, variant: LinkedNodeKind.genericFunctionType)
   LinkedNode get genericFunctionType_typeParameters;
 
@@ -2376,6 +2385,15 @@
   @Id(2)
   List<int> get exports;
 
+  @Id(3)
+  String get name;
+
+  @Id(5)
+  int get nameLength;
+
+  @Id(4)
+  int get nameOffset;
+
   @Id(1)
   List<LinkedNodeUnit> get units;
 
@@ -2425,6 +2443,7 @@
   bottom,
   dynamic_,
   function,
+  genericTypeAlias,
   interface,
   typeParameter,
   void_
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 541cfe7..bd2a422 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -419,21 +419,24 @@
   AnalysisOptionsForLink(this._linker);
 
   @override
+  ExperimentStatus get experimentStatus => new ExperimentStatus();
+
+  @override
   bool get hint => false;
 
   @override
   bool get implicitCasts => true;
 
+  @deprecated
+  @override
+  bool get previewDart2 => true;
+
   @override
   bool get strictInference => false;
 
   @override
   bool get strictRawTypes => false;
 
-  @deprecated
-  @override
-  bool get previewDart2 => true;
-
   @override
   bool get strongMode => true;
 
@@ -441,9 +444,6 @@
   bool get strongModeHints => false;
 
   @override
-  ExperimentStatus get experimentStatus => new ExperimentStatus();
-
-  @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
@@ -498,6 +498,9 @@
   Source get librarySource => library.source;
 
   @override
+  get linkedNode => null;
+
+  @override
   List<MethodElementForLink> get methods;
 
   @override
@@ -2344,6 +2347,9 @@
   LibraryElement get library => enclosingElement.library;
 
   @override
+  get linkedNode => null;
+
+  @override
   String get name {
     if (_name == null) {
       _name = serializedExecutable.name;
@@ -2854,6 +2860,9 @@
   bool get isAsynchronous => serializedExecutable.isAsynchronous;
 
   @override
+  get linkedNode => null;
+
+  @override
   DartType get returnType {
     // If this is a variable whose type needs inferring, infer it.
     if (_variable.hasImplicitType) {
@@ -3169,6 +3178,9 @@
   LibraryElementForLink get library => enclosingElement.library;
 
   @override
+  get linkedNode => null;
+
+  @override
   String get name => _unlinkedTypedef.name;
 
   @override
@@ -3287,6 +3299,9 @@
   LibraryElementForLink get library => enclosingElement.library;
 
   @override
+  get linkedNode => null;
+
+  @override
   String get name => '-';
 
   @override
@@ -3370,6 +3385,9 @@
   LibraryElementForLink get library => enclosingElement.library;
 
   @override
+  get linkedNode => null;
+
+  @override
   String get name => _unlinkedTypedef.name;
 
   @override
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 8a9076d..49d56ef 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -1356,7 +1356,7 @@
       result = containerRef.getChild(element.name ?? '');
     } else if (element is FunctionTypeAliasElement) {
       var enclosingRef = _getReference(element.enclosingElement);
-      var containerRef = enclosingRef.getChild('@functionTypeAlias');
+      var containerRef = enclosingRef.getChild('@typeAlias');
       _ensureReferenceIndex(containerRef);
 
       result = containerRef.getChild(element.name);
diff --git a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
index ed07f63..55637af 100644
--- a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
@@ -2,12 +2,14 @@
 // 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' as ast;
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/ast_binary_writer.dart';
 import 'package:analyzer/src/summary2/builder/prefix_builder.dart';
 import 'package:analyzer/src/summary2/declaration.dart';
 import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/summary2/reference_resolver.dart';
@@ -16,7 +18,6 @@
 
 class SourceLibraryBuilder {
   final Linker linker;
-  final LinkedElementFactory elementFactory;
   final Uri uri;
   final Reference reference;
   final LinkedNodeLibraryBuilder node;
@@ -31,49 +32,14 @@
   /// The export scope of the library.
   final Scope exportScope = Scope.top();
 
-  SourceLibraryBuilder(Linker linker, LinkedElementFactory elementFactory,
-      Uri uri, Reference reference, LinkedNodeLibraryBuilder node)
-      : this._(linker, elementFactory, uri, reference, node, Scope.top());
+  SourceLibraryBuilder(Linker linker, Uri uri, Reference reference,
+      LinkedNodeLibraryBuilder node)
+      : this._(linker, uri, reference, node, Scope.top());
 
-  SourceLibraryBuilder._(this.linker, this.elementFactory, this.uri,
-      this.reference, this.node, this.importScope)
+  SourceLibraryBuilder._(
+      this.linker, this.uri, this.reference, this.node, this.importScope)
       : scope = Scope(importScope, <String, Declaration>{});
 
-  void addSyntheticConstructors() {
-    for (var declaration in scope.map.values) {
-      var reference = declaration.reference;
-      var node = reference.node;
-      if (node == null) continue;
-      if (node.kind != LinkedNodeKind.classDeclaration) continue;
-
-      // Skip the class if it already has a constructor.
-      if (node.classOrMixinDeclaration_members
-          .any((n) => n.kind == LinkedNodeKind.constructorDeclaration)) {
-        continue;
-      }
-
-      node.classOrMixinDeclaration_members.add(
-        LinkedNodeBuilder.constructorDeclaration(
-          constructorDeclaration_parameters:
-              LinkedNodeBuilder.formalParameterList(),
-          constructorDeclaration_body: LinkedNodeBuilder.emptyFunctionBody(),
-        )..isSynthetic = true,
-      );
-    }
-  }
-
-  void performTopLevelInference() {
-    for (var unit in units) {
-      TopLevelInference(linker, reference, unit).infer();
-    }
-  }
-
-  void resolveTypes() {
-    for (var unit in units) {
-      ReferenceResolver(linker, unit, scope).resolve();
-    }
-  }
-
   void addImportsToScope() {
     // TODO
     var hasDartCore = false;
@@ -87,7 +53,7 @@
       }
     }
     if (!hasDartCore) {
-      var references = elementFactory.exportsOfLibrary('dart:core');
+      var references = linker.elementFactory.exportsOfLibrary('dart:core');
       for (var reference in references) {
         var name = reference.name;
         importScope.declare(name, Declaration(name, reference));
@@ -101,6 +67,7 @@
       var unitRef = reference.getChild('@unit').getChild('${unit.uri}');
       var classRef = unitRef.getChild('@class');
       var functionRef = unitRef.getChild('@function');
+      var typeAliasRef = unitRef.getChild('@typeAlias');
       var getterRef = unitRef.getChild('@getter');
       var setterRef = unitRef.getChild('@setter');
       var variableRef = unitRef.getChild('@variable');
@@ -129,6 +96,20 @@
 
           var declaration = Declaration(name, reference);
           scope.declare(name, declaration);
+        } else if (node.kind == LinkedNodeKind.functionTypeAlias) {
+          var name = unit.context.getUnitMemberName(node);
+          var reference = typeAliasRef.getChild(name);
+          reference.node = node;
+
+          var declaration = Declaration(name, reference);
+          scope.declare(name, declaration);
+        } else if (node.kind == LinkedNodeKind.genericTypeAlias) {
+          var name = unit.context.getUnitMemberName(node);
+          var reference = typeAliasRef.getChild(name);
+          reference.node = node;
+
+          var declaration = Declaration(name, reference);
+          scope.declare(name, declaration);
         } else if (node.kind == LinkedNodeKind.topLevelVariableDeclaration) {
           var variableList = node.topLevelVariableDeclaration_variableList;
           for (var variable in variableList.variableDeclarationList_variables) {
@@ -153,6 +134,29 @@
     }
   }
 
+  void addSyntheticConstructors() {
+    for (var declaration in scope.map.values) {
+      var reference = declaration.reference;
+      var node = reference.node;
+      if (node == null) continue;
+      if (node.kind != LinkedNodeKind.classDeclaration) continue;
+
+      // Skip the class if it already has a constructor.
+      if (node.classOrMixinDeclaration_members
+          .any((n) => n.kind == LinkedNodeKind.constructorDeclaration)) {
+        continue;
+      }
+
+      node.classOrMixinDeclaration_members.add(
+        LinkedNodeBuilder.constructorDeclaration(
+          constructorDeclaration_parameters:
+              LinkedNodeBuilder.formalParameterList(),
+          constructorDeclaration_body: LinkedNodeBuilder.emptyFunctionBody(),
+        )..isSynthetic = true,
+      );
+    }
+  }
+
   /// Return `true` if the export scope was modified.
   bool addToExportScope(String name, Declaration declaration) {
     if (name.startsWith('_')) return false;
@@ -168,22 +172,96 @@
     return true;
   }
 
-  void addUnit(Uri uri, LinkedUnitContext context, LinkedNode node) {
-    units.add(UnitBuilder(uri, context, node));
-  }
-
   void buildInitialExportScope() {
     scope.forEach((name, declaration) {
       addToExportScope(name, declaration);
     });
   }
 
+  void performTopLevelInference() {
+    for (var unit in units) {
+      TopLevelInference(linker, reference, unit).infer();
+    }
+  }
+
+  void resolveTypes() {
+    for (var unit in units) {
+      var unitReference = reference.getChild('@unit').getChild('${unit.uri}');
+      ReferenceResolver(linker, unit, scope, unitReference).resolve();
+    }
+  }
+
   void storeExportScope() {
     for (var declaration in exportScope.map.values) {
       var index = linker.indexOfReference(declaration.reference);
       node.exports.add(index);
     }
   }
+
+  static void build(Linker linker, Source librarySource,
+      Map<Source, ast.CompilationUnit> libraryUnits) {
+    var libraryUriStr = librarySource.uri.toString();
+    var libraryReference = linker.rootReference.getChild(libraryUriStr);
+
+    var unitNodeList = <LinkedNodeUnitBuilder>[];
+    var libraryNode = LinkedNodeLibraryBuilder(
+      units: unitNodeList,
+      uriStr: libraryUriStr,
+    );
+
+    var builder = SourceLibraryBuilder(
+      linker,
+      librarySource.uri,
+      libraryReference,
+      libraryNode,
+    );
+
+    ast.CompilationUnit definingUnit;
+    for (var unitSource in libraryUnits.keys) {
+      var unit = libraryUnits[unitSource];
+      definingUnit ??= unit;
+
+      var writer = AstBinaryWriter();
+      var unitNode = writer.writeNode(unit);
+
+      var unitContext = LinkedUnitContext(linker.bundleContext, writer.tokens);
+      builder.units.add(
+        UnitBuilder(unitSource.uri, unitContext, unitNode),
+      );
+
+      libraryNode.units.add(
+        LinkedNodeUnitBuilder(
+          uriStr: '${unitSource.uri}',
+          tokens: writer.tokens,
+          node: unitNode,
+        ),
+      );
+
+      if (libraryUriStr == 'dart:core') {
+        for (var declaration in unitNode.compilationUnit_declarations) {
+          if (declaration.kind == LinkedNodeKind.classDeclaration) {
+            var nameNode = declaration.namedCompilationUnitMember_name;
+            if (unitContext.getSimpleName(nameNode) == 'Object') {
+              declaration.classDeclaration_isDartObject = true;
+            }
+          }
+        }
+      }
+    }
+
+    for (var directive in definingUnit.directives) {
+      if (directive is ast.LibraryDirective) {
+        var name = directive.name;
+        libraryNode.name = name.components.map((id) => id.name).join('.');
+        libraryNode.nameOffset = name.offset;
+        libraryNode.nameLength = name.length;
+        break;
+      }
+    }
+
+    linker.linkingLibraries.add(libraryNode);
+    linker.builders.add(builder);
+  }
 }
 
 class UnitBuilder {
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 24c6b70..d7b9425 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -11,28 +11,24 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart';
-import 'package:analyzer/src/summary2/ast_binary_writer.dart';
 import 'package:analyzer/src/summary2/builder/source_library_builder.dart';
 import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 
 LinkResult link(
-  AnalysisContext analysisContext,
-  AnalysisSession analysisSession,
+  AnalysisOptions analysisOptions,
+  SourceFactory sourceFactory,
   Reference rootReference,
   List<LinkedNodeBundle> inputs,
   Map<Source, Map<Source, CompilationUnit>> unitMap,
 ) {
-  var linker = Linker(analysisContext, analysisSession, rootReference);
+  var linker = Linker(analysisOptions, sourceFactory, rootReference);
   linker.link(inputs, unitMap);
   return LinkResult(linker.linkingBundle);
 }
 
 class Linker {
-  final AnalysisContext analysisContext;
-  final AnalysisSession analysisSession;
   final Reference rootReference;
   LinkedElementFactory elementFactory;
 
@@ -47,62 +43,39 @@
     name: [''],
   );
 
+  List<LinkedNodeLibraryBuilder> linkingLibraries = [];
   LinkedNodeBundleBuilder linkingBundle;
+  LinkedBundleContext bundleContext;
 
   /// Libraries that are being linked.
   final List<SourceLibraryBuilder> builders = [];
 
+  _AnalysisContextForLinking analysisContext;
   TypeProvider typeProvider;
   Dart2TypeSystem typeSystem;
 
-  Linker(this.analysisContext, this.analysisSession, this.rootReference) {
+  Linker(AnalysisOptions analysisOptions, SourceFactory sourceFactory,
+      this.rootReference) {
+    analysisContext = _AnalysisContextForLinking(
+      analysisOptions,
+      sourceFactory,
+    );
+
     elementFactory = LinkedElementFactory(
       analysisContext,
-      analysisSession,
+      _AnalysisSessionForLinking(),
       rootReference,
     );
-  }
 
-  void addSyntheticConstructors() {
-    for (var library in builders) {
-      library.addSyntheticConstructors();
-    }
-  }
+    linkingBundle = LinkedNodeBundleBuilder(
+      references: referencesBuilder,
+      libraries: linkingLibraries,
+    );
 
-  void buildOutlines() {
-    computeLibraryScopes();
-    addSyntheticConstructors();
-    createTypeSystem();
-    resolveTypes();
-    performTopLevelInference();
-  }
-
-  void computeLibraryScopes() {
-    for (var library in builders) {
-      library.addLocalDeclarations();
-    }
-
-    for (var library in builders) {
-      library.buildInitialExportScope();
-    }
-
-    for (var library in builders) {
-      library.addImportsToScope();
-    }
-
-    for (var library in builders) {
-      library.storeExportScope();
-    }
-
-    // TODO(scheglov) process imports and exports
-  }
-
-  void createTypeSystem() {
-    var coreRef = rootReference.getChild('dart:core');
-    var coreLib = elementFactory.elementOfReference(coreRef);
-    typeProvider = SummaryTypeProvider()..initializeCore(coreLib);
-
-    typeSystem = Dart2TypeSystem(typeProvider);
+    bundleContext = LinkedBundleContext(
+      elementFactory,
+      linkingBundle.references,
+    );
   }
 
   int indexOfReference(Reference reference) {
@@ -124,69 +97,67 @@
       elementFactory.addBundle(input);
     }
 
-    var linkingLibraries = <LinkedNodeLibraryBuilder>[];
-    linkingBundle = LinkedNodeBundleBuilder(
-      references: referencesBuilder,
-      libraries: linkingLibraries,
-    );
-    var bundleContext = LinkedBundleContext(
-      elementFactory,
-      linkingBundle.references,
-    );
-
     for (var librarySource in unitMap.keys) {
-      var libraryUriStr = librarySource.uri.toString();
-      var libraryReference = rootReference.getChild(libraryUriStr);
-
-      var units = <LinkedNodeUnitBuilder>[];
-      var libraryNode = LinkedNodeLibraryBuilder(
-        units: units,
-        uriStr: libraryUriStr,
-      );
-
-      var libraryBuilder = SourceLibraryBuilder(
-        this,
-        elementFactory,
-        librarySource.uri,
-        libraryReference,
-        libraryNode,
-      );
-      builders.add(libraryBuilder);
-
-      var libraryUnits = unitMap[librarySource];
-      for (var unitSource in libraryUnits.keys) {
-        var unit = libraryUnits[unitSource];
-
-        var writer = AstBinaryWriter();
-        var unitData = writer.writeNode(unit);
-
-        var unitContext = LinkedUnitContext(bundleContext, writer.tokens);
-        libraryBuilder.addUnit(unitSource.uri, unitContext, unitData);
-
-        libraryNode.units.add(
-          LinkedNodeUnitBuilder(
-            uriStr: '${unitSource.uri}',
-            tokens: writer.tokens,
-            node: unitData,
-          ),
-        );
-      }
-      linkingLibraries.add(libraryNode);
+      SourceLibraryBuilder.build(this, librarySource, unitMap[librarySource]);
     }
 
     // Add libraries being linked, so we can ask for their elements as well.
     elementFactory.addBundle(linkingBundle, context: bundleContext);
 
-    buildOutlines();
+    _buildOutlines();
   }
 
-  void performTopLevelInference() {
+  void _addSyntheticConstructors() {
+    for (var library in builders) {
+      library.addSyntheticConstructors();
+    }
+  }
+
+  void _buildOutlines() {
+    _computeLibraryScopes();
+    _addSyntheticConstructors();
+    _createTypeSystem();
+    _resolveTypes();
+    _performTopLevelInference();
+  }
+
+  void _computeLibraryScopes() {
+    for (var library in builders) {
+      library.addLocalDeclarations();
+    }
+
+    for (var library in builders) {
+      library.buildInitialExportScope();
+    }
+
+    for (var library in builders) {
+      library.addImportsToScope();
+    }
+
+    for (var library in builders) {
+      library.storeExportScope();
+    }
+
+    // TODO(scheglov) process imports and exports
+  }
+
+  void _createTypeSystem() {
+    var coreRef = rootReference.getChild('dart:core');
+    var coreLib = elementFactory.elementOfReference(coreRef);
+    typeProvider = SummaryTypeProvider()..initializeCore(coreLib);
+    analysisContext.typeProvider = typeProvider;
+
+    typeSystem = Dart2TypeSystem(typeProvider);
+    analysisContext.typeSystem = typeSystem;
+  }
+
+  void _performTopLevelInference() {
     for (var library in builders) {
       library.performTopLevelInference();
     }
   }
 
-  void resolveTypes() {
+  void _resolveTypes() {
     for (var library in builders) {
       library.resolveTypes();
     }
@@ -198,3 +169,25 @@
 
   LinkResult(this.bundle);
 }
+
+class _AnalysisContextForLinking implements AnalysisContext {
+  @override
+  final AnalysisOptions analysisOptions;
+
+  @override
+  final SourceFactory sourceFactory;
+
+  @override
+  TypeProvider typeProvider;
+
+  @override
+  TypeSystem typeSystem;
+
+  _AnalysisContextForLinking(this.analysisOptions, this.sourceFactory);
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+class _AnalysisSessionForLinking implements AnalysisSession {
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
index 38c43ff..c7661d2 100644
--- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
@@ -35,6 +35,10 @@
         element,
         linkedType.interfaceTypeArguments.map(getType).toList(),
       );
+    } else if (kind == LinkedNodeTypeKind.typeParameter) {
+      var reference = referenceOfIndex(linkedType.typeParameterParameter);
+      Element element = elementFactory.elementOfReference(reference);
+      return TypeParameterTypeImpl(element);
     } else if (kind == LinkedNodeTypeKind.void_) {
       return VoidTypeImpl.instance;
     } else {
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index e99dd4e..1b4c3e9 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -27,10 +27,6 @@
     }
   }
 
-  LinkedBundleContext bundleContextOfLibrary(String uriStr) {
-    return libraryMap[uriStr].context;
-  }
-
   Element elementOfReference(Reference reference) {
     if (reference.element != null) {
       return reference.element;
@@ -50,6 +46,11 @@
     }
     return exportReferences;
   }
+
+  LibraryElementImpl libraryOfUri(String uriStr) {
+    var reference = rootReference.getChild(uriStr);
+    return elementOfReference(reference);
+  }
 }
 
 class _ElementRequest {
@@ -71,19 +72,39 @@
     );
   }
 
-  LibraryElementImpl createLibraryElement(Reference reference) {
-    // TODO(scheglov) use actual values
-    var libraryElement = LibraryElementImpl(elementFactory.analysisContext,
-        elementFactory.analysisSession, '', -1, 0);
+  GenericTypeAliasElementImpl createFunctionTypeAliasElement(
+      CompilationUnitElementImpl unit, Reference reference) {
+    if (reference.node == null) {
+      indexUnitDeclarations(unit);
+      assert(reference.node != 0, '$reference');
+    }
+    return reference.element = GenericTypeAliasElementImpl.forLinkedNode(
+      unit,
+      reference,
+      reference.node,
+    );
+  }
 
+  LibraryElementImpl createLibraryElement(Reference reference) {
     var uriStr = reference.name;
+
     var sourceFactory = elementFactory.analysisContext.sourceFactory;
-    var libraryData = elementFactory.libraryMap[uriStr];
     var librarySource = sourceFactory.forUri(uriStr);
 
+    var libraryData = elementFactory.libraryMap[uriStr];
+    var node = libraryData.node;
+    var hasName = node.name.isNotEmpty;
+    var libraryElement = LibraryElementImpl(
+      elementFactory.analysisContext,
+      elementFactory.analysisSession,
+      node.name,
+      hasName ? node.nameOffset : -1,
+      node.name.length,
+    );
+
     var units = <CompilationUnitElementImpl>[];
     var unitContainerRef = reference.getChild('@unit');
-    for (var unitData in libraryData.node.units) {
+    for (var unitData in node.units) {
       var unitSource = sourceFactory.forUri(unitData.uriStr);
       var unitElement = CompilationUnitElementImpl.forLinkedNode(
         libraryElement,
@@ -119,6 +140,19 @@
       return createClassElement(unit, reference);
     }
 
+    if (parentName == '@typeAlias') {
+      var unit = elementOfReference(parent2);
+      return createFunctionTypeAliasElement(unit, reference);
+    }
+
+    if (parentName == '@typeParameter') {
+      var enclosing = elementOfReference(parent2) as TypeParameterizedElement;
+      enclosing.typeParameters;
+      // Requesting type parameters sets elements for all their references.
+      assert(reference.element != null);
+      return reference.element;
+    }
+
     if (parentName == '@unit') {
       elementOfReference(parent2);
       // Creating a library fills all its units.
@@ -132,13 +166,18 @@
 
   void indexUnitDeclarations(CompilationUnitElementImpl unit) {
     var context = unit.linkedContext;
-    var classRef = unit.reference.getChild('@class');
+    var unitRef = unit.reference;
+    var classRef = unitRef.getChild('@class');
+    var typeAliasRef = unitRef.getChild('@typeAlias');
     for (var declaration in unit.linkedNode.compilationUnit_declarations) {
       var kind = declaration.kind;
       if (kind == LinkedNodeKind.classDeclaration ||
           kind == LinkedNodeKind.classTypeAlias) {
         var name = context.getUnitMemberName(declaration);
         classRef.getChild(name).node = declaration;
+      } else if (kind == LinkedNodeKind.functionTypeAlias) {
+        var name = context.getUnitMemberName(declaration);
+        typeAliasRef.getChild(name).node = declaration;
       } else {
         // TODO(scheglov) support other elements
         throw UnimplementedError('$kind');
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 3a8e6ce..d26e9b0 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -53,6 +53,8 @@
     } else if (kind == LinkedNodeKind.functionDeclaration) {
       parameterList = node.functionDeclaration_functionExpression
           .functionExpression_formalParameters;
+    } else if (kind == LinkedNodeKind.functionTypeAlias) {
+      parameterList = node.functionTypeAlias_formalParameters;
     } else if (kind == LinkedNodeKind.methodDeclaration) {
       parameterList = node.methodDeclaration_formalParameters;
     } else {
@@ -107,6 +109,15 @@
     return bundleContext.getType(linkedType);
   }
 
+  DartType getTypeAnnotationType(LinkedNode node) {
+    var kind = node.kind;
+    if (kind == LinkedNodeKind.typeName) {
+      return getType(node.typeName_type);
+    } else {
+      throw UnimplementedError('$kind');
+    }
+  }
+
   List<LinkedNode> getTypeParameters(LinkedNode node) {
     LinkedNode typeParameterList;
     var kind = node.kind;
@@ -115,6 +126,14 @@
     } else if (kind == LinkedNodeKind.classDeclaration ||
         kind == LinkedNodeKind.mixinDeclaration) {
       typeParameterList = node.classOrMixinDeclaration_typeParameters;
+    } else if (kind == LinkedNodeKind.functionDeclaration) {
+      return getTypeParameters(node.functionDeclaration_functionExpression);
+    } else if (kind == LinkedNodeKind.functionExpression) {
+      typeParameterList = node.functionExpression_typeParameters;
+    } else if (kind == LinkedNodeKind.functionTypeAlias) {
+      typeParameterList = node.functionTypeAlias_typeParameters;
+    } else if (kind == LinkedNodeKind.methodDeclaration) {
+      typeParameterList = node.methodDeclaration_typeParameters;
     } else {
       throw UnimplementedError('$kind');
     }
@@ -154,7 +173,7 @@
   }
 
   bool isConstKeyword(int token) {
-    return getTokenLexeme(token) == 'const';
+    return tokens.type[token] == UnlinkedTokenType.CONST;
   }
 
   bool isConstVariableList(LinkedNode node) {
@@ -183,7 +202,7 @@
   }
 
   bool isFinalKeyword(int token) {
-    return getTokenLexeme(token) == 'final';
+    return tokens.type[token] == UnlinkedTokenType.FINAL;
   }
 
   bool isFinalVariableList(LinkedNode node) {
@@ -216,6 +235,10 @@
         _isGetToken(node.methodDeclaration_propertyKeyword);
   }
 
+  bool isLibraryKeyword(int token) {
+    return tokens.type[token] == UnlinkedTokenType.LIBRARY;
+  }
+
   bool isMethod(LinkedNode node) {
     return node.kind == LinkedNodeKind.methodDeclaration;
   }
diff --git a/pkg/analyzer/lib/src/summary2/reference.dart b/pkg/analyzer/lib/src/summary2/reference.dart
index 6045db9..b647ad3 100644
--- a/pkg/analyzer/lib/src/summary2/reference.dart
+++ b/pkg/analyzer/lib/src/summary2/reference.dart
@@ -48,6 +48,12 @@
 
   bool get isClass => parent != null && parent.name == '@class';
 
+  bool get isGenericTypeAlias => parent != null && parent.name == '@typeAlias';
+
+  bool get isTypeParameter => parent != null && parent.name == '@typeParameter';
+
+  int get numOfChildren => _children != null ? _children.length : 0;
+
   /// Return the child with the given name, or `null` if does not exist.
   Reference operator [](String name) {
     return _children != null ? _children[name] : null;
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index b507621..f5e0e76 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -5,7 +5,9 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/builder/source_library_builder.dart';
+import 'package:analyzer/src/summary2/declaration.dart';
 import 'package:analyzer/src/summary2/link.dart';
+import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/summary2/scope.dart';
 
 /// Recursive visitor of [LinkedNode]s that resolves explicit type annotations
@@ -24,7 +26,15 @@
   /// TODO(scheglov) Update scope with local scopes (formal / type parameters).
   Scope scope;
 
-  ReferenceResolver(this.linker, this.unit, this.scope);
+  Reference reference;
+
+  ReferenceResolver(this.linker, this.unit, this.scope, this.reference);
+
+  LinkedNodeTypeBuilder get _dynamicType {
+    return LinkedNodeTypeBuilder(
+      kind: LinkedNodeTypeKind.dynamic_,
+    );
+  }
 
   void resolve() {
     _node(unit.node);
@@ -97,7 +107,7 @@
     var typeNode = node.fieldFormalParameter_type;
     if (typeNode != null) {
       _node(typeNode);
-      node.fieldFormalParameter_type2 = typeNode.typeName_type;
+      node.fieldFormalParameter_type2 = _getTypeAnnotationType(typeNode);
     }
 
     var formalParameters = node.fieldFormalParameter_formalParameters;
@@ -116,13 +126,10 @@
   void _functionDeclaration(LinkedNodeBuilder node) {
     var returnType = node.functionDeclaration_returnType;
     if (returnType != null) {
-      _typeName(returnType);
-      // TODO(scheglov) type annotation?
-      node.functionDeclaration_returnType2 = returnType.typeName_type;
+      _node(returnType);
+      node.functionDeclaration_returnType2 = _getTypeAnnotationType(returnType);
     } else {
-      node.functionDeclaration_returnType2 = LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.dynamic_,
-      );
+      node.functionDeclaration_returnType2 = _dynamicType;
     }
 
     _node(node.functionDeclaration_functionExpression);
@@ -133,19 +140,122 @@
     _node(node.functionExpression_formalParameters);
   }
 
+  void _functionTypeAlias(LinkedNodeBuilder node) {
+    var name = unit.context.getSimpleName(
+      node.namedCompilationUnitMember_name,
+    );
+    reference = reference.getChild('@typeAlias').getChild(name);
+
+    var typeParameters = node.functionTypeAlias_typeParameters;
+    if (typeParameters != null) {
+      _newScopeTypeParameters(typeParameters);
+    }
+
+    _node(typeParameters);
+
+    var returnType = node.functionTypeAlias_returnType;
+    if (returnType != null) {
+      _node(returnType);
+      node.functionTypeAlias_returnType2 = _getTypeAnnotationType(returnType);
+    } else {
+      node.functionTypeAlias_returnType2 = _dynamicType;
+    }
+
+    _node(node.functionTypeAlias_formalParameters);
+
+    if (typeParameters != null) {
+      scope = scope.parent;
+    }
+    reference = reference.parent.parent;
+  }
+
+  void _genericFunctionType(LinkedNodeBuilder node) {
+    reference = reference.getChild('@function');
+
+    var name = '${reference.numOfChildren}';
+    reference = reference.getChild(name);
+
+    var typeParameters = node.genericFunctionType_typeParameters;
+    if (typeParameters != null) {
+      _newScopeTypeParameters(typeParameters);
+    }
+
+    _node(typeParameters);
+
+    var returnType = node.genericFunctionType_returnType;
+    if (returnType != null) {
+      _node(returnType);
+      node.genericFunctionType_returnType2 = _getTypeAnnotationType(returnType);
+    } else {
+      node.genericFunctionType_returnType2 = _dynamicType;
+    }
+
+    _node(node.genericFunctionType_formalParameters);
+
+    if (typeParameters != null) {
+      scope = scope.parent;
+    }
+    reference = reference.parent.parent;
+  }
+
+  void _genericTypeAlias(LinkedNodeBuilder node) {
+    var name = unit.context.getSimpleName(
+      node.namedCompilationUnitMember_name,
+    );
+    reference = reference.getChild('@typeAlias').getChild(name);
+
+    var typeParameters = node.genericTypeAlias_typeParameters;
+    if (typeParameters != null) {
+      _newScopeTypeParameters(typeParameters);
+    }
+
+    var function = node.genericTypeAlias_functionType;
+
+    _node(typeParameters);
+    _node(function);
+
+    if (typeParameters != null) {
+      scope = scope.parent;
+    }
+    reference = reference.parent.parent;
+  }
+
+  LinkedNodeTypeBuilder _getTypeAnnotationType(LinkedNodeBuilder node) {
+    var kind = node.kind;
+    if (kind == LinkedNodeKind.typeName) {
+      return node.typeName_type;
+    } else {
+      throw UnimplementedError('$kind');
+    }
+  }
+
+  void _libraryDirective(LinkedNodeBuilder node) {}
+
   void _methodDeclaration(LinkedNodeBuilder node) {
     _node(node.methodDeclaration_typeParameters);
 
     var returnType = node.methodDeclaration_returnType;
     if (returnType != null) {
       _node(returnType);
-      // TODO(scheglov) might be an not TypeName
-      node.methodDeclaration_returnType2 = returnType.typeName_type;
+      node.methodDeclaration_returnType2 = _getTypeAnnotationType(returnType);
     }
 
     _node(node.methodDeclaration_formalParameters);
   }
 
+  void _newScopeTypeParameters(LinkedNode typeParameterList) {
+    scope = Scope(this.scope, {});
+
+    var containerRef = this.reference.getChild('@typeParameter');
+    var typeParameters = typeParameterList.typeParameterList_typeParameters;
+    for (var typeParameter in typeParameters) {
+      var name = unit.context.getSimpleName(typeParameter.typeParameter_name);
+      var reference = containerRef.getChild(name);
+      reference.node = typeParameter;
+      scope.declare(name, Declaration(name, reference));
+    }
+  }
+
   void _node(LinkedNodeBuilder node) {
     if (node == null) return;
 
@@ -167,6 +277,14 @@
       _functionDeclaration(node);
     } else if (node.kind == LinkedNodeKind.functionExpression) {
       _functionExpression(node);
+    } else if (node.kind == LinkedNodeKind.functionTypeAlias) {
+      _functionTypeAlias(node);
+    } else if (node.kind == LinkedNodeKind.genericFunctionType) {
+      _genericFunctionType(node);
+    } else if (node.kind == LinkedNodeKind.genericTypeAlias) {
+      _genericTypeAlias(node);
+    } else if (node.kind == LinkedNodeKind.libraryDirective) {
+      _libraryDirective(node);
     } else if (node.kind == LinkedNodeKind.methodDeclaration) {
       _methodDeclaration(node);
     } else if (node.kind == LinkedNodeKind.simpleFormalParameter) {
@@ -202,12 +320,10 @@
     var typeNode = node.simpleFormalParameter_type;
     if (typeNode != null) {
       _node(typeNode);
-      node.simpleFormalParameter_type2 = typeNode.typeName_type;
+      node.simpleFormalParameter_type2 = _getTypeAnnotationType(typeNode);
     } else {
       // TODO(scheglov) might be inferred
-      node.simpleFormalParameter_type2 = LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.dynamic_,
-      );
+      node.simpleFormalParameter_type2 = _dynamicType;
     }
 
     if (node.normalFormalParameter_covariantKeyword != 0) {
@@ -244,9 +360,7 @@
       var declaration = scope.lookup(name);
       if (declaration == null) {
         identifier.simpleIdentifier_element = 0;
-        node.typeName_type = LinkedNodeTypeBuilder(
-          kind: LinkedNodeTypeKind.dynamic_,
-        );
+        node.typeName_type = _dynamicType;
         return;
       }
 
@@ -259,7 +373,7 @@
       if (typeArgumentList != null) {
         _node(typeArgumentList);
         typeArguments = typeArgumentList.typeArgumentList_arguments
-            .map((node) => node.typeName_type)
+            .map((node) => _getTypeAnnotationType(node))
             .toList();
       }
 
@@ -269,7 +383,11 @@
           interfaceClass: referenceIndex,
           interfaceTypeArguments: typeArguments,
         );
-        // TODO(scheglov) type arguments
+      } else if (reference.isTypeParameter) {
+        node.typeName_type = LinkedNodeTypeBuilder(
+          kind: LinkedNodeTypeKind.typeParameter,
+          typeParameterParameter: referenceIndex,
+        );
       } else {
         // TODO(scheglov) set Object? keep unresolved?
         throw UnimplementedError();
@@ -296,7 +414,7 @@
     if (typeNode != null) {
       _node(typeNode);
       for (var field in node.variableDeclarationList_variables) {
-        field.variableDeclaration_type2 = typeNode.typeName_type;
+        field.variableDeclaration_type2 = _getTypeAnnotationType(typeNode);
       }
     }
   }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 002ff8c..69da6c9 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -6,6 +6,8 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/type_system.dart';
+import 'package:analyzer/src/summary/summary_sdk.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
@@ -30,6 +32,8 @@
     var dartCoreSource = sourceFactory.forUri('dart:core');
     var dartCoreCode = getFile(dartCoreSource.fullName).readAsStringSync();
     dartCoreCode = r'''
+library dart.core;
+
 abstract class Comparable<T> {
   int compareTo(T other);
 }
@@ -74,24 +78,29 @@
     };
 
     var linkResult = link(
-      _FakeAnalysisContext(sourceFactory, null),
-      null,
+      AnalysisOptionsImpl(),
+      sourceFactory,
       rootReference,
       [dartCoreResult.bundle],
       libraryUnitMap,
     );
 
-    var rootReference2 = Reference.root();
+    var analysisContext = _FakeAnalysisContext(sourceFactory);
+
     var elementFactory = LinkedElementFactory(
-      _FakeAnalysisContext(sourceFactory, null),
+      analysisContext,
       null,
-      rootReference2,
+      Reference.root(),
     );
     elementFactory.addBundle(dartCoreResult.bundle);
     elementFactory.addBundle(linkResult.bundle);
-    return elementFactory.elementOfReference(
-      rootReference2.getChild('${source.uri}'),
-    );
+
+    var dartCore = elementFactory.libraryOfUri('dart:core');
+    var typeProvider = SummaryTypeProvider()..initializeCore(dartCore);
+    analysisContext.typeProvider = typeProvider;
+    analysisContext.typeSystem = Dart2TypeSystem(typeProvider);
+
+    return elementFactory.libraryOfUri('${source.uri}');
   }
 
   @override
@@ -178,12 +187,6 @@
 
   @override
   @failingTest
-  test_class_type_parameters_bound() async {
-    await super.test_class_type_parameters_bound();
-  }
-
-  @override
-  @failingTest
   test_class_type_parameters_f_bound_complex() async {
     await super.test_class_type_parameters_f_bound_complex();
   }
@@ -650,12 +653,6 @@
 
   @override
   @failingTest
-  test_const_topLevel_ifNull() async {
-    await super.test_const_topLevel_ifNull();
-  }
-
-  @override
-  @failingTest
   test_const_topLevel_literal() async {
     await super.test_const_topLevel_literal();
   }
@@ -1425,12 +1422,6 @@
 
   @override
   @failingTest
-  test_inferred_function_type_for_variable_in_generic_function() async {
-    await super.test_inferred_function_type_for_variable_in_generic_function();
-  }
-
-  @override
-  @failingTest
   test_inferred_function_type_in_generic_class_in_generic_method() async {
     await super
         .test_inferred_function_type_in_generic_class_in_generic_method();
@@ -1438,18 +1429,6 @@
 
   @override
   @failingTest
-  test_inferred_function_type_in_generic_closure() async {
-    await super.test_inferred_function_type_in_generic_closure();
-  }
-
-  @override
-  @failingTest
-  test_inferred_generic_function_type_in_generic_closure() async {
-    await super.test_inferred_generic_function_type_in_generic_closure();
-  }
-
-  @override
-  @failingTest
   test_inferred_type_is_typedef() async {
     await super.test_inferred_type_is_typedef();
   }
@@ -1683,18 +1662,6 @@
 
   @override
   @failingTest
-  test_library_name_with_spaces() async {
-    await super.test_library_name_with_spaces();
-  }
-
-  @override
-  @failingTest
-  test_library_named() async {
-    await super.test_library_named();
-  }
-
-  @override
-  @failingTest
   test_main_class_alias_via_export() async {
     await super.test_main_class_alias_via_export();
   }
@@ -1713,12 +1680,6 @@
 
   @override
   @failingTest
-  test_main_typedef() async {
-    await super.test_main_typedef();
-  }
-
-  @override
-  @failingTest
   test_main_typedef_via_export() async {
     await super.test_main_typedef_via_export();
   }
@@ -1941,30 +1902,6 @@
 
   @override
   @failingTest
-  test_metadata_typeParameter_ofClass() async {
-    await super.test_metadata_typeParameter_ofClass();
-  }
-
-  @override
-  @failingTest
-  test_metadata_typeParameter_ofClassTypeAlias() async {
-    await super.test_metadata_typeParameter_ofClassTypeAlias();
-  }
-
-  @override
-  @failingTest
-  test_metadata_typeParameter_ofFunction() async {
-    await super.test_metadata_typeParameter_ofFunction();
-  }
-
-  @override
-  @failingTest
-  test_metadata_typeParameter_ofTypedef() async {
-    await super.test_metadata_typeParameter_ofTypedef();
-  }
-
-  @override
-  @failingTest
   test_method_inferred_type_nonStatic_implicit_param() async {
     await super.test_method_inferred_type_nonStatic_implicit_param();
   }
@@ -2053,18 +1990,6 @@
 
   @override
   @failingTest
-  test_nested_generic_functions_with_function_typed_param() async {
-    await super.test_nested_generic_functions_with_function_typed_param();
-  }
-
-  @override
-  @failingTest
-  test_nested_generic_functions_with_local_variables() async {
-    await super.test_nested_generic_functions_with_local_variables();
-  }
-
-  @override
-  @failingTest
   test_parameter_covariant_inherited() async {
     await super.test_parameter_covariant_inherited();
   }
@@ -2149,24 +2074,12 @@
 
   @override
   @failingTest
-  test_syntheticFunctionType_genericClosure_inGenericFunction() async {
-    await super.test_syntheticFunctionType_genericClosure_inGenericFunction();
-  }
-
-  @override
-  @failingTest
   test_syntheticFunctionType_inGenericClass() async {
     await super.test_syntheticFunctionType_inGenericClass();
   }
 
   @override
   @failingTest
-  test_syntheticFunctionType_inGenericFunction() async {
-    await super.test_syntheticFunctionType_inGenericFunction();
-  }
-
-  @override
-  @failingTest
   test_syntheticFunctionType_noArguments() async {
     await super.test_syntheticFunctionType_noArguments();
   }
@@ -2365,12 +2278,6 @@
 
   @override
   @failingTest
-  test_typedef_documented() async {
-    await super.test_typedef_documented();
-  }
-
-  @override
-  @failingTest
   test_typedef_generic() async {
     await super.test_typedef_generic();
   }
@@ -2401,66 +2308,12 @@
 
   @override
   @failingTest
-  test_typedef_parameter_type() async {
-    await super.test_typedef_parameter_type();
-  }
-
-  @override
-  @failingTest
-  test_typedef_parameter_type_generic() async {
-    await super.test_typedef_parameter_type_generic();
-  }
-
-  @override
-  @failingTest
-  test_typedef_parameters() async {
-    await super.test_typedef_parameters();
-  }
-
-  @override
-  @failingTest
   test_typedef_parameters_named() async {
     await super.test_typedef_parameters_named();
   }
 
   @override
   @failingTest
-  test_typedef_return_type() async {
-    await super.test_typedef_return_type();
-  }
-
-  @override
-  @failingTest
-  test_typedef_return_type_generic() async {
-    await super.test_typedef_return_type_generic();
-  }
-
-  @override
-  @failingTest
-  test_typedef_return_type_implicit() async {
-    await super.test_typedef_return_type_implicit();
-  }
-
-  @override
-  @failingTest
-  test_typedef_return_type_void() async {
-    await super.test_typedef_return_type_void();
-  }
-
-  @override
-  @failingTest
-  test_typedef_type_parameters() async {
-    await super.test_typedef_type_parameters();
-  }
-
-  @override
-  @failingTest
-  test_typedef_type_parameters_bound() async {
-    await super.test_typedef_type_parameters_bound();
-  }
-
-  @override
-  @failingTest
   test_typedef_type_parameters_bound_recursive() async {
     await super.test_typedef_type_parameters_bound_recursive();
   }
@@ -2641,32 +2494,22 @@
     };
 
     var rootReference = Reference.root();
-    var linkResult = link(
-      _FakeAnalysisContext(sourceFactory, null),
-      null,
+    return link(
+      AnalysisOptionsImpl(),
+      sourceFactory,
       rootReference,
       [],
       libraryUnitMap,
     );
-    return linkResult;
-//    var linkResult = link(rootReference, libraryUnitMap);
-
-//    var libraryLinkResult = linkResult.libraries[source];
-//    var defaultUnitResult = libraryLinkResult.units[source];
-//
-//    var linkedBundleContext = LinkedBundleContext(linkResult.references);
-//    var linkedUnitContext = LinkedUnitContext(
-//      linkedBundleContext,
-//      defaultUnitResult.tokens,
-//    );
   }
 }
 
 class _FakeAnalysisContext implements AnalysisContext {
   final SourceFactory sourceFactory;
-  final Dart2TypeSystem typeSystem;
+  TypeProvider typeProvider;
+  Dart2TypeSystem typeSystem;
 
-  _FakeAnalysisContext(this.sourceFactory, this.typeSystem);
+  _FakeAnalysisContext(this.sourceFactory);
 
   @override
   AnalysisOptions get analysisOptions {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 985f379..2a5a696 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -24,7 +24,7 @@
 
 @reflectiveTest
 class ResynthesizeAstStrongTest extends ResynthesizeTestStrategyTwoPhase
-    with ResynthesizeTestCases, ResynthesizeTestHelpers {
+    with ResynthesizeTestCases, GetElementTestCases, ResynthesizeTestHelpers {
   @failingTest // See dartbug.com/32290
   test_const_constructor_inferred_args() =>
       super.test_const_constructor_inferred_args();
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 3f672e4..7c2c962 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -107,6 +107,104 @@
 /// Mixin containing test cases exercising summary resynthesis.  Intended to be
 /// applied to a class implementing [ResynthesizeTestStrategy], along with the
 /// mixin [ResynthesizeTestHelpers].
+mixin GetElementTestCases implements ResynthesizeTestHelpers {
+  test_getElement_class() async {
+    var resynthesized = _validateGetElement(
+      'class C { m() {} }',
+      ['C'],
+    );
+    expect(resynthesized, isClassElement);
+  }
+
+  test_getElement_constructor_named() async {
+    var resynthesized = _validateGetElement(
+      'class C { C.named(); }',
+      ['C', 'named'],
+    );
+    expect(resynthesized, isConstructorElement);
+  }
+
+  test_getElement_constructor_unnamed() async {
+    var resynthesized = _validateGetElement(
+      'class C { C(); }',
+      ['C', ''],
+    );
+    expect(resynthesized, isConstructorElement);
+  }
+
+  test_getElement_field() async {
+    var resynthesized = _validateGetElement(
+      'class C { var f; }',
+      ['C', 'f'],
+    );
+    expect(resynthesized, isFieldElement);
+  }
+
+  test_getElement_getter() async {
+    var resynthesized = _validateGetElement(
+      'class C { get f => null; }',
+      ['C', 'f?'],
+    );
+    expect(resynthesized, isPropertyAccessorElement);
+  }
+
+  test_getElement_method() async {
+    var resynthesized = _validateGetElement(
+      'class C { m() {} }',
+      ['C', 'm'],
+    );
+    expect(resynthesized, isMethodElement);
+  }
+
+  test_getElement_operator() async {
+    var resynthesized = _validateGetElement(
+      'class C { operator+(x) => null; }',
+      ['C', '+'],
+    );
+    expect(resynthesized, isMethodElement);
+  }
+
+  test_getElement_setter() async {
+    var resynthesized = _validateGetElement(
+      'class C { void set f(value) {} }',
+      ['C', 'f='],
+    );
+    expect(resynthesized, isPropertyAccessorElement);
+  }
+
+  test_getElement_unit() async {
+    var resynthesized = _validateGetElement('class C {}', []);
+    expect(resynthesized, isCompilationUnitElement);
+  }
+
+  /**
+   * Encode the library [text] into a summary and then use
+   * [TestSummaryResynthesizer.getElement] to retrieve just the element with
+   * the specified [names] from the resynthesized summary.
+   */
+  Element _validateGetElement(String text, List<String> names) {
+    Source source = addTestSource(text);
+    SummaryResynthesizer resynthesizer = encodeLibrary(source);
+
+    var locationComponents = [
+      source.uri.toString(),
+      source.uri.toString(),
+    ]..addAll(names);
+    var location = ElementLocationImpl.con3(locationComponents);
+
+    Element result = resynthesizer.getElement(location);
+    checkMinimalResynthesisWork(resynthesizer, source.uri, [source.uri]);
+    // Check that no other summaries needed to be resynthesized to resynthesize
+    // the library element.
+    expect(resynthesizer.resynthesisCount, 3);
+    expect(result.location, location);
+    return result;
+  }
+}
+
+/// Mixin containing test cases exercising summary resynthesis.  Intended to be
+/// applied to a class implementing [ResynthesizeTestStrategy], along with the
+/// mixin [ResynthesizeTestHelpers].
 mixin ResynthesizeTestCases implements ResynthesizeTestHelpers {
   test_class_abstract() async {
     var library = await checkLibrary('abstract class C {}');
@@ -4911,75 +5009,6 @@
 ''');
   }
 
-  test_getElement_class() async {
-    var resynthesized = _validateGetElement(
-      'class C { m() {} }',
-      ['C'],
-    );
-    expect(resynthesized, isClassElement);
-  }
-
-  test_getElement_constructor_named() async {
-    var resynthesized = _validateGetElement(
-      'class C { C.named(); }',
-      ['C', 'named'],
-    );
-    expect(resynthesized, isConstructorElement);
-  }
-
-  test_getElement_constructor_unnamed() async {
-    var resynthesized = _validateGetElement(
-      'class C { C(); }',
-      ['C', ''],
-    );
-    expect(resynthesized, isConstructorElement);
-  }
-
-  test_getElement_field() async {
-    var resynthesized = _validateGetElement(
-      'class C { var f; }',
-      ['C', 'f'],
-    );
-    expect(resynthesized, isFieldElement);
-  }
-
-  test_getElement_getter() async {
-    var resynthesized = _validateGetElement(
-      'class C { get f => null; }',
-      ['C', 'f?'],
-    );
-    expect(resynthesized, isPropertyAccessorElement);
-  }
-
-  test_getElement_method() async {
-    var resynthesized = _validateGetElement(
-      'class C { m() {} }',
-      ['C', 'm'],
-    );
-    expect(resynthesized, isMethodElement);
-  }
-
-  test_getElement_operator() async {
-    var resynthesized = _validateGetElement(
-      'class C { operator+(x) => null; }',
-      ['C', '+'],
-    );
-    expect(resynthesized, isMethodElement);
-  }
-
-  test_getElement_setter() async {
-    var resynthesized = _validateGetElement(
-      'class C { void set f(value) {} }',
-      ['C', 'f='],
-    );
-    expect(resynthesized, isPropertyAccessorElement);
-  }
-
-  test_getElement_unit() async {
-    var resynthesized = _validateGetElement('class C {}', []);
-    expect(resynthesized, isCompilationUnitElement);
-  }
-
   test_getter_documented() async {
     var library = await checkLibrary('''
 // Extra comment so doc comment offset != 0
@@ -8684,30 +8713,6 @@
 int j;
 ''');
   }
-
-  /**
-   * Encode the library [text] into a summary and then use
-   * [TestSummaryResynthesizer.getElement] to retrieve just the element with
-   * the specified [names] from the resynthesized summary.
-   */
-  Element _validateGetElement(String text, List<String> names) {
-    Source source = addTestSource(text);
-    SummaryResynthesizer resynthesizer = encodeLibrary(source);
-
-    var locationComponents = [
-      source.uri.toString(),
-      source.uri.toString(),
-    ]..addAll(names);
-    var location = ElementLocationImpl.con3(locationComponents);
-
-    Element result = resynthesizer.getElement(location);
-    checkMinimalResynthesisWork(resynthesizer, source.uri, [source.uri]);
-    // Check that no other summaries needed to be resynthesized to resynthesize
-    // the library element.
-    expect(resynthesizer.resynthesisCount, 3);
-    expect(result.location, location);
-    return result;
-  }
 }
 
 /// Mixin containing helper methods for testing summary resynthesis.  Intended