Skip to content
Closed
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
1 change: 1 addition & 0 deletions src/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export namespace CommonSymbols {
export const native = "native";
export const indexof = "indexof";
export const valueof = "valueof";
export const ReturnType = "ReturnType";
// aliases
export const null_ = "null";
export const true_ = "true";
Expand Down
2 changes: 2 additions & 0 deletions src/diagnosticMessages.generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ export enum DiagnosticCode {
Namespace_0_has_no_exported_member_1 = 2694,
Required_type_parameters_may_not_follow_optional_type_parameters = 2706,
Duplicate_property_0 = 2718,
Type_0_has_no_call_signatures = 2757,
File_0_not_found = 6054,
Numeric_separators_are_not_allowed_here = 6188,
Multiple_consecutive_numeric_separators_are_not_permitted = 6189,
Expand Down Expand Up @@ -275,6 +276,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
case 2694: return "Namespace '{0}' has no exported member '{1}'.";
case 2706: return "Required type parameters may not follow optional type parameters.";
case 2718: return "Duplicate property '{0}'.";
case 2757: return "Type '{0}' has no call signatures.";
case 6054: return "File '{0}' not found.";
case 6188: return "Numeric separators are not allowed here.";
case 6189: return "Multiple consecutive numeric separators are not permitted.";
Expand Down
1 change: 1 addition & 0 deletions src/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"Namespace '{0}' has no exported member '{1}'.": 2694,
"Required type parameters may not follow optional type parameters.": 2706,
"Duplicate property '{0}'.": 2718,
"Type '{0}' has no call signatures.": 2757,

"File '{0}' not found.": 6054,
"Numeric separators are not allowed here.": 6188,
Expand Down
6 changes: 6 additions & 0 deletions src/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,12 @@ export class Program extends DiagnosticEmitter {
this.makeNativeTypeDeclaration(CommonSymbols.valueof, CommonFlags.EXPORT | CommonFlags.GENERIC),
DecoratorFlags.BUILTIN
));
this.nativeFile.add(CommonSymbols.ReturnType, new TypeDefinition(
CommonSymbols.ReturnType,
this.nativeFile,
this.makeNativeTypeDeclaration(CommonSymbols.ReturnType, CommonFlags.EXPORT | CommonFlags.GENERIC),
DecoratorFlags.BUILTIN
));
if (options.hasFeature(Feature.SIMD)) this.registerNativeType(CommonSymbols.v128, Type.v128);

// register compiler hints
Expand Down
36 changes: 36 additions & 0 deletions src/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ export class Resolver extends DiagnosticEmitter {
case CommonSymbols.native: return this.resolveBuiltinNativeType(node, ctxElement, ctxTypes, reportMode);
case CommonSymbols.indexof: return this.resolveBuiltinIndexofType(node, ctxElement, ctxTypes, reportMode);
case CommonSymbols.valueof: return this.resolveBuiltinValueofType(node, ctxElement, ctxTypes, reportMode);
case CommonSymbols.ReturnType: return this.resolveBuiltinReturnTypeType(node, ctxElement, ctxTypes, reportMode);
}
}

Expand Down Expand Up @@ -550,6 +551,41 @@ export class Resolver extends DiagnosticEmitter {
return null;
}

private resolveBuiltinReturnTypeType(
/** The type to resolve. */
node: NamedTypeNode,
/** Contextual element. */
ctxElement: Element,
/** Contextual types, i.e. `T`. */
ctxTypes: Map<string,Type> | null = null,
/** How to proceed with eventualy diagnostics. */
reportMode: ReportMode = ReportMode.REPORT
): Type | null {
var typeArgumentNodes = node.typeArguments;
if (!(typeArgumentNodes && typeArgumentNodes.length == 1)) {
if (reportMode == ReportMode.REPORT) {
this.error(
DiagnosticCode.Expected_0_type_arguments_but_got_1,
node.range, "1", (typeArgumentNodes ? typeArgumentNodes.length : 1).toString(10)
);
}
return null;
}
var typeArgument = this.resolveType(typeArgumentNodes[0], ctxElement, ctxTypes, reportMode);
if (!typeArgument) return null;
var signatureReference = typeArgument.signatureReference;
if (!signatureReference) {
if (reportMode == ReportMode.REPORT) {
this.error(
DiagnosticCode.Type_0_has_no_call_signatures,
typeArgumentNodes[0].range, typeArgument.toString()
);
}
return null;
}
return signatureReference.returnType;
}

/** Resolves a type name to the program element it refers to. */
resolveTypeName(
/** The type name to resolve. */
Expand Down
2 changes: 1 addition & 1 deletion std/assembly/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -886,7 +886,7 @@ declare type native<T> = T;
declare type indexof<T extends unknown[]> = keyof T;
/** Special type evaluating the indexed access value type. */
declare type valueof<T extends unknown[]> = T[0];

declare type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
/** Pseudo-class representing the backing class of integer types. */
declare class _Integer {
/** Smallest representable value. */
Expand Down
9 changes: 9 additions & 0 deletions tests/compiler/ReturnType-error.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"asc_flags": [
"--runtime none"
],
"stderr": [
"TS2757: Type 'i32' has no call signatures.",
"EOF"
]
}
8 changes: 8 additions & 0 deletions tests/compiler/ReturnType-error.optimized.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(module
(type $FUNCSIG$v (func))
(memory $0 0)
(export "memory" (memory $0))
(func $null (; 0 ;) (type $FUNCSIG$v)
nop
)
)
2 changes: 2 additions & 0 deletions tests/compiler/ReturnType-error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
assert(isInteger<ReturnType<i32>>())
ERROR("EOF");
Empty file.
5 changes: 5 additions & 0 deletions tests/compiler/ReturnType.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"asc_flags": [
"--runtime none"
]
}
8 changes: 8 additions & 0 deletions tests/compiler/ReturnType.optimized.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
(module
(type $FUNCSIG$v (func))
(memory $0 0)
(export "memory" (memory $0))
(func $null (; 0 ;) (type $FUNCSIG$v)
nop
)
)
14 changes: 14 additions & 0 deletions tests/compiler/ReturnType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
assert(isInteger<ReturnType<() => i8>>());
assert(isSigned<ReturnType<() => i8>>());
assert(sizeof<ReturnType<() => i8>>() == 1); // i32

assert(isFloat<ReturnType<() => f64>>());
assert(sizeof<ReturnType<() => f64>>() == 8);

class SomeExample {
a: f64;
b: f64;
}

assert(isManaged<ReturnType<() => SomeExample>>());
assert(offsetof<ReturnType<() => SomeExample>>() == 16);
9 changes: 9 additions & 0 deletions tests/compiler/ReturnType.untouched.wat
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(module
(type $FUNCSIG$v (func))
(memory $0 0)
(table $0 1 funcref)
(elem (i32.const 0) $null)
(export "memory" (memory $0))
(func $null (; 0 ;) (type $FUNCSIG$v)
)
)
2 changes: 0 additions & 2 deletions tests/compiler/binary.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@
local.get $2
i32.wrap_i64
i32.const 0
i32.ne
i32.const 0
local.get $1
i32.const 2147483647
i32.and
Expand Down
20 changes: 8 additions & 12 deletions tests/compiler/std/libm.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -2933,8 +2933,6 @@
i32.const 1
local.get $6
i32.const 0
i32.ne
i32.const 0
local.get $8
i32.const 2146435072
i32.eq
Expand All @@ -2946,8 +2944,6 @@
i32.const 1
local.get $19
i32.const 0
i32.ne
i32.const 0
local.get $4
i32.const 2146435072
i32.eq
Expand Down Expand Up @@ -7185,14 +7181,14 @@
local.get $8
i32.const -1021968384
i32.eq
if
local.get $1
local.get $0
local.get $2
f32.sub
f32.le
br_if $folding-inner1
end
i32.const 0
local.get $1
local.get $0
local.get $2
f32.sub
f32.le
select
br_if $folding-inner1
end
end
local.get $8
Expand Down
20 changes: 8 additions & 12 deletions tests/compiler/std/math.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -6321,8 +6321,6 @@
i32.const 1
local.get $6
i32.const 0
i32.ne
i32.const 0
local.get $8
i32.const 2146435072
i32.eq
Expand All @@ -6334,8 +6332,6 @@
i32.const 1
local.get $19
i32.const 0
i32.ne
i32.const 0
local.get $4
i32.const 2146435072
i32.eq
Expand Down Expand Up @@ -7801,14 +7797,14 @@
local.get $8
i32.const -1021968384
i32.eq
if
local.get $1
local.get $0
local.get $2
f32.sub
f32.le
br_if $folding-inner1
end
i32.const 0
local.get $1
local.get $0
local.get $2
f32.sub
f32.le
select
br_if $folding-inner1
end
end
local.get $8
Expand Down
4 changes: 0 additions & 4 deletions tests/compiler/std/operator-overloading.optimized.wat
Original file line number Diff line number Diff line change
Expand Up @@ -284,8 +284,6 @@
i32.const 1
local.get $6
i32.const 0
i32.ne
i32.const 0
local.get $8
i32.const 2146435072
i32.eq
Expand All @@ -297,8 +295,6 @@
i32.const 1
local.get $19
i32.const 0
i32.ne
i32.const 0
local.get $4
i32.const 2146435072
i32.eq
Expand Down