mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-19 10:41:56 -05:00
Addressed CR feedback.
This commit is contained in:
@@ -5945,10 +5945,17 @@ module ts {
|
||||
return getUnionType([type1, type2]);
|
||||
}
|
||||
|
||||
function checkTemplateExpression(node: TemplateExpression): void {
|
||||
function checkTemplateExpression(node: TemplateExpression): Type {
|
||||
// We just want to check each expressions, but we are unconcerned with
|
||||
// the type of each expression, as any value may be coerced into a string.
|
||||
// It is worth asking whether this is what we really want though.
|
||||
// A place where we actually *are* concerned with the expressions' types are
|
||||
// in tagged templates.
|
||||
forEach((<TemplateExpression>node).templateSpans, templateSpan => {
|
||||
checkExpression(templateSpan.expression);
|
||||
});
|
||||
|
||||
return stringType;
|
||||
}
|
||||
|
||||
function checkExpressionWithContextualType(node: Expression, contextualType: Type, contextualMapper?: TypeMapper): Type {
|
||||
@@ -6005,8 +6012,7 @@ module ts {
|
||||
case SyntaxKind.NumericLiteral:
|
||||
return numberType;
|
||||
case SyntaxKind.TemplateExpression:
|
||||
checkTemplateExpression(<TemplateExpression>node);
|
||||
// fall through
|
||||
return checkTemplateExpression(<TemplateExpression>node);
|
||||
case SyntaxKind.StringLiteral:
|
||||
case SyntaxKind.NoSubstitutionTemplateLiteral:
|
||||
return stringType;
|
||||
|
||||
@@ -806,12 +806,14 @@ module ts {
|
||||
}
|
||||
|
||||
function getTemplateLiteralAsStringLiteral(node: LiteralExpression): string {
|
||||
return "\"" + escapeString(node.text) + "\"";
|
||||
return '"' + escapeString(node.text) + '"';
|
||||
}
|
||||
|
||||
function emitTemplateExpression(node: TemplateExpression): void {
|
||||
// In ES6 mode and above, we can simply emit each portion of a template in order, but in
|
||||
// ES3 & ES5 we must convert the template expression into a series of string concatenations.
|
||||
if (compilerOptions.target >= ScriptTarget.ES6) {
|
||||
forEachChild(node, emitNode);
|
||||
forEachChild(node, emit);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -825,6 +827,15 @@ module ts {
|
||||
emitLiteral(node.head);
|
||||
|
||||
forEach(node.templateSpans, templateSpan => {
|
||||
// Check if the expression has operands and binds its operands less closely than binary '+'.
|
||||
// If it does, we need to wrap the expression in parentheses. Otherwise, something like
|
||||
// `abc${ 1 << 2}`
|
||||
// becomes
|
||||
// "abc" + 1 << 2 + ""
|
||||
// which is really
|
||||
// ("abc" + 1) << (2 + "")
|
||||
// rather than
|
||||
// "abc" + (1 << 2) + ""
|
||||
var needsParens = comparePrecedenceToBinaryPlus(templateSpan.expression) !== Comparison.GreaterThan;
|
||||
|
||||
write(" + ");
|
||||
@@ -858,6 +869,7 @@ module ts {
|
||||
//
|
||||
// TODO (drosen): Note that we need to account for the upcoming 'yield' and
|
||||
// spread ('...') unary operators that are anticipated for ES6.
|
||||
Debug.assert(compilerOptions.target <= ScriptTarget.ES5);
|
||||
switch (expression.kind) {
|
||||
case SyntaxKind.BinaryExpression:
|
||||
switch ((<BinaryExpression>expression).operator) {
|
||||
@@ -880,7 +892,8 @@ module ts {
|
||||
}
|
||||
|
||||
function emitTemplateSpan(span: TemplateSpan) {
|
||||
forEachChild(span, emitNode);
|
||||
emit(span.expression);
|
||||
emit(span.literal);
|
||||
}
|
||||
|
||||
// This function specifically handles numeric/string literals for enum and accessor 'identifiers'.
|
||||
|
||||
@@ -519,10 +519,10 @@ module ts {
|
||||
return +(text.substring(start, pos));
|
||||
}
|
||||
|
||||
function scanHexDigits(count: number, useExactCount?: boolean): number {
|
||||
function scanHexDigits(count: number, mustMatchCount?: boolean): number {
|
||||
var digits = 0;
|
||||
var value = 0;
|
||||
while (digits < count || !useExactCount) {
|
||||
while (digits < count || !mustMatchCount) {
|
||||
var ch = text.charCodeAt(pos);
|
||||
if (ch >= CharacterCodes._0 && ch <= CharacterCodes._9) {
|
||||
value = value * 16 + ch - CharacterCodes._0;
|
||||
@@ -582,18 +582,18 @@ module ts {
|
||||
* a literal component of a TemplateExpression.
|
||||
*/
|
||||
function scanTemplateAndSetTokenValue(): SyntaxKind {
|
||||
var isStartOfTemplate = text.charCodeAt(pos) === CharacterCodes.backtick;
|
||||
var startedWithBacktick = text.charCodeAt(pos) === CharacterCodes.backtick;
|
||||
|
||||
pos++;
|
||||
var start = pos;
|
||||
var contents = ""
|
||||
var resultingToken = SyntaxKind.Unknown;
|
||||
var resultingToken: SyntaxKind;
|
||||
|
||||
while (true) {
|
||||
if (pos >= len) {
|
||||
contents += text.substring(start, pos);
|
||||
error(Diagnostics.Unexpected_end_of_text);
|
||||
resultingToken = isStartOfTemplate ? SyntaxKind.NoSubstitutionTemplateLiteral : SyntaxKind.TemplateTail;
|
||||
resultingToken = startedWithBacktick ? SyntaxKind.NoSubstitutionTemplateLiteral : SyntaxKind.TemplateTail;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -603,7 +603,7 @@ module ts {
|
||||
if (currChar === CharacterCodes.backtick) {
|
||||
contents += text.substring(start, pos);
|
||||
pos++;
|
||||
resultingToken = isStartOfTemplate ? SyntaxKind.NoSubstitutionTemplateLiteral : SyntaxKind.TemplateTail;
|
||||
resultingToken = startedWithBacktick ? SyntaxKind.NoSubstitutionTemplateLiteral : SyntaxKind.TemplateTail;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -611,7 +611,7 @@ module ts {
|
||||
if (currChar === CharacterCodes.$ && pos + 1 < len && text.charCodeAt(pos + 1) === CharacterCodes.openBrace) {
|
||||
contents += text.substring(start, pos);
|
||||
pos += 2;
|
||||
resultingToken = isStartOfTemplate ? SyntaxKind.TemplateHead : SyntaxKind.TemplateMiddle;
|
||||
resultingToken = startedWithBacktick ? SyntaxKind.TemplateHead : SyntaxKind.TemplateMiddle;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -641,6 +641,8 @@ module ts {
|
||||
pos++;
|
||||
}
|
||||
|
||||
Debug.assert(resultingToken !== undefined);
|
||||
|
||||
tokenValue = contents;
|
||||
return resultingToken;
|
||||
}
|
||||
@@ -673,7 +675,7 @@ module ts {
|
||||
return "\"";
|
||||
case CharacterCodes.x:
|
||||
case CharacterCodes.u:
|
||||
var ch = scanHexDigits(ch === CharacterCodes.x ? 2 : 4, /*useExactCount*/ true);
|
||||
var ch = scanHexDigits(ch === CharacterCodes.x ? 2 : 4, /*mustMatchCount*/ true);
|
||||
if (ch >= 0) {
|
||||
return String.fromCharCode(ch);
|
||||
}
|
||||
@@ -704,7 +706,7 @@ module ts {
|
||||
if (pos + 5 < len && text.charCodeAt(pos + 1) === CharacterCodes.u) {
|
||||
var start = pos;
|
||||
pos += 2;
|
||||
var value = scanHexDigits(4, /*useExactCount*/ true);
|
||||
var value = scanHexDigits(4, /*mustMatchCount*/ true);
|
||||
pos = start;
|
||||
return value;
|
||||
}
|
||||
@@ -922,7 +924,7 @@ module ts {
|
||||
case CharacterCodes._0:
|
||||
if (pos + 2 < len && (text.charCodeAt(pos + 1) === CharacterCodes.X || text.charCodeAt(pos + 1) === CharacterCodes.x)) {
|
||||
pos += 2;
|
||||
var value = scanHexDigits(1, /*useExactCount*/ false);
|
||||
var value = scanHexDigits(1, /*mustMatchCount*/ false);
|
||||
if (value < 0) {
|
||||
error(Diagnostics.Hexadecimal_digit_expected);
|
||||
value = 0;
|
||||
@@ -1112,7 +1114,7 @@ module ts {
|
||||
* Unconditionally back up and scan a template expression portion.
|
||||
*/
|
||||
function reScanTemplateToken(): SyntaxKind {
|
||||
Debug.assert("'reScanTemplateToken' should only be called on a '}'");
|
||||
Debug.assert(token === SyntaxKind.CloseBraceToken, "'reScanTemplateToken' should only be called on a '}'");
|
||||
pos = tokenPos;
|
||||
return token = scanTemplateAndSetTokenValue();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user