Account for typedef nullability (#257)
Account for typedef nullability
_desugarTypedef accepts a _RawType and returns its
underlying type if it's a typedef. However, it doesn't
account for whether the _RawType is nullable or not.
In order to accurately desugar a use of a typedef, we
should union the _RawType's nullability with the underlying
type's nullability. For example, `SomeTypedef?` should
always be nullable after being desugared.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2d7e04d..b9cdd1a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -19,6 +19,7 @@
to avoid users accidentally downcasting `num`, which has different semantics
depending on whether you compile to JS or Wasm. See issue [#57][] for more
details.
+- Fix an issue where some union types didn't account for typedef nullability.
[#57]: https://github.com/dart-lang/web/issues/57
diff --git a/lib/src/dom/webgl1.dart b/lib/src/dom/webgl1.dart
index bf50609..b6ef237 100644
--- a/lib/src/dom/webgl1.dart
+++ b/lib/src/dom/webgl1.dart
@@ -1630,7 +1630,7 @@
/// buffer object's data store.
external void bufferData(
GLenum target,
- JSAny dataOrSize,
+ JSAny? dataOrSize,
GLenum usage,
);
diff --git a/lib/src/dom/webgl2.dart b/lib/src/dom/webgl2.dart
index 68b354a..128ecfe 100644
--- a/lib/src/dom/webgl2.dart
+++ b/lib/src/dom/webgl2.dart
@@ -1268,7 +1268,7 @@
GLint border,
GLenum format,
GLenum type,
- JSAny pboOffsetOrSourceOrSrcData, [
+ JSAny? pboOffsetOrSourceOrSrcData, [
int srcOffset,
]);
@@ -1287,7 +1287,7 @@
GLsizei depth,
GLenum format,
GLenum type,
- JSAny pboOffsetOrSourceOrSrcData, [
+ JSAny? pboOffsetOrSourceOrSrcData, [
int srcOffset,
]);
@@ -1946,7 +1946,7 @@
/// creates and initializes the buffer object's data store.
external void bufferData(
GLenum target,
- JSAny sizeOrSrcData,
+ JSAny? sizeOrSrcData,
GLenum usage, [
int srcOffset,
GLuint length,
@@ -1972,7 +1972,7 @@
JSAny borderOrSource, [
GLenum format,
GLenum type,
- JSAny pboOffsetOrPixelsOrSourceOrSrcData,
+ JSAny? pboOffsetOrPixelsOrSourceOrSrcData,
int srcOffset,
]);
external void texSubImage2D(
@@ -1984,7 +1984,7 @@
JSAny heightOrType,
JSAny formatOrSource, [
GLenum type,
- JSAny pboOffsetOrPixelsOrSourceOrSrcData,
+ JSAny? pboOffsetOrPixelsOrSourceOrSrcData,
int srcOffset,
]);
external void compressedTexImage2D(
@@ -2086,7 +2086,7 @@
GLsizei height,
GLenum format,
GLenum type,
- JSAny dstDataOrOffset, [
+ JSAny? dstDataOrOffset, [
int dstOffset,
]);
external JSObject get canvas;
diff --git a/tool/generator/translator.dart b/tool/generator/translator.dart
index 189fdfb..c28f0ad 100644
--- a/tool/generator/translator.dart
+++ b/tool/generator/translator.dart
@@ -104,20 +104,23 @@
}
/// If [rawType] corresponds to an IDL type that we declare as a typedef,
-/// desugars the typedef.
+/// desugars the typedef, accounting for nullability along the way.
///
/// Otherwise, returns null.
_RawType? _desugarTypedef(_RawType rawType) {
final decl = Translator.instance!._typeToDeclaration[rawType.type];
return switch (decl?.type) {
- 'typedef' => _getRawType((decl as idl.Typedef).idlType),
+ 'typedef' => _getRawType((decl as idl.Typedef).idlType)
+ ..nullable |= rawType.nullable,
// TODO(srujzs): If we ever add a generic JS function type, we should
// maybe leverage that here so we have stronger type-checking of
// callbacks.
- 'callback' || 'callback interface' => _RawType('JSFunction', false),
+ 'callback' ||
+ 'callback interface' =>
+ _RawType('JSFunction', rawType.nullable),
// TODO(srujzs): Enums in the WebIDL are just strings, but we could make
// them easier to work with on the Dart side.
- 'enum' => _RawType('JSString', false),
+ 'enum' => _RawType('JSString', rawType.nullable),
_ => null
};
}