diff --git a/static_core/plugins/ets/tools/declgen_ts2sts/src/ASTAutofixer.ts b/static_core/plugins/ets/tools/declgen_ts2sts/src/ASTAutofixer.ts index e75471ecdec34be6029982205c55b865ab4afa8a..a63bce951da51793576722443fe6682970f86c5e 100644 --- a/static_core/plugins/ets/tools/declgen_ts2sts/src/ASTAutofixer.ts +++ b/static_core/plugins/ets/tools/declgen_ts2sts/src/ASTAutofixer.ts @@ -118,7 +118,8 @@ export class Autofixer { this[FaultID.GeneratorFunction].bind(this), this[FaultID.ObjectBindingParams].bind(this), this[FaultID.DefaultExport].bind(this), - this[FaultID.RemoveLimitDecorator].bind(this) + this[FaultID.RemoveLimitDecorator].bind(this), + this[FaultID.AddReturnType].bind(this) ] ], [ @@ -141,7 +142,12 @@ export class Autofixer { this[FaultID.NoOptionalMemberFunction].bind(this) ] ], - [ts.SyntaxKind.MethodDeclaration, [this[FaultID.NoETSKeyword].bind(this)]], + [ + ts.SyntaxKind.MethodDeclaration, [ + this[FaultID.AddReturnType].bind(this), + this[FaultID.NoETSKeyword].bind(this) + ] + ], [ ts.SyntaxKind.ImportDeclaration, [ @@ -158,8 +164,10 @@ export class Autofixer { [ts.SyntaxKind.UnionType, [this[FaultID.NoVoidUnionType].bind(this)]], [ts.SyntaxKind.VariableDeclaration, [this[FaultID.ConstLiteralToType].bind(this)]], [ts.SyntaxKind.IndexedAccessType, [this[FaultID.IndexAccessType].bind(this)]], - [ts.SyntaxKind.FunctionType, [this[FaultID.FunctionType].bind(this)]] - ]); + [ts.SyntaxKind.FunctionType, [this[FaultID.FunctionType].bind(this)]], + [ts.SyntaxKind.MethodSignature, [this[FaultID.AddReturnType].bind(this)]] + ] + ); fixNode(node: ts.Node): ts.VisitResult { const autofixes = this.autofixes.get(node.kind); @@ -1601,6 +1609,63 @@ export class Autofixer { } return node; } + + /** + * Rule: `arkts-no-return-type-in-functions` + */ + private [FaultID.AddReturnType](node: ts.Node): ts.VisitResult { + /** + * For function and method declarations without explicit return type, + * add JSValue as the default return type. + */ + + if (ts.isMethodDeclaration(node)) { + if (!node.type && !ts.isConstructorDeclaration(node)) { + return this.context.factory.updateMethodDeclaration( + node, + node.modifiers, + node.asteriskToken, + node.name, + node.questionToken, + node.typeParameters, + node.parameters, + this.context.factory.createTypeReferenceNode(JSValue), + node.body + ); + } + } + + if (ts.isFunctionDeclaration(node)) { + if (!node.type) { + return this.context.factory.updateFunctionDeclaration( + node, + node.modifiers, + node.asteriskToken, + node.name, + node.typeParameters, + node.parameters, + this.context.factory.createTypeReferenceNode(JSValue), + node.body + ); + } + } + + if (ts.isMethodSignature(node)) { + if (!node.type) { + return this.context.factory.updateMethodSignature( + node, + node.modifiers, + node.name, + node.questionToken, + node.typeParameters, + node.parameters, + this.context.factory.createTypeReferenceNode(JSValue) + ); + } + } + + return node; + } } /** @@ -2542,9 +2607,6 @@ function shouldCreateTypeAlias 0) { - return true; - } return expressions.some(className => FINAL_CLASS.includes(className)) && !promises.some(promise => expressions.includes(promise)); diff --git a/static_core/plugins/ets/tools/declgen_ts2sts/src/Declgen.ts b/static_core/plugins/ets/tools/declgen_ts2sts/src/Declgen.ts index 074ef8358089c6516c0604a41ba25ef53a2c8b6d..a28de6a7eaca1de3a409f3b70bb0058cb57943be 100644 --- a/static_core/plugins/ets/tools/declgen_ts2sts/src/Declgen.ts +++ b/static_core/plugins/ets/tools/declgen_ts2sts/src/Declgen.ts @@ -81,6 +81,7 @@ export class Declgen { }); // Prevent the noemit of the passed compilerOptions from being true this.compilerOptions.noEmit = false; + this.compilerOptions.experimentalDecorators = true; this.hookedHost = Declgen.createHookedCompilerHost(this.sourceFileMap, this.compilerOptions, declgenOptions); if (customResolveModuleNames) { this.hookedHost.resolveModuleNames = customResolveModuleNames; diff --git a/static_core/plugins/ets/tools/declgen_ts2sts/test/cookbook_tests/dets_output/arkts-function-return-type.d.ets b/static_core/plugins/ets/tools/declgen_ts2sts/test/cookbook_tests/dets_output/arkts-function-return-type.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..9669370dd9f28b93b6b774e26d2f2beaaa8a7e18 --- /dev/null +++ b/static_core/plugins/ets/tools/declgen_ts2sts/test/cookbook_tests/dets_output/arkts-function-return-type.d.ets @@ -0,0 +1,70 @@ +'use static' +/* + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +declare function greet(name: string): Any; +declare function add(a: number, b: number): number; +export declare function createInstance(ctor: Any): Any; +export declare function processArray(arr: T[], processor: (item: T) => void): Any; +export declare class Calculator { + constructor(initialValue: number); + add(value: number): Any; + subtract(value: number): Any; + multiply(value: number): Any; + divide(value: number): Any; + getValue(): Any; +} +export declare class MathUtils { + constructor(); + power(base: number, exponent: number): number; + sqrt(value: number): number; + factorial(n: number): Any; + isPrime(num: number): Any; + printResult(result: number): Any; +} +export declare class BaseProcessor { + constructor(); + initialize(): Any; + cleanup(): Any; +} +export declare class FileProcessor extends BaseProcessor { + readFile(filename: string): Any; + writeFile(filename: string, data: Any): boolean; + deleteFile(filename: string): Any; +} +export declare class StringUtils { + static isEmpty(param0?: string): Any; + static capitalize(str: string): Any; + trim(): Any; +} +export declare class NumberUtils { + static parse(str: string): number; + static format(num: number): Any; + value: number; + increment(): Any; + decrement(): number; +} +export declare class Collection { + constructor(); + add(item: T): Any; + remove(item: T): Any; + find(predicate: (item: T) => boolean): Any; + map(transform: (item: T) => R): Any; + size(): number; +} +export declare interface DataProcessor { + processData(data: Any): Any; + validate(data: Any): Any; + save(data: Any): boolean; +} diff --git a/static_core/plugins/ets/tools/declgen_ts2sts/test/cookbook_tests/dts_declarations/arkts-function-return-type.d.ts b/static_core/plugins/ets/tools/declgen_ts2sts/test/cookbook_tests/dts_declarations/arkts-function-return-type.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..314b4d8c9be69c5ae3916c49ee8085eb63b359ab --- /dev/null +++ b/static_core/plugins/ets/tools/declgen_ts2sts/test/cookbook_tests/dts_declarations/arkts-function-return-type.d.ts @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022-2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +declare function greet(name: string); +declare function add(a: number, b: number): number; + +export declare class Calculator { + constructor(initialValue: number); + add(value: number); + subtract(value: number); + multiply(value: number); + divide(value: number); + getValue(); +} + +export declare class MathUtils { + constructor(); + power(base: number, exponent: number): number; + sqrt(value: number): number; + factorial(n: number); + isPrime(num: number); + printResult(result: number); +} + +export interface DataProcessor { + processData(data: any); + validate(data: any); + save(data: any): boolean; +} + +export declare class BaseProcessor { + constructor(); + initialize(); + cleanup(); +} + +export declare class FileProcessor extends BaseProcessor { + readFile(filename: string); + writeFile(filename: string, data: any): boolean; + deleteFile(filename: string); +} + +export declare class StringUtils { + static isEmpty(str: string); + static capitalize(str: string); + length: number; + isEmpty(); + trim(); +} + +export declare class NumberUtils { + static parse(str: string): number; + static format(num: number); + value: number; + increment(); + decrement(): number; +} + +export declare class Collection { + constructor(); + add(item: T); + remove(item: T); + find(predicate: (item: T) => boolean); + map(transform: (item: T) => R); + size(): number; +} + +export declare function createInstance(ctor: new () => T); +export declare function processArray(arr: T[], processor: (item: T) => void); \ No newline at end of file diff --git a/static_core/plugins/ets/tools/declgen_ts2sts/test/cookbook_tests/json_storage/arkts-function-return-type.json b/static_core/plugins/ets/tools/declgen_ts2sts/test/cookbook_tests/json_storage/arkts-function-return-type.json new file mode 100644 index 0000000000000000000000000000000000000000..3653f6b26c74c9fa2d78766088dc7b5d5efd32b9 --- /dev/null +++ b/static_core/plugins/ets/tools/declgen_ts2sts/test/cookbook_tests/json_storage/arkts-function-return-type.json @@ -0,0 +1,3 @@ +{ + "nodes": [] +} diff --git a/static_core/plugins/ets/tools/declgen_ts2sts/utils/lib/FaultId.ts b/static_core/plugins/ets/tools/declgen_ts2sts/utils/lib/FaultId.ts index a259a9c5c91ee1a75076329e4b7011a2d72dc320..de72091f835048c68307a19b34b27ec219ea0c44 100644 --- a/static_core/plugins/ets/tools/declgen_ts2sts/utils/lib/FaultId.ts +++ b/static_core/plugins/ets/tools/declgen_ts2sts/utils/lib/FaultId.ts @@ -150,6 +150,7 @@ export enum FaultID { AddDeclareToClass, FunctionType, MergeOverloadedMethods, + AddReturnType, // this should always be last enum LAST_ID } diff --git a/static_core/plugins/ets/tools/declgen_ts2sts/utils/lib/TypeUtils.ts b/static_core/plugins/ets/tools/declgen_ts2sts/utils/lib/TypeUtils.ts index 4a5c052ab33f6fb3faa1422a8e295f7fad76fa62..4716dd26ce6ed7fa2463ec3ae056ac955111b996 100644 --- a/static_core/plugins/ets/tools/declgen_ts2sts/utils/lib/TypeUtils.ts +++ b/static_core/plugins/ets/tools/declgen_ts2sts/utils/lib/TypeUtils.ts @@ -146,6 +146,7 @@ export const InvalidFuncParaNames: Set = new Set([ 'short', 'long', 'int', + 'interface', 'char', 'byte', 'float',