@neocompose/cli 0.61.5 → 0.62.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 +18 -0
- package/dist/neo.mjs +1417 -472
- package/package.json +1 -1
- package/skills/neocompose-cli/SKILL.md +1 -1
- package/skills/neocompose-cli/references/cli-development.md +1 -1
- package/skills/neocompose-cli/references/declarations-and-construction.md +11 -0
- package/skills/neocompose-cli/references/neoscript.md +3 -1
- package/skills/neocompose-cli/references/values-identities-and-references.md +3 -1
package/dist/neo.mjs
CHANGED
|
@@ -119,6 +119,92 @@ var init_workspace_source_path = __esm({
|
|
|
119
119
|
}
|
|
120
120
|
});
|
|
121
121
|
|
|
122
|
+
// ../packages/neoscript-language/src/local-scope-index.ts
|
|
123
|
+
var LocalScopeIndex;
|
|
124
|
+
var init_local_scope_index = __esm({
|
|
125
|
+
"../packages/neoscript-language/src/local-scope-index.ts"() {
|
|
126
|
+
"use strict";
|
|
127
|
+
LocalScopeIndex = class {
|
|
128
|
+
constructor(locals) {
|
|
129
|
+
this.locals = locals;
|
|
130
|
+
for (let index = 0; index < locals.length; index++) {
|
|
131
|
+
const local = locals[index];
|
|
132
|
+
if (local.scopeStart > local.scopeEnd) continue;
|
|
133
|
+
const named = this.byName.get(local.name);
|
|
134
|
+
if (named) named.push(index);
|
|
135
|
+
else this.byName.set(local.name, [index]);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
locals;
|
|
139
|
+
byName = /* @__PURE__ */ new Map();
|
|
140
|
+
segments = /* @__PURE__ */ new Map();
|
|
141
|
+
at(name, offset) {
|
|
142
|
+
const named = this.byName.get(name);
|
|
143
|
+
if (!named) return void 0;
|
|
144
|
+
let segments = this.segments.get(name);
|
|
145
|
+
if (!segments) {
|
|
146
|
+
segments = this.buildSegments(named);
|
|
147
|
+
this.segments.set(name, segments);
|
|
148
|
+
}
|
|
149
|
+
let low = 0;
|
|
150
|
+
let high = segments.length;
|
|
151
|
+
while (low < high) {
|
|
152
|
+
const middle = low + high >>> 1;
|
|
153
|
+
if (segments[middle].start <= offset) low = middle + 1;
|
|
154
|
+
else high = middle;
|
|
155
|
+
}
|
|
156
|
+
const index = segments[low - 1]?.localIndex;
|
|
157
|
+
return index === void 0 ? void 0 : this.locals[index];
|
|
158
|
+
}
|
|
159
|
+
buildSegments(indices) {
|
|
160
|
+
const events = indices.flatMap((index) => [
|
|
161
|
+
{ offset: this.locals[index].scopeStart, index },
|
|
162
|
+
// Scope ends are inclusive in the editor's recovery model.
|
|
163
|
+
{ offset: this.locals[index].scopeEnd + 1, index: void 0 }
|
|
164
|
+
]);
|
|
165
|
+
events.sort((a, b) => a.offset - b.offset);
|
|
166
|
+
const active = [];
|
|
167
|
+
const result = [];
|
|
168
|
+
for (let eventIndex = 0; eventIndex < events.length; ) {
|
|
169
|
+
const offset = events[eventIndex].offset;
|
|
170
|
+
while (events[eventIndex]?.offset === offset) {
|
|
171
|
+
const index = events[eventIndex++].index;
|
|
172
|
+
if (index === void 0) continue;
|
|
173
|
+
let child = active.length;
|
|
174
|
+
active.push(index);
|
|
175
|
+
while (child > 0) {
|
|
176
|
+
const parent = child - 1 >>> 1;
|
|
177
|
+
if (active[parent] >= index) break;
|
|
178
|
+
active[child] = active[parent];
|
|
179
|
+
child = parent;
|
|
180
|
+
}
|
|
181
|
+
active[child] = index;
|
|
182
|
+
}
|
|
183
|
+
while (active.length && this.locals[active[0]].scopeEnd < offset) {
|
|
184
|
+
const last = active.pop();
|
|
185
|
+
if (!active.length) break;
|
|
186
|
+
let parent = 0;
|
|
187
|
+
while (parent * 2 + 1 < active.length) {
|
|
188
|
+
let child = parent * 2 + 1;
|
|
189
|
+
if (child + 1 < active.length && active[child + 1] > active[child])
|
|
190
|
+
child++;
|
|
191
|
+
if (active[child] <= last) break;
|
|
192
|
+
active[parent] = active[child];
|
|
193
|
+
parent = child;
|
|
194
|
+
}
|
|
195
|
+
active[parent] = last;
|
|
196
|
+
}
|
|
197
|
+
const localIndex = active[0];
|
|
198
|
+
if (!result.length || result.at(-1).localIndex !== localIndex) {
|
|
199
|
+
result.push({ start: offset, localIndex });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return result;
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
|
|
122
208
|
// ../packages/neoscript-language/src/cell-pattern.ts
|
|
123
209
|
var NEO_CELL_PATTERN_CLASS_ID, NEO_CELL_PATTERN_CONSTRUCTOR_ID, NEO_CELL_PATTERN_EXCLUDING_ENUM_ID, NEO_CELL_PATTERN_EXCLUDING_OPTION_IDS, NEO_CELL_PATTERN_MEMBER_IDS, NEO_OBJECT_GRID_MEMBER_IDS, NEO_CELL_PATTERN_PURE_NATIVE_MEMBER_IDS, NEO_OBJECT_CLASS_ID;
|
|
124
210
|
var init_cell_pattern = __esm({
|
|
@@ -8385,7 +8471,7 @@ var init_strict_resolver = __esm({
|
|
|
8385
8471
|
};
|
|
8386
8472
|
}
|
|
8387
8473
|
if (expression.kind !== "member") return null;
|
|
8388
|
-
if (expression.receiver.kind === "ident" && !
|
|
8474
|
+
if (expression.receiver.kind === "ident" && !this.hasValueReceiver(expression.receiver.name, scope)) {
|
|
8389
8475
|
const owner2 = this.project.typeByName.get(expression.receiver.name);
|
|
8390
8476
|
const symbol2 = owner2?.members.find(
|
|
8391
8477
|
(candidate) => candidate.name === expression.name
|
|
@@ -9015,7 +9101,7 @@ var init_strict_resolver = __esm({
|
|
|
9015
9101
|
expression: this.resolveIdentifier("this", scope, expression.pos)
|
|
9016
9102
|
};
|
|
9017
9103
|
} else if (expression.kind === "member") {
|
|
9018
|
-
if (expression.receiver.kind === "ident" && !
|
|
9104
|
+
if (expression.receiver.kind === "ident" && !this.hasValueReceiver(expression.receiver.name, scope)) {
|
|
9019
9105
|
owner = this.project.typeByName.get(expression.receiver.name);
|
|
9020
9106
|
symbol = owner?.members.find(
|
|
9021
9107
|
(candidate) => candidate.name === expression.name && (candidate.kind === "function" || candidate.kind === "method")
|
|
@@ -9100,7 +9186,7 @@ var init_strict_resolver = __esm({
|
|
|
9100
9186
|
owner = implicit.owner;
|
|
9101
9187
|
receiverType = this.context.thisClass;
|
|
9102
9188
|
} else if (expression.kind === "member") {
|
|
9103
|
-
if (expression.receiver.kind === "ident" && !
|
|
9189
|
+
if (expression.receiver.kind === "ident" && !this.hasValueReceiver(expression.receiver.name, scope)) {
|
|
9104
9190
|
owner = this.project.typeByName.get(expression.receiver.name);
|
|
9105
9191
|
symbol = owner?.members.find(
|
|
9106
9192
|
(candidate) => candidate.name === expression.name && (candidate.kind === "function" || candidate.kind === "method")
|
|
@@ -9320,10 +9406,17 @@ var init_strict_resolver = __esm({
|
|
|
9320
9406
|
if (global) return this.symbolValue(global);
|
|
9321
9407
|
const implicit = this.implicitMember(name);
|
|
9322
9408
|
if (implicit && implicit.symbol.kind !== "function" && implicit.symbol.kind !== "method") {
|
|
9409
|
+
if (implicit.symbol.static === true) {
|
|
9410
|
+
return this.resolveStaticMemberValue(
|
|
9411
|
+
implicit.owner,
|
|
9412
|
+
implicit.symbol,
|
|
9413
|
+
pos
|
|
9414
|
+
);
|
|
9415
|
+
}
|
|
9323
9416
|
return this.resolveMember(
|
|
9324
9417
|
{
|
|
9325
9418
|
kind: "ident",
|
|
9326
|
-
name:
|
|
9419
|
+
name: "this",
|
|
9327
9420
|
pos
|
|
9328
9421
|
},
|
|
9329
9422
|
name,
|
|
@@ -9545,7 +9638,7 @@ var init_strict_resolver = __esm({
|
|
|
9545
9638
|
if (path[1] !== NEO_VARIANT_SCOPE_NAME) return null;
|
|
9546
9639
|
const className = path[0];
|
|
9547
9640
|
if (className === void 0) return null;
|
|
9548
|
-
if (
|
|
9641
|
+
if (this.hasValueReceiver(className, scope)) return null;
|
|
9549
9642
|
const classType = this.project.typeByName.get(className);
|
|
9550
9643
|
if (classType === void 0 || classType.kind !== "class") return null;
|
|
9551
9644
|
const rest = path.slice(2);
|
|
@@ -9649,7 +9742,7 @@ var init_strict_resolver = __esm({
|
|
|
9649
9742
|
const isInitialize = callee.name === VARIANT_INITIALIZE_NAME;
|
|
9650
9743
|
const isApply = callee.name === VARIANT_APPLY_NAME;
|
|
9651
9744
|
if (!isInitialize && !isApply) return null;
|
|
9652
|
-
if (callee.receiver.kind === "ident" && !
|
|
9745
|
+
if (callee.receiver.kind === "ident" && !this.hasValueReceiver(callee.receiver.name, scope) && this.project.typeByName.has(callee.receiver.name)) {
|
|
9653
9746
|
return null;
|
|
9654
9747
|
}
|
|
9655
9748
|
const receiver = this.resolveExpression(callee.receiver, scope);
|
|
@@ -9804,6 +9897,49 @@ var init_strict_resolver = __esm({
|
|
|
9804
9897
|
}
|
|
9805
9898
|
return resolved;
|
|
9806
9899
|
}
|
|
9900
|
+
resolveStaticMemberValue(staticType, member, pos) {
|
|
9901
|
+
this.assertMemberAccessible(staticType, member, pos);
|
|
9902
|
+
if (member.static !== true) {
|
|
9903
|
+
throw new CompileError(
|
|
9904
|
+
`Member '${staticType.name}.${member.name}' requires an instance receiver.`,
|
|
9905
|
+
pos
|
|
9906
|
+
);
|
|
9907
|
+
}
|
|
9908
|
+
if (member.kind === "function" || member.kind === "method") {
|
|
9909
|
+
throw new CompileError(
|
|
9910
|
+
`Static Function '${staticType.name}.${member.name}' must be called with \`()\`; it cannot be read as a value.`,
|
|
9911
|
+
pos
|
|
9912
|
+
);
|
|
9913
|
+
}
|
|
9914
|
+
if (member.id === NEOSCRIPT_SPRITE_INFO_EMPTY_MEMBER_ID) {
|
|
9915
|
+
return literal(member.type, {
|
|
9916
|
+
...NEOSCRIPT_SPRITE_INFO_EMPTY_VALUE
|
|
9917
|
+
});
|
|
9918
|
+
}
|
|
9919
|
+
if (member.computed === true) {
|
|
9920
|
+
return {
|
|
9921
|
+
pointer: {
|
|
9922
|
+
type: "callGetter" /* CallGetter */,
|
|
9923
|
+
memberId: member.id,
|
|
9924
|
+
receiver: { kind: "static", memberId: member.id }
|
|
9925
|
+
},
|
|
9926
|
+
type: member.type,
|
|
9927
|
+
symbol: member,
|
|
9928
|
+
...member.writable ? {
|
|
9929
|
+
writability: member.writability ? toWritability(member.writability) : "setter" /* Setter */
|
|
9930
|
+
} : {}
|
|
9931
|
+
};
|
|
9932
|
+
}
|
|
9933
|
+
return {
|
|
9934
|
+
pointer: {
|
|
9935
|
+
type: "staticMember" /* StaticMember */,
|
|
9936
|
+
memberId: member.id
|
|
9937
|
+
},
|
|
9938
|
+
type: member.type,
|
|
9939
|
+
symbol: member,
|
|
9940
|
+
...member.writability ? { writability: toWritability(member.writability) } : {}
|
|
9941
|
+
};
|
|
9942
|
+
}
|
|
9807
9943
|
resolveMemberNatural(receiverAst, name, scope, pos, optional2) {
|
|
9808
9944
|
if (receiverAst.kind === "ident" && receiverAst.name === "base") {
|
|
9809
9945
|
const { owner, symbol, receiver: receiver2 } = this.resolveBaseMember(
|
|
@@ -9844,7 +9980,7 @@ var init_strict_resolver = __esm({
|
|
|
9844
9980
|
}
|
|
9845
9981
|
return variantPath2;
|
|
9846
9982
|
}
|
|
9847
|
-
if (receiverAst.kind === "ident" && !
|
|
9983
|
+
if (receiverAst.kind === "ident" && !this.hasValueReceiver(receiverAst.name, scope)) {
|
|
9848
9984
|
if (receiverAst.name === "SpriteInfo" && name === "Empty") {
|
|
9849
9985
|
return literal(
|
|
9850
9986
|
{ kind: "primitive", name: "SpriteInfo" },
|
|
@@ -9886,47 +10022,7 @@ var init_strict_resolver = __esm({
|
|
|
9886
10022
|
pos
|
|
9887
10023
|
);
|
|
9888
10024
|
}
|
|
9889
|
-
this.
|
|
9890
|
-
if (member.static !== true) {
|
|
9891
|
-
throw new CompileError(
|
|
9892
|
-
`Member '${staticType.name}.${name}' requires an instance receiver.`,
|
|
9893
|
-
pos
|
|
9894
|
-
);
|
|
9895
|
-
}
|
|
9896
|
-
if (member.kind === "function" || member.kind === "method") {
|
|
9897
|
-
throw new CompileError(
|
|
9898
|
-
`Static Function '${staticType.name}.${name}' must be called with \`()\`; it cannot be read as a value.`,
|
|
9899
|
-
pos
|
|
9900
|
-
);
|
|
9901
|
-
}
|
|
9902
|
-
if (member.id === NEOSCRIPT_SPRITE_INFO_EMPTY_MEMBER_ID) {
|
|
9903
|
-
return literal(member.type, {
|
|
9904
|
-
...NEOSCRIPT_SPRITE_INFO_EMPTY_VALUE
|
|
9905
|
-
});
|
|
9906
|
-
}
|
|
9907
|
-
if (member.computed === true) {
|
|
9908
|
-
return {
|
|
9909
|
-
pointer: {
|
|
9910
|
-
type: "callGetter" /* CallGetter */,
|
|
9911
|
-
memberId: member.id,
|
|
9912
|
-
receiver: { kind: "static", memberId: member.id }
|
|
9913
|
-
},
|
|
9914
|
-
type: member.type,
|
|
9915
|
-
symbol: member,
|
|
9916
|
-
...member.writable ? {
|
|
9917
|
-
writability: member.writability ? toWritability(member.writability) : "setter" /* Setter */
|
|
9918
|
-
} : {}
|
|
9919
|
-
};
|
|
9920
|
-
}
|
|
9921
|
-
return {
|
|
9922
|
-
pointer: {
|
|
9923
|
-
type: "staticMember" /* StaticMember */,
|
|
9924
|
-
memberId: member.id
|
|
9925
|
-
},
|
|
9926
|
-
type: member.type,
|
|
9927
|
-
symbol: member,
|
|
9928
|
-
...member.writability ? { writability: toWritability(member.writability) } : {}
|
|
9929
|
-
};
|
|
10025
|
+
return this.resolveStaticMemberValue(staticType, member, pos);
|
|
9930
10026
|
}
|
|
9931
10027
|
}
|
|
9932
10028
|
const resolvedReceiver = this.resolveExpression(receiverAst, scope);
|
|
@@ -10716,7 +10812,7 @@ var init_strict_resolver = __esm({
|
|
|
10716
10812
|
pos
|
|
10717
10813
|
);
|
|
10718
10814
|
}
|
|
10719
|
-
if (callee.receiver.kind === "ident" && !
|
|
10815
|
+
if (callee.receiver.kind === "ident" && !this.hasValueReceiver(callee.receiver.name, scope)) {
|
|
10720
10816
|
if (callee.receiver.name === MATH_NAMESPACE_NAME) {
|
|
10721
10817
|
if (callee.optional) {
|
|
10722
10818
|
throw new CompileError(
|
|
@@ -11967,7 +12063,7 @@ var init_strict_resolver = __esm({
|
|
|
11967
12063
|
if (implicit?.symbol.static !== true)
|
|
11968
12064
|
receiverType = this.context.thisClass;
|
|
11969
12065
|
} else if (expression.kind === "member") {
|
|
11970
|
-
const isStatic = expression.receiver.kind === "ident" && !
|
|
12066
|
+
const isStatic = expression.receiver.kind === "ident" && !this.hasValueReceiver(expression.receiver.name, scope) && this.project.typeByName.has(expression.receiver.name);
|
|
11971
12067
|
if (!isStatic) {
|
|
11972
12068
|
receiverType = this.resolveExpression(expression.receiver, scope).type;
|
|
11973
12069
|
}
|
|
@@ -12673,7 +12769,7 @@ var init_strict_resolver = __esm({
|
|
|
12673
12769
|
}
|
|
12674
12770
|
if (expression.callee.kind !== "member") return null;
|
|
12675
12771
|
const memberName = expression.callee.name;
|
|
12676
|
-
if (expression.callee.receiver.kind === "ident" && !
|
|
12772
|
+
if (expression.callee.receiver.kind === "ident" && !this.hasValueReceiver(expression.callee.receiver.name, scope)) {
|
|
12677
12773
|
const staticType = this.project.typeByName.get(
|
|
12678
12774
|
expression.callee.receiver.name
|
|
12679
12775
|
);
|
|
@@ -13384,6 +13480,9 @@ var init_strict_resolver = __esm({
|
|
|
13384
13480
|
}
|
|
13385
13481
|
return literal(symbol.type, null);
|
|
13386
13482
|
}
|
|
13483
|
+
hasValueReceiver(name, scope) {
|
|
13484
|
+
return scope.lookup(name) !== null || this.implicitMember(name) !== null;
|
|
13485
|
+
}
|
|
13387
13486
|
implicitMember(name) {
|
|
13388
13487
|
if (this.context.implicitMemberAccess !== true) return null;
|
|
13389
13488
|
const declaring = this.context.declaringType ?? this.context.thisClass;
|
|
@@ -13425,6 +13524,53 @@ var init_strict_resolver = __esm({
|
|
|
13425
13524
|
});
|
|
13426
13525
|
|
|
13427
13526
|
// ../packages/neoscript-language/src/analyzer.ts
|
|
13527
|
+
function scriptFeatureIndex(snapshot) {
|
|
13528
|
+
const cached = SCRIPT_FEATURE_INDEX.get(snapshot);
|
|
13529
|
+
if (cached) return cached;
|
|
13530
|
+
const references = /* @__PURE__ */ new Map();
|
|
13531
|
+
const locals = /* @__PURE__ */ new Map();
|
|
13532
|
+
const calls = /* @__PURE__ */ new Map();
|
|
13533
|
+
const contextualKeywords = /* @__PURE__ */ new Set();
|
|
13534
|
+
const typeAnnotations = /* @__PURE__ */ new Set();
|
|
13535
|
+
for (const reference2 of snapshot.parsed.references) {
|
|
13536
|
+
if (!references.has(reference2.start))
|
|
13537
|
+
references.set(reference2.start, reference2);
|
|
13538
|
+
}
|
|
13539
|
+
for (const local of snapshot.parsed.locals) {
|
|
13540
|
+
const start = snapshot.source.offsetAt(local.nameRange.start);
|
|
13541
|
+
if (!locals.has(start)) locals.set(start, local);
|
|
13542
|
+
if (local.contextualKeywordRange)
|
|
13543
|
+
contextualKeywords.add(
|
|
13544
|
+
snapshot.source.offsetAt(local.contextualKeywordRange.start)
|
|
13545
|
+
);
|
|
13546
|
+
for (const token of local.typeTokens) typeAnnotations.add(token.start);
|
|
13547
|
+
}
|
|
13548
|
+
for (const call of snapshot.parsed.calls) {
|
|
13549
|
+
const start = snapshot.source.offsetAt(call.nameRange.start);
|
|
13550
|
+
if (!calls.has(start)) calls.set(start, call);
|
|
13551
|
+
if (call.kind === "constructor" && call.contextualKeywordRange)
|
|
13552
|
+
contextualKeywords.add(
|
|
13553
|
+
snapshot.source.offsetAt(call.contextualKeywordRange.start)
|
|
13554
|
+
);
|
|
13555
|
+
}
|
|
13556
|
+
const tokens = snapshot.lexed.tokens.filter(
|
|
13557
|
+
(token) => token.kind !== "comment" && token.kind !== "eof"
|
|
13558
|
+
);
|
|
13559
|
+
const tokenIndexes = new Map(
|
|
13560
|
+
tokens.map((token, index2) => [token.start, index2])
|
|
13561
|
+
);
|
|
13562
|
+
const index = {
|
|
13563
|
+
references,
|
|
13564
|
+
locals,
|
|
13565
|
+
calls,
|
|
13566
|
+
contextualKeywords,
|
|
13567
|
+
typeAnnotations,
|
|
13568
|
+
tokens,
|
|
13569
|
+
tokenIndexes
|
|
13570
|
+
};
|
|
13571
|
+
SCRIPT_FEATURE_INDEX.set(snapshot, index);
|
|
13572
|
+
return index;
|
|
13573
|
+
}
|
|
13428
13574
|
function buildProjectIndexWithBuiltins(context) {
|
|
13429
13575
|
const typeIds = new Set(context.project.types.map((type) => type.id));
|
|
13430
13576
|
const globalIds3 = new Set(context.project.globals.map((symbol) => symbol.id));
|
|
@@ -13684,8 +13830,12 @@ function signatureHelp(snapshot, position) {
|
|
|
13684
13830
|
function inlayHints(snapshot, range2) {
|
|
13685
13831
|
const hints = [];
|
|
13686
13832
|
for (const call of snapshot.parsed.calls) {
|
|
13687
|
-
|
|
13688
|
-
(
|
|
13833
|
+
if (range2 && !call.argumentRanges.some(
|
|
13834
|
+
(argument2) => comparePositions(argument2.end, range2.start) >= 0 && comparePositions(argument2.start, range2.end) <= 0
|
|
13835
|
+
))
|
|
13836
|
+
continue;
|
|
13837
|
+
const reference2 = scriptFeatureIndex(snapshot).references.get(
|
|
13838
|
+
snapshot.source.offsetAt(call.nameRange.start)
|
|
13689
13839
|
);
|
|
13690
13840
|
const resolution = reference2 ? resolveReference(snapshot, reference2) : null;
|
|
13691
13841
|
const parameterNames = call.kind === "constructor" ? constructorParameterNames(resolution?.staticType) : resolution?.symbol?.parameters?.map((parameter4) => parameter4.name);
|
|
@@ -13698,6 +13848,7 @@ function inlayHints(snapshot, range2) {
|
|
|
13698
13848
|
continue;
|
|
13699
13849
|
}
|
|
13700
13850
|
const position = firstNonWhitespacePosition(snapshot, argumentRange);
|
|
13851
|
+
if (comparePositions(position, argumentRange.end) >= 0) continue;
|
|
13701
13852
|
if (range2 && !positionInRange(position, range2)) continue;
|
|
13702
13853
|
hints.push({
|
|
13703
13854
|
position,
|
|
@@ -13709,10 +13860,10 @@ function inlayHints(snapshot, range2) {
|
|
|
13709
13860
|
}
|
|
13710
13861
|
for (const local of snapshot.parsed.locals) {
|
|
13711
13862
|
if (!local.inferred || !local.contextualKeywordRange) continue;
|
|
13712
|
-
const type = resolveDeclaredType(local, snapshot);
|
|
13713
|
-
if (type.kind === "primitive" && type.name === "unknown") continue;
|
|
13714
13863
|
const position = local.nameRange.end;
|
|
13715
13864
|
if (range2 && !positionInRange(position, range2)) continue;
|
|
13865
|
+
const type = localSymbol(local, snapshot).type;
|
|
13866
|
+
if (type.kind === "primitive" && type.name === "unknown") continue;
|
|
13716
13867
|
hints.push({
|
|
13717
13868
|
position,
|
|
13718
13869
|
label: `: ${formatType(type, snapshot.project)}`,
|
|
@@ -13806,6 +13957,7 @@ function documentSymbols(snapshot) {
|
|
|
13806
13957
|
}
|
|
13807
13958
|
function semanticTokens(snapshot) {
|
|
13808
13959
|
const result = [];
|
|
13960
|
+
const index = scriptFeatureIndex(snapshot);
|
|
13809
13961
|
for (const token of snapshot.lexed.tokens) {
|
|
13810
13962
|
if (token.kind === "eof" || token.kind === "error") continue;
|
|
13811
13963
|
if (token.kind === "keyword" || token.kind === "comment" || token.kind === "string") {
|
|
@@ -13829,17 +13981,11 @@ function semanticTokens(snapshot) {
|
|
|
13829
13981
|
continue;
|
|
13830
13982
|
}
|
|
13831
13983
|
if (token.kind !== "identifier") continue;
|
|
13832
|
-
if (
|
|
13833
|
-
(local) => local.contextualKeywordRange?.start.line === token.range.start.line && local.contextualKeywordRange.start.character === token.range.start.character
|
|
13834
|
-
) || snapshot.parsed.calls.some(
|
|
13835
|
-
(call) => call.kind === "constructor" && call.contextualKeywordRange?.start.line === token.range.start.line && call.contextualKeywordRange.start.character === token.range.start.character
|
|
13836
|
-
)) {
|
|
13984
|
+
if (index.contextualKeywords.has(token.start)) {
|
|
13837
13985
|
result.push({ range: token.range, type: "keyword", modifiers: [] });
|
|
13838
13986
|
continue;
|
|
13839
13987
|
}
|
|
13840
|
-
const declaredLocal =
|
|
13841
|
-
(local) => local.nameRange.start.line === token.range.start.line && local.nameRange.start.character === token.range.start.character
|
|
13842
|
-
);
|
|
13988
|
+
const declaredLocal = index.locals.get(token.start);
|
|
13843
13989
|
if (declaredLocal) {
|
|
13844
13990
|
const symbol2 = localSymbol(declaredLocal, snapshot);
|
|
13845
13991
|
result.push({
|
|
@@ -13852,9 +13998,7 @@ function semanticTokens(snapshot) {
|
|
|
13852
13998
|
});
|
|
13853
13999
|
continue;
|
|
13854
14000
|
}
|
|
13855
|
-
const reference2 =
|
|
13856
|
-
(candidate) => candidate.start === token.start
|
|
13857
|
-
);
|
|
14001
|
+
const reference2 = index.references.get(token.start);
|
|
13858
14002
|
const resolved = reference2 ? resolveReference(snapshot, reference2) : null;
|
|
13859
14003
|
if (resolved?.staticType) {
|
|
13860
14004
|
result.push({
|
|
@@ -13906,6 +14050,16 @@ function referenceAtPosition(snapshot, position) {
|
|
|
13906
14050
|
snapshot.source.offsetAt(position)
|
|
13907
14051
|
);
|
|
13908
14052
|
}
|
|
14053
|
+
function localSymbolAtPosition(snapshot, position) {
|
|
14054
|
+
const offset = snapshot.source.offsetAt(position);
|
|
14055
|
+
const declaration = snapshot.parsed.locals.find(
|
|
14056
|
+
(local) => snapshot.source.offsetAt(local.nameRange.start) <= offset && offset <= snapshot.source.offsetAt(local.nameRange.end)
|
|
14057
|
+
);
|
|
14058
|
+
if (declaration) return localSymbol(declaration, snapshot);
|
|
14059
|
+
const reference2 = referenceAtPosition(snapshot, position);
|
|
14060
|
+
const symbol = reference2 ? resolveReference(snapshot, reference2)?.symbol : null;
|
|
14061
|
+
return symbol?.id.startsWith("local:") ? symbol : null;
|
|
14062
|
+
}
|
|
13909
14063
|
function contextualCompletionItems(snapshot, offset, word) {
|
|
13910
14064
|
const items = [];
|
|
13911
14065
|
const expectedType = expectedTypeAt(snapshot, word.start);
|
|
@@ -14148,6 +14302,14 @@ function expectedTypeAt(snapshot, offset) {
|
|
|
14148
14302
|
offset
|
|
14149
14303
|
);
|
|
14150
14304
|
}
|
|
14305
|
+
if (snapshot.expressionRange && snapshot.context.returnType) {
|
|
14306
|
+
return expectedCollectionElementType(
|
|
14307
|
+
snapshot.context.returnType,
|
|
14308
|
+
tokens,
|
|
14309
|
+
snapshot.source.offsetAt(snapshot.expressionRange.start),
|
|
14310
|
+
offset
|
|
14311
|
+
);
|
|
14312
|
+
}
|
|
14151
14313
|
return null;
|
|
14152
14314
|
}
|
|
14153
14315
|
function expectedTypeFromComparisonRight(snapshot, offset) {
|
|
@@ -14559,16 +14721,12 @@ function resolveReference(snapshot, reference2) {
|
|
|
14559
14721
|
);
|
|
14560
14722
|
if (contextual) return contextual;
|
|
14561
14723
|
}
|
|
14562
|
-
|
|
14563
|
-
(token) => token.kind !== "comment" && token.kind !== "eof" && token.end <= reference2.end
|
|
14564
|
-
);
|
|
14565
|
-
const tokenIndex = tokens.findIndex(
|
|
14566
|
-
(token) => token.start === reference2.start
|
|
14567
|
-
);
|
|
14568
|
-
if (tokenIndex < 0) return null;
|
|
14569
|
-
if (!reference2.member) {
|
|
14724
|
+
if (!reference2.member)
|
|
14570
14725
|
return resolveRoot(snapshot, reference2.name, reference2.start);
|
|
14571
|
-
|
|
14726
|
+
const index = scriptFeatureIndex(snapshot);
|
|
14727
|
+
const tokens = index.tokens;
|
|
14728
|
+
const tokenIndex = index.tokenIndexes.get(reference2.start);
|
|
14729
|
+
if (tokenIndex === void 0) return null;
|
|
14572
14730
|
const dotIndex = tokenIndex - 1;
|
|
14573
14731
|
const chainTokens = expressionTokensBefore(tokens, dotIndex);
|
|
14574
14732
|
const receiver = resolveChain(snapshot, chainTokens, reference2.start);
|
|
@@ -14576,9 +14734,7 @@ function resolveReference(snapshot, reference2) {
|
|
|
14576
14734
|
return resolveContextualSwitchEnumReference(snapshot, reference2);
|
|
14577
14735
|
}
|
|
14578
14736
|
const member = resolveMember(snapshot, receiver, reference2.name);
|
|
14579
|
-
const call =
|
|
14580
|
-
(call2) => call2.nameRange.start.line === reference2.range.start.line && call2.nameRange.start.character === reference2.range.start.character
|
|
14581
|
-
);
|
|
14737
|
+
const call = index.calls.get(reference2.start);
|
|
14582
14738
|
return specializeGridQuery(snapshot, member, call?.typeArgumentTokens);
|
|
14583
14739
|
}
|
|
14584
14740
|
function specializeGridQuery(snapshot, resolved, typeArguments) {
|
|
@@ -14786,9 +14942,7 @@ function selectLambdaResultTokens(body) {
|
|
|
14786
14942
|
return semicolon < 0 ? tail : tail.slice(0, semicolon);
|
|
14787
14943
|
}
|
|
14788
14944
|
function resolveRoot(snapshot, name, offset) {
|
|
14789
|
-
const symbol = scopeAt(snapshot, offset)
|
|
14790
|
-
(candidate) => candidate.name === name
|
|
14791
|
-
);
|
|
14945
|
+
const symbol = scopeAt(snapshot, offset, name)[0];
|
|
14792
14946
|
if (symbol) return { type: symbol.returnType ?? symbol.type, symbol };
|
|
14793
14947
|
const typeParameter2 = contextualTypeParameters(snapshot).find(
|
|
14794
14948
|
(candidate) => candidate.name === name
|
|
@@ -14842,18 +14996,18 @@ function resolveMember(snapshot, receiver, name) {
|
|
|
14842
14996
|
symbol: member
|
|
14843
14997
|
};
|
|
14844
14998
|
}
|
|
14845
|
-
function scopeAt(snapshot, offset) {
|
|
14999
|
+
function scopeAt(snapshot, offset, name) {
|
|
14846
15000
|
const result = [];
|
|
14847
|
-
for (const root of snapshot.context.project.roots) {
|
|
15001
|
+
for (const root of namedItems(snapshot.context.project.roots, name)) {
|
|
14848
15002
|
result.push(withScope(root, 0, snapshot.source.text.length));
|
|
14849
15003
|
}
|
|
14850
15004
|
for (const global of [
|
|
14851
|
-
...snapshot.context.project.globals,
|
|
14852
|
-
...NEOSCRIPT_GLOBALS
|
|
15005
|
+
...namedItems(snapshot.context.project.globals, name),
|
|
15006
|
+
...namedItems(NEOSCRIPT_GLOBALS, name)
|
|
14853
15007
|
]) {
|
|
14854
15008
|
result.push(withScope(global, 0, snapshot.source.text.length));
|
|
14855
15009
|
}
|
|
14856
|
-
if (snapshot.context.thisClass) {
|
|
15010
|
+
if (snapshot.context.thisClass && (name === void 0 || name === "this")) {
|
|
14857
15011
|
result.push(
|
|
14858
15012
|
withScope(
|
|
14859
15013
|
{
|
|
@@ -14868,7 +15022,7 @@ function scopeAt(snapshot, offset) {
|
|
|
14868
15022
|
)
|
|
14869
15023
|
);
|
|
14870
15024
|
}
|
|
14871
|
-
if (snapshot.context.baseClass) {
|
|
15025
|
+
if (snapshot.context.baseClass && (name === void 0 || name === "base")) {
|
|
14872
15026
|
result.push(
|
|
14873
15027
|
withScope(
|
|
14874
15028
|
{
|
|
@@ -14910,7 +15064,7 @@ function scopeAt(snapshot, offset) {
|
|
|
14910
15064
|
)
|
|
14911
15065
|
);
|
|
14912
15066
|
}
|
|
14913
|
-
if (snapshot.context.dialogueContextType) {
|
|
15067
|
+
if (snapshot.context.dialogueContextType && (name === void 0 || name === "context")) {
|
|
14914
15068
|
result.push(
|
|
14915
15069
|
withScope(
|
|
14916
15070
|
{
|
|
@@ -14925,7 +15079,7 @@ function scopeAt(snapshot, offset) {
|
|
|
14925
15079
|
)
|
|
14926
15080
|
);
|
|
14927
15081
|
}
|
|
14928
|
-
for (const alias of snapshot.context.valueAliases ?? []) {
|
|
15082
|
+
for (const alias of namedItems(snapshot.context.valueAliases ?? [], name)) {
|
|
14929
15083
|
result.push(
|
|
14930
15084
|
withScope(
|
|
14931
15085
|
{
|
|
@@ -14944,7 +15098,7 @@ function scopeAt(snapshot, offset) {
|
|
|
14944
15098
|
if (snapshot.context.implicitMemberAccess === true && declaringType?.kind === "named") {
|
|
14945
15099
|
const owner = snapshot.project.typeById.get(declaringType.typeId);
|
|
14946
15100
|
if (owner) {
|
|
14947
|
-
for (const member of owner.members) {
|
|
15101
|
+
for (const member of namedItems(owner.members, name)) {
|
|
14948
15102
|
if (snapshot.context.staticMember === true && member.static !== true) {
|
|
14949
15103
|
continue;
|
|
14950
15104
|
}
|
|
@@ -14953,7 +15107,7 @@ function scopeAt(snapshot, offset) {
|
|
|
14953
15107
|
}
|
|
14954
15108
|
}
|
|
14955
15109
|
}
|
|
14956
|
-
if (effectiveDocumentKind(snapshot, offset) === "setter" && snapshot.context.returnType) {
|
|
15110
|
+
if ((name === void 0 || name === "value") && effectiveDocumentKind(snapshot, offset) === "setter" && snapshot.context.returnType) {
|
|
14957
15111
|
result.push(
|
|
14958
15112
|
withScope(
|
|
14959
15113
|
{
|
|
@@ -14968,19 +15122,47 @@ function scopeAt(snapshot, offset) {
|
|
|
14968
15122
|
)
|
|
14969
15123
|
);
|
|
14970
15124
|
}
|
|
14971
|
-
for (const parameter4 of snapshot.context.parameters ?? []) {
|
|
15125
|
+
for (const parameter4 of namedItems(snapshot.context.parameters ?? [], name)) {
|
|
14972
15126
|
result.push(
|
|
14973
15127
|
parameterSymbol(parameter4, snapshot.uri, snapshot.source.text.length)
|
|
14974
15128
|
);
|
|
14975
15129
|
}
|
|
14976
|
-
|
|
14977
|
-
|
|
14978
|
-
|
|
15130
|
+
if (name === void 0) {
|
|
15131
|
+
for (const local of snapshot.parsed.locals) {
|
|
15132
|
+
if (offset < local.scopeStart || offset > local.scopeEnd) continue;
|
|
15133
|
+
result.push(localSymbol(local, snapshot));
|
|
15134
|
+
}
|
|
15135
|
+
} else {
|
|
15136
|
+
let index = LOCAL_SCOPE_INDEX.get(snapshot.parsed.locals);
|
|
15137
|
+
if (!index) {
|
|
15138
|
+
index = new LocalScopeIndex(snapshot.parsed.locals);
|
|
15139
|
+
LOCAL_SCOPE_INDEX.set(snapshot.parsed.locals, index);
|
|
15140
|
+
}
|
|
15141
|
+
const local = index.at(name, offset);
|
|
15142
|
+
if (local) result.push(localSymbol(local, snapshot));
|
|
14979
15143
|
}
|
|
14980
15144
|
const byName = /* @__PURE__ */ new Map();
|
|
14981
|
-
for (const symbol of result)
|
|
15145
|
+
for (const symbol of result) {
|
|
15146
|
+
if (name === void 0 || symbol.name === name)
|
|
15147
|
+
byName.set(symbol.name, symbol);
|
|
15148
|
+
}
|
|
14982
15149
|
return [...byName.values()];
|
|
14983
15150
|
}
|
|
15151
|
+
function namedItems(items, name) {
|
|
15152
|
+
if (name === void 0) return items;
|
|
15153
|
+
let index = NAMED_ITEM_INDEX.get(items);
|
|
15154
|
+
if (!index) {
|
|
15155
|
+
index = /* @__PURE__ */ new Map();
|
|
15156
|
+
for (let i2 = 0; i2 < items.length; i2++) {
|
|
15157
|
+
const key = items[i2].name;
|
|
15158
|
+
const matches = index.get(key);
|
|
15159
|
+
if (matches) matches.push(i2);
|
|
15160
|
+
else index.set(key, [i2]);
|
|
15161
|
+
}
|
|
15162
|
+
NAMED_ITEM_INDEX.set(items, index);
|
|
15163
|
+
}
|
|
15164
|
+
return (index.get(name) ?? []).map((i2) => items[i2]);
|
|
15165
|
+
}
|
|
14984
15166
|
function resolveDeclaredType(local, snapshot) {
|
|
14985
15167
|
if (local.inferred) return inferLocalType(local, snapshot);
|
|
14986
15168
|
const tokens = local.typeTokens;
|
|
@@ -15474,7 +15656,14 @@ function parameterSymbol(value, uri, documentEnd) {
|
|
|
15474
15656
|
);
|
|
15475
15657
|
}
|
|
15476
15658
|
function localSymbol(local, snapshot) {
|
|
15477
|
-
|
|
15659
|
+
let symbols = LOCAL_SYMBOL_CACHE.get(snapshot);
|
|
15660
|
+
if (!symbols) {
|
|
15661
|
+
symbols = /* @__PURE__ */ new Map();
|
|
15662
|
+
LOCAL_SYMBOL_CACHE.set(snapshot, symbols);
|
|
15663
|
+
}
|
|
15664
|
+
const cached = symbols.get(local);
|
|
15665
|
+
if (cached) return cached;
|
|
15666
|
+
const symbol = withScope(
|
|
15478
15667
|
{
|
|
15479
15668
|
id: `local:${snapshot.uri}:${local.nameRange.start.line}:${local.nameRange.start.character}`,
|
|
15480
15669
|
name: local.name,
|
|
@@ -15486,6 +15675,8 @@ function localSymbol(local, snapshot) {
|
|
|
15486
15675
|
local.scopeStart,
|
|
15487
15676
|
local.scopeEnd
|
|
15488
15677
|
);
|
|
15678
|
+
symbols.set(local, symbol);
|
|
15679
|
+
return symbol;
|
|
15489
15680
|
}
|
|
15490
15681
|
function inferLambdaParameterType(local, snapshot) {
|
|
15491
15682
|
const explicit = resolveDeclaredType(local, snapshot);
|
|
@@ -15850,18 +16041,16 @@ function comparePositions(left, right) {
|
|
|
15850
16041
|
return left.line === right.line ? left.character - right.character : left.line - right.line;
|
|
15851
16042
|
}
|
|
15852
16043
|
function isTypeAnnotationReference(snapshot, reference2) {
|
|
15853
|
-
return snapshot.
|
|
15854
|
-
(local) => local.typeTokens.some((token) => token.start === reference2.start)
|
|
15855
|
-
);
|
|
16044
|
+
return scriptFeatureIndex(snapshot).typeAnnotations.has(reference2.start);
|
|
15856
16045
|
}
|
|
15857
16046
|
function isConstructorTypeReference(snapshot, reference2) {
|
|
15858
|
-
return snapshot.
|
|
15859
|
-
(call) => call.kind === "constructor" && call.nameRange.start.line === reference2.range.start.line && call.nameRange.start.character === reference2.range.start.character
|
|
15860
|
-
);
|
|
16047
|
+
return scriptFeatureIndex(snapshot).calls.get(reference2.start)?.kind === "constructor";
|
|
15861
16048
|
}
|
|
16049
|
+
var SCRIPT_FEATURE_INDEX, LOCAL_SCOPE_INDEX, NAMED_ITEM_INDEX, LOCAL_SYMBOL_CACHE;
|
|
15862
16050
|
var init_analyzer = __esm({
|
|
15863
16051
|
"../packages/neoscript-language/src/analyzer.ts"() {
|
|
15864
16052
|
"use strict";
|
|
16053
|
+
init_local_scope_index();
|
|
15865
16054
|
init_cell_pattern();
|
|
15866
16055
|
init_tile_conversion();
|
|
15867
16056
|
init_syntax_index();
|
|
@@ -15870,6 +16059,10 @@ var init_analyzer = __esm({
|
|
|
15870
16059
|
init_executable_parser();
|
|
15871
16060
|
init_strict_resolver();
|
|
15872
16061
|
init_project();
|
|
16062
|
+
SCRIPT_FEATURE_INDEX = /* @__PURE__ */ new WeakMap();
|
|
16063
|
+
LOCAL_SCOPE_INDEX = /* @__PURE__ */ new WeakMap();
|
|
16064
|
+
NAMED_ITEM_INDEX = /* @__PURE__ */ new WeakMap();
|
|
16065
|
+
LOCAL_SYMBOL_CACHE = /* @__PURE__ */ new WeakMap();
|
|
15873
16066
|
}
|
|
15874
16067
|
});
|
|
15875
16068
|
|
|
@@ -19131,16 +19324,34 @@ function documentPrefix(text, position) {
|
|
|
19131
19324
|
].join("\n");
|
|
19132
19325
|
}
|
|
19133
19326
|
function projectTokenAt(document, position) {
|
|
19134
|
-
|
|
19327
|
+
return projectTokens(document)[projectTokenIndexAt(document, position)];
|
|
19328
|
+
}
|
|
19329
|
+
function projectTokenIndexAt(document, position) {
|
|
19330
|
+
const offset = projectSourceText(document).offsetAt(position);
|
|
19135
19331
|
const tokens = projectTokens(document);
|
|
19136
|
-
|
|
19137
|
-
|
|
19138
|
-
)
|
|
19139
|
-
|
|
19140
|
-
|
|
19141
|
-
|
|
19142
|
-
|
|
19143
|
-
|
|
19332
|
+
let low = 0;
|
|
19333
|
+
let high = tokens.length;
|
|
19334
|
+
while (low < high) {
|
|
19335
|
+
const middle = low + high >>> 1;
|
|
19336
|
+
if (tokens[middle].start <= offset) low = middle + 1;
|
|
19337
|
+
else high = middle;
|
|
19338
|
+
}
|
|
19339
|
+
const candidate = tokens[low - 1];
|
|
19340
|
+
const containing = candidate && offset < candidate.end ? low - 1 : -1;
|
|
19341
|
+
if (isProjectNameToken(tokens[containing])) return containing;
|
|
19342
|
+
const touching = isProjectNameToken(candidate) && candidate.end === offset ? low - 1 : low - 2;
|
|
19343
|
+
if (isProjectNameToken(tokens[touching]) && tokens[touching].end === offset) {
|
|
19344
|
+
return touching;
|
|
19345
|
+
}
|
|
19346
|
+
return containing;
|
|
19347
|
+
}
|
|
19348
|
+
function projectSourceText(document) {
|
|
19349
|
+
let source = PROJECT_SOURCE_CACHE.get(document);
|
|
19350
|
+
if (!source) {
|
|
19351
|
+
source = new SourceText(document.text);
|
|
19352
|
+
PROJECT_SOURCE_CACHE.set(document, source);
|
|
19353
|
+
}
|
|
19354
|
+
return source;
|
|
19144
19355
|
}
|
|
19145
19356
|
function isProjectNameToken(token) {
|
|
19146
19357
|
return token !== void 0 && (token.kind === "identifier" || token.kind === "type" || token.kind === "keyword");
|
|
@@ -19148,7 +19359,7 @@ function isProjectNameToken(token) {
|
|
|
19148
19359
|
function projectTokens(document) {
|
|
19149
19360
|
const cached = PROJECT_TOKEN_CACHE.get(document);
|
|
19150
19361
|
if (cached) return cached;
|
|
19151
|
-
const source =
|
|
19362
|
+
const source = projectSourceText(document);
|
|
19152
19363
|
const tokens = lex(document.text).tokens.flatMap(
|
|
19153
19364
|
(token) => {
|
|
19154
19365
|
if (token.kind !== "string" || !token.raw.startsWith('"""')) {
|
|
@@ -19248,18 +19459,16 @@ function tripleInterpolationEnd(text, start, limit) {
|
|
|
19248
19459
|
}
|
|
19249
19460
|
return null;
|
|
19250
19461
|
}
|
|
19251
|
-
function rangesEqual(left, right) {
|
|
19252
|
-
return positionCompare2(left.start, right.start) === 0 && positionCompare2(left.end, right.end) === 0;
|
|
19253
|
-
}
|
|
19254
19462
|
function positionCompare2(left, right) {
|
|
19255
19463
|
return left.line === right.line ? left.character - right.character : left.line - right.line;
|
|
19256
19464
|
}
|
|
19257
|
-
var PROJECT_TOKEN_CACHE;
|
|
19465
|
+
var PROJECT_SOURCE_CACHE, PROJECT_TOKEN_CACHE;
|
|
19258
19466
|
var init_project_source_tokens = __esm({
|
|
19259
19467
|
"../packages/neoscript-language/src/project-source-tokens.ts"() {
|
|
19260
19468
|
"use strict";
|
|
19261
19469
|
init_lexer();
|
|
19262
19470
|
init_source_text();
|
|
19471
|
+
PROJECT_SOURCE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
19263
19472
|
PROJECT_TOKEN_CACHE = /* @__PURE__ */ new WeakMap();
|
|
19264
19473
|
}
|
|
19265
19474
|
});
|
|
@@ -19367,6 +19576,56 @@ var init_project_source_registry = __esm({
|
|
|
19367
19576
|
}
|
|
19368
19577
|
});
|
|
19369
19578
|
|
|
19579
|
+
// ../packages/neoscript-language/src/reference-argument.ts
|
|
19580
|
+
function parseReferenceArgument(raw) {
|
|
19581
|
+
let expression;
|
|
19582
|
+
try {
|
|
19583
|
+
expression = typeof raw === "string" ? parseExpression(raw) : raw;
|
|
19584
|
+
} catch {
|
|
19585
|
+
return null;
|
|
19586
|
+
}
|
|
19587
|
+
if (expression.kind === "litNull") return { kind: "none" };
|
|
19588
|
+
if (expression.kind === "call") {
|
|
19589
|
+
if (expression.callee.kind !== "ident" || expression.callee.name !== "Reference")
|
|
19590
|
+
return null;
|
|
19591
|
+
const idIndex = expression.argumentNames?.indexOf("id") ?? -1;
|
|
19592
|
+
const index = idIndex < 0 ? 0 : idIndex;
|
|
19593
|
+
if (expression.args.length < 1 || expression.args.length > 2) return null;
|
|
19594
|
+
for (let i2 = 0; i2 < expression.args.length; i2++) {
|
|
19595
|
+
const name = expression.argumentNames?.[i2];
|
|
19596
|
+
if (i2 === index) {
|
|
19597
|
+
if (name != null && name !== "id") return null;
|
|
19598
|
+
} else if (name !== "withProvenance" || expression.args[i2]?.kind !== "litBool")
|
|
19599
|
+
return null;
|
|
19600
|
+
}
|
|
19601
|
+
expression = expression.args[index];
|
|
19602
|
+
if (expression.kind === "litString") {
|
|
19603
|
+
return expression.value.length === 0 ? null : { kind: "id", value: expression.value };
|
|
19604
|
+
}
|
|
19605
|
+
}
|
|
19606
|
+
const segments = [];
|
|
19607
|
+
while (expression.kind === "member") {
|
|
19608
|
+
segments.push(expression.name);
|
|
19609
|
+
expression = expression.receiver;
|
|
19610
|
+
}
|
|
19611
|
+
if (expression.kind !== "ident" || expression.name !== "root" || segments.length === 0)
|
|
19612
|
+
return null;
|
|
19613
|
+
return { kind: "rootPath", value: ["root", ...segments.reverse()].join(".") };
|
|
19614
|
+
}
|
|
19615
|
+
function referenceArgumentRequirement(name) {
|
|
19616
|
+
if (name === "collectionValue")
|
|
19617
|
+
return '@settings collectionValue requires Reference("id") or a root path such as root.Assets.Collection.';
|
|
19618
|
+
if (name === "template")
|
|
19619
|
+
return '@settings template requires Reference("id") or a template symbol.';
|
|
19620
|
+
return `@settings ${name} requires Reference("id").`;
|
|
19621
|
+
}
|
|
19622
|
+
var init_reference_argument = __esm({
|
|
19623
|
+
"../packages/neoscript-language/src/reference-argument.ts"() {
|
|
19624
|
+
"use strict";
|
|
19625
|
+
init_executable_parser();
|
|
19626
|
+
}
|
|
19627
|
+
});
|
|
19628
|
+
|
|
19370
19629
|
// ../packages/neoscript-language/src/project-schema-contract.generated.ts
|
|
19371
19630
|
var PROJECT_FILE_UPLOAD_BATCH_SIZE, NEO_PROJECT_SOURCE_RECORD_CONTRACT;
|
|
19372
19631
|
var init_project_schema_contract_generated = __esm({
|
|
@@ -23942,6 +24201,22 @@ function validateAnnotations(uri, annotations, context, environment, diagnostics
|
|
|
23942
24201
|
if (field.name === "member" && (annotation2.name === "index" || annotation2.name === "column")) {
|
|
23943
24202
|
continue;
|
|
23944
24203
|
}
|
|
24204
|
+
if (annotation2.name === "settings" && (field.name === "collectionValue" || field.name === "group" || field.name === "template")) {
|
|
24205
|
+
const reference2 = parseReferenceArgument(argument2.text);
|
|
24206
|
+
if (reference2?.kind === "none" || reference2?.kind === "id" || reference2?.kind === "rootPath" && field.name === "collectionValue")
|
|
24207
|
+
continue;
|
|
24208
|
+
const templateSymbol = field.name === "template" && /^[A-Za-z_][A-Za-z0-9_]*$/.test(argument2.text.trim());
|
|
24209
|
+
if (!templateSymbol) {
|
|
24210
|
+
pushDiagnostic(
|
|
24211
|
+
diagnostics,
|
|
24212
|
+
uri,
|
|
24213
|
+
argument2.range,
|
|
24214
|
+
"invalid-reference-argument",
|
|
24215
|
+
referenceArgumentRequirement(field.name)
|
|
24216
|
+
);
|
|
24217
|
+
continue;
|
|
24218
|
+
}
|
|
24219
|
+
}
|
|
23945
24220
|
validateExpressionText(
|
|
23946
24221
|
uri,
|
|
23947
24222
|
argument2.text,
|
|
@@ -25758,6 +26033,7 @@ var NEO_VARIANT_FOLDER_SETTING, primitiveType, LIST_COLUMN_INHERITANCE_KEY, SEMA
|
|
|
25758
26033
|
var init_project_source_semantics = __esm({
|
|
25759
26034
|
"../packages/neoscript-language/src/project-source-semantics.ts"() {
|
|
25760
26035
|
"use strict";
|
|
26036
|
+
init_reference_argument();
|
|
25761
26037
|
init_project_source_ast();
|
|
25762
26038
|
init_project_local_values();
|
|
25763
26039
|
init_language_spec();
|
|
@@ -25783,18 +26059,25 @@ var init_project_source_semantics = __esm({
|
|
|
25783
26059
|
});
|
|
25784
26060
|
|
|
25785
26061
|
// ../packages/neoscript-language/src/project-source-accessors.ts
|
|
25786
|
-
function
|
|
25787
|
-
if (source.length === 0) return null;
|
|
26062
|
+
function projectSourceAccessors(source, containingRange) {
|
|
25788
26063
|
const full = new SourceText(source);
|
|
25789
26064
|
const range2 = containingRange ?? full.fullRange();
|
|
25790
26065
|
const bodyStart = full.offsetAt(range2.start);
|
|
25791
|
-
const
|
|
25792
|
-
|
|
25793
|
-
|
|
26066
|
+
const tokens = lex(
|
|
26067
|
+
source.slice(bodyStart, full.offsetAt(range2.end))
|
|
26068
|
+
).roots.filter((token) => token.kind !== "comment");
|
|
25794
26069
|
if (isToken(tokens[0], "operator", "=>")) {
|
|
25795
|
-
|
|
25796
|
-
|
|
26070
|
+
return [
|
|
26071
|
+
{
|
|
26072
|
+
keyword: "get",
|
|
26073
|
+
form: "expression",
|
|
26074
|
+
range: range2,
|
|
26075
|
+
parameters: null,
|
|
26076
|
+
body: expressionAccessor(source, full, tokens, bodyStart, 1)
|
|
26077
|
+
}
|
|
26078
|
+
];
|
|
25797
26079
|
}
|
|
26080
|
+
const accessors = [];
|
|
25798
26081
|
let depth = 0;
|
|
25799
26082
|
for (let index = 0; index < tokens.length; index++) {
|
|
25800
26083
|
const token = tokens[index];
|
|
@@ -25806,44 +26089,66 @@ function findProjectSourceAccessorBody(source, keyword, containingRange) {
|
|
|
25806
26089
|
depth--;
|
|
25807
26090
|
continue;
|
|
25808
26091
|
}
|
|
25809
|
-
if (depth !== 1 || token.kind !== "identifier" && token.kind !== "keyword" || token.text !==
|
|
26092
|
+
if (depth !== 1 || token.kind !== "identifier" && token.kind !== "keyword" || token.text !== "get" && token.text !== "set")
|
|
25810
26093
|
continue;
|
|
25811
|
-
}
|
|
25812
26094
|
let openIndex = index + 1;
|
|
26095
|
+
let parameters = null;
|
|
25813
26096
|
if (isToken(tokens[openIndex], "punctuation", "(")) {
|
|
26097
|
+
const firstParameter = ++openIndex;
|
|
25814
26098
|
let parameterDepth = 1;
|
|
25815
|
-
for (
|
|
25816
|
-
|
|
25817
|
-
if (isToken(
|
|
25818
|
-
if (
|
|
25819
|
-
if (parameterDepth !== 0) continue;
|
|
25820
|
-
openIndex = cursor + 1;
|
|
25821
|
-
break;
|
|
26099
|
+
for (; openIndex < tokens.length; openIndex++) {
|
|
26100
|
+
if (isToken(tokens[openIndex], "punctuation", "(")) parameterDepth++;
|
|
26101
|
+
if (isToken(tokens[openIndex], "punctuation", ")")) parameterDepth--;
|
|
26102
|
+
if (parameterDepth === 0) break;
|
|
25822
26103
|
}
|
|
25823
|
-
|
|
26104
|
+
parameters = tokens.slice(firstParameter, openIndex);
|
|
26105
|
+
openIndex++;
|
|
25824
26106
|
}
|
|
25825
26107
|
const open = tokens[openIndex];
|
|
26108
|
+
let body = null;
|
|
26109
|
+
let form = isToken(open, "punctuation", ";") ? "contract" : "invalid";
|
|
25826
26110
|
if (isToken(open, "operator", "=>")) {
|
|
25827
|
-
|
|
25828
|
-
|
|
25829
|
-
|
|
25830
|
-
|
|
25831
|
-
|
|
25832
|
-
|
|
25833
|
-
|
|
25834
|
-
|
|
25835
|
-
|
|
25836
|
-
|
|
25837
|
-
|
|
25838
|
-
|
|
25839
|
-
|
|
25840
|
-
|
|
25841
|
-
|
|
25842
|
-
|
|
26111
|
+
form = "expression";
|
|
26112
|
+
body = expressionAccessor(source, full, tokens, bodyStart, openIndex + 1);
|
|
26113
|
+
if (body) {
|
|
26114
|
+
const end = full.offsetAt(body.range.end) - bodyStart;
|
|
26115
|
+
while (openIndex + 1 < tokens.length && tokens[openIndex + 1].start < end)
|
|
26116
|
+
openIndex++;
|
|
26117
|
+
}
|
|
26118
|
+
} else if (isToken(open, "punctuation", "{")) {
|
|
26119
|
+
form = "block";
|
|
26120
|
+
let accessorDepth = 1;
|
|
26121
|
+
for (let cursor = openIndex + 1; cursor < tokens.length; cursor++) {
|
|
26122
|
+
const candidate = tokens[cursor];
|
|
26123
|
+
if (isToken(candidate, "punctuation", "{")) accessorDepth++;
|
|
26124
|
+
if (isToken(candidate, "punctuation", "}")) accessorDepth--;
|
|
26125
|
+
if (accessorDepth !== 0) continue;
|
|
26126
|
+
const start = bodyStart + open.end;
|
|
26127
|
+
const end = bodyStart + candidate.start;
|
|
26128
|
+
body = {
|
|
26129
|
+
range: full.range(start, end),
|
|
26130
|
+
source: source.slice(start, end),
|
|
26131
|
+
form: "block"
|
|
26132
|
+
};
|
|
26133
|
+
openIndex = cursor;
|
|
26134
|
+
break;
|
|
26135
|
+
}
|
|
25843
26136
|
}
|
|
25844
|
-
|
|
26137
|
+
accessors.push({
|
|
26138
|
+
keyword: token.text,
|
|
26139
|
+
form,
|
|
26140
|
+
range: full.range(bodyStart + token.start, bodyStart + token.end),
|
|
26141
|
+
parameters,
|
|
26142
|
+
body
|
|
26143
|
+
});
|
|
26144
|
+
index = Math.max(index, openIndex);
|
|
25845
26145
|
}
|
|
25846
|
-
return
|
|
26146
|
+
return accessors;
|
|
26147
|
+
}
|
|
26148
|
+
function findProjectSourceAccessorBody(source, keyword, containingRange) {
|
|
26149
|
+
return projectSourceAccessors(source, containingRange).find(
|
|
26150
|
+
(accessor) => accessor.keyword === keyword
|
|
26151
|
+
)?.body ?? null;
|
|
25847
26152
|
}
|
|
25848
26153
|
function isToken(token, kind, text) {
|
|
25849
26154
|
return token?.kind === kind && token.text === text;
|
|
@@ -26078,9 +26383,10 @@ function compileBody(args) {
|
|
|
26078
26383
|
memberName: args.memberName,
|
|
26079
26384
|
unit: args.unit,
|
|
26080
26385
|
range: args.range,
|
|
26081
|
-
context: args.context
|
|
26386
|
+
context: args.context,
|
|
26387
|
+
...args.bodyMode ? { bodyMode: args.bodyMode } : {}
|
|
26082
26388
|
});
|
|
26083
|
-
const source =
|
|
26389
|
+
const source = args.document.syntax.source;
|
|
26084
26390
|
const start = source.offsetAt(args.range.start);
|
|
26085
26391
|
const end = source.offsetAt(args.range.end);
|
|
26086
26392
|
const result = compileNeoScriptStrict(
|
|
@@ -26435,7 +26741,9 @@ function sourceMemberSymbol(member, owner, typeIds, source) {
|
|
|
26435
26741
|
};
|
|
26436
26742
|
}
|
|
26437
26743
|
if (member.kind === "property") {
|
|
26438
|
-
const hasSetter =
|
|
26744
|
+
const hasSetter = projectSourceAccessors(source, member.body.range).some(
|
|
26745
|
+
(accessor) => accessor.keyword === "set"
|
|
26746
|
+
);
|
|
26439
26747
|
return {
|
|
26440
26748
|
...common,
|
|
26441
26749
|
kind: "property",
|
|
@@ -27463,6 +27771,8 @@ function validateMemberTypeKind(uri, type, context, name, diagnostics) {
|
|
|
27463
27771
|
function validateMembers(environment, diagnostics) {
|
|
27464
27772
|
for (const ref of environment.interfaces.values()) {
|
|
27465
27773
|
for (const member of ref.declaration.members) {
|
|
27774
|
+
if (member.kind === "property")
|
|
27775
|
+
validatePropertyAccessors(ref, member, diagnostics);
|
|
27466
27776
|
if (member.kind === "field") {
|
|
27467
27777
|
diagnose(
|
|
27468
27778
|
diagnostics,
|
|
@@ -27723,34 +28033,95 @@ function validateClassMemberModifiers(ref, environment, diagnostics) {
|
|
|
27723
28033
|
related(ref.location, "The containing class is declared here.")
|
|
27724
28034
|
);
|
|
27725
28035
|
}
|
|
27726
|
-
if (member.kind === "property"
|
|
28036
|
+
if (member.kind === "property")
|
|
28037
|
+
validatePropertyAccessors(ref, member, diagnostics);
|
|
28038
|
+
if (modifiers.has("abstract") && member.kind === "field" && member.initializer) {
|
|
28039
|
+
diagnose(
|
|
28040
|
+
diagnostics,
|
|
28041
|
+
ref.uri,
|
|
28042
|
+
member.initializer.range,
|
|
28043
|
+
"abstract-member-initializer",
|
|
28044
|
+
`Abstract member '${member.name}' cannot declare a default initializer.`
|
|
28045
|
+
);
|
|
28046
|
+
}
|
|
28047
|
+
}
|
|
28048
|
+
}
|
|
28049
|
+
function validatePropertyAccessors(ref, member, diagnostics) {
|
|
28050
|
+
const accessors = projectSourceAccessors(member.body.text);
|
|
28051
|
+
const isInterface = ref.declaration.kind === "interface";
|
|
28052
|
+
const isAbstract = member.modifiers.includes("abstract");
|
|
28053
|
+
const contract = isInterface || isAbstract;
|
|
28054
|
+
const seen = /* @__PURE__ */ new Set();
|
|
28055
|
+
for (const accessor of accessors) {
|
|
28056
|
+
if (seen.has(accessor.keyword)) {
|
|
27727
28057
|
diagnose(
|
|
27728
28058
|
diagnostics,
|
|
27729
28059
|
ref.uri,
|
|
27730
28060
|
member.nameRange,
|
|
27731
|
-
"
|
|
27732
|
-
`Property '${ref.declaration.name}.${member.name}'
|
|
28061
|
+
"duplicate-property-accessor",
|
|
28062
|
+
`Property '${ref.declaration.name}.${member.name}' declares more than one '${accessor.keyword}' accessor.`
|
|
27733
28063
|
);
|
|
27734
28064
|
}
|
|
27735
|
-
|
|
28065
|
+
seen.add(accessor.keyword);
|
|
28066
|
+
if (accessor.form === "invalid") {
|
|
27736
28067
|
diagnose(
|
|
27737
28068
|
diagnostics,
|
|
27738
28069
|
ref.uri,
|
|
27739
|
-
member.
|
|
27740
|
-
"
|
|
27741
|
-
`
|
|
28070
|
+
member.nameRange,
|
|
28071
|
+
"invalid-property-accessor",
|
|
28072
|
+
`Property '${ref.declaration.name}.${member.name}' accessor '${accessor.keyword}' requires a body or a semicolon for an abstract/interface contract.`
|
|
27742
28073
|
);
|
|
27743
28074
|
}
|
|
27744
|
-
|
|
28075
|
+
const parameters = accessor.parameters;
|
|
28076
|
+
if (parameters !== null) {
|
|
28077
|
+
const actual = parameters.map((token) => token.text);
|
|
28078
|
+
const expected = accessor.keyword === "get" ? "" : `${accessorTypeName(member.type)} value`;
|
|
28079
|
+
const expectedTokens = lex(expected).roots.filter((token) => token.kind !== "eof").map((token) => token.text);
|
|
28080
|
+
if (actual.length !== expectedTokens.length || actual.some((token, index) => token !== expectedTokens[index])) {
|
|
28081
|
+
const signature = accessor.keyword === "get" ? "get" : `set(${accessorTypeName(member.type)} value)`;
|
|
28082
|
+
diagnose(
|
|
28083
|
+
diagnostics,
|
|
28084
|
+
ref.uri,
|
|
28085
|
+
member.nameRange,
|
|
28086
|
+
"property-accessor-signature",
|
|
28087
|
+
`Property '${ref.declaration.name}.${member.name}' requires '${signature}'; accessor parameters must match the property type and use the name 'value' for a setter.`
|
|
28088
|
+
);
|
|
28089
|
+
}
|
|
28090
|
+
}
|
|
28091
|
+
if (contract && (accessor.form === "block" || accessor.form === "expression")) {
|
|
27745
28092
|
diagnose(
|
|
27746
28093
|
diagnostics,
|
|
27747
28094
|
ref.uri,
|
|
27748
28095
|
member.body.range,
|
|
27749
|
-
"abstract-member-body",
|
|
27750
|
-
|
|
28096
|
+
isInterface ? "interface-property-body" : "abstract-member-body",
|
|
28097
|
+
`${isInterface ? "Interface" : "Abstract"} property '${member.name}' can declare accessor contracts but cannot implement an accessor body.`
|
|
28098
|
+
);
|
|
28099
|
+
}
|
|
28100
|
+
if (!contract && accessor.keyword === "set" && accessor.body === null) {
|
|
28101
|
+
diagnose(
|
|
28102
|
+
diagnostics,
|
|
28103
|
+
ref.uri,
|
|
28104
|
+
member.nameRange,
|
|
28105
|
+
"concrete-property-setter-body",
|
|
28106
|
+
`Property '${ref.declaration.name}.${member.name}' requires a setter body. Implement 'set(${accessorTypeName(member.type)} value) { ... }', or remove the setter for a read-only property.`
|
|
27751
28107
|
);
|
|
27752
28108
|
}
|
|
27753
28109
|
}
|
|
28110
|
+
if (!contract && !accessors.some(
|
|
28111
|
+
(accessor) => accessor.keyword === "get" && accessor.body !== null
|
|
28112
|
+
)) {
|
|
28113
|
+
diagnose(
|
|
28114
|
+
diagnostics,
|
|
28115
|
+
ref.uri,
|
|
28116
|
+
member.nameRange,
|
|
28117
|
+
"concrete-property-getter-body",
|
|
28118
|
+
`Property '${ref.declaration.name}.${member.name}' requires a getter body. Implement 'get { return ...; }' or 'get => ...;', declare the property abstract in an abstract class, or use a field with an initializer for stored data.`
|
|
28119
|
+
);
|
|
28120
|
+
}
|
|
28121
|
+
}
|
|
28122
|
+
function accessorTypeName(type) {
|
|
28123
|
+
const argumentsText = type.typeArguments.length ? `<${type.typeArguments.map(accessorTypeName).join(",")}>` : "";
|
|
28124
|
+
return `${type.name}${argumentsText}${type.nullable ? "?" : ""}`;
|
|
27754
28125
|
}
|
|
27755
28126
|
function validateClassOverrides(ref, environment, diagnostics) {
|
|
27756
28127
|
const inherited = inheritedClassMembers(ref, environment);
|
|
@@ -28144,10 +28515,10 @@ function valueAccessors(member, environment) {
|
|
|
28144
28515
|
};
|
|
28145
28516
|
}
|
|
28146
28517
|
if (member.kind === "function") return { get: false, set: false };
|
|
28147
|
-
|
|
28518
|
+
const accessors = projectSourceAccessors(member.body.text);
|
|
28148
28519
|
return {
|
|
28149
|
-
get:
|
|
28150
|
-
set:
|
|
28520
|
+
get: accessors.some((accessor) => accessor.keyword === "get"),
|
|
28521
|
+
set: accessors.some((accessor) => accessor.keyword === "set")
|
|
28151
28522
|
};
|
|
28152
28523
|
}
|
|
28153
28524
|
function resolvedSourceMemberStorage(owner, member, environment, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -28327,6 +28698,7 @@ var init_project_source_type_checker = __esm({
|
|
|
28327
28698
|
"use strict";
|
|
28328
28699
|
init_language_spec();
|
|
28329
28700
|
init_project_source_ast();
|
|
28701
|
+
init_lexer();
|
|
28330
28702
|
init_project_source_accessors();
|
|
28331
28703
|
init_project_source_identifiers();
|
|
28332
28704
|
BUILTIN_ARITY = /* @__PURE__ */ new Map([
|
|
@@ -29658,7 +30030,7 @@ function projectCompletions(analysis, document, position) {
|
|
|
29658
30030
|
return projectFallbackCompletions(analysis, document, position);
|
|
29659
30031
|
}
|
|
29660
30032
|
function projectAnnotationCompletions(analysis, document, position) {
|
|
29661
|
-
const source =
|
|
30033
|
+
const source = projectSourceText(document);
|
|
29662
30034
|
const offset = source.offsetAt(position);
|
|
29663
30035
|
const word = projectWordRange(document.text, offset);
|
|
29664
30036
|
if (document.text[word.start - 1] !== "@") return null;
|
|
@@ -29686,7 +30058,7 @@ function projectAnnotationNamesAt(analysis, document, position) {
|
|
|
29686
30058
|
if (document.languageId === "neoflow") {
|
|
29687
30059
|
return ["id", "primary", "incomplete"];
|
|
29688
30060
|
}
|
|
29689
|
-
const offset =
|
|
30061
|
+
const offset = projectSourceText(document).offsetAt(position);
|
|
29690
30062
|
const followingDeclaration = /^\s*(class|interface|enum)\b([^{}]*)/.exec(
|
|
29691
30063
|
document.text.slice(offset)
|
|
29692
30064
|
);
|
|
@@ -29738,7 +30110,7 @@ function projectMemberAnnotationNames(member) {
|
|
|
29738
30110
|
return names;
|
|
29739
30111
|
}
|
|
29740
30112
|
function projectContextualEnumCompletions(analysis, document, position) {
|
|
29741
|
-
const source =
|
|
30113
|
+
const source = projectSourceText(document);
|
|
29742
30114
|
const offset = source.offsetAt(position);
|
|
29743
30115
|
const word = projectWordRange(document.text, offset);
|
|
29744
30116
|
if (!isContextualDot(document.text, word.start)) return null;
|
|
@@ -29866,7 +30238,7 @@ function projectAfterNewAt(analysis, document, position) {
|
|
|
29866
30238
|
);
|
|
29867
30239
|
let cursor = tokens.length - 1;
|
|
29868
30240
|
const current = tokens[cursor];
|
|
29869
|
-
const offset =
|
|
30241
|
+
const offset = projectSourceText(document).offsetAt(position);
|
|
29870
30242
|
if (current?.kind === "identifier" && current.text !== "new" && /[A-Za-z0-9_]$/.test(document.text.slice(0, offset))) {
|
|
29871
30243
|
cursor--;
|
|
29872
30244
|
}
|
|
@@ -29899,10 +30271,35 @@ function projectTypeNameAssignable(analysis, sourceName, targetName) {
|
|
|
29899
30271
|
};
|
|
29900
30272
|
return derivesFrom(source.id);
|
|
29901
30273
|
}
|
|
30274
|
+
function projectBodies(analysis, uri) {
|
|
30275
|
+
let byUri = PROJECT_BODIES.get(analysis);
|
|
30276
|
+
if (!byUri) {
|
|
30277
|
+
byUri = /* @__PURE__ */ new Map();
|
|
30278
|
+
for (const body of analysis.bodyContexts) {
|
|
30279
|
+
const bodies = byUri.get(body.uri);
|
|
30280
|
+
if (bodies) bodies.push(body);
|
|
30281
|
+
else byUri.set(body.uri, [body]);
|
|
30282
|
+
}
|
|
30283
|
+
for (const bodies of byUri.values())
|
|
30284
|
+
bodies.sort((a, b) => positionCompare2(a.range.end, b.range.end));
|
|
30285
|
+
PROJECT_BODIES.set(analysis, byUri);
|
|
30286
|
+
}
|
|
30287
|
+
return byUri.get(uri) ?? [];
|
|
30288
|
+
}
|
|
30289
|
+
function rangeItemAt(items, position) {
|
|
30290
|
+
let low = 0;
|
|
30291
|
+
let high = items.length;
|
|
30292
|
+
while (low < high) {
|
|
30293
|
+
const middle = low + high >>> 1;
|
|
30294
|
+
if (positionCompare2(items[middle].range.end, position) < 0)
|
|
30295
|
+
low = middle + 1;
|
|
30296
|
+
else high = middle;
|
|
30297
|
+
}
|
|
30298
|
+
const item = items[low];
|
|
30299
|
+
return item && rangeContains(item.range, position) ? item : void 0;
|
|
30300
|
+
}
|
|
29902
30301
|
function projectBodySnapshotAt(analysis, document, position) {
|
|
29903
|
-
const body = analysis.
|
|
29904
|
-
(candidate) => candidate.uri === document.uri && rangeContains(candidate.range, position)
|
|
29905
|
-
);
|
|
30302
|
+
const body = rangeItemAt(projectBodies(analysis, document.uri), position);
|
|
29906
30303
|
return body ? projectBodySnapshot(analysis, document, body) : null;
|
|
29907
30304
|
}
|
|
29908
30305
|
function projectBodySnapshot(analysis, document, body) {
|
|
@@ -29913,30 +30310,35 @@ function projectBodySnapshot(analysis, document, body) {
|
|
|
29913
30310
|
}
|
|
29914
30311
|
const cached = snapshots.get(body);
|
|
29915
30312
|
if (cached) return cached;
|
|
29916
|
-
const source =
|
|
30313
|
+
const source = projectSourceText(document);
|
|
29917
30314
|
const start = source.offsetAt(body.range.start);
|
|
29918
30315
|
const end = source.offsetAt(body.range.end);
|
|
29919
|
-
const
|
|
29920
|
-
const syntax = analyzeNeoScriptSyntax(
|
|
30316
|
+
const lexed = analysis.documents.get(document.uri)?.syntax ?? lex(document.text);
|
|
30317
|
+
const syntax = analyzeNeoScriptSyntax(
|
|
30318
|
+
document.text,
|
|
30319
|
+
body.context.kind,
|
|
30320
|
+
sliceLexResult(lexed, start, end)
|
|
30321
|
+
);
|
|
29921
30322
|
const context = { ...body.context, project: analysis.project };
|
|
29922
30323
|
const snapshot = {
|
|
29923
30324
|
uri: document.uri,
|
|
30325
|
+
...body.bodyMode === "expression" ? { expressionRange: body.range } : {},
|
|
29924
30326
|
source: syntax.lexed.source,
|
|
29925
30327
|
lexed: syntax.lexed,
|
|
29926
30328
|
parsed: syntax.parsed,
|
|
29927
30329
|
context,
|
|
29928
|
-
project:
|
|
30330
|
+
project: projectBodyIndex(analysis, context)
|
|
29929
30331
|
};
|
|
29930
30332
|
snapshots.set(body, snapshot);
|
|
29931
30333
|
return snapshot;
|
|
29932
30334
|
}
|
|
29933
|
-
function
|
|
29934
|
-
let
|
|
29935
|
-
|
|
29936
|
-
|
|
29937
|
-
|
|
30335
|
+
function projectBodyIndex(analysis, context) {
|
|
30336
|
+
let index = PROJECT_BODY_INDEX_CACHE.get(analysis);
|
|
30337
|
+
if (!index) {
|
|
30338
|
+
index = buildProjectIndexWithBuiltins(context);
|
|
30339
|
+
PROJECT_BODY_INDEX_CACHE.set(analysis, index);
|
|
29938
30340
|
}
|
|
29939
|
-
return
|
|
30341
|
+
return index;
|
|
29940
30342
|
}
|
|
29941
30343
|
function projectWordRange(text, offset) {
|
|
29942
30344
|
let start = offset;
|
|
@@ -29949,9 +30351,9 @@ function isContextualDot(text, wordStart) {
|
|
|
29949
30351
|
while (cursor >= 0 && /\s/.test(text[cursor] ?? "")) cursor--;
|
|
29950
30352
|
const beforeDot = text[cursor];
|
|
29951
30353
|
if (beforeDot !== void 0 && /[A-Za-z0-9_]/.test(beforeDot)) {
|
|
29952
|
-
|
|
29953
|
-
|
|
29954
|
-
)
|
|
30354
|
+
let start = cursor;
|
|
30355
|
+
while (start > 0 && /[A-Za-z0-9_]/.test(text[start - 1])) start--;
|
|
30356
|
+
const precedingWord = text.slice(start, cursor + 1);
|
|
29955
30357
|
return precedingWord === "return" || precedingWord === "case";
|
|
29956
30358
|
}
|
|
29957
30359
|
return beforeDot === void 0 || !/[A-Za-z0-9_\])}]/.test(beforeDot);
|
|
@@ -30012,54 +30414,44 @@ function projectClassBasePositionAt(analysis, document, position) {
|
|
|
30012
30414
|
return true;
|
|
30013
30415
|
}
|
|
30014
30416
|
function sourceTypeAt(document, position) {
|
|
30015
|
-
const contains2 = (
|
|
30016
|
-
for (const argument2 of
|
|
30417
|
+
const contains2 = (type2) => {
|
|
30418
|
+
for (const argument2 of type2.typeArguments) {
|
|
30017
30419
|
const nested = contains2(argument2);
|
|
30018
30420
|
if (nested) return nested;
|
|
30019
30421
|
}
|
|
30020
|
-
return rangeContains(
|
|
30021
|
-
};
|
|
30022
|
-
const parameterType = (parameters) => {
|
|
30023
|
-
for (const parameter4 of parameters ?? []) {
|
|
30024
|
-
const match = contains2(parameter4.type);
|
|
30025
|
-
if (match) return match;
|
|
30026
|
-
}
|
|
30027
|
-
return null;
|
|
30422
|
+
return rangeContains(type2.range, position) ? type2 : null;
|
|
30028
30423
|
};
|
|
30029
|
-
|
|
30030
|
-
|
|
30031
|
-
|
|
30032
|
-
|
|
30033
|
-
|
|
30034
|
-
}
|
|
30035
|
-
|
|
30036
|
-
|
|
30037
|
-
|
|
30038
|
-
|
|
30039
|
-
}
|
|
30040
|
-
if (declaration.kind === "class") {
|
|
30041
|
-
const header = parameterType(declaration.headerParameters);
|
|
30042
|
-
if (header) return header;
|
|
30043
|
-
for (const generic of declaration.genericParameters) {
|
|
30044
|
-
if (!generic.constraint) continue;
|
|
30045
|
-
const match = contains2(generic.constraint);
|
|
30046
|
-
if (match) return match;
|
|
30424
|
+
let types = SOURCE_TYPES.get(document);
|
|
30425
|
+
if (!types) {
|
|
30426
|
+
types = [];
|
|
30427
|
+
const parameters = (items) => {
|
|
30428
|
+
for (const parameter4 of items ?? []) types.push(parameter4.type);
|
|
30429
|
+
};
|
|
30430
|
+
for (const declaration of document.declarations) {
|
|
30431
|
+
if (declaration.kind === "global") {
|
|
30432
|
+
types.push(declaration.type);
|
|
30433
|
+
continue;
|
|
30047
30434
|
}
|
|
30048
|
-
|
|
30049
|
-
|
|
30050
|
-
|
|
30435
|
+
if (declaration.kind === "enum") continue;
|
|
30436
|
+
types.push(...declaration.baseTypes);
|
|
30437
|
+
if (declaration.kind === "class") {
|
|
30438
|
+
parameters(declaration.headerParameters);
|
|
30439
|
+
for (const generic of declaration.genericParameters) {
|
|
30440
|
+
if (generic.constraint) types.push(generic.constraint);
|
|
30441
|
+
}
|
|
30442
|
+
for (const constructor2 of declaration.constructors)
|
|
30443
|
+
parameters(constructor2.parameters);
|
|
30051
30444
|
}
|
|
30052
|
-
|
|
30053
|
-
|
|
30054
|
-
|
|
30055
|
-
if (memberType2) return memberType2;
|
|
30056
|
-
if (member.kind === "function") {
|
|
30057
|
-
const match = parameterType(member.parameters);
|
|
30058
|
-
if (match) return match;
|
|
30445
|
+
for (const member of declaration.members) {
|
|
30446
|
+
types.push(member.type);
|
|
30447
|
+
if (member.kind === "function") parameters(member.parameters);
|
|
30059
30448
|
}
|
|
30060
30449
|
}
|
|
30450
|
+
types.sort((a, b) => positionCompare2(a.range.end, b.range.end));
|
|
30451
|
+
SOURCE_TYPES.set(document, types);
|
|
30061
30452
|
}
|
|
30062
|
-
|
|
30453
|
+
const type = rangeItemAt(types, position);
|
|
30454
|
+
return type ? contains2(type) : null;
|
|
30063
30455
|
}
|
|
30064
30456
|
function projectMemberCompletions(analysis, document, position) {
|
|
30065
30457
|
const owner = projectMemberCompletionOwnerToken(document, position);
|
|
@@ -30436,6 +30828,7 @@ function projectCompletionKind(symbol) {
|
|
|
30436
30828
|
case "constructor":
|
|
30437
30829
|
return "method";
|
|
30438
30830
|
case "parameter":
|
|
30831
|
+
case "local":
|
|
30439
30832
|
case "flowBinding":
|
|
30440
30833
|
case "graphChild":
|
|
30441
30834
|
case "global":
|
|
@@ -30677,7 +31070,7 @@ function requiredDestinationEdit(sourceDocument, document, initializer, destinat
|
|
|
30677
31070
|
};
|
|
30678
31071
|
}
|
|
30679
31072
|
if (initializer.body.kind !== "block") return null;
|
|
30680
|
-
const source =
|
|
31073
|
+
const source = projectSourceText(document);
|
|
30681
31074
|
const start = source.offsetAt(initializer.body.range.start);
|
|
30682
31075
|
const end = source.offsetAt(initializer.body.range.end);
|
|
30683
31076
|
const tokens = sourceDocument.syntax.tokens;
|
|
@@ -30756,9 +31149,7 @@ function projectSignatureHelp(analysis, document, position) {
|
|
|
30756
31149
|
};
|
|
30757
31150
|
}
|
|
30758
31151
|
function projectInlayHints(analysis, document, range2) {
|
|
30759
|
-
const bodyContexts = analysis.
|
|
30760
|
-
(body) => body.uri === document.uri
|
|
30761
|
-
);
|
|
31152
|
+
const bodyContexts = projectBodies(analysis, document.uri);
|
|
30762
31153
|
const tokens = projectDocumentTokens(analysis, document).filter(
|
|
30763
31154
|
(token) => token.kind !== "comment" && token.kind !== "eof"
|
|
30764
31155
|
);
|
|
@@ -30767,19 +31158,28 @@ function projectInlayHints(analysis, document, range2) {
|
|
|
30767
31158
|
document
|
|
30768
31159
|
);
|
|
30769
31160
|
const hints = [];
|
|
31161
|
+
const delimiterEnds = projectDelimiterEnds(tokens);
|
|
30770
31162
|
for (let index = 0; index < tokens.length - 1; index++) {
|
|
30771
31163
|
const callee = tokens[index];
|
|
30772
31164
|
const open = tokens[index + 1];
|
|
30773
31165
|
if (!callee || callee.kind !== "identifier" && callee.kind !== "type") {
|
|
30774
31166
|
continue;
|
|
30775
31167
|
}
|
|
30776
|
-
if (bodyContexts
|
|
31168
|
+
if (rangeItemAt(bodyContexts, callee.range.start)) {
|
|
30777
31169
|
continue;
|
|
30778
31170
|
}
|
|
30779
31171
|
if (!open || open.text !== "(") continue;
|
|
30780
31172
|
const beforeCallee = tokens[index - 1];
|
|
30781
31173
|
if (beforeCallee?.text === "@") continue;
|
|
30782
31174
|
if (declarationNames.has(positionKey(callee.range.start))) continue;
|
|
31175
|
+
if (range2 && positionCompare2(callee.range.start, range2.end) > 0) break;
|
|
31176
|
+
const callArguments2 = projectCallArguments(
|
|
31177
|
+
tokens,
|
|
31178
|
+
index + 1,
|
|
31179
|
+
delimiterEnds
|
|
31180
|
+
);
|
|
31181
|
+
if (range2 && !callArguments2.some((argument2) => rangeContains(range2, argument2.start)))
|
|
31182
|
+
continue;
|
|
30783
31183
|
const parameterNames = projectCallParameterNames(
|
|
30784
31184
|
analysis,
|
|
30785
31185
|
document,
|
|
@@ -30787,7 +31187,6 @@ function projectInlayHints(analysis, document, range2) {
|
|
|
30787
31187
|
beforeCallee
|
|
30788
31188
|
);
|
|
30789
31189
|
if (!parameterNames) continue;
|
|
30790
|
-
const callArguments2 = projectCallArguments(tokens, index + 1);
|
|
30791
31190
|
for (let argument2 = 0; argument2 < callArguments2.length; argument2++) {
|
|
30792
31191
|
const argumentToken = callArguments2[argument2];
|
|
30793
31192
|
if (!argumentToken || argumentToken.named) continue;
|
|
@@ -30806,6 +31205,8 @@ function projectInlayHints(analysis, document, range2) {
|
|
|
30806
31205
|
}
|
|
30807
31206
|
}
|
|
30808
31207
|
for (const body of bodyContexts) {
|
|
31208
|
+
if (range2 && (positionCompare2(body.range.end, range2.start) < 0 || positionCompare2(body.range.start, range2.end) > 0))
|
|
31209
|
+
continue;
|
|
30809
31210
|
const snapshot = projectBodySnapshot(analysis, document, body);
|
|
30810
31211
|
hints.push(
|
|
30811
31212
|
...inlayHints(snapshot, range2).filter(
|
|
@@ -30850,19 +31251,31 @@ function projectCallParameterNames(analysis, document, callee, beforeCallee) {
|
|
|
30850
31251
|
return names.size === 1 && name ? name : null;
|
|
30851
31252
|
});
|
|
30852
31253
|
}
|
|
30853
|
-
function
|
|
31254
|
+
function projectDelimiterEnds(tokens) {
|
|
31255
|
+
const ends = /* @__PURE__ */ new Map();
|
|
31256
|
+
const stack = [];
|
|
31257
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
31258
|
+
const text = tokens[index].text;
|
|
31259
|
+
if (text === "(" || text === "[" || text === "{") stack.push(index);
|
|
31260
|
+
else if (text === ")" || text === "]" || text === "}") {
|
|
31261
|
+
const open = stack.pop();
|
|
31262
|
+
if (open !== void 0) ends.set(open, index);
|
|
31263
|
+
}
|
|
31264
|
+
}
|
|
31265
|
+
return ends;
|
|
31266
|
+
}
|
|
31267
|
+
function projectCallArguments(tokens, openIndex, delimiterEnds) {
|
|
30854
31268
|
const result = [];
|
|
30855
|
-
let depth = 0;
|
|
30856
31269
|
let atArgumentStart = true;
|
|
30857
31270
|
for (let index = openIndex + 1; index < tokens.length; index++) {
|
|
30858
31271
|
const token = tokens[index];
|
|
30859
31272
|
if (!token) break;
|
|
30860
|
-
if (
|
|
30861
|
-
if (
|
|
31273
|
+
if (token.text === ")") break;
|
|
31274
|
+
if (token.text === ",") {
|
|
30862
31275
|
atArgumentStart = true;
|
|
30863
31276
|
continue;
|
|
30864
31277
|
}
|
|
30865
|
-
if (
|
|
31278
|
+
if (atArgumentStart) {
|
|
30866
31279
|
result.push({
|
|
30867
31280
|
start: token.range.start,
|
|
30868
31281
|
named: token.kind === "identifier" && tokens[index + 1]?.text === ":",
|
|
@@ -30871,9 +31284,7 @@ function projectCallArguments(tokens, openIndex) {
|
|
|
30871
31284
|
atArgumentStart = false;
|
|
30872
31285
|
}
|
|
30873
31286
|
if (token.text === "(" || token.text === "[" || token.text === "{") {
|
|
30874
|
-
|
|
30875
|
-
} else if (token.text === ")" || token.text === "]" || token.text === "}") {
|
|
30876
|
-
if (depth > 0) depth--;
|
|
31287
|
+
index = delimiterEnds.get(index) ?? tokens.length;
|
|
30877
31288
|
}
|
|
30878
31289
|
}
|
|
30879
31290
|
return result;
|
|
@@ -30988,6 +31399,7 @@ function projectSemanticTokenType(symbol) {
|
|
|
30988
31399
|
return symbol.callable ? "method" : "property";
|
|
30989
31400
|
case "constructor":
|
|
30990
31401
|
return "method";
|
|
31402
|
+
case "local":
|
|
30991
31403
|
case "graphChild":
|
|
30992
31404
|
case "flowBinding":
|
|
30993
31405
|
case "global":
|
|
@@ -30998,9 +31410,13 @@ function symbolRangeKey(range2) {
|
|
|
30998
31410
|
return `${range2.start.line}:${range2.start.character}-${range2.end.line}:${range2.end.character}`;
|
|
30999
31411
|
}
|
|
31000
31412
|
function buildProjectSymbolIndex(symbols) {
|
|
31413
|
+
const cached = PROJECT_SYMBOL_INDEX_CACHE.get(symbols);
|
|
31414
|
+
if (cached) return cached;
|
|
31001
31415
|
const byLocation = /* @__PURE__ */ new Map();
|
|
31002
31416
|
const byName = /* @__PURE__ */ new Map();
|
|
31417
|
+
const byId = /* @__PURE__ */ new Map();
|
|
31003
31418
|
for (const symbol of symbols) {
|
|
31419
|
+
if (symbol.id !== null) byId.set(symbol.id, symbol);
|
|
31004
31420
|
let uriBucket = byLocation.get(symbol.location.uri);
|
|
31005
31421
|
if (!uriBucket) {
|
|
31006
31422
|
uriBucket = /* @__PURE__ */ new Map();
|
|
@@ -31014,7 +31430,9 @@ function buildProjectSymbolIndex(symbols) {
|
|
|
31014
31430
|
if (named) named.push(symbol);
|
|
31015
31431
|
else byName.set(symbol.name, [symbol]);
|
|
31016
31432
|
}
|
|
31017
|
-
|
|
31433
|
+
const index = { byLocation, byName, byId };
|
|
31434
|
+
PROJECT_SYMBOL_INDEX_CACHE.set(symbols, index);
|
|
31435
|
+
return index;
|
|
31018
31436
|
}
|
|
31019
31437
|
function symbolsDeclaredAt(index, uri, range2) {
|
|
31020
31438
|
return index.byLocation.get(uri)?.get(symbolRangeKey(range2)) ?? [];
|
|
@@ -31022,16 +31440,14 @@ function symbolsDeclaredAt(index, uri, range2) {
|
|
|
31022
31440
|
function projectSemanticTokens(document, analysis) {
|
|
31023
31441
|
const index = buildProjectSymbolIndex(analysis.symbols);
|
|
31024
31442
|
const tokens = projectTokens(document);
|
|
31025
|
-
const bodyContexts = analysis.
|
|
31026
|
-
(body) => body.uri === document.uri
|
|
31027
|
-
);
|
|
31443
|
+
const bodyContexts = projectBodies(analysis, document.uri);
|
|
31028
31444
|
const result = tokens.flatMap((token, tokenIndex) => {
|
|
31029
31445
|
if (token.kind === "eof" || token.kind === "error") return [];
|
|
31030
|
-
if (bodyContexts
|
|
31446
|
+
if (rangeItemAt(bodyContexts, token.range.start)) {
|
|
31031
31447
|
return [];
|
|
31032
31448
|
}
|
|
31033
31449
|
const declaration = symbolsDeclaredAt(index, document.uri, token.range)[0];
|
|
31034
|
-
const resolved = isProjectNameToken(token) ? indexedProjectSymbolAt(analysis, document, token.range.start, index)?.symbol : void 0;
|
|
31450
|
+
const resolved = !declaration && isProjectNameToken(token) ? indexedProjectSymbolAt(analysis, document, token.range.start, index)?.symbol : void 0;
|
|
31035
31451
|
let type;
|
|
31036
31452
|
if (declaration) {
|
|
31037
31453
|
type = projectSemanticTokenType(declaration);
|
|
@@ -31078,32 +31494,40 @@ function isProjectContextualKeyword(tokens, tokenIndex) {
|
|
|
31078
31494
|
if (token?.text !== "new") return false;
|
|
31079
31495
|
return next?.text === "(" || next?.text === "{" || next?.kind === "identifier" || next?.kind === "type";
|
|
31080
31496
|
}
|
|
31081
|
-
function projectSymbolAt(analysis, document, position) {
|
|
31082
|
-
return indexedProjectSymbolAt(
|
|
31083
|
-
analysis,
|
|
31084
|
-
document,
|
|
31085
|
-
position,
|
|
31086
|
-
buildProjectSymbolIndex(analysis.symbols)
|
|
31087
|
-
);
|
|
31497
|
+
function projectSymbolAt(analysis, document, position, index = buildProjectSymbolIndex(analysis.symbols)) {
|
|
31498
|
+
return indexedProjectSymbolAt(analysis, document, position, index);
|
|
31088
31499
|
}
|
|
31089
31500
|
function indexedProjectSymbolAt(analysis, document, position, index) {
|
|
31090
|
-
const
|
|
31501
|
+
const tokenIndex = projectTokenIndexAt(document, position);
|
|
31502
|
+
const sourceTokens = projectTokens(document);
|
|
31503
|
+
const token = sourceTokens[tokenIndex];
|
|
31091
31504
|
if (!isProjectNameToken(token)) return null;
|
|
31092
31505
|
const body = projectBodySnapshotAt(analysis, document, position);
|
|
31093
31506
|
if (body) {
|
|
31507
|
+
const local = localSymbolAtPosition(body, position);
|
|
31508
|
+
if (local?.location) {
|
|
31509
|
+
return {
|
|
31510
|
+
token,
|
|
31511
|
+
symbol: {
|
|
31512
|
+
kind: "local",
|
|
31513
|
+
id: local.id,
|
|
31514
|
+
name: local.name,
|
|
31515
|
+
location: local.location
|
|
31516
|
+
}
|
|
31517
|
+
};
|
|
31518
|
+
}
|
|
31094
31519
|
const reference2 = referenceAtPosition(body, position);
|
|
31095
31520
|
const symbolId = reference2 ? resolveReferenceSymbolId(body, reference2) : null;
|
|
31096
|
-
const
|
|
31521
|
+
const executable = symbolId ? body.project.symbolById.get(symbolId) : void 0;
|
|
31522
|
+
const location3 = executable?.selectionLocation ?? executable?.location;
|
|
31523
|
+
const located = location3 ? symbolsDeclaredAt(index, location3.uri, location3.range)[0] : void 0;
|
|
31524
|
+
const symbol = located ?? (symbolId ? index.byId.get(symbolId) : void 0);
|
|
31097
31525
|
if (symbol) return { token, symbol };
|
|
31098
31526
|
}
|
|
31099
31527
|
const exact = symbolsDeclaredAt(index, document.uri, token.range);
|
|
31100
31528
|
if (exact.length === 1) return { token, symbol: exact[0] };
|
|
31101
31529
|
const candidates = index.byName.get(token.text) ?? [];
|
|
31102
31530
|
if (candidates.length === 0) return null;
|
|
31103
|
-
const sourceTokens = projectTokens(document);
|
|
31104
|
-
const tokenIndex = sourceTokens.findIndex(
|
|
31105
|
-
(candidate) => candidate.start === token.start && candidate.end === token.end
|
|
31106
|
-
);
|
|
31107
31531
|
const source = analysis.documents.get(document.uri);
|
|
31108
31532
|
const typePosition = source && sourceTypeAt(source, token.range.start);
|
|
31109
31533
|
if (typePosition || sourceTokens[tokenIndex - 1]?.text === "new") {
|
|
@@ -31275,6 +31699,7 @@ function projectSymbolTypeName(symbol) {
|
|
|
31275
31699
|
return symbol.name;
|
|
31276
31700
|
case "member":
|
|
31277
31701
|
case "parameter":
|
|
31702
|
+
case "local":
|
|
31278
31703
|
case "flowBinding":
|
|
31279
31704
|
case "global":
|
|
31280
31705
|
return symbol.detail ?? null;
|
|
@@ -31291,13 +31716,6 @@ function declarationContaining(document, position) {
|
|
|
31291
31716
|
(declaration) => positionCompare2(declaration.range.start, position) <= 0 && positionCompare2(position, declaration.range.end) <= 0
|
|
31292
31717
|
);
|
|
31293
31718
|
}
|
|
31294
|
-
function sameProjectSymbol(left, right) {
|
|
31295
|
-
if (left.kind !== right.kind) return false;
|
|
31296
|
-
if (left.id && right.id) {
|
|
31297
|
-
return left.id === right.id && (left.kind !== "enumOption" || left.ownerName === right.ownerName);
|
|
31298
|
-
}
|
|
31299
|
-
return left.location.uri === right.location.uri && rangesEqual(left.location.range, right.location.range);
|
|
31300
|
-
}
|
|
31301
31719
|
function tokensBeforePosition(tokens, position) {
|
|
31302
31720
|
return tokens.filter(
|
|
31303
31721
|
(token) => token.kind !== "comment" && token.kind !== "eof" && positionCompare2(token.range.start, position) < 0
|
|
@@ -31391,31 +31809,67 @@ function contextualConstructorType(analysis, document, position) {
|
|
|
31391
31809
|
function initializerRootAt(analysis, document, position) {
|
|
31392
31810
|
const source = analysis.documents.get(document.uri);
|
|
31393
31811
|
if (!source) return null;
|
|
31394
|
-
|
|
31395
|
-
|
|
31396
|
-
|
|
31397
|
-
|
|
31812
|
+
let roots = INITIALIZER_ROOTS.get(source);
|
|
31813
|
+
if (!roots) {
|
|
31814
|
+
roots = [];
|
|
31815
|
+
for (const declaration of source.declarations) {
|
|
31816
|
+
if (declaration.kind === "global") {
|
|
31817
|
+
roots.push({
|
|
31398
31818
|
type: declaration.type,
|
|
31399
31819
|
range: declaration.initializer.range
|
|
31400
|
-
};
|
|
31820
|
+
});
|
|
31821
|
+
continue;
|
|
31401
31822
|
}
|
|
31402
|
-
continue;
|
|
31403
|
-
|
|
31404
|
-
|
|
31405
|
-
|
|
31406
|
-
|
|
31407
|
-
return { type: member.type, range: member.initializer.range };
|
|
31823
|
+
if (declaration.kind === "enum") continue;
|
|
31824
|
+
for (const member of declaration.members) {
|
|
31825
|
+
if (member.kind === "field" && member.initializer) {
|
|
31826
|
+
roots.push({ type: member.type, range: member.initializer.range });
|
|
31827
|
+
}
|
|
31408
31828
|
}
|
|
31409
31829
|
}
|
|
31830
|
+
roots.sort((a, b) => positionCompare2(a.range.end, b.range.end));
|
|
31831
|
+
INITIALIZER_ROOTS.set(source, roots);
|
|
31410
31832
|
}
|
|
31411
|
-
return null;
|
|
31833
|
+
return rangeItemAt(roots, position) ?? null;
|
|
31412
31834
|
}
|
|
31413
31835
|
function constructionSiteAt(analysis, document, position) {
|
|
31414
31836
|
const root = initializerRootAt(analysis, document, position);
|
|
31415
31837
|
if (!root) return null;
|
|
31416
|
-
|
|
31417
|
-
|
|
31418
|
-
|
|
31838
|
+
let documents = CONSTRUCTION_SITE_CACHE.get(analysis);
|
|
31839
|
+
if (!documents) {
|
|
31840
|
+
documents = /* @__PURE__ */ new WeakMap();
|
|
31841
|
+
CONSTRUCTION_SITE_CACHE.set(analysis, documents);
|
|
31842
|
+
}
|
|
31843
|
+
let roots = documents.get(document);
|
|
31844
|
+
if (!roots) {
|
|
31845
|
+
roots = /* @__PURE__ */ new Map();
|
|
31846
|
+
documents.set(document, roots);
|
|
31847
|
+
}
|
|
31848
|
+
const key = positionKey(root.range.start);
|
|
31849
|
+
let sites = roots.get(key);
|
|
31850
|
+
if (!sites) {
|
|
31851
|
+
sites = indexConstructionSites(analysis, document, root);
|
|
31852
|
+
roots.set(key, sites);
|
|
31853
|
+
}
|
|
31854
|
+
let low = 0;
|
|
31855
|
+
let high = sites.length;
|
|
31856
|
+
while (low < high) {
|
|
31857
|
+
const middle = low + high >>> 1;
|
|
31858
|
+
if (positionCompare2(sites[middle].position, position) < 0)
|
|
31859
|
+
low = middle + 1;
|
|
31860
|
+
else high = middle;
|
|
31861
|
+
}
|
|
31862
|
+
return sites[Math.max(0, low - 1)].site;
|
|
31863
|
+
}
|
|
31864
|
+
function indexConstructionSites(analysis, document, root) {
|
|
31865
|
+
const allTokens = projectTokens(document);
|
|
31866
|
+
let start = Math.max(0, projectTokenIndexAt(document, root.range.start));
|
|
31867
|
+
while (start < allTokens.length && positionCompare2(allTokens[start].range.start, root.range.start) < 0)
|
|
31868
|
+
start++;
|
|
31869
|
+
let end = start;
|
|
31870
|
+
while (end < allTokens.length && positionCompare2(allTokens[end].range.start, root.range.end) <= 0)
|
|
31871
|
+
end++;
|
|
31872
|
+
const tokens = allTokens.slice(start, end).filter((token) => token.kind !== "comment" && token.kind !== "eof");
|
|
31419
31873
|
const stack = [];
|
|
31420
31874
|
const expectedType = () => {
|
|
31421
31875
|
const frame = stack.at(-1);
|
|
@@ -31432,11 +31886,38 @@ function constructionSiteAt(analysis, document, position) {
|
|
|
31432
31886
|
return null;
|
|
31433
31887
|
}
|
|
31434
31888
|
};
|
|
31889
|
+
const objects = [];
|
|
31890
|
+
const snapshot = () => {
|
|
31891
|
+
const expected = expectedType();
|
|
31892
|
+
const innermost = stack.at(-1);
|
|
31893
|
+
const directly = innermost?.kind === "object" ? innermost : null;
|
|
31894
|
+
const keys = directly?.keys ?? [];
|
|
31895
|
+
const keyCount = keys.length;
|
|
31896
|
+
return {
|
|
31897
|
+
expectedType: expected,
|
|
31898
|
+
expectedTypeName: expected?.name ?? null,
|
|
31899
|
+
enclosingTypeName: objects.at(-1)?.typeName ?? null,
|
|
31900
|
+
initializerTypeName: directly?.typeName ?? null,
|
|
31901
|
+
get initializerKeys() {
|
|
31902
|
+
return keys.slice(0, keyCount);
|
|
31903
|
+
},
|
|
31904
|
+
atInitializerKey: directly?.atKey ?? false
|
|
31905
|
+
};
|
|
31906
|
+
};
|
|
31907
|
+
const sites = [];
|
|
31908
|
+
let previousPosition = root.range.start;
|
|
31909
|
+
const pop = () => {
|
|
31910
|
+
const frame = stack.pop();
|
|
31911
|
+
if (frame?.kind === "object") objects.pop();
|
|
31912
|
+
return frame;
|
|
31913
|
+
};
|
|
31435
31914
|
let sawNew = false;
|
|
31436
31915
|
let pendingNewTypeName = null;
|
|
31437
31916
|
let closedConstructorTypeName = null;
|
|
31438
31917
|
for (let index = 0; index < tokens.length; index++) {
|
|
31918
|
+
sites.push({ position: previousPosition, site: snapshot() });
|
|
31439
31919
|
const token = tokens[index];
|
|
31920
|
+
previousPosition = token.range.start;
|
|
31440
31921
|
if (token.text === "@") {
|
|
31441
31922
|
if ((tokens[index + 1]?.kind === "identifier" || tokens[index + 1]?.kind === "keyword") && tokens[index + 2]?.text === "(") {
|
|
31442
31923
|
let depth = 0;
|
|
@@ -31470,13 +31951,15 @@ function constructionSiteAt(analysis, document, position) {
|
|
|
31470
31951
|
}
|
|
31471
31952
|
if (token.text === "{") {
|
|
31472
31953
|
if (sawNew || closedConstructorTypeName !== null) {
|
|
31473
|
-
|
|
31954
|
+
const frame2 = {
|
|
31474
31955
|
kind: "object",
|
|
31475
31956
|
typeName: pendingNewTypeName ?? closedConstructorTypeName,
|
|
31476
31957
|
slotType: null,
|
|
31477
31958
|
keys: [],
|
|
31478
31959
|
atKey: true
|
|
31479
|
-
}
|
|
31960
|
+
};
|
|
31961
|
+
stack.push(frame2);
|
|
31962
|
+
objects.push(frame2);
|
|
31480
31963
|
sawNew = false;
|
|
31481
31964
|
pendingNewTypeName = null;
|
|
31482
31965
|
} else {
|
|
@@ -31519,12 +32002,12 @@ function constructionSiteAt(analysis, document, position) {
|
|
|
31519
32002
|
continue;
|
|
31520
32003
|
}
|
|
31521
32004
|
if (token.text === ")") {
|
|
31522
|
-
const frame2 =
|
|
32005
|
+
const frame2 = pop();
|
|
31523
32006
|
closedConstructorTypeName = frame2?.kind === "call" ? frame2.typeName : null;
|
|
31524
32007
|
continue;
|
|
31525
32008
|
}
|
|
31526
32009
|
if (token.text === "}" || token.text === "]") {
|
|
31527
|
-
|
|
32010
|
+
pop();
|
|
31528
32011
|
closedConstructorTypeName = null;
|
|
31529
32012
|
continue;
|
|
31530
32013
|
}
|
|
@@ -31555,19 +32038,8 @@ function constructionSiteAt(analysis, document, position) {
|
|
|
31555
32038
|
}
|
|
31556
32039
|
}
|
|
31557
32040
|
}
|
|
31558
|
-
|
|
31559
|
-
|
|
31560
|
-
);
|
|
31561
|
-
const innermost = stack.at(-1);
|
|
31562
|
-
const directly = innermost?.kind === "object" ? innermost : null;
|
|
31563
|
-
return {
|
|
31564
|
-
expectedType: expectedType(),
|
|
31565
|
-
expectedTypeName: expectedType()?.name ?? null,
|
|
31566
|
-
enclosingTypeName: enclosing?.typeName ?? null,
|
|
31567
|
-
initializerTypeName: directly?.typeName ?? null,
|
|
31568
|
-
initializerKeys: directly?.keys ?? [],
|
|
31569
|
-
atInitializerKey: directly?.atKey ?? false
|
|
31570
|
-
};
|
|
32041
|
+
sites.push({ position: previousPosition, site: snapshot() });
|
|
32042
|
+
return sites;
|
|
31571
32043
|
}
|
|
31572
32044
|
function collectionElementType(type) {
|
|
31573
32045
|
if (!type) return null;
|
|
@@ -31582,13 +32054,31 @@ function constructorArgumentType(analysis, frame) {
|
|
|
31582
32054
|
if (!declaration || declaration.kind === "global" || declaration.kind === "enum") {
|
|
31583
32055
|
return null;
|
|
31584
32056
|
}
|
|
31585
|
-
const fields = declaration
|
|
31586
|
-
(member) => member.kind === "field" && !member.modifiers.includes("static") && !member.modifiers.includes("readonly")
|
|
31587
|
-
);
|
|
32057
|
+
const fields = declarationFields(declaration);
|
|
31588
32058
|
if (frame.argumentName !== null) {
|
|
31589
|
-
return fields.
|
|
32059
|
+
return fields.assignableByName.get(frame.argumentName)?.type ?? null;
|
|
31590
32060
|
}
|
|
31591
|
-
return fields[frame.argumentIndex]?.type ?? null;
|
|
32061
|
+
return fields.assignable[frame.argumentIndex]?.type ?? null;
|
|
32062
|
+
}
|
|
32063
|
+
function declarationFields(declaration) {
|
|
32064
|
+
let fields = DECLARATION_FIELDS.get(declaration);
|
|
32065
|
+
if (!fields) {
|
|
32066
|
+
const byName = /* @__PURE__ */ new Map();
|
|
32067
|
+
const assignable = [];
|
|
32068
|
+
const assignableByName = /* @__PURE__ */ new Map();
|
|
32069
|
+
for (const member of declaration.members) {
|
|
32070
|
+
if (member.kind !== "field") continue;
|
|
32071
|
+
if (!byName.has(member.name)) byName.set(member.name, member);
|
|
32072
|
+
if (member.modifiers.includes("static") || member.modifiers.includes("readonly"))
|
|
32073
|
+
continue;
|
|
32074
|
+
assignable.push(member);
|
|
32075
|
+
if (!assignableByName.has(member.name))
|
|
32076
|
+
assignableByName.set(member.name, member);
|
|
32077
|
+
}
|
|
32078
|
+
fields = { byName, assignable, assignableByName };
|
|
32079
|
+
DECLARATION_FIELDS.set(declaration, fields);
|
|
32080
|
+
}
|
|
32081
|
+
return fields;
|
|
31592
32082
|
}
|
|
31593
32083
|
function declaredFieldType(analysis, typeName, fieldName) {
|
|
31594
32084
|
let current = typeName;
|
|
@@ -31599,9 +32089,7 @@ function declaredFieldType(analysis, typeName, fieldName) {
|
|
|
31599
32089
|
if (!declaration || declaration.kind === "global" || declaration.kind === "enum") {
|
|
31600
32090
|
return null;
|
|
31601
32091
|
}
|
|
31602
|
-
const member = declaration.
|
|
31603
|
-
(candidate) => candidate.kind === "field" && candidate.name === fieldName
|
|
31604
|
-
);
|
|
32092
|
+
const member = declarationFields(declaration).byName.get(fieldName);
|
|
31605
32093
|
if (member) return member.type;
|
|
31606
32094
|
current = declaration.kind === "class" ? resolvableBaseClassName(analysis, declaration) : null;
|
|
31607
32095
|
}
|
|
@@ -31615,13 +32103,19 @@ function resolvableBaseClassName(analysis, declaration) {
|
|
|
31615
32103
|
return null;
|
|
31616
32104
|
}
|
|
31617
32105
|
function findTypeDeclaration(analysis, name) {
|
|
31618
|
-
|
|
31619
|
-
|
|
31620
|
-
|
|
31621
|
-
)
|
|
31622
|
-
|
|
32106
|
+
let declarations = PROJECT_TYPE_DECLARATIONS.get(analysis);
|
|
32107
|
+
if (!declarations) {
|
|
32108
|
+
declarations = /* @__PURE__ */ new Map();
|
|
32109
|
+
for (const document of analysis.documents.values()) {
|
|
32110
|
+
for (const declaration of document.declarations) {
|
|
32111
|
+
if (declaration.kind !== "global" && !declarations.has(declaration.name)) {
|
|
32112
|
+
declarations.set(declaration.name, declaration);
|
|
32113
|
+
}
|
|
32114
|
+
}
|
|
32115
|
+
}
|
|
32116
|
+
PROJECT_TYPE_DECLARATIONS.set(analysis, declarations);
|
|
31623
32117
|
}
|
|
31624
|
-
return
|
|
32118
|
+
return declarations.get(name);
|
|
31625
32119
|
}
|
|
31626
32120
|
function constructorParameterLabel(parameter4) {
|
|
31627
32121
|
return `${parameter4.type} ${parameter4.name}${parameterDefaultSuffix2(parameter4)}`;
|
|
@@ -31738,21 +32232,27 @@ function graphConstructorParameters(typeName) {
|
|
|
31738
32232
|
}
|
|
31739
32233
|
}
|
|
31740
32234
|
function projectFunctionsNamed(analysis, name) {
|
|
31741
|
-
|
|
31742
|
-
|
|
31743
|
-
|
|
31744
|
-
|
|
31745
|
-
|
|
31746
|
-
|
|
31747
|
-
|
|
31748
|
-
|
|
32235
|
+
let byName = PROJECT_FUNCTIONS.get(analysis);
|
|
32236
|
+
if (!byName) {
|
|
32237
|
+
byName = /* @__PURE__ */ new Map();
|
|
32238
|
+
for (const document of analysis.documents.values()) {
|
|
32239
|
+
for (const declaration of document.declarations) {
|
|
32240
|
+
if (declaration.kind === "global" || declaration.kind === "enum")
|
|
32241
|
+
continue;
|
|
32242
|
+
for (const member of declaration.members) {
|
|
32243
|
+
if (member.kind !== "function") continue;
|
|
32244
|
+
const entry = { owner: declaration.name, member };
|
|
32245
|
+
const named = byName.get(member.name);
|
|
32246
|
+
if (named) named.push(entry);
|
|
32247
|
+
else byName.set(member.name, [entry]);
|
|
31749
32248
|
}
|
|
31750
32249
|
}
|
|
31751
32250
|
}
|
|
32251
|
+
PROJECT_FUNCTIONS.set(analysis, byName);
|
|
31752
32252
|
}
|
|
31753
|
-
return
|
|
32253
|
+
return byName.get(name) ?? [];
|
|
31754
32254
|
}
|
|
31755
|
-
var PROJECT_BODY_SNAPSHOT_CACHE, CONSTRUCTION_INDEX_CACHE, VARIANT_SCOPE_INDEX_CACHE;
|
|
32255
|
+
var PROJECT_BODIES, PROJECT_BODY_INDEX_CACHE, PROJECT_BODY_SNAPSHOT_CACHE, SOURCE_TYPES, CONSTRUCTION_INDEX_CACHE, VARIANT_SCOPE_INDEX_CACHE, PROJECT_SYMBOL_INDEX_CACHE, INITIALIZER_ROOTS, CONSTRUCTION_SITE_CACHE, DECLARATION_FIELDS, PROJECT_TYPE_DECLARATIONS, PROJECT_FUNCTIONS;
|
|
31756
32256
|
var init_project_source_language_features = __esm({
|
|
31757
32257
|
"../packages/neoscript-language/src/project-source-language-features.ts"() {
|
|
31758
32258
|
"use strict";
|
|
@@ -31766,11 +32266,19 @@ var init_project_source_language_features = __esm({
|
|
|
31766
32266
|
init_project_source_settlement();
|
|
31767
32267
|
init_project_source_tokens();
|
|
31768
32268
|
init_quick_fixes();
|
|
31769
|
-
init_source_text();
|
|
31770
32269
|
init_syntax();
|
|
32270
|
+
PROJECT_BODIES = /* @__PURE__ */ new WeakMap();
|
|
32271
|
+
PROJECT_BODY_INDEX_CACHE = /* @__PURE__ */ new WeakMap();
|
|
31771
32272
|
PROJECT_BODY_SNAPSHOT_CACHE = /* @__PURE__ */ new WeakMap();
|
|
32273
|
+
SOURCE_TYPES = /* @__PURE__ */ new WeakMap();
|
|
31772
32274
|
CONSTRUCTION_INDEX_CACHE = /* @__PURE__ */ new WeakMap();
|
|
31773
32275
|
VARIANT_SCOPE_INDEX_CACHE = /* @__PURE__ */ new WeakMap();
|
|
32276
|
+
PROJECT_SYMBOL_INDEX_CACHE = /* @__PURE__ */ new WeakMap();
|
|
32277
|
+
INITIALIZER_ROOTS = /* @__PURE__ */ new WeakMap();
|
|
32278
|
+
CONSTRUCTION_SITE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
32279
|
+
DECLARATION_FIELDS = /* @__PURE__ */ new WeakMap();
|
|
32280
|
+
PROJECT_TYPE_DECLARATIONS = /* @__PURE__ */ new WeakMap();
|
|
32281
|
+
PROJECT_FUNCTIONS = /* @__PURE__ */ new WeakMap();
|
|
31774
32282
|
}
|
|
31775
32283
|
});
|
|
31776
32284
|
|
|
@@ -34977,6 +35485,57 @@ var init_project_local_value_refactorings = __esm({
|
|
|
34977
35485
|
}
|
|
34978
35486
|
});
|
|
34979
35487
|
|
|
35488
|
+
// ../packages/neoscript-language/src/project-source-reference-family.ts
|
|
35489
|
+
function projectReferenceFamily(analysis, target, index = buildProjectSymbolIndex(analysis.symbols)) {
|
|
35490
|
+
const named = index.byName.get(target.name) ?? [];
|
|
35491
|
+
if (target.kind === "class" || target.kind === "constructor") {
|
|
35492
|
+
const owner = target.kind === "class" ? target.name : target.ownerName;
|
|
35493
|
+
return named.filter(
|
|
35494
|
+
(symbol) => symbol.kind === "class" ? symbol.name === owner : symbol.kind === "constructor" && symbol.ownerName === owner
|
|
35495
|
+
);
|
|
35496
|
+
}
|
|
35497
|
+
if (target.kind !== "member" || !target.ownerName) return [target];
|
|
35498
|
+
const symbols = new Map(
|
|
35499
|
+
named.filter((symbol) => symbol.kind === "member").map((symbol) => [symbol.ownerName, symbol])
|
|
35500
|
+
);
|
|
35501
|
+
const classes = /* @__PURE__ */ new Map();
|
|
35502
|
+
for (const document of analysis.documents.values()) {
|
|
35503
|
+
for (const declaration of document.declarations) {
|
|
35504
|
+
if (declaration.kind === "class")
|
|
35505
|
+
classes.set(declaration.name, declaration);
|
|
35506
|
+
}
|
|
35507
|
+
}
|
|
35508
|
+
const roots = /* @__PURE__ */ new Map();
|
|
35509
|
+
const root = (name) => {
|
|
35510
|
+
if (roots.has(name)) return roots.get(name);
|
|
35511
|
+
roots.set(name, null);
|
|
35512
|
+
const declaration = classes.get(name);
|
|
35513
|
+
const own = symbols.get(name);
|
|
35514
|
+
const member = declaration?.members.find(
|
|
35515
|
+
(candidate) => candidate.name === target.name
|
|
35516
|
+
);
|
|
35517
|
+
if (own && !member?.modifiers.includes("override")) {
|
|
35518
|
+
roots.set(name, own);
|
|
35519
|
+
return own;
|
|
35520
|
+
}
|
|
35521
|
+
const base = declaration?.baseTypes.find((type) => classes.has(type.name));
|
|
35522
|
+
const resolved = (base ? root(base.name) : null) ?? own ?? null;
|
|
35523
|
+
roots.set(name, resolved);
|
|
35524
|
+
return resolved;
|
|
35525
|
+
};
|
|
35526
|
+
const selected = root(target.ownerName);
|
|
35527
|
+
if (!selected) return [target];
|
|
35528
|
+
return [...symbols.values()].filter(
|
|
35529
|
+
(symbol) => symbol.ownerName && root(symbol.ownerName) === selected
|
|
35530
|
+
);
|
|
35531
|
+
}
|
|
35532
|
+
var init_project_source_reference_family = __esm({
|
|
35533
|
+
"../packages/neoscript-language/src/project-source-reference-family.ts"() {
|
|
35534
|
+
"use strict";
|
|
35535
|
+
init_project_source_language_features();
|
|
35536
|
+
}
|
|
35537
|
+
});
|
|
35538
|
+
|
|
34980
35539
|
// ../packages/neoscript-language/src/spelling-diagnostics.ts
|
|
34981
35540
|
function enhanceSpellingDiagnostics(document, diagnostics, completionAt) {
|
|
34982
35541
|
return diagnostics.map((diagnostic) => {
|
|
@@ -35126,8 +35685,8 @@ var init_spelling_diagnostics = __esm({
|
|
|
35126
35685
|
});
|
|
35127
35686
|
|
|
35128
35687
|
// ../packages/neoscript-language/src/service.ts
|
|
35129
|
-
function createNeoScriptLanguageService() {
|
|
35130
|
-
return new LanguageService();
|
|
35688
|
+
function createNeoScriptLanguageService(options = {}) {
|
|
35689
|
+
return new LanguageService(options);
|
|
35131
35690
|
}
|
|
35132
35691
|
function isProjectDocument(document, context) {
|
|
35133
35692
|
return context?.projectSourceKind !== "spec" && (document.languageId === "neo" || document.languageId === "neoflow");
|
|
@@ -35208,6 +35767,16 @@ function sameLocationInList(target, locations) {
|
|
|
35208
35767
|
(location3) => location3.uri === target.uri && location3.range.start.line === target.range.start.line && location3.range.start.character === target.range.start.character
|
|
35209
35768
|
);
|
|
35210
35769
|
}
|
|
35770
|
+
function locationKey(location3) {
|
|
35771
|
+
const { start, end } = location3.range;
|
|
35772
|
+
return JSON.stringify([
|
|
35773
|
+
location3.uri,
|
|
35774
|
+
start.line,
|
|
35775
|
+
start.character,
|
|
35776
|
+
end.line,
|
|
35777
|
+
end.character
|
|
35778
|
+
]);
|
|
35779
|
+
}
|
|
35211
35780
|
var LanguageService;
|
|
35212
35781
|
var init_service = __esm({
|
|
35213
35782
|
"../packages/neoscript-language/src/service.ts"() {
|
|
@@ -35220,6 +35789,7 @@ var init_service = __esm({
|
|
|
35220
35789
|
init_project_source_identifiers();
|
|
35221
35790
|
init_project_source_analysis();
|
|
35222
35791
|
init_project_source_construction_quick_fixes();
|
|
35792
|
+
init_project_source_reference_family();
|
|
35223
35793
|
init_project_source_language_features();
|
|
35224
35794
|
init_project_source_tokens();
|
|
35225
35795
|
init_quick_fixes();
|
|
@@ -35227,6 +35797,11 @@ var init_service = __esm({
|
|
|
35227
35797
|
init_syntax();
|
|
35228
35798
|
init_test_prelude();
|
|
35229
35799
|
LanguageService = class {
|
|
35800
|
+
constructor(options) {
|
|
35801
|
+
this.options = options;
|
|
35802
|
+
}
|
|
35803
|
+
options;
|
|
35804
|
+
cachedSourceValidation;
|
|
35230
35805
|
documents = /* @__PURE__ */ new Map();
|
|
35231
35806
|
specSnapshots = /* @__PURE__ */ new Set();
|
|
35232
35807
|
projectGeneration = 0;
|
|
@@ -35342,10 +35917,18 @@ var init_service = __esm({
|
|
|
35342
35917
|
if (signal?.aborted) return [];
|
|
35343
35918
|
const generation = ++state.validationGeneration;
|
|
35344
35919
|
if (isProjectDocument(state.document, state.context)) {
|
|
35345
|
-
const
|
|
35346
|
-
|
|
35347
|
-
|
|
35348
|
-
);
|
|
35920
|
+
const projectGeneration = this.projectGeneration;
|
|
35921
|
+
const project = this.projectAnalysis();
|
|
35922
|
+
const extended = await this.validateProjectSources();
|
|
35923
|
+
if (projectGeneration !== this.projectGeneration) return [];
|
|
35924
|
+
const diagnostics = this.enhanceDiagnostics(state, [
|
|
35925
|
+
...projectDiagnostics(project, uri),
|
|
35926
|
+
...extended.filter(
|
|
35927
|
+
(diagnostic) => diagnostic.uri === uri && !project.diagnostics.some(
|
|
35928
|
+
(existing) => existing.uri === uri && existing.code === diagnostic.code && existing.message === diagnostic.message && existing.range.start.line === diagnostic.range.start.line && existing.range.start.character === diagnostic.range.start.character
|
|
35929
|
+
)
|
|
35930
|
+
)
|
|
35931
|
+
]);
|
|
35349
35932
|
if (signal?.aborted) return [];
|
|
35350
35933
|
const current2 = this.documents.get(uri);
|
|
35351
35934
|
if (!current2 || current2.validationGeneration !== generation) return [];
|
|
@@ -35402,6 +35985,16 @@ var init_service = __esm({
|
|
|
35402
35985
|
if (!reference2) return [];
|
|
35403
35986
|
const symbolId = resolveReferenceSymbolId(source, reference2);
|
|
35404
35987
|
if (!symbolId) return [];
|
|
35988
|
+
for (const location3 of definition(source, position)) {
|
|
35989
|
+
const owner = this.documents.get(location3.uri);
|
|
35990
|
+
if (owner && isProjectDocument(owner.document, owner.context)) {
|
|
35991
|
+
return this.projectReferences(
|
|
35992
|
+
owner.document,
|
|
35993
|
+
location3.range.start,
|
|
35994
|
+
includeDeclaration
|
|
35995
|
+
);
|
|
35996
|
+
}
|
|
35997
|
+
}
|
|
35405
35998
|
const locations = [];
|
|
35406
35999
|
for (const other of this.documents.values()) {
|
|
35407
36000
|
if (isProjectDocument(other.document, other.context)) continue;
|
|
@@ -35455,8 +36048,10 @@ var init_service = __esm({
|
|
|
35455
36048
|
);
|
|
35456
36049
|
if (!resolved) return null;
|
|
35457
36050
|
const memberLabel2 = resolved.symbol.kind === "member" || resolved.symbol.kind === "enumOption" || resolved.symbol.kind === "graphChild";
|
|
35458
|
-
const binding = resolved.symbol.kind === "parameter" || resolved.symbol.kind === "genericParameter" || resolved.symbol.kind === "flowBinding";
|
|
35459
|
-
|
|
36051
|
+
const binding = resolved.symbol.kind === "local" || resolved.symbol.kind === "parameter" || resolved.symbol.kind === "genericParameter" || resolved.symbol.kind === "flowBinding";
|
|
36052
|
+
let validNeoName = memberLabel2 ? isValidNeoProjectMemberIdentifier(newName) : binding ? isValidNeoProjectBindingIdentifier(newName) : isValidNeoProjectIdentifier(newName);
|
|
36053
|
+
if (resolved.symbol.kind === "local")
|
|
36054
|
+
validNeoName = isValidNeoScriptBindingIdentifier(newName);
|
|
35460
36055
|
validName = validNeoName && isGeneratedCSharpIdentifier(newName) && !isGeneratedCSharpReservedKeyword(newName);
|
|
35461
36056
|
} else {
|
|
35462
36057
|
validName = isValidNeoScriptBindingIdentifier(newName);
|
|
@@ -35536,6 +36131,31 @@ var init_service = __esm({
|
|
|
35536
36131
|
)
|
|
35537
36132
|
);
|
|
35538
36133
|
}
|
|
36134
|
+
validateProjectSources() {
|
|
36135
|
+
const validate3 = this.options.validateProjectSources;
|
|
36136
|
+
if (validate3 === void 0) return Promise.resolve([]);
|
|
36137
|
+
if (this.cachedSourceValidation?.generation === this.projectGeneration)
|
|
36138
|
+
return this.cachedSourceValidation.result;
|
|
36139
|
+
const inputs = [...this.documents.values()].flatMap(
|
|
36140
|
+
({ document, context }) => isProjectDocument(document, context) ? [
|
|
36141
|
+
{
|
|
36142
|
+
uri: document.uri,
|
|
36143
|
+
text: document.text,
|
|
36144
|
+
kind: document.languageId === "neoflow" ? "flow" : context.kind === "migration" ? "migration" : "definition"
|
|
36145
|
+
}
|
|
36146
|
+
] : []
|
|
36147
|
+
);
|
|
36148
|
+
const result = validate3(inputs).catch((error) => {
|
|
36149
|
+
if (this.cachedSourceValidation?.result === result)
|
|
36150
|
+
this.cachedSourceValidation = void 0;
|
|
36151
|
+
throw error;
|
|
36152
|
+
});
|
|
36153
|
+
this.cachedSourceValidation = {
|
|
36154
|
+
generation: this.projectGeneration,
|
|
36155
|
+
result
|
|
36156
|
+
};
|
|
36157
|
+
return result;
|
|
36158
|
+
}
|
|
35539
36159
|
projectAnalysis() {
|
|
35540
36160
|
if (this.cachedProjectAnalysis?.generation === this.projectGeneration) {
|
|
35541
36161
|
return this.cachedProjectAnalysis.analysis;
|
|
@@ -35565,12 +36185,22 @@ var init_service = __esm({
|
|
|
35565
36185
|
const token = projectTokenAt(document, position);
|
|
35566
36186
|
if (!isProjectNameToken(token)) return [];
|
|
35567
36187
|
const analysis = this.projectAnalysis();
|
|
35568
|
-
const
|
|
36188
|
+
const index = buildProjectSymbolIndex(analysis.symbols);
|
|
36189
|
+
const resolved = projectSymbolAt(analysis, document, position, index);
|
|
35569
36190
|
if (!resolved) return [];
|
|
35570
36191
|
const declaration = resolved.symbol;
|
|
36192
|
+
const family = projectReferenceFamily(analysis, declaration, index);
|
|
36193
|
+
const familyLocations = new Set(
|
|
36194
|
+
family.map((member) => locationKey(member.location))
|
|
36195
|
+
);
|
|
36196
|
+
const familyIds = new Set(
|
|
36197
|
+
family.flatMap((member) => member.id === null ? [] : [member.id])
|
|
36198
|
+
);
|
|
35571
36199
|
const locations = [];
|
|
35572
36200
|
for (const state of this.documents.values()) {
|
|
35573
36201
|
if (!isProjectDocument(state.document, state.context)) continue;
|
|
36202
|
+
if (declaration.kind === "local" && state.document.uri !== document.uri)
|
|
36203
|
+
continue;
|
|
35574
36204
|
for (const candidate of projectTokens(state.document)) {
|
|
35575
36205
|
if (!isProjectNameToken(candidate) || candidate.text !== token.text) {
|
|
35576
36206
|
continue;
|
|
@@ -35578,28 +36208,29 @@ var init_service = __esm({
|
|
|
35578
36208
|
const candidateSymbol = projectSymbolAt(
|
|
35579
36209
|
analysis,
|
|
35580
36210
|
state.document,
|
|
35581
|
-
candidate.range.start
|
|
36211
|
+
candidate.range.start,
|
|
36212
|
+
index
|
|
35582
36213
|
)?.symbol;
|
|
35583
|
-
if (!candidateSymbol || !
|
|
36214
|
+
if (!candidateSymbol || !familyLocations.has(locationKey(candidateSymbol.location))) {
|
|
35584
36215
|
continue;
|
|
35585
36216
|
}
|
|
35586
36217
|
const location3 = { uri: state.document.uri, range: candidate.range };
|
|
35587
|
-
if (!includeDeclaration &&
|
|
36218
|
+
if (!includeDeclaration && familyLocations.has(locationKey(location3))) {
|
|
35588
36219
|
continue;
|
|
35589
36220
|
}
|
|
35590
36221
|
locations.push(location3);
|
|
35591
36222
|
}
|
|
35592
36223
|
}
|
|
35593
36224
|
for (const state of this.documents.values()) {
|
|
35594
|
-
if (
|
|
36225
|
+
if (declaration.kind === "local") break;
|
|
36226
|
+
if (isProjectDocument(state.document, state.context)) continue;
|
|
35595
36227
|
const snapshot = this.scriptSnapshot(state);
|
|
35596
36228
|
for (const candidate of snapshot.parsed.references) {
|
|
35597
36229
|
if (candidate.name !== declaration.name) continue;
|
|
35598
36230
|
const symbolId = resolveReferenceSymbolId(snapshot, candidate);
|
|
35599
36231
|
if (symbolId === null) continue;
|
|
35600
|
-
const matches =
|
|
35601
|
-
|
|
35602
|
-
definition(snapshot, candidate.range.start)
|
|
36232
|
+
const matches = familyIds.has(symbolId) || definition(snapshot, candidate.range.start).some(
|
|
36233
|
+
(location3) => familyLocations.has(locationKey(location3))
|
|
35603
36234
|
);
|
|
35604
36235
|
if (!matches) continue;
|
|
35605
36236
|
locations.push({ uri: state.document.uri, range: candidate.range });
|
|
@@ -35911,6 +36542,7 @@ var init_src = __esm({
|
|
|
35911
36542
|
init_project_local_value_refactorings();
|
|
35912
36543
|
init_cell_pattern();
|
|
35913
36544
|
init_tile_conversion();
|
|
36545
|
+
init_reference_argument();
|
|
35914
36546
|
}
|
|
35915
36547
|
});
|
|
35916
36548
|
|
|
@@ -38043,8 +38675,9 @@ var init_source_diagnostics = __esm({
|
|
|
38043
38675
|
"neoflow-incomplete-draft"
|
|
38044
38676
|
]);
|
|
38045
38677
|
SchemaSourceError = class extends Error {
|
|
38046
|
-
constructor(
|
|
38047
|
-
super(`${file}:${line}:${column} \u2014 ${
|
|
38678
|
+
constructor(detail, file, line, column, code, severity = "error") {
|
|
38679
|
+
super(`${file}:${line}:${column} \u2014 ${detail}`);
|
|
38680
|
+
this.detail = detail;
|
|
38048
38681
|
this.file = file;
|
|
38049
38682
|
this.line = line;
|
|
38050
38683
|
this.column = column;
|
|
@@ -38052,6 +38685,7 @@ var init_source_diagnostics = __esm({
|
|
|
38052
38685
|
this.severity = severity;
|
|
38053
38686
|
this.name = "SchemaSourceError";
|
|
38054
38687
|
}
|
|
38688
|
+
detail;
|
|
38055
38689
|
file;
|
|
38056
38690
|
line;
|
|
38057
38691
|
column;
|
|
@@ -50359,6 +50993,41 @@ var init_interface_graph = __esm({
|
|
|
50359
50993
|
});
|
|
50360
50994
|
|
|
50361
50995
|
// ../src/models/neoscript/type-info-compatibility.ts
|
|
50996
|
+
function isTypeInfoAssignable(from, to, context) {
|
|
50997
|
+
if (to.type === NS_TYPE_UNKNOWN) return true;
|
|
50998
|
+
if (from.type === NS_TYPE_UNKNOWN) return false;
|
|
50999
|
+
if (from.required === false && to.required === true) return false;
|
|
51000
|
+
if (from.type === 0 /* Null */) return to.required === false;
|
|
51001
|
+
if (from.type === 2 /* Int */ && to.type === 4 /* Float */) {
|
|
51002
|
+
return true;
|
|
51003
|
+
}
|
|
51004
|
+
if (from.type === 7 /* Class */ && to.type === 7 /* Class */) {
|
|
51005
|
+
if (from.classId === to.classId) {
|
|
51006
|
+
return typeInfosInvariantlyEqual({ ...from, required: to.required }, to);
|
|
51007
|
+
}
|
|
51008
|
+
return resolveInheritanceChain(from.classId, context.classes).some(
|
|
51009
|
+
(schemaClass2) => schemaClass2.id === to.classId
|
|
51010
|
+
);
|
|
51011
|
+
}
|
|
51012
|
+
if (from.type === 7 /* Class */ && to.type === 22 /* Interface */) {
|
|
51013
|
+
return classImplementsInterface(
|
|
51014
|
+
from.classId,
|
|
51015
|
+
to.interfaceId,
|
|
51016
|
+
context.classes,
|
|
51017
|
+
context.interfaces
|
|
51018
|
+
);
|
|
51019
|
+
}
|
|
51020
|
+
if (from.type === 22 /* Interface */ && to.type === 22 /* Interface */) {
|
|
51021
|
+
return resolveInterfaceClosure(from.interfaceId, context.interfaces).some(
|
|
51022
|
+
(neoInterface) => neoInterface.id === to.interfaceId
|
|
51023
|
+
);
|
|
51024
|
+
}
|
|
51025
|
+
if (from.type === 22 /* Interface */ || to.type === 22 /* Interface */) {
|
|
51026
|
+
return false;
|
|
51027
|
+
}
|
|
51028
|
+
const normalizedFrom = { ...from, required: to.required };
|
|
51029
|
+
return typeInfosInvariantlyEqual(normalizedFrom, to);
|
|
51030
|
+
}
|
|
50362
51031
|
var init_type_info_compatibility = __esm({
|
|
50363
51032
|
"../src/models/neoscript/type-info-compatibility.ts"() {
|
|
50364
51033
|
"use strict";
|
|
@@ -61758,13 +62427,23 @@ function lowerClass(context, declaration) {
|
|
|
61758
62427
|
...placement
|
|
61759
62428
|
});
|
|
61760
62429
|
} catch (error) {
|
|
61761
|
-
|
|
61762
|
-
throw new SchemaSourceError(
|
|
62430
|
+
const positioned = error instanceof SchemaSourceError ? error : new SchemaSourceError(
|
|
61763
62431
|
error instanceof Error ? error.message : String(error),
|
|
61764
62432
|
memberDeclaration.source.uri,
|
|
61765
62433
|
memberDeclaration.source.range.start.line + 1,
|
|
61766
62434
|
memberDeclaration.source.range.start.character + 1
|
|
61767
62435
|
);
|
|
62436
|
+
if (context.onDeclarationError === void 0) throw positioned;
|
|
62437
|
+
context.onDeclarationError(positioned, memberDeclaration);
|
|
62438
|
+
const previous = context.baseMembers.get(memberId);
|
|
62439
|
+
if (previous !== void 0)
|
|
62440
|
+
context.loweredMembers.set(memberId, previous);
|
|
62441
|
+
else {
|
|
62442
|
+
delete schema[memberDeclaration.name];
|
|
62443
|
+
schemaKeyOrder.pop();
|
|
62444
|
+
placements.pop();
|
|
62445
|
+
}
|
|
62446
|
+
continue;
|
|
61768
62447
|
}
|
|
61769
62448
|
const existing = context.loweredMembers.get(memberId);
|
|
61770
62449
|
if (existing && !sameSharedMember(existing, lowered)) {
|
|
@@ -62136,7 +62815,8 @@ function lowerFieldMember(context, ownerClass, declaration, id2, commonInput, ba
|
|
|
62136
62815
|
base,
|
|
62137
62816
|
id2,
|
|
62138
62817
|
storesSelectionArray,
|
|
62139
|
-
`${ownerClass.name}.${declaration.name}
|
|
62818
|
+
`${ownerClass.name}.${declaration.name}`,
|
|
62819
|
+
!declaration.modifiers.includes("static") && contextualEnumArgument(settings, "kind") === "Unordered"
|
|
62140
62820
|
)
|
|
62141
62821
|
};
|
|
62142
62822
|
const name = fieldType.name;
|
|
@@ -62812,7 +63492,9 @@ function lowerInterface(context, declaration) {
|
|
|
62812
63492
|
name: member.name,
|
|
62813
63493
|
...member.docsText === void 0 ? {} : { docsText: member.docsText },
|
|
62814
63494
|
type: lowerType(context, member.type),
|
|
62815
|
-
settable:
|
|
63495
|
+
settable: projectSourceAccessors(member.body ?? "").some(
|
|
63496
|
+
(accessor) => accessor.keyword === "set"
|
|
63497
|
+
),
|
|
62816
63498
|
accessModifier,
|
|
62817
63499
|
source
|
|
62818
63500
|
};
|
|
@@ -62995,12 +63677,12 @@ function lowerType(context, type, ownerClass) {
|
|
|
62995
63677
|
if (type.name === "object") return { kind: "unknown", nullable: nullable2 };
|
|
62996
63678
|
throw new Error(`Unknown Neo type ${JSON.stringify(type.name)}.`);
|
|
62997
63679
|
}
|
|
62998
|
-
function lowerDefault(context, initializer, type, ownerClass, base, memberId, storesSelectionArray, path) {
|
|
63680
|
+
function lowerDefault(context, initializer, type, ownerClass, base, memberId, storesSelectionArray, path, unorderedList = false) {
|
|
62999
63681
|
if (initializer === null) {
|
|
63000
63682
|
return base?.defaultValue && "serverValueId" in base.defaultValue ? base.defaultValue : null;
|
|
63001
63683
|
}
|
|
63002
63684
|
const expression = parseExpression(initializer);
|
|
63003
|
-
if (positionRequiresEvaluation(context, expression, type, ownerClass)) {
|
|
63685
|
+
if (unorderedList && expression.kind === "litList" && expression.elements.length > 0 || positionRequiresEvaluation(context, expression, type, ownerClass)) {
|
|
63004
63686
|
return {
|
|
63005
63687
|
init: {
|
|
63006
63688
|
code: context.settleInitializerReferences(
|
|
@@ -64152,7 +64834,15 @@ function storageChainStep(context, memberId) {
|
|
|
64152
64834
|
}
|
|
64153
64835
|
function referenceIdArgument(value, name) {
|
|
64154
64836
|
const raw = argument(value, name);
|
|
64155
|
-
|
|
64837
|
+
if (raw === null) return null;
|
|
64838
|
+
const parsed = parseReferenceArgument(raw);
|
|
64839
|
+
if (parsed?.kind === "none") return null;
|
|
64840
|
+
if (parsed?.kind === "id") return parsed.value;
|
|
64841
|
+
if (parsed?.kind === "rootPath" && name === "collectionValue")
|
|
64842
|
+
return `${PENDING_ID_PREFIX}root-path:${parsed.value}`;
|
|
64843
|
+
if (name === "template" && parseAnnotationExpression(raw).kind === "ident")
|
|
64844
|
+
return null;
|
|
64845
|
+
throw new Error(referenceArgumentRequirement(name));
|
|
64156
64846
|
}
|
|
64157
64847
|
function templateSymbolArgument(context, settings, ownerClass, declaration) {
|
|
64158
64848
|
const raw = argument(settings, "template");
|
|
@@ -64168,32 +64858,9 @@ function templateSymbolArgument(context, settings, ownerClass, declaration) {
|
|
|
64168
64858
|
return templateId;
|
|
64169
64859
|
}
|
|
64170
64860
|
function referenceId(raw) {
|
|
64171
|
-
|
|
64172
|
-
|
|
64173
|
-
|
|
64174
|
-
if (expression.callee.kind !== "ident" || expression.callee.name !== "Reference") {
|
|
64175
|
-
return null;
|
|
64176
|
-
}
|
|
64177
|
-
const index = expression.argumentNames?.findIndex((entry) => entry === "id") ?? -1;
|
|
64178
|
-
const value = expression.args[index >= 0 ? index : 0];
|
|
64179
|
-
if (value?.kind === "litString") return value.value;
|
|
64180
|
-
const path = value === void 0 ? null : rootValuePath(value);
|
|
64181
|
-
return path === null ? null : `${PENDING_ID_PREFIX}root-path:${path}`;
|
|
64182
|
-
} catch {
|
|
64183
|
-
return null;
|
|
64184
|
-
}
|
|
64185
|
-
}
|
|
64186
|
-
function rootValuePath(expression) {
|
|
64187
|
-
const segments = [];
|
|
64188
|
-
let cursor = expression;
|
|
64189
|
-
while (cursor.kind === "member") {
|
|
64190
|
-
segments.unshift(cursor.name);
|
|
64191
|
-
cursor = cursor.receiver;
|
|
64192
|
-
}
|
|
64193
|
-
if (cursor.kind !== "ident") return null;
|
|
64194
|
-
if (cursor.name !== "root") return null;
|
|
64195
|
-
if (segments.length === 0) return null;
|
|
64196
|
-
return ["root", ...segments].join(".");
|
|
64861
|
+
const parsed = parseReferenceArgument(raw);
|
|
64862
|
+
if (parsed === null || parsed.kind === "none") return null;
|
|
64863
|
+
return parsed.kind === "id" ? parsed.value : `${PENDING_ID_PREFIX}root-path:${parsed.value}`;
|
|
64197
64864
|
}
|
|
64198
64865
|
function isImpliedSchemaKeyOrder(order) {
|
|
64199
64866
|
return order.every((key, index) => index === 0 || order[index - 1] <= key);
|
|
@@ -64214,7 +64881,8 @@ function propertyAccessors(body) {
|
|
|
64214
64881
|
const accessor = findProjectSourceAccessorBody(body, keyword);
|
|
64215
64882
|
if (accessor === null) return null;
|
|
64216
64883
|
const source = normalizeBodySource(accessor.source);
|
|
64217
|
-
if (accessor.form === "block")
|
|
64884
|
+
if (accessor.form === "block")
|
|
64885
|
+
return keyword === "set" && source.length === 0 ? "return;" : source;
|
|
64218
64886
|
return keyword === "get" ? `return ${source};` : `${source};`;
|
|
64219
64887
|
};
|
|
64220
64888
|
return {
|
|
@@ -111834,16 +112502,8 @@ function validateDocumentInheritanceFlags(ctx) {
|
|
|
111834
112502
|
const valueBearing = memberKindSupportsStorage(member.kind);
|
|
111835
112503
|
const valueId = getField(member, "valueId");
|
|
111836
112504
|
if (valueBearing) {
|
|
111837
|
-
if (
|
|
111838
|
-
errors.push(
|
|
111839
|
-
message: `Static member "${member.name}" (${member.id}) stores live content through valueId and cannot retain a schema defaultValue seed.`
|
|
111840
|
-
});
|
|
111841
|
-
}
|
|
111842
|
-
if (isRequiredMember2(member) && (typeof valueId !== "string" || valueId.length === 0)) {
|
|
111843
|
-
errors.push({
|
|
111844
|
-
message: `Required static member "${member.name}" (${member.id}) must have an authored value binding.`
|
|
111845
|
-
});
|
|
111846
|
-
}
|
|
112505
|
+
if (ctx.phase !== "schema")
|
|
112506
|
+
errors.push(...validateStaticMemberValueBinding(member));
|
|
111847
112507
|
} else if (member.storage != null || valueId != null || member.defaultValue != null) {
|
|
111848
112508
|
errors.push({
|
|
111849
112509
|
message: `Value-less static member "${member.name}" (${member.id}) cannot declare storage, valueId, or default content.`
|
|
@@ -111987,8 +112647,12 @@ function validateDocumentInheritanceFlags(ctx) {
|
|
|
111987
112647
|
)) {
|
|
111988
112648
|
continue;
|
|
111989
112649
|
}
|
|
112650
|
+
const declaringClass = classesById.get(
|
|
112651
|
+
inheritedMetadata.declarationClassId
|
|
112652
|
+
);
|
|
111990
112653
|
errors.push({
|
|
111991
|
-
|
|
112654
|
+
memberId,
|
|
112655
|
+
message: `Schema member "${schemaKey}" on class "${schemaClass2.name}" (${schemaClass2.id}) does not match the inherited generated signature from member "${generatedAncestorMember.name}" (${generatedAncestorMember.id}). ${schemaClass2.name}.${schemaKey} generates "${ctx.signatureProjector.format(localSignature)}" but ${declaringClass?.name ?? inheritedMetadata.memberId}.${schemaKey} declares "${ctx.signatureProjector.format(ancestorSignature)}". Abstract implementations and re-abstractions must preserve the generated member contract or have a supported codegen bridge.`
|
|
111992
112656
|
});
|
|
111993
112657
|
}
|
|
111994
112658
|
}
|
|
@@ -112066,6 +112730,23 @@ function nearestAncestorDeclaration2(schemaClass2, schemaKey, classesById) {
|
|
|
112066
112730
|
}
|
|
112067
112731
|
return null;
|
|
112068
112732
|
}
|
|
112733
|
+
function validateStaticMemberValueBinding(member) {
|
|
112734
|
+
if (!isStaticMember(member) || !memberKindSupportsStorage(member.kind))
|
|
112735
|
+
return [];
|
|
112736
|
+
const errors = [];
|
|
112737
|
+
if (member.defaultValue != null)
|
|
112738
|
+
errors.push({
|
|
112739
|
+
memberId: member.id,
|
|
112740
|
+
message: `Static member "${member.name}" (${member.id}) stores live content through valueId and cannot retain a schema defaultValue seed.`
|
|
112741
|
+
});
|
|
112742
|
+
const valueId = getField(member, "valueId");
|
|
112743
|
+
if (isRequiredMember2(member) && (typeof valueId !== "string" || valueId.length === 0))
|
|
112744
|
+
errors.push({
|
|
112745
|
+
memberId: member.id,
|
|
112746
|
+
message: `Required static member "${member.name}" (${member.id}) must have an authored value binding.`
|
|
112747
|
+
});
|
|
112748
|
+
return errors;
|
|
112749
|
+
}
|
|
112069
112750
|
var init_inheritance_flags_validation = __esm({
|
|
112070
112751
|
"../src/models/classes/inheritance-flags-validation.ts"() {
|
|
112071
112752
|
"use strict";
|
|
@@ -112176,6 +112857,7 @@ function createGenerationContext(exportData, diagnostics, docs = EMPTY_UNITY_COD
|
|
|
112176
112857
|
docs,
|
|
112177
112858
|
members: Object.values(exportData.members),
|
|
112178
112859
|
classes: Object.values(exportData.classes),
|
|
112860
|
+
interfaces: Object.values(exportData.interfaces),
|
|
112179
112861
|
diagnostics,
|
|
112180
112862
|
enumNames: buildEnumNameMap(Object.values(exportData.enums), diagnostics),
|
|
112181
112863
|
enumOptionFieldNames: /* @__PURE__ */ new Map(),
|
|
@@ -112411,29 +113093,35 @@ function emittedGeneratedMemberContract(ctx, ownerClassId, schemaKey, memberId,
|
|
|
112411
113093
|
valueType: narrowedMemberValueType(ctx, member, valueType, inherited),
|
|
112412
113094
|
hasSetter,
|
|
112413
113095
|
getOnlyContract: (inherited?.getOnlyContract ?? false) || isAbstractMember(member) === true && !hasSetter,
|
|
112414
|
-
|
|
113096
|
+
valueTypeInfo: generatedValueTypeInfo(ctx, member),
|
|
112415
113097
|
closesGenericType: (inherited?.closesGenericType ?? false) || lookupNarrowsThroughGenericParam(member) || isMemberGenericBase(member)
|
|
112416
113098
|
};
|
|
112417
113099
|
}
|
|
112418
113100
|
function suppressesInheritedSetter(contract) {
|
|
112419
113101
|
return contract?.getOnlyContract === true;
|
|
112420
113102
|
}
|
|
112421
|
-
function
|
|
112422
|
-
|
|
112423
|
-
|
|
112424
|
-
|
|
112425
|
-
return nsReturnTypeInfo.type === 7 /* Class */ ? nsReturnTypeInfo.classId : null;
|
|
113103
|
+
function generatedValueTypeInfo(ctx, member) {
|
|
113104
|
+
const required2 = isRequiredMember2(member);
|
|
113105
|
+
if (isMemberClassBase(member)) {
|
|
113106
|
+
return { type: 7 /* Class */, classId: member.classId, required: required2 };
|
|
112426
113107
|
}
|
|
113108
|
+
const returnType = nsPropertyReturnTypeInfo(member);
|
|
113109
|
+
if (returnType !== null) return returnType;
|
|
112427
113110
|
if (isMemberLookupBase(member)) {
|
|
112428
|
-
const
|
|
112429
|
-
if (
|
|
112430
|
-
|
|
113111
|
+
const declaredType = lookupDeclaredTypeInfo2(member);
|
|
113112
|
+
if (declaredType !== null) return declaredType;
|
|
113113
|
+
const entry = resolveLookupEntryMember(ctx, member);
|
|
113114
|
+
if (entry === null) return null;
|
|
113115
|
+
if (isMemberClassBase(entry)) {
|
|
113116
|
+
return { type: 7 /* Class */, classId: entry.classId, required: required2 };
|
|
112431
113117
|
}
|
|
112432
|
-
const entryMember = resolveLookupEntryMember(ctx, member);
|
|
112433
|
-
return entryMember !== null && isMemberClassBase(entryMember) ? entryMember.classId : null;
|
|
112434
113118
|
}
|
|
112435
113119
|
return null;
|
|
112436
113120
|
}
|
|
113121
|
+
function generatedValueClassId(ctx, member) {
|
|
113122
|
+
const typeInfo = generatedValueTypeInfo(ctx, member);
|
|
113123
|
+
return typeInfo?.type === 7 /* Class */ ? typeInfo.classId : null;
|
|
113124
|
+
}
|
|
112437
113125
|
function narrowedMemberValueType(ctx, member, rawValueType, contract) {
|
|
112438
113126
|
if (contract === null) return rawValueType;
|
|
112439
113127
|
if (contract.valueType === rawValueType) return rawValueType;
|
|
@@ -112449,13 +113137,18 @@ function narrowedMemberValueType(ctx, member, rawValueType, contract) {
|
|
|
112449
113137
|
)) {
|
|
112450
113138
|
return contract.valueType;
|
|
112451
113139
|
}
|
|
112452
|
-
|
|
112453
|
-
|
|
112454
|
-
if (
|
|
112455
|
-
|
|
112456
|
-
|
|
112457
|
-
);
|
|
112458
|
-
|
|
113140
|
+
const inheritedType = contract.valueTypeInfo;
|
|
113141
|
+
if (inheritedType === null) return rawValueType;
|
|
113142
|
+
if (inheritedType.type !== 7 /* Class */ && inheritedType.type !== 22 /* Interface */)
|
|
113143
|
+
return rawValueType;
|
|
113144
|
+
const valueType = generatedValueTypeInfo(ctx, member);
|
|
113145
|
+
if (valueType === null) return rawValueType;
|
|
113146
|
+
const sourceType = valueType.type === 7 /* Class */ && inheritedType.type === 7 /* Class */ && valueType.required === false && inheritedType.required === true ? { ...valueType, required: true } : valueType;
|
|
113147
|
+
try {
|
|
113148
|
+
return isTypeInfoAssignable(sourceType, inheritedType, ctx) ? contract.valueType : rawValueType;
|
|
113149
|
+
} catch {
|
|
113150
|
+
return rawValueType;
|
|
113151
|
+
}
|
|
112459
113152
|
}
|
|
112460
113153
|
function storedCollectionImplementsContract(ctx, member, rawValueType, contractType2) {
|
|
112461
113154
|
const contract = contractType2.replace(/\?$/, "");
|
|
@@ -112639,6 +113332,13 @@ function createGeneratedInstanceMemberSignatureProjector(exportData) {
|
|
|
112639
113332
|
equals: generatedInstanceMemberSignaturesEqual
|
|
112640
113333
|
};
|
|
112641
113334
|
}
|
|
113335
|
+
function formatGeneratedInstanceMemberSignature(signature) {
|
|
113336
|
+
if (signature.kind === "property") {
|
|
113337
|
+
const accessors = signature.hasSetter ? "get; set;" : "get;";
|
|
113338
|
+
return `${signature.valueType} ${signature.name} { ${accessors} }`;
|
|
113339
|
+
}
|
|
113340
|
+
return `${signature.returnType} ${signature.name}(${signature.parameterTypes.join(", ")})`;
|
|
113341
|
+
}
|
|
112642
113342
|
function generatedInstanceMemberSignaturesEqual(left, right) {
|
|
112643
113343
|
if (left.kind !== right.kind) return false;
|
|
112644
113344
|
if (left.name !== right.name) return false;
|
|
@@ -114246,6 +114946,7 @@ var init_generate_unity_classes = __esm({
|
|
|
114246
114946
|
init_sdk_runtime_enums();
|
|
114247
114947
|
init_members();
|
|
114248
114948
|
init_classes();
|
|
114949
|
+
init_type_info_compatibility();
|
|
114249
114950
|
DEFAULT_NAMESPACE = "Assets.Scripts.Neo";
|
|
114250
114951
|
isNSPropertyContractDeclaration = isMemberNSPropertyContractBase;
|
|
114251
114952
|
SMART_TILE_CONTRACT_WORLD_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -114302,7 +115003,7 @@ function changesRequireInheritanceFlagsValidation(changes) {
|
|
|
114302
115003
|
(change) => change.recordKind === "member" || change.recordKind === "class" || change.recordKind === "enum" || change.recordKind === "interface" || change.recordKind === "project"
|
|
114303
115004
|
);
|
|
114304
115005
|
}
|
|
114305
|
-
function
|
|
115006
|
+
function collectProjectDocumentInheritanceFlagsErrors(document, phase = "complete") {
|
|
114306
115007
|
let generatedSignatures = null;
|
|
114307
115008
|
const getGeneratedSignatures = () => {
|
|
114308
115009
|
if (generatedSignatures !== null) return generatedSignatures;
|
|
@@ -114328,12 +115029,14 @@ function assertProjectDocumentInheritanceFlagsValid(document) {
|
|
|
114328
115029
|
return generatedSignatures;
|
|
114329
115030
|
};
|
|
114330
115031
|
const errors = validateDocumentInheritanceFlags({
|
|
115032
|
+
phase,
|
|
114331
115033
|
members: document.members,
|
|
114332
115034
|
classes: document.classes,
|
|
114333
115035
|
rootMemberIds: new Set(
|
|
114334
115036
|
PROJECT_ROOTS.map((root) => document.project[root.projectField])
|
|
114335
115037
|
),
|
|
114336
115038
|
signatureProjector: {
|
|
115039
|
+
format: formatGeneratedInstanceMemberSignature,
|
|
114337
115040
|
resolveLocal: (classId, schemaKey) => getGeneratedSignatures().projectLocal(classId, schemaKey),
|
|
114338
115041
|
resolveInherited: (classId, schemaKey) => getGeneratedSignatures().projectInherited(classId, schemaKey),
|
|
114339
115042
|
resolveInheritedMetadata: (classId, schemaKey) => {
|
|
@@ -114343,6 +115046,7 @@ function assertProjectDocumentInheritanceFlagsValid(document) {
|
|
|
114343
115046
|
);
|
|
114344
115047
|
return signature === null ? null : {
|
|
114345
115048
|
memberId: signature.memberId,
|
|
115049
|
+
declarationClassId: signature.declarationClassId,
|
|
114346
115050
|
isAbstract: signature.isAbstract
|
|
114347
115051
|
};
|
|
114348
115052
|
},
|
|
@@ -114350,9 +115054,11 @@ function assertProjectDocumentInheritanceFlagsValid(document) {
|
|
|
114350
115054
|
hasImplementationBridge: (classId, schemaKey) => getGeneratedSignatures().hasImplementationBridge(classId, schemaKey)
|
|
114351
115055
|
}
|
|
114352
115056
|
});
|
|
114353
|
-
|
|
114354
|
-
|
|
114355
|
-
|
|
115057
|
+
return errors;
|
|
115058
|
+
}
|
|
115059
|
+
function assertProjectDocumentInheritanceFlagsValid(document) {
|
|
115060
|
+
const errors = collectProjectDocumentInheritanceFlagsErrors(document);
|
|
115061
|
+
if (errors.length > 0) throw new Error(errors[0].message);
|
|
114356
115062
|
}
|
|
114357
115063
|
var init_project_document_inheritance_validation = __esm({
|
|
114358
115064
|
"../src/database/project-document-inheritance-validation.ts"() {
|
|
@@ -116846,6 +117552,103 @@ var init_client_commit_preparation = __esm({
|
|
|
116846
117552
|
}
|
|
116847
117553
|
});
|
|
116848
117554
|
|
|
117555
|
+
// src/project-source/schema-source-validation.ts
|
|
117556
|
+
function sourceDiagnosticMapper(analysis) {
|
|
117557
|
+
const locations = /* @__PURE__ */ new Map();
|
|
117558
|
+
for (const declaration of analysis.schema.classes) {
|
|
117559
|
+
locations.set(
|
|
117560
|
+
materializedId(declaration, "class", declaration.name),
|
|
117561
|
+
declaration.source
|
|
117562
|
+
);
|
|
117563
|
+
for (const member of declaration.members) {
|
|
117564
|
+
locations.set(
|
|
117565
|
+
materializedId(member, "member", `${declaration.name}.${member.name}`),
|
|
117566
|
+
member.source
|
|
117567
|
+
);
|
|
117568
|
+
}
|
|
117569
|
+
}
|
|
117570
|
+
return (error, fallback = "<project>", recordId) => {
|
|
117571
|
+
const message = error instanceof SchemaSourceError ? error.detail : error instanceof Error ? error.message : String(error);
|
|
117572
|
+
if (error instanceof SchemaSourceError && !error.file.startsWith("<"))
|
|
117573
|
+
return error;
|
|
117574
|
+
let location3 = recordId === void 0 ? void 0 : locations.get(recordId);
|
|
117575
|
+
if (location3 === void 0) {
|
|
117576
|
+
for (const match of message.matchAll(
|
|
117577
|
+
/(__pending__:[^:\s]+:[^:\s]+:\d+:\d+:[^\s"()]*)|\(([^()]+)\)|"([^"\n]+)"/g
|
|
117578
|
+
)) {
|
|
117579
|
+
const id2 = match[1] ?? match[2] ?? match[3];
|
|
117580
|
+
location3 = locations.get(id2);
|
|
117581
|
+
if (location3 !== void 0) break;
|
|
117582
|
+
const pending = /^__pending__:[^:]+:([^:]+):(\d+):(\d+):/.exec(id2);
|
|
117583
|
+
if (pending !== null) {
|
|
117584
|
+
const start = {
|
|
117585
|
+
line: Number(pending[2]),
|
|
117586
|
+
character: Number(pending[3])
|
|
117587
|
+
};
|
|
117588
|
+
location3 = {
|
|
117589
|
+
uri: decodeURIComponent(pending[1]),
|
|
117590
|
+
range: { start, end: start }
|
|
117591
|
+
};
|
|
117592
|
+
break;
|
|
117593
|
+
}
|
|
117594
|
+
}
|
|
117595
|
+
}
|
|
117596
|
+
if (location3 === void 0 && error instanceof SchemaSourceError)
|
|
117597
|
+
return error;
|
|
117598
|
+
return new SchemaSourceError(
|
|
117599
|
+
message,
|
|
117600
|
+
location3?.uri ?? fallback,
|
|
117601
|
+
(location3?.range.start.line ?? 0) + 1,
|
|
117602
|
+
(location3?.range.start.character ?? 0) + 1,
|
|
117603
|
+
error instanceof SchemaSourceError ? error.code : "schema-validation"
|
|
117604
|
+
);
|
|
117605
|
+
};
|
|
117606
|
+
}
|
|
117607
|
+
function collectSourceSchemaErrors(document) {
|
|
117608
|
+
const rootMemberIds2 = new Set(
|
|
117609
|
+
PROJECT_ROOTS.map((root) => document.project[root.projectField])
|
|
117610
|
+
);
|
|
117611
|
+
const errors = [];
|
|
117612
|
+
for (const validate3 of [
|
|
117613
|
+
() => validateDocumentAccessModifiers({ ...document, rootMemberIds: rootMemberIds2 }),
|
|
117614
|
+
() => collectProjectDocumentInheritanceFlagsErrors(document, "schema")
|
|
117615
|
+
]) {
|
|
117616
|
+
try {
|
|
117617
|
+
errors.push(...validate3());
|
|
117618
|
+
} catch (error) {
|
|
117619
|
+
errors.push({
|
|
117620
|
+
message: error instanceof Error ? error.message : String(error)
|
|
117621
|
+
});
|
|
117622
|
+
}
|
|
117623
|
+
}
|
|
117624
|
+
for (const member of document.members) {
|
|
117625
|
+
if (member.kind !== 6 /* List */) continue;
|
|
117626
|
+
errors.push(...validateListIndexDefinitions(document, member));
|
|
117627
|
+
}
|
|
117628
|
+
return errors;
|
|
117629
|
+
}
|
|
117630
|
+
function uniqueSourceErrors(errors) {
|
|
117631
|
+
const seen = /* @__PURE__ */ new Set();
|
|
117632
|
+
return errors.filter((error) => {
|
|
117633
|
+
const key = `${error.file}:${error.line}:${error.column}:${error.detail}`;
|
|
117634
|
+
if (seen.has(key)) return false;
|
|
117635
|
+
seen.add(key);
|
|
117636
|
+
return true;
|
|
117637
|
+
});
|
|
117638
|
+
}
|
|
117639
|
+
var init_schema_source_validation = __esm({
|
|
117640
|
+
"src/project-source/schema-source-validation.ts"() {
|
|
117641
|
+
"use strict";
|
|
117642
|
+
init_project_document_inheritance_validation();
|
|
117643
|
+
init_member_access_modifier_validation();
|
|
117644
|
+
init_list_indexes();
|
|
117645
|
+
init_member_kinds();
|
|
117646
|
+
init_project2();
|
|
117647
|
+
init_source_diagnostics();
|
|
117648
|
+
init_lower_support();
|
|
117649
|
+
}
|
|
117650
|
+
});
|
|
117651
|
+
|
|
116849
117652
|
// src/project-sync/value-record-comparison.ts
|
|
116850
117653
|
function valueRecordComparisonBody(value) {
|
|
116851
117654
|
if (!isObjectRecord2(value)) return value;
|
|
@@ -116906,7 +117709,13 @@ function lowerConfiguration(base, analysis) {
|
|
|
116906
117709
|
(global) => global.type.name === "Localization"
|
|
116907
117710
|
);
|
|
116908
117711
|
if (!localizationGlobal) {
|
|
116909
|
-
throw new
|
|
117712
|
+
throw new SchemaSourceError(
|
|
117713
|
+
"Format-4 source requires one Localization global.",
|
|
117714
|
+
base.localization.source.span.path,
|
|
117715
|
+
1,
|
|
117716
|
+
1,
|
|
117717
|
+
"missing-localization-global"
|
|
117718
|
+
);
|
|
116910
117719
|
}
|
|
116911
117720
|
return {
|
|
116912
117721
|
textureTemplates,
|
|
@@ -117837,6 +118646,7 @@ var wireEnumOptions, TEXTURE_TYPE_WIRE_OPTIONS, ALPHA_SOURCE_WIRE_OPTIONS, NON_P
|
|
|
117837
118646
|
var init_lower_configuration = __esm({
|
|
117838
118647
|
"src/project-source/lower-configuration.ts"() {
|
|
117839
118648
|
"use strict";
|
|
118649
|
+
init_source_diagnostics();
|
|
117840
118650
|
init_src();
|
|
117841
118651
|
init_lower_support();
|
|
117842
118652
|
wireEnumOptions = () => (options) => options;
|
|
@@ -118551,6 +119361,7 @@ function lowerProjectSchemaV4(base, analysis, options = {}) {
|
|
|
118551
119361
|
)
|
|
118552
119362
|
);
|
|
118553
119363
|
const context = {
|
|
119364
|
+
onDeclarationError: options.onDeclarationError,
|
|
118554
119365
|
base,
|
|
118555
119366
|
baseClasses: new Map(base.classes.map((entry) => [entry.id, entry])),
|
|
118556
119367
|
baseConstructors: new Map(
|
|
@@ -118609,17 +119420,29 @@ function lowerProjectSchemaV4(base, analysis, options = {}) {
|
|
|
118609
119420
|
analysis.compiledBodies.filter((body) => body.unit === "function").map((body) => [`${body.ownerName}.${body.memberName}`, body.ir])
|
|
118610
119421
|
)
|
|
118611
119422
|
};
|
|
118612
|
-
const classes = analysis.schema.classes.
|
|
118613
|
-
|
|
118614
|
-
|
|
118615
|
-
|
|
118616
|
-
|
|
118617
|
-
|
|
118618
|
-
|
|
118619
|
-
|
|
118620
|
-
|
|
118621
|
-
|
|
118622
|
-
|
|
119423
|
+
const classes = analysis.schema.classes.flatMap((declaration) => {
|
|
119424
|
+
try {
|
|
119425
|
+
return [lowerClass(context, declaration)];
|
|
119426
|
+
} catch (error) {
|
|
119427
|
+
if (options.onDeclarationError === void 0) throw error;
|
|
119428
|
+
options.onDeclarationError(error, declaration);
|
|
119429
|
+
return [];
|
|
119430
|
+
}
|
|
119431
|
+
});
|
|
119432
|
+
const constructors = analysis.schema.classes.flatMap((declaration) => {
|
|
119433
|
+
try {
|
|
119434
|
+
return lowerClassConstructors(
|
|
119435
|
+
context,
|
|
119436
|
+
declaration,
|
|
119437
|
+
materializedId(declaration, "class", declaration.name),
|
|
119438
|
+
(type, ownerClass) => lowerType(context, type, ownerClass)
|
|
119439
|
+
);
|
|
119440
|
+
} catch (error) {
|
|
119441
|
+
if (options.onDeclarationError === void 0) throw error;
|
|
119442
|
+
options.onDeclarationError(error, declaration);
|
|
119443
|
+
return [];
|
|
119444
|
+
}
|
|
119445
|
+
});
|
|
118623
119446
|
normalizeLookupDeclaredTypes(context);
|
|
118624
119447
|
for (const [memberId, placements] of context.placements) {
|
|
118625
119448
|
const member = context.loweredMembers.get(memberId);
|
|
@@ -123054,6 +123877,9 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
123054
123877
|
staticMemberOwnershipRecoveries.filter((recovery) => recovery.action === "delete").map((recovery) => recordStateKey("member", recovery.memberId))
|
|
123055
123878
|
);
|
|
123056
123879
|
let manifest;
|
|
123880
|
+
let rootEnvelopeValid = false;
|
|
123881
|
+
let invalidSchema = false;
|
|
123882
|
+
let schemaValidationDocument;
|
|
123057
123883
|
let authoredValueSeeds = /* @__PURE__ */ new Map();
|
|
123058
123884
|
let staticMemberValueIds = /* @__PURE__ */ new Map();
|
|
123059
123885
|
let memberDefaults = {
|
|
@@ -123087,36 +123913,33 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
123087
123913
|
}
|
|
123088
123914
|
const analysis = options.readProjectAnalysisCache?.(workspace.root, compilationSources) ?? compileNeoProjectSources(compilationSources);
|
|
123089
123915
|
projectAnalysisV4 = analysis;
|
|
123090
|
-
for (const
|
|
123916
|
+
for (const diagnostic2 of analysis.diagnostics) {
|
|
123091
123917
|
const positioned = new SchemaSourceError(
|
|
123092
|
-
`${
|
|
123093
|
-
|
|
123094
|
-
|
|
123095
|
-
|
|
123096
|
-
|
|
123097
|
-
|
|
123918
|
+
`${diagnostic2.code ?? "analysis"}: ${diagnostic2.message}`,
|
|
123919
|
+
diagnostic2.uri,
|
|
123920
|
+
diagnostic2.range.start.line + 1,
|
|
123921
|
+
diagnostic2.range.start.character + 1,
|
|
123922
|
+
diagnostic2.code,
|
|
123923
|
+
diagnostic2.severity
|
|
123098
123924
|
);
|
|
123099
123925
|
if (positioned.severity === "error") parseErrors.push(positioned);
|
|
123100
123926
|
else parseWarnings.push(positioned);
|
|
123101
123927
|
}
|
|
123102
|
-
|
|
123103
|
-
|
|
123104
|
-
|
|
123105
|
-
|
|
123106
|
-
|
|
123107
|
-
|
|
123108
|
-
reconstructed: /* @__PURE__ */ new Map(),
|
|
123109
|
-
authoredValueSeeds,
|
|
123110
|
-
binaryChanges: [],
|
|
123111
|
-
binaryFiles: []
|
|
123112
|
-
};
|
|
123113
|
-
}
|
|
123928
|
+
const rootDeclaration = analysis.configuration.globals.find(
|
|
123929
|
+
(global) => global.type.name === "Root"
|
|
123930
|
+
);
|
|
123931
|
+
const rootHasCompilerError = rootDeclaration !== void 0 && analysis.diagnostics.some(
|
|
123932
|
+
(error) => error.severity === "error" && error.uri === rootDeclaration.source.uri && sourceRangeContains(rootDeclaration.source.range, error.range.start)
|
|
123933
|
+
);
|
|
123114
123934
|
try {
|
|
123115
|
-
|
|
123116
|
-
|
|
123117
|
-
|
|
123118
|
-
|
|
123119
|
-
|
|
123935
|
+
if (!rootHasCompilerError) {
|
|
123936
|
+
validateProjectRootEnvelopeV4(
|
|
123937
|
+
loweringRecords,
|
|
123938
|
+
analysis,
|
|
123939
|
+
valueLowerRegistry.parsedInitializers
|
|
123940
|
+
);
|
|
123941
|
+
rootEnvelopeValid = true;
|
|
123942
|
+
}
|
|
123120
123943
|
} catch (error) {
|
|
123121
123944
|
const root = analysis.configuration.globals.find(
|
|
123122
123945
|
(global) => global.type.name === "Root"
|
|
@@ -123129,18 +123952,48 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
123129
123952
|
(root?.source.range.start.character ?? 0) + 1
|
|
123130
123953
|
)
|
|
123131
123954
|
);
|
|
123132
|
-
return {
|
|
123133
|
-
changes: [],
|
|
123134
|
-
conflictedFiles,
|
|
123135
|
-
parseErrors,
|
|
123136
|
-
parseWarnings,
|
|
123137
|
-
reconstructed: /* @__PURE__ */ new Map(),
|
|
123138
|
-
authoredValueSeeds,
|
|
123139
|
-
binaryChanges: [],
|
|
123140
|
-
binaryFiles: []
|
|
123141
|
-
};
|
|
123142
123955
|
}
|
|
123143
|
-
|
|
123956
|
+
const diagnostic = sourceDiagnosticMapper(analysis);
|
|
123957
|
+
const errorsByUri = /* @__PURE__ */ new Map();
|
|
123958
|
+
for (const error of analysis.diagnostics) {
|
|
123959
|
+
if (error.severity !== "error") continue;
|
|
123960
|
+
const errors = errorsByUri.get(error.uri) ?? [];
|
|
123961
|
+
errors.push(error);
|
|
123962
|
+
errorsByUri.set(error.uri, errors);
|
|
123963
|
+
}
|
|
123964
|
+
const validAnalysis = {
|
|
123965
|
+
...analysis,
|
|
123966
|
+
configuration: {
|
|
123967
|
+
globals: analysis.configuration.globals.filter(
|
|
123968
|
+
(global) => global.type.name !== "Root" || rootEnvelopeValid && !rootHasCompilerError
|
|
123969
|
+
)
|
|
123970
|
+
},
|
|
123971
|
+
schema: {
|
|
123972
|
+
...analysis.schema,
|
|
123973
|
+
classes: analysis.schema.classes.map((declaration) => ({
|
|
123974
|
+
...declaration,
|
|
123975
|
+
members: declaration.members.filter(
|
|
123976
|
+
(member) => !(errorsByUri.get(member.source.uri) ?? []).some(
|
|
123977
|
+
(error) => sourceRangeContains(member.source.range, error.range.start)
|
|
123978
|
+
)
|
|
123979
|
+
)
|
|
123980
|
+
}))
|
|
123981
|
+
}
|
|
123982
|
+
};
|
|
123983
|
+
const failedDeclarations = /* @__PURE__ */ new Set();
|
|
123984
|
+
manifest = lowerProjectSchemaV4(baseManifest, validAnalysis, {
|
|
123985
|
+
onDeclarationError: (error, declaration) => {
|
|
123986
|
+
failedDeclarations.add(declaration);
|
|
123987
|
+
parseErrors.push(
|
|
123988
|
+
error instanceof SchemaSourceError ? error : new SchemaSourceError(
|
|
123989
|
+
error instanceof Error ? error.message : String(error),
|
|
123990
|
+
declaration.source.uri,
|
|
123991
|
+
declaration.source.range.start.line + 1,
|
|
123992
|
+
declaration.source.range.start.character + 1,
|
|
123993
|
+
"schema-lowering"
|
|
123994
|
+
)
|
|
123995
|
+
);
|
|
123996
|
+
},
|
|
123144
123997
|
staticValueIdsBySymbol: staticValueIdsBySymbol(loweringRecords),
|
|
123145
123998
|
projectFileIdsBySymbol: projectFileIdsBySymbol(loweringRecords, analysis),
|
|
123146
123999
|
rowBackedDefaultMemberIds: rowBackedDefaultMemberIdsV4(loweringRecords),
|
|
@@ -123148,9 +124001,61 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
123148
124001
|
Object.values(loweringRecords)
|
|
123149
124002
|
)
|
|
123150
124003
|
});
|
|
124004
|
+
try {
|
|
124005
|
+
const schemaRecords = /* @__PURE__ */ new Map();
|
|
124006
|
+
for (const [key, record6] of Object.entries(loweringRecords)) {
|
|
124007
|
+
if (record6.recordKind !== "project") continue;
|
|
124008
|
+
schemaRecords.set(key, { ...record6, deleted: false });
|
|
124009
|
+
}
|
|
124010
|
+
for (const record6 of projectSchemaManifestToDocuments(
|
|
124011
|
+
manifest,
|
|
124012
|
+
manifestToDocumentContext(baseDocuments)
|
|
124013
|
+
)) {
|
|
124014
|
+
schemaRecords.set(recordStateKey(record6.recordKind, record6.recordId), {
|
|
124015
|
+
...record6,
|
|
124016
|
+
contentHash: "",
|
|
124017
|
+
deleted: false
|
|
124018
|
+
});
|
|
124019
|
+
}
|
|
124020
|
+
if ([...schemaRecords.values()].some(
|
|
124021
|
+
(record6) => record6.recordKind === "project"
|
|
124022
|
+
)) {
|
|
124023
|
+
const document = readPulledProjectDocumentV4(schemaRecords);
|
|
124024
|
+
schemaValidationDocument = document;
|
|
124025
|
+
for (const error of collectSourceSchemaErrors(document)) {
|
|
124026
|
+
parseErrors.push(
|
|
124027
|
+
diagnostic(new Error(error.message), "<project>", error.memberId)
|
|
124028
|
+
);
|
|
124029
|
+
}
|
|
124030
|
+
}
|
|
124031
|
+
} catch (error) {
|
|
124032
|
+
parseErrors.push(diagnostic(error));
|
|
124033
|
+
}
|
|
124034
|
+
invalidSchema = parseErrors.some(isBlockingSchemaSourceError);
|
|
124035
|
+
const loweredMemberIds = new Set(
|
|
124036
|
+
manifest.members.map((member) => member.id)
|
|
124037
|
+
);
|
|
124038
|
+
projectAnalysisV4 = {
|
|
124039
|
+
...validAnalysis,
|
|
124040
|
+
schema: {
|
|
124041
|
+
...validAnalysis.schema,
|
|
124042
|
+
classes: validAnalysis.schema.classes.map((declaration) => ({
|
|
124043
|
+
...declaration,
|
|
124044
|
+
members: declaration.members.filter(
|
|
124045
|
+
(member) => !failedDeclarations.has(member) && loweredMemberIds.has(
|
|
124046
|
+
materializedId(
|
|
124047
|
+
member,
|
|
124048
|
+
"member",
|
|
124049
|
+
`${declaration.name}.${member.name}`
|
|
124050
|
+
)
|
|
124051
|
+
)
|
|
124052
|
+
)
|
|
124053
|
+
}))
|
|
124054
|
+
}
|
|
124055
|
+
};
|
|
123151
124056
|
memberDefaults = lowerMemberDefaultSourcesV4(
|
|
123152
124057
|
loweringRecords,
|
|
123153
|
-
|
|
124058
|
+
projectAnalysisV4,
|
|
123154
124059
|
manifest,
|
|
123155
124060
|
{ registry: valueLowerRegistry }
|
|
123156
124061
|
);
|
|
@@ -123170,9 +124075,17 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
123170
124075
|
);
|
|
123171
124076
|
reportPhase("analysis-schema-defaults", "Reading stored values\u2026");
|
|
123172
124077
|
} catch (error) {
|
|
124078
|
+
const missingLocalization = error instanceof SchemaSourceError && error.code === "missing-localization-global";
|
|
124079
|
+
const positioned = missingLocalization ? new SchemaSourceError(
|
|
124080
|
+
error.detail,
|
|
124081
|
+
loweringRecords[`localization-config:${baseManifest?.localization.id}`]?.file ?? "Localization.neo",
|
|
124082
|
+
1,
|
|
124083
|
+
1,
|
|
124084
|
+
error.code
|
|
124085
|
+
) : error;
|
|
123173
124086
|
parseErrors.push(
|
|
123174
|
-
|
|
123175
|
-
|
|
124087
|
+
positioned instanceof SchemaSourceError ? positioned : new SchemaSourceError(
|
|
124088
|
+
positioned instanceof Error ? positioned.message : String(positioned),
|
|
123176
124089
|
"<project>",
|
|
123177
124090
|
1,
|
|
123178
124091
|
1
|
|
@@ -123234,12 +124147,25 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
123234
124147
|
...memberDefaults.seeds
|
|
123235
124148
|
]);
|
|
123236
124149
|
staticMemberValueIds = staticValues.memberValueIds;
|
|
123237
|
-
|
|
123238
|
-
|
|
123239
|
-
|
|
123240
|
-
|
|
123241
|
-
|
|
123242
|
-
|
|
124150
|
+
if (schemaValidationDocument !== void 0) {
|
|
124151
|
+
const diagnostic = sourceDiagnosticMapper(projectAnalysisV4);
|
|
124152
|
+
for (const member of schemaValidationDocument.members) {
|
|
124153
|
+
const valueId = staticMemberValueIds.get(member.id);
|
|
124154
|
+
const finalized = valueId === void 0 ? member : { ...member, valueId, defaultValue: void 0 };
|
|
124155
|
+
for (const error of validateStaticMemberValueBinding(finalized)) {
|
|
124156
|
+
parseErrors.push(
|
|
124157
|
+
diagnostic(new Error(error.message), "<project>", member.id)
|
|
124158
|
+
);
|
|
124159
|
+
}
|
|
124160
|
+
}
|
|
124161
|
+
}
|
|
124162
|
+
const rootValues = rootEnvelopeValid ? lowerProjectRootSourceV4(loweringRecords, projectAnalysisV4, manifest, {
|
|
124163
|
+
registry: valueLowerRegistry
|
|
124164
|
+
}) : {
|
|
124165
|
+
records: [],
|
|
124166
|
+
memberValueIds: /* @__PURE__ */ new Map(),
|
|
124167
|
+
seeds: /* @__PURE__ */ new Map()
|
|
124168
|
+
};
|
|
123243
124169
|
reportPhase("documents-static-root", "Reading variants and dialogues\u2026");
|
|
123244
124170
|
authoredValueSeeds = new Map([...authoredValueSeeds, ...rootValues.seeds]);
|
|
123245
124171
|
const rootPathResolutionState = overlayProspectiveSourceRecords(
|
|
@@ -123864,6 +124790,14 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
123864
124790
|
}
|
|
123865
124791
|
reportPhase("initializer-materialization");
|
|
123866
124792
|
}
|
|
124793
|
+
const mapDiagnostic = projectAnalysisV4 === null ? null : sourceDiagnosticMapper(projectAnalysisV4);
|
|
124794
|
+
const positionedErrors = mapDiagnostic === null ? parseErrors : parseErrors.map((error) => mapDiagnostic(error, error.file));
|
|
124795
|
+
if (invalidSchema)
|
|
124796
|
+
return refusedStatus(
|
|
124797
|
+
conflictedFiles,
|
|
124798
|
+
uniqueSourceErrors(positionedErrors),
|
|
124799
|
+
parseWarnings
|
|
124800
|
+
);
|
|
123867
124801
|
return {
|
|
123868
124802
|
...projectAnalysisV4 === null ? {} : {
|
|
123869
124803
|
sourceSnapshot: {
|
|
@@ -123874,7 +124808,7 @@ function computeWorkspaceStatus(workspace, options) {
|
|
|
123874
124808
|
localValues: valueLowerRegistry.localValues?.placements(),
|
|
123875
124809
|
changes,
|
|
123876
124810
|
conflictedFiles,
|
|
123877
|
-
parseErrors,
|
|
124811
|
+
parseErrors: uniqueSourceErrors(positionedErrors),
|
|
123878
124812
|
parseWarnings,
|
|
123879
124813
|
reconstructed: reconstructed3,
|
|
123880
124814
|
authoredValueSeeds,
|
|
@@ -124851,10 +125785,16 @@ function refusedStatus(conflictedFiles, parseErrors, parseWarnings) {
|
|
|
124851
125785
|
binaryFiles: []
|
|
124852
125786
|
};
|
|
124853
125787
|
}
|
|
125788
|
+
function sourceRangeContains(range2, position) {
|
|
125789
|
+
return (position.line > range2.start.line || position.line === range2.start.line && position.character >= range2.start.character) && (position.line < range2.end.line || position.line === range2.end.line && position.character < range2.end.character);
|
|
125790
|
+
}
|
|
124854
125791
|
var ANIMATION_DOCUMENT_RECORD_KINDS, ANIMATION_REPLAY_RECORD_KINDS, PROSPECTIVE_ANIMATION_RECORD_KINDS;
|
|
124855
125792
|
var init_workspace_status_core = __esm({
|
|
124856
125793
|
"src/project-source/workspace-status-core.ts"() {
|
|
124857
125794
|
"use strict";
|
|
125795
|
+
init_lower_support();
|
|
125796
|
+
init_inheritance_flags_validation();
|
|
125797
|
+
init_schema_source_validation();
|
|
124858
125798
|
init_members();
|
|
124859
125799
|
init_collection_binding_materialization();
|
|
124860
125800
|
init_localizable_member_value_writes();
|
|
@@ -124977,9 +125917,9 @@ function verifyProjectSourceCommitAgainstStateV4(args) {
|
|
|
124977
125917
|
});
|
|
124978
125918
|
const blockingErrors = status.parseErrors.filter(isBlockingSchemaSourceError);
|
|
124979
125919
|
if (status.conflictedFiles.length > 0 || blockingErrors.length > 0) {
|
|
124980
|
-
const first = blockingErrors[0];
|
|
124981
125920
|
throw new ProjectSourceCommitVerificationError(
|
|
124982
|
-
|
|
125921
|
+
blockingErrors.length > 0 ? `Trusted source lowering failed:
|
|
125922
|
+
${blockingErrors.map((error) => error.message).join("\n")}` : `Trusted source lowering found conflict markers in ${status.conflictedFiles.join(", ")}.`
|
|
124983
125923
|
);
|
|
124984
125924
|
}
|
|
124985
125925
|
auditAuthoredSeedRowIdentities(
|
|
@@ -125012,8 +125952,10 @@ function verifyProjectSourceCommitAgainstStateV4(args) {
|
|
|
125012
125952
|
);
|
|
125013
125953
|
for (const pendingId2 of assignments.keys()) {
|
|
125014
125954
|
if (!usedAssignments.has(pendingId2)) {
|
|
125955
|
+
const message = `Pending id assignment ${pendingId2} is not present in the verified source manifest.`;
|
|
125956
|
+
const analysis = status.sourceSnapshot?.analysis;
|
|
125015
125957
|
throw new ProjectSourceCommitVerificationError(
|
|
125016
|
-
|
|
125958
|
+
analysis === void 0 ? message : sourceDiagnosticMapper(analysis)(new Error(message)).message
|
|
125017
125959
|
);
|
|
125018
125960
|
}
|
|
125019
125961
|
}
|
|
@@ -125507,6 +126449,7 @@ var ProjectSourceCommitVerificationError, ABSENT_DIFFERENCE_VALUE;
|
|
|
125507
126449
|
var init_trusted_commit_verification = __esm({
|
|
125508
126450
|
"src/project-source/trusted-commit-verification.ts"() {
|
|
125509
126451
|
"use strict";
|
|
126452
|
+
init_schema_source_validation();
|
|
125510
126453
|
init_projectRecordBuckets();
|
|
125511
126454
|
init_workspace_status_core();
|
|
125512
126455
|
init_supplemental_records();
|
|
@@ -127891,6 +128834,8 @@ function defaultRequiresOwnedRows(context, member, sourceExpression, source) {
|
|
|
127891
128834
|
}
|
|
127892
128835
|
function memberInitializerRequiresEvaluation(context, member, expression, source) {
|
|
127893
128836
|
if (member.kind === "class" && member.partial === true) return false;
|
|
128837
|
+
if (source.purpose === "memberDefault" && member.id === source.memberId && member.kind === "list" && member.listKind === "unordered" && expression.kind === "litList" && expression.elements.length > 0)
|
|
128838
|
+
return true;
|
|
127894
128839
|
const requiresEvaluation = isSchemaMemberValueRead(context, expression, source) || initializerRequiresEvaluation(
|
|
127895
128840
|
context.declaredConstructors,
|
|
127896
128841
|
expression,
|
|
@@ -134256,7 +135201,7 @@ var init_project_document_cache = __esm({
|
|
|
134256
135201
|
init_src();
|
|
134257
135202
|
init_project_documents();
|
|
134258
135203
|
PROJECT_SOURCE_BUILD_CACHE_PATH = ".neo/build/project-source-analysis-v4.json";
|
|
134259
|
-
PROJECT_SOURCE_BUILD_CACHE_REVISION =
|
|
135204
|
+
PROJECT_SOURCE_BUILD_CACHE_REVISION = 4;
|
|
134260
135205
|
}
|
|
134261
135206
|
});
|
|
134262
135207
|
|
|
@@ -146409,7 +147354,7 @@ var init_registry2 = __esm({
|
|
|
146409
147354
|
"../packages/manifest/schema-contract/registry.mjs"() {
|
|
146410
147355
|
"use strict";
|
|
146411
147356
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
146412
|
-
cliVersion: "0.
|
|
147357
|
+
cliVersion: "0.62.1",
|
|
146413
147358
|
projectFileUploadBatchSize: 32,
|
|
146414
147359
|
documentRecords: {
|
|
146415
147360
|
member: {
|
|
@@ -155089,7 +156034,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
155089
156034
|
async function main() {
|
|
155090
156035
|
const args = parseArgs(process.argv.slice(2));
|
|
155091
156036
|
if (args.command === "--version") {
|
|
155092
|
-
console.log("0.
|
|
156037
|
+
console.log("0.62.1");
|
|
155093
156038
|
return;
|
|
155094
156039
|
}
|
|
155095
156040
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|