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

Side by Side Diff: pkg/analyzer/lib/src/task/dart.dart

Issue 1204373002: Initial version of limiting invalidation. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Fixes for review comments. Created 5 years, 6 months 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
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/context/cache.dart'; 10 import 'package:analyzer/src/context/cache.dart';
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
275 * 275 *
276 * The list will be empty if there were no errors, but will not be `null`. 276 * The list will be empty if there were no errors, but will not be `null`.
277 * 277 *
278 * The result is only available for [Source]s representing a compilation unit. 278 * The result is only available for [Source]s representing a compilation unit.
279 */ 279 */
280 final ListResultDescriptor<AnalysisError> PARSE_ERRORS = 280 final ListResultDescriptor<AnalysisError> PARSE_ERRORS =
281 new ListResultDescriptor<AnalysisError>( 281 new ListResultDescriptor<AnalysisError>(
282 'PARSE_ERRORS', AnalysisError.NO_ERRORS); 282 'PARSE_ERRORS', AnalysisError.NO_ERRORS);
283 283
284 /** 284 /**
285 * The names (resolved and not) referenced by a unit.
286 *
287 * The result is only available for [Source]s representing a compilation unit.
288 */
289 final ResultDescriptor<ReferencedNames> REFERENCED_NAMES =
290 new ResultDescriptor<ReferencedNames>('REFERENCED_NAMES', null);
291
292 /**
285 * The errors produced while resolving references. 293 * The errors produced while resolving references.
286 * 294 *
287 * The list will be empty if there were no errors, but will not be `null`. 295 * The list will be empty if there were no errors, but will not be `null`.
288 * 296 *
289 * The result is only available for [LibrarySpecificUnit]s. 297 * The result is only available for [LibrarySpecificUnit]s.
290 */ 298 */
291 final ListResultDescriptor<AnalysisError> RESOLVE_REFERENCES_ERRORS = 299 final ListResultDescriptor<AnalysisError> RESOLVE_REFERENCES_ERRORS =
292 new ListResultDescriptor<AnalysisError>( 300 new ListResultDescriptor<AnalysisError>(
293 'RESOLVE_REFERENCES_ERRORS', AnalysisError.NO_ERRORS); 301 'RESOLVE_REFERENCES_ERRORS', AnalysisError.NO_ERRORS);
294 302
(...skipping 1613 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 * Create a [ContainingLibrariesTask] based on the given [target] in the given 1916 * Create a [ContainingLibrariesTask] based on the given [target] in the given
1909 * [context]. 1917 * [context].
1910 */ 1918 */
1911 static ContainingLibrariesTask createTask( 1919 static ContainingLibrariesTask createTask(
1912 AnalysisContext context, AnalysisTarget target) { 1920 AnalysisContext context, AnalysisTarget target) {
1913 return new ContainingLibrariesTask(context, target); 1921 return new ContainingLibrariesTask(context, target);
1914 } 1922 }
1915 } 1923 }
1916 1924
1917 /** 1925 /**
1926 * The description for a change in a Dart source.
1927 */
1928 class DartDelta extends Delta {
1929 bool hasDirectiveChange = false;
1930
1931 final Set<String> addedNames = new Set<String>();
1932 final Set<String> changedNames = new Set<String>();
1933 final Set<String> removedNames = new Set<String>();
1934
1935 final Set<Source> invalidatedSources = new Set<Source>();
1936
1937 DartDelta(Source source) : super(source) {
1938 invalidatedSources.add(source);
1939 }
1940
1941 @override
1942 bool affects(InternalAnalysisContext context, AnalysisTarget target,
1943 ResultDescriptor descriptor) {
1944 if (hasDirectiveChange) {
1945 return true;
1946 }
1947 Source targetSource = null;
1948 if (target is Source) {
1949 targetSource = target;
1950 }
1951 if (target is LibrarySpecificUnit) {
1952 targetSource = target.library;
1953 }
1954 if (target is Element) {
1955 targetSource = target.source;
1956 }
1957 if (targetSource == source) {
1958 return true;
1959 }
1960 if (targetSource != null) {
1961 List<Source> librarySources =
1962 context.getLibrariesContaining(targetSource);
1963 for (Source librarySource in librarySources) {
1964 AnalysisCache cache = context.analysisCache;
1965 ReferencedNames referencedNames =
1966 cache.getValue(librarySource, REFERENCED_NAMES);
1967 if (referencedNames == null) {
1968 return true;
1969 }
1970 referencedNames.addChangedElements(this);
1971 if (referencedNames.isAffectedBy(this)) {
1972 return true;
1973 }
1974 }
1975 return false;
1976 }
1977 return true;
1978 }
1979
1980 void elementAdded(Element element) {
1981 addedNames.add(element.name);
1982 }
1983
1984 void elementChanged(Element element) {
1985 changedNames.add(element.name);
1986 }
1987
1988 void elementRemoved(Element element) {
1989 removedNames.add(element.name);
1990 }
1991
1992 bool isNameAffected(String name) {
1993 return addedNames.contains(name) ||
1994 changedNames.contains(name) ||
1995 removedNames.contains(name);
1996 }
1997
1998 bool nameChanged(String name) {
1999 return changedNames.add(name);
2000 }
2001 }
2002
2003 /**
1918 * A task that merges all of the errors for a single source into a single list 2004 * A task that merges all of the errors for a single source into a single list
1919 * of errors. 2005 * of errors.
1920 */ 2006 */
1921 class DartErrorsTask extends SourceBasedAnalysisTask { 2007 class DartErrorsTask extends SourceBasedAnalysisTask {
1922 /** 2008 /**
1923 * The name of the [BUILD_DIRECTIVES_ERRORS] input. 2009 * The name of the [BUILD_DIRECTIVES_ERRORS] input.
1924 */ 2010 */
1925 static const String BUILD_DIRECTIVES_ERRORS_INPUT = 'BUILD_DIRECTIVES_ERRORS'; 2011 static const String BUILD_DIRECTIVES_ERRORS_INPUT = 'BUILD_DIRECTIVES_ERRORS';
1926 2012
1927 /** 2013 /**
(...skipping 856 matching lines...) Expand 10 before | Expand all | Expand 10 after
2784 void _addPublicNames(CompilationUnitElement compilationUnit) { 2870 void _addPublicNames(CompilationUnitElement compilationUnit) {
2785 compilationUnit.accessors.forEach(_addIfPublic); 2871 compilationUnit.accessors.forEach(_addIfPublic);
2786 compilationUnit.enums.forEach(_addIfPublic); 2872 compilationUnit.enums.forEach(_addIfPublic);
2787 compilationUnit.functions.forEach(_addIfPublic); 2873 compilationUnit.functions.forEach(_addIfPublic);
2788 compilationUnit.functionTypeAliases.forEach(_addIfPublic); 2874 compilationUnit.functionTypeAliases.forEach(_addIfPublic);
2789 compilationUnit.types.forEach(_addIfPublic); 2875 compilationUnit.types.forEach(_addIfPublic);
2790 } 2876 }
2791 } 2877 }
2792 2878
2793 /** 2879 /**
2880 * Information about a library - which names it uses, which names it defines
2881 * with their externally visible dependencies.
2882 */
2883 class ReferencedNames {
2884 final Set<String> names = new Set<String>();
2885 final Map<String, Set<String>> userToDependsOn = <String, Set<String>>{};
2886
2887 /**
2888 * Updates [delta] by adding names that are changed in this library.
2889 */
2890 void addChangedElements(DartDelta delta) {
2891 bool hasProgress = true;
2892 while (hasProgress) {
2893 hasProgress = false;
2894 userToDependsOn.forEach((user, dependencies) {
2895 for (String dependency in dependencies) {
2896 if (delta.isNameAffected(dependency)) {
2897 if (delta.nameChanged(user)) {
2898 hasProgress = true;
2899 }
2900 }
2901 }
2902 });
2903 }
2904 }
2905
2906 /**
2907 * Returns `true` if the library described by this object is affected by
2908 * the given [delta].
2909 */
2910 bool isAffectedBy(DartDelta delta) {
2911 for (String name in names) {
2912 if (delta.isNameAffected(name)) {
2913 return true;
2914 }
2915 }
2916 return false;
2917 }
2918 }
2919
2920 /**
2921 * A builder for creating [ReferencedNames].
2922 *
2923 * TODO(scheglov) Record dependencies for all other top-level declarations.
2924 */
2925 class ReferencedNamesBuilder extends RecursiveAstVisitor {
2926 final ReferencedNames names;
2927 int bodyLevel = 0;
2928 Set<String> dependsOn;
2929
2930 ReferencedNamesBuilder(this.names);
2931
2932 ReferencedNames build(CompilationUnit unit) {
2933 unit.accept(this);
2934 return names;
2935 }
2936
2937 @override
2938 visitBlockFunctionBody(BlockFunctionBody node) {
2939 try {
2940 bodyLevel++;
2941 super.visitBlockFunctionBody(node);
2942 } finally {
2943 bodyLevel--;
2944 }
2945 }
2946
2947 @override
2948 visitClassDeclaration(ClassDeclaration node) {
2949 dependsOn = new Set<String>();
2950 super.visitClassDeclaration(node);
2951 names.userToDependsOn[node.name.name] = dependsOn;
2952 dependsOn = null;
2953 }
2954
2955 @override
2956 visitExpressionFunctionBody(ExpressionFunctionBody node) {
2957 try {
2958 bodyLevel++;
2959 super.visitExpressionFunctionBody(node);
2960 } finally {
2961 bodyLevel--;
2962 }
2963 }
2964
2965 @override
2966 visitSimpleIdentifier(SimpleIdentifier node) {
2967 if (!node.inDeclarationContext()) {
2968 String name = node.name;
2969 names.names.add(name);
2970 if (dependsOn != null && bodyLevel == 0) {
2971 dependsOn.add(name);
2972 }
2973 }
2974 }
2975 }
2976
2977 /**
2794 * A task that finishes resolution by requesting [RESOLVED_UNIT_NO_CONSTANTS] fo r every 2978 * A task that finishes resolution by requesting [RESOLVED_UNIT_NO_CONSTANTS] fo r every
2795 * unit in the libraries closure and produces [LIBRARY_ELEMENT]. 2979 * unit in the libraries closure and produces [LIBRARY_ELEMENT].
2796 */ 2980 */
2797 class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask { 2981 class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
2798 /** 2982 /**
2799 * The name of the [LIBRARY_ELEMENT6] input. 2983 * The name of the [LIBRARY_ELEMENT6] input.
2800 */ 2984 */
2801 static const String LIBRARY_INPUT = 'LIBRARY_INPUT'; 2985 static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
2802 2986
2803 /** 2987 /**
2988 * The name of the [RESOLVED_UNIT6] input.
2989 */
2990 static const String UNITS_INPUT = 'UNITS_INPUT';
2991
2992 /**
2804 * The task descriptor describing this kind of task. 2993 * The task descriptor describing this kind of task.
2805 */ 2994 */
2806 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor( 2995 static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
2807 'ResolveLibraryReferencesTask', createTask, buildInputs, 2996 'ResolveLibraryReferencesTask', createTask, buildInputs,
2808 <ResultDescriptor>[LIBRARY_ELEMENT]); 2997 <ResultDescriptor>[LIBRARY_ELEMENT, REFERENCED_NAMES]);
2809 2998
2810 ResolveLibraryReferencesTask( 2999 ResolveLibraryReferencesTask(
2811 InternalAnalysisContext context, AnalysisTarget target) 3000 InternalAnalysisContext context, AnalysisTarget target)
2812 : super(context, target); 3001 : super(context, target);
2813 3002
2814 @override 3003 @override
2815 TaskDescriptor get descriptor => DESCRIPTOR; 3004 TaskDescriptor get descriptor => DESCRIPTOR;
2816 3005
2817 @override 3006 @override
2818 void internalPerform() { 3007 void internalPerform() {
3008 //
3009 // Prepare inputs.
3010 //
2819 LibraryElement library = getRequiredInput(LIBRARY_INPUT); 3011 LibraryElement library = getRequiredInput(LIBRARY_INPUT);
3012 List<CompilationUnit> units = getRequiredInput(UNITS_INPUT);
3013 // Compute referenced names.
3014 ReferencedNames referencedNames = new ReferencedNames();
3015 for (CompilationUnit unit in units) {
3016 new ReferencedNamesBuilder(referencedNames).build(unit);
3017 }
3018 //
3019 // Record outputs.
3020 //
2820 outputs[LIBRARY_ELEMENT] = library; 3021 outputs[LIBRARY_ELEMENT] = library;
3022 outputs[REFERENCED_NAMES] = referencedNames;
2821 } 3023 }
2822 3024
2823 /** 3025 /**
2824 * Return a map from the names of the inputs of this kind of task to the task 3026 * Return a map from the names of the inputs of this kind of task to the task
2825 * input descriptors describing those inputs for a task with the 3027 * input descriptors describing those inputs for a task with the
2826 * given [target]. 3028 * given [target].
2827 */ 3029 */
2828 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { 3030 static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
2829 Source source = target; 3031 Source source = target;
2830 return <String, TaskInput>{ 3032 return <String, TaskInput>{
2831 LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source), 3033 LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
3034 UNITS_INPUT: UNITS.of(source).toList((Source unit) =>
3035 RESOLVED_UNIT6.of(new LibrarySpecificUnit(source, unit))),
2832 'resolvedUnits': IMPORT_EXPORT_SOURCE_CLOSURE 3036 'resolvedUnits': IMPORT_EXPORT_SOURCE_CLOSURE
2833 .of(source) 3037 .of(source)
2834 .toMapOf(UNITS) 3038 .toMapOf(UNITS)
2835 .toFlattenList((Source library, Source unit) => 3039 .toFlattenList((Source library, Source unit) =>
2836 RESOLVED_UNIT6.of(new LibrarySpecificUnit(library, unit))), 3040 RESOLVED_UNIT6.of(new LibrarySpecificUnit(library, unit))),
2837 }; 3041 };
2838 } 3042 }
2839 3043
2840 /** 3044 /**
2841 * Create a [ResolveLibraryReferencesTask] based on the given [target] in 3045 * Create a [ResolveLibraryReferencesTask] based on the given [target] in
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
3050 3254
3051 /** 3255 /**
3052 * Return a map from the names of the inputs of this kind of task to the task 3256 * Return a map from the names of the inputs of this kind of task to the task
3053 * input descriptors describing those inputs for a task with the 3257 * input descriptors describing those inputs for a task with the
3054 * given [target]. 3258 * given [target].
3055 */ 3259 */
3056 static Map<String, TaskInput> buildInputs(AnalysisTarget target) { 3260 static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
3057 LibrarySpecificUnit unit = target; 3261 LibrarySpecificUnit unit = target;
3058 return <String, TaskInput>{ 3262 return <String, TaskInput>{
3059 'importsExportNamespace': 3263 'importsExportNamespace':
3060 IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4), 3264 IMPORTED_LIBRARIES.of(unit.library).toMapOf(LIBRARY_ELEMENT4),
3061 LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library), 3265 LIBRARY_INPUT: LIBRARY_ELEMENT4.of(unit.library),
3062 UNIT_INPUT: RESOLVED_UNIT2.of(unit), 3266 UNIT_INPUT: RESOLVED_UNIT2.of(unit),
3063 TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request) 3267 TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request)
3064 }; 3268 };
3065 } 3269 }
3066 3270
3067 /** 3271 /**
3068 * Create a [ResolveUnitTypeNamesTask] based on the given [target] in 3272 * Create a [ResolveUnitTypeNamesTask] based on the given [target] in
3069 * the given [context]. 3273 * the given [context].
3070 */ 3274 */
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
3485 3689
3486 @override 3690 @override
3487 bool moveNext() { 3691 bool moveNext() {
3488 if (_newSources.isEmpty) { 3692 if (_newSources.isEmpty) {
3489 return false; 3693 return false;
3490 } 3694 }
3491 currentTarget = _newSources.removeLast(); 3695 currentTarget = _newSources.removeLast();
3492 return true; 3696 return true;
3493 } 3697 }
3494 } 3698 }
OLDNEW
« no previous file with comments | « pkg/analyzer/lib/src/generated/engine.dart ('k') | pkg/analyzer/lib/src/task/incremental_element_builder.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698