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

Side by Side Diff: pkg/analysis_server/lib/src/context_manager.dart

Issue 1277063002: In analysis server, favor package root setting over ".packages" file. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 4 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
« no previous file with comments | « no previous file | pkg/analysis_server/test/context_manager_test.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2014, 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 context.directory.manager; 5 library context.directory.manager;
6 6
7 import 'dart:async'; 7 import 'dart:async';
8 import 'dart:collection'; 8 import 'dart:collection';
9 import 'dart:convert'; 9 import 'dart:convert';
10 import 'dart:core' hide Resource; 10 import 'dart:core' hide Resource;
(...skipping 712 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 /** 723 /**
724 * Compute the appropriate [FolderDisposition] for [folder]. Use 724 * Compute the appropriate [FolderDisposition] for [folder]. Use
725 * [addDependency] to indicate which files needed to be consulted in order to 725 * [addDependency] to indicate which files needed to be consulted in order to
726 * figure out the [FolderDisposition]; these dependencies will be watched in 726 * figure out the [FolderDisposition]; these dependencies will be watched in
727 * order to determine when it is necessary to call this function again. 727 * order to determine when it is necessary to call this function again.
728 * 728 *
729 * TODO(paulberry): use [addDependency] for tracking all folder disposition 729 * TODO(paulberry): use [addDependency] for tracking all folder disposition
730 * dependencies (currently we only use it to track "pub list" dependencies). 730 * dependencies (currently we only use it to track "pub list" dependencies).
731 */ 731 */
732 FolderDisposition _computeFolderDisposition( 732 FolderDisposition _computeFolderDisposition(
733 Folder folder, void addDependency(String path)) { 733 Folder folder, void addDependency(String path), File packagespecFile) {
734 String packageRoot = normalizedPackageRoots[folder.path]; 734 String packageRoot = normalizedPackageRoots[folder.path];
735 if (packageRoot != null) { 735 if (packageRoot != null) {
736 // TODO(paulberry): We shouldn't be using JavaFile here because it 736 // TODO(paulberry): We shouldn't be using JavaFile here because it
737 // makes the code untestable (see dartbug.com/23909). 737 // makes the code untestable (see dartbug.com/23909).
738 JavaFile packagesDir = new JavaFile(packageRoot); 738 JavaFile packagesDir = new JavaFile(packageRoot);
739 Map<String, List<Folder>> packageMap = new Map<String, List<Folder>>(); 739 Map<String, List<Folder>> packageMap = new Map<String, List<Folder>>();
740 if (packagesDir.isDirectory()) { 740 if (packagesDir.isDirectory()) {
741 for (JavaFile file in packagesDir.listFiles()) { 741 for (JavaFile file in packagesDir.listFiles()) {
742 // Ensure symlinks in packages directory are canonicalized 742 // Ensure symlinks in packages directory are canonicalized
743 // to prevent 'type X cannot be assigned to type X' warnings 743 // to prevent 'type X cannot be assigned to type X' warnings
(...skipping 12 matching lines...) Expand all
756 } 756 }
757 return new PackageMapDisposition(packageMap, packageRoot: packageRoot); 757 return new PackageMapDisposition(packageMap, packageRoot: packageRoot);
758 } 758 }
759 // The package root does not exist (or is not a folder). Since 759 // The package root does not exist (or is not a folder). Since
760 // [setRoots] ignores any package roots that don't exist (or aren't 760 // [setRoots] ignores any package roots that don't exist (or aren't
761 // folders), the only way we should be able to get here is due to a race 761 // folders), the only way we should be able to get here is due to a race
762 // condition. In any case, the package root folder is gone, so we can't 762 // condition. In any case, the package root folder is gone, so we can't
763 // resolve packages. 763 // resolve packages.
764 return new NoPackageFolderDisposition(packageRoot: packageRoot); 764 return new NoPackageFolderDisposition(packageRoot: packageRoot);
765 } else { 765 } else {
766 PackageMapInfo packageMapInfo;
766 callbacks.beginComputePackageMap(); 767 callbacks.beginComputePackageMap();
767 if (packageResolverProvider != null) { 768 try {
768 UriResolver resolver = packageResolverProvider(folder); 769 if (ENABLE_PACKAGESPEC_SUPPORT) {
769 if (resolver != null) { 770 // Try .packages first.
770 return new CustomPackageResolverDisposition(resolver); 771 if (pathos.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
772 Packages packages = _readPackagespec(packagespecFile);
773 return new PackagesFileDisposition(packages);
774 }
771 } 775 }
776 if (packageResolverProvider != null) {
777 UriResolver resolver = packageResolverProvider(folder);
778 if (resolver != null) {
779 return new CustomPackageResolverDisposition(resolver);
780 }
781 }
782 ServerPerformanceStatistics.pub.makeCurrentWhile(() {
783 packageMapInfo = _packageMapProvider.computePackageMap(folder);
784 });
785 } finally {
786 callbacks.endComputePackageMap();
772 } 787 }
773 PackageMapInfo packageMapInfo;
774 ServerPerformanceStatistics.pub.makeCurrentWhile(() {
775 packageMapInfo = _packageMapProvider.computePackageMap(folder);
776 });
777 callbacks.endComputePackageMap();
778 for (String dependencyPath in packageMapInfo.dependencies) { 788 for (String dependencyPath in packageMapInfo.dependencies) {
779 addDependency(dependencyPath); 789 addDependency(dependencyPath);
780 } 790 }
781 if (packageMapInfo.packageMap == null) { 791 if (packageMapInfo.packageMap == null) {
782 return new NoPackageFolderDisposition(); 792 return new NoPackageFolderDisposition();
783 } 793 }
784 return new PackageMapDisposition(packageMapInfo.packageMap); 794 return new PackageMapDisposition(packageMapInfo.packageMap);
785 } 795 }
786 } 796 }
787 797
788 /** 798 /**
789 * Create a new empty context associated with [folder], having parent 799 * Create a new empty context associated with [folder], having parent
790 * [parent] and using [packagespecFile] to resolve package URI's. 800 * [parent] and using [packagespecFile] to resolve package URI's.
791 */ 801 */
792 ContextInfo _createContext( 802 ContextInfo _createContext(
793 ContextInfo parent, Folder folder, File packagespecFile) { 803 ContextInfo parent, Folder folder, File packagespecFile) {
794 ContextInfo info = new ContextInfo(this, parent, folder, packagespecFile, 804 ContextInfo info = new ContextInfo(this, parent, folder, packagespecFile,
795 normalizedPackageRoots[folder.path]); 805 normalizedPackageRoots[folder.path]);
796 Map<String, YamlNode> options = analysisOptionsProvider.getOptions(folder); 806 Map<String, YamlNode> options = analysisOptionsProvider.getOptions(folder);
797 processOptionsForContext(info, options); 807 processOptionsForContext(info, options);
798 FolderDisposition disposition; 808 FolderDisposition disposition;
799 List<String> dependencies = <String>[]; 809 List<String> dependencies = <String>[];
800 810
801 if (ENABLE_PACKAGESPEC_SUPPORT) {
802 // Try .packages first.
803 if (pathos.basename(packagespecFile.path) == PACKAGE_SPEC_NAME) {
804 Packages packages = _readPackagespec(packagespecFile);
805 disposition = new PackagesFileDisposition(packages);
806 }
807 }
808
809 // Next resort to a package uri resolver. 811 // Next resort to a package uri resolver.
810 if (disposition == null) { 812 if (disposition == null) {
811 disposition = _computeFolderDisposition(folder, dependencies.add); 813 disposition =
814 _computeFolderDisposition(folder, dependencies.add, packagespecFile);
812 } 815 }
813 816
814 info.setDependencies(dependencies); 817 info.setDependencies(dependencies);
815 info.context = callbacks.addContext(folder, disposition); 818 info.context = callbacks.addContext(folder, disposition);
816 info.context.name = folder.path; 819 info.context.name = folder.path;
817 return info; 820 return info;
818 } 821 }
819 822
820 /** 823 /**
821 * Potentially create a new context associated with the given [folder]. 824 * Potentially create a new context associated with the given [folder].
822 * 825 *
823 * If there are subfolders with 'pubspec.yaml' files, separate contexts are 826 * If there are subfolders with 'pubspec.yaml' files, separate contexts are
824 * created for them and excluded from the context associated with the 827 * created for them and excluded from the context associated with the
825 * [folder]. 828 * [folder].
826 * 829 *
827 * If [withPackageSpecOnly] is `true`, a context will be created only if there 830 * If [withPackageSpecOnly] is `true`, a context will be created only if there
828 * is a 'pubspec.yaml' or '.packages' file in the [folder]. 831 * is a 'pubspec.yaml' or '.packages' file in the [folder].
829 * 832 *
830 * [parent] should be the parent of any contexts that are created. 833 * [parent] should be the parent of any contexts that are created.
831 */ 834 */
832 void _createContexts( 835 void _createContexts(
833 ContextInfo parent, Folder folder, bool withPackageSpecOnly) { 836 ContextInfo parent, Folder folder, bool withPackageSpecOnly) {
834 // Decide whether a context needs to be created for [folder] here, and if 837 // Decide whether a context needs to be created for [folder] here, and if
835 // so, create it. 838 // so, create it.
836 File packageSpec; 839 File packageSpec = _findPackageSpecFile(folder);
837
838 if (ENABLE_PACKAGESPEC_SUPPORT) {
839 // Start by looking for .packages.
840 packageSpec = folder.getChild(PACKAGE_SPEC_NAME);
841 }
842
843 // Fall back to looking for a pubspec.
844 if (packageSpec == null || !packageSpec.exists) {
845 packageSpec = folder.getChild(PUBSPEC_NAME);
846 }
847
848 bool createContext = packageSpec.exists || !withPackageSpecOnly; 840 bool createContext = packageSpec.exists || !withPackageSpecOnly;
849 if (withPackageSpecOnly && 841 if (withPackageSpecOnly &&
850 packageSpec.exists && 842 packageSpec.exists &&
851 (parent != null) && 843 (parent != null) &&
852 parent.ignored(packageSpec.path)) { 844 parent.ignored(packageSpec.path)) {
853 // Don't create a context if the package spec is required and ignored. 845 // Don't create a context if the package spec is required and ignored.
854 createContext = false; 846 createContext = false;
855 } 847 }
856 if (createContext) { 848 if (createContext) {
857 parent = _createContext(parent, folder, packageSpec); 849 parent = _createContext(parent, folder, packageSpec);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 changeSet.removedSource(source); 914 changeSet.removedSource(source);
923 }); 915 });
924 callbacks.applyChangesToContext(oldInfo.folder, changeSet); 916 callbacks.applyChangesToContext(oldInfo.folder, changeSet);
925 } 917 }
926 // TODO(paulberry): every context that was previously a child of oldInfo is 918 // TODO(paulberry): every context that was previously a child of oldInfo is
927 // is still a child of oldInfo. This is wrong--some of them ought to be 919 // is still a child of oldInfo. This is wrong--some of them ought to be
928 // adopted by newInfo now. 920 // adopted by newInfo now.
929 } 921 }
930 922
931 /** 923 /**
924 * Find the file that should be used to determine whether a context needs to
925 * be created here--this is either the ".packages" file or the "pubspec.yaml"
926 * file.
927 */
928 File _findPackageSpecFile(Folder folder) {
929 // Decide whether a context needs to be created for [folder] here, and if
930 // so, create it.
931 File packageSpec;
932
933 if (ENABLE_PACKAGESPEC_SUPPORT) {
934 // Start by looking for .packages.
935 packageSpec = folder.getChild(PACKAGE_SPEC_NAME);
936 }
937
938 // Fall back to looking for a pubspec.
939 if (packageSpec == null || !packageSpec.exists) {
940 packageSpec = folder.getChild(PUBSPEC_NAME);
941 }
942 return packageSpec;
943 }
944
945 /**
932 * Return the [ContextInfo] for the "innermost" context whose associated 946 * Return the [ContextInfo] for the "innermost" context whose associated
933 * folder is or contains the given path. ("innermost" refers to the nesting 947 * folder is or contains the given path. ("innermost" refers to the nesting
934 * of contexts, so if there is a context for path /foo and a context for 948 * of contexts, so if there is a context for path /foo and a context for
935 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is 949 * path /foo/bar, then the innermost context containing /foo/bar/baz.dart is
936 * the context for /foo/bar.) 950 * the context for /foo/bar.)
937 * 951 *
938 * If no context contains the given path, `null` is returned. 952 * If no context contains the given path, `null` is returned.
939 */ 953 */
940 ContextInfo _getInnermostContextInfoFor(String path) { 954 ContextInfo _getInnermostContextInfoFor(String path) {
941 ContextInfo info = _rootInfo.findChildInfoFor(path); 955 ContextInfo info = _rootInfo.findChildInfoFor(path);
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 /** 1189 /**
1176 * Recompute the [FolderDisposition] for the context described by [info], 1190 * Recompute the [FolderDisposition] for the context described by [info],
1177 * and update the client appropriately. 1191 * and update the client appropriately.
1178 */ 1192 */
1179 void _recomputeFolderDisposition(ContextInfo info) { 1193 void _recomputeFolderDisposition(ContextInfo info) {
1180 // TODO(paulberry): when computePackageMap is changed into an 1194 // TODO(paulberry): when computePackageMap is changed into an
1181 // asynchronous API call, we'll want to suspend analysis for this context 1195 // asynchronous API call, we'll want to suspend analysis for this context
1182 // while we're rerunning "pub list", since any analysis we complete while 1196 // while we're rerunning "pub list", since any analysis we complete while
1183 // "pub list" is in progress is just going to get thrown away anyhow. 1197 // "pub list" is in progress is just going to get thrown away anyhow.
1184 List<String> dependencies = <String>[]; 1198 List<String> dependencies = <String>[];
1185 FolderDisposition disposition = 1199 FolderDisposition disposition = _computeFolderDisposition(
1186 _computeFolderDisposition(info.folder, dependencies.add); 1200 info.folder, dependencies.add, _findPackageSpecFile(info.folder));
1187 info.setDependencies(dependencies); 1201 info.setDependencies(dependencies);
1188 callbacks.updateContextPackageUriResolver(info.folder, disposition); 1202 callbacks.updateContextPackageUriResolver(info.folder, disposition);
1189 } 1203 }
1190 1204
1191 /** 1205 /**
1192 * Create and return a source representing the given [file] within the given 1206 * Create and return a source representing the given [file] within the given
1193 * [context]. 1207 * [context].
1194 */ 1208 */
1195 static Source createSourceInContext(AnalysisContext context, File file) { 1209 static Source createSourceInContext(AnalysisContext context, File file) {
1196 // TODO(brianwilkerson) Optimize this, by allowing support for source 1210 // TODO(brianwilkerson) Optimize this, by allowing support for source
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
1352 PackagesFileDisposition(this.packages) {} 1366 PackagesFileDisposition(this.packages) {}
1353 1367
1354 @override 1368 @override
1355 String get packageRoot => null; 1369 String get packageRoot => null;
1356 1370
1357 @override 1371 @override
1358 Iterable<UriResolver> createPackageUriResolvers( 1372 Iterable<UriResolver> createPackageUriResolvers(
1359 ResourceProvider resourceProvider) => 1373 ResourceProvider resourceProvider) =>
1360 const <UriResolver>[]; 1374 const <UriResolver>[];
1361 } 1375 }
OLDNEW
« no previous file with comments | « no previous file | pkg/analysis_server/test/context_manager_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698