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

Side by Side Diff: pkg/kernel/lib/transformations/closure/info.dart

Issue 2561723003: Merge kernel closure conversion into the Dart SDK (Closed)
Patch Set: Remove path constraint Created 4 years 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
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
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.
4
5 library kernel.transformations.closure.info;
6
7 import '../../ast.dart'
8 show
9 Class,
10 Constructor,
11 Field,
12 FunctionDeclaration,
13 FunctionNode,
14 Member,
15 Name,
16 Procedure,
17 ProcedureKind,
18 PropertyGet,
19 ThisExpression,
20 TypeParameter,
21 TypeParameterType,
22 VariableDeclaration,
23 VariableGet,
24 VariableSet;
25
26 import '../../visitor.dart' show RecursiveVisitor;
27
28 class ClosureInfo extends RecursiveVisitor {
29 FunctionNode currentFunction;
30 final Map<VariableDeclaration, FunctionNode> function =
31 <VariableDeclaration, FunctionNode>{};
32
33 final Set<VariableDeclaration> variables = new Set<VariableDeclaration>();
34
35 final Map<FunctionNode, Set<TypeParameter>> typeVariables =
36 <FunctionNode, Set<TypeParameter>>{};
37
38 /// Map from members to synthetic variables for accessing `this` in a local
39 /// function.
40 final Map<FunctionNode, VariableDeclaration> thisAccess =
41 <FunctionNode, VariableDeclaration>{};
42
43 final Set<String> currentMemberLocalNames = new Set<String>();
44
45 final Map<FunctionNode, String> localNames = <FunctionNode, String>{};
46
47 /// Contains all names used as getter through a [PropertyGet].
48 final Set<Name> invokedGetters = new Set<Name>();
49
50 /// Contains all names of declared regular instance methods (not including
51 /// accessors and operators).
52 final Set<Name> declaredInstanceMethodNames = new Set<Name>();
53
54 Class currentClass;
55
56 Member currentMember;
57
58 FunctionNode currentMemberFunction;
59
60 bool get isOuterMostContext {
61 return currentFunction == null || currentMemberFunction == currentFunction;
62 }
63
64 /// Maps the names of all instance methods that may be torn off (aka
65 /// implicitly closurized) to `${name.name}#get`.
66 Map<Name, Name> get tearOffGetterNames {
67 Map<Name, Name> result = <Name, Name>{};
68 for (Name name in declaredInstanceMethodNames) {
69 if (invokedGetters.contains(name)) {
70 result[name] = new Name("${name.name}#get", name.library);
71 }
72 }
73 return result;
74 }
75
76 void beginMember(Member member, [FunctionNode function]) {
77 currentMemberLocalNames.clear();
78 if (function != null) {
79 localNames[function] = computeUniqueLocalName(member.name.name);
80 }
81 currentMember = member;
82 currentMemberFunction = function;
83 }
84
85 void endMember() {
86 currentMember = null;
87 currentMemberFunction = null;
88 }
89
90 visitClass(Class node) {
91 currentClass = node;
92 super.visitClass(node);
93 currentClass = null;
94 }
95
96 visitConstructor(Constructor node) {
97 beginMember(node, node.function);
98 super.visitConstructor(node);
99 endMember();
100 }
101
102 visitProcedure(Procedure node) {
103 beginMember(node, node.function);
104 if (node.isInstanceMember && node.kind == ProcedureKind.Method) {
105 // Ignore the `length` method of [File] subclasses for now, as they
106 // will force us to rename the `length` getter (kernel issue #43).
107 // TODO(ahe): remove this condition.
108 Class parent = node.parent;
109 if (node.name.name != "length" ||
110 parent.enclosingLibrary.importUri.toString() != "dart:io") {
111 declaredInstanceMethodNames.add(node.name);
112 }
113 }
114 super.visitProcedure(node);
115 endMember();
116 }
117
118 visitField(Field node) {
119 beginMember(node);
120 super.visitField(node);
121 endMember();
122 }
123
124 String computeUniqueLocalName([String name]) {
125 if (name == null || name.isEmpty) {
126 name = "function";
127 }
128 if (currentFunction == null) {
129 if (currentMember != null) {
130 name = "${currentMember.name.name}#$name";
131 }
132 if (currentClass != null) {
133 name = "${currentClass.name}#$name";
134 }
135 } else {
136 name = "${localNames[currentFunction]}#$name";
137 }
138 int count = 1;
139 String candidate = name;
140 while (currentMemberLocalNames.contains(candidate)) {
141 candidate = "$name#${count++}";
142 }
143 currentMemberLocalNames.add(candidate);
144 return candidate;
145 }
146
147 visitFunctionDeclaration(FunctionDeclaration node) {
148 assert(!localNames.containsKey(node));
149 localNames[node.function] = computeUniqueLocalName(node.variable.name);
150 return super.visitFunctionDeclaration(node);
151 }
152
153 visitFunctionNode(FunctionNode node) {
154 localNames.putIfAbsent(node, computeUniqueLocalName);
155 var saved = currentFunction;
156 currentFunction = node;
157 node.visitChildren(this);
158 currentFunction = saved;
159 Set<TypeParameter> capturedTypeVariables = typeVariables[node];
160 if (capturedTypeVariables != null && !isOuterMostContext) {
161 // Propagate captured type variables to enclosing function.
162 typeVariables
163 .putIfAbsent(currentFunction, () => new Set<TypeParameter>())
164 .addAll(capturedTypeVariables);
165 }
166 }
167
168 visitVariableDeclaration(VariableDeclaration node) {
169 function[node] = currentFunction;
170 node.visitChildren(this);
171 }
172
173 visitVariableGet(VariableGet node) {
174 if (function[node.variable] != currentFunction) {
175 variables.add(node.variable);
176 }
177 node.visitChildren(this);
178 }
179
180 visitVariableSet(VariableSet node) {
181 if (function[node.variable] != currentFunction) {
182 variables.add(node.variable);
183 }
184 node.visitChildren(this);
185 }
186
187 visitTypeParameterType(TypeParameterType node) {
188 if (!isOuterMostContext) {
189 typeVariables
190 .putIfAbsent(currentFunction, () => new Set<TypeParameter>())
191 .add(node.parameter);
192 }
193 }
194
195 visitThisExpression(ThisExpression node) {
196 if (!isOuterMostContext) {
197 thisAccess.putIfAbsent(
198 currentMemberFunction, () => new VariableDeclaration("#self"));
199 }
200 }
201
202 visitPropertyGet(PropertyGet node) {
203 invokedGetters.add(node.name);
204 super.visitPropertyGet(node);
205 }
206 }
OLDNEW
« no previous file with comments | « pkg/kernel/lib/transformations/closure/converter.dart ('k') | pkg/kernel/lib/transformations/closure/mock.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698