@neocompose/cli 0.61.5 → 0.62.0
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 +12 -0
- package/dist/neo.mjs +947 -358
- 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 +6 -0
- package/skills/neocompose-cli/references/neoscript.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
|
});
|
|
@@ -25783,18 +25992,25 @@ var init_project_source_semantics = __esm({
|
|
|
25783
25992
|
});
|
|
25784
25993
|
|
|
25785
25994
|
// ../packages/neoscript-language/src/project-source-accessors.ts
|
|
25786
|
-
function
|
|
25787
|
-
if (source.length === 0) return null;
|
|
25995
|
+
function projectSourceAccessors(source, containingRange) {
|
|
25788
25996
|
const full = new SourceText(source);
|
|
25789
25997
|
const range2 = containingRange ?? full.fullRange();
|
|
25790
25998
|
const bodyStart = full.offsetAt(range2.start);
|
|
25791
|
-
const
|
|
25792
|
-
|
|
25793
|
-
|
|
25999
|
+
const tokens = lex(
|
|
26000
|
+
source.slice(bodyStart, full.offsetAt(range2.end))
|
|
26001
|
+
).roots.filter((token) => token.kind !== "comment");
|
|
25794
26002
|
if (isToken(tokens[0], "operator", "=>")) {
|
|
25795
|
-
|
|
25796
|
-
|
|
26003
|
+
return [
|
|
26004
|
+
{
|
|
26005
|
+
keyword: "get",
|
|
26006
|
+
form: "expression",
|
|
26007
|
+
range: range2,
|
|
26008
|
+
parameters: null,
|
|
26009
|
+
body: expressionAccessor(source, full, tokens, bodyStart, 1)
|
|
26010
|
+
}
|
|
26011
|
+
];
|
|
25797
26012
|
}
|
|
26013
|
+
const accessors = [];
|
|
25798
26014
|
let depth = 0;
|
|
25799
26015
|
for (let index = 0; index < tokens.length; index++) {
|
|
25800
26016
|
const token = tokens[index];
|
|
@@ -25806,44 +26022,66 @@ function findProjectSourceAccessorBody(source, keyword, containingRange) {
|
|
|
25806
26022
|
depth--;
|
|
25807
26023
|
continue;
|
|
25808
26024
|
}
|
|
25809
|
-
if (depth !== 1 || token.kind !== "identifier" && token.kind !== "keyword" || token.text !==
|
|
26025
|
+
if (depth !== 1 || token.kind !== "identifier" && token.kind !== "keyword" || token.text !== "get" && token.text !== "set")
|
|
25810
26026
|
continue;
|
|
25811
|
-
}
|
|
25812
26027
|
let openIndex = index + 1;
|
|
26028
|
+
let parameters = null;
|
|
25813
26029
|
if (isToken(tokens[openIndex], "punctuation", "(")) {
|
|
26030
|
+
const firstParameter = ++openIndex;
|
|
25814
26031
|
let parameterDepth = 1;
|
|
25815
|
-
for (
|
|
25816
|
-
|
|
25817
|
-
if (isToken(
|
|
25818
|
-
if (
|
|
25819
|
-
if (parameterDepth !== 0) continue;
|
|
25820
|
-
openIndex = cursor + 1;
|
|
25821
|
-
break;
|
|
26032
|
+
for (; openIndex < tokens.length; openIndex++) {
|
|
26033
|
+
if (isToken(tokens[openIndex], "punctuation", "(")) parameterDepth++;
|
|
26034
|
+
if (isToken(tokens[openIndex], "punctuation", ")")) parameterDepth--;
|
|
26035
|
+
if (parameterDepth === 0) break;
|
|
25822
26036
|
}
|
|
25823
|
-
|
|
26037
|
+
parameters = tokens.slice(firstParameter, openIndex);
|
|
26038
|
+
openIndex++;
|
|
25824
26039
|
}
|
|
25825
26040
|
const open = tokens[openIndex];
|
|
26041
|
+
let body = null;
|
|
26042
|
+
let form = isToken(open, "punctuation", ";") ? "contract" : "invalid";
|
|
25826
26043
|
if (isToken(open, "operator", "=>")) {
|
|
25827
|
-
|
|
25828
|
-
|
|
25829
|
-
|
|
25830
|
-
|
|
25831
|
-
|
|
25832
|
-
|
|
25833
|
-
|
|
25834
|
-
|
|
25835
|
-
|
|
25836
|
-
|
|
25837
|
-
|
|
25838
|
-
|
|
25839
|
-
|
|
25840
|
-
|
|
25841
|
-
|
|
25842
|
-
|
|
26044
|
+
form = "expression";
|
|
26045
|
+
body = expressionAccessor(source, full, tokens, bodyStart, openIndex + 1);
|
|
26046
|
+
if (body) {
|
|
26047
|
+
const end = full.offsetAt(body.range.end) - bodyStart;
|
|
26048
|
+
while (openIndex + 1 < tokens.length && tokens[openIndex + 1].start < end)
|
|
26049
|
+
openIndex++;
|
|
26050
|
+
}
|
|
26051
|
+
} else if (isToken(open, "punctuation", "{")) {
|
|
26052
|
+
form = "block";
|
|
26053
|
+
let accessorDepth = 1;
|
|
26054
|
+
for (let cursor = openIndex + 1; cursor < tokens.length; cursor++) {
|
|
26055
|
+
const candidate = tokens[cursor];
|
|
26056
|
+
if (isToken(candidate, "punctuation", "{")) accessorDepth++;
|
|
26057
|
+
if (isToken(candidate, "punctuation", "}")) accessorDepth--;
|
|
26058
|
+
if (accessorDepth !== 0) continue;
|
|
26059
|
+
const start = bodyStart + open.end;
|
|
26060
|
+
const end = bodyStart + candidate.start;
|
|
26061
|
+
body = {
|
|
26062
|
+
range: full.range(start, end),
|
|
26063
|
+
source: source.slice(start, end),
|
|
26064
|
+
form: "block"
|
|
26065
|
+
};
|
|
26066
|
+
openIndex = cursor;
|
|
26067
|
+
break;
|
|
26068
|
+
}
|
|
25843
26069
|
}
|
|
25844
|
-
|
|
26070
|
+
accessors.push({
|
|
26071
|
+
keyword: token.text,
|
|
26072
|
+
form,
|
|
26073
|
+
range: full.range(bodyStart + token.start, bodyStart + token.end),
|
|
26074
|
+
parameters,
|
|
26075
|
+
body
|
|
26076
|
+
});
|
|
26077
|
+
index = Math.max(index, openIndex);
|
|
25845
26078
|
}
|
|
25846
|
-
return
|
|
26079
|
+
return accessors;
|
|
26080
|
+
}
|
|
26081
|
+
function findProjectSourceAccessorBody(source, keyword, containingRange) {
|
|
26082
|
+
return projectSourceAccessors(source, containingRange).find(
|
|
26083
|
+
(accessor) => accessor.keyword === keyword
|
|
26084
|
+
)?.body ?? null;
|
|
25847
26085
|
}
|
|
25848
26086
|
function isToken(token, kind, text) {
|
|
25849
26087
|
return token?.kind === kind && token.text === text;
|
|
@@ -26078,9 +26316,10 @@ function compileBody(args) {
|
|
|
26078
26316
|
memberName: args.memberName,
|
|
26079
26317
|
unit: args.unit,
|
|
26080
26318
|
range: args.range,
|
|
26081
|
-
context: args.context
|
|
26319
|
+
context: args.context,
|
|
26320
|
+
...args.bodyMode ? { bodyMode: args.bodyMode } : {}
|
|
26082
26321
|
});
|
|
26083
|
-
const source =
|
|
26322
|
+
const source = args.document.syntax.source;
|
|
26084
26323
|
const start = source.offsetAt(args.range.start);
|
|
26085
26324
|
const end = source.offsetAt(args.range.end);
|
|
26086
26325
|
const result = compileNeoScriptStrict(
|
|
@@ -26435,7 +26674,9 @@ function sourceMemberSymbol(member, owner, typeIds, source) {
|
|
|
26435
26674
|
};
|
|
26436
26675
|
}
|
|
26437
26676
|
if (member.kind === "property") {
|
|
26438
|
-
const hasSetter =
|
|
26677
|
+
const hasSetter = projectSourceAccessors(source, member.body.range).some(
|
|
26678
|
+
(accessor) => accessor.keyword === "set"
|
|
26679
|
+
);
|
|
26439
26680
|
return {
|
|
26440
26681
|
...common,
|
|
26441
26682
|
kind: "property",
|
|
@@ -27463,6 +27704,8 @@ function validateMemberTypeKind(uri, type, context, name, diagnostics) {
|
|
|
27463
27704
|
function validateMembers(environment, diagnostics) {
|
|
27464
27705
|
for (const ref of environment.interfaces.values()) {
|
|
27465
27706
|
for (const member of ref.declaration.members) {
|
|
27707
|
+
if (member.kind === "property")
|
|
27708
|
+
validatePropertyAccessors(ref, member, diagnostics);
|
|
27466
27709
|
if (member.kind === "field") {
|
|
27467
27710
|
diagnose(
|
|
27468
27711
|
diagnostics,
|
|
@@ -27723,35 +27966,96 @@ function validateClassMemberModifiers(ref, environment, diagnostics) {
|
|
|
27723
27966
|
related(ref.location, "The containing class is declared here.")
|
|
27724
27967
|
);
|
|
27725
27968
|
}
|
|
27726
|
-
if (member.kind === "property"
|
|
27969
|
+
if (member.kind === "property")
|
|
27970
|
+
validatePropertyAccessors(ref, member, diagnostics);
|
|
27971
|
+
if (modifiers.has("abstract") && member.kind === "field" && member.initializer) {
|
|
27972
|
+
diagnose(
|
|
27973
|
+
diagnostics,
|
|
27974
|
+
ref.uri,
|
|
27975
|
+
member.initializer.range,
|
|
27976
|
+
"abstract-member-initializer",
|
|
27977
|
+
`Abstract member '${member.name}' cannot declare a default initializer.`
|
|
27978
|
+
);
|
|
27979
|
+
}
|
|
27980
|
+
}
|
|
27981
|
+
}
|
|
27982
|
+
function validatePropertyAccessors(ref, member, diagnostics) {
|
|
27983
|
+
const accessors = projectSourceAccessors(member.body.text);
|
|
27984
|
+
const isInterface = ref.declaration.kind === "interface";
|
|
27985
|
+
const isAbstract = member.modifiers.includes("abstract");
|
|
27986
|
+
const contract = isInterface || isAbstract;
|
|
27987
|
+
const seen = /* @__PURE__ */ new Set();
|
|
27988
|
+
for (const accessor of accessors) {
|
|
27989
|
+
if (seen.has(accessor.keyword)) {
|
|
27727
27990
|
diagnose(
|
|
27728
27991
|
diagnostics,
|
|
27729
27992
|
ref.uri,
|
|
27730
27993
|
member.nameRange,
|
|
27731
|
-
"
|
|
27732
|
-
`Property '${ref.declaration.name}.${member.name}'
|
|
27994
|
+
"duplicate-property-accessor",
|
|
27995
|
+
`Property '${ref.declaration.name}.${member.name}' declares more than one '${accessor.keyword}' accessor.`
|
|
27733
27996
|
);
|
|
27734
27997
|
}
|
|
27735
|
-
|
|
27998
|
+
seen.add(accessor.keyword);
|
|
27999
|
+
if (accessor.form === "invalid") {
|
|
27736
28000
|
diagnose(
|
|
27737
28001
|
diagnostics,
|
|
27738
28002
|
ref.uri,
|
|
27739
|
-
member.
|
|
27740
|
-
"
|
|
27741
|
-
`
|
|
28003
|
+
member.nameRange,
|
|
28004
|
+
"invalid-property-accessor",
|
|
28005
|
+
`Property '${ref.declaration.name}.${member.name}' accessor '${accessor.keyword}' requires a body or a semicolon for an abstract/interface contract.`
|
|
27742
28006
|
);
|
|
27743
28007
|
}
|
|
27744
|
-
|
|
28008
|
+
const parameters = accessor.parameters;
|
|
28009
|
+
if (parameters !== null) {
|
|
28010
|
+
const actual = parameters.map((token) => token.text);
|
|
28011
|
+
const expected = accessor.keyword === "get" ? "" : `${accessorTypeName(member.type)} value`;
|
|
28012
|
+
const expectedTokens = lex(expected).roots.filter((token) => token.kind !== "eof").map((token) => token.text);
|
|
28013
|
+
if (actual.length !== expectedTokens.length || actual.some((token, index) => token !== expectedTokens[index])) {
|
|
28014
|
+
const signature = accessor.keyword === "get" ? "get" : `set(${accessorTypeName(member.type)} value)`;
|
|
28015
|
+
diagnose(
|
|
28016
|
+
diagnostics,
|
|
28017
|
+
ref.uri,
|
|
28018
|
+
member.nameRange,
|
|
28019
|
+
"property-accessor-signature",
|
|
28020
|
+
`Property '${ref.declaration.name}.${member.name}' requires '${signature}'; accessor parameters must match the property type and use the name 'value' for a setter.`
|
|
28021
|
+
);
|
|
28022
|
+
}
|
|
28023
|
+
}
|
|
28024
|
+
if (contract && (accessor.form === "block" || accessor.form === "expression")) {
|
|
27745
28025
|
diagnose(
|
|
27746
28026
|
diagnostics,
|
|
27747
28027
|
ref.uri,
|
|
27748
28028
|
member.body.range,
|
|
27749
|
-
"abstract-member-body",
|
|
27750
|
-
|
|
28029
|
+
isInterface ? "interface-property-body" : "abstract-member-body",
|
|
28030
|
+
`${isInterface ? "Interface" : "Abstract"} property '${member.name}' can declare accessor contracts but cannot implement an accessor body.`
|
|
27751
28031
|
);
|
|
27752
28032
|
}
|
|
28033
|
+
if (!contract && accessor.keyword === "set" && accessor.body === null) {
|
|
28034
|
+
diagnose(
|
|
28035
|
+
diagnostics,
|
|
28036
|
+
ref.uri,
|
|
28037
|
+
member.nameRange,
|
|
28038
|
+
"concrete-property-setter-body",
|
|
28039
|
+
`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.`
|
|
28040
|
+
);
|
|
28041
|
+
}
|
|
28042
|
+
}
|
|
28043
|
+
if (!contract && !accessors.some(
|
|
28044
|
+
(accessor) => accessor.keyword === "get" && accessor.body !== null
|
|
28045
|
+
)) {
|
|
28046
|
+
diagnose(
|
|
28047
|
+
diagnostics,
|
|
28048
|
+
ref.uri,
|
|
28049
|
+
member.nameRange,
|
|
28050
|
+
"concrete-property-getter-body",
|
|
28051
|
+
`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.`
|
|
28052
|
+
);
|
|
27753
28053
|
}
|
|
27754
28054
|
}
|
|
28055
|
+
function accessorTypeName(type) {
|
|
28056
|
+
const argumentsText = type.typeArguments.length ? `<${type.typeArguments.map(accessorTypeName).join(",")}>` : "";
|
|
28057
|
+
return `${type.name}${argumentsText}${type.nullable ? "?" : ""}`;
|
|
28058
|
+
}
|
|
27755
28059
|
function validateClassOverrides(ref, environment, diagnostics) {
|
|
27756
28060
|
const inherited = inheritedClassMembers(ref, environment);
|
|
27757
28061
|
for (const member of ref.declaration.members) {
|
|
@@ -28144,10 +28448,10 @@ function valueAccessors(member, environment) {
|
|
|
28144
28448
|
};
|
|
28145
28449
|
}
|
|
28146
28450
|
if (member.kind === "function") return { get: false, set: false };
|
|
28147
|
-
|
|
28451
|
+
const accessors = projectSourceAccessors(member.body.text);
|
|
28148
28452
|
return {
|
|
28149
|
-
get:
|
|
28150
|
-
set:
|
|
28453
|
+
get: accessors.some((accessor) => accessor.keyword === "get"),
|
|
28454
|
+
set: accessors.some((accessor) => accessor.keyword === "set")
|
|
28151
28455
|
};
|
|
28152
28456
|
}
|
|
28153
28457
|
function resolvedSourceMemberStorage(owner, member, environment, seen = /* @__PURE__ */ new Set()) {
|
|
@@ -28327,6 +28631,7 @@ var init_project_source_type_checker = __esm({
|
|
|
28327
28631
|
"use strict";
|
|
28328
28632
|
init_language_spec();
|
|
28329
28633
|
init_project_source_ast();
|
|
28634
|
+
init_lexer();
|
|
28330
28635
|
init_project_source_accessors();
|
|
28331
28636
|
init_project_source_identifiers();
|
|
28332
28637
|
BUILTIN_ARITY = /* @__PURE__ */ new Map([
|
|
@@ -29658,7 +29963,7 @@ function projectCompletions(analysis, document, position) {
|
|
|
29658
29963
|
return projectFallbackCompletions(analysis, document, position);
|
|
29659
29964
|
}
|
|
29660
29965
|
function projectAnnotationCompletions(analysis, document, position) {
|
|
29661
|
-
const source =
|
|
29966
|
+
const source = projectSourceText(document);
|
|
29662
29967
|
const offset = source.offsetAt(position);
|
|
29663
29968
|
const word = projectWordRange(document.text, offset);
|
|
29664
29969
|
if (document.text[word.start - 1] !== "@") return null;
|
|
@@ -29686,7 +29991,7 @@ function projectAnnotationNamesAt(analysis, document, position) {
|
|
|
29686
29991
|
if (document.languageId === "neoflow") {
|
|
29687
29992
|
return ["id", "primary", "incomplete"];
|
|
29688
29993
|
}
|
|
29689
|
-
const offset =
|
|
29994
|
+
const offset = projectSourceText(document).offsetAt(position);
|
|
29690
29995
|
const followingDeclaration = /^\s*(class|interface|enum)\b([^{}]*)/.exec(
|
|
29691
29996
|
document.text.slice(offset)
|
|
29692
29997
|
);
|
|
@@ -29738,7 +30043,7 @@ function projectMemberAnnotationNames(member) {
|
|
|
29738
30043
|
return names;
|
|
29739
30044
|
}
|
|
29740
30045
|
function projectContextualEnumCompletions(analysis, document, position) {
|
|
29741
|
-
const source =
|
|
30046
|
+
const source = projectSourceText(document);
|
|
29742
30047
|
const offset = source.offsetAt(position);
|
|
29743
30048
|
const word = projectWordRange(document.text, offset);
|
|
29744
30049
|
if (!isContextualDot(document.text, word.start)) return null;
|
|
@@ -29866,7 +30171,7 @@ function projectAfterNewAt(analysis, document, position) {
|
|
|
29866
30171
|
);
|
|
29867
30172
|
let cursor = tokens.length - 1;
|
|
29868
30173
|
const current = tokens[cursor];
|
|
29869
|
-
const offset =
|
|
30174
|
+
const offset = projectSourceText(document).offsetAt(position);
|
|
29870
30175
|
if (current?.kind === "identifier" && current.text !== "new" && /[A-Za-z0-9_]$/.test(document.text.slice(0, offset))) {
|
|
29871
30176
|
cursor--;
|
|
29872
30177
|
}
|
|
@@ -29899,10 +30204,35 @@ function projectTypeNameAssignable(analysis, sourceName, targetName) {
|
|
|
29899
30204
|
};
|
|
29900
30205
|
return derivesFrom(source.id);
|
|
29901
30206
|
}
|
|
30207
|
+
function projectBodies(analysis, uri) {
|
|
30208
|
+
let byUri = PROJECT_BODIES.get(analysis);
|
|
30209
|
+
if (!byUri) {
|
|
30210
|
+
byUri = /* @__PURE__ */ new Map();
|
|
30211
|
+
for (const body of analysis.bodyContexts) {
|
|
30212
|
+
const bodies = byUri.get(body.uri);
|
|
30213
|
+
if (bodies) bodies.push(body);
|
|
30214
|
+
else byUri.set(body.uri, [body]);
|
|
30215
|
+
}
|
|
30216
|
+
for (const bodies of byUri.values())
|
|
30217
|
+
bodies.sort((a, b) => positionCompare2(a.range.end, b.range.end));
|
|
30218
|
+
PROJECT_BODIES.set(analysis, byUri);
|
|
30219
|
+
}
|
|
30220
|
+
return byUri.get(uri) ?? [];
|
|
30221
|
+
}
|
|
30222
|
+
function rangeItemAt(items, position) {
|
|
30223
|
+
let low = 0;
|
|
30224
|
+
let high = items.length;
|
|
30225
|
+
while (low < high) {
|
|
30226
|
+
const middle = low + high >>> 1;
|
|
30227
|
+
if (positionCompare2(items[middle].range.end, position) < 0)
|
|
30228
|
+
low = middle + 1;
|
|
30229
|
+
else high = middle;
|
|
30230
|
+
}
|
|
30231
|
+
const item = items[low];
|
|
30232
|
+
return item && rangeContains(item.range, position) ? item : void 0;
|
|
30233
|
+
}
|
|
29902
30234
|
function projectBodySnapshotAt(analysis, document, position) {
|
|
29903
|
-
const body = analysis.
|
|
29904
|
-
(candidate) => candidate.uri === document.uri && rangeContains(candidate.range, position)
|
|
29905
|
-
);
|
|
30235
|
+
const body = rangeItemAt(projectBodies(analysis, document.uri), position);
|
|
29906
30236
|
return body ? projectBodySnapshot(analysis, document, body) : null;
|
|
29907
30237
|
}
|
|
29908
30238
|
function projectBodySnapshot(analysis, document, body) {
|
|
@@ -29913,30 +30243,35 @@ function projectBodySnapshot(analysis, document, body) {
|
|
|
29913
30243
|
}
|
|
29914
30244
|
const cached = snapshots.get(body);
|
|
29915
30245
|
if (cached) return cached;
|
|
29916
|
-
const source =
|
|
30246
|
+
const source = projectSourceText(document);
|
|
29917
30247
|
const start = source.offsetAt(body.range.start);
|
|
29918
30248
|
const end = source.offsetAt(body.range.end);
|
|
29919
|
-
const
|
|
29920
|
-
const syntax = analyzeNeoScriptSyntax(
|
|
30249
|
+
const lexed = analysis.documents.get(document.uri)?.syntax ?? lex(document.text);
|
|
30250
|
+
const syntax = analyzeNeoScriptSyntax(
|
|
30251
|
+
document.text,
|
|
30252
|
+
body.context.kind,
|
|
30253
|
+
sliceLexResult(lexed, start, end)
|
|
30254
|
+
);
|
|
29921
30255
|
const context = { ...body.context, project: analysis.project };
|
|
29922
30256
|
const snapshot = {
|
|
29923
30257
|
uri: document.uri,
|
|
30258
|
+
...body.bodyMode === "expression" ? { expressionRange: body.range } : {},
|
|
29924
30259
|
source: syntax.lexed.source,
|
|
29925
30260
|
lexed: syntax.lexed,
|
|
29926
30261
|
parsed: syntax.parsed,
|
|
29927
30262
|
context,
|
|
29928
|
-
project:
|
|
30263
|
+
project: projectBodyIndex(analysis, context)
|
|
29929
30264
|
};
|
|
29930
30265
|
snapshots.set(body, snapshot);
|
|
29931
30266
|
return snapshot;
|
|
29932
30267
|
}
|
|
29933
|
-
function
|
|
29934
|
-
let
|
|
29935
|
-
|
|
29936
|
-
|
|
29937
|
-
|
|
30268
|
+
function projectBodyIndex(analysis, context) {
|
|
30269
|
+
let index = PROJECT_BODY_INDEX_CACHE.get(analysis);
|
|
30270
|
+
if (!index) {
|
|
30271
|
+
index = buildProjectIndexWithBuiltins(context);
|
|
30272
|
+
PROJECT_BODY_INDEX_CACHE.set(analysis, index);
|
|
29938
30273
|
}
|
|
29939
|
-
return
|
|
30274
|
+
return index;
|
|
29940
30275
|
}
|
|
29941
30276
|
function projectWordRange(text, offset) {
|
|
29942
30277
|
let start = offset;
|
|
@@ -29949,9 +30284,9 @@ function isContextualDot(text, wordStart) {
|
|
|
29949
30284
|
while (cursor >= 0 && /\s/.test(text[cursor] ?? "")) cursor--;
|
|
29950
30285
|
const beforeDot = text[cursor];
|
|
29951
30286
|
if (beforeDot !== void 0 && /[A-Za-z0-9_]/.test(beforeDot)) {
|
|
29952
|
-
|
|
29953
|
-
|
|
29954
|
-
)
|
|
30287
|
+
let start = cursor;
|
|
30288
|
+
while (start > 0 && /[A-Za-z0-9_]/.test(text[start - 1])) start--;
|
|
30289
|
+
const precedingWord = text.slice(start, cursor + 1);
|
|
29955
30290
|
return precedingWord === "return" || precedingWord === "case";
|
|
29956
30291
|
}
|
|
29957
30292
|
return beforeDot === void 0 || !/[A-Za-z0-9_\])}]/.test(beforeDot);
|
|
@@ -30012,54 +30347,44 @@ function projectClassBasePositionAt(analysis, document, position) {
|
|
|
30012
30347
|
return true;
|
|
30013
30348
|
}
|
|
30014
30349
|
function sourceTypeAt(document, position) {
|
|
30015
|
-
const contains2 = (
|
|
30016
|
-
for (const argument2 of
|
|
30350
|
+
const contains2 = (type2) => {
|
|
30351
|
+
for (const argument2 of type2.typeArguments) {
|
|
30017
30352
|
const nested = contains2(argument2);
|
|
30018
30353
|
if (nested) return nested;
|
|
30019
30354
|
}
|
|
30020
|
-
return rangeContains(
|
|
30355
|
+
return rangeContains(type2.range, position) ? type2 : null;
|
|
30021
30356
|
};
|
|
30022
|
-
|
|
30023
|
-
|
|
30024
|
-
|
|
30025
|
-
|
|
30026
|
-
|
|
30027
|
-
|
|
30028
|
-
|
|
30029
|
-
|
|
30030
|
-
|
|
30031
|
-
|
|
30032
|
-
if (match) return match;
|
|
30033
|
-
continue;
|
|
30034
|
-
}
|
|
30035
|
-
if (declaration.kind === "enum") continue;
|
|
30036
|
-
for (const base of declaration.baseTypes) {
|
|
30037
|
-
const match = contains2(base);
|
|
30038
|
-
if (match) return match;
|
|
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;
|
|
30357
|
+
let types = SOURCE_TYPES.get(document);
|
|
30358
|
+
if (!types) {
|
|
30359
|
+
types = [];
|
|
30360
|
+
const parameters = (items) => {
|
|
30361
|
+
for (const parameter4 of items ?? []) types.push(parameter4.type);
|
|
30362
|
+
};
|
|
30363
|
+
for (const declaration of document.declarations) {
|
|
30364
|
+
if (declaration.kind === "global") {
|
|
30365
|
+
types.push(declaration.type);
|
|
30366
|
+
continue;
|
|
30047
30367
|
}
|
|
30048
|
-
|
|
30049
|
-
|
|
30050
|
-
|
|
30368
|
+
if (declaration.kind === "enum") continue;
|
|
30369
|
+
types.push(...declaration.baseTypes);
|
|
30370
|
+
if (declaration.kind === "class") {
|
|
30371
|
+
parameters(declaration.headerParameters);
|
|
30372
|
+
for (const generic of declaration.genericParameters) {
|
|
30373
|
+
if (generic.constraint) types.push(generic.constraint);
|
|
30374
|
+
}
|
|
30375
|
+
for (const constructor2 of declaration.constructors)
|
|
30376
|
+
parameters(constructor2.parameters);
|
|
30051
30377
|
}
|
|
30052
|
-
|
|
30053
|
-
|
|
30054
|
-
|
|
30055
|
-
if (memberType2) return memberType2;
|
|
30056
|
-
if (member.kind === "function") {
|
|
30057
|
-
const match = parameterType(member.parameters);
|
|
30058
|
-
if (match) return match;
|
|
30378
|
+
for (const member of declaration.members) {
|
|
30379
|
+
types.push(member.type);
|
|
30380
|
+
if (member.kind === "function") parameters(member.parameters);
|
|
30059
30381
|
}
|
|
30060
30382
|
}
|
|
30383
|
+
types.sort((a, b) => positionCompare2(a.range.end, b.range.end));
|
|
30384
|
+
SOURCE_TYPES.set(document, types);
|
|
30061
30385
|
}
|
|
30062
|
-
|
|
30386
|
+
const type = rangeItemAt(types, position);
|
|
30387
|
+
return type ? contains2(type) : null;
|
|
30063
30388
|
}
|
|
30064
30389
|
function projectMemberCompletions(analysis, document, position) {
|
|
30065
30390
|
const owner = projectMemberCompletionOwnerToken(document, position);
|
|
@@ -30436,6 +30761,7 @@ function projectCompletionKind(symbol) {
|
|
|
30436
30761
|
case "constructor":
|
|
30437
30762
|
return "method";
|
|
30438
30763
|
case "parameter":
|
|
30764
|
+
case "local":
|
|
30439
30765
|
case "flowBinding":
|
|
30440
30766
|
case "graphChild":
|
|
30441
30767
|
case "global":
|
|
@@ -30677,7 +31003,7 @@ function requiredDestinationEdit(sourceDocument, document, initializer, destinat
|
|
|
30677
31003
|
};
|
|
30678
31004
|
}
|
|
30679
31005
|
if (initializer.body.kind !== "block") return null;
|
|
30680
|
-
const source =
|
|
31006
|
+
const source = projectSourceText(document);
|
|
30681
31007
|
const start = source.offsetAt(initializer.body.range.start);
|
|
30682
31008
|
const end = source.offsetAt(initializer.body.range.end);
|
|
30683
31009
|
const tokens = sourceDocument.syntax.tokens;
|
|
@@ -30756,9 +31082,7 @@ function projectSignatureHelp(analysis, document, position) {
|
|
|
30756
31082
|
};
|
|
30757
31083
|
}
|
|
30758
31084
|
function projectInlayHints(analysis, document, range2) {
|
|
30759
|
-
const bodyContexts = analysis.
|
|
30760
|
-
(body) => body.uri === document.uri
|
|
30761
|
-
);
|
|
31085
|
+
const bodyContexts = projectBodies(analysis, document.uri);
|
|
30762
31086
|
const tokens = projectDocumentTokens(analysis, document).filter(
|
|
30763
31087
|
(token) => token.kind !== "comment" && token.kind !== "eof"
|
|
30764
31088
|
);
|
|
@@ -30767,19 +31091,28 @@ function projectInlayHints(analysis, document, range2) {
|
|
|
30767
31091
|
document
|
|
30768
31092
|
);
|
|
30769
31093
|
const hints = [];
|
|
31094
|
+
const delimiterEnds = projectDelimiterEnds(tokens);
|
|
30770
31095
|
for (let index = 0; index < tokens.length - 1; index++) {
|
|
30771
31096
|
const callee = tokens[index];
|
|
30772
31097
|
const open = tokens[index + 1];
|
|
30773
31098
|
if (!callee || callee.kind !== "identifier" && callee.kind !== "type") {
|
|
30774
31099
|
continue;
|
|
30775
31100
|
}
|
|
30776
|
-
if (bodyContexts
|
|
31101
|
+
if (rangeItemAt(bodyContexts, callee.range.start)) {
|
|
30777
31102
|
continue;
|
|
30778
31103
|
}
|
|
30779
31104
|
if (!open || open.text !== "(") continue;
|
|
30780
31105
|
const beforeCallee = tokens[index - 1];
|
|
30781
31106
|
if (beforeCallee?.text === "@") continue;
|
|
30782
31107
|
if (declarationNames.has(positionKey(callee.range.start))) continue;
|
|
31108
|
+
if (range2 && positionCompare2(callee.range.start, range2.end) > 0) break;
|
|
31109
|
+
const callArguments2 = projectCallArguments(
|
|
31110
|
+
tokens,
|
|
31111
|
+
index + 1,
|
|
31112
|
+
delimiterEnds
|
|
31113
|
+
);
|
|
31114
|
+
if (range2 && !callArguments2.some((argument2) => rangeContains(range2, argument2.start)))
|
|
31115
|
+
continue;
|
|
30783
31116
|
const parameterNames = projectCallParameterNames(
|
|
30784
31117
|
analysis,
|
|
30785
31118
|
document,
|
|
@@ -30787,7 +31120,6 @@ function projectInlayHints(analysis, document, range2) {
|
|
|
30787
31120
|
beforeCallee
|
|
30788
31121
|
);
|
|
30789
31122
|
if (!parameterNames) continue;
|
|
30790
|
-
const callArguments2 = projectCallArguments(tokens, index + 1);
|
|
30791
31123
|
for (let argument2 = 0; argument2 < callArguments2.length; argument2++) {
|
|
30792
31124
|
const argumentToken = callArguments2[argument2];
|
|
30793
31125
|
if (!argumentToken || argumentToken.named) continue;
|
|
@@ -30806,6 +31138,8 @@ function projectInlayHints(analysis, document, range2) {
|
|
|
30806
31138
|
}
|
|
30807
31139
|
}
|
|
30808
31140
|
for (const body of bodyContexts) {
|
|
31141
|
+
if (range2 && (positionCompare2(body.range.end, range2.start) < 0 || positionCompare2(body.range.start, range2.end) > 0))
|
|
31142
|
+
continue;
|
|
30809
31143
|
const snapshot = projectBodySnapshot(analysis, document, body);
|
|
30810
31144
|
hints.push(
|
|
30811
31145
|
...inlayHints(snapshot, range2).filter(
|
|
@@ -30850,19 +31184,31 @@ function projectCallParameterNames(analysis, document, callee, beforeCallee) {
|
|
|
30850
31184
|
return names.size === 1 && name ? name : null;
|
|
30851
31185
|
});
|
|
30852
31186
|
}
|
|
30853
|
-
function
|
|
31187
|
+
function projectDelimiterEnds(tokens) {
|
|
31188
|
+
const ends = /* @__PURE__ */ new Map();
|
|
31189
|
+
const stack = [];
|
|
31190
|
+
for (let index = 0; index < tokens.length; index++) {
|
|
31191
|
+
const text = tokens[index].text;
|
|
31192
|
+
if (text === "(" || text === "[" || text === "{") stack.push(index);
|
|
31193
|
+
else if (text === ")" || text === "]" || text === "}") {
|
|
31194
|
+
const open = stack.pop();
|
|
31195
|
+
if (open !== void 0) ends.set(open, index);
|
|
31196
|
+
}
|
|
31197
|
+
}
|
|
31198
|
+
return ends;
|
|
31199
|
+
}
|
|
31200
|
+
function projectCallArguments(tokens, openIndex, delimiterEnds) {
|
|
30854
31201
|
const result = [];
|
|
30855
|
-
let depth = 0;
|
|
30856
31202
|
let atArgumentStart = true;
|
|
30857
31203
|
for (let index = openIndex + 1; index < tokens.length; index++) {
|
|
30858
31204
|
const token = tokens[index];
|
|
30859
31205
|
if (!token) break;
|
|
30860
|
-
if (
|
|
30861
|
-
if (
|
|
31206
|
+
if (token.text === ")") break;
|
|
31207
|
+
if (token.text === ",") {
|
|
30862
31208
|
atArgumentStart = true;
|
|
30863
31209
|
continue;
|
|
30864
31210
|
}
|
|
30865
|
-
if (
|
|
31211
|
+
if (atArgumentStart) {
|
|
30866
31212
|
result.push({
|
|
30867
31213
|
start: token.range.start,
|
|
30868
31214
|
named: token.kind === "identifier" && tokens[index + 1]?.text === ":",
|
|
@@ -30871,9 +31217,7 @@ function projectCallArguments(tokens, openIndex) {
|
|
|
30871
31217
|
atArgumentStart = false;
|
|
30872
31218
|
}
|
|
30873
31219
|
if (token.text === "(" || token.text === "[" || token.text === "{") {
|
|
30874
|
-
|
|
30875
|
-
} else if (token.text === ")" || token.text === "]" || token.text === "}") {
|
|
30876
|
-
if (depth > 0) depth--;
|
|
31220
|
+
index = delimiterEnds.get(index) ?? tokens.length;
|
|
30877
31221
|
}
|
|
30878
31222
|
}
|
|
30879
31223
|
return result;
|
|
@@ -30988,6 +31332,7 @@ function projectSemanticTokenType(symbol) {
|
|
|
30988
31332
|
return symbol.callable ? "method" : "property";
|
|
30989
31333
|
case "constructor":
|
|
30990
31334
|
return "method";
|
|
31335
|
+
case "local":
|
|
30991
31336
|
case "graphChild":
|
|
30992
31337
|
case "flowBinding":
|
|
30993
31338
|
case "global":
|
|
@@ -30998,9 +31343,13 @@ function symbolRangeKey(range2) {
|
|
|
30998
31343
|
return `${range2.start.line}:${range2.start.character}-${range2.end.line}:${range2.end.character}`;
|
|
30999
31344
|
}
|
|
31000
31345
|
function buildProjectSymbolIndex(symbols) {
|
|
31346
|
+
const cached = PROJECT_SYMBOL_INDEX_CACHE.get(symbols);
|
|
31347
|
+
if (cached) return cached;
|
|
31001
31348
|
const byLocation = /* @__PURE__ */ new Map();
|
|
31002
31349
|
const byName = /* @__PURE__ */ new Map();
|
|
31350
|
+
const byId = /* @__PURE__ */ new Map();
|
|
31003
31351
|
for (const symbol of symbols) {
|
|
31352
|
+
if (symbol.id !== null) byId.set(symbol.id, symbol);
|
|
31004
31353
|
let uriBucket = byLocation.get(symbol.location.uri);
|
|
31005
31354
|
if (!uriBucket) {
|
|
31006
31355
|
uriBucket = /* @__PURE__ */ new Map();
|
|
@@ -31014,7 +31363,9 @@ function buildProjectSymbolIndex(symbols) {
|
|
|
31014
31363
|
if (named) named.push(symbol);
|
|
31015
31364
|
else byName.set(symbol.name, [symbol]);
|
|
31016
31365
|
}
|
|
31017
|
-
|
|
31366
|
+
const index = { byLocation, byName, byId };
|
|
31367
|
+
PROJECT_SYMBOL_INDEX_CACHE.set(symbols, index);
|
|
31368
|
+
return index;
|
|
31018
31369
|
}
|
|
31019
31370
|
function symbolsDeclaredAt(index, uri, range2) {
|
|
31020
31371
|
return index.byLocation.get(uri)?.get(symbolRangeKey(range2)) ?? [];
|
|
@@ -31022,16 +31373,14 @@ function symbolsDeclaredAt(index, uri, range2) {
|
|
|
31022
31373
|
function projectSemanticTokens(document, analysis) {
|
|
31023
31374
|
const index = buildProjectSymbolIndex(analysis.symbols);
|
|
31024
31375
|
const tokens = projectTokens(document);
|
|
31025
|
-
const bodyContexts = analysis.
|
|
31026
|
-
(body) => body.uri === document.uri
|
|
31027
|
-
);
|
|
31376
|
+
const bodyContexts = projectBodies(analysis, document.uri);
|
|
31028
31377
|
const result = tokens.flatMap((token, tokenIndex) => {
|
|
31029
31378
|
if (token.kind === "eof" || token.kind === "error") return [];
|
|
31030
|
-
if (bodyContexts
|
|
31379
|
+
if (rangeItemAt(bodyContexts, token.range.start)) {
|
|
31031
31380
|
return [];
|
|
31032
31381
|
}
|
|
31033
31382
|
const declaration = symbolsDeclaredAt(index, document.uri, token.range)[0];
|
|
31034
|
-
const resolved = isProjectNameToken(token) ? indexedProjectSymbolAt(analysis, document, token.range.start, index)?.symbol : void 0;
|
|
31383
|
+
const resolved = !declaration && isProjectNameToken(token) ? indexedProjectSymbolAt(analysis, document, token.range.start, index)?.symbol : void 0;
|
|
31035
31384
|
let type;
|
|
31036
31385
|
if (declaration) {
|
|
31037
31386
|
type = projectSemanticTokenType(declaration);
|
|
@@ -31078,32 +31427,40 @@ function isProjectContextualKeyword(tokens, tokenIndex) {
|
|
|
31078
31427
|
if (token?.text !== "new") return false;
|
|
31079
31428
|
return next?.text === "(" || next?.text === "{" || next?.kind === "identifier" || next?.kind === "type";
|
|
31080
31429
|
}
|
|
31081
|
-
function projectSymbolAt(analysis, document, position) {
|
|
31082
|
-
return indexedProjectSymbolAt(
|
|
31083
|
-
analysis,
|
|
31084
|
-
document,
|
|
31085
|
-
position,
|
|
31086
|
-
buildProjectSymbolIndex(analysis.symbols)
|
|
31087
|
-
);
|
|
31430
|
+
function projectSymbolAt(analysis, document, position, index = buildProjectSymbolIndex(analysis.symbols)) {
|
|
31431
|
+
return indexedProjectSymbolAt(analysis, document, position, index);
|
|
31088
31432
|
}
|
|
31089
31433
|
function indexedProjectSymbolAt(analysis, document, position, index) {
|
|
31090
|
-
const
|
|
31434
|
+
const tokenIndex = projectTokenIndexAt(document, position);
|
|
31435
|
+
const sourceTokens = projectTokens(document);
|
|
31436
|
+
const token = sourceTokens[tokenIndex];
|
|
31091
31437
|
if (!isProjectNameToken(token)) return null;
|
|
31092
31438
|
const body = projectBodySnapshotAt(analysis, document, position);
|
|
31093
31439
|
if (body) {
|
|
31440
|
+
const local = localSymbolAtPosition(body, position);
|
|
31441
|
+
if (local?.location) {
|
|
31442
|
+
return {
|
|
31443
|
+
token,
|
|
31444
|
+
symbol: {
|
|
31445
|
+
kind: "local",
|
|
31446
|
+
id: local.id,
|
|
31447
|
+
name: local.name,
|
|
31448
|
+
location: local.location
|
|
31449
|
+
}
|
|
31450
|
+
};
|
|
31451
|
+
}
|
|
31094
31452
|
const reference2 = referenceAtPosition(body, position);
|
|
31095
31453
|
const symbolId = reference2 ? resolveReferenceSymbolId(body, reference2) : null;
|
|
31096
|
-
const
|
|
31454
|
+
const executable = symbolId ? body.project.symbolById.get(symbolId) : void 0;
|
|
31455
|
+
const location3 = executable?.selectionLocation ?? executable?.location;
|
|
31456
|
+
const located = location3 ? symbolsDeclaredAt(index, location3.uri, location3.range)[0] : void 0;
|
|
31457
|
+
const symbol = located ?? (symbolId ? index.byId.get(symbolId) : void 0);
|
|
31097
31458
|
if (symbol) return { token, symbol };
|
|
31098
31459
|
}
|
|
31099
31460
|
const exact = symbolsDeclaredAt(index, document.uri, token.range);
|
|
31100
31461
|
if (exact.length === 1) return { token, symbol: exact[0] };
|
|
31101
31462
|
const candidates = index.byName.get(token.text) ?? [];
|
|
31102
31463
|
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
31464
|
const source = analysis.documents.get(document.uri);
|
|
31108
31465
|
const typePosition = source && sourceTypeAt(source, token.range.start);
|
|
31109
31466
|
if (typePosition || sourceTokens[tokenIndex - 1]?.text === "new") {
|
|
@@ -31275,6 +31632,7 @@ function projectSymbolTypeName(symbol) {
|
|
|
31275
31632
|
return symbol.name;
|
|
31276
31633
|
case "member":
|
|
31277
31634
|
case "parameter":
|
|
31635
|
+
case "local":
|
|
31278
31636
|
case "flowBinding":
|
|
31279
31637
|
case "global":
|
|
31280
31638
|
return symbol.detail ?? null;
|
|
@@ -31291,13 +31649,6 @@ function declarationContaining(document, position) {
|
|
|
31291
31649
|
(declaration) => positionCompare2(declaration.range.start, position) <= 0 && positionCompare2(position, declaration.range.end) <= 0
|
|
31292
31650
|
);
|
|
31293
31651
|
}
|
|
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
31652
|
function tokensBeforePosition(tokens, position) {
|
|
31302
31653
|
return tokens.filter(
|
|
31303
31654
|
(token) => token.kind !== "comment" && token.kind !== "eof" && positionCompare2(token.range.start, position) < 0
|
|
@@ -31391,31 +31742,67 @@ function contextualConstructorType(analysis, document, position) {
|
|
|
31391
31742
|
function initializerRootAt(analysis, document, position) {
|
|
31392
31743
|
const source = analysis.documents.get(document.uri);
|
|
31393
31744
|
if (!source) return null;
|
|
31394
|
-
|
|
31395
|
-
|
|
31396
|
-
|
|
31397
|
-
|
|
31745
|
+
let roots = INITIALIZER_ROOTS.get(source);
|
|
31746
|
+
if (!roots) {
|
|
31747
|
+
roots = [];
|
|
31748
|
+
for (const declaration of source.declarations) {
|
|
31749
|
+
if (declaration.kind === "global") {
|
|
31750
|
+
roots.push({
|
|
31398
31751
|
type: declaration.type,
|
|
31399
31752
|
range: declaration.initializer.range
|
|
31400
|
-
};
|
|
31753
|
+
});
|
|
31754
|
+
continue;
|
|
31401
31755
|
}
|
|
31402
|
-
continue;
|
|
31403
|
-
|
|
31404
|
-
|
|
31405
|
-
|
|
31406
|
-
|
|
31407
|
-
return { type: member.type, range: member.initializer.range };
|
|
31756
|
+
if (declaration.kind === "enum") continue;
|
|
31757
|
+
for (const member of declaration.members) {
|
|
31758
|
+
if (member.kind === "field" && member.initializer) {
|
|
31759
|
+
roots.push({ type: member.type, range: member.initializer.range });
|
|
31760
|
+
}
|
|
31408
31761
|
}
|
|
31409
31762
|
}
|
|
31763
|
+
roots.sort((a, b) => positionCompare2(a.range.end, b.range.end));
|
|
31764
|
+
INITIALIZER_ROOTS.set(source, roots);
|
|
31410
31765
|
}
|
|
31411
|
-
return null;
|
|
31766
|
+
return rangeItemAt(roots, position) ?? null;
|
|
31412
31767
|
}
|
|
31413
31768
|
function constructionSiteAt(analysis, document, position) {
|
|
31414
31769
|
const root = initializerRootAt(analysis, document, position);
|
|
31415
31770
|
if (!root) return null;
|
|
31416
|
-
|
|
31417
|
-
|
|
31418
|
-
|
|
31771
|
+
let documents = CONSTRUCTION_SITE_CACHE.get(analysis);
|
|
31772
|
+
if (!documents) {
|
|
31773
|
+
documents = /* @__PURE__ */ new WeakMap();
|
|
31774
|
+
CONSTRUCTION_SITE_CACHE.set(analysis, documents);
|
|
31775
|
+
}
|
|
31776
|
+
let roots = documents.get(document);
|
|
31777
|
+
if (!roots) {
|
|
31778
|
+
roots = /* @__PURE__ */ new Map();
|
|
31779
|
+
documents.set(document, roots);
|
|
31780
|
+
}
|
|
31781
|
+
const key = positionKey(root.range.start);
|
|
31782
|
+
let sites = roots.get(key);
|
|
31783
|
+
if (!sites) {
|
|
31784
|
+
sites = indexConstructionSites(analysis, document, root);
|
|
31785
|
+
roots.set(key, sites);
|
|
31786
|
+
}
|
|
31787
|
+
let low = 0;
|
|
31788
|
+
let high = sites.length;
|
|
31789
|
+
while (low < high) {
|
|
31790
|
+
const middle = low + high >>> 1;
|
|
31791
|
+
if (positionCompare2(sites[middle].position, position) < 0)
|
|
31792
|
+
low = middle + 1;
|
|
31793
|
+
else high = middle;
|
|
31794
|
+
}
|
|
31795
|
+
return sites[Math.max(0, low - 1)].site;
|
|
31796
|
+
}
|
|
31797
|
+
function indexConstructionSites(analysis, document, root) {
|
|
31798
|
+
const allTokens = projectTokens(document);
|
|
31799
|
+
let start = Math.max(0, projectTokenIndexAt(document, root.range.start));
|
|
31800
|
+
while (start < allTokens.length && positionCompare2(allTokens[start].range.start, root.range.start) < 0)
|
|
31801
|
+
start++;
|
|
31802
|
+
let end = start;
|
|
31803
|
+
while (end < allTokens.length && positionCompare2(allTokens[end].range.start, root.range.end) <= 0)
|
|
31804
|
+
end++;
|
|
31805
|
+
const tokens = allTokens.slice(start, end).filter((token) => token.kind !== "comment" && token.kind !== "eof");
|
|
31419
31806
|
const stack = [];
|
|
31420
31807
|
const expectedType = () => {
|
|
31421
31808
|
const frame = stack.at(-1);
|
|
@@ -31432,11 +31819,38 @@ function constructionSiteAt(analysis, document, position) {
|
|
|
31432
31819
|
return null;
|
|
31433
31820
|
}
|
|
31434
31821
|
};
|
|
31822
|
+
const objects = [];
|
|
31823
|
+
const snapshot = () => {
|
|
31824
|
+
const expected = expectedType();
|
|
31825
|
+
const innermost = stack.at(-1);
|
|
31826
|
+
const directly = innermost?.kind === "object" ? innermost : null;
|
|
31827
|
+
const keys = directly?.keys ?? [];
|
|
31828
|
+
const keyCount = keys.length;
|
|
31829
|
+
return {
|
|
31830
|
+
expectedType: expected,
|
|
31831
|
+
expectedTypeName: expected?.name ?? null,
|
|
31832
|
+
enclosingTypeName: objects.at(-1)?.typeName ?? null,
|
|
31833
|
+
initializerTypeName: directly?.typeName ?? null,
|
|
31834
|
+
get initializerKeys() {
|
|
31835
|
+
return keys.slice(0, keyCount);
|
|
31836
|
+
},
|
|
31837
|
+
atInitializerKey: directly?.atKey ?? false
|
|
31838
|
+
};
|
|
31839
|
+
};
|
|
31840
|
+
const sites = [];
|
|
31841
|
+
let previousPosition = root.range.start;
|
|
31842
|
+
const pop = () => {
|
|
31843
|
+
const frame = stack.pop();
|
|
31844
|
+
if (frame?.kind === "object") objects.pop();
|
|
31845
|
+
return frame;
|
|
31846
|
+
};
|
|
31435
31847
|
let sawNew = false;
|
|
31436
31848
|
let pendingNewTypeName = null;
|
|
31437
31849
|
let closedConstructorTypeName = null;
|
|
31438
31850
|
for (let index = 0; index < tokens.length; index++) {
|
|
31851
|
+
sites.push({ position: previousPosition, site: snapshot() });
|
|
31439
31852
|
const token = tokens[index];
|
|
31853
|
+
previousPosition = token.range.start;
|
|
31440
31854
|
if (token.text === "@") {
|
|
31441
31855
|
if ((tokens[index + 1]?.kind === "identifier" || tokens[index + 1]?.kind === "keyword") && tokens[index + 2]?.text === "(") {
|
|
31442
31856
|
let depth = 0;
|
|
@@ -31470,13 +31884,15 @@ function constructionSiteAt(analysis, document, position) {
|
|
|
31470
31884
|
}
|
|
31471
31885
|
if (token.text === "{") {
|
|
31472
31886
|
if (sawNew || closedConstructorTypeName !== null) {
|
|
31473
|
-
|
|
31887
|
+
const frame2 = {
|
|
31474
31888
|
kind: "object",
|
|
31475
31889
|
typeName: pendingNewTypeName ?? closedConstructorTypeName,
|
|
31476
31890
|
slotType: null,
|
|
31477
31891
|
keys: [],
|
|
31478
31892
|
atKey: true
|
|
31479
|
-
}
|
|
31893
|
+
};
|
|
31894
|
+
stack.push(frame2);
|
|
31895
|
+
objects.push(frame2);
|
|
31480
31896
|
sawNew = false;
|
|
31481
31897
|
pendingNewTypeName = null;
|
|
31482
31898
|
} else {
|
|
@@ -31519,12 +31935,12 @@ function constructionSiteAt(analysis, document, position) {
|
|
|
31519
31935
|
continue;
|
|
31520
31936
|
}
|
|
31521
31937
|
if (token.text === ")") {
|
|
31522
|
-
const frame2 =
|
|
31938
|
+
const frame2 = pop();
|
|
31523
31939
|
closedConstructorTypeName = frame2?.kind === "call" ? frame2.typeName : null;
|
|
31524
31940
|
continue;
|
|
31525
31941
|
}
|
|
31526
31942
|
if (token.text === "}" || token.text === "]") {
|
|
31527
|
-
|
|
31943
|
+
pop();
|
|
31528
31944
|
closedConstructorTypeName = null;
|
|
31529
31945
|
continue;
|
|
31530
31946
|
}
|
|
@@ -31555,19 +31971,8 @@ function constructionSiteAt(analysis, document, position) {
|
|
|
31555
31971
|
}
|
|
31556
31972
|
}
|
|
31557
31973
|
}
|
|
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
|
-
};
|
|
31974
|
+
sites.push({ position: previousPosition, site: snapshot() });
|
|
31975
|
+
return sites;
|
|
31571
31976
|
}
|
|
31572
31977
|
function collectionElementType(type) {
|
|
31573
31978
|
if (!type) return null;
|
|
@@ -31582,13 +31987,31 @@ function constructorArgumentType(analysis, frame) {
|
|
|
31582
31987
|
if (!declaration || declaration.kind === "global" || declaration.kind === "enum") {
|
|
31583
31988
|
return null;
|
|
31584
31989
|
}
|
|
31585
|
-
const fields = declaration
|
|
31586
|
-
(member) => member.kind === "field" && !member.modifiers.includes("static") && !member.modifiers.includes("readonly")
|
|
31587
|
-
);
|
|
31990
|
+
const fields = declarationFields(declaration);
|
|
31588
31991
|
if (frame.argumentName !== null) {
|
|
31589
|
-
return fields.
|
|
31992
|
+
return fields.assignableByName.get(frame.argumentName)?.type ?? null;
|
|
31590
31993
|
}
|
|
31591
|
-
return fields[frame.argumentIndex]?.type ?? null;
|
|
31994
|
+
return fields.assignable[frame.argumentIndex]?.type ?? null;
|
|
31995
|
+
}
|
|
31996
|
+
function declarationFields(declaration) {
|
|
31997
|
+
let fields = DECLARATION_FIELDS.get(declaration);
|
|
31998
|
+
if (!fields) {
|
|
31999
|
+
const byName = /* @__PURE__ */ new Map();
|
|
32000
|
+
const assignable = [];
|
|
32001
|
+
const assignableByName = /* @__PURE__ */ new Map();
|
|
32002
|
+
for (const member of declaration.members) {
|
|
32003
|
+
if (member.kind !== "field") continue;
|
|
32004
|
+
if (!byName.has(member.name)) byName.set(member.name, member);
|
|
32005
|
+
if (member.modifiers.includes("static") || member.modifiers.includes("readonly"))
|
|
32006
|
+
continue;
|
|
32007
|
+
assignable.push(member);
|
|
32008
|
+
if (!assignableByName.has(member.name))
|
|
32009
|
+
assignableByName.set(member.name, member);
|
|
32010
|
+
}
|
|
32011
|
+
fields = { byName, assignable, assignableByName };
|
|
32012
|
+
DECLARATION_FIELDS.set(declaration, fields);
|
|
32013
|
+
}
|
|
32014
|
+
return fields;
|
|
31592
32015
|
}
|
|
31593
32016
|
function declaredFieldType(analysis, typeName, fieldName) {
|
|
31594
32017
|
let current = typeName;
|
|
@@ -31599,9 +32022,7 @@ function declaredFieldType(analysis, typeName, fieldName) {
|
|
|
31599
32022
|
if (!declaration || declaration.kind === "global" || declaration.kind === "enum") {
|
|
31600
32023
|
return null;
|
|
31601
32024
|
}
|
|
31602
|
-
const member = declaration.
|
|
31603
|
-
(candidate) => candidate.kind === "field" && candidate.name === fieldName
|
|
31604
|
-
);
|
|
32025
|
+
const member = declarationFields(declaration).byName.get(fieldName);
|
|
31605
32026
|
if (member) return member.type;
|
|
31606
32027
|
current = declaration.kind === "class" ? resolvableBaseClassName(analysis, declaration) : null;
|
|
31607
32028
|
}
|
|
@@ -31615,13 +32036,19 @@ function resolvableBaseClassName(analysis, declaration) {
|
|
|
31615
32036
|
return null;
|
|
31616
32037
|
}
|
|
31617
32038
|
function findTypeDeclaration(analysis, name) {
|
|
31618
|
-
|
|
31619
|
-
|
|
31620
|
-
|
|
31621
|
-
)
|
|
31622
|
-
|
|
32039
|
+
let declarations = PROJECT_TYPE_DECLARATIONS.get(analysis);
|
|
32040
|
+
if (!declarations) {
|
|
32041
|
+
declarations = /* @__PURE__ */ new Map();
|
|
32042
|
+
for (const document of analysis.documents.values()) {
|
|
32043
|
+
for (const declaration of document.declarations) {
|
|
32044
|
+
if (declaration.kind !== "global" && !declarations.has(declaration.name)) {
|
|
32045
|
+
declarations.set(declaration.name, declaration);
|
|
32046
|
+
}
|
|
32047
|
+
}
|
|
32048
|
+
}
|
|
32049
|
+
PROJECT_TYPE_DECLARATIONS.set(analysis, declarations);
|
|
31623
32050
|
}
|
|
31624
|
-
return
|
|
32051
|
+
return declarations.get(name);
|
|
31625
32052
|
}
|
|
31626
32053
|
function constructorParameterLabel(parameter4) {
|
|
31627
32054
|
return `${parameter4.type} ${parameter4.name}${parameterDefaultSuffix2(parameter4)}`;
|
|
@@ -31738,21 +32165,27 @@ function graphConstructorParameters(typeName) {
|
|
|
31738
32165
|
}
|
|
31739
32166
|
}
|
|
31740
32167
|
function projectFunctionsNamed(analysis, name) {
|
|
31741
|
-
|
|
31742
|
-
|
|
31743
|
-
|
|
31744
|
-
|
|
31745
|
-
|
|
31746
|
-
|
|
31747
|
-
|
|
31748
|
-
|
|
32168
|
+
let byName = PROJECT_FUNCTIONS.get(analysis);
|
|
32169
|
+
if (!byName) {
|
|
32170
|
+
byName = /* @__PURE__ */ new Map();
|
|
32171
|
+
for (const document of analysis.documents.values()) {
|
|
32172
|
+
for (const declaration of document.declarations) {
|
|
32173
|
+
if (declaration.kind === "global" || declaration.kind === "enum")
|
|
32174
|
+
continue;
|
|
32175
|
+
for (const member of declaration.members) {
|
|
32176
|
+
if (member.kind !== "function") continue;
|
|
32177
|
+
const entry = { owner: declaration.name, member };
|
|
32178
|
+
const named = byName.get(member.name);
|
|
32179
|
+
if (named) named.push(entry);
|
|
32180
|
+
else byName.set(member.name, [entry]);
|
|
31749
32181
|
}
|
|
31750
32182
|
}
|
|
31751
32183
|
}
|
|
32184
|
+
PROJECT_FUNCTIONS.set(analysis, byName);
|
|
31752
32185
|
}
|
|
31753
|
-
return
|
|
32186
|
+
return byName.get(name) ?? [];
|
|
31754
32187
|
}
|
|
31755
|
-
var PROJECT_BODY_SNAPSHOT_CACHE, CONSTRUCTION_INDEX_CACHE, VARIANT_SCOPE_INDEX_CACHE;
|
|
32188
|
+
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
32189
|
var init_project_source_language_features = __esm({
|
|
31757
32190
|
"../packages/neoscript-language/src/project-source-language-features.ts"() {
|
|
31758
32191
|
"use strict";
|
|
@@ -31766,11 +32199,19 @@ var init_project_source_language_features = __esm({
|
|
|
31766
32199
|
init_project_source_settlement();
|
|
31767
32200
|
init_project_source_tokens();
|
|
31768
32201
|
init_quick_fixes();
|
|
31769
|
-
init_source_text();
|
|
31770
32202
|
init_syntax();
|
|
32203
|
+
PROJECT_BODIES = /* @__PURE__ */ new WeakMap();
|
|
32204
|
+
PROJECT_BODY_INDEX_CACHE = /* @__PURE__ */ new WeakMap();
|
|
31771
32205
|
PROJECT_BODY_SNAPSHOT_CACHE = /* @__PURE__ */ new WeakMap();
|
|
32206
|
+
SOURCE_TYPES = /* @__PURE__ */ new WeakMap();
|
|
31772
32207
|
CONSTRUCTION_INDEX_CACHE = /* @__PURE__ */ new WeakMap();
|
|
31773
32208
|
VARIANT_SCOPE_INDEX_CACHE = /* @__PURE__ */ new WeakMap();
|
|
32209
|
+
PROJECT_SYMBOL_INDEX_CACHE = /* @__PURE__ */ new WeakMap();
|
|
32210
|
+
INITIALIZER_ROOTS = /* @__PURE__ */ new WeakMap();
|
|
32211
|
+
CONSTRUCTION_SITE_CACHE = /* @__PURE__ */ new WeakMap();
|
|
32212
|
+
DECLARATION_FIELDS = /* @__PURE__ */ new WeakMap();
|
|
32213
|
+
PROJECT_TYPE_DECLARATIONS = /* @__PURE__ */ new WeakMap();
|
|
32214
|
+
PROJECT_FUNCTIONS = /* @__PURE__ */ new WeakMap();
|
|
31774
32215
|
}
|
|
31775
32216
|
});
|
|
31776
32217
|
|
|
@@ -34977,6 +35418,57 @@ var init_project_local_value_refactorings = __esm({
|
|
|
34977
35418
|
}
|
|
34978
35419
|
});
|
|
34979
35420
|
|
|
35421
|
+
// ../packages/neoscript-language/src/project-source-reference-family.ts
|
|
35422
|
+
function projectReferenceFamily(analysis, target, index = buildProjectSymbolIndex(analysis.symbols)) {
|
|
35423
|
+
const named = index.byName.get(target.name) ?? [];
|
|
35424
|
+
if (target.kind === "class" || target.kind === "constructor") {
|
|
35425
|
+
const owner = target.kind === "class" ? target.name : target.ownerName;
|
|
35426
|
+
return named.filter(
|
|
35427
|
+
(symbol) => symbol.kind === "class" ? symbol.name === owner : symbol.kind === "constructor" && symbol.ownerName === owner
|
|
35428
|
+
);
|
|
35429
|
+
}
|
|
35430
|
+
if (target.kind !== "member" || !target.ownerName) return [target];
|
|
35431
|
+
const symbols = new Map(
|
|
35432
|
+
named.filter((symbol) => symbol.kind === "member").map((symbol) => [symbol.ownerName, symbol])
|
|
35433
|
+
);
|
|
35434
|
+
const classes = /* @__PURE__ */ new Map();
|
|
35435
|
+
for (const document of analysis.documents.values()) {
|
|
35436
|
+
for (const declaration of document.declarations) {
|
|
35437
|
+
if (declaration.kind === "class")
|
|
35438
|
+
classes.set(declaration.name, declaration);
|
|
35439
|
+
}
|
|
35440
|
+
}
|
|
35441
|
+
const roots = /* @__PURE__ */ new Map();
|
|
35442
|
+
const root = (name) => {
|
|
35443
|
+
if (roots.has(name)) return roots.get(name);
|
|
35444
|
+
roots.set(name, null);
|
|
35445
|
+
const declaration = classes.get(name);
|
|
35446
|
+
const own = symbols.get(name);
|
|
35447
|
+
const member = declaration?.members.find(
|
|
35448
|
+
(candidate) => candidate.name === target.name
|
|
35449
|
+
);
|
|
35450
|
+
if (own && !member?.modifiers.includes("override")) {
|
|
35451
|
+
roots.set(name, own);
|
|
35452
|
+
return own;
|
|
35453
|
+
}
|
|
35454
|
+
const base = declaration?.baseTypes.find((type) => classes.has(type.name));
|
|
35455
|
+
const resolved = (base ? root(base.name) : null) ?? own ?? null;
|
|
35456
|
+
roots.set(name, resolved);
|
|
35457
|
+
return resolved;
|
|
35458
|
+
};
|
|
35459
|
+
const selected = root(target.ownerName);
|
|
35460
|
+
if (!selected) return [target];
|
|
35461
|
+
return [...symbols.values()].filter(
|
|
35462
|
+
(symbol) => symbol.ownerName && root(symbol.ownerName) === selected
|
|
35463
|
+
);
|
|
35464
|
+
}
|
|
35465
|
+
var init_project_source_reference_family = __esm({
|
|
35466
|
+
"../packages/neoscript-language/src/project-source-reference-family.ts"() {
|
|
35467
|
+
"use strict";
|
|
35468
|
+
init_project_source_language_features();
|
|
35469
|
+
}
|
|
35470
|
+
});
|
|
35471
|
+
|
|
34980
35472
|
// ../packages/neoscript-language/src/spelling-diagnostics.ts
|
|
34981
35473
|
function enhanceSpellingDiagnostics(document, diagnostics, completionAt) {
|
|
34982
35474
|
return diagnostics.map((diagnostic) => {
|
|
@@ -35208,6 +35700,16 @@ function sameLocationInList(target, locations) {
|
|
|
35208
35700
|
(location3) => location3.uri === target.uri && location3.range.start.line === target.range.start.line && location3.range.start.character === target.range.start.character
|
|
35209
35701
|
);
|
|
35210
35702
|
}
|
|
35703
|
+
function locationKey(location3) {
|
|
35704
|
+
const { start, end } = location3.range;
|
|
35705
|
+
return JSON.stringify([
|
|
35706
|
+
location3.uri,
|
|
35707
|
+
start.line,
|
|
35708
|
+
start.character,
|
|
35709
|
+
end.line,
|
|
35710
|
+
end.character
|
|
35711
|
+
]);
|
|
35712
|
+
}
|
|
35211
35713
|
var LanguageService;
|
|
35212
35714
|
var init_service = __esm({
|
|
35213
35715
|
"../packages/neoscript-language/src/service.ts"() {
|
|
@@ -35220,6 +35722,7 @@ var init_service = __esm({
|
|
|
35220
35722
|
init_project_source_identifiers();
|
|
35221
35723
|
init_project_source_analysis();
|
|
35222
35724
|
init_project_source_construction_quick_fixes();
|
|
35725
|
+
init_project_source_reference_family();
|
|
35223
35726
|
init_project_source_language_features();
|
|
35224
35727
|
init_project_source_tokens();
|
|
35225
35728
|
init_quick_fixes();
|
|
@@ -35402,6 +35905,16 @@ var init_service = __esm({
|
|
|
35402
35905
|
if (!reference2) return [];
|
|
35403
35906
|
const symbolId = resolveReferenceSymbolId(source, reference2);
|
|
35404
35907
|
if (!symbolId) return [];
|
|
35908
|
+
for (const location3 of definition(source, position)) {
|
|
35909
|
+
const owner = this.documents.get(location3.uri);
|
|
35910
|
+
if (owner && isProjectDocument(owner.document, owner.context)) {
|
|
35911
|
+
return this.projectReferences(
|
|
35912
|
+
owner.document,
|
|
35913
|
+
location3.range.start,
|
|
35914
|
+
includeDeclaration
|
|
35915
|
+
);
|
|
35916
|
+
}
|
|
35917
|
+
}
|
|
35405
35918
|
const locations = [];
|
|
35406
35919
|
for (const other of this.documents.values()) {
|
|
35407
35920
|
if (isProjectDocument(other.document, other.context)) continue;
|
|
@@ -35455,8 +35968,10 @@ var init_service = __esm({
|
|
|
35455
35968
|
);
|
|
35456
35969
|
if (!resolved) return null;
|
|
35457
35970
|
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
|
-
|
|
35971
|
+
const binding = resolved.symbol.kind === "local" || resolved.symbol.kind === "parameter" || resolved.symbol.kind === "genericParameter" || resolved.symbol.kind === "flowBinding";
|
|
35972
|
+
let validNeoName = memberLabel2 ? isValidNeoProjectMemberIdentifier(newName) : binding ? isValidNeoProjectBindingIdentifier(newName) : isValidNeoProjectIdentifier(newName);
|
|
35973
|
+
if (resolved.symbol.kind === "local")
|
|
35974
|
+
validNeoName = isValidNeoScriptBindingIdentifier(newName);
|
|
35460
35975
|
validName = validNeoName && isGeneratedCSharpIdentifier(newName) && !isGeneratedCSharpReservedKeyword(newName);
|
|
35461
35976
|
} else {
|
|
35462
35977
|
validName = isValidNeoScriptBindingIdentifier(newName);
|
|
@@ -35565,12 +36080,22 @@ var init_service = __esm({
|
|
|
35565
36080
|
const token = projectTokenAt(document, position);
|
|
35566
36081
|
if (!isProjectNameToken(token)) return [];
|
|
35567
36082
|
const analysis = this.projectAnalysis();
|
|
35568
|
-
const
|
|
36083
|
+
const index = buildProjectSymbolIndex(analysis.symbols);
|
|
36084
|
+
const resolved = projectSymbolAt(analysis, document, position, index);
|
|
35569
36085
|
if (!resolved) return [];
|
|
35570
36086
|
const declaration = resolved.symbol;
|
|
36087
|
+
const family = projectReferenceFamily(analysis, declaration, index);
|
|
36088
|
+
const familyLocations = new Set(
|
|
36089
|
+
family.map((member) => locationKey(member.location))
|
|
36090
|
+
);
|
|
36091
|
+
const familyIds = new Set(
|
|
36092
|
+
family.flatMap((member) => member.id === null ? [] : [member.id])
|
|
36093
|
+
);
|
|
35571
36094
|
const locations = [];
|
|
35572
36095
|
for (const state of this.documents.values()) {
|
|
35573
36096
|
if (!isProjectDocument(state.document, state.context)) continue;
|
|
36097
|
+
if (declaration.kind === "local" && state.document.uri !== document.uri)
|
|
36098
|
+
continue;
|
|
35574
36099
|
for (const candidate of projectTokens(state.document)) {
|
|
35575
36100
|
if (!isProjectNameToken(candidate) || candidate.text !== token.text) {
|
|
35576
36101
|
continue;
|
|
@@ -35578,28 +36103,29 @@ var init_service = __esm({
|
|
|
35578
36103
|
const candidateSymbol = projectSymbolAt(
|
|
35579
36104
|
analysis,
|
|
35580
36105
|
state.document,
|
|
35581
|
-
candidate.range.start
|
|
36106
|
+
candidate.range.start,
|
|
36107
|
+
index
|
|
35582
36108
|
)?.symbol;
|
|
35583
|
-
if (!candidateSymbol || !
|
|
36109
|
+
if (!candidateSymbol || !familyLocations.has(locationKey(candidateSymbol.location))) {
|
|
35584
36110
|
continue;
|
|
35585
36111
|
}
|
|
35586
36112
|
const location3 = { uri: state.document.uri, range: candidate.range };
|
|
35587
|
-
if (!includeDeclaration &&
|
|
36113
|
+
if (!includeDeclaration && familyLocations.has(locationKey(location3))) {
|
|
35588
36114
|
continue;
|
|
35589
36115
|
}
|
|
35590
36116
|
locations.push(location3);
|
|
35591
36117
|
}
|
|
35592
36118
|
}
|
|
35593
36119
|
for (const state of this.documents.values()) {
|
|
35594
|
-
if (
|
|
36120
|
+
if (declaration.kind === "local") break;
|
|
36121
|
+
if (isProjectDocument(state.document, state.context)) continue;
|
|
35595
36122
|
const snapshot = this.scriptSnapshot(state);
|
|
35596
36123
|
for (const candidate of snapshot.parsed.references) {
|
|
35597
36124
|
if (candidate.name !== declaration.name) continue;
|
|
35598
36125
|
const symbolId = resolveReferenceSymbolId(snapshot, candidate);
|
|
35599
36126
|
if (symbolId === null) continue;
|
|
35600
|
-
const matches =
|
|
35601
|
-
|
|
35602
|
-
definition(snapshot, candidate.range.start)
|
|
36127
|
+
const matches = familyIds.has(symbolId) || definition(snapshot, candidate.range.start).some(
|
|
36128
|
+
(location3) => familyLocations.has(locationKey(location3))
|
|
35603
36129
|
);
|
|
35604
36130
|
if (!matches) continue;
|
|
35605
36131
|
locations.push({ uri: state.document.uri, range: candidate.range });
|
|
@@ -50359,6 +50885,41 @@ var init_interface_graph = __esm({
|
|
|
50359
50885
|
});
|
|
50360
50886
|
|
|
50361
50887
|
// ../src/models/neoscript/type-info-compatibility.ts
|
|
50888
|
+
function isTypeInfoAssignable(from, to, context) {
|
|
50889
|
+
if (to.type === NS_TYPE_UNKNOWN) return true;
|
|
50890
|
+
if (from.type === NS_TYPE_UNKNOWN) return false;
|
|
50891
|
+
if (from.required === false && to.required === true) return false;
|
|
50892
|
+
if (from.type === 0 /* Null */) return to.required === false;
|
|
50893
|
+
if (from.type === 2 /* Int */ && to.type === 4 /* Float */) {
|
|
50894
|
+
return true;
|
|
50895
|
+
}
|
|
50896
|
+
if (from.type === 7 /* Class */ && to.type === 7 /* Class */) {
|
|
50897
|
+
if (from.classId === to.classId) {
|
|
50898
|
+
return typeInfosInvariantlyEqual({ ...from, required: to.required }, to);
|
|
50899
|
+
}
|
|
50900
|
+
return resolveInheritanceChain(from.classId, context.classes).some(
|
|
50901
|
+
(schemaClass2) => schemaClass2.id === to.classId
|
|
50902
|
+
);
|
|
50903
|
+
}
|
|
50904
|
+
if (from.type === 7 /* Class */ && to.type === 22 /* Interface */) {
|
|
50905
|
+
return classImplementsInterface(
|
|
50906
|
+
from.classId,
|
|
50907
|
+
to.interfaceId,
|
|
50908
|
+
context.classes,
|
|
50909
|
+
context.interfaces
|
|
50910
|
+
);
|
|
50911
|
+
}
|
|
50912
|
+
if (from.type === 22 /* Interface */ && to.type === 22 /* Interface */) {
|
|
50913
|
+
return resolveInterfaceClosure(from.interfaceId, context.interfaces).some(
|
|
50914
|
+
(neoInterface) => neoInterface.id === to.interfaceId
|
|
50915
|
+
);
|
|
50916
|
+
}
|
|
50917
|
+
if (from.type === 22 /* Interface */ || to.type === 22 /* Interface */) {
|
|
50918
|
+
return false;
|
|
50919
|
+
}
|
|
50920
|
+
const normalizedFrom = { ...from, required: to.required };
|
|
50921
|
+
return typeInfosInvariantlyEqual(normalizedFrom, to);
|
|
50922
|
+
}
|
|
50362
50923
|
var init_type_info_compatibility = __esm({
|
|
50363
50924
|
"../src/models/neoscript/type-info-compatibility.ts"() {
|
|
50364
50925
|
"use strict";
|
|
@@ -62812,7 +63373,9 @@ function lowerInterface(context, declaration) {
|
|
|
62812
63373
|
name: member.name,
|
|
62813
63374
|
...member.docsText === void 0 ? {} : { docsText: member.docsText },
|
|
62814
63375
|
type: lowerType(context, member.type),
|
|
62815
|
-
settable:
|
|
63376
|
+
settable: projectSourceAccessors(member.body ?? "").some(
|
|
63377
|
+
(accessor) => accessor.keyword === "set"
|
|
63378
|
+
),
|
|
62816
63379
|
accessModifier,
|
|
62817
63380
|
source
|
|
62818
63381
|
};
|
|
@@ -64214,7 +64777,8 @@ function propertyAccessors(body) {
|
|
|
64214
64777
|
const accessor = findProjectSourceAccessorBody(body, keyword);
|
|
64215
64778
|
if (accessor === null) return null;
|
|
64216
64779
|
const source = normalizeBodySource(accessor.source);
|
|
64217
|
-
if (accessor.form === "block")
|
|
64780
|
+
if (accessor.form === "block")
|
|
64781
|
+
return keyword === "set" && source.length === 0 ? "return;" : source;
|
|
64218
64782
|
return keyword === "get" ? `return ${source};` : `${source};`;
|
|
64219
64783
|
};
|
|
64220
64784
|
return {
|
|
@@ -111987,8 +112551,11 @@ function validateDocumentInheritanceFlags(ctx) {
|
|
|
111987
112551
|
)) {
|
|
111988
112552
|
continue;
|
|
111989
112553
|
}
|
|
112554
|
+
const declaringClass = classesById.get(
|
|
112555
|
+
inheritedMetadata.declarationClassId
|
|
112556
|
+
);
|
|
111990
112557
|
errors.push({
|
|
111991
|
-
message: `Schema member "${schemaKey}" on class "${schemaClass2.name}" (${schemaClass2.id}) does not match the inherited generated signature from member "${generatedAncestorMember.name}" (${generatedAncestorMember.id}). Abstract implementations and re-abstractions must preserve the generated member contract or have a supported codegen bridge.`
|
|
112558
|
+
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
112559
|
});
|
|
111993
112560
|
}
|
|
111994
112561
|
}
|
|
@@ -112176,6 +112743,7 @@ function createGenerationContext(exportData, diagnostics, docs = EMPTY_UNITY_COD
|
|
|
112176
112743
|
docs,
|
|
112177
112744
|
members: Object.values(exportData.members),
|
|
112178
112745
|
classes: Object.values(exportData.classes),
|
|
112746
|
+
interfaces: Object.values(exportData.interfaces),
|
|
112179
112747
|
diagnostics,
|
|
112180
112748
|
enumNames: buildEnumNameMap(Object.values(exportData.enums), diagnostics),
|
|
112181
112749
|
enumOptionFieldNames: /* @__PURE__ */ new Map(),
|
|
@@ -112411,29 +112979,35 @@ function emittedGeneratedMemberContract(ctx, ownerClassId, schemaKey, memberId,
|
|
|
112411
112979
|
valueType: narrowedMemberValueType(ctx, member, valueType, inherited),
|
|
112412
112980
|
hasSetter,
|
|
112413
112981
|
getOnlyContract: (inherited?.getOnlyContract ?? false) || isAbstractMember(member) === true && !hasSetter,
|
|
112414
|
-
|
|
112982
|
+
valueTypeInfo: generatedValueTypeInfo(ctx, member),
|
|
112415
112983
|
closesGenericType: (inherited?.closesGenericType ?? false) || lookupNarrowsThroughGenericParam(member) || isMemberGenericBase(member)
|
|
112416
112984
|
};
|
|
112417
112985
|
}
|
|
112418
112986
|
function suppressesInheritedSetter(contract) {
|
|
112419
112987
|
return contract?.getOnlyContract === true;
|
|
112420
112988
|
}
|
|
112421
|
-
function
|
|
112422
|
-
|
|
112423
|
-
|
|
112424
|
-
|
|
112425
|
-
return nsReturnTypeInfo.type === 7 /* Class */ ? nsReturnTypeInfo.classId : null;
|
|
112989
|
+
function generatedValueTypeInfo(ctx, member) {
|
|
112990
|
+
const required2 = isRequiredMember2(member);
|
|
112991
|
+
if (isMemberClassBase(member)) {
|
|
112992
|
+
return { type: 7 /* Class */, classId: member.classId, required: required2 };
|
|
112426
112993
|
}
|
|
112994
|
+
const returnType = nsPropertyReturnTypeInfo(member);
|
|
112995
|
+
if (returnType !== null) return returnType;
|
|
112427
112996
|
if (isMemberLookupBase(member)) {
|
|
112428
|
-
const
|
|
112429
|
-
if (
|
|
112430
|
-
|
|
112997
|
+
const declaredType = lookupDeclaredTypeInfo2(member);
|
|
112998
|
+
if (declaredType !== null) return declaredType;
|
|
112999
|
+
const entry = resolveLookupEntryMember(ctx, member);
|
|
113000
|
+
if (entry === null) return null;
|
|
113001
|
+
if (isMemberClassBase(entry)) {
|
|
113002
|
+
return { type: 7 /* Class */, classId: entry.classId, required: required2 };
|
|
112431
113003
|
}
|
|
112432
|
-
const entryMember = resolveLookupEntryMember(ctx, member);
|
|
112433
|
-
return entryMember !== null && isMemberClassBase(entryMember) ? entryMember.classId : null;
|
|
112434
113004
|
}
|
|
112435
113005
|
return null;
|
|
112436
113006
|
}
|
|
113007
|
+
function generatedValueClassId(ctx, member) {
|
|
113008
|
+
const typeInfo = generatedValueTypeInfo(ctx, member);
|
|
113009
|
+
return typeInfo?.type === 7 /* Class */ ? typeInfo.classId : null;
|
|
113010
|
+
}
|
|
112437
113011
|
function narrowedMemberValueType(ctx, member, rawValueType, contract) {
|
|
112438
113012
|
if (contract === null) return rawValueType;
|
|
112439
113013
|
if (contract.valueType === rawValueType) return rawValueType;
|
|
@@ -112449,13 +113023,18 @@ function narrowedMemberValueType(ctx, member, rawValueType, contract) {
|
|
|
112449
113023
|
)) {
|
|
112450
113024
|
return contract.valueType;
|
|
112451
113025
|
}
|
|
112452
|
-
|
|
112453
|
-
|
|
112454
|
-
if (
|
|
112455
|
-
|
|
112456
|
-
|
|
112457
|
-
);
|
|
112458
|
-
|
|
113026
|
+
const inheritedType = contract.valueTypeInfo;
|
|
113027
|
+
if (inheritedType === null) return rawValueType;
|
|
113028
|
+
if (inheritedType.type !== 7 /* Class */ && inheritedType.type !== 22 /* Interface */)
|
|
113029
|
+
return rawValueType;
|
|
113030
|
+
const valueType = generatedValueTypeInfo(ctx, member);
|
|
113031
|
+
if (valueType === null) return rawValueType;
|
|
113032
|
+
const sourceType = valueType.type === 7 /* Class */ && inheritedType.type === 7 /* Class */ && valueType.required === false && inheritedType.required === true ? { ...valueType, required: true } : valueType;
|
|
113033
|
+
try {
|
|
113034
|
+
return isTypeInfoAssignable(sourceType, inheritedType, ctx) ? contract.valueType : rawValueType;
|
|
113035
|
+
} catch {
|
|
113036
|
+
return rawValueType;
|
|
113037
|
+
}
|
|
112459
113038
|
}
|
|
112460
113039
|
function storedCollectionImplementsContract(ctx, member, rawValueType, contractType2) {
|
|
112461
113040
|
const contract = contractType2.replace(/\?$/, "");
|
|
@@ -112639,6 +113218,13 @@ function createGeneratedInstanceMemberSignatureProjector(exportData) {
|
|
|
112639
113218
|
equals: generatedInstanceMemberSignaturesEqual
|
|
112640
113219
|
};
|
|
112641
113220
|
}
|
|
113221
|
+
function formatGeneratedInstanceMemberSignature(signature) {
|
|
113222
|
+
if (signature.kind === "property") {
|
|
113223
|
+
const accessors = signature.hasSetter ? "get; set;" : "get;";
|
|
113224
|
+
return `${signature.valueType} ${signature.name} { ${accessors} }`;
|
|
113225
|
+
}
|
|
113226
|
+
return `${signature.returnType} ${signature.name}(${signature.parameterTypes.join(", ")})`;
|
|
113227
|
+
}
|
|
112642
113228
|
function generatedInstanceMemberSignaturesEqual(left, right) {
|
|
112643
113229
|
if (left.kind !== right.kind) return false;
|
|
112644
113230
|
if (left.name !== right.name) return false;
|
|
@@ -114246,6 +114832,7 @@ var init_generate_unity_classes = __esm({
|
|
|
114246
114832
|
init_sdk_runtime_enums();
|
|
114247
114833
|
init_members();
|
|
114248
114834
|
init_classes();
|
|
114835
|
+
init_type_info_compatibility();
|
|
114249
114836
|
DEFAULT_NAMESPACE = "Assets.Scripts.Neo";
|
|
114250
114837
|
isNSPropertyContractDeclaration = isMemberNSPropertyContractBase;
|
|
114251
114838
|
SMART_TILE_CONTRACT_WORLD_KINDS = /* @__PURE__ */ new Set([
|
|
@@ -114334,6 +114921,7 @@ function assertProjectDocumentInheritanceFlagsValid(document) {
|
|
|
114334
114921
|
PROJECT_ROOTS.map((root) => document.project[root.projectField])
|
|
114335
114922
|
),
|
|
114336
114923
|
signatureProjector: {
|
|
114924
|
+
format: formatGeneratedInstanceMemberSignature,
|
|
114337
114925
|
resolveLocal: (classId, schemaKey) => getGeneratedSignatures().projectLocal(classId, schemaKey),
|
|
114338
114926
|
resolveInherited: (classId, schemaKey) => getGeneratedSignatures().projectInherited(classId, schemaKey),
|
|
114339
114927
|
resolveInheritedMetadata: (classId, schemaKey) => {
|
|
@@ -114343,6 +114931,7 @@ function assertProjectDocumentInheritanceFlagsValid(document) {
|
|
|
114343
114931
|
);
|
|
114344
114932
|
return signature === null ? null : {
|
|
114345
114933
|
memberId: signature.memberId,
|
|
114934
|
+
declarationClassId: signature.declarationClassId,
|
|
114346
114935
|
isAbstract: signature.isAbstract
|
|
114347
114936
|
};
|
|
114348
114937
|
},
|
|
@@ -134256,7 +134845,7 @@ var init_project_document_cache = __esm({
|
|
|
134256
134845
|
init_src();
|
|
134257
134846
|
init_project_documents();
|
|
134258
134847
|
PROJECT_SOURCE_BUILD_CACHE_PATH = ".neo/build/project-source-analysis-v4.json";
|
|
134259
|
-
PROJECT_SOURCE_BUILD_CACHE_REVISION =
|
|
134848
|
+
PROJECT_SOURCE_BUILD_CACHE_REVISION = 4;
|
|
134260
134849
|
}
|
|
134261
134850
|
});
|
|
134262
134851
|
|
|
@@ -146409,7 +146998,7 @@ var init_registry2 = __esm({
|
|
|
146409
146998
|
"../packages/manifest/schema-contract/registry.mjs"() {
|
|
146410
146999
|
"use strict";
|
|
146411
147000
|
PROJECT_SCHEMA_CONTRACT = Object.freeze({
|
|
146412
|
-
cliVersion: "0.
|
|
147001
|
+
cliVersion: "0.62.0",
|
|
146413
147002
|
projectFileUploadBatchSize: 32,
|
|
146414
147003
|
documentRecords: {
|
|
146415
147004
|
member: {
|
|
@@ -155089,7 +155678,7 @@ There is no --keep-current: preserving current semantic state defines flatten.
|
|
|
155089
155678
|
async function main() {
|
|
155090
155679
|
const args = parseArgs(process.argv.slice(2));
|
|
155091
155680
|
if (args.command === "--version") {
|
|
155092
|
-
console.log("0.
|
|
155681
|
+
console.log("0.62.0");
|
|
155093
155682
|
return;
|
|
155094
155683
|
}
|
|
155095
155684
|
if (args.command === null || args.command === "help" || args.command === "--help" || args.command === "-h") {
|