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:front_end/src/fasta/kernel/kernel_shadow_ast.dart' |
| 8 show KernelProcedure; |
| 9 |
| 10 import 'package:front_end/src/fasta/source/source_library_builder.dart' |
| 11 show SourceLibraryBuilder; |
| 12 |
| 13 import 'package:front_end/src/fasta/type_inference/type_inference_listener.dart' |
| 14 show TypeInferenceListener; |
| 15 |
7 import 'package:kernel/ast.dart' | 16 import 'package:kernel/ast.dart' |
8 show | 17 show |
9 Arguments, | 18 Arguments, |
10 AsyncMarker, | 19 AsyncMarker, |
11 Constructor, | 20 Constructor, |
12 ConstructorInvocation, | 21 ConstructorInvocation, |
13 DartType, | 22 DartType, |
14 DynamicType, | 23 DynamicType, |
15 EmptyStatement, | 24 EmptyStatement, |
16 Expression, | 25 Expression, |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 } | 167 } |
159 } | 168 } |
160 if (containsTypeVariable(result.returnType, set)) { | 169 if (containsTypeVariable(result.returnType, set)) { |
161 result.returnType = removeTypeVariables(result.returnType); | 170 result.returnType = removeTypeVariables(result.returnType); |
162 } | 171 } |
163 } | 172 } |
164 } | 173 } |
165 return function = result; | 174 return function = result; |
166 } | 175 } |
167 | 176 |
168 Member build(LibraryBuilder library); | 177 Member build(SourceLibraryBuilder library); |
169 | 178 |
170 void becomeNative(Loader loader) { | 179 void becomeNative(Loader loader) { |
171 target.isExternal = true; | 180 target.isExternal = true; |
172 Builder constructor = loader.getNativeAnnotation(); | 181 Builder constructor = loader.getNativeAnnotation(); |
173 Arguments arguments = | 182 Arguments arguments = |
174 new Arguments(<Expression>[new StringLiteral(nativeMethodName)]); | 183 new Arguments(<Expression>[new StringLiteral(nativeMethodName)]); |
175 Expression annotation; | 184 Expression annotation; |
176 if (constructor.isConstructor) { | 185 if (constructor.isConstructor) { |
177 annotation = new ConstructorInvocation(constructor.target, arguments) | 186 annotation = new ConstructorInvocation(constructor.target, arguments) |
178 ..isConst = true; | 187 ..isConst = true; |
179 } else { | 188 } else { |
180 annotation = new StaticInvocation(constructor.target, arguments) | 189 annotation = new StaticInvocation(constructor.target, arguments) |
181 ..isConst = true; | 190 ..isConst = true; |
182 } | 191 } |
183 target.addAnnotation(annotation); | 192 target.addAnnotation(annotation); |
184 } | 193 } |
185 } | 194 } |
186 | 195 |
187 class KernelProcedureBuilder extends KernelFunctionBuilder { | 196 class KernelProcedureBuilder extends KernelFunctionBuilder { |
188 final Procedure procedure; | 197 final KernelProcedure procedure; |
189 final int charOpenParenOffset; | 198 final int charOpenParenOffset; |
190 | 199 |
191 AsyncMarker actualAsyncModifier = AsyncMarker.Sync; | 200 AsyncMarker actualAsyncModifier = AsyncMarker.Sync; |
192 | 201 |
193 final ConstructorReferenceBuilder redirectionTarget; | 202 final ConstructorReferenceBuilder redirectionTarget; |
194 | 203 |
195 KernelProcedureBuilder( | 204 KernelProcedureBuilder( |
196 List<MetadataBuilder> metadata, | 205 List<MetadataBuilder> metadata, |
197 int modifiers, | 206 int modifiers, |
198 KernelTypeBuilder returnType, | 207 KernelTypeBuilder returnType, |
199 String name, | 208 String name, |
200 List<TypeVariableBuilder> typeVariables, | 209 List<TypeVariableBuilder> typeVariables, |
201 List<FormalParameterBuilder> formals, | 210 List<FormalParameterBuilder> formals, |
202 ProcedureKind kind, | 211 ProcedureKind kind, |
203 KernelLibraryBuilder compilationUnit, | 212 KernelLibraryBuilder compilationUnit, |
204 int charOffset, | 213 int charOffset, |
205 this.charOpenParenOffset, | 214 this.charOpenParenOffset, |
206 int charEndOffset, | 215 int charEndOffset, |
207 [String nativeMethodName, | 216 [String nativeMethodName, |
208 this.redirectionTarget]) | 217 this.redirectionTarget]) |
209 : procedure = new Procedure(null, kind, null, | 218 : procedure = new KernelProcedure(null, kind, null, |
210 fileUri: compilationUnit?.relativeFileUri) | 219 fileUri: compilationUnit?.relativeFileUri) |
211 ..fileOffset = charOffset | 220 ..fileOffset = charOffset |
212 ..fileEndOffset = charEndOffset, | 221 ..fileEndOffset = charEndOffset, |
213 super(metadata, modifiers, returnType, name, typeVariables, formals, | 222 super(metadata, modifiers, returnType, name, typeVariables, formals, |
214 compilationUnit, charOffset, nativeMethodName); | 223 compilationUnit, charOffset, nativeMethodName); |
215 | 224 |
216 ProcedureKind get kind => procedure.kind; | 225 ProcedureKind get kind => procedure.kind; |
217 | 226 |
218 AsyncMarker get asyncModifier => actualAsyncModifier; | 227 AsyncMarker get asyncModifier => actualAsyncModifier; |
219 | 228 |
220 Statement get body { | 229 Statement get body { |
221 if (actualBody == null && | 230 if (actualBody == null && |
222 redirectionTarget == null && | 231 redirectionTarget == null && |
223 !isAbstract && | 232 !isAbstract && |
224 !isExternal) { | 233 !isExternal) { |
225 actualBody = new EmptyStatement(); | 234 actualBody = new EmptyStatement(); |
226 } | 235 } |
227 return actualBody; | 236 return actualBody; |
228 } | 237 } |
229 | 238 |
230 void set asyncModifier(AsyncMarker newModifier) { | 239 void set asyncModifier(AsyncMarker newModifier) { |
231 actualAsyncModifier = newModifier; | 240 actualAsyncModifier = newModifier; |
232 if (function != null) { | 241 if (function != null) { |
233 // No parent, it's an enum. | 242 // No parent, it's an enum. |
234 function.asyncMarker = actualAsyncModifier; | 243 function.asyncMarker = actualAsyncModifier; |
235 function.dartAsyncMarker = actualAsyncModifier; | 244 function.dartAsyncMarker = actualAsyncModifier; |
236 } | 245 } |
237 } | 246 } |
238 | 247 |
239 Procedure build(LibraryBuilder library) { | 248 bool get isEligibleForGetterSetterInference { |
| 249 if (!isInstanceMember) return false; |
| 250 if (isGetter) { |
| 251 return returnType == null; |
| 252 } else if (isSetter) { |
| 253 return formals != null && formals.length > 0 && formals[0].type == null; |
| 254 } else { |
| 255 return false; |
| 256 } |
| 257 } |
| 258 |
| 259 Procedure build(SourceLibraryBuilder library) { |
240 // TODO(ahe): I think we may call this twice on parts. Investigate. | 260 // TODO(ahe): I think we may call this twice on parts. Investigate. |
241 if (procedure.name == null) { | 261 if (procedure.name == null) { |
242 procedure.function = buildFunction(library); | 262 procedure.function = buildFunction(library); |
243 procedure.function.parent = procedure; | 263 procedure.function.parent = procedure; |
244 procedure.function.fileOffset = charOpenParenOffset; | 264 procedure.function.fileOffset = charOpenParenOffset; |
245 procedure.function.fileEndOffset = procedure.fileEndOffset; | 265 procedure.function.fileEndOffset = procedure.fileEndOffset; |
246 procedure.isAbstract = isAbstract; | 266 procedure.isAbstract = isAbstract; |
247 procedure.isStatic = isStatic; | 267 procedure.isStatic = isStatic; |
248 procedure.isExternal = isExternal; | 268 procedure.isExternal = isExternal; |
249 procedure.isConst = isConst; | 269 procedure.isConst = isConst; |
250 procedure.name = new Name(name, library.target); | 270 procedure.name = new Name(name, library.target); |
251 } | 271 } |
| 272 if (isEligibleForGetterSetterInference) { |
| 273 library.loader.typeInferenceEngine.recordMember(procedure); |
| 274 } |
252 return procedure; | 275 return procedure; |
253 } | 276 } |
254 | 277 |
255 Procedure get target => procedure; | 278 Procedure get target => procedure; |
| 279 |
| 280 @override |
| 281 void prepareInitializerInference( |
| 282 SourceLibraryBuilder library, ClassBuilder currentClass) { |
| 283 if (isEligibleForGetterSetterInference) { |
| 284 var typeInferenceEngine = library.loader.typeInferenceEngine; |
| 285 var listener = new TypeInferenceListener(); |
| 286 typeInferenceEngine.createTopLevelTypeInferrer( |
| 287 listener, procedure.enclosingClass?.thisType, procedure); |
| 288 } |
| 289 } |
256 } | 290 } |
257 | 291 |
258 // TODO(ahe): Move this to own file? | 292 // TODO(ahe): Move this to own file? |
259 class KernelConstructorBuilder extends KernelFunctionBuilder { | 293 class KernelConstructorBuilder extends KernelFunctionBuilder { |
260 final Constructor constructor; | 294 final Constructor constructor; |
261 | 295 |
262 final int charOpenParenOffset; | 296 final int charOpenParenOffset; |
263 | 297 |
264 bool hasMovedSuperInitializer = false; | 298 bool hasMovedSuperInitializer = false; |
265 | 299 |
(...skipping 24 matching lines...) Expand all Loading... |
290 bool get isConstructor => true; | 324 bool get isConstructor => true; |
291 | 325 |
292 AsyncMarker get asyncModifier => AsyncMarker.Sync; | 326 AsyncMarker get asyncModifier => AsyncMarker.Sync; |
293 | 327 |
294 ProcedureKind get kind => null; | 328 ProcedureKind get kind => null; |
295 | 329 |
296 bool get isRedirectingGenerativeConstructor { | 330 bool get isRedirectingGenerativeConstructor { |
297 return isRedirectingGenerativeConstructorImplementation(constructor); | 331 return isRedirectingGenerativeConstructorImplementation(constructor); |
298 } | 332 } |
299 | 333 |
300 Constructor build(LibraryBuilder library) { | 334 Constructor build(SourceLibraryBuilder library) { |
301 if (constructor.name == null) { | 335 if (constructor.name == null) { |
302 constructor.function = buildFunction(library); | 336 constructor.function = buildFunction(library); |
303 constructor.function.parent = constructor; | 337 constructor.function.parent = constructor; |
304 constructor.function.fileOffset = charOpenParenOffset; | 338 constructor.function.fileOffset = charOpenParenOffset; |
305 constructor.function.fileEndOffset = constructor.fileEndOffset; | 339 constructor.function.fileEndOffset = constructor.fileEndOffset; |
306 constructor.isConst = isConst; | 340 constructor.isConst = isConst; |
307 constructor.isExternal = isExternal; | 341 constructor.isExternal = isExternal; |
308 constructor.name = new Name(name, library.target); | 342 constructor.name = new Name(name, library.target); |
309 } | 343 } |
310 return constructor; | 344 return constructor; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 } | 406 } |
373 } | 407 } |
374 initializers.add(initializer..parent = constructor); | 408 initializers.add(initializer..parent = constructor); |
375 initializers.add(superInitializer); | 409 initializers.add(superInitializer); |
376 return; | 410 return; |
377 } | 411 } |
378 initializers.add(initializer); | 412 initializers.add(initializer); |
379 initializer.parent = constructor; | 413 initializer.parent = constructor; |
380 } | 414 } |
381 } | 415 } |
OLD | NEW |