diff --git a/ets2panda/linter/rule-config.json b/ets2panda/linter/rule-config.json index dc1ab4b18ff833330e09c4c6d8617fdeb143d3b5..bd60d74d5c034a0f665bdf25e126106f12d6ef81 100644 --- a/ets2panda/linter/rule-config.json +++ b/ets2panda/linter/rule-config.json @@ -142,7 +142,10 @@ "arkui-buildernode-no-nestingbuildersupported", "arkui-sdk-common-deprecated-api", "arkui-sdk-common-whitelist-api", - "arkui-sdk-common-behaviorchange-api" + "arkui-sdk-common-behaviorchange-api", + "arkui-persistent-prop-serialization", + "arkui-persistent-props-serialization", + "arkui-persistencev2-connect-serialization" ], "builtin": [ "arkts-builtin-thisArgs", diff --git a/ets2panda/linter/src/lib/CookBookMsg.ts b/ets2panda/linter/src/lib/CookBookMsg.ts index 4d5245cdc2f123c5db1c9c52c19bff2eaee7e1a9..91b3d4b8b2ffc84ae441a293468209239358e000 100644 --- a/ets2panda/linter/src/lib/CookBookMsg.ts +++ b/ets2panda/linter/src/lib/CookBookMsg.ts @@ -415,6 +415,12 @@ cookBookTag[381] = 'The code block passed to stateStyles needs to be an arrow function (arkui-statestyles-block-need-arrow-func)'; cookBookTag[382] = 'Promiseconstructor only supports using resolve (undefined) (arkts-promise-with-void-type-need-undefined-as-resolve-arg)'; +cookBookTag[391] = + 'The class of the second parameter passed to the "persistProp" method must be a primitive type or Date type, or implement the "toJson" and "fromJson" methods (arkui-persistent-prop-serialization)'; +cookBookTag[392] = + 'The class of the "defaultValue" parameter in the literal passed to the "persistProps" method must be a primitive type or Date type, or implement the "toJson" and "fromJson" methods (arkui-persistent-props-serialization)'; +cookBookTag[393] = + 'When calling the "globalConnect" and "connect" methods, the parameter list of the methods needs to include "toJson" and "fromJson" (arkui-persistencev2-connect-serialization)'; cookBookTag[399] = 'ArkUI deprecated api check (arkui-no-deprecated-api)'; cookBookTag[400] = 'ArkUI sdk common deprecated api check (arkui-sdk-common-deprecated-api)'; cookBookTag[401] = 'ArkUI sdk common whitelist api check (arkui-sdk-common-whitelist-api)'; diff --git a/ets2panda/linter/src/lib/FaultAttrs.ts b/ets2panda/linter/src/lib/FaultAttrs.ts index d52e47f4756d9fdfe24a71db39b9d9170a58f06e..c5bd277904da40d3086aa9f2bbdfaada13448c65 100644 --- a/ets2panda/linter/src/lib/FaultAttrs.ts +++ b/ets2panda/linter/src/lib/FaultAttrs.ts @@ -291,6 +291,9 @@ faultsAttrs[FaultID.NondecimalBigint] = new FaultAttributes(377); faultsAttrs[FaultID.UnsupportOperator] = new FaultAttributes(378); faultsAttrs[FaultID.StateStylesBlockNeedArrowFunc] = new FaultAttributes(381); faultsAttrs[FaultID.PromiseVoidNeedResolveArg] = new FaultAttributes(382); +faultsAttrs[FaultID.PersistentPropNeedImplementMethod] = new FaultAttributes(391); +faultsAttrs[FaultID.PersistentPropsNeedImplementMethod] = new FaultAttributes(392); +faultsAttrs[FaultID.PersistenceV2ConnectNeedAddParam] = new FaultAttributes(393); faultsAttrs[FaultID.NoDeprecatedApi] = new FaultAttributes(399); faultsAttrs[FaultID.SdkCommonApiDeprecated] = new FaultAttributes(400); faultsAttrs[FaultID.SdkCommonApiWhiteList] = new FaultAttributes(401); diff --git a/ets2panda/linter/src/lib/FaultDesc.ts b/ets2panda/linter/src/lib/FaultDesc.ts index d2753c7fb5bb2837f6f6bcdb24b593be1c7bb459..58c24b4f955b8dfb27f08a39c030df095cc5a6b0 100644 --- a/ets2panda/linter/src/lib/FaultDesc.ts +++ b/ets2panda/linter/src/lib/FaultDesc.ts @@ -285,3 +285,6 @@ faultDesc[FaultID.NoESObjectSupport] = 'ESObject type cannot be used'; faultDesc[FaultID.SdkCommonApiDeprecated] = 'ArkUI sdk common deprecated api check'; faultDesc[FaultID.SdkCommonApiWhiteList] = 'ArkUI sdk common whiteList api check'; faultDesc[FaultID.SdkCommonApiBehaviorChange] = 'ArkUI sdk common behavior change api check'; +faultDesc[FaultID.PersistentPropNeedImplementMethod] = 'Serialization needs class to implement the specific methods'; +faultDesc[FaultID.PersistentPropsNeedImplementMethod] = 'Serialization needs class to implement the specific methods'; +faultDesc[FaultID.PersistenceV2ConnectNeedAddParam] = 'Serialization needs class to implement the specific methods'; diff --git a/ets2panda/linter/src/lib/Problems.ts b/ets2panda/linter/src/lib/Problems.ts index d607d731b137835c97f5cc8fd29fe9796cd46104..9f9cc40485b526a20b824f81414b5df932a3183b 100644 --- a/ets2panda/linter/src/lib/Problems.ts +++ b/ets2panda/linter/src/lib/Problems.ts @@ -284,6 +284,9 @@ export enum FaultID { SdkCommonApiDeprecated, SdkCommonApiWhiteList, SdkCommonApiBehaviorChange, + PersistentPropNeedImplementMethod, + PersistentPropsNeedImplementMethod, + PersistenceV2ConnectNeedAddParam, // this should always be last enum LAST_ID } diff --git a/ets2panda/linter/src/lib/TypeScriptLinter.ts b/ets2panda/linter/src/lib/TypeScriptLinter.ts index 2658cb6a0d25c67bc325d128ec695ae4c4794efe..a6a69f2f1bfa66a2d682975c94e4d83f513d604d 100644 --- a/ets2panda/linter/src/lib/TypeScriptLinter.ts +++ b/ets2panda/linter/src/lib/TypeScriptLinter.ts @@ -122,7 +122,15 @@ import { VIRTUAL_SCROLL_IDENTIFIER, BUILDERNODE_D_TS, BuilderNodeFunctionName, - NESTING_BUILDER_SUPPORTED + NESTING_BUILDER_SUPPORTED, + COMMON_TS_ETS_API_D_TS, + UI_STATE_MANAGEMENT_D_TS, + PERSIST_PROP_FUNC_NAME, + PERSIST_PROPS_FUNC_NAME, + GLOBAL_CONNECT_FUNC_NAME, + CONNECT_FUNC_NAME, + serializationTypeFlags, + serializationTypeName } from './utils/consts/ArkuiConstants'; import { arkuiImportList } from './utils/consts/ArkuiImportList'; import type { IdentifierAndArguments, ForbidenAPICheckResult } from './utils/consts/InteropAPI'; @@ -5529,6 +5537,7 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { this.handleStateStyles(node); this.handleCallExpressionForRepeat(node); this.handleNodeForWrappedBuilder(node); + this.handleCallExpressionForSerialization(node); } handleNoTsLikeFunctionCall(callExpr: ts.CallExpression): void { @@ -14431,4 +14440,122 @@ export class TypeScriptLinter extends BaseTypeScriptLinter { node.right.text === '0' ); } + + private handleCallExpressionForSerialization(node: ts.CallExpression): void { + if (!this.options.arkts2) { + return; + } + + const propertyAccess = node.expression; + if (!ts.isPropertyAccessExpression(propertyAccess)) { + return; + } + + const persistentClass = propertyAccess.expression; + if (!ts.isIdentifier(persistentClass)) { + return; + } + + switch (persistentClass.getText()) { + case StorageTypeName.PersistentStorage: + if (this.isDeclInTargetFile(persistentClass, COMMON_TS_ETS_API_D_TS)) { + this.handleCallExpressionForPersistentStorage(node, propertyAccess); + } + break; + case StorageTypeName.PersistenceV2: + if (this.isDeclInTargetFile(persistentClass, UI_STATE_MANAGEMENT_D_TS)) { + this.handleCallExpressionForPersistenceV2(node, propertyAccess); + } + break; + default: + } + } + + private handleCallExpressionForPersistentStorage( + callExpr: ts.CallExpression, + propertyAccess: ts.PropertyAccessExpression + ): void { + const funcName = propertyAccess.name.getText(); + + switch (funcName) { + case PERSIST_PROP_FUNC_NAME: + if (!this.checkPersistPropForSerialization(callExpr)) { + this.incrementCounters(callExpr, FaultID.PersistentPropNeedImplementMethod); + } + break; + case PERSIST_PROPS_FUNC_NAME: + if (!this.checkPersistPropsForSerialization(callExpr)) { + this.incrementCounters(callExpr, FaultID.PersistentPropsNeedImplementMethod); + } + break; + default: + } + } + + private checkPersistPropForSerialization(callExpr: ts.CallExpression): boolean { + const arg = callExpr.arguments?.[1]; + return !arg || this.checkArgumentForSerialization(arg); + } + + private checkPersistPropsForSerialization(callExpr: ts.CallExpression): boolean { + const arg = callExpr.arguments?.[0]; + if (!arg || !ts.isArrayLiteralExpression(arg)) { + return true; + } + + const literals = arg.elements; + let serializable: boolean = true; + for (const literal of literals) { + if (!ts.isObjectLiteralExpression(literal)) { + continue; + } + const property = literal.properties?.[1]; + if (!property || !ts.isPropertyAssignment(property)) { + continue; + } + if (!this.checkArgumentForSerialization(property.initializer)) { + serializable = false; + break; + } + } + + return serializable; + } + + private checkArgumentForSerialization(arg: ts.Node): boolean { + const type = this.tsTypeChecker.getTypeAtLocation(arg); + + if (type.isUnion()) { + if ( + type.types.some((type) => { + return !this.isSpecificTypeOfSerialization(type); + }) + ) { + return false; + } + return true; + } + + return this.isSpecificTypeOfSerialization(type); + } + + private isSpecificTypeOfSerialization(type: ts.Type): boolean { + const typeName = this.tsTypeChecker.typeToString(type); + return serializationTypeFlags.has(type.flags) || serializationTypeName.has(typeName); + } + + private handleCallExpressionForPersistenceV2( + callExpr: ts.CallExpression, + propertyAccess: ts.PropertyAccessExpression + ): void { + const funcName = propertyAccess.name.getText(); + if (funcName !== GLOBAL_CONNECT_FUNC_NAME && funcName !== CONNECT_FUNC_NAME) { + return; + } + + const errorMsg = + `When calling the "${funcName}" method, the parameter list of the methods needs to include ` + + '"toJson" and "fromJson" (arkui-persistencev2-connect-serialization)'; + this.incrementCounters(callExpr, FaultID.PersistenceV2ConnectNeedAddParam, undefined, errorMsg); + } } diff --git a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts index 40063205dac9d0f9b4ed214aec4b8922450b3a67..61081566a21ebeb31a8e02be92b48ae77adea900 100644 --- a/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts +++ b/ets2panda/linter/src/lib/utils/consts/ArkuiConstants.ts @@ -13,6 +13,8 @@ * limitations under the License. */ +import * as ts from 'typescript'; + export const DOUBLE_DOLLAR_IDENTIFIER = '$$'; export const THIS_IDENTIFIER = 'this'; export const ATTRIBUTE_SUFFIX = 'Attribute'; @@ -42,7 +44,9 @@ export enum CustomInterfaceName { export enum StorageTypeName { LocalStorage = 'LocalStorage', - AppStorage = 'AppStorage' + AppStorage = 'AppStorage', + PersistentStorage = 'PersistentStorage', + PersistenceV2 = 'PersistenceV2' } export enum PropDecoratorName { @@ -85,6 +89,74 @@ export const skipImportDecoratorName: Set = new Set([ 'LocalStorageProp' ]); +export const serializationTypeFlags: Set = new Set([ + ts.TypeFlags.String, + ts.TypeFlags.Number, + ts.TypeFlags.Boolean, + ts.TypeFlags.StringLiteral, + ts.TypeFlags.NumberLiteral, + ts.TypeFlags.BooleanLiteral, + ts.TypeFlags.Undefined, + ts.TypeFlags.Null +]); + +export const serializationTypeName: Set = new Set([ + 'Date', + 'number', + 'boolean', + 'string', + 'undefined', + 'null', + 'Date[]', + 'number[]', + 'boolean[]', + 'string[]', + 'undefined[]', + 'null[]', + 'Set', + 'Set', + 'Set', + 'Set', + 'Set', + 'Set', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map', + 'Map' +]); + export const customLayoutFunctionName: Set = new Set(['onMeasureSize', 'onPlaceChildren']); export const ENTRY_DECORATOR_NAME = 'Entry'; @@ -104,3 +176,10 @@ export const STATE_MANAGEMENT_MODULE = '@ohos.arkui.StateManagement'; export const BUILDERNODE_D_TS = 'BuilderNode.d.ts'; export const NESTING_BUILDER_SUPPORTED = 'nestingBuilderSupported'; + +export const COMMON_TS_ETS_API_D_TS = 'common_ts_ets_api.d.ts'; +export const UI_STATE_MANAGEMENT_D_TS = '@ohos.arkui.StateManagement.d.ts'; +export const PERSIST_PROP_FUNC_NAME = 'persistProp'; +export const PERSIST_PROPS_FUNC_NAME = 'persistProps'; +export const GLOBAL_CONNECT_FUNC_NAME = 'globalConnect'; +export const CONNECT_FUNC_NAME = 'connect'; diff --git a/ets2panda/linter/test/main/persist_serial_1.ets b/ets2panda/linter/test/main/persist_serial_1.ets new file mode 100644 index 0000000000000000000000000000000000000000..72a51f4537e70825aac96c0813e56c554555ac68 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_1.ets @@ -0,0 +1,70 @@ +/* + * Copyright (c) 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. + */ + +import { PersistentStorage } from './ui_modules/common_ts_ets_api'; + +class MyClassA {} + +function MyGet1() { + if (1 > 0) { + return 1 + } else { + return 2 + } +} + +function MyGet2() { + if (1 > 0) { + return 0 + } else { + return new MyClassA() + } +} + +const a1 = new MyClassA(); +const a2 = new MyClassA(); +const myArr1: Array = new Array(1, 2); +const mySet1: Set = new Set([1, 2, 3]); +const myMap1: Map = new Map([["jack", 3], ["tom", 2]]); +const myMap2: Map = new Map([[1, a1], [2, a2]]); + +PersistentStorage.persistProp('PropA', 47); +PersistentStorage.persistProp('PropA', true); +PersistentStorage.persistProp('PropA', "Jack"); +PersistentStorage.persistProp('PropA', null); +PersistentStorage.persistProp('PropA', undefined); +PersistentStorage.persistProp('PropA', new Date()); +PersistentStorage.persistProp('PropA', a1); // error +PersistentStorage.persistProp('PropA', new MyClassA()); // error +PersistentStorage.persistProp('PropA', MyGet1()); +PersistentStorage.persistProp('PropA', MyGet2()); // error +PersistentStorage.persistProp('PropA', 1 < 0 ? 1 : new MyClassA()); // error + +PersistentStorage.persistProp('PropA', new Array(1, 2)); +PersistentStorage.persistProp('PropA', new Array("jack", "tom")); +PersistentStorage.persistProp('PropA', new Array(myArr1)); // error +PersistentStorage.persistProp('PropA', new Array(new MyClassA())); // error +PersistentStorage.persistProp('PropA', new Array(a1)); // error + +PersistentStorage.persistProp('PropA', new Set([1, 2])); +PersistentStorage.persistProp('PropA', new Set(["jack", "tom"])); +PersistentStorage.persistProp('PropA', mySet1); +PersistentStorage.persistProp('PropA', new Set([new MyClassA()])); // error +PersistentStorage.persistProp('PropA', new Set([a1])); // error + +PersistentStorage.persistProp('PropA', new Map([["jack", 3], ["tom", 2]])); +PersistentStorage.persistProp('PropA', new Map([[1, a1], [2, a2]])); // error +PersistentStorage.persistProp('PropA', myMap1); +PersistentStorage.persistProp('PropA', myMap2); // error diff --git a/ets2panda/linter/test/main/persist_serial_1.ets.args.json b/ets2panda/linter/test/main/persist_serial_1.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9992d92461d66e16b80975e33f95872c06af54 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_1.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 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." + ], + "mode": { + "arkts2": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_1.ets.arkts2.json b/ets2panda/linter/test/main/persist_serial_1.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..5a82da735eddf67b7d90486d5d305cda9d8052ae --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_1.ets.arkts2.json @@ -0,0 +1,278 @@ +{ + "copyright": [ + "Copyright (c) 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." + ], + "result": [ + { + "line": 38, + "column": 31, + "endLine": 38, + "endColumn": 46, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 29, + "endLine": 39, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 37, + "endLine": 40, + "endColumn": 71, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 39, + "endLine": 41, + "endColumn": 66, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 49, + "column": 1, + "endLine": 49, + "endColumn": 43, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 1, + "endLine": 50, + "endColumn": 55, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 1, + "endLine": 52, + "endColumn": 49, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 1, + "endLine": 53, + "endColumn": 67, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 40, + "endLine": 55, + "endColumn": 55, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 40, + "endLine": 56, + "endColumn": 64, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 1, + "endLine": 57, + "endColumn": 58, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 57, + "column": 40, + "endLine": 57, + "endColumn": 57, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 1, + "endLine": 58, + "endColumn": 66, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 40, + "endLine": 58, + "endColumn": 65, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 1, + "endLine": 59, + "endColumn": 54, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 40, + "endLine": 59, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 40, + "endLine": 61, + "endColumn": 55, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 40, + "endLine": 62, + "endColumn": 64, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 1, + "endLine": 64, + "endColumn": 66, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 40, + "endLine": 64, + "endColumn": 65, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 1, + "endLine": 65, + "endColumn": 54, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 40, + "endLine": 65, + "endColumn": 53, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 40, + "endLine": 67, + "endColumn": 74, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 1, + "endLine": 68, + "endColumn": 68, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + }, + { + "line": 68, + "column": 40, + "endLine": 68, + "endColumn": 67, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 70, + "column": 1, + "endLine": 70, + "endColumn": 47, + "problem": "PersistentPropNeedImplementMethod", + "suggest": "", + "rule": "The class of the second parameter passed to the \"persistProp\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-prop-serialization)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_1.ets.json b/ets2panda/linter/test/main/persist_serial_1.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_1.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 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." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_2.ets b/ets2panda/linter/test/main/persist_serial_2.ets new file mode 100644 index 0000000000000000000000000000000000000000..5f0214c5673ff0dca84f14772571116851161114 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_2.ets @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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. + */ + +import { PersistentStorage } from './ui_modules/common_ts_ets_api'; + +class MyClassA {} + +function MyGet1() { + if (1 > 0) { + return 1 + } else { + return 2 + } +} + +function MyGet2() { + if (1 > 0) { + return 0 + } else { + return new MyClassA() + } +} + +const a1 = new MyClassA(); +const a2 = new MyClassA(); +const myArr1: Array = new Array(1, 2); +const mySet1: Set = new Set([1, 2, 3]); +const myMap1: Map = new Map([["jack", 3], ["tom", 2]]); +const myMap2: Map = new Map([[1, a1], [2, a2]]); + +PersistentStorage.persistProps([{ key: 'highScore', defaultValue: '0' }, { key: 'wightScore', defaultValue: '1' }]); +PersistentStorage.persistProps([{ key: 'highScore', defaultValue: 0 }, { key: 'wightScore', defaultValue: 1 }]); +PersistentStorage.persistProps([{ key: 'highScore', defaultValue: false }, { key: 'wightScore', defaultValue: true }]); + +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new MyClassA() }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: 1 < 0 ? 1 : new MyClassA() }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: MyGet1() }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: MyGet2() }]); // error + +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array(1, 2) }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array("jack", "tom") }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array(myArr1) }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array(new MyClassA()) }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Array(a1) }]); // error + +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Set([1, 2]) }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Set(["jack", "tom"]) }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: mySet1 }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Set([new MyClassA()]) }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Set([a1]) }]); // error + +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Map([["jack", 3], ["tom", 2]]) }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: new Map([[1, a1], [2, a2]]) }]); // error +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: myMap1 }]); +PersistentStorage.persistProps([{ key: 'PropA', defaultValue: '0' }, { key: 'PropB', defaultValue: myMap2 }]); // error \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_2.ets.args.json b/ets2panda/linter/test/main/persist_serial_2.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9992d92461d66e16b80975e33f95872c06af54 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_2.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 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." + ], + "mode": { + "arkts2": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_2.ets.arkts2.json b/ets2panda/linter/test/main/persist_serial_2.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..16144bf46db661eee43d885cd407b12c36a11353 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_2.ets.arkts2.json @@ -0,0 +1,268 @@ +{ + "copyright": [ + "Copyright (c) 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." + ], + "result": [ + { + "line": 38, + "column": 31, + "endLine": 38, + "endColumn": 46, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 39, + "column": 29, + "endLine": 39, + "endColumn": 47, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 37, + "endLine": 40, + "endColumn": 71, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 39, + "endLine": 41, + "endColumn": 66, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 47, + "column": 1, + "endLine": 47, + "endColumn": 118, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 48, + "column": 1, + "endLine": 48, + "endColumn": 130, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 50, + "column": 1, + "endLine": 50, + "endColumn": 112, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 52, + "column": 100, + "endLine": 52, + "endColumn": 115, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 53, + "column": 100, + "endLine": 53, + "endColumn": 124, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 1, + "endLine": 54, + "endColumn": 121, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 54, + "column": 100, + "endLine": 54, + "endColumn": 117, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 1, + "endLine": 55, + "endColumn": 129, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 55, + "column": 100, + "endLine": 55, + "endColumn": 125, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 1, + "endLine": 56, + "endColumn": 117, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 56, + "column": 100, + "endLine": 56, + "endColumn": 113, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 58, + "column": 100, + "endLine": 58, + "endColumn": 115, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 59, + "column": 100, + "endLine": 59, + "endColumn": 124, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 1, + "endLine": 61, + "endColumn": 129, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 61, + "column": 100, + "endLine": 61, + "endColumn": 125, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 1, + "endLine": 62, + "endColumn": 117, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 62, + "column": 100, + "endLine": 62, + "endColumn": 113, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 64, + "column": 100, + "endLine": 64, + "endColumn": 134, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 1, + "endLine": 65, + "endColumn": 131, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + }, + { + "line": 65, + "column": 100, + "endLine": 65, + "endColumn": 127, + "problem": "GenericCallNoTypeArgs", + "suggest": "", + "rule": "Type inference in case of generic function calls is limited (arkts-no-inferred-generic-params)", + "severity": "ERROR" + }, + { + "line": 67, + "column": 1, + "endLine": 67, + "endColumn": 110, + "problem": "PersistentPropsNeedImplementMethod", + "suggest": "", + "rule": "The class of the \"defaultValue\" parameter in the literal passed to the \"persistProps\" method must be a primitive type or Date type, or implement the \"toJson\" and \"fromJson\" methods (arkui-persistent-props-serialization)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_2.ets.json b/ets2panda/linter/test/main/persist_serial_2.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..ca88f857e960b437dcf767c0ac40be998c8f1236 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_2.ets.json @@ -0,0 +1,17 @@ +{ + "copyright": [ + "Copyright (c) 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." + ], + "result": [] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_3.ets b/ets2panda/linter/test/main/persist_serial_3.ets new file mode 100644 index 0000000000000000000000000000000000000000..f314b869406c1ed70ab17236974b8cd2cbe9b32b --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_3.ets @@ -0,0 +1,49 @@ +/* + * Copyright (c) 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. + */ + +import { ConnectOptions, PersistenceV2, Type } from './ui_modules/@kit.ArkUI'; +import { contextConstant } from '@kit.AbilityKit'; + +PersistenceV2.notifyOnError((key: string, reason: string, msg: string) => {}) + +@ObservedV2 +class SampleChild { + @Trace childId: number = 0; + groupId: number = 1; +} + +@ObservedV2 +class Sample { + @Type(SampleChild) + @Trace father: SampleChild = new SampleChild(); +} + +@Entry +@ComponentV2 +struct TestCase2 { + @Local p1: Sample | undefined = PersistenceV2.globalConnect({type: Sample, defaultCreator:() => new Sample()}); // error + + @Local p2: Sample | undefined = PersistenceV2.globalConnect({type: Sample, key: 'global1', defaultCreator:() => new Sample(), areaMode: contextConstant.AreaMode.EL1}); // error + + options: ConnectOptions = {type: Sample, key: 'global2', defaultCreator:() => new Sample()}; + @Local p3: Sample | undefined = PersistenceV2.globalConnect(this.options); // error + + @Local p4: Sample | undefined = PersistenceV2.globalConnect({type: Sample, key: 'global1', defaultCreator:() => new Sample(), areaMode: 3}); // error + + @Local p5: Sample | undefined = PersistenceV2.connect(Sample, () => new Sample()); // error + + build() { + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_3.ets.args.json b/ets2panda/linter/test/main/persist_serial_3.ets.args.json new file mode 100644 index 0000000000000000000000000000000000000000..ec9992d92461d66e16b80975e33f95872c06af54 --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_3.ets.args.json @@ -0,0 +1,19 @@ +{ + "copyright": [ + "Copyright (c) 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." + ], + "mode": { + "arkts2": "" + } +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_3.ets.arkts2.json b/ets2panda/linter/test/main/persist_serial_3.ets.arkts2.json new file mode 100644 index 0000000000000000000000000000000000000000..151971eb234021de3a50c2110398f41caac4855e --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_3.ets.arkts2.json @@ -0,0 +1,248 @@ +{ + "copyright": [ + "Copyright (c) 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." + ], + "result": [ + { + "line": 16, + "column": 41, + "endLine": 16, + "endColumn": 45, + "problem": "InvalidIdentifier", + "suggest": "", + "rule": "This keyword cannot be used as identifiers (arkts-invalid-identifier)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 35, + "endLine": 36, + "endColumn": 113, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"globalConnect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 35, + "endLine": 36, + "endColumn": 113, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 35, + "endLine": 38, + "endColumn": 169, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"globalConnect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 35, + "endLine": 38, + "endColumn": 169, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 40, + "column": 44, + "endLine": 40, + "endColumn": 50, + "problem": "ClassAsObjectError", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 35, + "endLine": 41, + "endColumn": 76, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"globalConnect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 35, + "endLine": 41, + "endColumn": 76, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 35, + "endLine": 43, + "endColumn": 142, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"globalConnect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 35, + "endLine": 43, + "endColumn": 142, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 35, + "endLine": 45, + "endColumn": 84, + "problem": "PersistenceV2ConnectNeedAddParam", + "suggest": "", + "rule": "When calling the \"connect\" method, the parameter list of the methods needs to include \"toJson\" and \"fromJson\" (arkui-persistencev2-connect-serialization)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 35, + "endLine": 45, + "endColumn": 84, + "problem": "LimitedVoidType", + "suggest": "", + "rule": "Type \"void\" has no instances.(arkts-limited-void-type)", + "severity": "ERROR" + }, + { + "line": 21, + "column": 2, + "endLine": 21, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ObservedV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 23, + "column": 4, + "endLine": 23, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Trace\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 27, + "column": 2, + "endLine": 27, + "endColumn": 12, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ObservedV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 30, + "column": 4, + "endLine": 30, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Trace\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 33, + "column": 2, + "endLine": 33, + "endColumn": 7, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Entry\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 34, + "column": 2, + "endLine": 34, + "endColumn": 13, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"ComponentV2\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 36, + "column": 4, + "endLine": 36, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 38, + "column": 4, + "endLine": 38, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 41, + "column": 4, + "endLine": 41, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 43, + "column": 4, + "endLine": 43, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + }, + { + "line": 45, + "column": 4, + "endLine": 45, + "endColumn": 9, + "problem": "UIInterfaceImport", + "suggest": "", + "rule": "The ArkUI interface \"Local\" should be imported before it is used (arkui-modular-interface)", + "severity": "ERROR" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/persist_serial_3.ets.json b/ets2panda/linter/test/main/persist_serial_3.ets.json new file mode 100644 index 0000000000000000000000000000000000000000..097b66ff3c436ef1e2f9b8373703c5bb650894de --- /dev/null +++ b/ets2panda/linter/test/main/persist_serial_3.ets.json @@ -0,0 +1,28 @@ +{ + "copyright": [ + "Copyright (c) 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." + ], + "result": [ + { + "line": 40, + "column": 44, + "endLine": 40, + "endColumn": 50, + "problem": "ClassAsObject", + "suggest": "", + "rule": "Classes cannot be used as objects (arkts-no-classes-as-obj)", + "severity": "WARNING" + } + ] +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ui_modules/@kit.ArkUI.d.ts b/ets2panda/linter/test/main/ui_modules/@kit.ArkUI.d.ts index cf71890e70f66a55e52e5cc7d90ca8f1207ca921..638b3a1404338d3dc8cd16d181fe002e024cbbce 100644 --- a/ets2panda/linter/test/main/ui_modules/@kit.ArkUI.d.ts +++ b/ets2panda/linter/test/main/ui_modules/@kit.ArkUI.d.ts @@ -14,4 +14,5 @@ */ import { BuilderNode } from './@ohos.arkui.node'; -export { BuilderNode }; \ No newline at end of file +import { PersistenceV2 } from './@ohos.arkui.StateManagement'; +export { BuilderNode, PersistenceV2 }; \ No newline at end of file diff --git a/ets2panda/linter/test/main/ui_modules/@ohos.arkui.StateManagement.d.ts b/ets2panda/linter/test/main/ui_modules/@ohos.arkui.StateManagement.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..3ba4dbfcb73b09a4e861b21440ed15c3af639ff7 --- /dev/null +++ b/ets2panda/linter/test/main/ui_modules/@ohos.arkui.StateManagement.d.ts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 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. + */ + +export declare class PersistenceV2 extends AppStorageV2{ + static globalConnect(): void; +} + +declare class AppStorageV2 { + static connect(): void; +} \ No newline at end of file diff --git a/ets2panda/linter/test/main/ui_modules/common_ts_ets_api.d.ts b/ets2panda/linter/test/main/ui_modules/common_ts_ets_api.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..2634f5bd9faa4449476f8844e42819c4eaaf1876 --- /dev/null +++ b/ets2panda/linter/test/main/ui_modules/common_ts_ets_api.d.ts @@ -0,0 +1,19 @@ +/* + * Copyright (c) 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. + */ + +export declare class PersistentStorage { + static persistProp(): void; + static PersistProps(): void; +} \ No newline at end of file