pando-ai 0.3.0 → 0.3.2
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/dist/cli.js +445 -669
- package/dist/watcher-process.js +664 -888
- package/dist/workers/chunk-5T4KKWJC.mjs +16 -0
- package/dist/workers/indexer-worker.mjs +1 -1
- package/dist/workers/snapshot-worker.mjs +1 -1
- package/dist/workers/sqlite-writer-worker.mjs +16 -6
- package/package.json +1 -1
- package/resources/tools/generated_pando-tools.json +38 -12
- package/tools/clang-indexer/bin/pando-clang-indexer +0 -0
- package/tools/clojure-editor/lib/pando-clojure-editor-standalone.jar +0 -0
- package/tools/clojure-indexer/lib/pando-clojure-indexer-standalone.jar +0 -0
- package/tools/csharp-indexer/CSharpIndexer.csproj +4 -0
- package/tools/csharp-indexer/src/Program.cs +159 -19
- package/dist/workers/chunk-A6FOFRZ6.mjs +0 -518
|
@@ -4,7 +4,11 @@
|
|
|
4
4
|
<TargetFrameworks>net8.0;net9.0;net10.0</TargetFrameworks>
|
|
5
5
|
<Nullable>enable</Nullable>
|
|
6
6
|
<LangVersion>latest</LangVersion>
|
|
7
|
+
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
|
|
7
8
|
</PropertyGroup>
|
|
9
|
+
<ItemGroup>
|
|
10
|
+
<Compile Include="src/**/*.cs" />
|
|
11
|
+
</ItemGroup>
|
|
8
12
|
<ItemGroup>
|
|
9
13
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.10.0" />
|
|
10
14
|
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" Version="4.10.0" />
|
|
@@ -29,6 +29,12 @@ namespace Pando.CSharpIndexer
|
|
|
29
29
|
[JsonPropertyName("qualifiedName")] public string? QualifiedName { get; set; }
|
|
30
30
|
[JsonPropertyName("scopeChain")] public List<string>? ScopeChain { get; set; }
|
|
31
31
|
[JsonPropertyName("symbolKey")] public string? SymbolKey { get; set; }
|
|
32
|
+
[JsonPropertyName("parentIndex")] public int? ParentIndex { get; set; }
|
|
33
|
+
[JsonPropertyName("role")] public string? Role { get; set; }
|
|
34
|
+
[JsonPropertyName("indexInParent")] public int? IndexInParent { get; set; }
|
|
35
|
+
[JsonPropertyName("depth")] public int? Depth { get; set; }
|
|
36
|
+
[JsonPropertyName("bodyStart")] public int? BodyStart { get; set; }
|
|
37
|
+
[JsonPropertyName("bodyEnd")] public int? BodyEnd { get; set; }
|
|
32
38
|
[JsonPropertyName("metadata")] public Dictionary<string, object?>? Metadata { get; set; }
|
|
33
39
|
}
|
|
34
40
|
|
|
@@ -156,7 +162,8 @@ namespace Pando.CSharpIndexer
|
|
|
156
162
|
return resolved.Error == null ? 0 : 2;
|
|
157
163
|
}
|
|
158
164
|
|
|
159
|
-
var
|
|
165
|
+
var emitMode = parsed.TryGetValue("emitMode", out var mode) && !string.IsNullOrWhiteSpace(mode) ? mode! : "light";
|
|
166
|
+
var result = BuildParseResult(root, content, emitMode);
|
|
160
167
|
WriteOutput(parsed, result);
|
|
161
168
|
return 0;
|
|
162
169
|
}
|
|
@@ -218,7 +225,8 @@ namespace Pando.CSharpIndexer
|
|
|
218
225
|
}
|
|
219
226
|
try
|
|
220
227
|
{
|
|
221
|
-
var
|
|
228
|
+
var emitMode = GetString(item, "emitMode") ?? "light";
|
|
229
|
+
var result = ParseFile(file!, emitMode);
|
|
222
230
|
results.Add(new { file, ok = true, result });
|
|
223
231
|
}
|
|
224
232
|
catch (Exception ex)
|
|
@@ -237,7 +245,8 @@ namespace Pando.CSharpIndexer
|
|
|
237
245
|
}
|
|
238
246
|
try
|
|
239
247
|
{
|
|
240
|
-
var
|
|
248
|
+
var emitMode = GetString(root, "emitMode") ?? "light";
|
|
249
|
+
var result = ParseFile(singleFile!, emitMode);
|
|
241
250
|
WriteServerResponse(new { id, ok = true, result }, options);
|
|
242
251
|
}
|
|
243
252
|
catch (Exception ex)
|
|
@@ -347,12 +356,12 @@ namespace Pando.CSharpIndexer
|
|
|
347
356
|
return null;
|
|
348
357
|
}
|
|
349
358
|
|
|
350
|
-
private static CliParseResult ParseFile(string file)
|
|
359
|
+
private static CliParseResult ParseFile(string file, string emitMode)
|
|
351
360
|
{
|
|
352
361
|
var content = File.ReadAllText(file);
|
|
353
362
|
var tree = CSharpSyntaxTree.ParseText(content, path: file);
|
|
354
363
|
var root = tree.GetCompilationUnitRoot();
|
|
355
|
-
return BuildParseResult(root, content);
|
|
364
|
+
return BuildParseResult(root, content, emitMode);
|
|
356
365
|
}
|
|
357
366
|
|
|
358
367
|
private static CliResolvedSpan ResolveFile(string file, string nodePath)
|
|
@@ -414,7 +423,7 @@ namespace Pando.CSharpIndexer
|
|
|
414
423
|
}
|
|
415
424
|
}
|
|
416
425
|
|
|
417
|
-
private static CliParseResult BuildParseResult(CompilationUnitSyntax root, string content)
|
|
426
|
+
private static CliParseResult BuildParseResult(CompilationUnitSyntax root, string content, string emitMode)
|
|
418
427
|
{
|
|
419
428
|
var result = new CliParseResult();
|
|
420
429
|
var semanticModel = TryCreateSemanticModel(root);
|
|
@@ -529,12 +538,128 @@ namespace Pando.CSharpIndexer
|
|
|
529
538
|
}
|
|
530
539
|
}
|
|
531
540
|
|
|
541
|
+
if (IsFullEmitMode(emitMode))
|
|
542
|
+
{
|
|
543
|
+
AddFullSyntaxNodes(result, root);
|
|
544
|
+
AddCommentTriviaNodes(result, root);
|
|
545
|
+
}
|
|
546
|
+
|
|
532
547
|
EnrichNodeHierarchy(result.Nodes, root);
|
|
533
548
|
|
|
534
549
|
result.ModulePublic = publicNames.ToList();
|
|
535
550
|
return result;
|
|
536
551
|
}
|
|
537
552
|
|
|
553
|
+
private static bool IsFullEmitMode(string? emitMode)
|
|
554
|
+
{
|
|
555
|
+
return string.Equals(emitMode, "full", StringComparison.OrdinalIgnoreCase);
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
private static void AddFullSyntaxNodes(CliParseResult result, CompilationUnitSyntax root)
|
|
559
|
+
{
|
|
560
|
+
var emittedKeys = result.Nodes
|
|
561
|
+
.Select(n => NodeKey(n.Start, n.End, n.RawKind ?? n.Kind))
|
|
562
|
+
.ToHashSet(StringComparer.Ordinal);
|
|
563
|
+
|
|
564
|
+
foreach (var node in EnumerateSyntaxNodesIncludingRoot(root))
|
|
565
|
+
{
|
|
566
|
+
var rawKind = node.Kind().ToString();
|
|
567
|
+
var start = NodeStart(node);
|
|
568
|
+
var end = NodeEnd(node);
|
|
569
|
+
var key = NodeKey(start, end, rawKind);
|
|
570
|
+
if (emittedKeys.Contains(key)) { continue; }
|
|
571
|
+
result.Nodes.Add(new CliNode
|
|
572
|
+
{
|
|
573
|
+
Name = null,
|
|
574
|
+
Kind = rawKind,
|
|
575
|
+
RawKind = rawKind,
|
|
576
|
+
RawKindSource = "roslyn",
|
|
577
|
+
SemanticKind = InferSemanticKind(node),
|
|
578
|
+
Start = start,
|
|
579
|
+
End = end,
|
|
580
|
+
IsExported = 0,
|
|
581
|
+
ContainerKind = null,
|
|
582
|
+
ContainerRawKind = null,
|
|
583
|
+
ContainerRawKindSource = null,
|
|
584
|
+
ParamCount = null,
|
|
585
|
+
Metadata = null,
|
|
586
|
+
});
|
|
587
|
+
emittedKeys.Add(key);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
private static void AddCommentTriviaNodes(CliParseResult result, CompilationUnitSyntax root)
|
|
592
|
+
{
|
|
593
|
+
var emittedKeys = result.Nodes
|
|
594
|
+
.Select(n => NodeKey(n.Start, n.End, n.RawKind ?? n.Kind))
|
|
595
|
+
.ToHashSet(StringComparer.Ordinal);
|
|
596
|
+
var rootIndex = result.Nodes.FindIndex(n =>
|
|
597
|
+
n.Start == NodeStart(root)
|
|
598
|
+
&& n.End == NodeEnd(root)
|
|
599
|
+
&& string.Equals(n.RawKind ?? n.Kind, root.Kind().ToString(), StringComparison.Ordinal));
|
|
600
|
+
var commentOrdinal = 0;
|
|
601
|
+
|
|
602
|
+
foreach (var trivia in root.DescendantTrivia(descendIntoTrivia: true))
|
|
603
|
+
{
|
|
604
|
+
if (!IsCommentTrivia(trivia)) { continue; }
|
|
605
|
+
var rawKind = trivia.Kind().ToString();
|
|
606
|
+
var start = trivia.Span.Start;
|
|
607
|
+
var end = trivia.Span.End;
|
|
608
|
+
var key = NodeKey(start, end, rawKind);
|
|
609
|
+
if (emittedKeys.Contains(key)) { continue; }
|
|
610
|
+
result.Nodes.Add(new CliNode
|
|
611
|
+
{
|
|
612
|
+
Name = null,
|
|
613
|
+
Kind = rawKind,
|
|
614
|
+
RawKind = rawKind,
|
|
615
|
+
RawKindSource = "roslyn-trivia",
|
|
616
|
+
SemanticKind = "comment",
|
|
617
|
+
Start = start,
|
|
618
|
+
End = end,
|
|
619
|
+
IsExported = 0,
|
|
620
|
+
ContainerKind = null,
|
|
621
|
+
ContainerRawKind = root.Kind().ToString(),
|
|
622
|
+
ContainerRawKindSource = "roslyn",
|
|
623
|
+
ParamCount = null,
|
|
624
|
+
ParentIndex = rootIndex >= 0 ? rootIndex : null,
|
|
625
|
+
Role = "comment",
|
|
626
|
+
IndexInParent = commentOrdinal,
|
|
627
|
+
Depth = rootIndex >= 0 ? 1 : 0,
|
|
628
|
+
Metadata = null,
|
|
629
|
+
});
|
|
630
|
+
emittedKeys.Add(key);
|
|
631
|
+
commentOrdinal++;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
private static IEnumerable<SyntaxNode> EnumerateSyntaxNodesIncludingRoot(CompilationUnitSyntax root)
|
|
636
|
+
{
|
|
637
|
+
yield return root;
|
|
638
|
+
foreach (var node in root.DescendantNodes())
|
|
639
|
+
{
|
|
640
|
+
yield return node;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
private static bool IsCommentTrivia(SyntaxTrivia trivia)
|
|
645
|
+
{
|
|
646
|
+
return trivia.IsKind(SyntaxKind.SingleLineCommentTrivia)
|
|
647
|
+
|| trivia.IsKind(SyntaxKind.MultiLineCommentTrivia)
|
|
648
|
+
|| trivia.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia)
|
|
649
|
+
|| trivia.IsKind(SyntaxKind.MultiLineDocumentationCommentTrivia)
|
|
650
|
+
|| trivia.IsKind(SyntaxKind.DocumentationCommentExteriorTrivia);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
private static int NodeStart(SyntaxNode node)
|
|
654
|
+
{
|
|
655
|
+
return node is CompilationUnitSyntax ? node.FullSpan.Start : node.Span.Start;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
private static int NodeEnd(SyntaxNode node)
|
|
659
|
+
{
|
|
660
|
+
return node is CompilationUnitSyntax ? node.FullSpan.End : node.Span.End;
|
|
661
|
+
}
|
|
662
|
+
|
|
538
663
|
private static string NormalizeQualifiedName(string? qualifiedName)
|
|
539
664
|
{
|
|
540
665
|
if (string.IsNullOrWhiteSpace(qualifiedName)) { return string.Empty; }
|
|
@@ -1327,7 +1452,7 @@ namespace Pando.CSharpIndexer
|
|
|
1327
1452
|
metadata["isStatic"] = node.Modifiers.Any(SyntaxKind.StaticKeyword);
|
|
1328
1453
|
metadata["returnType"] = node.Type.ToString();
|
|
1329
1454
|
|
|
1330
|
-
var kind = node.ImplicitOrExplicitKeyword.
|
|
1455
|
+
var kind = node.ImplicitOrExplicitKeyword.IsKind(SyntaxKind.ImplicitKeyword) ? "implicit" : "explicit";
|
|
1331
1456
|
result.Nodes.Add(new CliNode
|
|
1332
1457
|
{
|
|
1333
1458
|
Name = $"{kind} operator {node.Type}",
|
|
@@ -1436,12 +1561,21 @@ namespace Pando.CSharpIndexer
|
|
|
1436
1561
|
|
|
1437
1562
|
private static void EnrichNodeHierarchy(List<CliNode> nodes, CompilationUnitSyntax root)
|
|
1438
1563
|
{
|
|
1439
|
-
var syntaxByKey = root
|
|
1440
|
-
.GroupBy(n => NodeKey(n
|
|
1564
|
+
var syntaxByKey = EnumerateSyntaxNodesIncludingRoot(root)
|
|
1565
|
+
.GroupBy(n => NodeKey(NodeStart(n), NodeEnd(n), n.Kind().ToString()))
|
|
1441
1566
|
.ToDictionary(g => g.Key, g => g.First(), StringComparer.Ordinal);
|
|
1442
1567
|
var nodeByKey = nodes
|
|
1443
1568
|
.GroupBy(n => NodeKey(n.Start, n.End, n.RawKind ?? n.Kind), StringComparer.Ordinal)
|
|
1444
1569
|
.ToDictionary(g => g.Key, g => g.First(), StringComparer.Ordinal);
|
|
1570
|
+
var nodeIndexByKey = new Dictionary<string, int>(StringComparer.Ordinal);
|
|
1571
|
+
for (var i = 0; i < nodes.Count; i++)
|
|
1572
|
+
{
|
|
1573
|
+
var key = NodeKey(nodes[i].Start, nodes[i].End, nodes[i].RawKind ?? nodes[i].Kind);
|
|
1574
|
+
if (!nodeIndexByKey.ContainsKey(key))
|
|
1575
|
+
{
|
|
1576
|
+
nodeIndexByKey[key] = i;
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1445
1579
|
var emittedKeys = new HashSet<string>(nodeByKey.Keys, StringComparer.Ordinal);
|
|
1446
1580
|
var childrenByParent = new Dictionary<string, List<CliNode>>(StringComparer.Ordinal);
|
|
1447
1581
|
|
|
@@ -1453,17 +1587,25 @@ namespace Pando.CSharpIndexer
|
|
|
1453
1587
|
var body = GetBodySpan(syntax);
|
|
1454
1588
|
if (body != null)
|
|
1455
1589
|
{
|
|
1590
|
+
cliNode.BodyStart = body.Value.start;
|
|
1591
|
+
cliNode.BodyEnd = body.Value.end;
|
|
1456
1592
|
metadata["bodyStart"] = body.Value.start;
|
|
1457
1593
|
metadata["bodyEnd"] = body.Value.end;
|
|
1458
1594
|
}
|
|
1459
|
-
|
|
1595
|
+
var role = InferNodeRole(syntax);
|
|
1596
|
+
cliNode.Role = role;
|
|
1597
|
+
metadata["role"] = role;
|
|
1460
1598
|
|
|
1461
1599
|
var parent = syntax.Parent;
|
|
1462
1600
|
while (parent != null)
|
|
1463
1601
|
{
|
|
1464
|
-
var parentKey = NodeKey(parent
|
|
1602
|
+
var parentKey = NodeKey(NodeStart(parent), NodeEnd(parent), parent.Kind().ToString());
|
|
1465
1603
|
if (emittedKeys.Contains(parentKey))
|
|
1466
1604
|
{
|
|
1605
|
+
if (nodeIndexByKey.TryGetValue(parentKey, out var parentIndex))
|
|
1606
|
+
{
|
|
1607
|
+
cliNode.ParentIndex = parentIndex;
|
|
1608
|
+
}
|
|
1467
1609
|
metadata["parentStart"] = parent.Span.Start;
|
|
1468
1610
|
metadata["parentEnd"] = parent.Span.End;
|
|
1469
1611
|
metadata["parentKind"] = parent.Kind().ToString();
|
|
@@ -1501,6 +1643,7 @@ namespace Pando.CSharpIndexer
|
|
|
1501
1643
|
for (var i = 0; i < ordered.Count; i++)
|
|
1502
1644
|
{
|
|
1503
1645
|
var metadata = ordered[i].Metadata ??= new Dictionary<string, object?>();
|
|
1646
|
+
ordered[i].IndexInParent = i;
|
|
1504
1647
|
metadata["indexInParent"] = i;
|
|
1505
1648
|
}
|
|
1506
1649
|
}
|
|
@@ -1508,17 +1651,14 @@ namespace Pando.CSharpIndexer
|
|
|
1508
1651
|
foreach (var cliNode in nodes)
|
|
1509
1652
|
{
|
|
1510
1653
|
var depth = 0;
|
|
1511
|
-
var
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
&& metadata.TryGetValue("parentEnd", out var end)
|
|
1515
|
-
&& metadata.TryGetValue("parentKind", out var kind))
|
|
1654
|
+
var parentIndex = cliNode.ParentIndex;
|
|
1655
|
+
var visited = new HashSet<int>();
|
|
1656
|
+
while (parentIndex != null && parentIndex >= 0 && parentIndex < nodes.Count && visited.Add(parentIndex.Value))
|
|
1516
1657
|
{
|
|
1517
|
-
var parentKey = NodeKey(Convert.ToInt32(start), Convert.ToInt32(end), Convert.ToString(kind) ?? "");
|
|
1518
|
-
if (!nodeByKey.TryGetValue(parentKey, out var parent)) { break; }
|
|
1519
1658
|
depth++;
|
|
1520
|
-
|
|
1659
|
+
parentIndex = nodes[parentIndex.Value].ParentIndex;
|
|
1521
1660
|
}
|
|
1661
|
+
cliNode.Depth = depth;
|
|
1522
1662
|
cliNode.Metadata ??= new Dictionary<string, object?>();
|
|
1523
1663
|
cliNode.Metadata["depth"] = depth;
|
|
1524
1664
|
}
|