123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- /**
- * The MIT License (MIT)
- * Copyright (c) 2017-present Dmitry Soshnikov <dmitry.soshnikov@gmail.com>
- */
- 'use strict';
- var UPPER_A_CP = 'A'.codePointAt(0);
- var UPPER_Z_CP = 'Z'.codePointAt(0);
- /**
- * Transforms case-insensitive regexp to lowercase
- *
- * /AaBbÏ/i -> /aabbï/i
- */
- module.exports = {
- _AZClassRanges: null,
- _hasUFlag: false,
- init: function init(ast) {
- this._AZClassRanges = new Set();
- this._hasUFlag = ast.flags.includes('u');
- },
- shouldRun: function shouldRun(ast) {
- return ast.flags.includes('i');
- },
- Char: function Char(path) {
- var node = path.node,
- parent = path.parent;
- if (isNaN(node.codePoint)) {
- return;
- }
- // Engine support for case-insensitive matching without the u flag
- // for characters above \u1000 does not seem reliable.
- if (!this._hasUFlag && node.codePoint >= 0x1000) {
- return;
- }
- if (parent.type === 'ClassRange') {
- // The only class ranges we handle must be inside A-Z.
- // After the `from` char is processed, the isAZClassRange test
- // will be false, so we use a Set to keep track of parents and
- // process the `to` char.
- if (!this._AZClassRanges.has(parent) && !isAZClassRange(parent)) {
- return;
- }
- this._AZClassRanges.add(parent);
- }
- var lower = node.symbol.toLowerCase();
- if (lower !== node.symbol) {
- node.value = displaySymbolAsValue(lower, node);
- node.symbol = lower;
- node.codePoint = lower.codePointAt(0);
- }
- }
- };
- function isAZClassRange(classRange) {
- var from = classRange.from,
- to = classRange.to;
- // A-Z
- return from.codePoint >= UPPER_A_CP && from.codePoint <= UPPER_Z_CP && to.codePoint >= UPPER_A_CP && to.codePoint <= UPPER_Z_CP;
- }
- function displaySymbolAsValue(symbol, node) {
- var codePoint = symbol.codePointAt(0);
- if (node.kind === 'decimal') {
- return '\\' + codePoint;
- }
- if (node.kind === 'oct') {
- return '\\0' + codePoint.toString(8);
- }
- if (node.kind === 'hex') {
- return '\\x' + codePoint.toString(16);
- }
- if (node.kind === 'unicode') {
- if (node.isSurrogatePair) {
- var _getSurrogatePairFrom = getSurrogatePairFromCodePoint(codePoint),
- lead = _getSurrogatePairFrom.lead,
- trail = _getSurrogatePairFrom.trail;
- return '\\u' + '0'.repeat(4 - lead.length) + lead + '\\u' + '0'.repeat(4 - trail.length) + trail;
- } else if (node.value.includes('{')) {
- return '\\u{' + codePoint.toString(16) + '}';
- } else {
- var code = codePoint.toString(16);
- return '\\u' + '0'.repeat(4 - code.length) + code;
- }
- }
- // simple
- return symbol;
- }
- /**
- * Converts a code point to a surrogate pair.
- * Conversion algorithm is taken from The Unicode Standard 3.0 Section 3.7
- * (https://www.unicode.org/versions/Unicode3.0.0/ch03.pdf)
- * @param {number} codePoint - Between 0x10000 and 0x10ffff
- * @returns {{lead: string, trail: string}}
- */
- function getSurrogatePairFromCodePoint(codePoint) {
- var lead = Math.floor((codePoint - 0x10000) / 0x400) + 0xd800;
- var trail = (codePoint - 0x10000) % 0x400 + 0xdc00;
- return {
- lead: lead.toString(16),
- trail: trail.toString(16)
- };
- }
|