diff --git a/src-runtime/validateType.js b/src-runtime/validateType.js index 5b68d4a..17d1a66 100644 --- a/src-runtime/validateType.js +++ b/src-runtime/validateType.js @@ -12,6 +12,7 @@ import {validateObject } from "./validateObject.js"; import {validateRecord } from "./validateRecord.js"; import {validateSet } from "./validateSet.js"; import {validateTuple } from "./validateTuple.js"; +import {validateTypeof } from "./validateTypeof.js"; import {validateTypedef } from "./validateTypedef.js"; import {validateUnion } from "./validateUnion.js"; /** @@ -125,6 +126,8 @@ function validateType(value, expect, loc, name, critical = true, warn, depth) { case 'tuple': // Trigger: pc.app.scene.setSkybox([1, 2, 3]); return validateTuple(value, expect, loc, name, critical, warn, depth + 1); + case 'typeof': + return validateTypeof(value, expect, loc, name, critical, warn, depth + 1); case '*': case 'any': return true; diff --git a/src-runtime/validateTypeof.js b/src-runtime/validateTypeof.js new file mode 100644 index 0000000..6d20a95 --- /dev/null +++ b/src-runtime/validateTypeof.js @@ -0,0 +1,15 @@ +import {classes} from "./registerClass.js"; +/** + * @param {*} value - The actual value that we need to validate. + * @param {*} expect - The supposed type information of said value. + * @param {string} loc - String like `BoundingBox#compute` + * @param {string} name - Name of the argument + * @param {boolean} critical - Only `false` for unions. + * @param {console["warn"]} warn - Function to warn with. + * @param {number} depth - The depth to detect recursion. + * @returns {boolean} Boolean indicating if a type is correct. + */ +export function validateTypeof(value, expect, loc, name, critical, warn, depth) { + // console.log("validateTypeof", {value, expect, loc, name, critical, warn, depth}); + return value === classes[expect.argument]; +} diff --git a/test-with-conversion.js b/test-with-conversion.js new file mode 100644 index 0000000..5c18a29 --- /dev/null +++ b/test-with-conversion.js @@ -0,0 +1,10 @@ +import {readFileSync, writeFileSync} from 'fs'; +import {addTypeChecks} from "./src-transpiler/addTypeChecks.js"; +const files = [ + "test-typeof.js", +]; +for (const file of files) { + const content = readFileSync('./test/convert-first/' + file, 'utf-8'); + const contentWithTypeChecks = addTypeChecks(content); + writeFileSync('./test/converted/' + file, contentWithTypeChecks); +} diff --git a/test/convert-first/test-typeof.js b/test/convert-first/test-typeof.js new file mode 100644 index 0000000..dd1398d --- /dev/null +++ b/test/convert-first/test-typeof.js @@ -0,0 +1,25 @@ +import {options} from '@runtime-type-inspector/runtime'; +class TestClass1 { + abc = 123; + constructor(greeting = "hi1") { + this.greeting = greeting; + } +} +class TestClass2 { + abc = 123; + constructor(greeting = "hi2") { + this.greeting = greeting; + } +} +/** + * @param {typeof TestClass1} someClass - Some class. + * @param {...any} args - The arguments. + * @returns {object} The object. + */ +function callNew(someClass, ...args) { + return new someClass(...args); +} +const testClass1 = callNew(TestClass1, "hoi1"); +console.assert(options.count === 0, "Should have 0 errors here"); +const testClass2 = callNew(TestClass2, "hoi2"); +console.assert(options.count === 1, "Should have 1 error here"); diff --git a/test/converted/test-typeof.mjs b/test/converted/test-typeof.mjs new file mode 100644 index 0000000..205a388 --- /dev/null +++ b/test/converted/test-typeof.mjs @@ -0,0 +1,45 @@ +import {inspectType, inspectTypeWithTemplates, youCanAddABreakpointHere, registerVariable, validateDivision, registerTypedef, registerClass, registerImportNamespaceSpecifier} from '@runtime-type-inspector/runtime'; +export * from '@runtime-type-inspector/runtime'; +import {options} from '@runtime-type-inspector/runtime'; +class TestClass1 { + abc = 123; + constructor(greeting = "hi1") { + this.greeting = greeting; + } +} +registerClass(TestClass1); +class TestClass2 { + abc = 123; + constructor(greeting = "hi2") { + this.greeting = greeting; + } +} +registerClass(TestClass2); + +/** + * @param {typeof TestClass1} someClass - Some class. + * @param {...any} args - The arguments. + * @returns {object} The object. + */ + +function callNew(someClass, ...args) { + if (!inspectType(someClass, { + "type": "typeof", + "argument": "TestClass1", + "optional": false + }, 'callNew', 'someClass')) { + youCanAddABreakpointHere(); + } + if (!inspectType(args, { + "type": "array", + "elementType": "any", + "optional": false + }, 'callNew', 'args')) { + youCanAddABreakpointHere(); + } + return new someClass(...args); +} +const testClass1 = callNew(TestClass1, "hoi1"); +console.assert(options.count === 0, "Should have 0 errors here"); +const testClass2 = callNew(TestClass2, "hoi2"); +console.assert(options.count === 1, "Should have 1 error here");