Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(419)

Side by Side Diff: pkg/compiler/lib/src/js_model/closure.dart

Issue 2984643002: Add Class/MemberDefinition to handle synthesized classes/members (Closed)
Patch Set: Updated cf. comment Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | pkg/compiler/lib/src/kernel/element_map.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 import 'package:kernel/ast.dart' as ir; 5 import 'package:kernel/ast.dart' as ir;
6 6
7 import '../closure.dart'; 7 import '../closure.dart';
8 import '../common.dart';
8 import '../common/tasks.dart'; 9 import '../common/tasks.dart';
9 import '../elements/entities.dart'; 10 import '../elements/entities.dart';
10 import '../kernel/element_map.dart'; 11 import '../kernel/element_map.dart';
11 import '../world.dart'; 12 import '../world.dart';
12 import 'elements.dart'; 13 import 'elements.dart';
13 import 'closure_visitors.dart'; 14 import 'closure_visitors.dart';
14 import 'locals.dart'; 15 import 'locals.dart';
15 16
16 /// Closure conversion code using our new Entity model. Closure conversion is 17 /// Closure conversion code using our new Entity model. Closure conversion is
17 /// necessary because the semantics of closures are slightly different in Dart 18 /// necessary because the semantics of closures are slightly different in Dart
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 void convertClosures(Iterable<MemberEntity> processedEntities, 60 void convertClosures(Iterable<MemberEntity> processedEntities,
60 ClosedWorldRefiner closedWorldRefiner) { 61 ClosedWorldRefiner closedWorldRefiner) {
61 var closuresToGenerate = <ir.TreeNode, ScopeInfo>{}; 62 var closuresToGenerate = <ir.TreeNode, ScopeInfo>{};
62 processedEntities.forEach((MemberEntity kEntity) { 63 processedEntities.forEach((MemberEntity kEntity) {
63 MemberEntity entity = kEntity; 64 MemberEntity entity = kEntity;
64 if (_kToJElementMap != null) { 65 if (_kToJElementMap != null) {
65 entity = _kToJElementMap.toBackendMember(kEntity); 66 entity = _kToJElementMap.toBackendMember(kEntity);
66 } 67 }
67 if (entity.isAbstract) return; 68 if (entity.isAbstract) return;
68 if (entity.isField && !entity.isInstanceMember) { 69 if (entity.isField && !entity.isInstanceMember) {
69 ir.Field field = _elementMap.getMemberNode(entity); 70 MemberDefinition definition = _elementMap.getMemberDefinition(entity);
71 assert(definition.kind == MemberKind.regular,
72 failedAt(entity, "Unexpected member definition $definition"));
73 ir.Field field = definition.node;
70 // Skip top-level/static fields without an initializer. 74 // Skip top-level/static fields without an initializer.
71 if (field.initializer == null) return; 75 if (field.initializer == null) return;
72 } 76 }
73 _buildClosureModel(entity, closuresToGenerate, closedWorldRefiner); 77 _buildClosureModel(entity, closuresToGenerate, closedWorldRefiner);
74 }); 78 });
75 79
76 for (ir.TreeNode node in closuresToGenerate.keys) { 80 for (ir.TreeNode node in closuresToGenerate.keys) {
77 _produceSyntheticElements( 81 _produceSyntheticElements(
78 node, closuresToGenerate[node], closedWorldRefiner); 82 node, closuresToGenerate[node], closedWorldRefiner);
79 } 83 }
80 } 84 }
81 85
82 /// Inspect members and mark if those members capture any state that needs to 86 /// Inspect members and mark if those members capture any state that needs to
83 /// be marked as free variables. 87 /// be marked as free variables.
84 void _buildClosureModel( 88 void _buildClosureModel(
85 MemberEntity entity, 89 MemberEntity entity,
86 Map<ir.TreeNode, ScopeInfo> closuresToGenerate, 90 Map<ir.TreeNode, ScopeInfo> closuresToGenerate,
87 ClosedWorldRefiner closedWorldRefiner) { 91 ClosedWorldRefiner closedWorldRefiner) {
88 if (_scopeMap.keys.contains(entity)) return; 92 if (_scopeMap.keys.contains(entity)) return;
89 ir.Node node = _elementMap.getMemberNode(entity); 93 MemberDefinition definition = _elementMap.getMemberDefinition(entity);
94 switch (definition.kind) {
95 case MemberKind.regular:
96 case MemberKind.constructor:
97 break;
98 default:
99 failedAt(entity, "Unexpected member definition $definition");
100 }
101 ir.Node node = definition.node;
90 if (_scopesCapturedInClosureMap.keys.contains(node)) return; 102 if (_scopesCapturedInClosureMap.keys.contains(node)) return;
91 CapturedScopeBuilder translator = new CapturedScopeBuilder( 103 CapturedScopeBuilder translator = new CapturedScopeBuilder(
92 _scopesCapturedInClosureMap, 104 _scopesCapturedInClosureMap,
93 _scopeMap, 105 _scopeMap,
94 entity, 106 entity,
95 closuresToGenerate, 107 closuresToGenerate,
96 _globalLocalsMap.getLocalsMap(entity), 108 _globalLocalsMap.getLocalsMap(entity),
97 _elementMap); 109 _elementMap);
98 if (entity.isField) { 110 if (entity.isField) {
99 if (node is ir.Field && node.initializer != null) { 111 if (node is ir.Field && node.initializer != null) {
100 translator.translateLazyInitializer(node); 112 translator.translateLazyInitializer(node);
101 } 113 }
102 } else { 114 } else {
103 assert(node is ir.Procedure || node is ir.Constructor); 115 assert(node is ir.Procedure || node is ir.Constructor);
104 translator.translateConstructorOrProcedure(node); 116 translator.translateConstructorOrProcedure(node);
105 } 117 }
106 } 118 }
107 119
108 /// Given what variables are captured at each point, construct closure classes 120 /// Given what variables are captured at each point, construct closure classes
109 /// with fields containing the captured variables to replicate the Dart 121 /// with fields containing the captured variables to replicate the Dart
110 /// closure semantics in JS. 122 /// closure semantics in JS.
111 void _produceSyntheticElements( 123 void _produceSyntheticElements(
112 ir.TreeNode /* ir.Field | ir.FunctionNode */ node, 124 ir.TreeNode /* ir.Field | ir.FunctionNode */ node,
113 ScopeInfo info, 125 ScopeInfo info,
114 ClosedWorldRefiner closedWorldRefiner) { 126 ClosedWorldRefiner closedWorldRefiner) {
115 Entity entity; 127 Entity entity;
116 KernelClosureClass closureClass = 128 KernelClosureClass closureClass =
117 new KernelClosureClass.fromScopeInfo(info); 129 new KernelClosureClass.fromScopeInfo(info, node.location);
118 if (node is ir.FunctionNode) { 130 if (node is ir.FunctionNode) {
119 // We want the original declaration where that function is used to point 131 // We want the original declaration where that function is used to point
120 // to the correct closure class. 132 // to the correct closure class.
121 // TODO(efortuna): entity equivalent of element.declaration? 133 // TODO(efortuna): entity equivalent of element.declaration?
122 node = (node as ir.FunctionNode).parent; 134 node = (node as ir.FunctionNode).parent;
123 _closureRepresentationMap[closureClass.callMethod] = closureClass; 135 _closureRepresentationMap[closureClass.callMethod] = closureClass;
124 } 136 }
125 137
126 if (node is ir.Member) { 138 if (node is ir.Member) {
127 entity = _elementMap.getMember(node); 139 entity = _elementMap.getMember(node);
(...skipping 18 matching lines...) Expand all
146 ConstructorBodyEntity constructorBody = entity; 158 ConstructorBodyEntity constructorBody = entity;
147 entity = constructorBody.constructor; 159 entity = constructorBody.constructor;
148 } 160 }
149 161
150 return _scopeMap[entity] ?? getClosureRepresentationInfo(entity); 162 return _scopeMap[entity] ?? getClosureRepresentationInfo(entity);
151 } 163 }
152 164
153 // TODO(efortuna): Eventually scopesCapturedInClosureMap[node] should always 165 // TODO(efortuna): Eventually scopesCapturedInClosureMap[node] should always
154 // be non-null, and we should just test that with an assert. 166 // be non-null, and we should just test that with an assert.
155 @override 167 @override
156 CapturedScope getCapturedScope(MemberEntity entity) => 168 CapturedScope getCapturedScope(MemberEntity entity) {
157 _scopesCapturedInClosureMap[_elementMap.getMemberNode(entity)] ?? 169 MemberDefinition definition = _elementMap.getMemberDefinition(entity);
158 const CapturedScope(); 170 switch (definition.kind) {
171 case MemberKind.regular:
172 case MemberKind.constructor:
173 case MemberKind.constructorBody:
174 return _scopesCapturedInClosureMap[definition.node] ??
175 const CapturedScope();
176 default:
177 throw failedAt(entity, "Unexpected member definition $definition");
178 }
179 }
159 180
160 @override 181 @override
161 // TODO(efortuna): Eventually scopesCapturedInClosureMap[node] should always 182 // TODO(efortuna): Eventually scopesCapturedInClosureMap[node] should always
162 // be non-null, and we should just test that with an assert. 183 // be non-null, and we should just test that with an assert.
163 CapturedLoopScope getCapturedLoopScope(ir.Node loopNode) => 184 CapturedLoopScope getCapturedLoopScope(ir.Node loopNode) =>
164 _scopesCapturedInClosureMap[loopNode] ?? const CapturedLoopScope(); 185 _scopesCapturedInClosureMap[loopNode] ?? const CapturedLoopScope();
165 186
166 @override 187 @override
167 // TODO(efortuna): Eventually closureRepresentationMap[node] should always be 188 // TODO(efortuna): Eventually closureRepresentationMap[node] should always be
168 // non-null, and we should just test that with an assert. 189 // non-null, and we should just test that with an assert.
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 KernelCapturedLoopScope(Set<Local> boxedVariables, this.boxedLoopVariables, 249 KernelCapturedLoopScope(Set<Local> boxedVariables, this.boxedLoopVariables,
229 Local context, Local thisLocal) 250 Local context, Local thisLocal)
230 : super(boxedVariables, context, thisLocal); 251 : super(boxedVariables, context, thisLocal);
231 252
232 bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty; 253 bool get hasBoxedLoopVariables => boxedLoopVariables.isNotEmpty;
233 } 254 }
234 255
235 // TODO(johnniwinther): Add unittest for the computed [ClosureClass]. 256 // TODO(johnniwinther): Add unittest for the computed [ClosureClass].
236 class KernelClosureClass extends KernelScopeInfo 257 class KernelClosureClass extends KernelScopeInfo
237 implements ClosureRepresentationInfo, JClass { 258 implements ClosureRepresentationInfo, JClass {
259 final ir.Location location;
260
238 // TODO(efortuna): Generate unique name for each closure class. 261 // TODO(efortuna): Generate unique name for each closure class.
239 final String name = 'ClosureClass'; 262 final String name = 'ClosureClass';
240 263
241 /// Index into the classData, classList and classEnvironment lists where this 264 /// Index into the classData, classList and classEnvironment lists where this
242 /// entity is stored in [JsToFrontendMapImpl]. 265 /// entity is stored in [JsToFrontendMapImpl].
243 int classIndex; 266 int classIndex;
244 267
245 final Map<Local, JField> localToFieldMap = new Map<Local, JField>(); 268 final Map<Local, JField> localToFieldMap = new Map<Local, JField>();
246 269
247 KernelClosureClass.fromScopeInfo(KernelScopeInfo info) 270 KernelClosureClass.fromScopeInfo(KernelScopeInfo info, this.location)
248 : super.from(info.thisLocal, info); 271 : super.from(info.thisLocal, info);
249 272
250 // TODO(efortuna): Implement. 273 // TODO(efortuna): Implement.
251 Local get closureEntity => null; 274 Local get closureEntity => null;
252 275
253 ClassEntity get closureClassEntity => this; 276 ClassEntity get closureClassEntity => this;
254 277
255 // TODO(efortuna): Implement. 278 // TODO(efortuna): Implement.
256 FunctionEntity get callMethod => null; 279 FunctionEntity get callMethod => null;
257 280
(...skipping 23 matching lines...) Expand all
281 // that (and the subsequent adjustment here) will follow soon. 304 // that (and the subsequent adjustment here) will follow soon.
282 bool get isClosure => false; 305 bool get isClosure => false;
283 306
284 bool get isAbstract => false; 307 bool get isAbstract => false;
285 308
286 // TODO(efortuna): Talk to Johnni. 309 // TODO(efortuna): Talk to Johnni.
287 JLibrary get library => null; 310 JLibrary get library => null;
288 311
289 String toString() => '${jsElementPrefix}class($name)'; 312 String toString() => '${jsElementPrefix}class($name)';
290 } 313 }
314
315 class ClosureClassDefinition implements ClassDefinition {
316 final ClassEntity cls;
317 final ir.Location location;
318
319 ClosureClassDefinition(this.cls, this.location);
320
321 ClassKind get kind => ClassKind.closure;
322
323 ir.Node get node =>
324 throw new UnsupportedError('ClosureClassDefinition.node for $cls');
325
326 String toString() =>
327 'ClosureClassDefinition(kind:$kind,cls:$cls,location:$location)';
328 }
OLDNEW
« no previous file with comments | « no previous file | pkg/compiler/lib/src/kernel/element_map.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698