mirror of
https://github.com/openharmony/developtools_ace-ets2bundle.git
synced 2026-07-20 19:47:44 -04:00
extend support logic Signed-off-by: houhaoyu <houhaoyu@huawei.com> Change-Id: I51bef8847b245afd90972fd54a1213b5a72eacfa
This commit is contained in:
@@ -33,7 +33,8 @@ import {
|
||||
STYLE_ADD_DOUBLE_DOLLAR,
|
||||
$$,
|
||||
PROPERTIES_ADD_DOUBLE_DOLLAR,
|
||||
$$_BLOCK_INTERFACE
|
||||
$$_BLOCK_INTERFACE,
|
||||
COMPONENT_EXTEND_DECORATOR
|
||||
} from './pre_define';
|
||||
import { getName } from './process_component_build';
|
||||
import { INNER_COMPONENT_NAMES } from './component_map';
|
||||
@@ -43,6 +44,8 @@ import {
|
||||
CacheFileName,
|
||||
cache
|
||||
} from './compile_info';
|
||||
import { hasDecorator } from './utils';
|
||||
import { isExtendFunction } from './process_ui_syntax';
|
||||
|
||||
function readDeaclareFiles(): string[] {
|
||||
const declarationsFileNames: string[] = [];
|
||||
@@ -85,6 +88,12 @@ function setCompilerOptions() {
|
||||
});
|
||||
}
|
||||
|
||||
interface extendInfo {
|
||||
start: number,
|
||||
end: number,
|
||||
compName: string
|
||||
}
|
||||
|
||||
export function createLanguageService(rootFileNames: string[]): ts.LanguageService {
|
||||
setCompilerOptions();
|
||||
const files: ts.MapLike<{ version: number }> = {};
|
||||
@@ -97,8 +106,9 @@ export function createLanguageService(rootFileNames: string[]): ts.LanguageServi
|
||||
return undefined;
|
||||
}
|
||||
if (/(?<!\.d)\.(ets|ts)$/.test(fileName)) {
|
||||
const content: string = processContent(fs.readFileSync(fileName).toString(), fileName);
|
||||
checkUISyntax(content, fileName);
|
||||
let content: string = processContent(fs.readFileSync(fileName).toString(), fileName);
|
||||
let extendFunctionInfo: extendInfo[] = [];
|
||||
content = instanceInsteadThis(content, fileName, extendFunctionInfo);
|
||||
return ts.ScriptSnapshot.fromString(content);
|
||||
}
|
||||
return ts.ScriptSnapshot.fromString(fs.readFileSync(fileName).toString());
|
||||
@@ -232,8 +242,9 @@ export function createWatchCompilerHost(rootFileNames: string[],
|
||||
return undefined;
|
||||
}
|
||||
if (/(?<!\.d)\.(ets|ts)$/.test(fileName)) {
|
||||
const content: string = processContent(fs.readFileSync(fileName).toString(), fileName);
|
||||
checkUISyntax(content, fileName);
|
||||
let content: string = processContent(fs.readFileSync(fileName).toString(), fileName);
|
||||
let extendFunctionInfo: extendInfo[] = [];
|
||||
content = instanceInsteadThis(content, fileName, extendFunctionInfo);
|
||||
return content;
|
||||
}
|
||||
return fs.readFileSync(fileName).toString();
|
||||
@@ -242,6 +253,18 @@ export function createWatchCompilerHost(rootFileNames: string[],
|
||||
return host;
|
||||
}
|
||||
|
||||
function instanceInsteadThis(content: string, fileName: string, extendFunctionInfo: extendInfo[]): string {
|
||||
checkUISyntax(content, fileName, extendFunctionInfo);
|
||||
extendFunctionInfo.reverse().forEach((item)=>{
|
||||
let subStr: string = content.substring(item.start,item.end);
|
||||
let insert: string = subStr.replace(/(\s)this(\.)/g, (origin, item1, item2)=>{
|
||||
return item1 + item.compName + 'Instance' + item2;
|
||||
})
|
||||
content = content.slice(0, item.start) + insert + content.slice(item.end);
|
||||
})
|
||||
return content;
|
||||
}
|
||||
|
||||
function getResolveModule(modulePath: string, type): ts.ResolvedModuleFull {
|
||||
return {
|
||||
resolvedFileName: modulePath,
|
||||
@@ -255,18 +278,18 @@ export const decoratorParamsCollection: Set<string> = new Set();
|
||||
export const extendCollection: Set<string> = new Set();
|
||||
export const importModuleCollection: Set<string> = new Set();
|
||||
|
||||
function checkUISyntax(source: string, fileName: string): void {
|
||||
function checkUISyntax(source: string, fileName: string, extendFunctionInfo: extendInfo[]): void {
|
||||
if (/\.ets$/.test(fileName)) {
|
||||
if (path.basename(fileName) !== 'app.ets') {
|
||||
const sourceFile: ts.SourceFile = ts.createSourceFile(fileName, source,
|
||||
ts.ScriptTarget.Latest, true, ts.ScriptKind.ETS);
|
||||
parseAllNode(sourceFile, sourceFile);
|
||||
parseAllNode(sourceFile, sourceFile, extendFunctionInfo);
|
||||
props.push(...dollarCollection, ...decoratorParamsCollection, ...extendCollection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function parseAllNode(node: ts.Node, sourceFileNode: ts.SourceFile): void {
|
||||
function parseAllNode(node: ts.Node, sourceFileNode: ts.SourceFile, extendFunctionInfo: extendInfo[]): void {
|
||||
if (ts.isStructDeclaration(node)) {
|
||||
if (node.members) {
|
||||
node.members.forEach(item => {
|
||||
@@ -295,7 +318,27 @@ function parseAllNode(node: ts.Node, sourceFileNode: ts.SourceFile): void {
|
||||
});
|
||||
}
|
||||
}
|
||||
node.getChildren().forEach((item: ts.Node) => parseAllNode(item, sourceFileNode));
|
||||
if (ts.isFunctionDeclaration(node) && hasDecorator(node, COMPONENT_EXTEND_DECORATOR)) {
|
||||
if (node.body && node.body.statements && node.body.statements.length &&
|
||||
!(isOriginalExtend(node.body))) {
|
||||
extendFunctionInfo.push({start:node.pos, end:node.end, compName: isExtendFunction(node)})
|
||||
}
|
||||
}
|
||||
node.getChildren().forEach((item: ts.Node) => parseAllNode(item, sourceFileNode, extendFunctionInfo));
|
||||
}
|
||||
|
||||
export function isOriginalExtend(node: ts.Block): boolean {
|
||||
let innerNode: ts.Node = node.statements[0];
|
||||
if (node.statements.length === 1 && ts.isExpressionStatement(innerNode)) {
|
||||
while (innerNode.expression) {
|
||||
innerNode = innerNode.expression;
|
||||
}
|
||||
if (ts.isIdentifier(innerNode) && innerNode.pos && innerNode.end && innerNode.pos === innerNode.end &&
|
||||
innerNode.escapedText.toString().match(/Instance$/)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function traverseBuild(node: ts.Node, index: number): void {
|
||||
|
||||
@@ -80,6 +80,7 @@ import {
|
||||
projectConfig
|
||||
} from '../main';
|
||||
import { createCustomComponentNewExpression, createViewCreate } from './process_component_member';
|
||||
import { isOriginalExtend } from './ets_checker'
|
||||
|
||||
export const transformLog: FileLog = new FileLog();
|
||||
export let contextGlobal: ts.TransformationContext;
|
||||
@@ -425,10 +426,15 @@ function processExtend(node: ts.FunctionDeclaration, log: LogInfo[]): ts.Functio
|
||||
const componentName: string = isExtendFunction(node);
|
||||
if (componentName && node.body && node.body.statements.length) {
|
||||
const statementArray: ts.Statement[] = [];
|
||||
let bodynode: ts.Block;
|
||||
const attrSet: ts.CallExpression = node.body.statements[0].expression;
|
||||
const changeCompName: ts.ExpressionStatement = ts.factory.createExpressionStatement(processExtendBody(attrSet));
|
||||
bindComponentAttr(changeCompName as ts.ExpressionStatement,
|
||||
ts.factory.createIdentifier(componentName), statementArray, log);
|
||||
if (isOriginalExtend(node.body)) {
|
||||
const changeCompName: ts.ExpressionStatement = ts.factory.createExpressionStatement(processExtendBody(attrSet));
|
||||
bindComponentAttr(changeCompName as ts.ExpressionStatement,
|
||||
ts.factory.createIdentifier(componentName), statementArray, log);
|
||||
} else {
|
||||
bodynode = ts.visitEachChild(node.body, traverseExtendExpression, contextGlobal);
|
||||
}
|
||||
let extendFunctionName: string;
|
||||
if (node.name.getText().startsWith('__' + componentName + '__')) {
|
||||
extendFunctionName = node.name.getText();
|
||||
@@ -438,18 +444,56 @@ function processExtend(node: ts.FunctionDeclaration, log: LogInfo[]): ts.Functio
|
||||
}
|
||||
return ts.factory.updateFunctionDeclaration(node, undefined, node.modifiers, node.asteriskToken,
|
||||
ts.factory.createIdentifier(extendFunctionName), node.typeParameters,
|
||||
node.parameters, node.type, ts.factory.updateBlock(node.body, statementArray));
|
||||
node.parameters, node.type, isOriginalExtend(node.body) ?
|
||||
ts.factory.updateBlock(node.body, statementArray) : bodynode);
|
||||
}
|
||||
function traverseExtendExpression(node: ts.Node): ts.Node {
|
||||
if (ts.isExpressionStatement(node) && isThisNode(node)) {
|
||||
let changeCompName: ts.ExpressionStatement =
|
||||
ts.factory.createExpressionStatement(processExtendBody(node.expression, componentName));
|
||||
const statementArray: ts.Statement[] = [];
|
||||
bindComponentAttr(changeCompName, ts.factory.createIdentifier(componentName), statementArray, []);
|
||||
return ts.factory.createCallExpression(
|
||||
ts.factory.createParenthesizedExpression(ts.factory.createFunctionExpression(
|
||||
undefined, undefined, undefined, undefined, [], undefined,
|
||||
ts.factory.createBlock(statementArray, true))), undefined, []);
|
||||
}
|
||||
return ts.visitEachChild(node, traverseExtendExpression, contextGlobal);
|
||||
}
|
||||
}
|
||||
|
||||
function processExtendBody(node: ts.Node): ts.Expression {
|
||||
|
||||
|
||||
function isThisNode(node: ts.ExpressionStatement): boolean {
|
||||
let innerNode: ts.Node = node;
|
||||
while(innerNode.expression) {
|
||||
innerNode = innerNode.expression;
|
||||
}
|
||||
if (innerNode.kind === ts.SyntaxKind.ThisKeyword) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function processExtendBody(node: ts.Node, componentName?: string): ts.Expression {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.CallExpression:
|
||||
return ts.factory.createCallExpression(processExtendBody(node.expression), undefined, node.arguments);
|
||||
return ts.factory.createCallExpression(processExtendBody(node.expression, componentName),
|
||||
undefined, node.arguments);
|
||||
case ts.SyntaxKind.PropertyAccessExpression:
|
||||
return ts.factory.createPropertyAccessExpression(processExtendBody(node.expression), node.name);
|
||||
return ts.factory.createPropertyAccessExpression(
|
||||
processExtendBody(node.expression, componentName), node.name);
|
||||
case ts.SyntaxKind.Identifier:
|
||||
return ts.factory.createIdentifier(node.escapedText.toString().replace(INSTANCE, ''));
|
||||
if (!componentName) {
|
||||
return ts.factory.createIdentifier(node.escapedText.toString().replace(INSTANCE, ''));
|
||||
}
|
||||
break;
|
||||
case ts.SyntaxKind.ThisKeyword:
|
||||
if (componentName) {
|
||||
return ts.factory.createIdentifier(componentName);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user