mirror of
https://gitee.com/openharmony/developtools_ace_ets2bundle
synced 2025-02-25 04:51:15 +00:00
!3531 CodeCheck Fix: Super-large function reconstruction
Merge pull request !3531 from OneYuan/codecheck0620
This commit is contained in:
commit
8e39e4e1a7
114
compiler/src/process_sendable.ts
Normal file
114
compiler/src/process_sendable.ts
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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 ts from 'typescript';
|
||||
import { COMPONENT_SENDABLE_DECORATOR } from './pre_define';
|
||||
|
||||
function transformOptionalMemberForSendable(node: ts.PropertyDeclaration): ts.PropertyDeclaration {
|
||||
let updatedTypeNode: ts.TypeNode = node.type;
|
||||
|
||||
if (ts.isUnionTypeNode(updatedTypeNode)) {
|
||||
if (!updatedTypeNode.types.find(type => type.kind === ts.SyntaxKind.UndefinedKeyword)) {
|
||||
updatedTypeNode = ts.factory.createUnionTypeNode([
|
||||
...updatedTypeNode.types,
|
||||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
updatedTypeNode = ts.factory.createUnionTypeNode([
|
||||
updatedTypeNode,
|
||||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)
|
||||
]);
|
||||
}
|
||||
|
||||
return ts.factory.createPropertyDeclaration(
|
||||
node.modifiers,
|
||||
node.name,
|
||||
undefined,
|
||||
updatedTypeNode,
|
||||
node.initializer ? node.initializer : ts.factory.createIdentifier('undefined')
|
||||
);
|
||||
}
|
||||
|
||||
function removeSendableDecorator(modifiers: ts.NodeArray<ts.ModifierLike>): ts.NodeArray<ts.ModifierLike> {
|
||||
return ts.factory.createNodeArray(
|
||||
modifiers.filter(decorator => {
|
||||
const originalDecortor: string = decorator.getText().replace(/\(.*\)$/, '').trim();
|
||||
return originalDecortor !== COMPONENT_SENDABLE_DECORATOR;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
function updateSendableConstructor(constructor: ts.ConstructorDeclaration): ts.ConstructorDeclaration {
|
||||
// Skip the overloaded signature of the constructor
|
||||
if (constructor.body === undefined) {
|
||||
return constructor;
|
||||
}
|
||||
const statementArray: ts.Statement[] = [
|
||||
ts.factory.createExpressionStatement(ts.factory.createStringLiteral('use sendable')),
|
||||
...constructor.body.statements
|
||||
];
|
||||
|
||||
return ts.factory.updateConstructorDeclaration(
|
||||
constructor,
|
||||
constructor.modifiers,
|
||||
constructor.parameters,
|
||||
ts.factory.updateBlock(constructor.body, statementArray)
|
||||
);
|
||||
}
|
||||
|
||||
function addConstructorForSendableClass(members: ts.NodeArray<ts.ClassElement>): ts.NodeArray<ts.ClassElement> {
|
||||
const constructor: ts.ConstructorDeclaration = ts.factory.createConstructorDeclaration(
|
||||
undefined,
|
||||
[],
|
||||
ts.factory.createBlock(
|
||||
[ts.factory.createExpressionStatement(ts.factory.createStringLiteral('use sendable'))],
|
||||
true
|
||||
)
|
||||
);
|
||||
return ts.factory.createNodeArray([constructor, ...(members || [])]);
|
||||
}
|
||||
|
||||
export function processSendableClass(node: ts.ClassDeclaration): ts.ClassDeclaration {
|
||||
let hasConstructor = false;
|
||||
let updatedMembers: ts.NodeArray<ts.ClassElement> = node.members;
|
||||
let updatedModifiers: ts.NodeArray<ts.ModifierLike> = removeSendableDecorator(node.modifiers);
|
||||
|
||||
for (const member of node.members) {
|
||||
if (ts.isPropertyDeclaration(member) && member.questionToken) {
|
||||
const propertyDecl: ts.PropertyDeclaration = member as ts.PropertyDeclaration;
|
||||
const updatedPropertyDecl: ts.PropertyDeclaration = transformOptionalMemberForSendable(member);
|
||||
updatedMembers = ts.factory.createNodeArray(
|
||||
updatedMembers.map(member => (member === propertyDecl ? updatedPropertyDecl : member))
|
||||
);
|
||||
}
|
||||
if (ts.isConstructorDeclaration(member)) {
|
||||
hasConstructor = true;
|
||||
const constructor: ts.ConstructorDeclaration = member as ts.ConstructorDeclaration;
|
||||
updatedMembers = ts.factory.createNodeArray(
|
||||
updatedMembers.map(member => (member === constructor ? updateSendableConstructor(constructor) : member))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasConstructor) {
|
||||
updatedMembers = addConstructorForSendableClass(updatedMembers);
|
||||
}
|
||||
|
||||
node = ts.factory.updateClassDeclaration(node, updatedModifiers, node.name, node.typeParameters,
|
||||
node.heritageClauses, updatedMembers);
|
||||
|
||||
return node;
|
||||
}
|
@ -152,6 +152,7 @@ import {
|
||||
import constantDefine from './constant_define';
|
||||
import processStructComponentV2 from './process_struct_componentV2';
|
||||
import createAstNodeUtils from './create_ast_node_utils';
|
||||
import { processSendableClass } from './process_sendable'
|
||||
|
||||
export let transformLog: FileLog = new FileLog();
|
||||
export let contextGlobal: ts.TransformationContext;
|
||||
@ -372,7 +373,7 @@ export function processUISyntax(program: ts.Program, ut = false,
|
||||
pos: node.getStart()
|
||||
});
|
||||
}
|
||||
node = processClassSendable(node);
|
||||
node = processSendableClass(node);
|
||||
}
|
||||
}
|
||||
return ts.visitEachChild(node, processAllNodes, context);
|
||||
@ -1037,92 +1038,6 @@ function processConcurrent(node: ts.FunctionDeclaration): ts.FunctionDeclaration
|
||||
return node;
|
||||
}
|
||||
|
||||
function transformQuestionToken(node: ts.PropertyDeclaration): ts.PropertyDeclaration {
|
||||
let updatedTypeNode: ts.TypeNode = node.type;
|
||||
|
||||
if (ts.isUnionTypeNode(updatedTypeNode)) {
|
||||
if (!updatedTypeNode.types.find(type => type.kind === ts.SyntaxKind.UndefinedKeyword)) {
|
||||
updatedTypeNode = ts.factory.createUnionTypeNode([
|
||||
...updatedTypeNode.types,
|
||||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
updatedTypeNode = ts.factory.createUnionTypeNode([
|
||||
updatedTypeNode,
|
||||
ts.factory.createKeywordTypeNode(ts.SyntaxKind.UndefinedKeyword)
|
||||
]);
|
||||
}
|
||||
|
||||
return ts.factory.createPropertyDeclaration(
|
||||
node.modifiers,
|
||||
node.name,
|
||||
undefined,
|
||||
updatedTypeNode,
|
||||
node.initializer ? node.initializer : ts.factory.createIdentifier('undefined')
|
||||
);
|
||||
}
|
||||
|
||||
function processClassSendable(node: ts.ClassDeclaration): ts.ClassDeclaration {
|
||||
let hasConstructor = false;
|
||||
let updatedMembers: ts.NodeArray<ts.ClassElement> = node.members;
|
||||
let updatedModifiers: ts.NodeArray<ts.ModifierLike> = node.modifiers;
|
||||
|
||||
updatedModifiers = ts.factory.createNodeArray(
|
||||
updatedModifiers.filter(decorator => {
|
||||
const originalDecortor: string = decorator.getText().replace(/\(.*\)$/, '').trim();
|
||||
return originalDecortor !== COMPONENT_SENDABLE_DECORATOR;
|
||||
})
|
||||
);
|
||||
|
||||
for (const member of node.members) {
|
||||
if (ts.isPropertyDeclaration(member) && member.questionToken) {
|
||||
const propertyDecl: ts.PropertyDeclaration = member as ts.PropertyDeclaration;
|
||||
const updatedPropertyDecl: ts.PropertyDeclaration = transformQuestionToken(member);
|
||||
updatedMembers = ts.factory.createNodeArray(
|
||||
updatedMembers.map(member => (member === propertyDecl ? updatedPropertyDecl : member))
|
||||
);
|
||||
}
|
||||
if (ts.isConstructorDeclaration(member)) {
|
||||
hasConstructor = true;
|
||||
const constructor: ts.ConstructorDeclaration = member as ts.ConstructorDeclaration;
|
||||
if (constructor.body !== undefined) {
|
||||
const statementArray: ts.Statement[] = [
|
||||
ts.factory.createExpressionStatement(ts.factory.createStringLiteral('use sendable')),
|
||||
...constructor.body.statements
|
||||
];
|
||||
|
||||
const updatedConstructor: ts.ConstructorDeclaration = ts.factory.updateConstructorDeclaration(
|
||||
constructor,
|
||||
constructor.modifiers,
|
||||
constructor.parameters,
|
||||
ts.factory.updateBlock(constructor.body, statementArray));
|
||||
|
||||
updatedMembers = ts.factory.createNodeArray(
|
||||
updatedMembers.map(member => (member === constructor ? updatedConstructor : member))
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasConstructor) {
|
||||
const constructor: ts.ConstructorDeclaration = ts.factory.createConstructorDeclaration(
|
||||
undefined,
|
||||
[],
|
||||
ts.factory.createBlock(
|
||||
[ts.factory.createExpressionStatement(ts.factory.createStringLiteral('use sendable'))],
|
||||
true
|
||||
)
|
||||
);
|
||||
updatedMembers = ts.factory.createNodeArray([constructor, ...(updatedMembers || [])]);
|
||||
}
|
||||
|
||||
node = ts.factory.updateClassDeclaration(node, updatedModifiers, node.name, node.typeParameters,
|
||||
node.heritageClauses, updatedMembers);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
export function isOriginalExtend(node: ts.Block): boolean {
|
||||
let innerNode: ts.Node = node.statements[0];
|
||||
if (node.statements.length === 1 && ts.isExpressionStatement(innerNode)) {
|
||||
|
@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2024 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use rollupObject 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 { expect } from 'chai';
|
||||
import mocha from 'mocha';
|
||||
import * as ts from 'typescript';
|
||||
import path from 'path';
|
||||
import { hasDecorator } from '../../../lib/utils';
|
||||
import { processSendableClass } from '../../../lib/process_sendable';
|
||||
import { COMPONENT_SENDABLE_DECORATOR } from '../../../lib/pre_define';
|
||||
|
||||
const SENDABLE_WITHOUT_CONSTRUCTOR_CODE: string =
|
||||
`
|
||||
@Sendable
|
||||
class sendableClass {}
|
||||
`
|
||||
|
||||
const SENDABLE_WITHOUT_CONSTRUCTOR_CODE_EXPECT: string =
|
||||
'"use strict";\n' +
|
||||
'class sendableClass {\n' +
|
||||
' constructor() {\n' +
|
||||
' "use sendable";\n' +
|
||||
' }\n' +
|
||||
'}\n' +
|
||||
'//# sourceMappingURL=sendableTest.js.map'
|
||||
|
||||
const SENDABLE_WITH_CONSTRUCTOR_CODE: string =
|
||||
`
|
||||
@Sendable
|
||||
class sendableClass {
|
||||
constructor() {}
|
||||
}
|
||||
`
|
||||
|
||||
const SENDABLE_WITH_CONSTRUCTOR_CODE_EXPECT: string =
|
||||
'"use strict";\n' +
|
||||
'class sendableClass {\n' +
|
||||
' constructor() {\n' +
|
||||
' "use sendable";\n' +
|
||||
' }\n' +
|
||||
'}\n' +
|
||||
'//# sourceMappingURL=sendableTest.js.map'
|
||||
|
||||
const compilerOptions = ts.readConfigFile(
|
||||
path.resolve(__dirname, '../../../tsconfig.json'), ts.sys.readFile).config.compilerOptions;
|
||||
|
||||
function processSendable(): Function {
|
||||
return (context: ts.TransformationContext) => {
|
||||
const visitor: ts.Visitor = node => {
|
||||
if (ts.isClassDeclaration(node) && hasDecorator(node, COMPONENT_SENDABLE_DECORATOR)) {
|
||||
return processSendableClass(node);
|
||||
}
|
||||
return node;
|
||||
};
|
||||
|
||||
return (node: ts.SourceFile) => {
|
||||
return ts.visitEachChild(node, visitor, context);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
mocha.describe('process sendable class without constrcutor tests', function () {
|
||||
mocha.it('process sendable decorator', function () {
|
||||
const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_WITHOUT_CONSTRUCTOR_CODE, {
|
||||
compilerOptions: compilerOptions,
|
||||
fileName: "sendableTest.ts",
|
||||
transformers: { before: [ processSendable() ] }
|
||||
});
|
||||
console.log(result.outputText);
|
||||
expect(result.outputText == SENDABLE_WITHOUT_CONSTRUCTOR_CODE_EXPECT).to.be.true;
|
||||
});
|
||||
})
|
||||
|
||||
mocha.describe('process sendable class with constrcutor tests', function () {
|
||||
mocha.it('process sendable decorator', function () {
|
||||
const result: ts.TranspileOutput = ts.transpileModule(SENDABLE_WITH_CONSTRUCTOR_CODE, {
|
||||
compilerOptions: compilerOptions,
|
||||
fileName: "sendableTest.ts",
|
||||
transformers: { before: [ processSendable() ] }
|
||||
});
|
||||
console.log(result.outputText);
|
||||
expect(result.outputText == SENDABLE_WITH_CONSTRUCTOR_CODE_EXPECT).to.be.true;
|
||||
});
|
||||
})
|
Loading…
x
Reference in New Issue
Block a user