| 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 '../common.dart'; | 9 import '../common.dart'; |
| 10 import '../common/names.dart' show Identifiers; | 10 import '../common/names.dart' show Identifiers; |
| 11 import '../common/resolution.dart'; | 11 import '../common/resolution.dart'; |
| 12 import '../compile_time_constants.dart'; | 12 import '../compile_time_constants.dart'; |
| 13 import '../constants/constant_system.dart'; | 13 import '../constants/constant_system.dart'; |
| 14 import '../constants/constructors.dart'; | 14 import '../constants/constructors.dart'; |
| 15 import '../constants/evaluation.dart'; | 15 import '../constants/evaluation.dart'; |
| 16 import '../constants/expressions.dart'; | 16 import '../constants/expressions.dart'; |
| 17 import '../constants/values.dart'; | 17 import '../constants/values.dart'; |
| 18 import '../common_elements.dart'; | 18 import '../common_elements.dart'; |
| 19 import '../elements/elements.dart'; | 19 import '../elements/elements.dart'; |
| 20 import '../elements/entities.dart'; | 20 import '../elements/entities.dart'; |
| 21 import '../elements/entity_utils.dart' as utils; |
| 21 import '../elements/names.dart'; | 22 import '../elements/names.dart'; |
| 22 import '../elements/types.dart'; | 23 import '../elements/types.dart'; |
| 23 import '../environment.dart'; | 24 import '../environment.dart'; |
| 24 import '../frontend_strategy.dart'; | 25 import '../frontend_strategy.dart'; |
| 25 import '../js_backend/backend_usage.dart'; | 26 import '../js_backend/backend_usage.dart'; |
| 26 import '../js_backend/constant_system_javascript.dart'; | 27 import '../js_backend/constant_system_javascript.dart'; |
| 27 import '../js_backend/interceptor_data.dart'; | 28 import '../js_backend/interceptor_data.dart'; |
| 28 import '../js_backend/native_data.dart'; | 29 import '../js_backend/native_data.dart'; |
| 29 import '../js_backend/no_such_method_registry.dart'; | 30 import '../js_backend/no_such_method_registry.dart'; |
| 30 import '../js_backend/runtime_types.dart'; | 31 import '../js_backend/runtime_types.dart'; |
| (...skipping 1944 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 return; | 1976 return; |
| 1976 } | 1977 } |
| 1977 ConstructorData data = _memberData[constructor.memberIndex]; | 1978 ConstructorData data = _memberData[constructor.memberIndex]; |
| 1978 if (data.constructorBody != null) { | 1979 if (data.constructorBody != null) { |
| 1979 f(data.constructorBody); | 1980 f(data.constructorBody); |
| 1980 } | 1981 } |
| 1981 }); | 1982 }); |
| 1982 } | 1983 } |
| 1983 | 1984 |
| 1984 KernelClosureClass constructClosureClass( | 1985 KernelClosureClass constructClosureClass( |
| 1985 String name, | 1986 MemberEntity member, |
| 1987 ir.FunctionNode node, |
| 1986 JLibrary enclosingLibrary, | 1988 JLibrary enclosingLibrary, |
| 1987 KernelScopeInfo info, | 1989 KernelScopeInfo info, |
| 1988 ir.Location location, | 1990 ir.Location location, |
| 1989 KernelToLocalsMap localsMap, | 1991 KernelToLocalsMap localsMap, |
| 1990 InterfaceType supertype) { | 1992 InterfaceType supertype) { |
| 1993 String name = _computeClosureName(node); |
| 1991 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( | 1994 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( |
| 1992 name, _classEnvs.length, enclosingLibrary, info, location, localsMap); | 1995 name, _classEnvs.length, enclosingLibrary, info, location, localsMap); |
| 1993 _classList.add(cls); | 1996 _classList.add(cls); |
| 1994 _classEnvs.add(new ClassEnv.closureClass()); | 1997 _classEnvs.add(new ClassEnv.closureClass()); |
| 1995 | 1998 |
| 1996 // Create a classData and set up the interfaces and subclass | 1999 // Create a classData and set up the interfaces and subclass |
| 1997 // relationships that _ensureSupertypes and _ensureThisAndRawType are doing | 2000 // relationships that _ensureSupertypes and _ensureThisAndRawType are doing |
| 1998 var closureData = | 2001 var closureData = |
| 1999 new ClassData(null, new ClosureClassDefinition(cls, cls.location)); | 2002 new ClassData(null, new ClosureClassDefinition(cls, cls.location)); |
| 2000 closureData | 2003 closureData |
| 2001 ..isMixinApplication = false | 2004 ..isMixinApplication = false |
| 2002 ..thisType = | 2005 ..thisType = |
| 2003 closureData.rawType = new InterfaceType(cls, const/*<DartType>*/ []) | 2006 closureData.rawType = new InterfaceType(cls, const/*<DartType>*/ []) |
| 2004 ..supertype = supertype | 2007 ..supertype = supertype |
| 2005 ..interfaces = const <InterfaceType>[]; | 2008 ..interfaces = const <InterfaceType>[]; |
| 2006 var setBuilder = new _KernelOrderedTypeSetBuilder(this, cls); | 2009 var setBuilder = new _KernelOrderedTypeSetBuilder(this, cls); |
| 2007 _classData.add(closureData); | 2010 _classData.add(closureData); |
| 2008 closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( | 2011 closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
| 2009 closureData.supertype, const Link<InterfaceType>()); | 2012 closureData.supertype, const Link<InterfaceType>()); |
| 2010 | 2013 |
| 2011 int i = 0; | 2014 int i = 0; |
| 2012 for (ir.VariableDeclaration variable in info.freeVariables) { | 2015 for (ir.VariableDeclaration variable in info.freeVariables) { |
| 2013 // Make a corresponding field entity in this closure class for every | 2016 // Make a corresponding field entity in this closure class for every |
| 2014 // single freeVariable in the KernelScopeInfo.freeVariable. | 2017 // single freeVariable in the KernelScopeInfo.freeVariable. |
| 2015 _constructClosureFields(cls, variable, i, localsMap); | 2018 _constructClosureFields(cls, variable, i, localsMap); |
| 2016 i++; | 2019 i++; |
| 2017 } | 2020 } |
| 2018 | 2021 |
| 2022 cls.callMethod = new JClosureCallMethod(_memberData.length, cls, member); |
| 2023 _memberList.add(cls.callMethod); |
| 2024 _memberData.add(new MemberData( |
| 2025 null, |
| 2026 new ClosureMemberDefinition( |
| 2027 member, cls.location, MemberKind.closureCall, node.parent))); |
| 2028 |
| 2019 // TODO(efortuna): Does getMetadata get called in ClassData for this object? | 2029 // TODO(efortuna): Does getMetadata get called in ClassData for this object? |
| 2020 return cls; | 2030 return cls; |
| 2021 } | 2031 } |
| 2022 | 2032 |
| 2023 _constructClosureFields( | 2033 _constructClosureFields( |
| 2024 KernelClosureClass cls, | 2034 KernelClosureClass cls, |
| 2025 ir.VariableDeclaration variable, | 2035 ir.VariableDeclaration variable, |
| 2026 int fieldNumber, | 2036 int fieldNumber, |
| 2027 KernelToLocalsMap localsMap) { | 2037 KernelToLocalsMap localsMap) { |
| 2028 // NOTE: This construction order may be slightly different than the | 2038 // NOTE: This construction order may be slightly different than the |
| 2029 // old Element version. The old version did all the boxed items and then | 2039 // old Element version. The old version did all the boxed items and then |
| 2030 // all the others. | 2040 // all the others. |
| 2031 Local capturedLocal = localsMap.getLocalVariable(variable); | 2041 Local capturedLocal = localsMap.getLocalVariable(variable); |
| 2032 if (cls.isBoxed(capturedLocal)) { | 2042 if (cls.isBoxed(capturedLocal)) { |
| 2033 // TODO(efortuna): Coming soon. | 2043 // TODO(efortuna): Coming soon. |
| 2034 } else { | 2044 } else { |
| 2035 var closureField = new ClosureField( | 2045 var closureField = new JClosureField( |
| 2036 _getClosureVariableName(capturedLocal.name, fieldNumber), | 2046 _getClosureVariableName(capturedLocal.name, fieldNumber), |
| 2037 _memberData.length, | 2047 _memberData.length, |
| 2038 cls, | 2048 cls, |
| 2039 variable.isConst, | 2049 variable.isConst, |
| 2040 variable.isFinal || variable.isConst); | 2050 variable.isFinal || variable.isConst); |
| 2041 cls.localToFieldMap[capturedLocal] = closureField; | 2051 cls.localToFieldMap[capturedLocal] = closureField; |
| 2042 _memberList.add(closureField); | 2052 _memberList.add(closureField); |
| 2043 _memberData.add(new MemberData( | 2053 _memberData.add(new MemberData( |
| 2044 null, | 2054 null, |
| 2045 new ClosureMemberDefinition(cls.localToFieldMap[capturedLocal], | 2055 new ClosureMemberDefinition(cls.localToFieldMap[capturedLocal], |
| 2046 variable.location, MemberKind.closureField, variable))); | 2056 variable.location, MemberKind.closureField, variable))); |
| 2047 } | 2057 } |
| 2048 } | 2058 } |
| 2049 | 2059 |
| 2060 // Returns a non-unique name for the given closure element. |
| 2061 String _computeClosureName(ir.TreeNode treeNode) { |
| 2062 var parts = <String>[]; |
| 2063 if (treeNode is ir.Field && treeNode.name.name != "") { |
| 2064 parts.add(treeNode.name.name); |
| 2065 } else { |
| 2066 parts.add('closure'); |
| 2067 } |
| 2068 ir.TreeNode node = treeNode.parent; |
| 2069 while (node != null && |
| 2070 (node is ir.Constructor || |
| 2071 node is ir.Class || |
| 2072 node is ir.FunctionNode || |
| 2073 node is ir.Procedure)) { |
| 2074 // TODO(johnniwinther): Simplify computed names. |
| 2075 if (node is ir.Constructor || |
| 2076 node.parent is ir.Constructor || |
| 2077 (node is ir.Procedure && node.kind == ir.ProcedureKind.Factory)) { |
| 2078 FunctionEntity entity; |
| 2079 if (node.parent is ir.Constructor) { |
| 2080 entity = getConstructorBody(node); |
| 2081 } else { |
| 2082 entity = getMember(node); |
| 2083 } |
| 2084 parts.add(utils.reconstructConstructorName(entity)); |
| 2085 } else { |
| 2086 String surroundingName = ''; |
| 2087 if (node is ir.Class) { |
| 2088 surroundingName = Elements.operatorNameToIdentifier(node.name); |
| 2089 } else if (node is ir.Procedure) { |
| 2090 surroundingName = Elements.operatorNameToIdentifier(node.name.name); |
| 2091 } |
| 2092 parts.add(surroundingName); |
| 2093 } |
| 2094 // A generative constructors's parent is the class; the class name is |
| 2095 // already part of the generative constructor's name. |
| 2096 if (node is ir.Constructor) break; |
| 2097 node = node.parent; |
| 2098 } |
| 2099 return parts.reversed.join('_'); |
| 2100 } |
| 2101 |
| 2050 /// Generate a unique name for the [id]th closure field, with proposed name | 2102 /// Generate a unique name for the [id]th closure field, with proposed name |
| 2051 /// [name]. | 2103 /// [name]. |
| 2052 /// | 2104 /// |
| 2053 /// The result is used as the name of [ClosureFieldElement]s, and must | 2105 /// The result is used as the name of [ClosureFieldElement]s, and must |
| 2054 /// therefore be unique to avoid breaking an invariant in the element model | 2106 /// therefore be unique to avoid breaking an invariant in the element model |
| 2055 /// (classes cannot declare multiple fields with the same name). | 2107 /// (classes cannot declare multiple fields with the same name). |
| 2056 /// | 2108 /// |
| 2057 /// Also, the names should be distinct from real field names to prevent | 2109 /// Also, the names should be distinct from real field names to prevent |
| 2058 /// clashes with selectors for those fields. | 2110 /// clashes with selectors for those fields. |
| 2059 /// | 2111 /// |
| 2060 /// These names are not used in generated code, just as element name. | 2112 /// These names are not used in generated code, just as element name. |
| 2061 String _getClosureVariableName(String name, int id) { | 2113 String _getClosureVariableName(String name, int id) { |
| 2062 return "_captured_${name}_$id"; | 2114 return "_captured_${name}_$id"; |
| 2063 } | 2115 } |
| 2064 | 2116 |
| 2065 String getDeferredUri(ir.LibraryDependency node) { | 2117 String getDeferredUri(ir.LibraryDependency node) { |
| 2066 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); | 2118 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); |
| 2067 } | 2119 } |
| 2068 } | 2120 } |
| OLD | NEW |