OLD | NEW |
1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 library dart2js.kernel.element_map; | 5 library dart2js.kernel.element_map; |
6 | 6 |
7 import 'package:kernel/ast.dart' as ir; | 7 import 'package:kernel/ast.dart' as ir; |
8 | 8 |
9 import '../closure.dart' show BoxLocal; | 9 import '../closure.dart' show BoxLocal; |
10 import '../common.dart'; | 10 import '../common.dart'; |
(...skipping 1941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 // creating elements for IR nodes should therefore not be needed. | 1952 // creating elements for IR nodes should therefore not be needed. |
1953 // Currently some are created purely for testing (like | 1953 // Currently some are created purely for testing (like |
1954 // `element == commonElements.foo`, where 'foo' might not be live). | 1954 // `element == commonElements.foo`, where 'foo' might not be live). |
1955 // Others are created because we do a | 1955 // Others are created because we do a |
1956 // `elementEnvironment.forEachLibraryMember(...)` call on each emitted | 1956 // `elementEnvironment.forEachLibraryMember(...)` call on each emitted |
1957 // library. | 1957 // library. |
1958 ElementCreatorMixin | 1958 ElementCreatorMixin |
1959 implements | 1959 implements |
1960 KernelToWorldBuilder { | 1960 KernelToWorldBuilder { |
1961 NativeBasicData nativeBasicData; | 1961 NativeBasicData nativeBasicData; |
| 1962 int fieldNumber = 0; |
1962 | 1963 |
1963 JsKernelToElementMap(DiagnosticReporter reporter, Environment environment, | 1964 JsKernelToElementMap(DiagnosticReporter reporter, Environment environment, |
1964 KernelToElementMapForImpactImpl _elementMap) | 1965 KernelToElementMapForImpactImpl _elementMap) |
1965 : super(reporter, environment) { | 1966 : super(reporter, environment) { |
1966 _env = _elementMap._env; | 1967 _env = _elementMap._env; |
1967 for (int libraryIndex = 0; | 1968 for (int libraryIndex = 0; |
1968 libraryIndex < _elementMap._libraryEnvs.length; | 1969 libraryIndex < _elementMap._libraryEnvs.length; |
1969 libraryIndex++) { | 1970 libraryIndex++) { |
1970 LibraryEnv env = _elementMap._libraryEnvs[libraryIndex]; | 1971 LibraryEnv env = _elementMap._libraryEnvs[libraryIndex]; |
1971 LibraryData data = _elementMap._libraryData[libraryIndex]; | 1972 LibraryData data = _elementMap._libraryData[libraryIndex]; |
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2149 FunctionData data = _memberData[function.memberIndex]; | 2150 FunctionData data = _memberData[function.memberIndex]; |
2150 data.forEachParameter(this, f); | 2151 data.forEachParameter(this, f); |
2151 } | 2152 } |
2152 | 2153 |
2153 void _forEachConstructorBody( | 2154 void _forEachConstructorBody( |
2154 IndexedClass cls, void f(ConstructorBodyEntity member)) { | 2155 IndexedClass cls, void f(ConstructorBodyEntity member)) { |
2155 ClassEnv env = _classEnvs[cls.classIndex]; | 2156 ClassEnv env = _classEnvs[cls.classIndex]; |
2156 env.forEachConstructorBody(f); | 2157 env.forEachConstructorBody(f); |
2157 } | 2158 } |
2158 | 2159 |
| 2160 JRecord _constructBoxedField( |
| 2161 ir.VariableDeclaration variable, |
| 2162 BoxLocal boxLocal, |
| 2163 JClass container, |
| 2164 Map<String, MemberEntity> memberMap, |
| 2165 KernelToLocalsMap localsMap) { |
| 2166 Local local = localsMap.getLocalVariable(variable); |
| 2167 var boxedField = new JRecord( |
| 2168 _getClosureVariableName(local.name, fieldNumber), |
| 2169 _memberData.length, |
| 2170 boxLocal, |
| 2171 container, |
| 2172 variable.isConst, |
| 2173 variable.isFinal || variable.isConst); |
| 2174 _memberList.add(boxedField); |
| 2175 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
| 2176 boxedField, |
| 2177 computeSourceSpanFromTreeNode(variable), |
| 2178 MemberKind.closureField, |
| 2179 variable))); |
| 2180 memberMap[boxedField.name] = boxedField; |
| 2181 |
| 2182 //JsScopeInfo scopeInfo = getScopeInfo(local.memberContext); |
| 2183 //scopeInfo.boxedVariables[local] = boxedField; |
| 2184 return boxedField; |
| 2185 } |
| 2186 |
| 2187 /// Make a container controlling access to records, that is, variables that |
| 2188 /// are accessed in different scopes. This function creates the container as |
| 2189 /// and returns a map of locals to the corresponding records created. |
| 2190 Map<Local, JRecord> makeRecordContainer( |
| 2191 KernelScopeInfo info, MemberEntity member, KernelToLocalsMap localsMap) { |
| 2192 Map<Local, JRecord> boxedFields = {}; |
| 2193 fieldNumber = 0; |
| 2194 if (info.boxedVariables.isNotEmpty) { |
| 2195 Map<Local, JRecord> boxedVariables = new Map<Local, JRecord>(); |
| 2196 NodeBox box = info.capturedVariablesAccessor; |
| 2197 BoxLocal boxLocal = new BoxLocal( |
| 2198 box.name, getMember(box.executableContext.parent), member); |
| 2199 |
| 2200 /// |
| 2201 var container = |
| 2202 new JRecordContainer(member.library, _classEnvs.length, box.name); |
| 2203 _classList.add(container); |
| 2204 Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; |
| 2205 _classEnvs.add(new RecordContainerEnv(memberMap)); |
| 2206 |
| 2207 var containerData = new ClassData( |
| 2208 null, |
| 2209 new ClosureClassDefinition(container, |
| 2210 computeSourceSpanFromTreeNode(getMemberDefinition(member).node))); |
| 2211 containerData |
| 2212 ..isMixinApplication = false |
| 2213 ..thisType = new InterfaceType(container, const <DartType>[]) |
| 2214 ..supertype = commonElements.objectType |
| 2215 ..interfaces = const <InterfaceType>[]; |
| 2216 var setBuilder = new _KernelOrderedTypeSetBuilder(this, container); |
| 2217 _classData.add(containerData); |
| 2218 containerData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
| 2219 containerData.supertype, const Link<InterfaceType>()); |
| 2220 |
| 2221 /// |
| 2222 |
| 2223 for (ir.VariableDeclaration variable in info.boxedVariables) { |
| 2224 boxedFields[localsMap.getLocalVariable(variable)] = |
| 2225 _constructBoxedField( |
| 2226 variable, boxLocal, container, memberMap, localsMap); |
| 2227 fieldNumber++; |
| 2228 } |
| 2229 } |
| 2230 return boxedFields; |
| 2231 } |
| 2232 |
| 2233 Map<Local, JRecord> _makeBoxAndFields( |
| 2234 KernelScopeInfo info, |
| 2235 MemberEntity member, |
| 2236 JClass classEntity, |
| 2237 Map<String, MemberEntity> memberMap, |
| 2238 KernelToLocalsMap localsMap) { |
| 2239 Map<Local, JRecord> boxedFields = {}; |
| 2240 fieldNumber = 0; |
| 2241 if (info.boxedVariables.isNotEmpty) { |
| 2242 Map<Local, JRecord> boxedVariables = new Map<Local, JRecord>(); |
| 2243 NodeBox box = info.capturedVariablesAccessor; |
| 2244 BoxLocal boxLocal = new BoxLocal( |
| 2245 box.name, localsMap.getLocalVariable(box.executableContext), member); |
| 2246 |
| 2247 for (ir.VariableDeclaration variable in info.boxedVariables) { |
| 2248 Local local = localsMap.getLocalVariable(variable); |
| 2249 boxedFields[local] = _constructBoxedField( |
| 2250 variable, boxLocal, classEntity, memberMap, localsMap); |
| 2251 fieldNumber++; |
| 2252 } |
| 2253 } |
| 2254 return boxedFields; |
| 2255 } |
| 2256 |
2159 KernelClosureClass constructClosureClass( | 2257 KernelClosureClass constructClosureClass( |
2160 MemberEntity member, | 2258 MemberEntity member, |
2161 ir.FunctionNode node, | 2259 ir.FunctionNode node, |
2162 JLibrary enclosingLibrary, | 2260 JLibrary enclosingLibrary, |
| 2261 Set<JsCapturedScope> capturedScopes, |
2163 KernelScopeInfo info, | 2262 KernelScopeInfo info, |
2164 ir.Location location, | 2263 ir.Location location, |
2165 KernelToLocalsMap localsMap, | 2264 KernelToLocalsMap localsMap, |
2166 InterfaceType supertype) { | 2265 InterfaceType supertype) { |
2167 String name = _computeClosureName(node); | 2266 String name = _computeClosureName(node); |
2168 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( | 2267 JClass clsEntity = |
2169 node, name, _classEnvs.length, enclosingLibrary, info, localsMap); | 2268 new JClosureClass(localsMap, enclosingLibrary, _classEnvs.length, name); |
2170 _classList.add(cls); | 2269 _classList.add(clsEntity); |
2171 Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; | 2270 Map<String, MemberEntity> memberMap = <String, MemberEntity>{}; |
2172 _classEnvs.add(new ClosureClassEnv(memberMap)); | 2271 _classEnvs.add(new ClosureClassEnv(memberMap)); |
2173 | 2272 |
2174 // Create a classData and set up the interfaces and subclass | 2273 // Create a classData and set up the interfaces and subclass |
2175 // relationships that _ensureSupertypes and _ensureThisAndRawType are doing | 2274 // relationships that _ensureSupertypes and _ensureThisAndRawType are doing |
2176 var closureData = new ClassData(null, | 2275 var closureData = new ClassData( |
2177 new ClosureClassDefinition(cls, computeSourceSpanFromTreeNode(node))); | 2276 null, |
| 2277 new ClosureClassDefinition( |
| 2278 clsEntity, computeSourceSpanFromTreeNode(node))); |
2178 closureData | 2279 closureData |
2179 ..isMixinApplication = false | 2280 ..isMixinApplication = false |
2180 ..thisType = | 2281 ..thisType = |
2181 closureData.rawType = new InterfaceType(cls, const <DartType>[]) | 2282 closureData.rawType = new InterfaceType(clsEntity, const <DartType>[]) |
2182 ..supertype = supertype | 2283 ..supertype = supertype |
2183 ..interfaces = const <InterfaceType>[]; | 2284 ..interfaces = const <InterfaceType>[]; |
2184 var setBuilder = new _KernelOrderedTypeSetBuilder(this, cls); | 2285 var setBuilder = new _KernelOrderedTypeSetBuilder(this, clsEntity); |
2185 _classData.add(closureData); | 2286 _classData.add(closureData); |
2186 closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( | 2287 closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
2187 closureData.supertype, const Link<InterfaceType>()); | 2288 closureData.supertype, const Link<InterfaceType>()); |
2188 | 2289 |
2189 int i = 0; | 2290 var boxedFields = |
| 2291 _makeBoxAndFields(info, member, clsEntity, memberMap, localsMap); |
| 2292 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( |
| 2293 clsEntity, node, boxedFields, capturedScopes, info, localsMap); |
| 2294 |
2190 for (ir.VariableDeclaration variable in info.freeVariables) { | 2295 for (ir.VariableDeclaration variable in info.freeVariables) { |
2191 // Make a corresponding field entity in this closure class for every | 2296 // Make a corresponding field entity in this closure class for every |
2192 // single freeVariable in the KernelScopeInfo.freeVariable. | 2297 // single freeVariable in the KernelScopeInfo.freeVariable. |
2193 _constructClosureFields(member, cls, memberMap, variable, i, | 2298 _constructClosureField(member, cls, memberMap, variable, |
2194 info.capturedVariablesAccessor, localsMap); | 2299 info.capturedVariablesAccessor, localsMap); |
2195 i++; | 2300 fieldNumber++; |
2196 } | 2301 } |
2197 | 2302 |
2198 FunctionEntity callMethod = cls.callMethod = new JClosureCallMethod( | 2303 FunctionEntity callMethod = cls.callMethod = new JClosureCallMethod( |
2199 _memberData.length, | 2304 _memberData.length, |
2200 cls, | 2305 cls, |
2201 _getParameterStructure(node), | 2306 _getParameterStructure(node), |
2202 _getAsyncMarker(node)); | 2307 _getAsyncMarker(node)); |
2203 _memberList.add(cls.callMethod); | 2308 _memberList.add(cls.callMethod); |
2204 | 2309 |
2205 _memberData.add(new ClosureFunctionData( | 2310 _memberData.add(new ClosureFunctionData( |
2206 new ClosureMemberDefinition(callMethod, closureData.definition.location, | 2311 new ClosureMemberDefinition(callMethod, closureData.definition.location, |
2207 MemberKind.closureCall, node.parent), | 2312 MemberKind.closureCall, node.parent), |
2208 getFunctionType(node), | 2313 getFunctionType(node), |
2209 node)); | 2314 node)); |
2210 memberMap[cls.callMethod.name] = cls.callMethod; | 2315 memberMap[cls.callMethod.name] = cls.callMethod; |
2211 return cls; | 2316 return cls; |
2212 } | 2317 } |
2213 | 2318 |
2214 _constructClosureFields( | 2319 _constructClosureField( |
2215 MemberEntity member, | 2320 MemberEntity member, |
2216 KernelClosureClass cls, | 2321 KernelClosureClass cls, |
2217 Map<String, MemberEntity> memberMap, | 2322 Map<String, MemberEntity> memberMap, |
2218 ir.VariableDeclaration variable, | 2323 ir.VariableDeclaration variable, |
2219 int fieldNumber, | |
2220 NodeBox box, | 2324 NodeBox box, |
2221 KernelToLocalsMap localsMap) { | 2325 KernelToLocalsMap localsMap) { |
2222 // NOTE: This construction order may be slightly different than the | |
2223 // old Element version. The old version did all the boxed items and then | |
2224 // all the others. | |
2225 Local capturedLocal = localsMap.getLocalVariable(variable); | 2326 Local capturedLocal = localsMap.getLocalVariable(variable); |
2226 if (cls.isBoxed(capturedLocal)) { | 2327 if (!cls.isBoxed(capturedLocal)) { |
2227 FieldEntity boxedField = new JBoxedField( | 2328 print('WWWWWWWWWWWWWW $capturedLocal aaaand ${cls.boxedVariables}'); |
2228 _getClosureVariableName(capturedLocal.name, fieldNumber), | |
2229 _memberData.length, | |
2230 new BoxLocal(box.name, | |
2231 localsMap.getLocalVariable(box.executableContext), member), | |
2232 cls, | |
2233 variable.isConst, | |
2234 variable.isFinal || variable.isConst); | |
2235 cls.localToFieldMap[capturedLocal] = boxedField; | |
2236 _memberList.add(boxedField); | |
2237 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( | |
2238 boxedField, | |
2239 computeSourceSpanFromTreeNode(variable), | |
2240 MemberKind.closureField, | |
2241 variable))); | |
2242 memberMap[boxedField.name] = boxedField; | |
2243 } else { | |
2244 FieldEntity closureField = new JClosureField( | 2329 FieldEntity closureField = new JClosureField( |
2245 _getClosureVariableName(capturedLocal.name, fieldNumber), | 2330 _getClosureVariableName(capturedLocal.name, fieldNumber), |
2246 _memberData.length, | 2331 _memberData.length, |
2247 cls, | 2332 cls, |
2248 variable.isConst, | 2333 variable.isConst, |
2249 variable.isFinal || variable.isConst); | 2334 variable.isFinal || variable.isConst); |
2250 cls.localToFieldMap[capturedLocal] = closureField; | 2335 cls.localToFieldMap[capturedLocal] = closureField; |
2251 _memberList.add(closureField); | 2336 _memberList.add(closureField); |
2252 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( | 2337 _memberData.add(new ClosureFieldData(new ClosureMemberDefinition( |
2253 cls.localToFieldMap[capturedLocal], | 2338 cls.localToFieldMap[capturedLocal], |
2254 computeSourceSpanFromTreeNode(variable), | 2339 computeSourceSpanFromTreeNode(variable), |
2255 MemberKind.closureField, | 2340 MemberKind.closureField, |
2256 variable))); | 2341 variable))); |
2257 memberMap[closureField.name] = closureField; | 2342 memberMap[closureField.name] = closureField; |
| 2343 } else { |
| 2344 // The box field should already be constructed from looping through the |
| 2345 // boxed fields separately. |
| 2346 cls.localToFieldMap[capturedLocal] = cls.boxedVariables[capturedLocal]; |
| 2347 //assert(cls.localToFieldMap[capturedLocal] != null); |
2258 } | 2348 } |
2259 } | 2349 } |
2260 | 2350 |
2261 // Returns a non-unique name for the given closure element. | 2351 // Returns a non-unique name for the given closure element. |
2262 String _computeClosureName(ir.TreeNode treeNode) { | 2352 String _computeClosureName(ir.TreeNode treeNode) { |
2263 var parts = <String>[]; | 2353 var parts = <String>[]; |
2264 if (treeNode is ir.Field && treeNode.name.name != "") { | 2354 if (treeNode is ir.Field && treeNode.name.name != "") { |
2265 parts.add(treeNode.name.name); | 2355 parts.add(treeNode.name.name); |
2266 } else { | 2356 } else { |
2267 parts.add('closure'); | 2357 parts.add('closure'); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2306 /// | 2396 /// |
2307 /// These names are not used in generated code, just as element name. | 2397 /// These names are not used in generated code, just as element name. |
2308 String _getClosureVariableName(String name, int id) { | 2398 String _getClosureVariableName(String name, int id) { |
2309 return "_captured_${name}_$id"; | 2399 return "_captured_${name}_$id"; |
2310 } | 2400 } |
2311 | 2401 |
2312 String getDeferredUri(ir.LibraryDependency node) { | 2402 String getDeferredUri(ir.LibraryDependency node) { |
2313 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); | 2403 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); |
2314 } | 2404 } |
2315 } | 2405 } |
OLD | NEW |