Skip to content

Commit 2719a69

Browse files
author
StArray
committed
refactor(all): 添加Stub的dll生成器,并优化部分代码
1 parent 386894e commit 2719a69

53 files changed

Lines changed: 8783 additions & 4341 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.gitattributes‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# Normalize text files to UTF-8 without BOM and LF line endings.
2+
# This prevents PowerShell and other tools from corrupting encodings.
3+
4+
* text=auto eol=lf
5+
6+
# Source code
7+
*.cs text diff=csharp
8+
*.csproj text
9+
*.slnx text
10+
*.props text
11+
*.targets text
12+
*.json text
13+
*.xml text
14+
*.yml text
15+
*.yaml text
16+
*.editorconfig text
17+
*.cmake text
18+
Makefile text
19+
*.java text
20+
*.kt text
21+
22+
# Scripts
23+
*.sh text eol=lf
24+
*.bat text eol=crlf
25+
*.cmd text eol=crlf
26+
27+
# Docs
28+
*.md text diff=markdown
29+
*.txt text
30+
31+
# Native code
32+
*.c text
33+
*.h text
34+
*.hpp text
35+
*.cpp text
36+
37+
38+
# Gradle
39+
*.gradle text
40+
/gradlew text eol=lf
41+
42+
# Binary / generated
43+
*.png binary
44+
*.jpg binary
45+
*.ico binary
46+
*.ttf binary
47+
*.otf binary
48+
*.so binary
49+
*.dll binary
50+
*.exe binary
51+
*.lib binary
52+
*.a binary
53+
*.obj binary
54+
*.pdb binary
55+
*.apk binary
56+
*.aar binary
57+
*.jar binary
58+
*.zip binary
59+
*.tar binary
60+
*.gz binary

‎.gitignore‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,6 @@ LevelDebugger
7474
.vscode
7575
log.txt
7676
imgui.ini
77-
Corehold
77+
Corehold
78+
.claude
79+
.backup

‎Android/library/src/main/cpp/core/misc.c‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//
1+
//
22
// Created by StArray on 2026/7/19.
33
//
44
#include <stdio.h>
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
using Microsoft.CodeAnalysis;
2+
3+
namespace StArray.ModManager.Analyzer;
4+
5+
/// <summary>
6+
/// 生成器诊断。此前所有失败路径都是静默 return/continue —— 用户漏写 partial、漏写 static、
7+
/// 或程序集名少了 .dll,都不会有任何提示,只能在运行时表现为「功能不存在」。
8+
/// </summary>
9+
internal static class Diagnostics
10+
{
11+
private const string Category = "StArray.ModManager";
12+
13+
/// <summary>类标了 [UnmanagedType] 却不是 partial</summary>
14+
public static readonly DiagnosticDescriptor TypeNotPartial = new(
15+
"SAMM001",
16+
"标记 [UnmanagedType] 的类必须是 partial",
17+
"类型 '{0}' 标记了 [UnmanagedType],但不是 partial —— 不会为它生成任何存根实现",
18+
Category, DiagnosticSeverity.Error, isEnabledByDefault: true);
19+
20+
/// <summary>成员标了 [UnmanagedMember] 却不是 partial 定义</summary>
21+
public static readonly DiagnosticDescriptor MemberNotPartial = new(
22+
"SAMM002",
23+
"标记 [UnmanagedMember] 的方法必须是 partial 定义",
24+
"方法 '{0}' 标记了 [UnmanagedMember],但不是无实现的 partial 定义 —— 会被跳过",
25+
Category, DiagnosticSeverity.Error, isEnabledByDefault: true);
26+
27+
/// <summary>类里没有任何可生成的成员</summary>
28+
public static readonly DiagnosticDescriptor NoMembers = new(
29+
"SAMM003",
30+
"[UnmanagedType] 类型没有可生成的成员",
31+
"类型 '{0}' 标记了 [UnmanagedType],但没有任何标记 [UnmanagedMember] 的 partial 方法",
32+
Category, DiagnosticSeverity.Warning, isEnabledByDefault: true);
33+
34+
/// <summary>程序集名缺少 .dll 后缀</summary>
35+
public static readonly DiagnosticDescriptor AssemblyNameMissingDll = new(
36+
"SAMM004",
37+
"程序集名应带 .dll 后缀",
38+
"程序集名 '{0}' 缺少 .dll 后缀;运行时通过 OpenAssembly 解析,需要文件名形式(如 \"{0}.dll\"),否则会在运行时静默解析失败",
39+
Category, DiagnosticSeverity.Warning, isEnabledByDefault: true);
40+
41+
/// <summary>Hook 方法不是 static</summary>
42+
public static readonly DiagnosticDescriptor HookNotStatic = new(
43+
"SAMM005",
44+
"Hook 方法必须是 static",
45+
"方法 '{0}' 标记了 Hook 特性,但不是 static —— 不会为它生成任何 hook 代码",
46+
Category, DiagnosticSeverity.Error, isEnabledByDefault: true);
47+
48+
/// <summary>Hook 的目标类型/方法名为空</summary>
49+
public static readonly DiagnosticDescriptor HookMissingTarget = new(
50+
"SAMM006",
51+
"Hook 缺少目标信息",
52+
"方法 '{0}' 的 Hook 特性缺少必要的目标参数({1})",
53+
Category, DiagnosticSeverity.Error, isEnabledByDefault: true);
54+
55+
/// <summary>[NativeImport] 方法不是 partial / 有实现体</summary>
56+
public static readonly DiagnosticDescriptor ImportNotPartial = new(
57+
"SAMM007",
58+
"标记 [NativeImport] 的方法必须是无实现的 partial 定义",
59+
"方法 '{0}' 标记了 [NativeImport],但不是无实现的 partial 定义 —— 会被跳过",
60+
Category, DiagnosticSeverity.Error, isEnabledByDefault: true);
61+
62+
/// <summary>[NativeImport] 未指定库名,且所在类也没有类级默认库</summary>
63+
public static readonly DiagnosticDescriptor ImportMissingLibrary = new(
64+
"SAMM008",
65+
"[NativeImport] 缺少库名",
66+
"方法 '{0}' 未指定库名,且其所在类型没有类级默认库",
67+
Category, DiagnosticSeverity.Error, isEnabledByDefault: true);
68+
69+
/// <summary>实例 Hook 的首参不是 nint</summary>
70+
public static readonly DiagnosticDescriptor HookFirstParamNotThis = new(
71+
"SAMM009",
72+
"实例方法 Hook 的首个参数应为 nint(this 指针)",
73+
"方法 '{0}' 的首个参数是 '{1}';被 hook 的实例方法在 native 侧首参为 this 指针,通常应声明为 nint",
74+
Category, DiagnosticSeverity.Info, isEnabledByDefault: true);
75+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System;
2+
using System.Collections;
3+
using System.Collections.Generic;
4+
using System.Collections.Immutable;
5+
using System.Linq;
6+
7+
namespace StArray.ModManager.Analyzer;
8+
9+
/// <summary>
10+
/// 带值相等语义的不可变数组。
11+
///
12+
/// 增量生成器靠模型的 <c>Equals</c> 判断下游要不要重算,而 <see cref="ImmutableArray{T}"/>
13+
/// 比较的是底层数组引用 —— 直接把它放进模型会让缓存永远 miss,
14+
/// <c>IIncrementalGenerator</c> 退化成每次全量重跑。
15+
/// </summary>
16+
internal readonly struct EquatableArray<T> : IEquatable<EquatableArray<T>>, IEnumerable<T>
17+
where T : IEquatable<T>
18+
{
19+
private readonly T[]? _items;
20+
21+
public EquatableArray(T[]? items) => _items = items;
22+
23+
public EquatableArray(ImmutableArray<T> items) => _items = items.IsDefault ? null : items.ToArray();
24+
25+
public static EquatableArray<T> Empty => new(Array.Empty<T>());
26+
27+
public int Count => _items?.Length ?? 0;
28+
29+
public T this[int index] => _items![index];
30+
31+
public bool Equals(EquatableArray<T> other)
32+
{
33+
if (_items is null || other._items is null) return _items is null && other._items is null;
34+
return _items.AsSpan().SequenceEqual(other._items.AsSpan());
35+
}
36+
37+
public override bool Equals(object? obj) => obj is EquatableArray<T> a && Equals(a);
38+
39+
public override int GetHashCode()
40+
{
41+
if (_items is null) return 0;
42+
var hash = 17;
43+
foreach (var item in _items)
44+
hash = hash * 31 + (item?.GetHashCode() ?? 0);
45+
return hash;
46+
}
47+
48+
public IEnumerator<T> GetEnumerator() => ((IEnumerable<T>)(_items ?? Array.Empty<T>())).GetEnumerator();
49+
50+
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
51+
52+
public static implicit operator EquatableArray<T>(T[] items) => new(items);
53+
public static implicit operator EquatableArray<T>(ImmutableArray<T> items) => new(items);
54+
}
55+
56+
internal static class EquatableArrayExtensions
57+
{
58+
public static EquatableArray<T> ToEquatable<T>(this IEnumerable<T> source) where T : IEquatable<T>
59+
=> new(source.ToArray());
60+
}
61+
62+
/// <summary>参数的类型与名称。用 record struct 以获得值相等。</summary>
63+
internal readonly record struct ParamInfo(string Type, string Name);
64+
65+
/// <summary>特性的具名参数。</summary>
66+
internal readonly record struct NamedArg(string Key, string Value);
67+
68+

0 commit comments

Comments
 (0)