OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 import 'package:analyzer/dart/element/element.dart'; | 5 import 'package:analyzer/dart/element/element.dart'; |
6 import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember; | 6 import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember; |
7 import 'package:analyzer/dart/element/type.dart'; | 7 import 'package:analyzer/dart/element/type.dart'; |
8 | 8 |
9 import '../js_ast/js_ast.dart' as JS; | 9 import '../js_ast/js_ast.dart' as JS; |
10 import '../js_ast/js_ast.dart' show js; | 10 import '../js_ast/js_ast.dart' show js; |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 var temp = _names[type]; | 143 var temp = _names[type]; |
144 if (temp == null) { | 144 if (temp == null) { |
145 _names[type] = temp = chooseTypeName(type); | 145 _names[type] = temp = chooseTypeName(type); |
146 _defs[type] = typeRep; | 146 _defs[type] = typeRep; |
147 } | 147 } |
148 return js.call('#()', [temp]); | 148 return js.call('#()', [temp]); |
149 } | 149 } |
150 } | 150 } |
151 | 151 |
152 class TypeTable { | 152 class TypeTable { |
153 /// Cache variable names for types emitted in place. | |
154 final _cacheNames = new _CacheTable(); | |
155 | |
156 /// Cache variable names for definite function types emitted in place. | |
157 final _definiteCacheNames = new _CacheTable(); | |
158 | |
159 /// Generator variable names for hoisted types. | 153 /// Generator variable names for hoisted types. |
160 final _GeneratorTable _generators; | 154 final _GeneratorTable _generators; |
161 | 155 |
162 /// Generator variable names for hoisted definite function types. | 156 /// Generator variable names for hoisted definite function types. |
163 final _GeneratorTable _definiteGenerators; | 157 final _GeneratorTable _definiteGenerators; |
164 | 158 |
165 /// Mapping from type parameters to the types which must have their | 159 /// Mapping from type parameters to the types which must have their |
166 /// cache/generator variables discharged at the binding site for the | 160 /// cache/generator variables discharged at the binding site for the |
167 /// type variable since the type definition depends on the type | 161 /// type variable since the type definition depends on the type |
168 /// parameter. | 162 /// parameter. |
169 final _scopeDependencies = <TypeParameterElement, List<DartType>>{}; | 163 final _scopeDependencies = <TypeParameterElement, List<DartType>>{}; |
170 | 164 |
171 TypeTable(JS.Identifier runtime) | 165 TypeTable(JS.Identifier runtime) |
172 : _generators = new _GeneratorTable(runtime), | 166 : _generators = new _GeneratorTable(runtime), |
173 _definiteGenerators = new _GeneratorTable(runtime); | 167 _definiteGenerators = new _GeneratorTable(runtime); |
174 | 168 |
175 /// Emit a list of statements declaring the cache variables and generator | 169 /// Emit a list of statements declaring the cache variables and generator |
176 /// definitions tracked by the table. If [formals] is present, only | 170 /// definitions tracked by the table. If [formals] is present, only |
177 /// emit the definitions which depend on the formals. | 171 /// emit the definitions which depend on the formals. |
178 List<JS.Statement> discharge([List<TypeParameterElement> formals]) { | 172 List<JS.Statement> discharge([List<TypeParameterElement> formals]) { |
179 var filter = formals?.expand((p) => _scopeDependencies[p] ?? <DartType>[]); | 173 var filter = formals?.expand((p) => _scopeDependencies[p] ?? <DartType>[]); |
180 var stmts = [ | 174 var stmts = [_generators, _definiteGenerators] |
181 _cacheNames, | 175 .expand((c) => c.discharge(filter)) |
182 _definiteCacheNames, | 176 .toList(); |
183 _generators, | |
184 _definiteGenerators | |
185 ].expand((c) => c.discharge(filter)).toList(); | |
186 formals?.forEach(_scopeDependencies.remove); | 177 formals?.forEach(_scopeDependencies.remove); |
187 return stmts; | 178 return stmts; |
188 } | 179 } |
189 | 180 |
190 /// Record the dependencies of the type on its free variables | 181 /// Record the dependencies of the type on its free variables |
191 bool recordScopeDependencies(DartType type) { | 182 bool recordScopeDependencies(DartType type) { |
192 var freeVariables = freeTypeParameters(type); | 183 var freeVariables = freeTypeParameters(type); |
193 // TODO(leafp): This is a hack to avoid trying to hoist out of | 184 // TODO(leafp): This is a hack to avoid trying to hoist out of |
194 // generic functions and generic function types. This often degrades | 185 // generic functions and generic function types. This often degrades |
195 // readability to little or no benefit. It would be good to do this | 186 // readability to little or no benefit. It would be good to do this |
(...skipping 28 matching lines...) Expand all Loading... |
224 /// initializer expression will be emitted in place. The generated code | 215 /// initializer expression will be emitted in place. The generated code |
225 /// for dart.is(x, type) in this case ends up as: | 216 /// for dart.is(x, type) in this case ends up as: |
226 /// let generator = () => (generator = dart.constFn(type))() | 217 /// let generator = () => (generator = dart.constFn(type))() |
227 /// .... | 218 /// .... |
228 /// dart.is(x, generator()) | 219 /// dart.is(x, generator()) |
229 /// | 220 /// |
230 /// The boolean parameter [definite] distinguishes between definite function | 221 /// The boolean parameter [definite] distinguishes between definite function |
231 /// types and other types (since the same DartType may have different | 222 /// types and other types (since the same DartType may have different |
232 /// representations as definite and indefinite function types). | 223 /// representations as definite and indefinite function types). |
233 JS.Expression nameType(DartType type, JS.Expression typeRep, | 224 JS.Expression nameType(DartType type, JS.Expression typeRep, |
234 {bool hoistType, bool definite: false}) { | 225 {bool definite: false}) { |
235 assert(hoistType != null); | 226 var table = definite ? _definiteGenerators : _generators; |
236 var table = hoistType | |
237 ? (definite ? _definiteGenerators : _generators) | |
238 : (definite ? _definiteCacheNames : _cacheNames); | |
239 if (!table.isNamed(type)) { | 227 if (!table.isNamed(type)) { |
240 if (recordScopeDependencies(type)) return typeRep; | 228 if (recordScopeDependencies(type)) return typeRep; |
241 } | 229 } |
242 return table.nameType(type, typeRep); | 230 return table.nameType(type, typeRep); |
243 } | 231 } |
244 } | 232 } |
OLD | NEW |