| 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 import 'dart:math' as math; | 8 import 'dart:math' as math; |
| 9 | 9 |
| 10 import 'package:analyzer/src/generated/ast.dart'; | 10 import 'package:analyzer/src/generated/ast.dart'; |
| 11 import 'package:analyzer/src/generated/element.dart'; | 11 import 'package:analyzer/src/generated/element.dart'; |
| 12 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask; | 12 import 'package:analyzer/src/generated/engine.dart' hide AnalysisTask; |
| 13 import 'package:analyzer/src/generated/error.dart'; | 13 import 'package:analyzer/src/generated/error.dart'; |
| 14 import 'package:analyzer/src/generated/error_verifier.dart'; | 14 import 'package:analyzer/src/generated/error_verifier.dart'; |
| 15 import 'package:analyzer/src/generated/java_engine.dart'; | 15 import 'package:analyzer/src/generated/java_engine.dart'; |
| 16 import 'package:analyzer/src/generated/parser.dart'; | 16 import 'package:analyzer/src/generated/parser.dart'; |
| 17 import 'package:analyzer/src/generated/resolver.dart'; | 17 import 'package:analyzer/src/generated/resolver.dart'; |
| 18 import 'package:analyzer/src/generated/scanner.dart'; | 18 import 'package:analyzer/src/generated/scanner.dart'; |
| 19 import 'package:analyzer/src/generated/sdk.dart'; | 19 import 'package:analyzer/src/generated/sdk.dart'; |
| 20 import 'package:analyzer/src/generated/source.dart'; | 20 import 'package:analyzer/src/generated/source.dart'; |
| 21 import 'package:analyzer/src/task/general.dart'; | 21 import 'package:analyzer/src/task/general.dart'; |
| 22 import 'package:analyzer/src/task/incremental_element_builder.dart'; | |
| 23 import 'package:analyzer/src/task/model.dart'; | 22 import 'package:analyzer/src/task/model.dart'; |
| 24 import 'package:analyzer/task/dart.dart'; | 23 import 'package:analyzer/task/dart.dart'; |
| 25 import 'package:analyzer/task/general.dart'; | 24 import 'package:analyzer/task/general.dart'; |
| 26 import 'package:analyzer/task/model.dart'; | 25 import 'package:analyzer/task/model.dart'; |
| 27 | 26 |
| 28 /** | 27 /** |
| 29 * The [ResultCachingPolicy] for ASTs. | 28 * The [ResultCachingPolicy] for ASTs. |
| 30 */ | 29 */ |
| 31 const ResultCachingPolicy AST_CACHING_POLICY = | 30 const ResultCachingPolicy AST_CACHING_POLICY = |
| 32 const SimpleResultCachingPolicy(256, 64); | 31 const SimpleResultCachingPolicy(256, 64); |
| (...skipping 534 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 } | 566 } |
| 568 for (int i = argumentCount; i < parameterCount; i++) { | 567 for (int i = argumentCount; i < parameterCount; i++) { |
| 569 types[i] = dynamic; | 568 types[i] = dynamic; |
| 570 } | 569 } |
| 571 } | 570 } |
| 572 return types; | 571 return types; |
| 573 } | 572 } |
| 574 } | 573 } |
| 575 | 574 |
| 576 /** | 575 /** |
| 577 * The memento for [BuildCompilationUnitElementTask]. | |
| 578 */ | |
| 579 class BuildCompilationUnitElementMemento { | |
| 580 final List<ClassElement> classElements; | |
| 581 final CompilationUnit unit; | |
| 582 final CompilationUnitElement unitElement; | |
| 583 BuildCompilationUnitElementMemento( | |
| 584 this.classElements, this.unit, this.unitElement); | |
| 585 } | |
| 586 | |
| 587 /** | |
| 588 * A task that builds a compilation unit element for a single compilation unit. | 576 * A task that builds a compilation unit element for a single compilation unit. |
| 589 */ | 577 */ |
| 590 class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask { | 578 class BuildCompilationUnitElementTask extends SourceBasedAnalysisTask { |
| 591 /** | 579 /** |
| 592 * The name of the input whose value is the AST for the compilation unit. | 580 * The name of the input whose value is the AST for the compilation unit. |
| 593 */ | 581 */ |
| 594 static const String PARSED_UNIT_INPUT_NAME = 'PARSED_UNIT_INPUT_NAME'; | 582 static const String PARSED_UNIT_INPUT_NAME = 'PARSED_UNIT_INPUT_NAME'; |
| 595 | 583 |
| 596 /** | 584 /** |
| 597 * The task descriptor describing this kind of task. | 585 * The task descriptor describing this kind of task. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 616 TaskDescriptor get descriptor => DESCRIPTOR; | 604 TaskDescriptor get descriptor => DESCRIPTOR; |
| 617 | 605 |
| 618 @override | 606 @override |
| 619 void internalPerform() { | 607 void internalPerform() { |
| 620 // | 608 // |
| 621 // Prepare inputs. | 609 // Prepare inputs. |
| 622 // | 610 // |
| 623 Source source = getRequiredSource(); | 611 Source source = getRequiredSource(); |
| 624 CompilationUnit unit = getRequiredInput(PARSED_UNIT_INPUT_NAME); | 612 CompilationUnit unit = getRequiredInput(PARSED_UNIT_INPUT_NAME); |
| 625 // | 613 // |
| 626 // Use memento. | |
| 627 // | |
| 628 if (inputMemento is BuildCompilationUnitElementMemento) { | |
| 629 BuildCompilationUnitElementMemento memento = inputMemento; | |
| 630 unit = AstCloner.clone(unit); | |
| 631 new IncrementalCompilationUnitElementBuilder(memento.unit, unit).build(); | |
| 632 CompilationUnitElement element = unit.element; | |
| 633 outputs[CLASS_ELEMENTS] = element.types; | |
| 634 outputs[COMPILATION_UNIT_ELEMENT] = element; | |
| 635 outputs[RESOLVED_UNIT1] = unit; | |
| 636 outputMemento = | |
| 637 new BuildCompilationUnitElementMemento(element.types, unit, element); | |
| 638 return; | |
| 639 } | |
| 640 // | |
| 641 // Process inputs. | 614 // Process inputs. |
| 642 // | 615 // |
| 643 unit = AstCloner.clone(unit); | 616 unit = AstCloner.clone(unit); |
| 644 CompilationUnitBuilder builder = new CompilationUnitBuilder(); | 617 CompilationUnitBuilder builder = new CompilationUnitBuilder(); |
| 645 CompilationUnitElement element = builder.buildCompilationUnit(source, unit); | 618 CompilationUnitElement element = builder.buildCompilationUnit(source, unit); |
| 646 // | 619 // |
| 647 // Record outputs. | 620 // Record outputs. |
| 648 // | 621 // |
| 649 outputs[CLASS_ELEMENTS] = element.types; | 622 outputs[CLASS_ELEMENTS] = element.types; |
| 650 outputs[COMPILATION_UNIT_ELEMENT] = element; | 623 outputs[COMPILATION_UNIT_ELEMENT] = element; |
| 651 outputs[RESOLVED_UNIT1] = unit; | 624 outputs[RESOLVED_UNIT1] = unit; |
| 652 outputMemento = | |
| 653 new BuildCompilationUnitElementMemento(element.types, unit, element); | |
| 654 } | 625 } |
| 655 | 626 |
| 656 /** | 627 /** |
| 657 * Return a map from the names of the inputs of this kind of task to the task | 628 * Return a map from the names of the inputs of this kind of task to the task |
| 658 * input descriptors describing those inputs for a task with the given | 629 * input descriptors describing those inputs for a task with the given |
| 659 * [target]. | 630 * [target]. |
| 660 */ | 631 */ |
| 661 static Map<String, TaskInput> buildInputs(LibrarySpecificUnit target) { | 632 static Map<String, TaskInput> buildInputs(LibrarySpecificUnit target) { |
| 662 return <String, TaskInput>{ | 633 return <String, TaskInput>{ |
| 663 PARSED_UNIT_INPUT_NAME: PARSED_UNIT.of(target.unit) | 634 PARSED_UNIT_INPUT_NAME: PARSED_UNIT.of(target.unit) |
| (...skipping 1532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2196 * Create a [LibraryUnitErrorsTask] based on the given [target] in the given | 2167 * Create a [LibraryUnitErrorsTask] based on the given [target] in the given |
| 2197 * [context]. | 2168 * [context]. |
| 2198 */ | 2169 */ |
| 2199 static LibraryUnitErrorsTask createTask( | 2170 static LibraryUnitErrorsTask createTask( |
| 2200 AnalysisContext context, AnalysisTarget target) { | 2171 AnalysisContext context, AnalysisTarget target) { |
| 2201 return new LibraryUnitErrorsTask(context, target); | 2172 return new LibraryUnitErrorsTask(context, target); |
| 2202 } | 2173 } |
| 2203 } | 2174 } |
| 2204 | 2175 |
| 2205 /** | 2176 /** |
| 2206 * The memento for [ParseDartTask]. | |
| 2207 */ | |
| 2208 class ParseDartMemento { | |
| 2209 final Token inputTokenStream; | |
| 2210 final List<Source> explicitlyImportedLibraries; | |
| 2211 final List<Source> exportedLibraries; | |
| 2212 final List<Source> importedLibraries; | |
| 2213 final List<Source> includedParts; | |
| 2214 final List<AnalysisError> parseErrors; | |
| 2215 final CompilationUnit parsedUnit; | |
| 2216 final SourceKind sourceKind; | |
| 2217 final List<Source> units; | |
| 2218 ParseDartMemento(this.inputTokenStream, this.explicitlyImportedLibraries, | |
| 2219 this.exportedLibraries, this.importedLibraries, this.includedParts, | |
| 2220 this.parseErrors, this.parsedUnit, this.sourceKind, this.units); | |
| 2221 } | |
| 2222 | |
| 2223 /** | |
| 2224 * A task that parses the content of a Dart file, producing an AST structure. | 2177 * A task that parses the content of a Dart file, producing an AST structure. |
| 2225 */ | 2178 */ |
| 2226 class ParseDartTask extends SourceBasedAnalysisTask { | 2179 class ParseDartTask extends SourceBasedAnalysisTask { |
| 2227 /** | 2180 /** |
| 2228 * The name of the input whose value is the line information produced for the | 2181 * The name of the input whose value is the line information produced for the |
| 2229 * file. | 2182 * file. |
| 2230 */ | 2183 */ |
| 2231 static const String LINE_INFO_INPUT_NAME = 'LINE_INFO_INPUT_NAME'; | 2184 static const String LINE_INFO_INPUT_NAME = 'LINE_INFO_INPUT_NAME'; |
| 2232 | 2185 |
| 2233 /** | 2186 /** |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2259 | 2212 |
| 2260 @override | 2213 @override |
| 2261 TaskDescriptor get descriptor => DESCRIPTOR; | 2214 TaskDescriptor get descriptor => DESCRIPTOR; |
| 2262 | 2215 |
| 2263 @override | 2216 @override |
| 2264 void internalPerform() { | 2217 void internalPerform() { |
| 2265 Source source = getRequiredSource(); | 2218 Source source = getRequiredSource(); |
| 2266 LineInfo lineInfo = getRequiredInput(LINE_INFO_INPUT_NAME); | 2219 LineInfo lineInfo = getRequiredInput(LINE_INFO_INPUT_NAME); |
| 2267 Token tokenStream = getRequiredInput(TOKEN_STREAM_INPUT_NAME); | 2220 Token tokenStream = getRequiredInput(TOKEN_STREAM_INPUT_NAME); |
| 2268 | 2221 |
| 2269 if (inputMemento is ParseDartMemento) { | |
| 2270 ParseDartMemento memento = inputMemento; | |
| 2271 if (identical(memento.inputTokenStream, tokenStream)) { | |
| 2272 outputMemento = memento; | |
| 2273 outputs[EXPLICITLY_IMPORTED_LIBRARIES] = | |
| 2274 memento.explicitlyImportedLibraries; | |
| 2275 outputs[EXPORTED_LIBRARIES] = memento.exportedLibraries; | |
| 2276 outputs[IMPORTED_LIBRARIES] = memento.importedLibraries; | |
| 2277 outputs[INCLUDED_PARTS] = memento.includedParts; | |
| 2278 outputs[PARSE_ERRORS] = memento.parseErrors; | |
| 2279 outputs[PARSED_UNIT] = memento.parsedUnit; | |
| 2280 outputs[SOURCE_KIND] = memento.sourceKind; | |
| 2281 outputs[UNITS] = memento.units; | |
| 2282 return; | |
| 2283 } | |
| 2284 } | |
| 2285 | |
| 2286 RecordingErrorListener errorListener = new RecordingErrorListener(); | 2222 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 2287 Parser parser = new Parser(source, errorListener); | 2223 Parser parser = new Parser(source, errorListener); |
| 2288 AnalysisOptions options = context.analysisOptions; | 2224 AnalysisOptions options = context.analysisOptions; |
| 2289 parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source); | 2225 parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source); |
| 2290 CompilationUnit unit = parser.parseCompilationUnit(tokenStream); | 2226 CompilationUnit unit = parser.parseCompilationUnit(tokenStream); |
| 2291 unit.lineInfo = lineInfo; | 2227 unit.lineInfo = lineInfo; |
| 2292 | 2228 |
| 2293 bool hasNonPartOfDirective = false; | 2229 bool hasNonPartOfDirective = false; |
| 2294 bool hasPartOfDirective = false; | 2230 bool hasPartOfDirective = false; |
| 2295 HashSet<Source> explicitlyImportedSourceSet = new HashSet<Source>(); | 2231 HashSet<Source> explicitlyImportedSourceSet = new HashSet<Source>(); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2345 List<AnalysisError> parseErrors = errorListener.errors; | 2281 List<AnalysisError> parseErrors = errorListener.errors; |
| 2346 List<Source> unitSources = <Source>[source]..addAll(includedSourceSet); | 2282 List<Source> unitSources = <Source>[source]..addAll(includedSourceSet); |
| 2347 outputs[EXPLICITLY_IMPORTED_LIBRARIES] = explicitlyImportedSources; | 2283 outputs[EXPLICITLY_IMPORTED_LIBRARIES] = explicitlyImportedSources; |
| 2348 outputs[EXPORTED_LIBRARIES] = exportedSources; | 2284 outputs[EXPORTED_LIBRARIES] = exportedSources; |
| 2349 outputs[IMPORTED_LIBRARIES] = importedSources; | 2285 outputs[IMPORTED_LIBRARIES] = importedSources; |
| 2350 outputs[INCLUDED_PARTS] = includedSources; | 2286 outputs[INCLUDED_PARTS] = includedSources; |
| 2351 outputs[PARSE_ERRORS] = parseErrors; | 2287 outputs[PARSE_ERRORS] = parseErrors; |
| 2352 outputs[PARSED_UNIT] = unit; | 2288 outputs[PARSED_UNIT] = unit; |
| 2353 outputs[SOURCE_KIND] = sourceKind; | 2289 outputs[SOURCE_KIND] = sourceKind; |
| 2354 outputs[UNITS] = unitSources; | 2290 outputs[UNITS] = unitSources; |
| 2355 outputMemento = new ParseDartMemento(tokenStream, explicitlyImportedSources, | |
| 2356 exportedSources, importedSources, includedSources, parseErrors, unit, | |
| 2357 sourceKind, unitSources); | |
| 2358 } | 2291 } |
| 2359 | 2292 |
| 2360 /** | 2293 /** |
| 2361 * Return a map from the names of the inputs of this kind of task to the task | 2294 * Return a map from the names of the inputs of this kind of task to the task |
| 2362 * input descriptors describing those inputs for a task with the given | 2295 * input descriptors describing those inputs for a task with the given |
| 2363 * [source]. | 2296 * [source]. |
| 2364 */ | 2297 */ |
| 2365 static Map<String, TaskInput> buildInputs(Source source) { | 2298 static Map<String, TaskInput> buildInputs(Source source) { |
| 2366 return <String, TaskInput>{ | 2299 return <String, TaskInput>{ |
| 2367 LINE_INFO_INPUT_NAME: LINE_INFO.of(source), | 2300 LINE_INFO_INPUT_NAME: LINE_INFO.of(source), |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2724 * Create a [ResolveVariableReferencesTask] based on the given [target] in | 2657 * Create a [ResolveVariableReferencesTask] based on the given [target] in |
| 2725 * the given [context]. | 2658 * the given [context]. |
| 2726 */ | 2659 */ |
| 2727 static ResolveVariableReferencesTask createTask( | 2660 static ResolveVariableReferencesTask createTask( |
| 2728 AnalysisContext context, AnalysisTarget target) { | 2661 AnalysisContext context, AnalysisTarget target) { |
| 2729 return new ResolveVariableReferencesTask(context, target); | 2662 return new ResolveVariableReferencesTask(context, target); |
| 2730 } | 2663 } |
| 2731 } | 2664 } |
| 2732 | 2665 |
| 2733 /** | 2666 /** |
| 2734 * The memento for [ScanDartTask]. | |
| 2735 */ | |
| 2736 class ScanDartMemento { | |
| 2737 final String content; | |
| 2738 final Token tokenStream; | |
| 2739 final LineInfo lineInfo; | |
| 2740 final List<AnalysisError> errors; | |
| 2741 ScanDartMemento(this.content, this.tokenStream, this.lineInfo, this.errors); | |
| 2742 } | |
| 2743 | |
| 2744 /** | |
| 2745 * A task that scans the content of a file, producing a set of Dart tokens. | 2667 * A task that scans the content of a file, producing a set of Dart tokens. |
| 2746 */ | 2668 */ |
| 2747 class ScanDartTask extends SourceBasedAnalysisTask { | 2669 class ScanDartTask extends SourceBasedAnalysisTask { |
| 2748 /** | 2670 /** |
| 2749 * The name of the input whose value is the content of the file. | 2671 * The name of the input whose value is the content of the file. |
| 2750 */ | 2672 */ |
| 2751 static const String CONTENT_INPUT_NAME = 'CONTENT_INPUT_NAME'; | 2673 static const String CONTENT_INPUT_NAME = 'CONTENT_INPUT_NAME'; |
| 2752 | 2674 |
| 2753 /** | 2675 /** |
| 2754 * The task descriptor describing this kind of task. | 2676 * The task descriptor describing this kind of task. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2768 : super(context, target); | 2690 : super(context, target); |
| 2769 | 2691 |
| 2770 @override | 2692 @override |
| 2771 TaskDescriptor get descriptor => DESCRIPTOR; | 2693 TaskDescriptor get descriptor => DESCRIPTOR; |
| 2772 | 2694 |
| 2773 @override | 2695 @override |
| 2774 void internalPerform() { | 2696 void internalPerform() { |
| 2775 Source source = getRequiredSource(); | 2697 Source source = getRequiredSource(); |
| 2776 String content = getRequiredInput(CONTENT_INPUT_NAME); | 2698 String content = getRequiredInput(CONTENT_INPUT_NAME); |
| 2777 | 2699 |
| 2778 if (inputMemento is ScanDartMemento) { | |
| 2779 ScanDartMemento memento = inputMemento; | |
| 2780 if (memento.content == content) { | |
| 2781 outputMemento = memento; | |
| 2782 outputs[TOKEN_STREAM] = memento.tokenStream; | |
| 2783 outputs[LINE_INFO] = memento.lineInfo; | |
| 2784 outputs[SCAN_ERRORS] = memento.errors; | |
| 2785 return; | |
| 2786 } | |
| 2787 } | |
| 2788 | |
| 2789 RecordingErrorListener errorListener = new RecordingErrorListener(); | 2700 RecordingErrorListener errorListener = new RecordingErrorListener(); |
| 2790 Scanner scanner = | 2701 Scanner scanner = |
| 2791 new Scanner(source, new CharSequenceReader(content), errorListener); | 2702 new Scanner(source, new CharSequenceReader(content), errorListener); |
| 2792 scanner.preserveComments = context.analysisOptions.preserveComments; | 2703 scanner.preserveComments = context.analysisOptions.preserveComments; |
| 2793 scanner.enableNullAwareOperators = | 2704 scanner.enableNullAwareOperators = |
| 2794 context.analysisOptions.enableNullAwareOperators; | 2705 context.analysisOptions.enableNullAwareOperators; |
| 2795 | 2706 |
| 2796 Token tokenStream = scanner.tokenize(); | 2707 Token tokenStream = scanner.tokenize(); |
| 2797 LineInfo lineInfo = new LineInfo(scanner.lineStarts); | 2708 LineInfo lineInfo = new LineInfo(scanner.lineStarts); |
| 2798 List<AnalysisError> errors = errorListener.errors; | 2709 List<AnalysisError> errors = errorListener.errors; |
| 2799 outputs[TOKEN_STREAM] = tokenStream; | 2710 outputs[TOKEN_STREAM] = tokenStream; |
| 2800 outputs[LINE_INFO] = lineInfo; | 2711 outputs[LINE_INFO] = lineInfo; |
| 2801 outputs[SCAN_ERRORS] = errors; | 2712 outputs[SCAN_ERRORS] = errors; |
| 2802 outputMemento = new ScanDartMemento(content, tokenStream, lineInfo, errors); | |
| 2803 } | 2713 } |
| 2804 | 2714 |
| 2805 /** | 2715 /** |
| 2806 * Return a map from the names of the inputs of this kind of task to the task | 2716 * Return a map from the names of the inputs of this kind of task to the task |
| 2807 * input descriptors describing those inputs for a task with the given | 2717 * input descriptors describing those inputs for a task with the given |
| 2808 * [source]. | 2718 * [source]. |
| 2809 */ | 2719 */ |
| 2810 static Map<String, TaskInput> buildInputs(Source source) { | 2720 static Map<String, TaskInput> buildInputs(Source source) { |
| 2811 return <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)}; | 2721 return <String, TaskInput>{CONTENT_INPUT_NAME: CONTENT.of(source)}; |
| 2812 } | 2722 } |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2982 @override | 2892 @override |
| 2983 bool moveNext() { | 2893 bool moveNext() { |
| 2984 if (_newSources.isEmpty) { | 2894 if (_newSources.isEmpty) { |
| 2985 return false; | 2895 return false; |
| 2986 } | 2896 } |
| 2987 currentTarget = _newSources.first; | 2897 currentTarget = _newSources.first; |
| 2988 _newSources.remove(currentTarget); | 2898 _newSources.remove(currentTarget); |
| 2989 return true; | 2899 return true; |
| 2990 } | 2900 } |
| 2991 } | 2901 } |
| OLD | NEW |