| 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 1928 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1959 return; | 1960 return; |
| 1960 } | 1961 } |
| 1961 ConstructorData data = _memberData[constructor.memberIndex]; | 1962 ConstructorData data = _memberData[constructor.memberIndex]; |
| 1962 if (data.constructorBody != null) { | 1963 if (data.constructorBody != null) { |
| 1963 f(data.constructorBody); | 1964 f(data.constructorBody); |
| 1964 } | 1965 } |
| 1965 }); | 1966 }); |
| 1966 } | 1967 } |
| 1967 | 1968 |
| 1968 KernelClosureClass constructClosureClass( | 1969 KernelClosureClass constructClosureClass( |
| 1969 String name, | 1970 MemberEntity member, |
| 1971 ir.FunctionNode node, |
| 1970 JLibrary enclosingLibrary, | 1972 JLibrary enclosingLibrary, |
| 1971 KernelScopeInfo info, | 1973 KernelScopeInfo info, |
| 1972 ir.Location location, | 1974 ir.Location location, |
| 1973 KernelToLocalsMap localsMap, | 1975 KernelToLocalsMap localsMap, |
| 1974 InterfaceType supertype) { | 1976 InterfaceType supertype) { |
| 1977 String name = _computeClosureName(node); |
| 1975 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( | 1978 KernelClosureClass cls = new KernelClosureClass.fromScopeInfo( |
| 1976 name, _classEnvs.length, enclosingLibrary, info, location, localsMap); | 1979 name, _classEnvs.length, enclosingLibrary, info, location, localsMap); |
| 1977 _classList.add(cls); | 1980 _classList.add(cls); |
| 1978 _classEnvs.add(new ClassEnv.closureClass()); | 1981 _classEnvs.add(new ClassEnv.closureClass()); |
| 1979 | 1982 |
| 1980 // Create a classData and set up the interfaces and subclass | 1983 // Create a classData and set up the interfaces and subclass |
| 1981 // relationships that _ensureSupertypes and _ensureThisAndRawType are doing | 1984 // relationships that _ensureSupertypes and _ensureThisAndRawType are doing |
| 1982 var closureData = | 1985 var closureData = |
| 1983 new ClassData(null, new ClosureClassDefinition(cls, cls.location)); | 1986 new ClassData(null, new ClosureClassDefinition(cls, cls.location)); |
| 1984 closureData | 1987 closureData |
| 1985 ..isMixinApplication = false | 1988 ..isMixinApplication = false |
| 1986 ..thisType = | 1989 ..thisType = |
| 1987 closureData.rawType = new InterfaceType(cls, const/*<DartType>*/ []) | 1990 closureData.rawType = new InterfaceType(cls, const/*<DartType>*/ []) |
| 1988 ..supertype = supertype | 1991 ..supertype = supertype |
| 1989 ..interfaces = const <InterfaceType>[]; | 1992 ..interfaces = const <InterfaceType>[]; |
| 1990 var setBuilder = new _KernelOrderedTypeSetBuilder(this, cls); | 1993 var setBuilder = new _KernelOrderedTypeSetBuilder(this, cls); |
| 1991 _classData.add(closureData); | 1994 _classData.add(closureData); |
| 1992 closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( | 1995 closureData.orderedTypeSet = setBuilder.createOrderedTypeSet( |
| 1993 closureData.supertype, const Link<InterfaceType>()); | 1996 closureData.supertype, const Link<InterfaceType>()); |
| 1994 | 1997 |
| 1995 int i = 0; | 1998 int i = 0; |
| 1996 for (ir.VariableDeclaration variable in info.freeVariables) { | 1999 for (ir.VariableDeclaration variable in info.freeVariables) { |
| 1997 // Make a corresponding field entity in this closure class for every | 2000 // Make a corresponding field entity in this closure class for every |
| 1998 // single freeVariable in the KernelScopeInfo.freeVariable. | 2001 // single freeVariable in the KernelScopeInfo.freeVariable. |
| 1999 _constructClosureFields(cls, variable, i, localsMap); | 2002 _constructClosureFields(cls, variable, i, localsMap); |
| 2000 i++; | 2003 i++; |
| 2001 } | 2004 } |
| 2002 | 2005 |
| 2006 cls.callMethod = new ClosureCall(_memberData.length, cls, member); |
| 2007 _memberList.add(cls.callMethod); |
| 2008 _memberData.add(new MemberData( |
| 2009 null, |
| 2010 new ClosureMemberDefinition( |
| 2011 member, cls.location, MemberKind.closureCall, node.parent))); |
| 2012 |
| 2003 // TODO(efortuna): Does getMetadata get called in ClassData for this object? | 2013 // TODO(efortuna): Does getMetadata get called in ClassData for this object? |
| 2004 return cls; | 2014 return cls; |
| 2005 } | 2015 } |
| 2006 | 2016 |
| 2007 _constructClosureFields( | 2017 _constructClosureFields( |
| 2008 KernelClosureClass cls, | 2018 KernelClosureClass cls, |
| 2009 ir.VariableDeclaration variable, | 2019 ir.VariableDeclaration variable, |
| 2010 int fieldNumber, | 2020 int fieldNumber, |
| 2011 KernelToLocalsMap localsMap) { | 2021 KernelToLocalsMap localsMap) { |
| 2012 // NOTE: This construction order may be slightly different than the | 2022 // NOTE: This construction order may be slightly different than the |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2024 variable.isFinal || variable.isConst); | 2034 variable.isFinal || variable.isConst); |
| 2025 cls.localToFieldMap[capturedLocal] = closureField; | 2035 cls.localToFieldMap[capturedLocal] = closureField; |
| 2026 _memberList.add(closureField); | 2036 _memberList.add(closureField); |
| 2027 _memberData.add(new MemberData( | 2037 _memberData.add(new MemberData( |
| 2028 null, | 2038 null, |
| 2029 new ClosureMemberDefinition(cls.localToFieldMap[capturedLocal], | 2039 new ClosureMemberDefinition(cls.localToFieldMap[capturedLocal], |
| 2030 variable.location, MemberKind.closureField, variable))); | 2040 variable.location, MemberKind.closureField, variable))); |
| 2031 } | 2041 } |
| 2032 } | 2042 } |
| 2033 | 2043 |
| 2044 // Returns a non-unique name for the given closure element. |
| 2045 String _computeClosureName(ir.TreeNode treeNode) { |
| 2046 var parts = <String>[]; |
| 2047 if (treeNode is ir.Field && treeNode.name.name != "") { |
| 2048 parts.add(treeNode.name.name); |
| 2049 } else { |
| 2050 parts.add('closure'); |
| 2051 } |
| 2052 ir.TreeNode node = treeNode.parent; |
| 2053 while (node != null && |
| 2054 (node is ir.Constructor || |
| 2055 node is ir.Class || |
| 2056 node is ir.FunctionNode || |
| 2057 node is ir.Procedure)) { |
| 2058 // TODO(johnniwinther): Simplify computed names. |
| 2059 if (node is ir.Constructor || |
| 2060 node.parent is ir.Constructor || |
| 2061 (node is ir.Procedure && node.kind == ir.ProcedureKind.Factory)) { |
| 2062 FunctionEntity entity; |
| 2063 if (node.parent is ir.Constructor) { |
| 2064 entity = getConstructorBody(node); |
| 2065 } else { |
| 2066 entity = getMember(node); |
| 2067 } |
| 2068 parts.add(utils.reconstructConstructorName(entity)); |
| 2069 } else { |
| 2070 String surroundingName = ''; |
| 2071 if (node is ir.Class) { |
| 2072 surroundingName = Elements.operatorNameToIdentifier(node.name); |
| 2073 } else if (node is ir.Procedure) { |
| 2074 surroundingName = Elements.operatorNameToIdentifier(node.name.name); |
| 2075 } |
| 2076 parts.add(surroundingName); |
| 2077 } |
| 2078 // A generative constructors's parent is the class; the class name is |
| 2079 // already part of the generative constructor's name. |
| 2080 if (node is ir.Constructor) break; |
| 2081 node = node.parent; |
| 2082 } |
| 2083 return parts.reversed.join('_'); |
| 2084 } |
| 2085 |
| 2034 /// Generate a unique name for the [id]th closure field, with proposed name | 2086 /// Generate a unique name for the [id]th closure field, with proposed name |
| 2035 /// [name]. | 2087 /// [name]. |
| 2036 /// | 2088 /// |
| 2037 /// The result is used as the name of [ClosureFieldElement]s, and must | 2089 /// The result is used as the name of [ClosureFieldElement]s, and must |
| 2038 /// therefore be unique to avoid breaking an invariant in the element model | 2090 /// therefore be unique to avoid breaking an invariant in the element model |
| 2039 /// (classes cannot declare multiple fields with the same name). | 2091 /// (classes cannot declare multiple fields with the same name). |
| 2040 /// | 2092 /// |
| 2041 /// Also, the names should be distinct from real field names to prevent | 2093 /// Also, the names should be distinct from real field names to prevent |
| 2042 /// clashes with selectors for those fields. | 2094 /// clashes with selectors for those fields. |
| 2043 /// | 2095 /// |
| 2044 /// These names are not used in generated code, just as element name. | 2096 /// These names are not used in generated code, just as element name. |
| 2045 String _getClosureVariableName(String name, int id) { | 2097 String _getClosureVariableName(String name, int id) { |
| 2046 return "_captured_${name}_$id"; | 2098 return "_captured_${name}_$id"; |
| 2047 } | 2099 } |
| 2048 | 2100 |
| 2049 String getDeferredUri(ir.LibraryDependency node) { | 2101 String getDeferredUri(ir.LibraryDependency node) { |
| 2050 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); | 2102 throw new UnimplementedError('JsKernelToElementMap.getDeferredUri'); |
| 2051 } | 2103 } |
| 2052 } | 2104 } |
| OLD | NEW |