PackageBuildWorkspace should stop at the first pubspec.yaml found, don't go up.

Change-Id: I1b996b34055d6887816313d333175869f570ada1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/172900
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index 2e2dce1..2a8a2f0 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,4 +1,9 @@
-## 0.41.0 (Not yet released - breaking changes)
+## 0.41.1-dev
+* Updated `PackageBuildWorkspace` that supports `package:build` to stop
+  at the first directory with `pubspec.yaml`, and don't try to go up
+  and find another one with both `pubspec.yaml` and `.dart_tool/build`.
+
+## 0.41.0
 * Replaced `Scope.lookup({id, setter})` with `lookup(id)`.
 * Deprecated `Scope.lookup2(id)`, use `lookup()` instead.
 * Removed deprecated `Member.baseElement`.
diff --git a/pkg/analyzer/lib/src/workspace/package_build.dart b/pkg/analyzer/lib/src/workspace/package_build.dart
index 7240390..17ac171 100644
--- a/pkg/analyzer/lib/src/workspace/package_build.dart
+++ b/pkg/analyzer/lib/src/workspace/package_build.dart
@@ -297,7 +297,16 @@
               provider.pathContext.join(generatedRootPath, packageName);
           return PackageBuildWorkspace._(provider, packageMap, folder.path,
               packageName, generatedRootPath, generatedThisPath);
-        } catch (_) {}
+        } catch (_) {
+          return null;
+        }
+      }
+
+      // We found `pubspec.yaml`, but not `.dart_tool/build`.
+      // Stop going up, this package does not have package:build results.
+      // We don't want to find results of a parent package.
+      if (pubspec.exists) {
+        return null;
       }
 
       // Go up the folder.
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index d97ca2a..d6e35e5 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.41.0
+version: 0.41.1-dev
 description: This package provides a library that performs static analysis of Dart code.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
 
diff --git a/pkg/analyzer/test/src/workspace/package_build_test.dart b/pkg/analyzer/test/src/workspace/package_build_test.dart
index 42c46c4..2a9000a 100644
--- a/pkg/analyzer/test/src/workspace/package_build_test.dart
+++ b/pkg/analyzer/test/src/workspace/package_build_test.dart
@@ -444,6 +444,21 @@
     );
   }
 
+  void test_find_hasBuild_hasPubspec_malformed_dontGoToUp() {
+    newFolder('/workspace/.dart_tool/build/generated');
+    newFile('/workspace/pubspec.yaml', content: 'name: project');
+
+    newFolder('/workspace/aaa/.dart_tool/build/generated');
+    newFile('/workspace/aaa/pubspec.yaml', content: '*');
+
+    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
+      resourceProvider,
+      {},
+      convertPath('/workspace/aaa/lib'),
+    );
+    expect(workspace, isNull);
+  }
+
   void test_find_hasDartToolAndPubspec() {
     newFolder('/workspace/.dart_tool/build/generated/project/lib');
     newFile('/workspace/pubspec.yaml', content: 'name: project');
@@ -471,22 +486,6 @@
     expect(workspace.projectPackageName, 'subproject');
   }
 
-  void
-      test_find_hasDartToolAndPubspec_inParentDirectory_ignoresMalformedPubspec() {
-    newFolder('/workspace/.dart_tool/build/generated/project/lib');
-    newFolder('/workspace/opened/up/a/child/dir/.dart_tool/build');
-    newFile('/workspace/opened/up/a/child/dir/pubspec.yaml',
-        content: 'not: yaml: here!!! 111');
-    newFile('/workspace/pubspec.yaml', content: 'name: project');
-    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
-      resourceProvider,
-      {},
-      convertPath('/workspace/opened/up/a/child/dir'),
-    );
-    expect(workspace.root, convertPath('/workspace'));
-    expect(workspace.projectPackageName, 'project');
-  }
-
   void test_find_hasDartToolAndPubspec_inParentDirectory_ignoresSoloDartTool() {
     newFolder('/workspace/.dart_tool/build/generated/project/lib');
     newFolder('/workspace/opened/up/a/child/dir');
@@ -501,21 +500,6 @@
     expect(workspace.projectPackageName, 'project');
   }
 
-  void test_find_hasDartToolAndPubspec_inParentDirectory_ignoresSoloPubspec() {
-    newFolder('/workspace/.dart_tool/build/generated/project/lib');
-    newFolder('/workspace/opened/up/a/child/dir');
-    newFile('/workspace/opened/up/a/child/dir/pubspec.yaml',
-        content: 'name: subproject');
-    newFile('/workspace/pubspec.yaml', content: 'name: project');
-    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
-      resourceProvider,
-      {},
-      convertPath('/workspace/opened/up/a/child/dir'),
-    );
-    expect(workspace.root, convertPath('/workspace'));
-    expect(workspace.projectPackageName, 'project');
-  }
-
   void test_find_hasDartToolNoBuild() {
     // Edge case: an empty .dart_tool directory. Don't assume package:build.
     newFolder('/workspace/.dart_tool');
@@ -561,6 +545,20 @@
     expect(workspace, isNull);
   }
 
+  void test_find_hasPubspec_noDartTool_dontGoUp() {
+    newFolder('/workspace/.dart_tool/build/generated');
+    newFile('/workspace/pubspec.yaml', content: 'name: project');
+
+    newFile('/workspace/aaa/pubspec.yaml', content: '*');
+
+    PackageBuildWorkspace workspace = PackageBuildWorkspace.find(
+      resourceProvider,
+      {},
+      convertPath('/workspace/aaa/lib'),
+    );
+    expect(workspace, isNull);
+  }
+
   void test_find_hasPubspecNoDartTool() {
     newFile('/workspace/pubspec.yaml', content: 'name: project');
     PackageBuildWorkspace workspace = PackageBuildWorkspace.find(