From 98f53ad08fb9f380b1eb58831daf8440969665a8 Mon Sep 17 00:00:00 2001 From: Aidas Patas Date: Sat, 13 Mar 2021 19:27:08 +0200 Subject: [PATCH] rpc support and typings update --- cli/stubs/typings.stub | 13 ++++++-- compiler/index.js | 71 ++++++++++++++++++++++++++++++------------ compiler/parser.js | 39 +++++++++++++++++++++-- 3 files changed, 97 insertions(+), 26 deletions(-) diff --git a/cli/stubs/typings.stub b/cli/stubs/typings.stub index 5f8778d..1161f97 100644 --- a/cli/stubs/typings.stub +++ b/cli/stubs/typings.stub @@ -1,17 +1,24 @@ type UPROPERTYParam = null; +type UFUNCTIONParam = null; type KEYBINDParam = 0 | 1; -declare const EditAnywhere: UPROPERTYParam = null; -declare const VisibleAnywhere: UPROPERTYParam = null; +declare const EditAnywhere: UPROPERTYParam; +declare const VisibleAnywhere: UPROPERTYParam; declare const BindAxis: KEYBINDParam = 0; declare const BindAction: KEYBINDParam = 1; declare const IE_PRESSED: KEYBINDParam = 0; declare const IE_RELEASED: KEYBINDParam = 1; +declare const Server: UFUNCTIONParam; +declare const Client: UFUNCTIONParam; +declare const Reliable: UFUNCTIONParam; +declare const Unreliable: UFUNCTIONParam; +declare const NetMulticast: UFUNCTIONParam; + declare const UCLASS = (): Function => (): void => {}; declare const UPROPERTY = (...args: UPROPERTYParam[]): Function => (): void => {}; -declare const UFUNCTION = (...args: UPROPERTYParam[]): Function => (): void => {}; +declare const UFUNCTION = (...args: UFUNCTIONParam[]): Function => (): void => {}; declare const KEYBIND = (type: KEYBINDParam, action: string, event: ?KEYBINDParam = 0): Function => (): void => {}; declare type float = number; diff --git a/compiler/index.js b/compiler/index.js index 68b2c61..787d90c 100644 --- a/compiler/index.js +++ b/compiler/index.js @@ -5,6 +5,7 @@ module.exports = (code) => { const lines = code.split('\n'); const propertyBag = []; + // because TS removes comments where it shouldn't and UnrealJS needs them const thingsToReplaceAfterTypescript = []; let constructorLine = null; @@ -16,7 +17,20 @@ module.exports = (code) => { let keybindConfiguration = null; let keybindMethodLine = null; + let uFunctionConfiguration = null; + let uFunctionMethodLine = null; + const transformedCodeArray = lines.map((line, i) => { + if (i === uFunctionMethodLine) { + uFunctionMethodLine = null; + const [ + result, + whatToReplaceAfterTypescript, + ] = parser.formatUFunctionMethod(line, uFunctionConfiguration); + + thingsToReplaceAfterTypescript.push(whatToReplaceAfterTypescript); + return result; + } if (i === keybindMethodLine) { keybindMethodLine = null; const [result, whatToReplaceAfterTypescript] = parser.formatKeybindMethod( @@ -36,7 +50,7 @@ module.exports = (code) => { } if ( new RegExp(`new ${className}`).test(line) - || new RegExp(`export .*? ${className}`).test(line) + || new RegExp(`export.*?${className}`).test(line) ) { if (firstClassReferenceLine === null) { firstClassReferenceLine = i - 1; @@ -64,6 +78,21 @@ module.exports = (code) => { if (decorator === 'UCLASS') { return ''; } + if (decorator === 'UFUNCTION') { + uFunctionMethodLine = i + 1; + + // check what method are we ufunction-ing + const nextLine = lines[i + 1]; + const [methodName, args] = parser.parseTypescriptMethod(nextLine); + uFunctionConfiguration = { + method: methodName, + args, + line: i + 1, + decoratorArguments, + }; + + return ''; + } if (decorator === 'KEYBIND') { keybindMethodLine = i + 1; @@ -111,14 +140,12 @@ module.exports = (code) => { ); classHash = newClassHash; - // let times = 0; const replacedClassReferencesAndSuperCall = processedCode.map((line) => { - if (new RegExp(className).test(line) && (/new/.test(line) || /export/.test(line))) { - console.log(line); - // if (times > 0) { - return line.replace(className, `${className}_${classHash}`); - // } - // times += 1; + if ( + new RegExp(className).test(line) + && (/new/.test(line) || /export/.test(line)) + ) { + return line.replace(className, `${className}_${classHash}`); } if (/super\(.*\)/.test(line) && replaceSuper) { @@ -132,21 +159,25 @@ module.exports = (code) => { replacedClassReferencesAndSuperCall.join('\n'), ); - const replacedJavascript = compiledJavascript.split('\n').map((line) => { - const noSpaces = line.replace(/ /g, '').replace(/\r/g, ''); + const replacedJavascript = compiledJavascript + .split('\n') + .map((line) => { + const noSpaces = line.replace(/ /g, '').replace(/\r/g, ''); - let result = line; + let result = line; - // eslint-disable-next-line consistent-return - thingsToReplaceAfterTypescript.forEach(([target, replacement]) => { - if (target === noSpaces) { - // eslint-disable-next-line no-return-assign - return result = replacement; - } - }); + // eslint-disable-next-line consistent-return + thingsToReplaceAfterTypescript.forEach(([target, replacement]) => { + // console.log(target); + if (target === noSpaces) { + // eslint-disable-next-line no-return-assign + return (result = replacement); + } + }); - return result; - }).join('\n'); + return result; + }) + .join('\n'); return replacedJavascript.replace( 'Object.defineProperty(exports, "__esModule", { value: true });', diff --git a/compiler/parser.js b/compiler/parser.js index b6784fb..38ab88b 100644 --- a/compiler/parser.js +++ b/compiler/parser.js @@ -22,15 +22,45 @@ const buildCompiledClass = (className) => { }; module.exports = { + formatUFunctionMethod(line, configuration) { + const noSpaces = line.replace(/ /g, ''); + let result = noSpaces; + + configuration.args.forEach((arg) => { + if (arg.name !== '') { + result = result.replace( + `${arg.name}:${arg.type}`, + `${arg.name} /*${arg.type}*/`, + ); + } + }); + + const rpcArguments = configuration.decoratorArguments.reduce( + (acc, arg) => (acc === '' ? `${arg}` : `${acc}+${arg}`), + '', + ); + + const replaceWhat = result.replace(/ /g, ''); + result = result.replace(')', `) /*${rpcArguments}*/`); + + return [result, [replaceWhat, result]]; + }, formatKeybindMethod(line, configuration) { const noSpaces = line.replace(/ /g, ''); let result; configuration.args.forEach((arg) => { - result = noSpaces.replace(`${arg.name}:${arg.type}`, `${arg.name} /*${arg.type}*/`); + result = noSpaces.replace( + `${arg.name}:${arg.type}`, + `${arg.name} /*${arg.type}*/`, + ); }); - const [bindWhat, methodName, event = false] = configuration.decoratorArguments; + const [ + bindWhat, + methodName, + event = false, + ] = configuration.decoratorArguments; let bindType; if (bindWhat === 'BindAxis') { @@ -49,7 +79,10 @@ module.exports = { const cleanMethodName = methodName.replace(/'/g, '').replace(/"/g, ''); const replaceWhat = result.replace(/ /g, ''); - result = result.replace(')', `) /*${bindType}[${cleanMethodName}, ${additionalArguments}]*/`); + result = result.replace( + ')', + `) /*${bindType}[${cleanMethodName}, ${additionalArguments}]*/`, + ); return [result, [replaceWhat, result]]; },