Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
quarto-dev
GitHub Repository: quarto-dev/quarto-cli
Path: blob/main/tools/sass-variable-explainer/_attic/print-dependency-graph.ts
12925 views
1
import { parse } from "npm:scss-parser";
2
import { assert } from "jsr:@std/assert";
3
import * as prettier from "npm:prettier";
4
import { propagateDeclarationTypes } from "./sass-analyzer/declaration-types.ts";
5
import { getVariableDependencies } from "./sass-analyzer/get-dependencies.ts";
6
import { cleanSassAst } from "./sass-analyzer/clean-ast.ts";
7
import { makeParserModule } from "./sass-analyzer/parse.ts";
8
9
export const getSassAst = makeParserModule(parse, prettier.format).getSassAst;
10
11
const drawColorDependencyGraph = (ast: any) => {
12
const declarations = propagateDeclarationTypes(ast);
13
14
let labelCount = 0;
15
const labels: Map<string, string> = new Map();
16
const dotNodeName = (name: string) => {
17
if (labels.has(name)) {
18
return { id: labels.get(name) };
19
}
20
const newName = `N${labelCount++}`;
21
labels.set(name, newName);
22
return { id: newName, nodeDecl: `${newName}[label="${name}"]` };
23
}
24
25
console.log("```{dot}");
26
console.log("digraph G {\n rankdir=LR;\n");
27
console.log(" splines=false;");
28
console.log(" node [shape=rectangle, color=gray]");
29
console.log(" edge [color=gray]");
30
31
const varDeps = getVariableDependencies(declarations);
32
const inverseVarDeps = new Map<string, Set<string>>();
33
const origins = new Map<string, Set<string>>();
34
const addToSetMap = (map: Map<string, Set<string>>, key: string, value: string) => {
35
if (!map.has(key)) {
36
map.set(key, new Set());
37
}
38
map.get(key)!.add(value);
39
}
40
41
for (const [name, deps] of varDeps) {
42
// update origin sets
43
const node = deps.node;
44
const origin = node?.annotation?.origin ?? "unknown";
45
addToSetMap(origins, origin, name);
46
// update inverse dependencies
47
for (const dep of deps.dependencies) {
48
if (declarations.get(name)?.valueType !== "color" ||
49
declarations.get(dep)?.valueType !== "color") {
50
continue;
51
}
52
addToSetMap(inverseVarDeps, dep, name);
53
}
54
}
55
let subgraphCount = 0;
56
for (const [name, vars] of origins) {
57
if (name === "unknown") {
58
continue;
59
}
60
subgraphCount++;
61
console.log(`subgraph subgraph_${subgraphCount} {`);
62
for (const varName of vars) {
63
// only show numbered colors if they have inverse dependencies
64
if (varName.match(/^.+-[0-9]00$/) && !inverseVarDeps.get(varName)?.size) {
65
continue;
66
}
67
const { nodeDecl: sourceNodeDecl } = dotNodeName(varName);
68
if (!sourceNodeDecl) {
69
throw new Error("multiple origins for a variable? " + varName);
70
}
71
assert(sourceNodeDecl);
72
console.log(` ${sourceNodeDecl}`);
73
}
74
console.log(` label = "${name}"`);
75
console.log(` color=red`);
76
console.log("}");
77
}
78
79
for (const [name, deps] of varDeps) {
80
if (deps.node.valueType !== "color") {
81
continue;
82
}
83
// only show numbered colors if they have inverse dependencies
84
if (name.match(/^.+-[0-9]00$/) && !inverseVarDeps.get(name)?.size) {
85
continue;
86
}
87
for (const dep of deps.dependencies) {
88
if (declarations.get(dep)?.valueType !== "color") {
89
continue;
90
}
91
const {id: sourceId, nodeDecl: sourceNodeDecl } = dotNodeName(dep);
92
const {id: targetId, nodeDecl: targetNodeDecl } = dotNodeName(name);
93
if (sourceNodeDecl) {
94
console.log(` ${sourceNodeDecl}`);
95
}
96
if (targetNodeDecl) {
97
console.log(` ${targetNodeDecl}`);
98
}
99
100
console.log(` ${sourceId} -> ${targetId}`);
101
}
102
}
103
104
console.log("}");
105
console.log("```");
106
}
107
108
if (import.meta.main) {
109
const ast = await getSassAst(Deno.readTextFileSync(Deno.args[0] || "/dev/stdin"));
110
let cleaned = cleanSassAst(ast);
111
drawColorDependencyGraph(cleaned);
112
// const declarations = propagateDeclarationTypes(cleaned);
113
// for (const [name, node] of declarations) {
114
// if (node.valueType === "color") {
115
// console.log(name, node.line);
116
// }
117
// // console.log(name, node);
118
// }
119
}
120