| OLD | NEW |
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 analyzer.src.task.dart; | 5 library analyzer.src.task.dart; |
| 6 | 6 |
| 7 import 'dart:collection'; | 7 import 'dart:collection'; |
| 8 | 8 |
| 9 import 'package:analyzer/src/context/cache.dart'; | 9 import 'package:analyzer/src/context/cache.dart'; |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
| (...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 358 * | 358 * |
| 359 * The list will be empty if there were no errors, but will not be `null`. | 359 * The list will be empty if there were no errors, but will not be `null`. |
| 360 * | 360 * |
| 361 * The result is only available for [LibrarySpecificUnit]s. | 361 * The result is only available for [LibrarySpecificUnit]s. |
| 362 */ | 362 */ |
| 363 final ListResultDescriptor<AnalysisError> RESOLVE_TYPE_NAMES_ERRORS = | 363 final ListResultDescriptor<AnalysisError> RESOLVE_TYPE_NAMES_ERRORS = |
| 364 new ListResultDescriptor<AnalysisError>( | 364 new ListResultDescriptor<AnalysisError>( |
| 365 'RESOLVE_TYPE_NAMES_ERRORS', AnalysisError.NO_ERRORS); | 365 'RESOLVE_TYPE_NAMES_ERRORS', AnalysisError.NO_ERRORS); |
| 366 | 366 |
| 367 /** | 367 /** |
| 368 * The partially resolved [CompilationUnit] associated with a unit. | 368 * The partially resolved [CompilationUnit] associated with a compilation unit. |
| 369 * | 369 * |
| 370 * All declarations bound to the element defined by the declaration. | 370 * Tasks that use this value as an input can assume that the [SimpleIdentifier]s |
| 371 * at all declaration sites have been bound to the element defined by the |
| 372 * declaration, except for the constants defined in an 'enum' declaration. |
| 371 * | 373 * |
| 372 * The result is only available for [LibrarySpecificUnit]s. | 374 * The result is only available for [LibrarySpecificUnit]s. |
| 373 */ | 375 */ |
| 374 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT1 = | 376 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT1 = |
| 375 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT1', null, | 377 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT1', null, |
| 376 cachingPolicy: AST_CACHING_POLICY); | 378 cachingPolicy: AST_CACHING_POLICY); |
| 377 | 379 |
| 378 /** | 380 /** |
| 379 * The partially resolved [CompilationUnit] associated with a unit. | 381 * The partially resolved [CompilationUnit] associated with a compilation unit. |
| 380 * | 382 * |
| 381 * All the enum member elements are built. | 383 * Tasks that use this value as an input can assume that the [SimpleIdentifier]s |
| 384 * at all declaration sites have been bound to the element defined by the |
| 385 * declaration, including for the constants defined in an 'enum' declaration. |
| 382 * | 386 * |
| 383 * The result is only available for [LibrarySpecificUnit]s. | 387 * The result is only available for [LibrarySpecificUnit]s. |
| 384 */ | 388 */ |
| 385 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT2 = | 389 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT2 = |
| 386 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT2', null, | 390 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT2', null, |
| 387 cachingPolicy: AST_CACHING_POLICY); | 391 cachingPolicy: AST_CACHING_POLICY); |
| 388 | 392 |
| 389 /** | 393 /** |
| 390 * The partially resolved [CompilationUnit] associated with a unit. | 394 * The partially resolved [CompilationUnit] associated with a compilation unit. |
| 391 * | 395 * |
| 392 * [RESOLVED_UNIT2] with resolved type names. | 396 * In addition to what is true of a [RESOLVED_UNIT2], tasks that use this value |
| 397 * as an input can assume that the types associated with declarations have been |
| 398 * resolved. This includes the types of superclasses, mixins, interfaces, |
| 399 * fields, return types, parameters, and local variables. |
| 393 * | 400 * |
| 394 * The result is only available for [LibrarySpecificUnit]s. | 401 * The result is only available for [LibrarySpecificUnit]s. |
| 395 */ | 402 */ |
| 396 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT3 = | 403 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT3 = |
| 397 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT3', null, | 404 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT3', null, |
| 398 cachingPolicy: AST_CACHING_POLICY); | 405 cachingPolicy: AST_CACHING_POLICY); |
| 399 | 406 |
| 400 /** | 407 /** |
| 401 * The partially resolved [CompilationUnit] associated with a unit. | 408 * The partially resolved [CompilationUnit] associated with a compilation unit. |
| 402 * | 409 * |
| 403 * [RESOLVED_UNIT3] plus resolved local variables and formal parameters. | 410 * In addition to what is true of a [RESOLVED_UNIT3], tasks that use this value |
| 411 * as an input can assume that references to local variables and formal |
| 412 * parameters have been resolved. |
| 404 * | 413 * |
| 405 * The result is only available for [LibrarySpecificUnit]s. | 414 * The result is only available for [LibrarySpecificUnit]s. |
| 406 */ | 415 */ |
| 407 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT4 = | 416 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT4 = |
| 408 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT4', null, | 417 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT4', null, |
| 409 cachingPolicy: AST_CACHING_POLICY); | 418 cachingPolicy: AST_CACHING_POLICY); |
| 410 | 419 |
| 411 /** | 420 /** |
| 412 * The resolved [CompilationUnit] associated with a compilation unit in which | 421 * The partially resolved [CompilationUnit] associated with a compilation unit. |
| 413 * elements and types have been initially resolved outside of method bodies in | 422 * |
| 414 * addition to everything that is true of a [RESOLVED_UNIT4]. | 423 * In addition to what is true of a [RESOLVED_UNIT4], tasks that use this value |
| 424 * as an input can assume that elements and types have been initially resolved |
| 425 * outside of method bodies. |
| 415 * | 426 * |
| 416 * The result is only available for [LibrarySpecificUnit]s. | 427 * The result is only available for [LibrarySpecificUnit]s. |
| 417 */ | 428 */ |
| 418 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT5 = | 429 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT5 = |
| 419 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT5', null, | 430 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT5', null, |
| 420 cachingPolicy: AST_CACHING_POLICY); | 431 cachingPolicy: AST_CACHING_POLICY); |
| 421 | 432 |
| 422 /** | 433 /** |
| 423 * The resolved [CompilationUnit] associated with a compilation unit in which | 434 * The partially resolved [CompilationUnit] associated with a compilation unit. |
| 424 * the types of static variables have been inferred in addition to everything | 435 * |
| 425 * that is true of a [RESOLVED_UNIT5]. | 436 * In addition to what is true of a [RESOLVED_UNIT5], tasks that use this value |
| 437 * as an input can assume that the types of static variables have been inferred. |
| 426 * | 438 * |
| 427 * The result is only available for [LibrarySpecificUnit]s. | 439 * The result is only available for [LibrarySpecificUnit]s. |
| 428 */ | 440 */ |
| 429 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT6 = | 441 final ResultDescriptor<CompilationUnit> RESOLVED_UNIT6 = |
| 430 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT6', null, | 442 new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT6', null, |
| 431 cachingPolicy: AST_CACHING_POLICY); | 443 cachingPolicy: AST_CACHING_POLICY); |
| 432 | 444 |
| 433 /** | 445 /** |
| 434 * The resolved [CompilationUnit] associated with a compilation unit in which | 446 * The resolved [CompilationUnit] associated with a compilation unit in which |
| 435 * the right hand sides of instance variables have been re-resolved in addition | 447 * the right hand sides of instance variables have been re-resolved in addition |
| (...skipping 2809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3245 * Create a [LibraryUnitErrorsTask] based on the given [target] in the given | 3257 * Create a [LibraryUnitErrorsTask] based on the given [target] in the given |
| 3246 * [context]. | 3258 * [context]. |
| 3247 */ | 3259 */ |
| 3248 static LibraryUnitErrorsTask createTask( | 3260 static LibraryUnitErrorsTask createTask( |
| 3249 AnalysisContext context, AnalysisTarget target) { | 3261 AnalysisContext context, AnalysisTarget target) { |
| 3250 return new LibraryUnitErrorsTask(context, target); | 3262 return new LibraryUnitErrorsTask(context, target); |
| 3251 } | 3263 } |
| 3252 } | 3264 } |
| 3253 | 3265 |
| 3254 /** | 3266 /** |
| 3255 * A task that parses the content of a Dart file, producing an AST structure. | 3267 * A task that parses the content of a Dart file, producing an AST structure, |
| 3268 * any lexical errors found in the process, the kind of the file (library or |
| 3269 * part), and several lists based on the AST. |
| 3256 */ | 3270 */ |
| 3257 class ParseDartTask extends SourceBasedAnalysisTask { | 3271 class ParseDartTask extends SourceBasedAnalysisTask { |
| 3258 /** | 3272 /** |
| 3259 * The name of the input whose value is the line information produced for the | 3273 * The name of the input whose value is the line information produced for the |
| 3260 * file. | 3274 * file. |
| 3261 */ | 3275 */ |
| 3262 static const String LINE_INFO_INPUT_NAME = 'LINE_INFO_INPUT_NAME'; | 3276 static const String LINE_INFO_INPUT_NAME = 'LINE_INFO_INPUT_NAME'; |
| 3263 | 3277 |
| 3264 /** | 3278 /** |
| 3265 * The name of the input whose value is the modification time of the file. | 3279 * The name of the input whose value is the modification time of the file. |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3476 | 3490 |
| 3477 @override | 3491 @override |
| 3478 void internalPerform() { | 3492 void internalPerform() { |
| 3479 // | 3493 // |
| 3480 // Prepare inputs. | 3494 // Prepare inputs. |
| 3481 // | 3495 // |
| 3482 LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT); | 3496 LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT); |
| 3483 CompilationUnit unit = getRequiredInput(UNIT_INPUT); | 3497 CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
| 3484 CompilationUnitElement unitElement = unit.element; | 3498 CompilationUnitElement unitElement = unit.element; |
| 3485 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); | 3499 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
| 3500 // |
| 3501 // Resolve references and record outputs. |
| 3502 // |
| 3486 if (context.analysisOptions.strongMode) { | 3503 if (context.analysisOptions.strongMode) { |
| 3487 // | |
| 3488 // Resolve references. | |
| 3489 // | |
| 3490 InheritanceManager inheritanceManager = | 3504 InheritanceManager inheritanceManager = |
| 3491 new InheritanceManager(libraryElement); | 3505 new InheritanceManager(libraryElement); |
| 3492 PartialResolverVisitor visitor = new PartialResolverVisitor( | 3506 PartialResolverVisitor visitor = new PartialResolverVisitor( |
| 3493 libraryElement, | 3507 libraryElement, |
| 3494 unitElement.source, | 3508 unitElement.source, |
| 3495 typeProvider, | 3509 typeProvider, |
| 3496 AnalysisErrorListener.NULL_LISTENER, | 3510 AnalysisErrorListener.NULL_LISTENER, |
| 3497 inheritanceManager: inheritanceManager); | 3511 inheritanceManager: inheritanceManager); |
| 3498 unit.accept(visitor); | 3512 unit.accept(visitor); |
| 3499 // | 3513 |
| 3500 // Record outputs. | |
| 3501 // | |
| 3502 outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.variablesAndFields; | 3514 outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = visitor.variablesAndFields; |
| 3503 } else { | 3515 } else { |
| 3504 outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = []; | 3516 outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = []; |
| 3505 } | 3517 } |
| 3506 outputs[RESOLVED_UNIT5] = unit; | 3518 outputs[RESOLVED_UNIT5] = unit; |
| 3507 } | 3519 } |
| 3508 | 3520 |
| 3509 /** | 3521 /** |
| 3510 * Return a map from the names of the inputs of this kind of task to the task | 3522 * Return a map from the names of the inputs of this kind of task to the task |
| 3511 * input descriptors describing those inputs for a task with the | 3523 * input descriptors describing those inputs for a task with the |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3931 | 3943 |
| 3932 ResolveUnitTypeNamesTask( | 3944 ResolveUnitTypeNamesTask( |
| 3933 InternalAnalysisContext context, AnalysisTarget target) | 3945 InternalAnalysisContext context, AnalysisTarget target) |
| 3934 : super(context, target); | 3946 : super(context, target); |
| 3935 | 3947 |
| 3936 @override | 3948 @override |
| 3937 TaskDescriptor get descriptor => DESCRIPTOR; | 3949 TaskDescriptor get descriptor => DESCRIPTOR; |
| 3938 | 3950 |
| 3939 @override | 3951 @override |
| 3940 void internalPerform() { | 3952 void internalPerform() { |
| 3941 RecordingErrorListener errorListener = new RecordingErrorListener(); | |
| 3942 // | 3953 // |
| 3943 // Prepare inputs. | 3954 // Prepare inputs. |
| 3944 // | 3955 // |
| 3945 LibraryElement library = getRequiredInput(LIBRARY_INPUT); | 3956 LibraryElement library = getRequiredInput(LIBRARY_INPUT); |
| 3946 CompilationUnit unit = getRequiredInput(UNIT_INPUT); | 3957 CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
| 3947 CompilationUnitElement unitElement = unit.element; | 3958 CompilationUnitElement unitElement = unit.element; |
| 3948 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); | 3959 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
| 3949 // | 3960 // |
| 3950 // Resolve TypeName nodes. | 3961 // Resolve TypeName nodes. |
| 3951 // | 3962 // |
| 3963 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 3952 TypeResolverVisitor visitor = new TypeResolverVisitor( | 3964 TypeResolverVisitor visitor = new TypeResolverVisitor( |
| 3953 library, unitElement.source, typeProvider, errorListener); | 3965 library, unitElement.source, typeProvider, errorListener); |
| 3954 unit.accept(visitor); | 3966 unit.accept(visitor); |
| 3955 // | 3967 // |
| 3956 // Record outputs. | 3968 // Record outputs. |
| 3957 // | 3969 // |
| 3958 outputs[RESOLVE_TYPE_NAMES_ERRORS] = | 3970 outputs[RESOLVE_TYPE_NAMES_ERRORS] = |
| 3959 removeDuplicateErrors(errorListener.errors); | 3971 removeDuplicateErrors(errorListener.errors); |
| 3960 outputs[RESOLVED_UNIT3] = unit; | 3972 outputs[RESOLVED_UNIT3] = unit; |
| 3961 } | 3973 } |
| 3962 | 3974 |
| 3963 /** | 3975 /** |
| 3964 * Return a map from the names of the inputs of this kind of task to the task | 3976 * Return a map from the names of the inputs of this kind of task to the task |
| 3965 * input descriptors describing those inputs for a task with the | 3977 * input descriptors describing those inputs for a task with the |
| 3966 * given [target]. | 3978 * given [target]. |
| 3967 */ | 3979 */ |
| 3968 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { | 3980 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { |
| 3981 // TODO(brianwilkerson) This task updates the element model to have type |
| 3982 // information and updates the class hierarchy. It should produce a new |
| 3983 // version of the element model in order to record those changes. |
| 3969 LibrarySpecificUnit unit = target; | 3984 LibrarySpecificUnit unit = target; |
| 3970 return <String, TaskInput>{ | 3985 return <String, TaskInput>{ |
| 3971 'importsExportNamespace': | 3986 'importsExportNamespace': |
| 3972 IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4), | 3987 IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4), |
| 3973 LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library), | 3988 LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library), |
| 3974 UNIT_INPUT: RESOLVED_UNIT2.of(unit), | 3989 UNIT_INPUT: RESOLVED_UNIT2.of(unit), |
| 3975 TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request) | 3990 TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request) |
| 3976 }; | 3991 }; |
| 3977 } | 3992 } |
| 3978 | 3993 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4016 | 4031 |
| 4017 ResolveVariableReferencesTask( | 4032 ResolveVariableReferencesTask( |
| 4018 InternalAnalysisContext context, AnalysisTarget target) | 4033 InternalAnalysisContext context, AnalysisTarget target) |
| 4019 : super(context, target); | 4034 : super(context, target); |
| 4020 | 4035 |
| 4021 @override | 4036 @override |
| 4022 TaskDescriptor get descriptor => DESCRIPTOR; | 4037 TaskDescriptor get descriptor => DESCRIPTOR; |
| 4023 | 4038 |
| 4024 @override | 4039 @override |
| 4025 void internalPerform() { | 4040 void internalPerform() { |
| 4026 RecordingErrorListener errorListener = new RecordingErrorListener(); | |
| 4027 // | 4041 // |
| 4028 // Prepare inputs. | 4042 // Prepare inputs. |
| 4029 // | 4043 // |
| 4030 LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT); | 4044 LibraryElement libraryElement = getRequiredInput(LIBRARY_INPUT); |
| 4031 CompilationUnit unit = getRequiredInput(UNIT_INPUT); | 4045 CompilationUnit unit = getRequiredInput(UNIT_INPUT); |
| 4032 CompilationUnitElement unitElement = unit.element; | 4046 CompilationUnitElement unitElement = unit.element; |
| 4047 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); |
| 4033 // | 4048 // |
| 4034 // Resolve local variables. | 4049 // Resolve local variables. |
| 4035 // | 4050 // |
| 4036 TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT); | 4051 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 4037 Scope nameScope = new LibraryScope(libraryElement, errorListener); | 4052 Scope nameScope = new LibraryScope(libraryElement, errorListener); |
| 4038 AstVisitor visitor = new VariableResolverVisitor( | 4053 VariableResolverVisitor visitor = new VariableResolverVisitor( |
| 4039 libraryElement, unitElement.source, typeProvider, errorListener, | 4054 libraryElement, unitElement.source, typeProvider, errorListener, |
| 4040 nameScope: nameScope); | 4055 nameScope: nameScope); |
| 4041 unit.accept(visitor); | 4056 unit.accept(visitor); |
| 4042 // | 4057 // |
| 4043 // Record outputs. | 4058 // Record outputs. |
| 4044 // | 4059 // |
| 4045 outputs[RESOLVED_UNIT4] = unit; | 4060 outputs[RESOLVED_UNIT4] = unit; |
| 4046 outputs[VARIABLE_REFERENCE_ERRORS] = | 4061 outputs[VARIABLE_REFERENCE_ERRORS] = |
| 4047 removeDuplicateErrors(errorListener.errors); | 4062 removeDuplicateErrors(errorListener.errors); |
| 4048 } | 4063 } |
| (...skipping 16 matching lines...) Expand all Loading... |
| 4065 * Create a [ResolveVariableReferencesTask] based on the given [target] in | 4080 * Create a [ResolveVariableReferencesTask] based on the given [target] in |
| 4066 * the given [context]. | 4081 * the given [context]. |
| 4067 */ | 4082 */ |
| 4068 static ResolveVariableReferencesTask createTask( | 4083 static ResolveVariableReferencesTask createTask( |
| 4069 AnalysisContext context, AnalysisTarget target) { | 4084 AnalysisContext context, AnalysisTarget target) { |
| 4070 return new ResolveVariableReferencesTask(context, target); | 4085 return new ResolveVariableReferencesTask(context, target); |
| 4071 } | 4086 } |
| 4072 } | 4087 } |
| 4073 | 4088 |
| 4074 /** | 4089 /** |
| 4075 * A task that scans the content of a file, producing a set of Dart tokens. | 4090 * A task that scans the content of a Dart file, producing a stream of Dart |
| 4091 * tokens, line information, and any lexical errors encountered in the process. |
| 4076 */ | 4092 */ |
| 4077 class ScanDartTask extends SourceBasedAnalysisTask { | 4093 class ScanDartTask extends SourceBasedAnalysisTask { |
| 4078 /** | 4094 /** |
| 4079 * The name of the input whose value is the content of the file. | 4095 * The name of the input whose value is the content of the file. |
| 4080 */ | 4096 */ |
| 4081 static const String CONTENT_INPUT_NAME = 'CONTENT_INPUT_NAME'; | 4097 static const String CONTENT_INPUT_NAME = 'CONTENT_INPUT_NAME'; |
| 4082 | 4098 |
| 4083 /** | 4099 /** |
| 4084 * The task descriptor describing this kind of task. | 4100 * The task descriptor describing this kind of task. |
| 4085 */ | 4101 */ |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4509 | 4525 |
| 4510 @override | 4526 @override |
| 4511 bool moveNext() { | 4527 bool moveNext() { |
| 4512 if (_newSources.isEmpty) { | 4528 if (_newSources.isEmpty) { |
| 4513 return false; | 4529 return false; |
| 4514 } | 4530 } |
| 4515 currentTarget = _newSources.removeLast(); | 4531 currentTarget = _newSources.removeLast(); |
| 4516 return true; | 4532 return true; |
| 4517 } | 4533 } |
| 4518 } | 4534 } |
| OLD | NEW |