@@ -85,7 +85,9 @@ class EmptyTypeEnvironment implements DDCTypeEnvironment {
8585
8686/// A type environment introduced by a class with one or more generic type
8787/// parameters.
88- class ClassTypeEnvironment implements DDCTypeEnvironment {
88+ class ClassTypeEnvironment
89+ implements DDCTypeEnvironment , ExtendableTypeEnvironment {
90+ @override
8991 final List <TypeParameter > _typeParameters;
9092
9193 ClassTypeEnvironment (this ._typeParameters);
@@ -94,7 +96,7 @@ class ClassTypeEnvironment implements DDCTypeEnvironment {
9496 DDCTypeEnvironment extend (List <TypeParameter > parameters) {
9597 return parameters.isEmpty
9698 ? this
97- : ExtendedClassTypeEnvironment (this , [...parameters]);
99+ : ExtendedTypeEnvironment < ClassTypeEnvironment > (this , [...parameters]);
98100 }
99101
100102 @override
@@ -125,17 +127,19 @@ class ClassTypeEnvironment implements DDCTypeEnvironment {
125127
126128/// A type environment introduced by a subroutine, wherein an RTI object is
127129/// explicitly provided.
128- class RtiTypeEnvironment implements DDCTypeEnvironment {
130+ class RtiTypeEnvironment
131+ implements DDCTypeEnvironment , ExtendableTypeEnvironment {
132+ @override
129133 final List <TypeParameter > _typeParameters;
130134
131135 RtiTypeEnvironment (this ._typeParameters);
132136
133137 @override
134138 DDCTypeEnvironment extend (List <TypeParameter > parameters) {
135- /// RtiTypeEnvironments are only used for constructors, factories, and type
136- /// signatures - none of which can accept generic arguments.
137- throw Exception (
138- 'RtiTypeEnvironments should not receive extended type parameters.' );
139+ /// RtiTypeEnvironments are only used for factories and type signatures. Of
140+ /// these factories can have generic functions defined in their bodies that
141+ /// require extending the environment.
142+ return ExtendedTypeEnvironment < RtiTypeEnvironment >( this , [...parameters] );
139143 }
140144
141145 @override
@@ -210,19 +214,25 @@ class BindingTypeEnvironment implements DDCTypeEnvironment {
210214 bool get isSingleTypeParameter => _typeParameters.length == 1 ;
211215}
212216
213- /// A type environment based on one introduced by a generic class but extended
214- /// with additional parameters from methods with generic type parameters.
215- class ExtendedClassTypeEnvironment implements DDCTypeEnvironment {
216- final ClassTypeEnvironment _classEnvironment;
217+ abstract class ExtendableTypeEnvironment extends DDCTypeEnvironment {
218+ List <TypeParameter > get _typeParameters;
219+ }
220+
221+ /// A type environment based on one introduced by a generic environment but
222+ /// extended with additional parameters from methods/functions with generic type
223+ /// parameters.
224+ class ExtendedTypeEnvironment <T extends ExtendableTypeEnvironment >
225+ implements DDCTypeEnvironment {
226+ final T _baseTypeEnvironment;
217227 final List <TypeParameter > _typeParameters;
218228
219- ExtendedClassTypeEnvironment (this ._classEnvironment , this ._typeParameters);
229+ ExtendedTypeEnvironment (this ._baseTypeEnvironment , this ._typeParameters);
220230
221231 @override
222232 DDCTypeEnvironment extend (List <TypeParameter > parameters) {
223233 return parameters.isEmpty
224234 ? this
225- : ExtendedClassTypeEnvironment (_classEnvironment , [
235+ : ExtendedTypeEnvironment (_baseTypeEnvironment , [
226236 // Place new parameters first so they can effectively shadow
227237 // parameters already in the environment.
228238 ...parameters, ..._typeParameters
@@ -231,36 +241,36 @@ class ExtendedClassTypeEnvironment implements DDCTypeEnvironment {
231241
232242 @override
233243 DDCTypeEnvironment prune (Iterable <TypeParameter > requiredParameters) {
234- var classEnvironmentNeeded =
235- requiredParameters.any (_classEnvironment ._typeParameters.contains);
244+ var baseEnvironmentNeeded =
245+ requiredParameters.any (_baseTypeEnvironment ._typeParameters.contains);
236246 var additionalParameters =
237247 requiredParameters.where (_typeParameters.contains);
238248 if (additionalParameters.isEmpty) {
239- return classEnvironmentNeeded
240- // Simply using the class environment has a compact representation
249+ return baseEnvironmentNeeded
250+ // Simply using the base environment has a compact representation
241251 // and is already constructed.
242- ? _classEnvironment
252+ ? _baseTypeEnvironment
243253 // No type parameters are needed from this environment.
244254 : const EmptyTypeEnvironment ();
245255 }
246256 // This is already the exact environment needed.
247257 if (additionalParameters.length == _typeParameters.length) return this ;
248- // An extended class environment with fewer additional parameters is needed.
249- return ExtendedClassTypeEnvironment (
250- _classEnvironment , additionalParameters.toList ());
258+ // An extended environment with fewer additional parameters is needed.
259+ return ExtendedTypeEnvironment (
260+ _baseTypeEnvironment , additionalParameters.toList ());
251261 }
252262
253263 @override
254264 int recipeIndexOf (TypeParameter parameter) {
255265 // Search in the extended type parameters first. They can shadow parameters
256- // from the class .
266+ // from the base environment .
257267 var i = _typeParameters.indexOf (parameter);
258268 // Type parameter was found and should be a one based index. Zero refers to
259- // the original class rti that is the basis on this environment.
269+ // the original rti that is the basis of this environment.
260270 if (i >= 0 ) return i + 1 ;
261- i = _classEnvironment .recipeIndexOf (parameter);
271+ i = _baseTypeEnvironment .recipeIndexOf (parameter);
262272 // The type parameter bindings with the closest scope have the lowest
263- // indices. Since the parameter was found in the class binding the index
273+ // indices. Since the parameter was found in the base binding the index
264274 // must be offset by the number of extended parameters.
265275 if (i > 0 ) return i + _typeParameters.length;
266276 // Type parameter not found.
@@ -269,7 +279,7 @@ class ExtendedClassTypeEnvironment implements DDCTypeEnvironment {
269279
270280 @override
271281 List <TypeParameter > get classTypeParameters =>
272- UnmodifiableListView (_classEnvironment .classTypeParameters);
282+ UnmodifiableListView (_baseTypeEnvironment .classTypeParameters);
273283
274284 @override
275285 List <TypeParameter > get functionTypeParameters =>
0 commit comments