1/* 2 * Copyright (c) 2023 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import ts from 'typescript'; 17import { projectConfig } from '../../../main'; 18import { DECORATOR_SUFFIX } from '../../pre_define'; 19 20export function disableMockDecorator(node: ts.Decorator): boolean { 21 if (!shouldDisableMockDecorator()) { 22 return false; 23 } 24 25 let parent: ts.Node = node.parent; 26 switch (parent.kind) { 27 case ts.SyntaxKind.Parameter: { 28 ts.factory.updateParameterDeclaration(<ts.ParameterDeclaration>parent, 29 ts.getModifiers((<ts.ParameterDeclaration>parent)), 30 (<ts.ParameterDeclaration>parent).dotDotDotToken, 31 (<ts.ParameterDeclaration>parent).name, 32 (<ts.ParameterDeclaration>parent).questionToken, 33 (<ts.ParameterDeclaration>parent).type, 34 (<ts.ParameterDeclaration>parent).initializer); 35 break; 36 } 37 case ts.SyntaxKind.MethodDeclaration: { 38 ts.factory.updateMethodDeclaration(<ts.MethodDeclaration>parent, 39 ts.getModifiers((<ts.MethodDeclaration>parent)), 40 (<ts.MethodDeclaration>parent).asteriskToken, 41 (<ts.MethodDeclaration>parent).name, 42 (<ts.MethodDeclaration>parent).questionToken, 43 (<ts.MethodDeclaration>parent).typeParameters, 44 (<ts.MethodDeclaration>parent).parameters, 45 (<ts.MethodDeclaration>parent).type, 46 (<ts.MethodDeclaration>parent).body); 47 break; 48 } 49 case ts.SyntaxKind.Constructor: { 50 ts.factory.updateConstructorDeclaration(<ts.ConstructorDeclaration>parent, 51 ts.getModifiers((<ts.ConstructorDeclaration>parent)), 52 (<ts.ConstructorDeclaration>parent).parameters, 53 (<ts.ConstructorDeclaration>parent).body); 54 break; 55 } 56 case ts.SyntaxKind.GetAccessor: { 57 ts.factory.updateGetAccessorDeclaration(<ts.GetAccessorDeclaration>parent, 58 ts.getModifiers((<ts.GetAccessorDeclaration>parent)), 59 (<ts.GetAccessorDeclaration>parent).name, 60 (<ts.GetAccessorDeclaration>parent).parameters, 61 (<ts.GetAccessorDeclaration>parent).type, 62 (<ts.GetAccessorDeclaration>parent).body); 63 break; 64 } 65 case ts.SyntaxKind.SetAccessor: { 66 ts.factory.updateSetAccessorDeclaration(<ts.SetAccessorDeclaration>parent, 67 ts.getModifiers((<ts.SetAccessorDeclaration>parent)), 68 (<ts.SetAccessorDeclaration>parent).name, 69 (<ts.SetAccessorDeclaration>parent).parameters, 70 (<ts.SetAccessorDeclaration>parent).body); 71 break; 72 } 73 case ts.SyntaxKind.PropertyDeclaration: { 74 if ((<ts.PropertyDeclaration>parent).questionToken) { 75 ts.factory.updatePropertyDeclaration(<ts.PropertyDeclaration>parent, 76 ts.getModifiers((<ts.PropertyDeclaration>parent)), 77 (<ts.PropertyDeclaration>parent).name, 78 (<ts.PropertyDeclaration>parent).questionToken, 79 (<ts.PropertyDeclaration>parent).type, 80 (<ts.PropertyDeclaration>parent).initializer); 81 } else if ((<ts.PropertyDeclaration>parent).exclamationToken) { 82 ts.factory.updatePropertyDeclaration(<ts.PropertyDeclaration>parent, 83 ts.getModifiers((<ts.PropertyDeclaration>parent)), 84 (<ts.PropertyDeclaration>parent).name, 85 (<ts.PropertyDeclaration>parent).exclamationToken, 86 (<ts.PropertyDeclaration>parent).type, 87 (<ts.PropertyDeclaration>parent).initializer); 88 } else { 89 ts.factory.updatePropertyDeclaration(<ts.PropertyDeclaration>parent, 90 ts.getModifiers((<ts.PropertyDeclaration>parent)), 91 (<ts.PropertyDeclaration>parent).name, 92 undefined, 93 (<ts.PropertyDeclaration>parent).type, 94 (<ts.PropertyDeclaration>parent).initializer); 95 } 96 break; 97 } 98 case ts.SyntaxKind.ClassDeclaration: { 99 ts.factory.updateClassDeclaration(<ts.ClassDeclaration>parent, 100 ts.getModifiers((<ts.ClassDeclaration>parent)), 101 (<ts.ClassDeclaration>parent).name, 102 (<ts.ClassDeclaration>parent).typeParameters, 103 (<ts.ClassDeclaration>parent).heritageClauses, 104 (<ts.ClassDeclaration>parent).members); 105 break; 106 } 107 default: { 108 break; 109 } 110 } 111 return true; 112} 113 114function removeMockDecorator(decs: readonly ts.Decorator[]): ts.Decorator[] { 115 let res: ts.Decorator[]; 116 for (let dec of decs) { 117 if (!isMockDecorator(dec)) { 118 res.push(dec); 119 } 120 } 121 122 return res; 123} 124 125export function isMockDecorator(dec: ts.Decorator): boolean { 126 let decObj = dec.expression; 127 if (!ts.isIdentifier(decObj)) { 128 return false; 129 } 130 131 if (projectConfig.mockParams) { 132 let mockDecorator: string = projectConfig.mockParams.decorator.replace(DECORATOR_SUFFIX, ''); 133 return ((<ts.Identifier>decObj).escapedText.toString() === mockDecorator); 134 } 135 136 return false; 137} 138 139function shouldDisableMockDecorator(): boolean { 140 // mock decorator only takes effect under preview mode, should be removed otherswise 141 if (projectConfig.isPreview) { 142 return false; 143 } 144 145 // mockParams = { 146 // "decorator": "name of mock decorator", 147 // "packageName": "name of mock package", 148 // "etsSourceRootPath": "path of ets source root", 149 // "mockConfigPath": "path of mock configuration file" 150 // } 151 return (projectConfig.mockParams && projectConfig.mockParams.decorator && projectConfig.mockParams.packageName) ? 152 true : false; 153} 154 155export const ORIGIN_EXTENTION: string = '.origin';