add support for Lift Template Literal Restriction (#23801)
* add support for Lift Template Literal Restriction * rename file and improve comment and tests * fix NoSubstitutionTemplateLiteral support * extract tagged template and add more test * avoid useless parameter * fix incorrect return node if cannot transform * accept baseline * correctly baseline * accept baseline * fix merge break * fix merge break * inline rescan template head or no subsititution template * update scan error * add comment and fix lint * refactor and fix lint * avoid blank * fix merge conflict * fix again * fix again * use multiple target * fix space lint Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
parent
20471182fc
commit
70399e146e
|
@ -4124,8 +4124,18 @@ namespace ts {
|
|||
case SyntaxKind.TemplateHead:
|
||||
case SyntaxKind.TemplateMiddle:
|
||||
case SyntaxKind.TemplateTail:
|
||||
case SyntaxKind.TemplateExpression:
|
||||
if ((<NoSubstitutionTemplateLiteral | TemplateHead | TemplateMiddle | TemplateTail>node).templateFlags) {
|
||||
transformFlags |= TransformFlags.AssertES2018;
|
||||
break;
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
if (hasInvalidEscape((<TaggedTemplateExpression>node).template)) {
|
||||
transformFlags |= TransformFlags.AssertES2018;
|
||||
break;
|
||||
}
|
||||
// falls through
|
||||
case SyntaxKind.TemplateExpression:
|
||||
case SyntaxKind.ShorthandPropertyAssignment:
|
||||
case SyntaxKind.StaticKeyword:
|
||||
case SyntaxKind.MetaProperty:
|
||||
|
|
|
@ -1486,7 +1486,7 @@ namespace ts {
|
|||
|
||||
let token = rawTextScanner.scan();
|
||||
if (token === SyntaxKind.CloseBracketToken) {
|
||||
token = rawTextScanner.reScanTemplateToken();
|
||||
token = rawTextScanner.reScanTemplateToken(/* isTaggedTemplate */ false);
|
||||
}
|
||||
|
||||
if (rawTextScanner.isUnterminated()) {
|
||||
|
|
|
@ -1137,8 +1137,12 @@ namespace ts {
|
|||
return currentToken = scanner.reScanSlashToken();
|
||||
}
|
||||
|
||||
function reScanTemplateToken(): SyntaxKind {
|
||||
return currentToken = scanner.reScanTemplateToken();
|
||||
function reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind {
|
||||
return currentToken = scanner.reScanTemplateToken(isTaggedTemplate);
|
||||
}
|
||||
|
||||
function reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind {
|
||||
return currentToken = scanner.reScanTemplateHeadOrNoSubstitutionTemplate();
|
||||
}
|
||||
|
||||
function reScanLessThanToken(): SyntaxKind {
|
||||
|
@ -2329,17 +2333,17 @@ namespace ts {
|
|||
return allowIdentifierNames ? parseIdentifierName() : parseIdentifier();
|
||||
}
|
||||
|
||||
function parseTemplateExpression(): TemplateExpression {
|
||||
function parseTemplateExpression(isTaggedTemplate: boolean): TemplateExpression {
|
||||
const template = <TemplateExpression>createNode(SyntaxKind.TemplateExpression);
|
||||
|
||||
template.head = parseTemplateHead();
|
||||
template.head = parseTemplateHead(isTaggedTemplate);
|
||||
Debug.assert(template.head.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
|
||||
|
||||
const list = [];
|
||||
const listPos = getNodePos();
|
||||
|
||||
do {
|
||||
list.push(parseTemplateSpan());
|
||||
list.push(parseTemplateSpan(isTaggedTemplate));
|
||||
}
|
||||
while (last(list).literal.kind === SyntaxKind.TemplateMiddle);
|
||||
|
||||
|
@ -2348,13 +2352,13 @@ namespace ts {
|
|||
return finishNode(template);
|
||||
}
|
||||
|
||||
function parseTemplateSpan(): TemplateSpan {
|
||||
function parseTemplateSpan(isTaggedTemplate: boolean): TemplateSpan {
|
||||
const span = <TemplateSpan>createNode(SyntaxKind.TemplateSpan);
|
||||
span.expression = allowInAnd(parseExpression);
|
||||
|
||||
let literal: TemplateMiddle | TemplateTail;
|
||||
if (token() === SyntaxKind.CloseBraceToken) {
|
||||
reScanTemplateToken();
|
||||
reScanTemplateToken(isTaggedTemplate);
|
||||
literal = parseTemplateMiddleOrTemplateTail();
|
||||
}
|
||||
else {
|
||||
|
@ -2369,7 +2373,10 @@ namespace ts {
|
|||
return <LiteralExpression>parseLiteralLikeNode(token());
|
||||
}
|
||||
|
||||
function parseTemplateHead(): TemplateHead {
|
||||
function parseTemplateHead(isTaggedTemplate: boolean): TemplateHead {
|
||||
if (isTaggedTemplate) {
|
||||
reScanTemplateHeadOrNoSubstitutionTemplate();
|
||||
}
|
||||
const fragment = parseLiteralLikeNode(token());
|
||||
Debug.assert(fragment.kind === SyntaxKind.TemplateHead, "Template head has wrong token kind");
|
||||
return <TemplateHead>fragment;
|
||||
|
@ -2413,6 +2420,10 @@ namespace ts {
|
|||
(<NumericLiteral>node).numericLiteralFlags = scanner.getTokenFlags() & TokenFlags.NumericLiteralFlags;
|
||||
}
|
||||
|
||||
if (isTemplateLiteralKind(node.kind)) {
|
||||
(<TemplateHead | TemplateMiddle | TemplateTail | NoSubstitutionTemplateLiteral>node).templateFlags = scanner.getTokenFlags() & TokenFlags.ContainsInvalidEscape;
|
||||
}
|
||||
|
||||
nextToken();
|
||||
finishNode(node);
|
||||
|
||||
|
@ -4772,8 +4783,8 @@ namespace ts {
|
|||
tagExpression.questionDotToken = questionDotToken;
|
||||
tagExpression.typeArguments = typeArguments;
|
||||
tagExpression.template = token() === SyntaxKind.NoSubstitutionTemplateLiteral
|
||||
? <NoSubstitutionTemplateLiteral>parseLiteralNode()
|
||||
: parseTemplateExpression();
|
||||
? (reScanTemplateHeadOrNoSubstitutionTemplate(), <NoSubstitutionTemplateLiteral>parseLiteralNode())
|
||||
: parseTemplateExpression(/*isTaggedTemplate*/ true);
|
||||
if (questionDotToken || tag.flags & NodeFlags.OptionalChain) {
|
||||
tagExpression.flags |= NodeFlags.OptionalChain;
|
||||
}
|
||||
|
@ -4945,7 +4956,7 @@ namespace ts {
|
|||
}
|
||||
break;
|
||||
case SyntaxKind.TemplateHead:
|
||||
return parseTemplateExpression();
|
||||
return parseTemplateExpression(/* isTaggedTemplate */ false);
|
||||
}
|
||||
|
||||
return parseIdentifier(Diagnostics.Expression_expected);
|
||||
|
|
|
@ -28,7 +28,8 @@ namespace ts {
|
|||
getTokenFlags(): TokenFlags;
|
||||
reScanGreaterToken(): SyntaxKind;
|
||||
reScanSlashToken(): SyntaxKind;
|
||||
reScanTemplateToken(): SyntaxKind;
|
||||
reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind;
|
||||
reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind;
|
||||
scanJsxIdentifier(): SyntaxKind;
|
||||
scanJsxAttributeValue(): SyntaxKind;
|
||||
reScanJsxAttributeValue(): SyntaxKind;
|
||||
|
@ -468,6 +469,14 @@ namespace ts {
|
|||
return ch >= CharacterCodes._0 && ch <= CharacterCodes._9;
|
||||
}
|
||||
|
||||
function isHexDigit(ch: number): boolean {
|
||||
return isDigit(ch) || ch >= CharacterCodes.A && ch <= CharacterCodes.F || ch >= CharacterCodes.a && ch <= CharacterCodes.f;
|
||||
}
|
||||
|
||||
function isCodePoint(code: number): boolean {
|
||||
return code <= 0x10FFFF;
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
export function isOctalDigit(ch: number): boolean {
|
||||
return ch >= CharacterCodes._0 && ch <= CharacterCodes._7;
|
||||
|
@ -901,6 +910,7 @@ namespace ts {
|
|||
reScanGreaterToken,
|
||||
reScanSlashToken,
|
||||
reScanTemplateToken,
|
||||
reScanTemplateHeadOrNoSubstitutionTemplate,
|
||||
scanJsxIdentifier,
|
||||
scanJsxAttributeValue,
|
||||
reScanJsxAttributeValue,
|
||||
|
@ -1164,7 +1174,7 @@ namespace ts {
|
|||
* Sets the current 'tokenValue' and returns a NoSubstitutionTemplateLiteral or
|
||||
* a literal component of a TemplateExpression.
|
||||
*/
|
||||
function scanTemplateAndSetTokenValue(): SyntaxKind {
|
||||
function scanTemplateAndSetTokenValue(isTaggedTemplate: boolean): SyntaxKind {
|
||||
const startedWithBacktick = text.charCodeAt(pos) === CharacterCodes.backtick;
|
||||
|
||||
pos++;
|
||||
|
@ -1202,7 +1212,7 @@ namespace ts {
|
|||
// Escape character
|
||||
if (currChar === CharacterCodes.backslash) {
|
||||
contents += text.substring(start, pos);
|
||||
contents += scanEscapeSequence();
|
||||
contents += scanEscapeSequence(isTaggedTemplate);
|
||||
start = pos;
|
||||
continue;
|
||||
}
|
||||
|
@ -1231,7 +1241,8 @@ namespace ts {
|
|||
return resultingToken;
|
||||
}
|
||||
|
||||
function scanEscapeSequence(): string {
|
||||
function scanEscapeSequence(isTaggedTemplate?: boolean): string {
|
||||
const start = pos;
|
||||
pos++;
|
||||
if (pos >= end) {
|
||||
error(Diagnostics.Unexpected_end_of_text);
|
||||
|
@ -1241,6 +1252,12 @@ namespace ts {
|
|||
pos++;
|
||||
switch (ch) {
|
||||
case CharacterCodes._0:
|
||||
// '\01'
|
||||
if (isTaggedTemplate && pos < end && isDigit(text.charCodeAt(pos))) {
|
||||
pos++;
|
||||
tokenFlags |= TokenFlags.ContainsInvalidEscape;
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
return "\0";
|
||||
case CharacterCodes.b:
|
||||
return "\b";
|
||||
|
@ -1259,10 +1276,41 @@ namespace ts {
|
|||
case CharacterCodes.doubleQuote:
|
||||
return "\"";
|
||||
case CharacterCodes.u:
|
||||
if (isTaggedTemplate) {
|
||||
// '\u' or '\u0' or '\u00' or '\u000'
|
||||
for (let escapePos = pos; escapePos < pos + 4; escapePos++) {
|
||||
if (escapePos < end && !isHexDigit(text.charCodeAt(escapePos)) && text.charCodeAt(escapePos) !== CharacterCodes.openBrace) {
|
||||
pos = escapePos;
|
||||
tokenFlags |= TokenFlags.ContainsInvalidEscape;
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
// '\u{DDDDDDDD}'
|
||||
if (pos < end && text.charCodeAt(pos) === CharacterCodes.openBrace) {
|
||||
tokenFlags |= TokenFlags.ExtendedUnicodeEscape;
|
||||
pos++;
|
||||
|
||||
// '\u{'
|
||||
if (isTaggedTemplate && !isHexDigit(text.charCodeAt(pos))) {
|
||||
tokenFlags |= TokenFlags.ContainsInvalidEscape;
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
|
||||
if (isTaggedTemplate) {
|
||||
const savePos = pos;
|
||||
const escapedValueString = scanMinimumNumberOfHexDigits(1, /*canHaveSeparators*/ false);
|
||||
const escapedValue = escapedValueString ? parseInt(escapedValueString, 16) : -1;
|
||||
|
||||
// '\u{Not Code Point' or '\u{CodePoint'
|
||||
if (!isCodePoint(escapedValue) || text.charCodeAt(pos) !== CharacterCodes.closeBrace) {
|
||||
tokenFlags |= TokenFlags.ContainsInvalidEscape;
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
else {
|
||||
pos = savePos;
|
||||
}
|
||||
}
|
||||
tokenFlags |= TokenFlags.ExtendedUnicodeEscape;
|
||||
return scanExtendedUnicodeEscape();
|
||||
}
|
||||
|
||||
|
@ -1271,6 +1319,17 @@ namespace ts {
|
|||
return scanHexadecimalEscape(/*numDigits*/ 4);
|
||||
|
||||
case CharacterCodes.x:
|
||||
if (isTaggedTemplate) {
|
||||
if (!isHexDigit(text.charCodeAt(pos))) {
|
||||
tokenFlags |= TokenFlags.ContainsInvalidEscape;
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
else if (!isHexDigit(text.charCodeAt(pos + 1))) {
|
||||
pos++;
|
||||
tokenFlags |= TokenFlags.ContainsInvalidEscape;
|
||||
return text.substring(start, pos);
|
||||
}
|
||||
}
|
||||
// '\xDD'
|
||||
return scanHexadecimalEscape(/*numDigits*/ 2);
|
||||
|
||||
|
@ -1561,7 +1620,7 @@ namespace ts {
|
|||
tokenValue = scanString();
|
||||
return token = SyntaxKind.StringLiteral;
|
||||
case CharacterCodes.backtick:
|
||||
return token = scanTemplateAndSetTokenValue();
|
||||
return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ false);
|
||||
case CharacterCodes.percent:
|
||||
if (text.charCodeAt(pos + 1) === CharacterCodes.equals) {
|
||||
return pos += 2, token = SyntaxKind.PercentEqualsToken;
|
||||
|
@ -2019,10 +2078,15 @@ namespace ts {
|
|||
/**
|
||||
* Unconditionally back up and scan a template expression portion.
|
||||
*/
|
||||
function reScanTemplateToken(): SyntaxKind {
|
||||
function reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind {
|
||||
Debug.assert(token === SyntaxKind.CloseBraceToken, "'reScanTemplateToken' should only be called on a '}'");
|
||||
pos = tokenPos;
|
||||
return token = scanTemplateAndSetTokenValue();
|
||||
return token = scanTemplateAndSetTokenValue(isTaggedTemplate);
|
||||
}
|
||||
|
||||
function reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind {
|
||||
pos = tokenPos;
|
||||
return token = scanTemplateAndSetTokenValue(/* isTaggedTemplate */ true);
|
||||
}
|
||||
|
||||
function reScanJsxToken(): JsxTokenSyntaxKind {
|
||||
|
|
|
@ -3951,78 +3951,14 @@ namespace ts {
|
|||
* @param node A TaggedTemplateExpression node.
|
||||
*/
|
||||
function visitTaggedTemplateExpression(node: TaggedTemplateExpression) {
|
||||
// Visit the tag expression
|
||||
const tag = visitNode(node.tag, visitor, isExpression);
|
||||
|
||||
// Build up the template arguments and the raw and cooked strings for the template.
|
||||
// We start out with 'undefined' for the first argument and revisit later
|
||||
// to avoid walking over the template string twice and shifting all our arguments over after the fact.
|
||||
const templateArguments: Expression[] = [undefined!];
|
||||
const cookedStrings: Expression[] = [];
|
||||
const rawStrings: Expression[] = [];
|
||||
const template = node.template;
|
||||
if (isNoSubstitutionTemplateLiteral(template)) {
|
||||
cookedStrings.push(createLiteral(template.text));
|
||||
rawStrings.push(getRawLiteral(template));
|
||||
}
|
||||
else {
|
||||
cookedStrings.push(createLiteral(template.head.text));
|
||||
rawStrings.push(getRawLiteral(template.head));
|
||||
for (const templateSpan of template.templateSpans) {
|
||||
cookedStrings.push(createLiteral(templateSpan.literal.text));
|
||||
rawStrings.push(getRawLiteral(templateSpan.literal));
|
||||
templateArguments.push(visitNode(templateSpan.expression, visitor, isExpression));
|
||||
}
|
||||
}
|
||||
|
||||
const helperCall = createTemplateObjectHelper(context, createArrayLiteral(cookedStrings), createArrayLiteral(rawStrings));
|
||||
|
||||
// Create a variable to cache the template object if we're in a module.
|
||||
// Do not do this in the global scope, as any variable we currently generate could conflict with
|
||||
// variables from outside of the current compilation. In the future, we can revisit this behavior.
|
||||
if (isExternalModule(currentSourceFile)) {
|
||||
const tempVar = createUniqueName("templateObject");
|
||||
recordTaggedTemplateString(tempVar);
|
||||
templateArguments[0] = createLogicalOr(
|
||||
tempVar,
|
||||
createAssignment(
|
||||
tempVar,
|
||||
helperCall)
|
||||
);
|
||||
}
|
||||
else {
|
||||
templateArguments[0] = helperCall;
|
||||
}
|
||||
|
||||
return createCall(tag, /*typeArguments*/ undefined, templateArguments);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ES5 compatible literal from an ES6 template literal.
|
||||
*
|
||||
* @param node The ES6 template literal.
|
||||
*/
|
||||
function getRawLiteral(node: TemplateLiteralLikeNode) {
|
||||
// Find original source text, since we need to emit the raw strings of the tagged template.
|
||||
// The raw strings contain the (escaped) strings of what the user wrote.
|
||||
// Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
|
||||
let text = node.rawText;
|
||||
if (text === undefined) {
|
||||
text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
|
||||
|
||||
// text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
|
||||
// thus we need to remove those characters.
|
||||
// First template piece starts with "`", others with "}"
|
||||
// Last template piece ends with "`", others with "${"
|
||||
const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail;
|
||||
text = text.substring(1, text.length - (isLast ? 1 : 2));
|
||||
}
|
||||
|
||||
// Newline normalization:
|
||||
// ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
|
||||
// <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
|
||||
text = text.replace(/\r\n?/g, "\n");
|
||||
return setTextRange(createLiteral(text), node);
|
||||
return processTaggedTemplateExpression(
|
||||
context,
|
||||
node,
|
||||
visitor,
|
||||
currentSourceFile,
|
||||
recordTaggedTemplateString,
|
||||
ProcessLevel.All
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -4358,18 +4294,6 @@ namespace ts {
|
|||
);
|
||||
}
|
||||
|
||||
function createTemplateObjectHelper(context: TransformationContext, cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression) {
|
||||
context.requestEmitHelper(templateObjectHelper);
|
||||
return createCall(
|
||||
getUnscopedHelperName("__makeTemplateObject"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
cooked,
|
||||
raw
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
export const extendsHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:extends",
|
||||
importName: "__extends",
|
||||
|
@ -4391,17 +4315,4 @@ namespace ts {
|
|||
};
|
||||
})();`
|
||||
};
|
||||
|
||||
export const templateObjectHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:makeTemplateObject",
|
||||
importName: "__makeTemplateObject",
|
||||
scoped: false,
|
||||
priority: 0,
|
||||
text: `
|
||||
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
||||
return cooked;
|
||||
};`
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,9 @@ namespace ts {
|
|||
let enclosingSuperContainerFlags: NodeCheckFlags = 0;
|
||||
let hasLexicalThis: boolean;
|
||||
|
||||
let currentSourceFile: SourceFile;
|
||||
let taggedTemplateStringDeclarations: VariableDeclaration[];
|
||||
|
||||
/** Keeps track of property names accessed on super (`super.x`) within async functions. */
|
||||
let capturedSuperProperties: UnderscoreEscapedMap<true>;
|
||||
/** Whether the async function contains an element access on super (`super[x]`). */
|
||||
|
@ -37,15 +40,23 @@ namespace ts {
|
|||
|
||||
return chainBundle(transformSourceFile);
|
||||
|
||||
function recordTaggedTemplateString(temp: Identifier) {
|
||||
taggedTemplateStringDeclarations = append(
|
||||
taggedTemplateStringDeclarations,
|
||||
createVariableDeclaration(temp));
|
||||
}
|
||||
|
||||
function transformSourceFile(node: SourceFile) {
|
||||
if (node.isDeclarationFile) {
|
||||
return node;
|
||||
}
|
||||
|
||||
exportedVariableStatement = false;
|
||||
hasLexicalThis = !isEffectiveStrictModeSourceFile(node, compilerOptions);
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
currentSourceFile = node;
|
||||
const visited = visitSourceFile(node);
|
||||
addEmitHelpers(visited, context.readEmitHelpers());
|
||||
|
||||
currentSourceFile = undefined!;
|
||||
taggedTemplateStringDeclarations = undefined!;
|
||||
return visited;
|
||||
}
|
||||
|
||||
|
@ -127,6 +138,8 @@ namespace ts {
|
|||
return visitExpressionStatement(node as ExpressionStatement);
|
||||
case SyntaxKind.ParenthesizedExpression:
|
||||
return visitParenthesizedExpression(node as ParenthesizedExpression, noDestructuringValue);
|
||||
case SyntaxKind.TaggedTemplateExpression:
|
||||
return visitTaggedTemplateExpression(node as TaggedTemplateExpression);
|
||||
case SyntaxKind.PropertyAccessExpression:
|
||||
if (capturedSuperProperties && isPropertyAccessExpression(node) && node.expression.kind === SyntaxKind.SuperKeyword) {
|
||||
capturedSuperProperties.set(node.name.escapedText, true);
|
||||
|
@ -297,6 +310,28 @@ namespace ts {
|
|||
return visitEachChild(node, noDestructuringValue ? visitorNoDestructuringValue : visitor, context);
|
||||
}
|
||||
|
||||
function visitSourceFile(node: SourceFile): SourceFile {
|
||||
exportedVariableStatement = false;
|
||||
hasLexicalThis = !isEffectiveStrictModeSourceFile(node, compilerOptions);
|
||||
const visited = visitEachChild(node, visitor, context);
|
||||
const statement = concatenate(visited.statements, taggedTemplateStringDeclarations && [
|
||||
createVariableStatement(/*modifiers*/ undefined,
|
||||
createVariableDeclarationList(taggedTemplateStringDeclarations))
|
||||
]);
|
||||
return updateSourceFileNode(visited, setTextRange(createNodeArray(statement), node.statements));
|
||||
}
|
||||
|
||||
function visitTaggedTemplateExpression(node: TaggedTemplateExpression) {
|
||||
return processTaggedTemplateExpression(
|
||||
context,
|
||||
node,
|
||||
visitor,
|
||||
currentSourceFile,
|
||||
recordTaggedTemplateString,
|
||||
ProcessLevel.LiftRestriction
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Visits a BinaryExpression that contains a destructuring assignment.
|
||||
*
|
||||
|
|
117
src/compiler/transformers/taggedTemplate.ts
Normal file
117
src/compiler/transformers/taggedTemplate.ts
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*@internal*/
|
||||
namespace ts {
|
||||
export enum ProcessLevel {
|
||||
LiftRestriction,
|
||||
All
|
||||
}
|
||||
|
||||
export function processTaggedTemplateExpression(
|
||||
context: TransformationContext,
|
||||
node: TaggedTemplateExpression,
|
||||
visitor: ((node: Node) => VisitResult<Node>) | undefined,
|
||||
currentSourceFile: SourceFile,
|
||||
recordTaggedTemplateString: (temp: Identifier) => void,
|
||||
level: ProcessLevel) {
|
||||
|
||||
// Visit the tag expression
|
||||
const tag = visitNode(node.tag, visitor, isExpression);
|
||||
|
||||
// Build up the template arguments and the raw and cooked strings for the template.
|
||||
// We start out with 'undefined' for the first argument and revisit later
|
||||
// to avoid walking over the template string twice and shifting all our arguments over after the fact.
|
||||
const templateArguments: Expression[] = [undefined!];
|
||||
const cookedStrings: Expression[] = [];
|
||||
const rawStrings: Expression[] = [];
|
||||
const template = node.template;
|
||||
|
||||
if (level === ProcessLevel.LiftRestriction && !hasInvalidEscape(template)) return node;
|
||||
|
||||
if (isNoSubstitutionTemplateLiteral(template)) {
|
||||
cookedStrings.push(createTemplateCooked(template));
|
||||
rawStrings.push(getRawLiteral(template, currentSourceFile));
|
||||
}
|
||||
else {
|
||||
cookedStrings.push(createTemplateCooked(template.head));
|
||||
rawStrings.push(getRawLiteral(template.head, currentSourceFile));
|
||||
for (const templateSpan of template.templateSpans) {
|
||||
cookedStrings.push(createTemplateCooked(templateSpan.literal));
|
||||
rawStrings.push(getRawLiteral(templateSpan.literal, currentSourceFile));
|
||||
templateArguments.push(visitNode(templateSpan.expression, visitor, isExpression));
|
||||
}
|
||||
}
|
||||
|
||||
const helperCall = createTemplateObjectHelper(context, createArrayLiteral(cookedStrings), createArrayLiteral(rawStrings));
|
||||
|
||||
// Create a variable to cache the template object if we're in a module.
|
||||
// Do not do this in the global scope, as any variable we currently generate could conflict with
|
||||
// variables from outside of the current compilation. In the future, we can revisit this behavior.
|
||||
if (isExternalModule(currentSourceFile)) {
|
||||
const tempVar = createUniqueName("templateObject");
|
||||
recordTaggedTemplateString(tempVar);
|
||||
templateArguments[0] = createLogicalOr(
|
||||
tempVar,
|
||||
createAssignment(
|
||||
tempVar,
|
||||
helperCall)
|
||||
);
|
||||
}
|
||||
else {
|
||||
templateArguments[0] = helperCall;
|
||||
}
|
||||
|
||||
return createCall(tag, /*typeArguments*/ undefined, templateArguments);
|
||||
}
|
||||
|
||||
function createTemplateCooked(template: TemplateHead | TemplateMiddle | TemplateTail | NoSubstitutionTemplateLiteral) {
|
||||
return template.templateFlags ? createIdentifier("undefined") : createLiteral(template.text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an ES5 compatible literal from an ES6 template literal.
|
||||
*
|
||||
* @param node The ES6 template literal.
|
||||
*/
|
||||
function getRawLiteral(node: LiteralLikeNode, currentSourceFile: SourceFile) {
|
||||
// Find original source text, since we need to emit the raw strings of the tagged template.
|
||||
// The raw strings contain the (escaped) strings of what the user wrote.
|
||||
// Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
|
||||
let text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
|
||||
|
||||
// text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
|
||||
// thus we need to remove those characters.
|
||||
// First template piece starts with "`", others with "}"
|
||||
// Last template piece ends with "`", others with "${"
|
||||
const isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail;
|
||||
text = text.substring(1, text.length - (isLast ? 1 : 2));
|
||||
|
||||
// Newline normalization:
|
||||
// ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
|
||||
// <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
|
||||
text = text.replace(/\r\n?/g, "\n");
|
||||
return setTextRange(createLiteral(text), node);
|
||||
}
|
||||
|
||||
function createTemplateObjectHelper(context: TransformationContext, cooked: ArrayLiteralExpression, raw: ArrayLiteralExpression) {
|
||||
context.requestEmitHelper(templateObjectHelper);
|
||||
return createCall(
|
||||
getUnscopedHelperName("__makeTemplateObject"),
|
||||
/*typeArguments*/ undefined,
|
||||
[
|
||||
cooked,
|
||||
raw
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
export const templateObjectHelper: UnscopedEmitHelper = {
|
||||
name: "typescript:makeTemplateObject",
|
||||
importName: "__makeTemplateObject",
|
||||
scoped: false,
|
||||
priority: 0,
|
||||
text: `
|
||||
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
||||
return cooked;
|
||||
};`
|
||||
};
|
||||
}
|
|
@ -38,6 +38,7 @@
|
|||
"sourcemap.ts",
|
||||
"transformers/utilities.ts",
|
||||
"transformers/destructuring.ts",
|
||||
"transformers/taggedTemplate.ts",
|
||||
"transformers/ts.ts",
|
||||
"transformers/classFields.ts",
|
||||
"transformers/es2017.ts",
|
||||
|
|
|
@ -1735,6 +1735,8 @@ namespace ts {
|
|||
|
||||
export interface NoSubstitutionTemplateLiteral extends LiteralExpression, TemplateLiteralLikeNode, Declaration {
|
||||
kind: SyntaxKind.NoSubstitutionTemplateLiteral;
|
||||
/* @internal */
|
||||
templateFlags?: TokenFlags;
|
||||
}
|
||||
|
||||
export const enum TokenFlags {
|
||||
|
@ -1757,6 +1759,8 @@ namespace ts {
|
|||
/* @internal */
|
||||
UnicodeEscape = 1 << 10,
|
||||
/* @internal */
|
||||
ContainsInvalidEscape = 1 << 11, // e.g. `\uhello`
|
||||
/* @internal */
|
||||
BinaryOrOctalSpecifier = BinarySpecifier | OctalSpecifier,
|
||||
/* @internal */
|
||||
NumericLiteralFlags = Scientific | Octal | HexSpecifier | BinaryOrOctalSpecifier | ContainsSeparator
|
||||
|
@ -1775,16 +1779,22 @@ namespace ts {
|
|||
export interface TemplateHead extends TemplateLiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateHead;
|
||||
parent: TemplateExpression;
|
||||
/* @internal */
|
||||
templateFlags?: TokenFlags;
|
||||
}
|
||||
|
||||
export interface TemplateMiddle extends TemplateLiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateMiddle;
|
||||
parent: TemplateSpan;
|
||||
/* @internal */
|
||||
templateFlags?: TokenFlags;
|
||||
}
|
||||
|
||||
export interface TemplateTail extends TemplateLiteralLikeNode {
|
||||
kind: SyntaxKind.TemplateTail;
|
||||
parent: TemplateSpan;
|
||||
/* @internal */
|
||||
templateFlags?: TokenFlags;
|
||||
}
|
||||
|
||||
export type TemplateLiteral = TemplateExpression | NoSubstitutionTemplateLiteral;
|
||||
|
|
|
@ -3365,6 +3365,13 @@ namespace ts {
|
|||
return str.replace(templateSubstitutionRegExp, "\\${");
|
||||
}
|
||||
|
||||
/** @internal */
|
||||
export function hasInvalidEscape(template: TemplateLiteral): boolean {
|
||||
return template && !!(isNoSubstitutionTemplateLiteral(template)
|
||||
? template.templateFlags
|
||||
: (template.head.templateFlags || some(template.templateSpans, span => !!span.literal.templateFlags)));
|
||||
}
|
||||
|
||||
// This consists of the first 19 unprintable ASCII characters, canonical escapes, lineSeparator,
|
||||
// paragraphSeparator, and nextLine. The latter three are just desirable to suppress new lines in
|
||||
// the language service. These characters should be escaped when printing, and if any characters are added,
|
||||
|
|
|
@ -135,7 +135,7 @@ namespace ts {
|
|||
const lastTemplateStackToken = lastOrUndefined(templateStack);
|
||||
|
||||
if (lastTemplateStackToken === SyntaxKind.TemplateHead) {
|
||||
token = scanner.reScanTemplateToken();
|
||||
token = scanner.reScanTemplateToken(/* isTaggedTemplate */ false);
|
||||
|
||||
// Only pop on a TemplateTail; a TemplateMiddle indicates there is more for us.
|
||||
if (token === SyntaxKind.TemplateTail) {
|
||||
|
|
|
@ -242,7 +242,7 @@ namespace ts.formatting {
|
|||
case ScanAction.RescanTemplateToken:
|
||||
if (token === SyntaxKind.CloseBraceToken) {
|
||||
lastScanAction = ScanAction.RescanTemplateToken;
|
||||
return scanner.reScanTemplateToken();
|
||||
return scanner.reScanTemplateToken(/* isTaggedTemplate */ false);
|
||||
}
|
||||
break;
|
||||
case ScanAction.RescanJsxIdentifier:
|
||||
|
|
|
@ -3345,7 +3345,8 @@ declare namespace ts {
|
|||
isUnterminated(): boolean;
|
||||
reScanGreaterToken(): SyntaxKind;
|
||||
reScanSlashToken(): SyntaxKind;
|
||||
reScanTemplateToken(): SyntaxKind;
|
||||
reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind;
|
||||
reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind;
|
||||
scanJsxIdentifier(): SyntaxKind;
|
||||
scanJsxAttributeValue(): SyntaxKind;
|
||||
reScanJsxAttributeValue(): SyntaxKind;
|
||||
|
|
|
@ -3345,7 +3345,8 @@ declare namespace ts {
|
|||
isUnterminated(): boolean;
|
||||
reScanGreaterToken(): SyntaxKind;
|
||||
reScanSlashToken(): SyntaxKind;
|
||||
reScanTemplateToken(): SyntaxKind;
|
||||
reScanTemplateToken(isTaggedTemplate: boolean): SyntaxKind;
|
||||
reScanTemplateHeadOrNoSubstitutionTemplate(): SyntaxKind;
|
||||
scanJsxIdentifier(): SyntaxKind;
|
||||
scanJsxAttributeValue(): SyntaxKind;
|
||||
reScanJsxAttributeValue(): SyntaxKind;
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(7,18): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,15): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,33): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,75): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,18): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,27): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,51): error TS1125: Hexadecimal digit expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts (7 errors) ====
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
return str
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
const b = tag`123 ${100}`
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
//// [invalidTaggedTemplateEscapeSequences.ts]
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
return str
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
const b = tag`123 ${100}`
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
|
||||
|
||||
//// [invalidTaggedTemplateEscapeSequences.js]
|
||||
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
||||
return cooked;
|
||||
};
|
||||
function tag(str, ...args) {
|
||||
return str;
|
||||
}
|
||||
const a = tag `123`;
|
||||
const b = tag `123 ${100}`;
|
||||
const x = tag(__makeTemplateObject([undefined, undefined, " wonderful ", undefined], ["\\u{hello} ", " \\xtraordinary ", " wonderful ", " \\uworld"]), 100, 200, 300);
|
||||
const y = `\u{hello} ${100} \xtraordinary ${200} wonderful ${300} \uworld`; // should error with NoSubstitutionTemplate
|
||||
const z = tag(__makeTemplateObject([undefined], ["\\u{hello} \\xtraordinary wonderful \\uworld"])); // should work with Tagged NoSubstitutionTemplate
|
||||
const a1 = tag `${100}\0`; // \0
|
||||
const a2 = tag(__makeTemplateObject(["", undefined], ["", "\\00"]), 100); // \\00
|
||||
const a3 = tag(__makeTemplateObject(["", undefined], ["", "\\u"]), 100); // \\u
|
||||
const a4 = tag(__makeTemplateObject(["", undefined], ["", "\\u0"]), 100); // \\u0
|
||||
const a5 = tag(__makeTemplateObject(["", undefined], ["", "\\u00"]), 100); // \\u00
|
||||
const a6 = tag(__makeTemplateObject(["", undefined], ["", "\\u000"]), 100); // \\u000
|
||||
const a7 = tag `${100}\u0000`; // \u0000
|
||||
const a8 = tag(__makeTemplateObject(["", undefined], ["", "\\u{"]), 100); // \\u{
|
||||
const a9 = tag `${100}\u{10FFFF}`; // \\u{10FFFF
|
||||
const a10 = tag(__makeTemplateObject(["", undefined], ["", "\\u{1f622"]), 100); // \\u{1f622
|
||||
const a11 = tag `${100}\u{1f622}`; // \u{1f622}
|
||||
const a12 = tag(__makeTemplateObject(["", undefined], ["", "\\x"]), 100); // \\x
|
||||
const a13 = tag(__makeTemplateObject(["", undefined], ["", "\\x0"]), 100); // \\x0
|
||||
const a14 = tag `${100}\x00`; // \x00
|
|
@ -0,0 +1,85 @@
|
|||
=== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts ===
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
>str : Symbol(str, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 14))
|
||||
>args : Symbol(args, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 23))
|
||||
|
||||
return str
|
||||
>str : Symbol(str, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 14))
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
>a : Symbol(a, Decl(invalidTaggedTemplateEscapeSequences.ts, 4, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const b = tag`123 ${100}`
|
||||
>b : Symbol(b, Decl(invalidTaggedTemplateEscapeSequences.ts, 5, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
>x : Symbol(x, Decl(invalidTaggedTemplateEscapeSequences.ts, 6, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
>y : Symbol(y, Decl(invalidTaggedTemplateEscapeSequences.ts, 7, 5))
|
||||
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
>z : Symbol(z, Decl(invalidTaggedTemplateEscapeSequences.ts, 8, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
>a1 : Symbol(a1, Decl(invalidTaggedTemplateEscapeSequences.ts, 10, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
>a2 : Symbol(a2, Decl(invalidTaggedTemplateEscapeSequences.ts, 11, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
>a3 : Symbol(a3, Decl(invalidTaggedTemplateEscapeSequences.ts, 12, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
>a4 : Symbol(a4, Decl(invalidTaggedTemplateEscapeSequences.ts, 13, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
>a5 : Symbol(a5, Decl(invalidTaggedTemplateEscapeSequences.ts, 14, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
>a6 : Symbol(a6, Decl(invalidTaggedTemplateEscapeSequences.ts, 15, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
>a7 : Symbol(a7, Decl(invalidTaggedTemplateEscapeSequences.ts, 16, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
>a8 : Symbol(a8, Decl(invalidTaggedTemplateEscapeSequences.ts, 17, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
>a9 : Symbol(a9, Decl(invalidTaggedTemplateEscapeSequences.ts, 18, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
>a10 : Symbol(a10, Decl(invalidTaggedTemplateEscapeSequences.ts, 19, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
>a11 : Symbol(a11, Decl(invalidTaggedTemplateEscapeSequences.ts, 20, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
>a12 : Symbol(a12, Decl(invalidTaggedTemplateEscapeSequences.ts, 21, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
>a13 : Symbol(a13, Decl(invalidTaggedTemplateEscapeSequences.ts, 22, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
>a14 : Symbol(a14, Decl(invalidTaggedTemplateEscapeSequences.ts, 23, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
=== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts ===
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>str : any
|
||||
>args : any[]
|
||||
|
||||
return str
|
||||
>str : any
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
>a : any
|
||||
>tag`123` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`123` : "123"
|
||||
|
||||
const b = tag`123 ${100}`
|
||||
>b : any
|
||||
>tag`123 ${100}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`123 ${100}` : string
|
||||
>100 : 100
|
||||
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
>x : any
|
||||
>tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : string
|
||||
>100 : 100
|
||||
>200 : 200
|
||||
>300 : 300
|
||||
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
>y : string
|
||||
>`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : string
|
||||
>100 : 100
|
||||
>200 : 200
|
||||
>300 : 300
|
||||
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
>z : any
|
||||
>tag`\u{hello} \xtraordinary wonderful \uworld` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`\u{hello} \xtraordinary wonderful \uworld` : "\\u{hello} \\xtraordinary wonderful \\uworld"
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
>a1 : any
|
||||
>tag`${ 100 }\0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\0` : string
|
||||
>100 : 100
|
||||
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
>a2 : any
|
||||
>tag`${ 100 }\00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\00` : string
|
||||
>100 : 100
|
||||
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
>a3 : any
|
||||
>tag`${ 100 }\u` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u` : string
|
||||
>100 : 100
|
||||
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
>a4 : any
|
||||
>tag`${ 100 }\u0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u0` : string
|
||||
>100 : 100
|
||||
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
>a5 : any
|
||||
>tag`${ 100 }\u00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u00` : string
|
||||
>100 : 100
|
||||
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
>a6 : any
|
||||
>tag`${ 100 }\u000` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u000` : string
|
||||
>100 : 100
|
||||
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
>a7 : any
|
||||
>tag`${ 100 }\u0000` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u0000` : string
|
||||
>100 : 100
|
||||
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
>a8 : any
|
||||
>tag`${ 100 }\u{` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{` : string
|
||||
>100 : 100
|
||||
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
>a9 : any
|
||||
>tag`${ 100 }\u{10FFFF}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{10FFFF}` : string
|
||||
>100 : 100
|
||||
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
>a10 : any
|
||||
>tag`${ 100 }\u{1f622` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{1f622` : string
|
||||
>100 : 100
|
||||
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
>a11 : any
|
||||
>tag`${ 100 }\u{1f622}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{1f622}` : string
|
||||
>100 : 100
|
||||
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
>a12 : any
|
||||
>tag`${ 100 }\x` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x` : string
|
||||
>100 : 100
|
||||
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
>a13 : any
|
||||
>tag`${ 100 }\x0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x0` : string
|
||||
>100 : 100
|
||||
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
>a14 : any
|
||||
>tag`${ 100 }\x00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x00` : string
|
||||
>100 : 100
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(7,18): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,15): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,33): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,75): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,18): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,27): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,51): error TS1125: Hexadecimal digit expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts (7 errors) ====
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
return str
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
const b = tag`123 ${100}`
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
//// [invalidTaggedTemplateEscapeSequences.ts]
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
return str
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
const b = tag`123 ${100}`
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
|
||||
|
||||
//// [invalidTaggedTemplateEscapeSequences.js]
|
||||
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
||||
return cooked;
|
||||
};
|
||||
function tag(str) {
|
||||
var args = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
args[_i - 1] = arguments[_i];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
var a = tag(__makeTemplateObject(["123"], ["123"]));
|
||||
var b = tag(__makeTemplateObject(["123 ", ""], ["123 ", ""]), 100);
|
||||
var x = tag(__makeTemplateObject([undefined, undefined, " wonderful ", undefined], ["\\u{hello} ", " \\xtraordinary ", " wonderful ", " \\uworld"]), 100, 200, 300);
|
||||
var y = "hello} " + 100 + " traordinary " + 200 + " wonderful " + 300 + " world"; // should error with NoSubstitutionTemplate
|
||||
var z = tag(__makeTemplateObject([undefined], ["\\u{hello} \\xtraordinary wonderful \\uworld"])); // should work with Tagged NoSubstitutionTemplate
|
||||
var a1 = tag(__makeTemplateObject(["", "\0"], ["", "\\0"]), 100); // \0
|
||||
var a2 = tag(__makeTemplateObject(["", undefined], ["", "\\00"]), 100); // \\00
|
||||
var a3 = tag(__makeTemplateObject(["", undefined], ["", "\\u"]), 100); // \\u
|
||||
var a4 = tag(__makeTemplateObject(["", undefined], ["", "\\u0"]), 100); // \\u0
|
||||
var a5 = tag(__makeTemplateObject(["", undefined], ["", "\\u00"]), 100); // \\u00
|
||||
var a6 = tag(__makeTemplateObject(["", undefined], ["", "\\u000"]), 100); // \\u000
|
||||
var a7 = tag(__makeTemplateObject(["", "\0"], ["", "\\u0000"]), 100); // \u0000
|
||||
var a8 = tag(__makeTemplateObject(["", undefined], ["", "\\u{"]), 100); // \\u{
|
||||
var a9 = tag(__makeTemplateObject(["", "\uDBFF\uDFFF"], ["", "\\u{10FFFF}"]), 100); // \\u{10FFFF
|
||||
var a10 = tag(__makeTemplateObject(["", undefined], ["", "\\u{1f622"]), 100); // \\u{1f622
|
||||
var a11 = tag(__makeTemplateObject(["", "\uD83D\uDE22"], ["", "\\u{1f622}"]), 100); // \u{1f622}
|
||||
var a12 = tag(__makeTemplateObject(["", undefined], ["", "\\x"]), 100); // \\x
|
||||
var a13 = tag(__makeTemplateObject(["", undefined], ["", "\\x0"]), 100); // \\x0
|
||||
var a14 = tag(__makeTemplateObject(["", "\0"], ["", "\\x00"]), 100); // \x00
|
|
@ -0,0 +1,85 @@
|
|||
=== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts ===
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
>str : Symbol(str, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 14))
|
||||
>args : Symbol(args, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 23))
|
||||
|
||||
return str
|
||||
>str : Symbol(str, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 14))
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
>a : Symbol(a, Decl(invalidTaggedTemplateEscapeSequences.ts, 4, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const b = tag`123 ${100}`
|
||||
>b : Symbol(b, Decl(invalidTaggedTemplateEscapeSequences.ts, 5, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
>x : Symbol(x, Decl(invalidTaggedTemplateEscapeSequences.ts, 6, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
>y : Symbol(y, Decl(invalidTaggedTemplateEscapeSequences.ts, 7, 5))
|
||||
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
>z : Symbol(z, Decl(invalidTaggedTemplateEscapeSequences.ts, 8, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
>a1 : Symbol(a1, Decl(invalidTaggedTemplateEscapeSequences.ts, 10, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
>a2 : Symbol(a2, Decl(invalidTaggedTemplateEscapeSequences.ts, 11, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
>a3 : Symbol(a3, Decl(invalidTaggedTemplateEscapeSequences.ts, 12, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
>a4 : Symbol(a4, Decl(invalidTaggedTemplateEscapeSequences.ts, 13, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
>a5 : Symbol(a5, Decl(invalidTaggedTemplateEscapeSequences.ts, 14, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
>a6 : Symbol(a6, Decl(invalidTaggedTemplateEscapeSequences.ts, 15, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
>a7 : Symbol(a7, Decl(invalidTaggedTemplateEscapeSequences.ts, 16, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
>a8 : Symbol(a8, Decl(invalidTaggedTemplateEscapeSequences.ts, 17, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
>a9 : Symbol(a9, Decl(invalidTaggedTemplateEscapeSequences.ts, 18, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
>a10 : Symbol(a10, Decl(invalidTaggedTemplateEscapeSequences.ts, 19, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
>a11 : Symbol(a11, Decl(invalidTaggedTemplateEscapeSequences.ts, 20, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
>a12 : Symbol(a12, Decl(invalidTaggedTemplateEscapeSequences.ts, 21, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
>a13 : Symbol(a13, Decl(invalidTaggedTemplateEscapeSequences.ts, 22, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
>a14 : Symbol(a14, Decl(invalidTaggedTemplateEscapeSequences.ts, 23, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
=== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts ===
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>str : any
|
||||
>args : any[]
|
||||
|
||||
return str
|
||||
>str : any
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
>a : any
|
||||
>tag`123` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`123` : "123"
|
||||
|
||||
const b = tag`123 ${100}`
|
||||
>b : any
|
||||
>tag`123 ${100}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`123 ${100}` : string
|
||||
>100 : 100
|
||||
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
>x : any
|
||||
>tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : string
|
||||
>100 : 100
|
||||
>200 : 200
|
||||
>300 : 300
|
||||
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
>y : string
|
||||
>`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : string
|
||||
>100 : 100
|
||||
>200 : 200
|
||||
>300 : 300
|
||||
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
>z : any
|
||||
>tag`\u{hello} \xtraordinary wonderful \uworld` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`\u{hello} \xtraordinary wonderful \uworld` : "\\u{hello} \\xtraordinary wonderful \\uworld"
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
>a1 : any
|
||||
>tag`${ 100 }\0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\0` : string
|
||||
>100 : 100
|
||||
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
>a2 : any
|
||||
>tag`${ 100 }\00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\00` : string
|
||||
>100 : 100
|
||||
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
>a3 : any
|
||||
>tag`${ 100 }\u` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u` : string
|
||||
>100 : 100
|
||||
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
>a4 : any
|
||||
>tag`${ 100 }\u0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u0` : string
|
||||
>100 : 100
|
||||
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
>a5 : any
|
||||
>tag`${ 100 }\u00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u00` : string
|
||||
>100 : 100
|
||||
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
>a6 : any
|
||||
>tag`${ 100 }\u000` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u000` : string
|
||||
>100 : 100
|
||||
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
>a7 : any
|
||||
>tag`${ 100 }\u0000` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u0000` : string
|
||||
>100 : 100
|
||||
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
>a8 : any
|
||||
>tag`${ 100 }\u{` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{` : string
|
||||
>100 : 100
|
||||
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
>a9 : any
|
||||
>tag`${ 100 }\u{10FFFF}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{10FFFF}` : string
|
||||
>100 : 100
|
||||
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
>a10 : any
|
||||
>tag`${ 100 }\u{1f622` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{1f622` : string
|
||||
>100 : 100
|
||||
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
>a11 : any
|
||||
>tag`${ 100 }\u{1f622}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{1f622}` : string
|
||||
>100 : 100
|
||||
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
>a12 : any
|
||||
>tag`${ 100 }\x` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x` : string
|
||||
>100 : 100
|
||||
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
>a13 : any
|
||||
>tag`${ 100 }\x0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x0` : string
|
||||
>100 : 100
|
||||
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
>a14 : any
|
||||
>tag`${ 100 }\x00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x00` : string
|
||||
>100 : 100
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(7,18): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,15): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,33): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,75): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,18): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,27): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,51): error TS1125: Hexadecimal digit expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts (7 errors) ====
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
return str
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
const b = tag`123 ${100}`
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
//// [invalidTaggedTemplateEscapeSequences.ts]
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
return str
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
const b = tag`123 ${100}`
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
|
||||
|
||||
//// [invalidTaggedTemplateEscapeSequences.js]
|
||||
function tag(str, ...args) {
|
||||
return str;
|
||||
}
|
||||
const a = tag `123`;
|
||||
const b = tag `123 ${100}`;
|
||||
const x = tag `\u{hello} ${100} \xtraordinary ${200} wonderful ${300} \uworld`;
|
||||
const y = `\u{hello} ${100} \xtraordinary ${200} wonderful ${300} \uworld`; // should error with NoSubstitutionTemplate
|
||||
const z = tag `\u{hello} \xtraordinary wonderful \uworld`; // should work with Tagged NoSubstitutionTemplate
|
||||
const a1 = tag `${100}\0`; // \0
|
||||
const a2 = tag `${100}\00`; // \\00
|
||||
const a3 = tag `${100}\u`; // \\u
|
||||
const a4 = tag `${100}\u0`; // \\u0
|
||||
const a5 = tag `${100}\u00`; // \\u00
|
||||
const a6 = tag `${100}\u000`; // \\u000
|
||||
const a7 = tag `${100}\u0000`; // \u0000
|
||||
const a8 = tag `${100}\u{`; // \\u{
|
||||
const a9 = tag `${100}\u{10FFFF}`; // \\u{10FFFF
|
||||
const a10 = tag `${100}\u{1f622`; // \\u{1f622
|
||||
const a11 = tag `${100}\u{1f622}`; // \u{1f622}
|
||||
const a12 = tag `${100}\x`; // \\x
|
||||
const a13 = tag `${100}\x0`; // \\x0
|
||||
const a14 = tag `${100}\x00`; // \x00
|
|
@ -0,0 +1,85 @@
|
|||
=== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts ===
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
>str : Symbol(str, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 14))
|
||||
>args : Symbol(args, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 23))
|
||||
|
||||
return str
|
||||
>str : Symbol(str, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 14))
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
>a : Symbol(a, Decl(invalidTaggedTemplateEscapeSequences.ts, 4, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const b = tag`123 ${100}`
|
||||
>b : Symbol(b, Decl(invalidTaggedTemplateEscapeSequences.ts, 5, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
>x : Symbol(x, Decl(invalidTaggedTemplateEscapeSequences.ts, 6, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
>y : Symbol(y, Decl(invalidTaggedTemplateEscapeSequences.ts, 7, 5))
|
||||
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
>z : Symbol(z, Decl(invalidTaggedTemplateEscapeSequences.ts, 8, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
>a1 : Symbol(a1, Decl(invalidTaggedTemplateEscapeSequences.ts, 10, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
>a2 : Symbol(a2, Decl(invalidTaggedTemplateEscapeSequences.ts, 11, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
>a3 : Symbol(a3, Decl(invalidTaggedTemplateEscapeSequences.ts, 12, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
>a4 : Symbol(a4, Decl(invalidTaggedTemplateEscapeSequences.ts, 13, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
>a5 : Symbol(a5, Decl(invalidTaggedTemplateEscapeSequences.ts, 14, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
>a6 : Symbol(a6, Decl(invalidTaggedTemplateEscapeSequences.ts, 15, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
>a7 : Symbol(a7, Decl(invalidTaggedTemplateEscapeSequences.ts, 16, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
>a8 : Symbol(a8, Decl(invalidTaggedTemplateEscapeSequences.ts, 17, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
>a9 : Symbol(a9, Decl(invalidTaggedTemplateEscapeSequences.ts, 18, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
>a10 : Symbol(a10, Decl(invalidTaggedTemplateEscapeSequences.ts, 19, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
>a11 : Symbol(a11, Decl(invalidTaggedTemplateEscapeSequences.ts, 20, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
>a12 : Symbol(a12, Decl(invalidTaggedTemplateEscapeSequences.ts, 21, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
>a13 : Symbol(a13, Decl(invalidTaggedTemplateEscapeSequences.ts, 22, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
>a14 : Symbol(a14, Decl(invalidTaggedTemplateEscapeSequences.ts, 23, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
=== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts ===
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>str : any
|
||||
>args : any[]
|
||||
|
||||
return str
|
||||
>str : any
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
>a : any
|
||||
>tag`123` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`123` : "123"
|
||||
|
||||
const b = tag`123 ${100}`
|
||||
>b : any
|
||||
>tag`123 ${100}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`123 ${100}` : string
|
||||
>100 : 100
|
||||
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
>x : any
|
||||
>tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : string
|
||||
>100 : 100
|
||||
>200 : 200
|
||||
>300 : 300
|
||||
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
>y : string
|
||||
>`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : string
|
||||
>100 : 100
|
||||
>200 : 200
|
||||
>300 : 300
|
||||
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
>z : any
|
||||
>tag`\u{hello} \xtraordinary wonderful \uworld` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`\u{hello} \xtraordinary wonderful \uworld` : "\\u{hello} \\xtraordinary wonderful \\uworld"
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
>a1 : any
|
||||
>tag`${ 100 }\0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\0` : string
|
||||
>100 : 100
|
||||
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
>a2 : any
|
||||
>tag`${ 100 }\00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\00` : string
|
||||
>100 : 100
|
||||
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
>a3 : any
|
||||
>tag`${ 100 }\u` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u` : string
|
||||
>100 : 100
|
||||
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
>a4 : any
|
||||
>tag`${ 100 }\u0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u0` : string
|
||||
>100 : 100
|
||||
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
>a5 : any
|
||||
>tag`${ 100 }\u00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u00` : string
|
||||
>100 : 100
|
||||
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
>a6 : any
|
||||
>tag`${ 100 }\u000` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u000` : string
|
||||
>100 : 100
|
||||
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
>a7 : any
|
||||
>tag`${ 100 }\u0000` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u0000` : string
|
||||
>100 : 100
|
||||
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
>a8 : any
|
||||
>tag`${ 100 }\u{` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{` : string
|
||||
>100 : 100
|
||||
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
>a9 : any
|
||||
>tag`${ 100 }\u{10FFFF}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{10FFFF}` : string
|
||||
>100 : 100
|
||||
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
>a10 : any
|
||||
>tag`${ 100 }\u{1f622` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{1f622` : string
|
||||
>100 : 100
|
||||
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
>a11 : any
|
||||
>tag`${ 100 }\u{1f622}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{1f622}` : string
|
||||
>100 : 100
|
||||
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
>a12 : any
|
||||
>tag`${ 100 }\x` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x` : string
|
||||
>100 : 100
|
||||
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
>a13 : any
|
||||
>tag`${ 100 }\x0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x0` : string
|
||||
>100 : 100
|
||||
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
>a14 : any
|
||||
>tag`${ 100 }\x00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x00` : string
|
||||
>100 : 100
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(7,18): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,15): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,33): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(8,75): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,18): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,27): error TS1125: Hexadecimal digit expected.
|
||||
tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts(9,51): error TS1125: Hexadecimal digit expected.
|
||||
|
||||
|
||||
==== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts (7 errors) ====
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
return str
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
const b = tag`123 ${100}`
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
!!! error TS1125: Hexadecimal digit expected.
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
//// [invalidTaggedTemplateEscapeSequences.ts]
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
return str
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
const b = tag`123 ${100}`
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
|
||||
|
||||
//// [invalidTaggedTemplateEscapeSequences.js]
|
||||
var __makeTemplateObject = (this && this.__makeTemplateObject) || function (cooked, raw) {
|
||||
if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
|
||||
return cooked;
|
||||
};
|
||||
function tag(str) {
|
||||
var args = [];
|
||||
for (var _i = 1; _i < arguments.length; _i++) {
|
||||
args[_i - 1] = arguments[_i];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
var a = tag(__makeTemplateObject(["123"], ["123"]));
|
||||
var b = tag(__makeTemplateObject(["123 ", ""], ["123 ", ""]), 100);
|
||||
var x = tag(__makeTemplateObject([undefined, undefined, " wonderful ", undefined], ["\\u{hello} ", " \\xtraordinary ", " wonderful ", " \\uworld"]), 100, 200, 300);
|
||||
var y = "hello} " + 100 + " traordinary " + 200 + " wonderful " + 300 + " world"; // should error with NoSubstitutionTemplate
|
||||
var z = tag(__makeTemplateObject([undefined], ["\\u{hello} \\xtraordinary wonderful \\uworld"])); // should work with Tagged NoSubstitutionTemplate
|
||||
var a1 = tag(__makeTemplateObject(["", "\0"], ["", "\\0"]), 100); // \0
|
||||
var a2 = tag(__makeTemplateObject(["", undefined], ["", "\\00"]), 100); // \\00
|
||||
var a3 = tag(__makeTemplateObject(["", undefined], ["", "\\u"]), 100); // \\u
|
||||
var a4 = tag(__makeTemplateObject(["", undefined], ["", "\\u0"]), 100); // \\u0
|
||||
var a5 = tag(__makeTemplateObject(["", undefined], ["", "\\u00"]), 100); // \\u00
|
||||
var a6 = tag(__makeTemplateObject(["", undefined], ["", "\\u000"]), 100); // \\u000
|
||||
var a7 = tag(__makeTemplateObject(["", "\0"], ["", "\\u0000"]), 100); // \u0000
|
||||
var a8 = tag(__makeTemplateObject(["", undefined], ["", "\\u{"]), 100); // \\u{
|
||||
var a9 = tag(__makeTemplateObject(["", "\uDBFF\uDFFF"], ["", "\\u{10FFFF}"]), 100); // \\u{10FFFF
|
||||
var a10 = tag(__makeTemplateObject(["", undefined], ["", "\\u{1f622"]), 100); // \\u{1f622
|
||||
var a11 = tag(__makeTemplateObject(["", "\uD83D\uDE22"], ["", "\\u{1f622}"]), 100); // \u{1f622}
|
||||
var a12 = tag(__makeTemplateObject(["", undefined], ["", "\\x"]), 100); // \\x
|
||||
var a13 = tag(__makeTemplateObject(["", undefined], ["", "\\x0"]), 100); // \\x0
|
||||
var a14 = tag(__makeTemplateObject(["", "\0"], ["", "\\x00"]), 100); // \x00
|
|
@ -0,0 +1,85 @@
|
|||
=== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts ===
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
>str : Symbol(str, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 14))
|
||||
>args : Symbol(args, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 23))
|
||||
|
||||
return str
|
||||
>str : Symbol(str, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 14))
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
>a : Symbol(a, Decl(invalidTaggedTemplateEscapeSequences.ts, 4, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const b = tag`123 ${100}`
|
||||
>b : Symbol(b, Decl(invalidTaggedTemplateEscapeSequences.ts, 5, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
>x : Symbol(x, Decl(invalidTaggedTemplateEscapeSequences.ts, 6, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
>y : Symbol(y, Decl(invalidTaggedTemplateEscapeSequences.ts, 7, 5))
|
||||
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
>z : Symbol(z, Decl(invalidTaggedTemplateEscapeSequences.ts, 8, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
>a1 : Symbol(a1, Decl(invalidTaggedTemplateEscapeSequences.ts, 10, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
>a2 : Symbol(a2, Decl(invalidTaggedTemplateEscapeSequences.ts, 11, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
>a3 : Symbol(a3, Decl(invalidTaggedTemplateEscapeSequences.ts, 12, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
>a4 : Symbol(a4, Decl(invalidTaggedTemplateEscapeSequences.ts, 13, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
>a5 : Symbol(a5, Decl(invalidTaggedTemplateEscapeSequences.ts, 14, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
>a6 : Symbol(a6, Decl(invalidTaggedTemplateEscapeSequences.ts, 15, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
>a7 : Symbol(a7, Decl(invalidTaggedTemplateEscapeSequences.ts, 16, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
>a8 : Symbol(a8, Decl(invalidTaggedTemplateEscapeSequences.ts, 17, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
>a9 : Symbol(a9, Decl(invalidTaggedTemplateEscapeSequences.ts, 18, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
>a10 : Symbol(a10, Decl(invalidTaggedTemplateEscapeSequences.ts, 19, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
>a11 : Symbol(a11, Decl(invalidTaggedTemplateEscapeSequences.ts, 20, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
>a12 : Symbol(a12, Decl(invalidTaggedTemplateEscapeSequences.ts, 21, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
>a13 : Symbol(a13, Decl(invalidTaggedTemplateEscapeSequences.ts, 22, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
>a14 : Symbol(a14, Decl(invalidTaggedTemplateEscapeSequences.ts, 23, 5))
|
||||
>tag : Symbol(tag, Decl(invalidTaggedTemplateEscapeSequences.ts, 0, 0))
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
=== tests/cases/conformance/es2018/invalidTaggedTemplateEscapeSequences.ts ===
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>str : any
|
||||
>args : any[]
|
||||
|
||||
return str
|
||||
>str : any
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
>a : any
|
||||
>tag`123` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`123` : "123"
|
||||
|
||||
const b = tag`123 ${100}`
|
||||
>b : any
|
||||
>tag`123 ${100}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`123 ${100}` : string
|
||||
>100 : 100
|
||||
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
>x : any
|
||||
>tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : string
|
||||
>100 : 100
|
||||
>200 : 200
|
||||
>300 : 300
|
||||
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
>y : string
|
||||
>`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld` : string
|
||||
>100 : 100
|
||||
>200 : 200
|
||||
>300 : 300
|
||||
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
>z : any
|
||||
>tag`\u{hello} \xtraordinary wonderful \uworld` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`\u{hello} \xtraordinary wonderful \uworld` : "\\u{hello} \\xtraordinary wonderful \\uworld"
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
>a1 : any
|
||||
>tag`${ 100 }\0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\0` : string
|
||||
>100 : 100
|
||||
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
>a2 : any
|
||||
>tag`${ 100 }\00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\00` : string
|
||||
>100 : 100
|
||||
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
>a3 : any
|
||||
>tag`${ 100 }\u` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u` : string
|
||||
>100 : 100
|
||||
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
>a4 : any
|
||||
>tag`${ 100 }\u0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u0` : string
|
||||
>100 : 100
|
||||
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
>a5 : any
|
||||
>tag`${ 100 }\u00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u00` : string
|
||||
>100 : 100
|
||||
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
>a6 : any
|
||||
>tag`${ 100 }\u000` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u000` : string
|
||||
>100 : 100
|
||||
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
>a7 : any
|
||||
>tag`${ 100 }\u0000` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u0000` : string
|
||||
>100 : 100
|
||||
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
>a8 : any
|
||||
>tag`${ 100 }\u{` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{` : string
|
||||
>100 : 100
|
||||
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
>a9 : any
|
||||
>tag`${ 100 }\u{10FFFF}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{10FFFF}` : string
|
||||
>100 : 100
|
||||
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
>a10 : any
|
||||
>tag`${ 100 }\u{1f622` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{1f622` : string
|
||||
>100 : 100
|
||||
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
>a11 : any
|
||||
>tag`${ 100 }\u{1f622}` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\u{1f622}` : string
|
||||
>100 : 100
|
||||
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
>a12 : any
|
||||
>tag`${ 100 }\x` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x` : string
|
||||
>100 : 100
|
||||
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
>a13 : any
|
||||
>tag`${ 100 }\x0` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x0` : string
|
||||
>100 : 100
|
||||
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
||||
>a14 : any
|
||||
>tag`${ 100 }\x00` : any
|
||||
>tag : (str: any, ...args: any[]) => any
|
||||
>`${ 100 }\x00` : string
|
||||
>100 : 100
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
// @target: ES5, ES2015, esnext
|
||||
|
||||
function tag (str: any, ...args: any[]): any {
|
||||
return str
|
||||
}
|
||||
|
||||
const a = tag`123`
|
||||
const b = tag`123 ${100}`
|
||||
const x = tag`\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`;
|
||||
const y = `\u{hello} ${ 100 } \xtraordinary ${ 200 } wonderful ${ 300 } \uworld`; // should error with NoSubstitutionTemplate
|
||||
const z = tag`\u{hello} \xtraordinary wonderful \uworld` // should work with Tagged NoSubstitutionTemplate
|
||||
|
||||
const a1 = tag`${ 100 }\0` // \0
|
||||
const a2 = tag`${ 100 }\00` // \\00
|
||||
const a3 = tag`${ 100 }\u` // \\u
|
||||
const a4 = tag`${ 100 }\u0` // \\u0
|
||||
const a5 = tag`${ 100 }\u00` // \\u00
|
||||
const a6 = tag`${ 100 }\u000` // \\u000
|
||||
const a7 = tag`${ 100 }\u0000` // \u0000
|
||||
const a8 = tag`${ 100 }\u{` // \\u{
|
||||
const a9 = tag`${ 100 }\u{10FFFF}` // \\u{10FFFF
|
||||
const a10 = tag`${ 100 }\u{1f622` // \\u{1f622
|
||||
const a11 = tag`${ 100 }\u{1f622}` // \u{1f622}
|
||||
const a12 = tag`${ 100 }\x` // \\x
|
||||
const a13 = tag`${ 100 }\x0` // \\x0
|
||||
const a14 = tag`${ 100 }\x00` // \x00
|
Loading…
Reference in a new issue