mirror of
https://github.com/colbymchenry/codegraph.git
synced 2026-10-16 20:53:57 +08:00
fa43e259b2
A kind-projector placeholder (`Align[Either[A, *]]`, `Functor[Map[K, ?]]`) reached the resolver as a type reference named `*`, and exact or fuzzy matching bound it to the one `*` in the project - algebra's `Signed.Sign.*` operator - 567 times in cats. A symbolic name in a Scala type now resolves only to a type or type alias of that name (cats' `F ~> G`), and otherwise to nothing, whatever strategy runs. cats -567; sttp unchanged. Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
/**
|
|
* A Scala kind-projector placeholder in a type — `Align[Either[A, *]]`,
|
|
* `Functor[Map[K, ?]]` — names no method: cats' 567 `*` type arguments went
|
|
* to an algebra `Sign`'s `*` operator.
|
|
*/
|
|
import { describe, it, expect, afterAll, beforeAll } from 'vitest';
|
|
import * as fs from 'fs';
|
|
import * as os from 'os';
|
|
import * as path from 'path';
|
|
import { CodeGraph } from '../src';
|
|
|
|
let root = '';
|
|
let cg: CodeGraph;
|
|
|
|
beforeAll(async () => {
|
|
root = fs.mkdtempSync(path.join(os.tmpdir(), 'cg-scala-kp-'));
|
|
const files: Record<string, string> = {
|
|
'src/main/scala/algebra/Signed.scala': `package algebra
|
|
|
|
object Signed {
|
|
sealed abstract class Sign(val toInt: Int) {
|
|
def *(that: Sign): Sign = this
|
|
}
|
|
}
|
|
`,
|
|
'src/main/scala/cats/Align.scala': `package cats
|
|
|
|
trait Align[F[_]]
|
|
|
|
object Align {
|
|
implicit def catsAlignForEither[A]: Align[Either[A, *]] = null
|
|
}
|
|
`,
|
|
};
|
|
for (const [rel, content] of Object.entries(files)) {
|
|
fs.mkdirSync(path.dirname(path.join(root, rel)), { recursive: true });
|
|
fs.writeFileSync(path.join(root, rel), content);
|
|
}
|
|
cg = await CodeGraph.init(root, { index: true });
|
|
});
|
|
|
|
afterAll(() => {
|
|
cg?.close();
|
|
if (root) fs.rmSync(root, { recursive: true, force: true });
|
|
});
|
|
|
|
describe('Scala kind-projector placeholders', () => {
|
|
it('are not references to a `*` method', () => {
|
|
const ids = cg.getNodesInFile('src/main/scala/cats/Align.scala').map((n) => n.id);
|
|
const targets = cg.getOutgoingEdgesFrom(ids).filter((e) => e.kind === 'references').map((e) => cg.getNode(e.target)!.name);
|
|
expect(targets).not.toContain('*');
|
|
});
|
|
});
|