Allow for ts strictdeps to look at multiple declaration sites of a symbol

PiperOrigin-RevId: 290365047
diff --git a/internal/tsc_wrapped/strict_deps.ts b/internal/tsc_wrapped/strict_deps.ts
index c2cb723..447fc3e 100644
--- a/internal/tsc_wrapped/strict_deps.ts
+++ b/internal/tsc_wrapped/strict_deps.ts
@@ -85,15 +85,24 @@
     if (!sym || !sym.declarations || sym.declarations.length < 1) {
       continue;
     }
-    // Module imports can only have one declaration location.
-    const declFileName = sym.declarations[0].getSourceFile().fileName;
-    if (allowedMap[stripExt(declFileName)]) continue;
-    const importName = path.posix.relative(rootDir, declFileName);
+    const declFileNames =
+        sym.declarations.map(decl => decl.getSourceFile().fileName);
+    if (declFileNames.find(
+            declFileName => !!allowedMap[stripExt(declFileName)])) {
+      continue;
+    }
+    const importNames = declFileNames.map(
+        declFileName => path.posix.relative(rootDir, declFileName));
+
+    const extraDeclarationLocationsMessage = (importNames.length < 2) ?
+        '' :
+        `(It is also declared in ${importNames.slice(1).join(', ')}) `;
     result.push({
       file: sf,
       start: modSpec.getStart(),
       length: modSpec.getEnd() - modSpec.getStart(),
-      messageText: `transitive dependency on ${importName} not allowed. ` +
+      messageText: `transitive dependency on ${importNames[0]} not allowed. ` +
+          extraDeclarationLocationsMessage +
           `Please add the BUILD target to your rule's deps.`,
       category: ts.DiagnosticCategory.Error,
       // semantics are close enough, needs taze.
diff --git a/internal/tsc_wrapped/strict_deps_test.ts b/internal/tsc_wrapped/strict_deps_test.ts
index 807e86e..1e3ae47 100644
--- a/internal/tsc_wrapped/strict_deps_test.ts
+++ b/internal/tsc_wrapped/strict_deps_test.ts
@@ -132,4 +132,26 @@
     expect(diags[0].messageText)
         .toMatch(/dependency on blaze-bin\/p\/sd1.d.ts not allowed/);
   });
+
+  it('allows multiple declarations of the same clutz-generated module', () => {
+    const p = createProgram({
+      '/src/blaze-bin/p/js1.d.ts': `declare module 'goog:thing' {}`,
+      '/src/blaze-bin/p/js2.d.ts': `declare module 'goog:thing' {}`,
+      '/src/blaze-bin/p/js3.d.ts': `declare module 'goog:thing' {}`,
+      // Import from the middle one, to be sure it doesn't pass just because the
+      // order so happens that we checked the declaration from the first one
+      '/src/p/my.ts': `import {} from 'goog:thing'; // taze: from //p:js2`,
+    });
+    const good = checkModuleDeps(
+        p.getSourceFile('/src/p/my.ts')!, p.getTypeChecker(),
+        ['/src/blaze-bin/p/js2.d.ts'], '/src');
+    expect(good.length).toBe(0);
+
+    const bad = checkModuleDeps(
+        p.getSourceFile('/src/p/my.ts')!, p.getTypeChecker(), [], '/src');
+    expect(bad.length).toBe(1);
+    expect(bad[0].messageText)
+        .toContain(
+            '(It is also declared in blaze-bin/p/js2.d.ts, blaze-bin/p/js3.d.ts)');
+  });
 });