1/* 2 * Copyright (c) 2021 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 * as ts from "typescript"; 17import { Compiler } from "../compiler"; 18import * as jshelpers from "../jshelpers"; 19import { 20 DiagnosticCode, 21 DiagnosticError 22} from "../diagnostic"; 23 24export enum RegExpFlags { 25 FLAG_GLOBAL = (1 << 0), 26 FLAG_IGNORECASE = (1 << 1), 27 FLAG_MULTILINE = (1 << 2), 28 FLAG_DOTALL = (1 << 3), 29 FLAG_UTF16 = (1 << 4), 30 FLAG_STICKY = (1 << 5) 31} 32 33 34export function compileRegularExpressionLiteral(compiler: Compiler, regexp: ts.RegularExpressionLiteral): void { 35 let pandaGen = compiler.getPandaGen(); 36 let regexpText = regexp.text; 37 let regexpPattern = regexpText; 38 let regexpFlags = ""; 39 let firstSlashPos = regexpText.indexOf('/'); 40 let lastSlashPos = regexpText.lastIndexOf('/'); 41 if (firstSlashPos === -1 || 42 lastSlashPos === -1 || 43 firstSlashPos === lastSlashPos) { 44 throw new DiagnosticError(regexp, DiagnosticCode.Incorrect_regular_expression); 45 } 46 regexpPattern = regexpText.substring(firstSlashPos + 1, lastSlashPos); 47 regexpFlags = regexpText.substring(lastSlashPos + 1); 48 let flagsBits = updateExpressionFlags(regexpFlags, regexp); 49 pandaGen.createRegExpWithLiteral(regexp, regexpPattern, flagsBits); 50 51} 52 53function updateExpressionFlags(regexpFlags: string, regexp: ts.RegularExpressionLiteral): number { 54 let flagsBits: number = 0; 55 let flagsBitsTemp: number = 0; 56 for (let idx = 0; idx < regexpFlags.length; idx++) { 57 switch (regexpFlags[idx]) { 58 case 'g': 59 flagsBitsTemp = RegExpFlags.FLAG_GLOBAL; 60 break; 61 case 'i': 62 flagsBitsTemp = RegExpFlags.FLAG_IGNORECASE; 63 break; 64 case 'm': 65 flagsBitsTemp = RegExpFlags.FLAG_MULTILINE; 66 break; 67 case 's': 68 flagsBitsTemp = RegExpFlags.FLAG_DOTALL; 69 break; 70 case 'u': 71 flagsBitsTemp = RegExpFlags.FLAG_UTF16; 72 break; 73 case 'y': 74 flagsBitsTemp = RegExpFlags.FLAG_STICKY; 75 break; 76 default: 77 let file = jshelpers.getSourceFileOfNode(regexp); 78 throw new DiagnosticError(regexp, DiagnosticCode.Invalid_regular_expression_flag_0, file, [regexpFlags[idx]]); 79 } 80 if ((flagsBits & flagsBitsTemp) != 0) { 81 let file = jshelpers.getSourceFileOfNode(regexp); 82 throw new DiagnosticError(regexp, DiagnosticCode.Invalid_regular_expression_flag_0, file, [regexpFlags[idx]]); 83 } 84 flagsBits |= flagsBitsTemp; 85 } 86 return flagsBits; 87} 88