OLD | NEW |
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 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 | 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 fasta.kernel_procedure_builder; | 5 library fasta.kernel_procedure_builder; |
6 | 6 |
7 import 'package:kernel/ast.dart' show | 7 import 'package:kernel/ast.dart' |
8 Arguments, | 8 show |
9 AsyncMarker, | 9 Arguments, |
10 Constructor, | 10 AsyncMarker, |
11 ConstructorInvocation, | 11 Constructor, |
12 DartType, | 12 ConstructorInvocation, |
13 DynamicType, | 13 DartType, |
14 EmptyStatement, | 14 DynamicType, |
15 Expression, | 15 EmptyStatement, |
16 FunctionNode, | 16 Expression, |
17 Initializer, | 17 FunctionNode, |
18 Library, | 18 Initializer, |
19 LocalInitializer, | 19 Library, |
20 Member, | 20 LocalInitializer, |
21 Name, | 21 Member, |
22 NamedExpression, | 22 Name, |
23 Procedure, | 23 NamedExpression, |
24 ProcedureKind, | 24 Procedure, |
25 RedirectingInitializer, | 25 ProcedureKind, |
26 Statement, | 26 RedirectingInitializer, |
27 StaticInvocation, | 27 Statement, |
28 StringLiteral, | 28 StaticInvocation, |
29 SuperInitializer, | 29 StringLiteral, |
30 TypeParameter, | 30 SuperInitializer, |
31 VariableDeclaration, | 31 TypeParameter, |
32 VariableGet, | 32 VariableDeclaration, |
33 VoidType, | 33 VariableGet, |
34 setParents; | 34 VoidType, |
| 35 setParents; |
35 | 36 |
36 import 'package:kernel/type_algebra.dart' show | 37 import 'package:kernel/type_algebra.dart' show containsTypeVariable, substitute; |
37 containsTypeVariable, | |
38 substitute; | |
39 | 38 |
40 import '../errors.dart' show | 39 import '../errors.dart' show internalError; |
41 internalError; | |
42 | 40 |
43 import '../messages.dart' show | 41 import '../messages.dart' show warning; |
44 warning; | |
45 | 42 |
46 import '../loader.dart' show | 43 import '../loader.dart' show Loader; |
47 Loader; | |
48 | 44 |
49 import 'kernel_builder.dart' show | 45 import 'kernel_builder.dart' |
50 Builder, | 46 show |
51 ClassBuilder, | 47 Builder, |
52 ConstructorReferenceBuilder, | 48 ClassBuilder, |
53 FormalParameterBuilder, | 49 ConstructorReferenceBuilder, |
54 KernelFormalParameterBuilder, | 50 FormalParameterBuilder, |
55 KernelLibraryBuilder, | 51 KernelFormalParameterBuilder, |
56 KernelTypeBuilder, | 52 KernelLibraryBuilder, |
57 KernelTypeVariableBuilder, | 53 KernelTypeBuilder, |
58 MetadataBuilder, | 54 KernelTypeVariableBuilder, |
59 ProcedureBuilder, | 55 MetadataBuilder, |
60 TypeVariableBuilder, | 56 ProcedureBuilder, |
61 memberError; | 57 TypeVariableBuilder, |
| 58 memberError; |
62 | 59 |
63 abstract class KernelFunctionBuilder | 60 abstract class KernelFunctionBuilder |
64 extends ProcedureBuilder<KernelTypeBuilder> { | 61 extends ProcedureBuilder<KernelTypeBuilder> { |
65 final String nativeMethodName; | 62 final String nativeMethodName; |
66 | 63 |
67 FunctionNode function; | 64 FunctionNode function; |
68 | 65 |
69 Statement actualBody; | 66 Statement actualBody; |
70 | 67 |
71 KernelFunctionBuilder(List<MetadataBuilder> metadata, int modifiers, | 68 KernelFunctionBuilder( |
72 KernelTypeBuilder returnType, String name, | 69 List<MetadataBuilder> metadata, |
| 70 int modifiers, |
| 71 KernelTypeBuilder returnType, |
| 72 String name, |
73 List<TypeVariableBuilder> typeVariables, | 73 List<TypeVariableBuilder> typeVariables, |
74 List<FormalParameterBuilder> formals, | 74 List<FormalParameterBuilder> formals, |
75 KernelLibraryBuilder compilationUnit, int charOffset, | 75 KernelLibraryBuilder compilationUnit, |
| 76 int charOffset, |
76 this.nativeMethodName) | 77 this.nativeMethodName) |
77 : super(metadata, modifiers, returnType, name, typeVariables, formals, | 78 : super(metadata, modifiers, returnType, name, typeVariables, formals, |
78 compilationUnit, charOffset); | 79 compilationUnit, charOffset); |
79 | 80 |
80 void set body(Statement newBody) { | 81 void set body(Statement newBody) { |
81 if (isAbstract && newBody != null) { | 82 if (isAbstract && newBody != null) { |
82 return internalError("Attempting to set body on abstract method."); | 83 return internalError("Attempting to set body on abstract method."); |
83 } | 84 } |
84 actualBody = newBody; | 85 actualBody = newBody; |
85 if (function != null) { | 86 if (function != null) { |
86 function.body = newBody; | 87 function.body = newBody; |
87 newBody?.parent = function; | 88 newBody?.parent = function; |
88 } | 89 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 if (substitution == null) { | 127 if (substitution == null) { |
127 substitution = <TypeParameter, DartType>{}; | 128 substitution = <TypeParameter, DartType>{}; |
128 for (TypeParameter parameter in typeParameters) { | 129 for (TypeParameter parameter in typeParameters) { |
129 substitution[parameter] = const DynamicType(); | 130 substitution[parameter] = const DynamicType(); |
130 } | 131 } |
131 } | 132 } |
132 warning(fileUri, charOffset, | 133 warning(fileUri, charOffset, |
133 "Can only use type variables in instance methods."); | 134 "Can only use type variables in instance methods."); |
134 return substitute(type, substitution); | 135 return substitute(type, substitution); |
135 } | 136 } |
| 137 |
136 Set<TypeParameter> set = typeParameters.toSet(); | 138 Set<TypeParameter> set = typeParameters.toSet(); |
137 for (VariableDeclaration parameter in result.positionalParameters) { | 139 for (VariableDeclaration parameter in result.positionalParameters) { |
138 if (containsTypeVariable(parameter.type, set)) { | 140 if (containsTypeVariable(parameter.type, set)) { |
139 parameter.type = removeTypeVariables(parameter.type); | 141 parameter.type = removeTypeVariables(parameter.type); |
140 } | 142 } |
141 } | 143 } |
142 for (VariableDeclaration parameter in result.namedParameters) { | 144 for (VariableDeclaration parameter in result.namedParameters) { |
143 if (containsTypeVariable(parameter.type, set)) { | 145 if (containsTypeVariable(parameter.type, set)) { |
144 parameter.type = removeTypeVariables(parameter.type); | 146 parameter.type = removeTypeVariables(parameter.type); |
145 } | 147 } |
146 } | 148 } |
147 if (containsTypeVariable(result.returnType, set)) { | 149 if (containsTypeVariable(result.returnType, set)) { |
148 result.returnType = removeTypeVariables(result.returnType); | 150 result.returnType = removeTypeVariables(result.returnType); |
149 } | 151 } |
150 } | 152 } |
151 } | 153 } |
152 return function = result; | 154 return function = result; |
153 } | 155 } |
154 | 156 |
155 Member build(Library library); | 157 Member build(Library library); |
156 | 158 |
157 void becomeNative(Loader loader) { | 159 void becomeNative(Loader loader) { |
158 target.isExternal = true; | 160 target.isExternal = true; |
159 Builder constructor = loader.getNativeAnnotation(); | 161 Builder constructor = loader.getNativeAnnotation(); |
160 Arguments arguments = | 162 Arguments arguments = |
161 new Arguments(<Expression>[new StringLiteral(nativeMethodName)]); | 163 new Arguments(<Expression>[new StringLiteral(nativeMethodName)]); |
162 Expression annotation; | 164 Expression annotation; |
163 if (constructor.isConstructor) { | 165 if (constructor.isConstructor) { |
164 annotation = new ConstructorInvocation(constructor.target, arguments) | 166 annotation = new ConstructorInvocation(constructor.target, arguments) |
165 ..isConst = true; | 167 ..isConst = true; |
166 } else { | 168 } else { |
167 annotation = new StaticInvocation(constructor.target, arguments) | 169 annotation = new StaticInvocation(constructor.target, arguments) |
168 ..isConst = true; | 170 ..isConst = true; |
169 } | 171 } |
170 target.addAnnotation(annotation); | 172 target.addAnnotation(annotation); |
171 } | 173 } |
172 } | 174 } |
173 | 175 |
174 class KernelProcedureBuilder extends KernelFunctionBuilder { | 176 class KernelProcedureBuilder extends KernelFunctionBuilder { |
175 final Procedure procedure; | 177 final Procedure procedure; |
176 | 178 |
177 AsyncMarker actualAsyncModifier; | 179 AsyncMarker actualAsyncModifier; |
178 | 180 |
179 final ConstructorReferenceBuilder redirectionTarget; | 181 final ConstructorReferenceBuilder redirectionTarget; |
180 | 182 |
181 KernelProcedureBuilder( | 183 KernelProcedureBuilder( |
182 List<MetadataBuilder> metadata, | 184 List<MetadataBuilder> metadata, |
183 int modifiers, KernelTypeBuilder returnType, String name, | 185 int modifiers, |
| 186 KernelTypeBuilder returnType, |
| 187 String name, |
184 List<TypeVariableBuilder> typeVariables, | 188 List<TypeVariableBuilder> typeVariables, |
185 List<FormalParameterBuilder> formals, this.actualAsyncModifier, | 189 List<FormalParameterBuilder> formals, |
186 ProcedureKind kind, KernelLibraryBuilder compilationUnit, int charOffset, | 190 this.actualAsyncModifier, |
187 [String nativeMethodName, this.redirectionTarget]) | 191 ProcedureKind kind, |
| 192 KernelLibraryBuilder compilationUnit, |
| 193 int charOffset, |
| 194 [String nativeMethodName, |
| 195 this.redirectionTarget]) |
188 : procedure = new Procedure(null, kind, null, | 196 : procedure = new Procedure(null, kind, null, |
189 fileUri: compilationUnit?.relativeFileUri), | 197 fileUri: compilationUnit?.relativeFileUri), |
190 super(metadata, modifiers, returnType, name, typeVariables, formals, | 198 super(metadata, modifiers, returnType, name, typeVariables, formals, |
191 compilationUnit, charOffset, nativeMethodName); | 199 compilationUnit, charOffset, nativeMethodName); |
192 | 200 |
193 ProcedureKind get kind => procedure.kind; | 201 ProcedureKind get kind => procedure.kind; |
194 | 202 |
195 AsyncMarker get asyncModifier => actualAsyncModifier; | 203 AsyncMarker get asyncModifier => actualAsyncModifier; |
196 | 204 |
197 Statement get body { | 205 Statement get body { |
198 if (actualBody == null && redirectionTarget == null && !isAbstract && | 206 if (actualBody == null && |
| 207 redirectionTarget == null && |
| 208 !isAbstract && |
199 !isExternal) { | 209 !isExternal) { |
200 actualBody = new EmptyStatement(); | 210 actualBody = new EmptyStatement(); |
201 } | 211 } |
202 return actualBody; | 212 return actualBody; |
203 } | 213 } |
204 | 214 |
205 void set asyncModifier(AsyncMarker newModifier) { | 215 void set asyncModifier(AsyncMarker newModifier) { |
206 actualAsyncModifier = newModifier; | 216 actualAsyncModifier = newModifier; |
207 if (function != null) { | 217 if (function != null) { |
208 // No parent, it's an enum. | 218 // No parent, it's an enum. |
(...skipping 23 matching lines...) Expand all Loading... |
232 final Constructor constructor = new Constructor(null); | 242 final Constructor constructor = new Constructor(null); |
233 | 243 |
234 bool hasMovedSuperInitializer = false; | 244 bool hasMovedSuperInitializer = false; |
235 | 245 |
236 SuperInitializer superInitializer; | 246 SuperInitializer superInitializer; |
237 | 247 |
238 RedirectingInitializer redirectingInitializer; | 248 RedirectingInitializer redirectingInitializer; |
239 | 249 |
240 KernelConstructorBuilder( | 250 KernelConstructorBuilder( |
241 List<MetadataBuilder> metadata, | 251 List<MetadataBuilder> metadata, |
242 int modifiers, KernelTypeBuilder returnType, String name, | 252 int modifiers, |
| 253 KernelTypeBuilder returnType, |
| 254 String name, |
243 List<TypeVariableBuilder> typeVariables, | 255 List<TypeVariableBuilder> typeVariables, |
244 List<FormalParameterBuilder> formals, | 256 List<FormalParameterBuilder> formals, |
245 KernelLibraryBuilder compilationUnit, int charOffset, | 257 KernelLibraryBuilder compilationUnit, |
| 258 int charOffset, |
246 [String nativeMethodName]) | 259 [String nativeMethodName]) |
247 : super(metadata, modifiers, returnType, name, typeVariables, formals, | 260 : super(metadata, modifiers, returnType, name, typeVariables, formals, |
248 compilationUnit, charOffset, nativeMethodName); | 261 compilationUnit, charOffset, nativeMethodName); |
249 | 262 |
250 bool get isInstanceMember => false; | 263 bool get isInstanceMember => false; |
251 | 264 |
252 bool get isConstructor => true; | 265 bool get isConstructor => true; |
253 | 266 |
254 AsyncMarker get asyncModifier => AsyncMarker.Sync; | 267 AsyncMarker get asyncModifier => AsyncMarker.Sync; |
255 | 268 |
256 ProcedureKind get kind => null; | 269 ProcedureKind get kind => null; |
257 | 270 |
258 Constructor build(Library library) { | 271 Constructor build(Library library) { |
259 if (constructor.name == null) { | 272 if (constructor.name == null) { |
260 constructor.function = buildFunction(); | 273 constructor.function = buildFunction(); |
261 constructor.function.parent = constructor; | 274 constructor.function.parent = constructor; |
262 constructor.isConst = isConst; | 275 constructor.isConst = isConst; |
263 constructor.isExternal = isExternal; | 276 constructor.isExternal = isExternal; |
264 constructor.name = new Name(name, library); | 277 constructor.name = new Name(name, library); |
265 } | 278 } |
266 return constructor; | 279 return constructor; |
267 } | 280 } |
268 | 281 |
269 FunctionNode buildFunction() { | 282 FunctionNode buildFunction() { |
270 // TODO(ahe): Should complain if another type is explicitly set. | 283 // TODO(ahe): Should complain if another type is explicitly set. |
271 return super.buildFunction() | 284 return super.buildFunction()..returnType = const VoidType(); |
272 ..returnType = const VoidType(); | |
273 } | 285 } |
274 | 286 |
275 Constructor get target => constructor; | 287 Constructor get target => constructor; |
276 | 288 |
277 void checkSuperOrThisInitializer(Initializer initializer) { | 289 void checkSuperOrThisInitializer(Initializer initializer) { |
278 if (superInitializer != null || redirectingInitializer != null) { | 290 if (superInitializer != null || redirectingInitializer != null) { |
279 memberError(target, | 291 memberError( |
| 292 target, |
280 "Can't have more than one 'super' or 'this' initializer.", | 293 "Can't have more than one 'super' or 'this' initializer.", |
281 initializer.fileOffset); | 294 initializer.fileOffset); |
282 } | 295 } |
283 } | 296 } |
284 | 297 |
285 void addInitializer(Initializer initializer) { | 298 void addInitializer(Initializer initializer) { |
286 List<Initializer> initializers = constructor.initializers; | 299 List<Initializer> initializers = constructor.initializers; |
287 if (initializer is SuperInitializer) { | 300 if (initializer is SuperInitializer) { |
288 checkSuperOrThisInitializer(initializer); | 301 checkSuperOrThisInitializer(initializer); |
289 superInitializer = initializer; | 302 superInitializer = initializer; |
(...skipping 18 matching lines...) Expand all Loading... |
308 // To preserve correct evaluation order, the arguments to super call | 321 // To preserve correct evaluation order, the arguments to super call |
309 // must be evaluated before [initializer]. Once the super initializer | 322 // must be evaluated before [initializer]. Once the super initializer |
310 // has been moved once, the arguments are evaluated in the correct | 323 // has been moved once, the arguments are evaluated in the correct |
311 // order. | 324 // order. |
312 hasMovedSuperInitializer = true; | 325 hasMovedSuperInitializer = true; |
313 Arguments arguments = superInitializer.arguments; | 326 Arguments arguments = superInitializer.arguments; |
314 List<Expression> positional = arguments.positional; | 327 List<Expression> positional = arguments.positional; |
315 for (int i = 0; i < positional.length; i++) { | 328 for (int i = 0; i < positional.length; i++) { |
316 VariableDeclaration variable = | 329 VariableDeclaration variable = |
317 new VariableDeclaration.forValue(positional[i], isFinal: true); | 330 new VariableDeclaration.forValue(positional[i], isFinal: true); |
318 initializers.add( | 331 initializers |
319 new LocalInitializer(variable)..parent = constructor); | 332 .add(new LocalInitializer(variable)..parent = constructor); |
320 positional[i] = new VariableGet(variable)..parent = arguments; | 333 positional[i] = new VariableGet(variable)..parent = arguments; |
321 } | 334 } |
322 for (NamedExpression named in arguments.named) { | 335 for (NamedExpression named in arguments.named) { |
323 VariableDeclaration variable = | 336 VariableDeclaration variable = |
324 new VariableDeclaration.forValue(named.value, isFinal: true); | 337 new VariableDeclaration.forValue(named.value, isFinal: true); |
325 named.value = new VariableGet(variable)..parent = named; | 338 named.value = new VariableGet(variable)..parent = named; |
326 initializers.add( | 339 initializers |
327 new LocalInitializer(variable)..parent = constructor); | 340 .add(new LocalInitializer(variable)..parent = constructor); |
328 } | 341 } |
329 } | 342 } |
330 initializers.add(initializer..parent = constructor); | 343 initializers.add(initializer..parent = constructor); |
331 initializers.add(superInitializer); | 344 initializers.add(superInitializer); |
332 return; | 345 return; |
333 } | 346 } |
334 initializers.add(initializer); | 347 initializers.add(initializer); |
335 initializer.parent = constructor; | 348 initializer.parent = constructor; |
336 } | 349 } |
337 } | 350 } |
OLD | NEW |