From 0d9c05882cf6ae26bb32696c46bb661ea6e2c577 Mon Sep 17 00:00:00 2001 From: Jordan Eldredge Date: Thu, 5 Sep 2019 06:12:34 -0700 Subject: [PATCH] Add/enforce return types for implemented Maki methods --- eslint-local-rules.js | 44 +++++++++++++++++++++++++++++++-- modern/src/runtime/Button.ts | 4 +-- modern/src/runtime/Container.ts | 7 +++--- modern/src/runtime/GuiObject.ts | 30 +++++++++++----------- modern/src/runtime/PopupMenu.ts | 9 +++++-- modern/src/runtime/System.ts | 14 +++++------ 6 files changed, 75 insertions(+), 33 deletions(-) diff --git a/eslint-local-rules.js b/eslint-local-rules.js index f0a60a47..4b5ba2fc 100644 --- a/eslint-local-rules.js +++ b/eslint-local-rules.js @@ -16,6 +16,11 @@ for (const value of Object.values(objects)) { } const TYPE_MAP = { + // This might be wrong. Maybe it really is an empty string? Or Null? + "": { + typeScriptName: "TSVoidKeyword", + stringRepresentation: "void", + }, string: { typeScriptName: "TSStringKeyword", stringRepresentation: "string", @@ -164,7 +169,42 @@ module.exports = { return; } - const { params } = node.value; + const { params, returnType, body } = node.value; + const sourceCode = context.getSourceCode(); + + if (returnType == null) { + const expectedTypeData = TYPE_MAP[func.result]; + if ( + expectedTypeData != null && + !sourceCode.getText(node).includes("unimplementedWarning") + ) { + context.report({ + node: body, + message: `Missing return type for Maki method. Expected \`${ + expectedTypeData.stringRepresentation + }\`.`, + fix: fixer => { + return fixer.insertTextBefore( + body, + `: ${expectedTypeData.stringRepresentation}` + ); + }, + }); + } + } else { + const expectedTypeData = TYPE_MAP[func.result]; + if ( + expectedTypeData != null && + expectedTypeData.typeScriptName !== returnType.typeAnnotation.type + ) { + context.report({ + node: returnType, + message: `Incorrect return type for Maki method. Expected \`${ + expectedTypeData.stringRepresentation + }\`.`, + }); + } + } func.parameters.forEach(([type, name], i) => { const actual = params[i]; @@ -179,7 +219,7 @@ module.exports = { } const expectedTypeData = TYPE_MAP[type.toLowerCase()]; if (expectedTypeData == null) { - console.warn(`Missing type data for ${type}.`); + // console.warn(`Missing type data for ${type}.`); return; } const fix = fixer => { diff --git a/modern/src/runtime/Button.ts b/modern/src/runtime/Button.ts index 47031989..a0828d6d 100644 --- a/modern/src/runtime/Button.ts +++ b/modern/src/runtime/Button.ts @@ -12,11 +12,11 @@ class Button extends GuiObject { return "Button"; } - leftclick() { + leftclick(): void { this.js_trigger("onLeftClick"); } - rightclick() { + rightclick(): void { this.js_trigger("onRightClick"); } diff --git a/modern/src/runtime/Container.ts b/modern/src/runtime/Container.ts index 310ff7f7..7af0969d 100644 --- a/modern/src/runtime/Container.ts +++ b/modern/src/runtime/Container.ts @@ -19,20 +19,19 @@ class Container extends MakiObject { return "Container"; } - show() { + show(): void { this.visible = true; this.parent.js_trigger("js_update"); } - hide() { + hide(): void { this.visible = false; this.parent.js_trigger("js_update"); } - setxmlparam(param: string, value: string) { + setxmlparam(param: string, value: string): void { this.attributes[param] = value; this.js_trigger("js_update"); - return value; } getlayout(id: string) { diff --git a/modern/src/runtime/GuiObject.ts b/modern/src/runtime/GuiObject.ts index af423b37..6fefce8b 100644 --- a/modern/src/runtime/GuiObject.ts +++ b/modern/src/runtime/GuiObject.ts @@ -47,16 +47,14 @@ class GuiObject extends MakiObject { return findDescendantByTypeAndId(this, null, id); } - init(newRoot) { + init(newRoot): void { this.parent = newRoot; newRoot.js_addChild(this); - return this; } - setxmlparam(param: string, value: string) { + setxmlparam(param: string, value: string): void { this.attributes[param] = value; this.js_trigger("js_update"); - return value; } getxmlparam(param: string) { @@ -71,42 +69,42 @@ class GuiObject extends MakiObject { return findParentNodeOfType(this, new Set(["layout"])); } - show() { + show(): void { this.visible = true; this.parent.js_trigger("js_update"); } - hide() { + hide(): void { this.visible = false; this.parent.js_trigger("js_update"); } - gettop() { + gettop(): number { return this._compareToUidSelector( Number(this.attributes.y) || 0, MakiSelectors.getTop ); } - getleft() { + getleft(): number { return Number(this.attributes.x) || 0; } - getheight() { + getheight(): number { // TODO // I don't know how it gets calculated exactly, but if a node has a minimum // and maximum h, but no h, getwidth still returns a value, return min for now return Number(this.attributes.h) || Number(this.attributes.minimum_h) || 0; } - getwidth() { + getwidth(): number { // TODO // I don't know how it gets calculated exactly, but if a node has a minimum // and maximum w, but no w, getwidth still returns a value, return min for now return Number(this.attributes.w) || Number(this.attributes.minimum_w) || 0; } - resize(x: number, y: number, w: number, h: number) { + resize(x: number, y: number, w: number, h: number): void { this.attributes.x = x; this.attributes.y = y; this.attributes.w = w; @@ -119,13 +117,12 @@ class GuiObject extends MakiObject { } // alpha range from 0-255 - setalpha(alpha: number) { + setalpha(alpha: number): void { this.attributes.alpha = alpha; - this.js_trigger("js_update"); } - isvisible() { - return this.visible; + isvisible(): number { + return this.visible ? 1 : 0; } onsetvisible(onoff: boolean) { @@ -229,7 +226,8 @@ class GuiObject extends MakiObject { } // alpha range from 0-255 - settargeta(alpha: number) { + settargeta(alpha: number): void { + unimplementedWarning("settargeta"); this.attributes.alpha = alpha; this.js_trigger("js_update"); } diff --git a/modern/src/runtime/PopupMenu.ts b/modern/src/runtime/PopupMenu.ts index a183046c..dd743330 100644 --- a/modern/src/runtime/PopupMenu.ts +++ b/modern/src/runtime/PopupMenu.ts @@ -19,7 +19,12 @@ class PopupMenu extends MakiObject { return "PopupMenu"; } - addcommand(txt: string, id: number, checked: boolean, disabled: boolean) { + addcommand( + txt: string, + id: number, + checked: boolean, + disabled: boolean + ): void { this.commands.push({ name: txt, id, @@ -28,7 +33,7 @@ class PopupMenu extends MakiObject { }); } - addseparator() { + addseparator(): void { this.commands.push({ id: "separator" }); } diff --git a/modern/src/runtime/System.ts b/modern/src/runtime/System.ts index 1e11aa5f..c856f278 100644 --- a/modern/src/runtime/System.ts +++ b/modern/src/runtime/System.ts @@ -140,7 +140,7 @@ class System extends MakiObject { return Selectors.getVolume(this._store.getState()); } - setvolume(volume: number) { + setvolume(volume: number): void { return this._store.dispatch(Actions.setVolume(volume)); } @@ -527,19 +527,19 @@ class System extends MakiObject { return Math.sin(value); } - cos(value: number) { + cos(value: number): number { return Math.cos(value); } - tan(value: number) { + tan(value: number): number { return Math.tan(value); } - asin(value: number) { + asin(value: number): number { return Math.asin(value); } - acos(value: number) { + acos(value: number): number { return Math.acos(value); } @@ -547,11 +547,11 @@ class System extends MakiObject { return Math.atan(value); } - atan2(y: number, x: number) { + atan2(y: number, x: number): number { return Math.atan2(y, x); } - pow(value: number, pvalue: number) { + pow(value: number, pvalue: number): number { return Math.pow(value, pvalue); }