mirror of
https://gitee.com/openharmony/developtools_ace_ets2bundle
synced 2025-03-01 06:46:02 +00:00
support validate track and observed. Signed-off-by: lihong <lihong67@huawei.com> Change-Id: Ia679b6467d7866fd03ad8bf7d9c7673b02a74691
This commit is contained in:
parent
4a94ab0590
commit
f46bf2946e
@ -50,6 +50,7 @@ export const COMPONENT_CUSTOM_DECORATOR: string = 'COMPONENT_CUSTOM_DECORATOR';
|
||||
export const COMPONENT_REQUIRE_DECORATOR: string = '@Require';
|
||||
|
||||
export const CLASS_TRACK_DECORATOR: string = 'Track';
|
||||
export const CLASS_MIN_TRACK_DECORATOR: string = 'track';
|
||||
|
||||
export const COMPONENT_DECORATORS_PARAMS: Set<string> = new Set([COMPONENT_CONSUME_DECORATOR,
|
||||
COMPONENT_STORAGE_PROP_DECORATOR, COMPONENT_STORAGE_LINK_DECORATOR, COMPONENT_PROVIDE_DECORATOR,
|
||||
@ -68,6 +69,7 @@ export const STRUCT_DECORATORS: Set<string> = new Set([...INNER_COMPONENT_DECORA
|
||||
|
||||
export const COMPONENT_OBSERVED_DECORATOR: string = '@Observed';
|
||||
export const OBSERVED: string = 'Observed';
|
||||
export const MIN_OBSERVED: string = 'observed';
|
||||
export const COMPONENT_BUILDER_DECORATOR: string = '@Builder';
|
||||
export const COMPONENT_EXTEND_DECORATOR: string = '@Extend';
|
||||
export const COMPONENT_STYLES_DECORATOR: string = '@Styles';
|
||||
|
@ -58,7 +58,9 @@ import {
|
||||
CHECK_COMPONENT_ANIMATABLE_EXTEND_DECORATOR,
|
||||
CLASS_TRACK_DECORATOR,
|
||||
COMPONENT_REQUIRE_DECORATOR,
|
||||
COMPONENT_SENDABLE_DECORATOR
|
||||
COMPONENT_SENDABLE_DECORATOR,
|
||||
CLASS_MIN_TRACK_DECORATOR,
|
||||
MIN_OBSERVED
|
||||
} from './pre_define';
|
||||
import {
|
||||
INNER_COMPONENT_NAMES,
|
||||
@ -429,21 +431,34 @@ function visitAllNode(node: ts.Node, sourceFileNode: ts.SourceFile, allComponent
|
||||
extendResult.componentName, node.name.getText());
|
||||
}
|
||||
} else if (hasDecorator(node, COMPONENT_STYLES_DECORATOR)) {
|
||||
if (ts.isBlock(node.body) && node.body.statements) {
|
||||
if (ts.isFunctionDeclaration(node)) {
|
||||
GLOBAL_STYLE_FUNCTION.set(node.name.getText(), node.body);
|
||||
} else {
|
||||
INNER_STYLE_FUNCTION.set(node.name.getText(), node.body);
|
||||
}
|
||||
STYLES_ATTRIBUTE.add(node.name.getText());
|
||||
BUILDIN_STYLE_NAMES.add(node.name.getText());
|
||||
}
|
||||
collectStyles(node);
|
||||
}
|
||||
if (hasDecorator(node, COMPONENT_CONCURRENT_DECORATOR)) {
|
||||
// ark compiler's feature
|
||||
checkConcurrentDecorator(node, log, sourceFileNode);
|
||||
}
|
||||
}
|
||||
checkDecorator(sourceFileNode, node, log, structContext, classContext);
|
||||
node.getChildren().forEach((item: ts.Node) => visitAllNode(item, sourceFileNode, allComponentNames,
|
||||
log, structContext, classContext, fileQuery));
|
||||
structContext = false;
|
||||
classContext = false;
|
||||
}
|
||||
|
||||
function collectStyles(node: ts.FunctionLikeDeclarationBase): void {
|
||||
if (ts.isBlock(node.body) && node.body.statements) {
|
||||
if (ts.isFunctionDeclaration(node)) {
|
||||
GLOBAL_STYLE_FUNCTION.set(node.name.getText(), node.body);
|
||||
} else {
|
||||
INNER_STYLE_FUNCTION.set(node.name.getText(), node.body);
|
||||
}
|
||||
STYLES_ATTRIBUTE.add(node.name.getText());
|
||||
BUILDIN_STYLE_NAMES.add(node.name.getText());
|
||||
}
|
||||
}
|
||||
|
||||
function checkDecorator(sourceFileNode: ts.SourceFile, node: ts.Node,
|
||||
log: LogInfo[], structContext: boolean, classContext: boolean): void {
|
||||
if (ts.isIdentifier(node) && (ts.isDecorator(node.parent) ||
|
||||
(ts.isCallExpression(node.parent) && ts.isDecorator(node.parent.parent)))) {
|
||||
const decoratorName: string = node.escapedText.toString();
|
||||
@ -451,24 +466,41 @@ function visitAllNode(node: ts.Node, sourceFileNode: ts.SourceFile, allComponent
|
||||
validateMethodDecorator(sourceFileNode, node, log, structContext, decoratorName);
|
||||
validateClassDecorator(sourceFileNode, node, log, classContext, decoratorName);
|
||||
}
|
||||
node.getChildren().forEach((item: ts.Node) => visitAllNode(item, sourceFileNode, allComponentNames,
|
||||
log, structContext, classContext, fileQuery));
|
||||
structContext = false;
|
||||
classContext = false;
|
||||
}
|
||||
|
||||
const classDecorators: string[] = [CLASS_TRACK_DECORATOR, CLASS_MIN_TRACK_DECORATOR, MIN_OBSERVED];
|
||||
|
||||
function validateClassDecorator(sourceFileNode: ts.SourceFile, node: ts.Identifier, log: LogInfo[],
|
||||
classContext: boolean, decoratorName: string): void {
|
||||
if (!classContext && decoratorName === CLASS_TRACK_DECORATOR) {
|
||||
const message: string = `The '@Track' decorator can only be used in 'class'.`;
|
||||
if (!classContext && classDecorators.includes(decoratorName)) {
|
||||
const message: string = `The '@${decoratorName}' decorator can only be used in 'class'.`;
|
||||
addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
|
||||
} else if ('@' + decoratorName === COMPONENT_SENDABLE_DECORATOR &&
|
||||
(!node.parent || !node.parent.parent || !ts.isClassDeclaration(node.parent.parent))) {
|
||||
const message: string = 'The \'@Sendable\' decorator can only be added to \'class\'.';
|
||||
addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
|
||||
} else if (decoratorName === CLASS_MIN_TRACK_DECORATOR && !hasObservedClass(classContext, node)) {
|
||||
const message: string = `The '@track' decorator can only be used within a 'class' decorated with observed.`;
|
||||
addLog(LogType.ERROR, message, node.pos, log, sourceFileNode);
|
||||
}
|
||||
}
|
||||
|
||||
function parseClassDecorator(node: ts.ClassDeclaration): boolean {
|
||||
const decorators: readonly ts.Decorator[] = ts.getAllDecorators(node);
|
||||
return decorators.some((item: ts.Decorator) => {
|
||||
return ts.isIdentifier(item.expression) && item.expression.escapedText.toString() === MIN_OBSERVED;
|
||||
});
|
||||
}
|
||||
|
||||
function hasObservedClass(classContext: boolean, node: ts.Identifier): boolean {
|
||||
let isObservedClass: boolean = false;
|
||||
if (classContext && ts.isDecorator(node.parent) && ts.isPropertyDeclaration(node.parent.parent) &&
|
||||
ts.isClassDeclaration(node.parent.parent.parent)) {
|
||||
isObservedClass = parseClassDecorator(node.parent.parent.parent);
|
||||
}
|
||||
return isObservedClass;
|
||||
}
|
||||
|
||||
function validateStructDecorator(sourceFileNode: ts.SourceFile, node: ts.Identifier, log: LogInfo[],
|
||||
structContext: boolean, decoratorName: string): void {
|
||||
if (!structContext && STRUCT_DECORATORS.has(`@${decoratorName}`)) {
|
||||
|
@ -280,5 +280,23 @@
|
||||
"@Track": {
|
||||
"message": "The '@Track' decorator can only be used in 'class'.",
|
||||
"type": "ERROR"
|
||||
}
|
||||
},
|
||||
"validate_track_observed": [
|
||||
{
|
||||
"message": "The struct 'child' use invalid decorator.",
|
||||
"type": "WARN"
|
||||
},
|
||||
{
|
||||
"message": "The '@track' decorator can only be used in 'class'.",
|
||||
"type": "ERROR"
|
||||
},
|
||||
{
|
||||
"message": "The '@observed' decorator can only be used in 'class'.",
|
||||
"type": "ERROR"
|
||||
},
|
||||
{
|
||||
"message": "The '@track' decorator can only be used within a 'class' decorated with observed.",
|
||||
"type": "ERROR"
|
||||
}
|
||||
]
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
exports.source = `
|
||||
@Entry
|
||||
@Component
|
||||
struct HomeComponent {
|
||||
@track value: string
|
||||
build() {
|
||||
Column() {
|
||||
Text("hello")
|
||||
}
|
||||
.height(500)
|
||||
}
|
||||
}
|
||||
|
||||
@observed
|
||||
@Component
|
||||
struct child {
|
||||
build() {
|
||||
Text("")
|
||||
}
|
||||
}
|
||||
|
||||
class A {
|
||||
@track value: string
|
||||
}
|
||||
|
||||
@observed
|
||||
class B {
|
||||
@track value: string
|
||||
}
|
||||
`;
|
Loading…
x
Reference in New Issue
Block a user