Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking
changeKind: internal
packages:
- "@typespec/compiler"
---

Fix: Using a scalar constructor defined in a parent scalar doesn't reference the right scalar
15 changes: 14 additions & 1 deletion packages/compiler/src/core/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5621,7 +5621,6 @@ export function createChecker(program: Program): Checker {
decorators,
derivedScalars: [],
});
checkScalarConstructors(type, node, type.constructors, mapper);
linkType(links, type, mapper);

if (node.extends) {
Expand All @@ -5631,6 +5630,7 @@ export function createChecker(program: Program): Checker {
type.baseScalar.derivedScalars.push(type);
}
}
checkScalarConstructors(type, node, type.constructors, mapper);
decorators.push(...checkDecorators(type, node, mapper));

if (mapper === undefined) {
Expand Down Expand Up @@ -5695,6 +5695,19 @@ export function createChecker(program: Program): Checker {
constructors: Map<string, ScalarConstructor>,
mapper: TypeMapper | undefined
) {
if (parentScalar.baseScalar) {
for (const member of parentScalar.baseScalar.constructors.values()) {
const newConstructor: ScalarConstructor = cloneTypeForSymbol(
getMemberSymbol(node.symbol, member.name)!,
{
...member,
scalar: parentScalar,
}
);
linkIndirectMember(node, newConstructor, mapper);
constructors.set(member.name, newConstructor);
}
}
for (const member of node.members) {
const constructor = checkScalarConstructor(member, mapper, parentScalar);
if (constructors.has(constructor.name as string)) {
Expand Down
5 changes: 3 additions & 2 deletions packages/compiler/src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1127,7 +1127,8 @@ export type MemberContainerNode =
| ModelExpressionNode
| InterfaceStatementNode
| EnumStatementNode
| UnionStatementNode;
| UnionStatementNode
| ScalarStatementNode;

export type MemberNode =
| ModelPropertyNode
Expand All @@ -1141,7 +1142,7 @@ export type MemberContainerType = Model | Enum | Interface | Union | Scalar;
/**
* Type that can be used as members of a container type.
*/
export type MemberType = ModelProperty | EnumMember | Operation | UnionVariant;
export type MemberType = ModelProperty | EnumMember | Operation | UnionVariant | ScalarConstructor;

export type Comment = LineComment | BlockComment;

Expand Down
15 changes: 15 additions & 0 deletions packages/compiler/test/checker/values/scalar-values.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ describe("instantiate with named constructor", () => {
]);
});

it("instantiate using constructor from parent scalar", async () => {
const value = await compileValue(
`b.fromString("a")`,
`
scalar a { init fromString(val: string);}
scalar b extends a { }
`
);
strictEqual(value.valueKind, "ScalarValue");
strictEqual(value.type.kind, "Scalar");
strictEqual(value.type.name, "b");
strictEqual(value.scalar?.name, "b");
strictEqual(value.value.name, "fromString");
});

it("instantiate from another scalar", async () => {
const value = await compileValue(
`b.fromA(a.fromString("a"))`,
Expand Down