Show More
Commit Description:
submission report
Commit Description:
submission report
References:
File last commit:
Show/Diff file:
Action:
node_modules/es-abstract/2017/GetSubstitution.js
| 104 lines
| 3.5 KiB
| application/javascript
| JavascriptLexer
|
r789 | ||||
'use strict'; | ||||
var GetIntrinsic = require('../GetIntrinsic'); | ||||
var $TypeError = GetIntrinsic('%TypeError%'); | ||||
var $parseInt = GetIntrinsic('%parseInt%'); | ||||
var inspect = require('object-inspect'); | ||||
var regexTester = require('../helpers/regexTester'); | ||||
var callBound = require('../helpers/callBound'); | ||||
var every = require('../helpers/every'); | ||||
var isDigit = regexTester(/^[0-9]$/); | ||||
var $charAt = callBound('String.prototype.charAt'); | ||||
var $strSlice = callBound('String.prototype.slice'); | ||||
var IsArray = require('./IsArray'); | ||||
var IsInteger = require('./IsInteger'); | ||||
var Type = require('./Type'); | ||||
var canDistinguishSparseFromUndefined = 0 in [undefined]; // IE 6 - 8 have a bug where this returns false | ||||
var isStringOrHole = function (capture, index, arr) { | ||||
return Type(capture) === 'String' || (canDistinguishSparseFromUndefined ? !(index in arr) : Type(capture) === 'Undefined'); | ||||
}; | ||||
// https://www.ecma-international.org/ecma-262/6.0/#sec-getsubstitution | ||||
// eslint-disable-next-line max-statements, max-params, max-lines-per-function | ||||
module.exports = function GetSubstitution(matched, str, position, captures, replacement) { | ||||
if (Type(matched) !== 'String') { | ||||
throw new $TypeError('Assertion failed: `matched` must be a String'); | ||||
} | ||||
var matchLength = matched.length; | ||||
if (Type(str) !== 'String') { | ||||
throw new $TypeError('Assertion failed: `str` must be a String'); | ||||
} | ||||
var stringLength = str.length; | ||||
if (!IsInteger(position) || position < 0 || position > stringLength) { | ||||
throw new $TypeError('Assertion failed: `position` must be a nonnegative integer, and less than or equal to the length of `string`, got ' + inspect(position)); | ||||
} | ||||
if (!IsArray(captures) || !every(captures, isStringOrHole)) { | ||||
throw new $TypeError('Assertion failed: `captures` must be a List of Strings, got ' + inspect(captures)); | ||||
} | ||||
if (Type(replacement) !== 'String') { | ||||
throw new $TypeError('Assertion failed: `replacement` must be a String'); | ||||
} | ||||
var tailPos = position + matchLength; | ||||
var m = captures.length; | ||||
var result = ''; | ||||
for (var i = 0; i < replacement.length; i += 1) { | ||||
// if this is a $, and it's not the end of the replacement | ||||
var current = $charAt(replacement, i); | ||||
var isLast = (i + 1) >= replacement.length; | ||||
var nextIsLast = (i + 2) >= replacement.length; | ||||
if (current === '$' && !isLast) { | ||||
var next = $charAt(replacement, i + 1); | ||||
if (next === '$') { | ||||
result += '$'; | ||||
i += 1; | ||||
} else if (next === '&') { | ||||
result += matched; | ||||
i += 1; | ||||
} else if (next === '`') { | ||||
result += position === 0 ? '' : $strSlice(str, 0, position - 1); | ||||
i += 1; | ||||
} else if (next === "'") { | ||||
result += tailPos >= stringLength ? '' : $strSlice(str, tailPos); | ||||
i += 1; | ||||
} else { | ||||
var nextNext = nextIsLast ? null : $charAt(replacement, i + 2); | ||||
if (isDigit(next) && next !== '0' && (nextIsLast || !isDigit(nextNext))) { | ||||
// $1 through $9, and not followed by a digit | ||||
var n = $parseInt(next, 10); | ||||
// if (n > m, impl-defined) | ||||
result += (n <= m && Type(captures[n - 1]) === 'Undefined') ? '' : captures[n - 1]; | ||||
i += 1; | ||||
} else if (isDigit(next) && (nextIsLast || isDigit(nextNext))) { | ||||
// $00 through $99 | ||||
var nn = next + nextNext; | ||||
var nnI = $parseInt(nn, 10) - 1; | ||||
// if nn === '00' or nn > m, impl-defined | ||||
result += (nn <= m && Type(captures[nnI]) === 'Undefined') ? '' : captures[nnI]; | ||||
i += 2; | ||||
} else { | ||||
result += '$'; | ||||
} | ||||
} | ||||
} else { | ||||
// the final $, or else not a $ | ||||
result += $charAt(replacement, i); | ||||
} | ||||
} | ||||
return result; | ||||
}; | ||||