@adhisang/minecraft-modding-mcp 4.0.0 → 4.1.1
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/CHANGELOG.md +61 -0
- package/README.md +40 -23
- package/dist/build-suggested-call.d.ts +29 -0
- package/dist/build-suggested-call.js +58 -0
- package/dist/cache-registry.d.ts +3 -1
- package/dist/cache-registry.js +50 -6
- package/dist/entry-tools/analyze-symbol-service.d.ts +16 -16
- package/dist/entry-tools/batch-class-members-service.d.ts +34 -0
- package/dist/entry-tools/batch-class-members-service.js +97 -0
- package/dist/entry-tools/batch-class-source-service.d.ts +37 -0
- package/dist/entry-tools/batch-class-source-service.js +100 -0
- package/dist/entry-tools/batch-mappings-service.d.ts +36 -0
- package/dist/entry-tools/batch-mappings-service.js +66 -0
- package/dist/entry-tools/batch-runner.d.ts +72 -0
- package/dist/entry-tools/batch-runner.js +90 -0
- package/dist/entry-tools/batch-symbol-exists-service.d.ts +46 -0
- package/dist/entry-tools/batch-symbol-exists-service.js +113 -0
- package/dist/entry-tools/compare-minecraft-service.d.ts +6 -6
- package/dist/entry-tools/inspect-minecraft/handlers/artifact.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/artifact.js +83 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-members.d.ts +6 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-members.js +80 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-overview.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-overview.js +248 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-source.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/class-source.js +60 -0
- package/dist/entry-tools/inspect-minecraft/handlers/file.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/file.js +54 -0
- package/dist/entry-tools/inspect-minecraft/handlers/list-files.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/list-files.js +100 -0
- package/dist/entry-tools/inspect-minecraft/handlers/search.d.ts +5 -0
- package/dist/entry-tools/inspect-minecraft/handlers/search.js +155 -0
- package/dist/entry-tools/inspect-minecraft/handlers/versions.d.ts +6 -0
- package/dist/entry-tools/inspect-minecraft/handlers/versions.js +49 -0
- package/dist/entry-tools/inspect-minecraft/internal.d.ts +1042 -0
- package/dist/entry-tools/inspect-minecraft/internal.js +448 -0
- package/dist/entry-tools/inspect-minecraft-service.d.ts +193 -308
- package/dist/entry-tools/inspect-minecraft-service.js +20 -1244
- package/dist/entry-tools/manage-cache-service.d.ts +16 -16
- package/dist/entry-tools/validate-project/cases/access-transformer.d.ts +6 -0
- package/dist/entry-tools/validate-project/cases/access-transformer.js +106 -0
- package/dist/entry-tools/validate-project/cases/access-widener.d.ts +6 -0
- package/dist/entry-tools/validate-project/cases/access-widener.js +86 -0
- package/dist/entry-tools/validate-project/cases/mixin.d.ts +6 -0
- package/dist/entry-tools/validate-project/cases/mixin.js +90 -0
- package/dist/entry-tools/validate-project/cases/project-summary.d.ts +102 -0
- package/dist/entry-tools/validate-project/cases/project-summary.js +415 -0
- package/dist/entry-tools/validate-project/internal.d.ts +142 -0
- package/dist/entry-tools/validate-project/internal.js +303 -0
- package/dist/entry-tools/validate-project-service.d.ts +67 -47
- package/dist/entry-tools/validate-project-service.js +13 -563
- package/dist/entry-tools/verify-mixin-target-service.d.ts +133 -0
- package/dist/entry-tools/verify-mixin-target-service.js +323 -0
- package/dist/error-mapping.d.ts +40 -0
- package/dist/error-mapping.js +139 -0
- package/dist/errors.d.ts +6 -0
- package/dist/errors.js +6 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +147 -1354
- package/dist/mapping/internal-types.d.ts +54 -0
- package/dist/mapping/internal-types.js +14 -0
- package/dist/mapping/loaders/mojang.d.ts +2 -0
- package/dist/mapping/loaders/mojang.js +64 -0
- package/dist/mapping/loaders/tiny-loom.d.ts +2 -0
- package/dist/mapping/loaders/tiny-loom.js +73 -0
- package/dist/mapping/loaders/tiny-maven.d.ts +2 -0
- package/dist/mapping/loaders/tiny-maven.js +104 -0
- package/dist/mapping/loaders/types.d.ts +14 -0
- package/dist/mapping/loaders/types.js +2 -0
- package/dist/mapping/lookup.d.ts +52 -0
- package/dist/mapping/lookup.js +496 -0
- package/dist/mapping/parsers/normalize.d.ts +10 -0
- package/dist/mapping/parsers/normalize.js +52 -0
- package/dist/mapping/parsers/proguard.d.ts +20 -0
- package/dist/mapping/parsers/proguard.js +138 -0
- package/dist/mapping/parsers/symbol-records.d.ts +27 -0
- package/dist/mapping/parsers/symbol-records.js +216 -0
- package/dist/mapping/parsers/tiny.d.ts +9 -0
- package/dist/mapping/parsers/tiny.js +96 -0
- package/dist/mapping/types.d.ts +147 -0
- package/dist/mapping/types.js +2 -0
- package/dist/mapping-pipeline-service.js +3 -2
- package/dist/mapping-service.d.ts +8 -145
- package/dist/mapping-service.js +30 -1207
- package/dist/mixin/access-validators.d.ts +9 -0
- package/dist/mixin/access-validators.js +257 -0
- package/dist/mixin/annotation-validators.d.ts +5 -0
- package/dist/mixin/annotation-validators.js +162 -0
- package/dist/mixin/helpers.d.ts +28 -0
- package/dist/mixin/helpers.js +315 -0
- package/dist/mixin/parsed-validator.d.ts +8 -0
- package/dist/mixin/parsed-validator.js +337 -0
- package/dist/mixin/types.d.ts +208 -0
- package/dist/mixin/types.js +28 -0
- package/dist/mixin-validator.d.ts +9 -201
- package/dist/mixin-validator.js +8 -1020
- package/dist/source/access-validate.d.ts +4 -0
- package/dist/source/access-validate.js +254 -0
- package/dist/source/artifact-resolver.d.ts +111 -0
- package/dist/source/artifact-resolver.js +1271 -0
- package/dist/source/cache-metrics.d.ts +26 -0
- package/dist/source/cache-metrics.js +172 -0
- package/dist/source/class-source/members-builder.d.ts +34 -0
- package/dist/source/class-source/members-builder.js +46 -0
- package/dist/source/class-source/snippet-builder.d.ts +19 -0
- package/dist/source/class-source/snippet-builder.js +46 -0
- package/dist/source/class-source-helpers.d.ts +34 -0
- package/dist/source/class-source-helpers.js +140 -0
- package/dist/source/class-source.d.ts +42 -0
- package/dist/source/class-source.js +883 -0
- package/dist/source/descriptor-utils.d.ts +6 -0
- package/dist/source/descriptor-utils.js +37 -0
- package/dist/source/file-access.d.ts +4 -0
- package/dist/source/file-access.js +102 -0
- package/dist/source/indexer.d.ts +82 -0
- package/dist/source/indexer.js +522 -0
- package/dist/source/lifecycle/diff-utils.d.ts +9 -0
- package/dist/source/lifecycle/diff-utils.js +107 -0
- package/dist/source/lifecycle/diff.d.ts +2 -0
- package/dist/source/lifecycle/diff.js +265 -0
- package/dist/source/lifecycle/mapping-helpers.d.ts +22 -0
- package/dist/source/lifecycle/mapping-helpers.js +327 -0
- package/dist/source/lifecycle/runtime-check.d.ts +2 -0
- package/dist/source/lifecycle/runtime-check.js +142 -0
- package/dist/source/lifecycle/trace.d.ts +2 -0
- package/dist/source/lifecycle/trace.js +231 -0
- package/dist/source/lifecycle.d.ts +4 -0
- package/dist/source/lifecycle.js +5 -0
- package/dist/source/search.d.ts +51 -0
- package/dist/source/search.js +676 -0
- package/dist/source/shared-utils.d.ts +6 -0
- package/dist/source/shared-utils.js +55 -0
- package/dist/source/state.d.ts +26 -0
- package/dist/source/state.js +24 -0
- package/dist/source/symbol-resolver.d.ts +3 -0
- package/dist/source/symbol-resolver.js +212 -0
- package/dist/source/validate-mixin/pipeline/mapping-health.d.ts +3 -0
- package/dist/source/validate-mixin/pipeline/mapping-health.js +41 -0
- package/dist/source/validate-mixin/pipeline/parse.d.ts +2 -0
- package/dist/source/validate-mixin/pipeline/parse.js +10 -0
- package/dist/source/validate-mixin/pipeline/resolve.d.ts +3 -0
- package/dist/source/validate-mixin/pipeline/resolve.js +78 -0
- package/dist/source/validate-mixin/pipeline/target-lookup.d.ts +6 -0
- package/dist/source/validate-mixin/pipeline/target-lookup.js +260 -0
- package/dist/source/validate-mixin/pipeline-context.d.ts +72 -0
- package/dist/source/validate-mixin/pipeline-context.js +93 -0
- package/dist/source/validate-mixin.d.ts +22 -0
- package/dist/source/validate-mixin.js +799 -0
- package/dist/source/workspace-target.d.ts +18 -0
- package/dist/source/workspace-target.js +305 -0
- package/dist/source-resolver.d.ts +1 -0
- package/dist/source-resolver.js +1 -1
- package/dist/source-service.d.ts +164 -170
- package/dist/source-service.js +70 -6116
- package/dist/stage-emitter.d.ts +13 -0
- package/dist/stage-emitter.js +30 -0
- package/dist/stdio-supervisor.d.ts +61 -0
- package/dist/stdio-supervisor.js +326 -9
- package/dist/tool-contract-manifest.d.ts +1 -1
- package/dist/tool-contract-manifest.js +23 -6
- package/dist/tool-guidance.d.ts +82 -0
- package/dist/tool-guidance.js +734 -0
- package/dist/tool-schema-registry.d.ts +16 -0
- package/dist/tool-schema-registry.js +37 -0
- package/dist/tool-schemas.d.ts +3518 -0
- package/dist/tool-schemas.js +813 -0
- package/dist/types.d.ts +36 -0
- package/dist/version-service.js +7 -6
- package/dist/workspace-context-cache.d.ts +32 -0
- package/dist/workspace-context-cache.js +66 -0
- package/dist/workspace-mapping-service.d.ts +16 -0
- package/dist/workspace-mapping-service.js +173 -1
- package/docs/README-ja.md +416 -0
- package/docs/examples.md +483 -0
- package/docs/tool-reference.md +462 -0
- package/package.json +17 -4
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { buildSuggestedCall } from "../../build-suggested-call.js";
|
|
2
|
+
import { ERROR_CODES, createError, isAppError } from "../../errors.js";
|
|
3
|
+
import { compactDiffDelta, diffMembersByKey, emptyDiffDelta, sortDiffMembers } from "./diff-utils.js";
|
|
4
|
+
import { normalizeMapping, resolveToObfuscatedClassName } from "./mapping-helpers.js";
|
|
5
|
+
export async function diffClassSignatures(svc, input) {
|
|
6
|
+
const className = input.className.trim();
|
|
7
|
+
const fromVersion = input.fromVersion.trim();
|
|
8
|
+
const toVersion = input.toVersion.trim();
|
|
9
|
+
const includeFullDiff = input.includeFullDiff ?? true;
|
|
10
|
+
if (!className || !fromVersion || !toVersion) {
|
|
11
|
+
throw createError({
|
|
12
|
+
code: ERROR_CODES.INVALID_INPUT,
|
|
13
|
+
message: "className, fromVersion, and toVersion must be non-empty strings.",
|
|
14
|
+
details: {
|
|
15
|
+
className: input.className,
|
|
16
|
+
fromVersion: input.fromVersion,
|
|
17
|
+
toVersion: input.toVersion
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const mapping = normalizeMapping(input.mapping);
|
|
22
|
+
const manifestOrder = await svc.versionService.listVersionIds();
|
|
23
|
+
if (manifestOrder.length === 0) {
|
|
24
|
+
throw createError({
|
|
25
|
+
code: ERROR_CODES.VERSION_NOT_FOUND,
|
|
26
|
+
message: "No Minecraft versions were returned by manifest.",
|
|
27
|
+
details: {
|
|
28
|
+
nextAction: "Use list-versions to see available Minecraft versions.",
|
|
29
|
+
...buildSuggestedCall({ tool: "list-versions", params: {} })
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
const chronological = [...manifestOrder].reverse();
|
|
34
|
+
const fromIndex = chronological.indexOf(fromVersion);
|
|
35
|
+
const toIndex = chronological.indexOf(toVersion);
|
|
36
|
+
if (fromIndex < 0) {
|
|
37
|
+
throw createError({
|
|
38
|
+
code: ERROR_CODES.VERSION_NOT_FOUND,
|
|
39
|
+
message: `fromVersion "${fromVersion}" was not found in manifest.`,
|
|
40
|
+
details: {
|
|
41
|
+
fromVersion,
|
|
42
|
+
nextAction: "Use list-versions to see available Minecraft versions.",
|
|
43
|
+
...buildSuggestedCall({ tool: "list-versions", params: {} })
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
if (toIndex < 0) {
|
|
48
|
+
throw createError({
|
|
49
|
+
code: ERROR_CODES.VERSION_NOT_FOUND,
|
|
50
|
+
message: `toVersion "${toVersion}" was not found in manifest.`,
|
|
51
|
+
details: {
|
|
52
|
+
toVersion,
|
|
53
|
+
nextAction: "Use list-versions to see available Minecraft versions.",
|
|
54
|
+
...buildSuggestedCall({ tool: "list-versions", params: {} })
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
if (fromIndex > toIndex) {
|
|
59
|
+
throw createError({
|
|
60
|
+
code: ERROR_CODES.INVALID_INPUT,
|
|
61
|
+
message: "fromVersion must be older than or equal to toVersion.",
|
|
62
|
+
details: { fromVersion, toVersion }
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
const mappingWarnings = [];
|
|
66
|
+
const obfuscatedFromClassName = await resolveToObfuscatedClassName(svc, className, fromVersion, mapping, input.sourcePriority, mappingWarnings);
|
|
67
|
+
const obfuscatedToClassName = fromVersion === toVersion
|
|
68
|
+
? obfuscatedFromClassName
|
|
69
|
+
: await resolveToObfuscatedClassName(svc, className, toVersion, mapping, input.sourcePriority, mappingWarnings);
|
|
70
|
+
const [fromResolved, toResolved] = await Promise.all([
|
|
71
|
+
svc.versionService.resolveVersionJar(fromVersion),
|
|
72
|
+
svc.versionService.resolveVersionJar(toVersion)
|
|
73
|
+
]);
|
|
74
|
+
const loadSignature = async (version, jarPath, obfuscatedClassName) => {
|
|
75
|
+
try {
|
|
76
|
+
const signature = await svc.explorerService.getSignature({
|
|
77
|
+
fqn: obfuscatedClassName,
|
|
78
|
+
jarPath,
|
|
79
|
+
access: "all",
|
|
80
|
+
includeSynthetic: false,
|
|
81
|
+
includeInherited: false
|
|
82
|
+
});
|
|
83
|
+
return {
|
|
84
|
+
constructors: signature.constructors,
|
|
85
|
+
fields: signature.fields,
|
|
86
|
+
methods: signature.methods,
|
|
87
|
+
warnings: signature.warnings
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
catch (caughtError) {
|
|
91
|
+
if (isAppError(caughtError) && caughtError.code === ERROR_CODES.CLASS_NOT_FOUND) {
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
throw caughtError;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
const [fromSignature, toSignature] = await Promise.all([
|
|
98
|
+
loadSignature(fromVersion, fromResolved.jarPath, obfuscatedFromClassName),
|
|
99
|
+
loadSignature(toVersion, toResolved.jarPath, obfuscatedToClassName)
|
|
100
|
+
]);
|
|
101
|
+
const warnings = [...mappingWarnings];
|
|
102
|
+
if (fromSignature) {
|
|
103
|
+
warnings.push(...fromSignature.warnings.map((warning) => `[${fromVersion}] ${warning}`));
|
|
104
|
+
}
|
|
105
|
+
if (toSignature) {
|
|
106
|
+
warnings.push(...toSignature.warnings.map((warning) => `[${toVersion}] ${warning}`));
|
|
107
|
+
}
|
|
108
|
+
let classChange = "present_in_both";
|
|
109
|
+
if (!fromSignature && !toSignature) {
|
|
110
|
+
classChange = "absent_in_both";
|
|
111
|
+
warnings.push(`Class "${className}" was not found in both versions.`);
|
|
112
|
+
}
|
|
113
|
+
else if (!fromSignature) {
|
|
114
|
+
classChange = "added";
|
|
115
|
+
}
|
|
116
|
+
else if (!toSignature) {
|
|
117
|
+
classChange = "removed";
|
|
118
|
+
}
|
|
119
|
+
const fromMembers = fromSignature ?? {
|
|
120
|
+
constructors: [],
|
|
121
|
+
fields: [],
|
|
122
|
+
methods: [],
|
|
123
|
+
warnings: []
|
|
124
|
+
};
|
|
125
|
+
const toMembers = toSignature ?? {
|
|
126
|
+
constructors: [],
|
|
127
|
+
fields: [],
|
|
128
|
+
methods: [],
|
|
129
|
+
warnings: []
|
|
130
|
+
};
|
|
131
|
+
const constructors = classChange === "added"
|
|
132
|
+
? {
|
|
133
|
+
added: sortDiffMembers(toMembers.constructors),
|
|
134
|
+
removed: [],
|
|
135
|
+
modified: []
|
|
136
|
+
}
|
|
137
|
+
: classChange === "removed"
|
|
138
|
+
? {
|
|
139
|
+
added: [],
|
|
140
|
+
removed: sortDiffMembers(fromMembers.constructors),
|
|
141
|
+
modified: []
|
|
142
|
+
}
|
|
143
|
+
: classChange === "absent_in_both"
|
|
144
|
+
? emptyDiffDelta()
|
|
145
|
+
: diffMembersByKey(fromMembers.constructors, toMembers.constructors, (member) => member.jvmDescriptor, false);
|
|
146
|
+
const methods = classChange === "added"
|
|
147
|
+
? {
|
|
148
|
+
added: sortDiffMembers(toMembers.methods),
|
|
149
|
+
removed: [],
|
|
150
|
+
modified: []
|
|
151
|
+
}
|
|
152
|
+
: classChange === "removed"
|
|
153
|
+
? {
|
|
154
|
+
added: [],
|
|
155
|
+
removed: sortDiffMembers(fromMembers.methods),
|
|
156
|
+
modified: []
|
|
157
|
+
}
|
|
158
|
+
: classChange === "absent_in_both"
|
|
159
|
+
? emptyDiffDelta()
|
|
160
|
+
: diffMembersByKey(fromMembers.methods, toMembers.methods, (member) => `${member.name}#${member.jvmDescriptor}`, false);
|
|
161
|
+
const fields = classChange === "added"
|
|
162
|
+
? {
|
|
163
|
+
added: sortDiffMembers(toMembers.fields),
|
|
164
|
+
removed: [],
|
|
165
|
+
modified: []
|
|
166
|
+
}
|
|
167
|
+
: classChange === "removed"
|
|
168
|
+
? {
|
|
169
|
+
added: [],
|
|
170
|
+
removed: sortDiffMembers(fromMembers.fields),
|
|
171
|
+
modified: []
|
|
172
|
+
}
|
|
173
|
+
: classChange === "absent_in_both"
|
|
174
|
+
? emptyDiffDelta()
|
|
175
|
+
: diffMembersByKey(fromMembers.fields, toMembers.fields, (member) => member.name, true);
|
|
176
|
+
// Remap diff delta members for non-obfuscated mappings
|
|
177
|
+
const remapDelta = async (delta, kind) => {
|
|
178
|
+
const [addedResult, removedResult] = await Promise.all([
|
|
179
|
+
svc.remapSignatureMembers(delta.added, kind, toVersion, "obfuscated", mapping, input.sourcePriority, warnings),
|
|
180
|
+
svc.remapSignatureMembers(delta.removed, kind, fromVersion, "obfuscated", mapping, input.sourcePriority, warnings)
|
|
181
|
+
]);
|
|
182
|
+
const remappedModified = await Promise.all(delta.modified.map(async (change) => {
|
|
183
|
+
if (!change.from || !change.to) {
|
|
184
|
+
throw createError({
|
|
185
|
+
code: ERROR_CODES.INTERNAL,
|
|
186
|
+
message: "Modified diff members are missing before remap.",
|
|
187
|
+
details: {
|
|
188
|
+
key: change.key,
|
|
189
|
+
kind,
|
|
190
|
+
fromVersion,
|
|
191
|
+
toVersion,
|
|
192
|
+
mapping
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
const [fromResult, toResult] = await Promise.all([
|
|
197
|
+
svc.remapSignatureMembers([change.from], kind, fromVersion, "obfuscated", mapping, input.sourcePriority, warnings),
|
|
198
|
+
svc.remapSignatureMembers([change.to], kind, toVersion, "obfuscated", mapping, input.sourcePriority, warnings)
|
|
199
|
+
]);
|
|
200
|
+
const fromMember = fromResult.members[0];
|
|
201
|
+
const toMember = toResult.members[0];
|
|
202
|
+
if (!fromMember || !toMember) {
|
|
203
|
+
throw createError({
|
|
204
|
+
code: ERROR_CODES.INTERNAL,
|
|
205
|
+
message: "Failed to remap modified diff members.",
|
|
206
|
+
details: {
|
|
207
|
+
key: change.key,
|
|
208
|
+
kind,
|
|
209
|
+
fromVersion,
|
|
210
|
+
toVersion,
|
|
211
|
+
mapping
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return { ...change, from: fromMember, to: toMember };
|
|
216
|
+
}));
|
|
217
|
+
return { added: addedResult.members, removed: removedResult.members, modified: remappedModified };
|
|
218
|
+
};
|
|
219
|
+
const [remappedConstructors, remappedMethods, remappedFields] = await Promise.all([
|
|
220
|
+
remapDelta(constructors, "method"),
|
|
221
|
+
remapDelta(methods, "method"),
|
|
222
|
+
remapDelta(fields, "field")
|
|
223
|
+
]);
|
|
224
|
+
const summary = {
|
|
225
|
+
constructors: {
|
|
226
|
+
added: remappedConstructors.added.length,
|
|
227
|
+
removed: remappedConstructors.removed.length,
|
|
228
|
+
modified: remappedConstructors.modified.length
|
|
229
|
+
},
|
|
230
|
+
methods: {
|
|
231
|
+
added: remappedMethods.added.length,
|
|
232
|
+
removed: remappedMethods.removed.length,
|
|
233
|
+
modified: remappedMethods.modified.length
|
|
234
|
+
},
|
|
235
|
+
fields: {
|
|
236
|
+
added: remappedFields.added.length,
|
|
237
|
+
removed: remappedFields.removed.length,
|
|
238
|
+
modified: remappedFields.modified.length
|
|
239
|
+
},
|
|
240
|
+
total: {
|
|
241
|
+
added: remappedConstructors.added.length + remappedMethods.added.length + remappedFields.added.length,
|
|
242
|
+
removed: remappedConstructors.removed.length + remappedMethods.removed.length + remappedFields.removed.length,
|
|
243
|
+
modified: remappedConstructors.modified.length + remappedMethods.modified.length + remappedFields.modified.length
|
|
244
|
+
}
|
|
245
|
+
};
|
|
246
|
+
return {
|
|
247
|
+
query: {
|
|
248
|
+
className,
|
|
249
|
+
fromVersion,
|
|
250
|
+
toVersion,
|
|
251
|
+
mapping
|
|
252
|
+
},
|
|
253
|
+
range: {
|
|
254
|
+
fromVersion,
|
|
255
|
+
toVersion
|
|
256
|
+
},
|
|
257
|
+
classChange,
|
|
258
|
+
constructors: includeFullDiff ? remappedConstructors : compactDiffDelta(remappedConstructors),
|
|
259
|
+
methods: includeFullDiff ? remappedMethods : compactDiffDelta(remappedMethods),
|
|
260
|
+
fields: includeFullDiff ? remappedFields : compactDiffDelta(remappedFields),
|
|
261
|
+
summary,
|
|
262
|
+
warnings
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { SignatureMember } from "../../minecraft-explorer-service.js";
|
|
2
|
+
import type { SourceService } from "../../source-service.js";
|
|
3
|
+
import type { MappingSourcePriority, SourceMapping } from "../../types.js";
|
|
4
|
+
export declare function normalizeMapping(mapping: SourceMapping | undefined): SourceMapping;
|
|
5
|
+
export declare function rejectLifecycleClassLikeInput(svc: SourceService, input: {
|
|
6
|
+
symbol: string;
|
|
7
|
+
className: string;
|
|
8
|
+
methodName: string;
|
|
9
|
+
mapping: SourceMapping;
|
|
10
|
+
version?: string;
|
|
11
|
+
sourcePriority?: MappingSourcePriority;
|
|
12
|
+
}): void;
|
|
13
|
+
export declare function releaseLifecycleMappingGraph(svc: SourceService, version: string, sourcePriority: MappingSourcePriority | undefined): void;
|
|
14
|
+
export declare function resolveToObfuscatedClassName(svc: SourceService, className: string, version: string, mapping: SourceMapping, sourcePriority: MappingSourcePriority | undefined, warnings: string[]): Promise<string>;
|
|
15
|
+
export declare function resolveToObfuscatedMemberName(svc: SourceService, name: string, ownerInSourceMapping: string, descriptor: string | undefined, kind: "field" | "method", version: string, mapping: SourceMapping, sourcePriority: MappingSourcePriority | undefined, warnings: string[]): Promise<{
|
|
16
|
+
name: string;
|
|
17
|
+
descriptor?: string;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function remapSignatureMembers(svc: SourceService, members: SignatureMember[], kind: "field" | "method", version: string, sourceMapping: SourceMapping, targetMapping: SourceMapping, sourcePriority: MappingSourcePriority | undefined, warnings: string[], projectPath?: string): Promise<{
|
|
20
|
+
members: SignatureMember[];
|
|
21
|
+
failedNames: Set<string>;
|
|
22
|
+
}>;
|
|
@@ -0,0 +1,327 @@
|
|
|
1
|
+
import { buildSuggestedCall } from "../../build-suggested-call.js";
|
|
2
|
+
import { ERROR_CODES, createError } from "../../errors.js";
|
|
3
|
+
import { rebuildJavaSignature, remapJvmDescriptor } from "../descriptor-utils.js";
|
|
4
|
+
export function normalizeMapping(mapping) {
|
|
5
|
+
if (mapping == null) {
|
|
6
|
+
return "obfuscated";
|
|
7
|
+
}
|
|
8
|
+
if (mapping === "obfuscated" ||
|
|
9
|
+
mapping === "mojang" ||
|
|
10
|
+
mapping === "intermediary" ||
|
|
11
|
+
mapping === "yarn") {
|
|
12
|
+
return mapping;
|
|
13
|
+
}
|
|
14
|
+
throw createError({
|
|
15
|
+
code: ERROR_CODES.MAPPING_UNAVAILABLE,
|
|
16
|
+
message: `Unsupported mapping "${mapping}".`,
|
|
17
|
+
details: {
|
|
18
|
+
mapping,
|
|
19
|
+
nextAction: "Try mapping=obfuscated which is always available.",
|
|
20
|
+
...buildSuggestedCall({ tool: "resolve-artifact", params: { mapping: "obfuscated" } })
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
function looksLikeClassSegment(name) {
|
|
25
|
+
const trimmed = name.trim();
|
|
26
|
+
return /^[A-Z_$]/.test(trimmed);
|
|
27
|
+
}
|
|
28
|
+
export function rejectLifecycleClassLikeInput(svc, input) {
|
|
29
|
+
void svc;
|
|
30
|
+
if (!looksLikeClassSegment(input.methodName)) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const classLikeSymbol = `${input.className}.${input.methodName}`;
|
|
34
|
+
throw createError({
|
|
35
|
+
code: ERROR_CODES.INVALID_INPUT,
|
|
36
|
+
message: `symbol must be in the form "fully.qualified.Class.method".`,
|
|
37
|
+
details: {
|
|
38
|
+
symbol: input.symbol,
|
|
39
|
+
classLikeSymbol,
|
|
40
|
+
nextAction: "Pass lifecycle input as Class.method and use the separate descriptor field for exact overload matching.",
|
|
41
|
+
...(input.version
|
|
42
|
+
? buildSuggestedCall({
|
|
43
|
+
tool: "check-symbol-exists",
|
|
44
|
+
params: {
|
|
45
|
+
version: input.version,
|
|
46
|
+
kind: "class",
|
|
47
|
+
name: classLikeSymbol,
|
|
48
|
+
sourceMapping: input.mapping
|
|
49
|
+
}
|
|
50
|
+
})
|
|
51
|
+
: {})
|
|
52
|
+
}
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
export function releaseLifecycleMappingGraph(svc, version, sourcePriority) {
|
|
56
|
+
if ("releaseGraphCacheEntry" in svc.mappingService &&
|
|
57
|
+
typeof svc.mappingService.releaseGraphCacheEntry === "function") {
|
|
58
|
+
svc.mappingService.releaseGraphCacheEntry(version, sourcePriority);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export async function resolveToObfuscatedClassName(svc, className, version, mapping, sourcePriority, warnings) {
|
|
62
|
+
return svc.resolveClassNameForLookup({
|
|
63
|
+
className,
|
|
64
|
+
version,
|
|
65
|
+
sourceMapping: mapping,
|
|
66
|
+
targetMapping: "obfuscated",
|
|
67
|
+
sourcePriority,
|
|
68
|
+
warnings,
|
|
69
|
+
context: "bytecode lookup"
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
export async function resolveToObfuscatedMemberName(svc, name, ownerInSourceMapping, descriptor, kind, version, mapping, sourcePriority, warnings) {
|
|
73
|
+
if (mapping === "obfuscated") {
|
|
74
|
+
return {
|
|
75
|
+
name,
|
|
76
|
+
descriptor: kind === "method" ? descriptor : undefined
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const canResolveMethodExactly = kind === "method" &&
|
|
81
|
+
descriptor &&
|
|
82
|
+
"resolveMethodMappingExact" in svc.mappingService &&
|
|
83
|
+
typeof svc.mappingService.resolveMethodMappingExact === "function";
|
|
84
|
+
const mapped = canResolveMethodExactly
|
|
85
|
+
? await svc.mappingService.resolveMethodMappingExact({
|
|
86
|
+
version,
|
|
87
|
+
owner: ownerInSourceMapping,
|
|
88
|
+
name,
|
|
89
|
+
descriptor,
|
|
90
|
+
sourceMapping: mapping,
|
|
91
|
+
targetMapping: "obfuscated",
|
|
92
|
+
sourcePriority
|
|
93
|
+
})
|
|
94
|
+
: await svc.mappingService.findMapping({
|
|
95
|
+
version,
|
|
96
|
+
kind,
|
|
97
|
+
name,
|
|
98
|
+
owner: ownerInSourceMapping,
|
|
99
|
+
descriptor,
|
|
100
|
+
// When we do have a descriptor this path is an exact lookup (the resolveMethodMappingExact
|
|
101
|
+
// fast path is chosen instead whenever possible). findMapping's service-layer default is
|
|
102
|
+
// "name-only" to match the public tool schema, so we must opt in to strict semantics here
|
|
103
|
+
// to preserve the descriptor-aware overload selection this caller relies on.
|
|
104
|
+
signatureMode: kind === "method"
|
|
105
|
+
? descriptor
|
|
106
|
+
? "exact"
|
|
107
|
+
: "name-only"
|
|
108
|
+
: undefined,
|
|
109
|
+
sourceMapping: mapping,
|
|
110
|
+
targetMapping: "obfuscated",
|
|
111
|
+
sourcePriority
|
|
112
|
+
});
|
|
113
|
+
warnings.push(...mapped.warnings);
|
|
114
|
+
if (mapped.resolved && mapped.resolvedSymbol) {
|
|
115
|
+
return {
|
|
116
|
+
name: mapped.resolvedSymbol.name,
|
|
117
|
+
descriptor: kind === "method" ? mapped.resolvedSymbol.descriptor ?? descriptor : undefined
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
if (canResolveMethodExactly && (mapped.status === "not_found" || mapped.status === "mapping_unavailable")) {
|
|
121
|
+
const fallbackMapped = await svc.mappingService.findMapping({
|
|
122
|
+
version,
|
|
123
|
+
kind,
|
|
124
|
+
name,
|
|
125
|
+
owner: ownerInSourceMapping,
|
|
126
|
+
descriptor,
|
|
127
|
+
signatureMode: "exact",
|
|
128
|
+
sourceMapping: mapping,
|
|
129
|
+
targetMapping: "obfuscated",
|
|
130
|
+
sourcePriority
|
|
131
|
+
});
|
|
132
|
+
warnings.push(...fallbackMapped.warnings);
|
|
133
|
+
if (fallbackMapped.resolved && fallbackMapped.resolvedSymbol) {
|
|
134
|
+
return {
|
|
135
|
+
name: fallbackMapped.resolvedSymbol.name,
|
|
136
|
+
descriptor: kind === "method" ? fallbackMapped.resolvedSymbol.descriptor ?? descriptor : undefined
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
warnings.push(`Could not map ${kind} "${name}" from ${mapping} to obfuscated.`);
|
|
141
|
+
}
|
|
142
|
+
catch (caughtError) {
|
|
143
|
+
warnings.push(`Mapping lookup failed for ${kind} "${name}": ${caughtError instanceof Error ? caughtError.message : String(caughtError)}`);
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
name,
|
|
147
|
+
descriptor: kind === "method" ? descriptor : undefined
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
export async function remapSignatureMembers(svc, members, kind, version, sourceMapping, targetMapping, sourcePriority, warnings, projectPath) {
|
|
151
|
+
const failedNames = new Set();
|
|
152
|
+
if (sourceMapping === targetMapping) {
|
|
153
|
+
return { members, failedNames };
|
|
154
|
+
}
|
|
155
|
+
const memberKeyToRemapped = new Map();
|
|
156
|
+
const memberDescriptorRemapped = new Map();
|
|
157
|
+
const ownerToRemapped = new Map();
|
|
158
|
+
for (const member of members) {
|
|
159
|
+
const memberKey = `${member.ownerFqn}\0${member.name}\0${member.jvmDescriptor}`;
|
|
160
|
+
if (!memberKeyToRemapped.has(memberKey)) {
|
|
161
|
+
memberKeyToRemapped.set(memberKey, member.name);
|
|
162
|
+
}
|
|
163
|
+
if (!ownerToRemapped.has(member.ownerFqn)) {
|
|
164
|
+
ownerToRemapped.set(member.ownerFqn, member.ownerFqn);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
const ownerEntries = [...ownerToRemapped.entries()];
|
|
168
|
+
await Promise.all(ownerEntries.map(async ([obfuscatedFqn]) => {
|
|
169
|
+
try {
|
|
170
|
+
const mapped = await svc.mappingService.findMapping({
|
|
171
|
+
version,
|
|
172
|
+
kind: "class",
|
|
173
|
+
name: obfuscatedFqn,
|
|
174
|
+
sourceMapping,
|
|
175
|
+
targetMapping,
|
|
176
|
+
sourcePriority,
|
|
177
|
+
projectPath
|
|
178
|
+
});
|
|
179
|
+
if (mapped.resolved && mapped.resolvedSymbol) {
|
|
180
|
+
ownerToRemapped.set(obfuscatedFqn, mapped.resolvedSymbol.name);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// keep source FQN as fallback
|
|
185
|
+
}
|
|
186
|
+
}));
|
|
187
|
+
const descriptorClassRefs = new Set();
|
|
188
|
+
for (const member of members) {
|
|
189
|
+
for (const match of member.jvmDescriptor.matchAll(/L([^;]+);/g)) {
|
|
190
|
+
const dotFqn = match[1].replace(/\//g, ".");
|
|
191
|
+
if (!ownerToRemapped.has(dotFqn)) {
|
|
192
|
+
descriptorClassRefs.add(dotFqn);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (descriptorClassRefs.size > 0) {
|
|
197
|
+
const refs = [...descriptorClassRefs];
|
|
198
|
+
for (const ref of refs) {
|
|
199
|
+
ownerToRemapped.set(ref, ref);
|
|
200
|
+
}
|
|
201
|
+
await Promise.all(refs.map(async (dotFqn) => {
|
|
202
|
+
try {
|
|
203
|
+
const mapped = await svc.mappingService.findMapping({
|
|
204
|
+
version,
|
|
205
|
+
kind: "class",
|
|
206
|
+
name: dotFqn,
|
|
207
|
+
sourceMapping,
|
|
208
|
+
targetMapping,
|
|
209
|
+
sourcePriority,
|
|
210
|
+
projectPath
|
|
211
|
+
});
|
|
212
|
+
if (mapped.resolved && mapped.resolvedSymbol) {
|
|
213
|
+
ownerToRemapped.set(dotFqn, mapped.resolvedSymbol.name);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// keep source name as fallback
|
|
218
|
+
}
|
|
219
|
+
}));
|
|
220
|
+
}
|
|
221
|
+
const classMap = new Map();
|
|
222
|
+
for (const [src, tgt] of ownerToRemapped) {
|
|
223
|
+
if (src !== tgt) {
|
|
224
|
+
classMap.set(src, tgt);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const canResolveMethodExactly = kind === "method" &&
|
|
228
|
+
"resolveMethodMappingExact" in svc.mappingService &&
|
|
229
|
+
typeof svc.mappingService.resolveMethodMappingExact === "function";
|
|
230
|
+
const memberEntries = [...memberKeyToRemapped.entries()];
|
|
231
|
+
await Promise.all(memberEntries.map(async ([key, _sourceName]) => {
|
|
232
|
+
const [ownerFqn, name, descriptor] = key.split("\0");
|
|
233
|
+
try {
|
|
234
|
+
const targetOwner = ownerToRemapped.get(ownerFqn) ?? ownerFqn;
|
|
235
|
+
if (canResolveMethodExactly && descriptor) {
|
|
236
|
+
try {
|
|
237
|
+
const exactResult = await svc.mappingService.resolveMethodMappingExact({
|
|
238
|
+
version,
|
|
239
|
+
owner: ownerFqn,
|
|
240
|
+
name: name,
|
|
241
|
+
descriptor,
|
|
242
|
+
sourceMapping,
|
|
243
|
+
targetMapping,
|
|
244
|
+
sourcePriority,
|
|
245
|
+
projectPath
|
|
246
|
+
});
|
|
247
|
+
if (exactResult.resolved && exactResult.resolvedSymbol) {
|
|
248
|
+
memberKeyToRemapped.set(key, exactResult.resolvedSymbol.name);
|
|
249
|
+
if (exactResult.resolvedSymbol.descriptor) {
|
|
250
|
+
memberDescriptorRemapped.set(key, exactResult.resolvedSymbol.descriptor);
|
|
251
|
+
}
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (exactError) {
|
|
256
|
+
warnings.push(`Exact method resolution failed for "${name}" (falling back to name-based lookup): ${exactError instanceof Error ? exactError.message : String(exactError)}`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
const remappedDescriptorHint = kind === "method" && descriptor
|
|
260
|
+
? remapJvmDescriptor(descriptor, classMap)
|
|
261
|
+
: undefined;
|
|
262
|
+
const mapped = await svc.mappingService.findMapping({
|
|
263
|
+
version,
|
|
264
|
+
kind,
|
|
265
|
+
name,
|
|
266
|
+
owner: ownerFqn,
|
|
267
|
+
descriptor: kind === "method" ? descriptor : undefined,
|
|
268
|
+
signatureMode: kind === "method" && descriptor ? "exact" : undefined,
|
|
269
|
+
sourceMapping,
|
|
270
|
+
targetMapping,
|
|
271
|
+
sourcePriority,
|
|
272
|
+
projectPath,
|
|
273
|
+
disambiguation: {
|
|
274
|
+
ownerHint: targetOwner,
|
|
275
|
+
descriptorHint: remappedDescriptorHint
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
if (mapped.resolved && mapped.resolvedSymbol) {
|
|
279
|
+
memberKeyToRemapped.set(key, mapped.resolvedSymbol.name);
|
|
280
|
+
if (kind === "method" && mapped.resolvedSymbol.descriptor) {
|
|
281
|
+
memberDescriptorRemapped.set(key, mapped.resolvedSymbol.descriptor);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else if (mapped.status === "ambiguous" && mapped.candidates && mapped.candidates.length > 0) {
|
|
285
|
+
const ownerMatched = mapped.candidates.filter((c) => c.owner === targetOwner);
|
|
286
|
+
const best = ownerMatched.length > 0 ? ownerMatched : mapped.candidates;
|
|
287
|
+
if (best.length > 0) {
|
|
288
|
+
memberKeyToRemapped.set(key, best[0].name);
|
|
289
|
+
if (best[0].confidence < 0.9) {
|
|
290
|
+
failedNames.add(name);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
warnings.push(`Could not remap ${kind} "${name}" from ${sourceMapping} to ${targetMapping}.`);
|
|
295
|
+
failedNames.add(name);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
warnings.push(`Could not remap ${kind} "${name}" from ${sourceMapping} to ${targetMapping}.`);
|
|
300
|
+
failedNames.add(name);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
catch {
|
|
304
|
+
warnings.push(`Remap failed for ${kind} "${name}" from ${sourceMapping} to ${targetMapping}.`);
|
|
305
|
+
failedNames.add(name);
|
|
306
|
+
}
|
|
307
|
+
}));
|
|
308
|
+
const isField = kind === "field";
|
|
309
|
+
return {
|
|
310
|
+
members: members.map((member) => {
|
|
311
|
+
const memberKey = `${member.ownerFqn}\0${member.name}\0${member.jvmDescriptor}`;
|
|
312
|
+
const remappedName = memberKeyToRemapped.get(memberKey) ?? member.name;
|
|
313
|
+
const remappedOwner = ownerToRemapped.get(member.ownerFqn) ?? member.ownerFqn;
|
|
314
|
+
const remappedDescriptor = memberDescriptorRemapped.get(memberKey)
|
|
315
|
+
?? remapJvmDescriptor(member.jvmDescriptor, classMap);
|
|
316
|
+
return {
|
|
317
|
+
...member,
|
|
318
|
+
name: remappedName,
|
|
319
|
+
ownerFqn: remappedOwner,
|
|
320
|
+
jvmDescriptor: remappedDescriptor,
|
|
321
|
+
javaSignature: rebuildJavaSignature({ name: remappedName, ownerFqn: remappedOwner, accessFlags: member.accessFlags }, remappedDescriptor, isField)
|
|
322
|
+
};
|
|
323
|
+
}),
|
|
324
|
+
failedNames
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
//# sourceMappingURL=mapping-helpers.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import type { CheckSymbolExistsInput, CheckSymbolExistsOutput, SourceService } from "../../source-service.js";
|
|
2
|
+
export declare function checkSymbolExistsInUnobfuscatedRuntime(svc: SourceService, input: CheckSymbolExistsInput, fallbackBase: CheckSymbolExistsOutput): Promise<CheckSymbolExistsOutput | undefined>;
|