[interop] Add support for the `never` type (#457)
* [interop] Add support for the `never` type
* removed `@override`
diff --git a/web_generator/lib/src/ast/builtin.dart b/web_generator/lib/src/ast/builtin.dart
index a46d7e3..bee4514 100644
--- a/web_generator/lib/src/ast/builtin.dart
+++ b/web_generator/lib/src/ast/builtin.dart
@@ -24,11 +24,17 @@
@override
bool isNullable;
+ /// This denotes a type that has a discardable result
+ ///
+ /// These are for types such as `void` or `never`
+ bool discardable;
+
BuiltinType(
{required this.name,
this.typeParams = const [],
this.fromDartJSInterop = false,
- bool? isNullable})
+ bool? isNullable,
+ this.discardable = false})
: isNullable = isNullable ?? false;
@override
@@ -82,6 +88,11 @@
PrimitiveType.any => (isNullable ?? false)
? anyType
: BuiltinType(name: 'JSAny', fromDartJSInterop: true),
+ PrimitiveType.never => BuiltinType(
+ name: 'JSAny',
+ fromDartJSInterop: true,
+ discardable: true,
+ isNullable: true),
PrimitiveType.unknown => anyType,
PrimitiveType.object => BuiltinType(
name: 'JSObject', fromDartJSInterop: true, isNullable: isNullable),
@@ -185,5 +196,6 @@
undefined,
symbol,
array,
- bigint
+ bigint,
+ never
}
diff --git a/web_generator/lib/src/ast/declarations.dart b/web_generator/lib/src/ast/declarations.dart
index 1ede563..025d15d 100644
--- a/web_generator/lib/src/ast/declarations.dart
+++ b/web_generator/lib/src/ast/declarations.dart
@@ -198,7 +198,11 @@
if (modifier == VariableModifier.$const) {
return Method((m) => m
..docs.addAll([...doc])
- ..annotations.addAll([...annotations])
+ ..annotations.addAll([
+ ...annotations,
+ if (_checkIfDiscardable(type))
+ refer('doNotStore', 'package:meta/meta.dart')
+ ])
..name = name
..type = MethodType.getter
..annotations.add(generateJSAnnotation())
@@ -226,6 +230,14 @@
}
}
+bool _checkIfDiscardable(Type type) {
+ if (type case BuiltinType(discardable: final typeIsDiscardable)
+ when typeIsDiscardable) {
+ return true;
+ }
+ return false;
+}
+
enum VariableModifier { let, $const, $var }
class FunctionDeclaration extends CallableDeclaration
@@ -274,7 +286,11 @@
return Method((m) => m
..docs.addAll([...doc])
- ..annotations.addAll([...annotations])
+ ..annotations.addAll([
+ ...annotations,
+ if (_checkIfDiscardable(returnType))
+ refer('doNotStore', 'package:meta/meta.dart')
+ ])
..external = true
..name = dartName ?? name
..annotations.add(generateJSAnnotation(
@@ -750,7 +766,11 @@
if (readonly) {
return Method((m) => m
..docs.addAll([...doc])
- ..annotations.addAll([...annotations])
+ ..annotations.addAll([
+ ...annotations,
+ if (_checkIfDiscardable(type))
+ refer('doNotStore', 'package:meta/meta.dart')
+ ])
..external = true
..name = dartName ?? name
..type = MethodType.getter
@@ -836,7 +856,11 @@
if (isNullable) {
return Method((m) => m
..docs.addAll([...doc])
- ..annotations.addAll([...annotations])
+ ..annotations.addAll([
+ ...annotations,
+ if (_checkIfDiscardable(returnType))
+ refer('doNotStore', 'package:meta/meta.dart')
+ ])
..external = true
..name = dartName ?? name
..type = MethodType.getter
@@ -1015,7 +1039,11 @@
return Method((m) => m
..docs.addAll([...doc])
- ..annotations.addAll([...annotations])
+ ..annotations.addAll([
+ ...annotations,
+ if (_checkIfDiscardable(returnType))
+ refer('doNotStore', 'package:meta/meta.dart')
+ ])
..external = true
..name = 'operator $name'
..types
diff --git a/web_generator/lib/src/interop_gen/transform/transformer.dart b/web_generator/lib/src/interop_gen/transform/transformer.dart
index 167ed26..e8cde85 100644
--- a/web_generator/lib/src/interop_gen/transform/transformer.dart
+++ b/web_generator/lib/src/interop_gen/transform/transformer.dart
@@ -1364,6 +1364,7 @@
TSSyntaxKind.VoidKeyword => PrimitiveType.$void,
TSSyntaxKind.BigIntKeyword => PrimitiveType.bigint,
TSSyntaxKind.SymbolKeyword => PrimitiveType.symbol,
+ TSSyntaxKind.NeverKeyword => PrimitiveType.never,
_ => throw UnsupportedError(
'The given type with kind ${type.kind} is not supported yet')
};
diff --git a/web_generator/lib/src/js/typescript.types.dart b/web_generator/lib/src/js/typescript.types.dart
index d2c322d..d9fdf8d 100644
--- a/web_generator/lib/src/js/typescript.types.dart
+++ b/web_generator/lib/src/js/typescript.types.dart
@@ -81,6 +81,7 @@
static const TSSyntaxKind VoidKeyword = TSSyntaxKind._(116);
static const TSSyntaxKind BigIntKeyword = TSSyntaxKind._(163);
static const TSSyntaxKind SymbolKeyword = TSSyntaxKind._(155);
+ static const TSSyntaxKind NeverKeyword = TSSyntaxKind._(146);
// types
static const TSSyntaxKind UnionType = TSSyntaxKind._(192);
diff --git a/web_generator/test/integration/interop_gen/functions_expected.dart b/web_generator/test/integration/interop_gen/functions_expected.dart
index 3cd8ad8..d2d6d25 100644
--- a/web_generator/test/integration/interop_gen/functions_expected.dart
+++ b/web_generator/test/integration/interop_gen/functions_expected.dart
@@ -3,6 +3,8 @@
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:js_interop' as _i1;
+import 'package:meta/meta.dart' as _i2;
+
@_i1.JS()
external String greetUser(String name);
@_i1.JS()
@@ -38,8 +40,12 @@
]);
@_i1.JS()
external T firstElement<T extends _i1.JSAny?>(_i1.JSArray<T> arr);
+@_i2.doNotStore
@_i1.JS()
-external void throwError(String msg);
+external _i1.JSAny? throwError([String? msg]);
+@_i2.doNotStore
+@_i1.JS('throwError')
+external _i1.JSAny? throwError$1();
@_i1.JS()
external _i1.JSArray<T> wrapInArray<T extends _i1.JSAny?>(T value);
@_i1.JS()
diff --git a/web_generator/test/integration/interop_gen/functions_input.d.ts b/web_generator/test/integration/interop_gen/functions_input.d.ts
index 6fc8665..8d5121f 100644
--- a/web_generator/test/integration/interop_gen/functions_input.d.ts
+++ b/web_generator/test/integration/interop_gen/functions_input.d.ts
@@ -2,13 +2,14 @@
export declare function logMessages(...messages: string[]): void;
export declare function delay<U>(ms: number, returnValue?: U): Promise<U>;
export declare function toArray(a: number): number[];
+export declare function toArray(a: string): string[];
export declare function square(a: number): number;
export declare function pow(a: number): number;
export declare function pow(a: number, power: number): number;
-export declare function toArray(a: string): string[];
export declare function createUser(name: string, age?: number, role?: string): object;
export declare function firstElement<T>(arr: T[]): T;
-export declare function throwError(msg: string): void;
+export declare function throwError(msg?: string): never;
+export declare function throwError(): never;
export declare function wrapInArray<T>(value: T): T[];
export declare function identity<T = string>(value: T): T;
export declare function someFunction<A>(arr: A[]): undefined;
diff --git a/web_generator/test/integration/interop_gen/variables_expected.dart b/web_generator/test/integration/interop_gen/variables_expected.dart
index 4bf7c0f..b2af7cc 100644
--- a/web_generator/test/integration/interop_gen/variables_expected.dart
+++ b/web_generator/test/integration/interop_gen/variables_expected.dart
@@ -3,6 +3,8 @@
// ignore_for_file: no_leading_underscores_for_library_prefixes
import 'dart:js_interop' as _i1;
+import 'package:meta/meta.dart' as _i2;
+
@_i1.JS()
external double counter;
@_i1.JS()
@@ -35,3 +37,6 @@
external _i1.JSArray<_i1.JSString> get names;
@_i1.JS()
external _i1.JSArray<_i1.JSString> get newNames;
+@_i2.doNotStore
+@_i1.JS()
+external _i1.JSAny? get neverUseThis;
diff --git a/web_generator/test/integration/interop_gen/variables_input.d.ts b/web_generator/test/integration/interop_gen/variables_input.d.ts
index 1bc7d05..975677c 100644
--- a/web_generator/test/integration/interop_gen/variables_input.d.ts
+++ b/web_generator/test/integration/interop_gen/variables_input.d.ts
@@ -11,3 +11,4 @@
export declare const maybeValue: unknown;
export declare const names: string[];
export declare const newNames: Array<string>;
+export declare const neverUseThis: never;