@mishasinitcyn/betterrank 0.2.10 → 0.2.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/outline.js +51 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mishasinitcyn/betterrank",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.11",
|
|
4
4
|
"description": "Structural code index with PageRank-ranked repo maps, symbol search, call-graph queries, and dependency analysis. Built on tree-sitter and graphology.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/index.js",
|
package/src/outline.js
CHANGED
|
@@ -133,19 +133,61 @@ function detectImportBlock(lines) {
|
|
|
133
133
|
return { start: firstImportLine + 1, end: lastImportLine + 1, lineCount, name: null };
|
|
134
134
|
}
|
|
135
135
|
|
|
136
|
-
function
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
// by the parent's collapse, preventing dozens of inline-callback markers.
|
|
140
|
-
const nested = new Set();
|
|
136
|
+
function findImmediateParents(defs) {
|
|
137
|
+
const parents = new Map();
|
|
138
|
+
|
|
141
139
|
for (const def of defs) {
|
|
140
|
+
let parent = null;
|
|
141
|
+
|
|
142
142
|
for (const other of defs) {
|
|
143
143
|
if (other === def) continue;
|
|
144
|
-
if (def.lineStart
|
|
145
|
-
|
|
146
|
-
|
|
144
|
+
if (def.lineStart <= other.lineStart || def.lineEnd > other.lineEnd) continue;
|
|
145
|
+
|
|
146
|
+
if (!parent) {
|
|
147
|
+
parent = other;
|
|
148
|
+
continue;
|
|
147
149
|
}
|
|
150
|
+
|
|
151
|
+
const isCloserParent =
|
|
152
|
+
other.lineStart >= parent.lineStart && other.lineEnd <= parent.lineEnd;
|
|
153
|
+
if (isCloserParent) parent = other;
|
|
148
154
|
}
|
|
155
|
+
|
|
156
|
+
parents.set(def, parent);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return parents;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
function findDelegatingContainers(defs, parentMap) {
|
|
163
|
+
const propertyChildCounts = new Map();
|
|
164
|
+
|
|
165
|
+
for (const def of defs) {
|
|
166
|
+
if (def.kind !== 'property') continue;
|
|
167
|
+
const parent = parentMap.get(def);
|
|
168
|
+
if (!parent || parent.kind !== 'variable') continue;
|
|
169
|
+
propertyChildCounts.set(parent, (propertyChildCounts.get(parent) || 0) + 1);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return new Set(
|
|
173
|
+
[...propertyChildCounts.entries()]
|
|
174
|
+
.filter(([, count]) => count > 0)
|
|
175
|
+
.map(([def]) => def),
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function outlineMode(lines, defs, pad, callerCounts) {
|
|
180
|
+
// Mark definitions that are nested inside another definition.
|
|
181
|
+
// Only defs nested inside opaque parents are swallowed.
|
|
182
|
+
// Some top-level variables are really structural containers, like exported
|
|
183
|
+
// procedure maps or routers. Those should delegate to their direct property
|
|
184
|
+
// children instead of collapsing the entire wrapper object.
|
|
185
|
+
const parentMap = findImmediateParents(defs);
|
|
186
|
+
const delegatingContainers = findDelegatingContainers(defs, parentMap);
|
|
187
|
+
const nested = new Set();
|
|
188
|
+
for (const def of defs) {
|
|
189
|
+
const parent = parentMap.get(def);
|
|
190
|
+
if (parent && !delegatingContainers.has(parent)) nested.add(def);
|
|
149
191
|
}
|
|
150
192
|
|
|
151
193
|
const collapseRanges = [];
|
|
@@ -157,6 +199,7 @@ function outlineMode(lines, defs, pad, callerCounts) {
|
|
|
157
199
|
// Collapse all top-level definitions (functions, classes, interfaces, components)
|
|
158
200
|
for (const def of defs) {
|
|
159
201
|
if (nested.has(def)) continue;
|
|
202
|
+
if (delegatingContainers.has(def)) continue;
|
|
160
203
|
if (!def.bodyStartLine) continue;
|
|
161
204
|
if (def.bodyStartLine > def.lineEnd) continue;
|
|
162
205
|
|