• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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