Skip to content

Commit 478417a

Browse files
committed
updated
1 parent c5f2228 commit 478417a

File tree

1 file changed

+64
-84
lines changed

1 file changed

+64
-84
lines changed

packages/compiler/src/core/checker.ts

Lines changed: 64 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -2549,8 +2549,8 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
25492549
case IdentifierKind.ModelExpressionProperty:
25502550
case IdentifierKind.ObjectLiteralProperty:
25512551
const model = getReferencedModel(node as ModelPropertyNode | ObjectLiteralPropertyNode);
2552-
if (model && !Array.isArray(model)) {
2553-
sym = getMemberSymbol(model.node!.symbol, id.sv);
2552+
if (model.length === 1) {
2553+
sym = getMemberSymbol(model[0].node!.symbol, id.sv);
25542554
} else {
25552555
return undefined;
25562556
}
@@ -2617,7 +2617,7 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
26172617

26182618
function getReferencedModel(
26192619
propertyNode: ObjectLiteralPropertyNode | ModelPropertyNode,
2620-
): Model | Model[] | undefined {
2620+
): Model[] {
26212621
type ModelOrArrayValueNode = ArrayLiteralNode | ObjectLiteralNode;
26222622
type ModelOrArrayTypeNode = ModelExpressionNode | TupleExpressionNode;
26232623
type ModelOrArrayNode = ModelOrArrayValueNode | ModelOrArrayTypeNode;
@@ -2661,9 +2661,7 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
26612661
break;
26622662
}
26632663

2664-
return refType?.kind === "Model" || refType?.kind === "Tuple" || refType?.kind === "Union"
2665-
? getNestedModel(refType, path)
2666-
: undefined;
2664+
return getNestedModel(refType, path);
26672665

26682666
function pushToModelPath(node: Node, preNode: Node | undefined, path: PathSeg[]) {
26692667
if (node.kind === SyntaxKind.ArrayLiteral || node.kind === SyntaxKind.TupleExpression) {
@@ -2680,91 +2678,77 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
26802678
) {
26812679
path.unshift({ propertyName: node.id.sv });
26822680
}
2683-
if (node.kind === SyntaxKind.ObjectLiteral) {
2684-
// define tupleIndex as -1 to indicate that we are looking for union type
2685-
const curResult = path.find((i) => i.tupleIndex === -1);
2686-
if (curResult === undefined) {
2687-
path.unshift({ tupleIndex: -1 });
2688-
} else {
2689-
if (path.length > 1) {
2690-
// If it is a specific type in the union type, the previous -1 needs to be deleted
2691-
const removeIdx = path.findIndex((i) => i.tupleIndex === -1);
2692-
if (removeIdx !== -1) {
2693-
path.splice(removeIdx, 1);
2694-
}
2695-
}
2696-
}
2697-
}
26982681
}
26992682

2700-
function getNestedModel(
2701-
modelOrTuple: Model | Tuple | Union | undefined,
2702-
path: PathSeg[],
2703-
): Model[] | undefined {
2704-
let cur: Type | undefined = modelOrTuple;
2683+
function getNestedModel(modelOrTupleOrUnion: Type | undefined, path: PathSeg[]): Model[] {
2684+
let cur = modelOrTupleOrUnion;
27052685
const models: Model[] = [];
2706-
for (const seg of path) {
2707-
switch (cur?.kind) {
2708-
case "Tuple":
2709-
if (
2710-
seg.tupleIndex !== undefined &&
2711-
seg.tupleIndex >= 0 &&
2712-
seg.tupleIndex < cur.values.length
2713-
) {
2714-
cur = cur.values[seg.tupleIndex];
2715-
} else {
2716-
return undefined;
2717-
}
2718-
break;
2719-
case "Model":
2720-
if (cur.name === "Array" && seg.tupleIndex !== undefined) {
2721-
cur = cur.templateMapper?.args[0] as Model;
2722-
} else if (cur.name !== "Array" && seg.propertyName) {
2723-
cur = cur.properties.get(seg.propertyName)?.type;
2724-
if (cur?.kind === "Model") {
2725-
const result = getNestedModel(cur, path);
2726-
if (result) {
2727-
models.push(...result);
2728-
}
2729-
}
2730-
} else if (seg.tupleIndex === -1) {
2686+
if (cur?.kind === "Model" || cur?.kind === "Tuple" || cur?.kind === "Union") {
2687+
if (path.length <= 0) {
2688+
// Handle union type nesting when path is empty
2689+
switch (cur?.kind) {
2690+
case "Model":
2691+
models.push(cur);
27312692
for (const child of cur.properties.values()) {
27322693
if (child.type.kind === "Model") {
2733-
const result = getNestedModel(child.type, path);
2734-
if (result) {
2735-
models.push(...result);
2736-
}
2694+
models.push(...(getNestedModel(child.type, path) ?? []));
27372695
}
27382696
}
2739-
} else {
2740-
return undefined;
2741-
}
2742-
2743-
break;
2744-
case "Union":
2745-
if (seg.tupleIndex === -1 || seg.propertyName) {
2746-
// seg.propertyName is empty and contains all,
2747-
// otherwise the value contains the model property corresponding to seg.propertyName
2697+
return models;
2698+
case "Union":
27482699
for (const variant of cur.variants.values()) {
2749-
if (variant.type.kind === "Model") {
2750-
const result = getNestedModel(variant.type, path);
2751-
if (result) {
2752-
models.push(...result);
2753-
}
2700+
if (variant.type.kind === "Model" || variant.type.kind === "Tuple") {
2701+
models.push(...(getNestedModel(variant.type, path) ?? []));
27542702
}
27552703
}
2704+
return models;
2705+
default:
2706+
return models;
2707+
}
2708+
} else {
2709+
for (const seg of path) {
2710+
switch (cur?.kind) {
2711+
case "Tuple":
2712+
if (
2713+
seg.tupleIndex !== undefined &&
2714+
seg.tupleIndex >= 0 &&
2715+
seg.tupleIndex < cur.values.length
2716+
) {
2717+
cur = cur.values[seg.tupleIndex];
2718+
} else {
2719+
return models;
2720+
}
2721+
break;
2722+
case "Model":
2723+
if (cur.name === "Array" && seg.tupleIndex !== undefined) {
2724+
cur = cur.templateMapper?.args[0] as Model;
2725+
} else if (cur.name !== "Array" && seg.propertyName) {
2726+
cur = cur.properties.get(seg.propertyName)?.type;
2727+
} else {
2728+
return models;
2729+
}
2730+
break;
2731+
case "Union":
2732+
// When seg.property name exists, it means that it is in the union model or tuple,
2733+
// and the corresponding model or tuple needs to be found recursively.
2734+
for (const variant of cur.variants.values()) {
2735+
if (variant.type.kind === "Model" || variant.type.kind === "Tuple") {
2736+
models.push(...(getNestedModel(variant.type, path) ?? []));
2737+
}
2738+
}
2739+
break;
2740+
default:
2741+
return models;
27562742
}
2757-
break;
2758-
default:
2759-
return undefined;
2760-
}
2761-
}
2743+
}
27622744

2763-
if (cur?.kind === "Model") {
2764-
models.push(cur);
2745+
if (cur?.kind === "Model") {
2746+
models.push(cur);
2747+
}
2748+
}
27652749
}
27662750

2767-
return models.length > 0 ? models : undefined;
2751+
return models;
27682752
}
27692753

27702754
function getReferencedTypeFromTemplateDeclaration(node: ModelOrArrayNode): Type | undefined {
@@ -2957,16 +2941,12 @@ export function createChecker(program: Program, resolver: NameResolver): Checker
29572941
kind === IdentifierKind.ObjectLiteralProperty
29582942
) {
29592943
const model = getReferencedModel(ancestor as ModelPropertyNode | ObjectLiteralPropertyNode);
2960-
if (!model) {
2944+
if (model.length <= 0) {
29612945
return completions;
29622946
}
29632947
const curModelNode = ancestor.parent as ModelExpressionNode | ObjectLiteralNode;
2964-
if (Array.isArray(model)) {
2965-
for (const curModel of model) {
2966-
addInheritedPropertyCompletions(curModel, curModelNode);
2967-
}
2968-
} else {
2969-
addInheritedPropertyCompletions(model, curModelNode);
2948+
for (const curModel of model) {
2949+
addInheritedPropertyCompletions(curModel, curModelNode);
29702950
}
29712951
} else if (identifier.parent && identifier.parent.kind === SyntaxKind.MemberExpression) {
29722952
let base = resolver.getNodeLinks(identifier.parent.base).resolvedSymbol;

0 commit comments

Comments
 (0)