Skip to content

Commit 7be2e50

Browse files
committed
merge with master
2 parents 4bf0bb6 + 21fb559 commit 7be2e50

File tree

259 files changed

+2658
-1092
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

259 files changed

+2658
-1092
lines changed

scripts/VSDevMode.ps1

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,38 @@ if(!(Test-Path $tsRegKey)){
3737
}
3838

3939
if($tsScript -ne ""){
40-
if(!(Test-Path $tsScript)){
41-
Throw "Could not locate the TypeScript language service script at ${tsScript}"
40+
$tsScriptServices = "${tsScript}\typescriptServices.js"
41+
$tsScriptlib = "${tsScript}\lib.d.ts"
42+
$tsES6Scriptlib = "${tsScript}\lib.es6.d.ts"
43+
44+
if(!(Test-Path $tsScriptServices)){
45+
Throw "Could not locate the TypeScript language service script at ${tsScriptServices}"
46+
}
47+
else {
48+
$path = resolve-path ${tsScriptServices}
49+
Set-ItemProperty -path $tsRegKey -name CustomTypeScriptServicesFileLocation -value "${path}"
50+
Write-Host "Enabled custom TypeScript language service at ${path} for Dev${vsVersion}"
51+
}
52+
53+
if(!(Test-Path $tsScriptlib)){
54+
Throw "Could not locate the TypeScript default library at ${tsScriptlib}"
55+
}
56+
else {
57+
$path = resolve-path ${tsScriptlib}
58+
Set-ItemProperty -path $tsRegKey -name CustomDefaultLibraryLocation -value "${path}"
59+
Write-Host "Enabled custom TypeScript default library at ${path} for Dev${vsVersion}"
60+
}
61+
62+
if(!(Test-Path $tsES6Scriptlib)){
63+
Throw "Could not locate the TypeScript default ES6 library at ${tsES6Scriptlib}"
64+
}
65+
else {
66+
$path = resolve-path ${tsES6Scriptlib}
67+
Set-ItemProperty -path $tsRegKey -name CustomDefaultES6LibraryLocation -value "${path}"
68+
Write-Host "Enabled custom TypeScript default ES6 library at ${path} for Dev${vsVersion}"
4269
}
43-
Set-ItemProperty -path $tsRegKey -name CustomTypeScriptServicesFileLocation -value "${tsScript}"
44-
Write-Host "Enabled custom TypeScript language service at ${tsScript} for Dev${vsVersion}"
4570
}
71+
4672
if($enableDevMode){
4773
Set-ItemProperty -path $tsRegKey -name EnableDevMode -value 1
4874
Write-Host "Enabled developer mode for Dev${vsVersion}"

src/compiler/binder.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ module ts {
389389

390390
function bind(node: Node) {
391391
node.parent = parent;
392+
392393
switch (node.kind) {
393394
case SyntaxKind.TypeParameter:
394395
bindDeclaration(<Declaration>node, SymbolFlags.TypeParameter, SymbolFlags.TypeParameterExcludes, /*isBlockScopeContainer*/ false);

src/compiler/checker.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6806,11 +6806,6 @@ module ts {
68066806
}
68076807

68086808
function checkTaggedTemplateExpression(node: TaggedTemplateExpression): Type {
6809-
// Grammar checking
6810-
if (languageVersion < ScriptTarget.ES6) {
6811-
grammarErrorOnFirstToken(node.template, Diagnostics.Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher);
6812-
}
6813-
68146809
return getReturnTypeOfSignature(getResolvedSignature(node));
68156810
}
68166811

@@ -10339,11 +10334,12 @@ module ts {
1033910334

1034010335
case SyntaxKind.StringLiteral:
1034110336
// External module name in an import declaration
10342-
if (isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
10343-
getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) {
10344-
var importSymbol = getSymbolOfNode(node.parent.parent);
10345-
var moduleType = getTypeOfSymbol(importSymbol);
10346-
return moduleType ? moduleType.symbol : undefined;
10337+
var moduleName: Expression;
10338+
if ((isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
10339+
getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) ||
10340+
((node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration) &&
10341+
(<ImportDeclaration>node.parent).moduleSpecifier === node)) {
10342+
return resolveExternalModuleName(node, <LiteralExpression>node);
1034710343
}
1034810344

1034910345
// Intentional fall-through

src/compiler/core.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,7 @@ module ts {
607607
}
608608

609609
var backslashOrDoubleQuote = /[\"\\]/g;
610-
var escapedCharsRegExp = /[\0-\19\t\v\f\b\0\r\n\u2028\u2029\u0085]/g;
610+
var escapedCharsRegExp = /[\u0000-\u001f\t\v\f\b\r\n\u2028\u2029\u0085]/g;
611611
var escapedCharsMap: Map<string> = {
612612
"\0": "\\0",
613613
"\t": "\\t",
@@ -624,7 +624,7 @@ module ts {
624624
};
625625

626626
/**
627-
* Based heavily on the abstract 'Quote' operation from ECMA-262 (24.3.2.2),
627+
* Based heavily on the abstract 'Quote'/ 'QuoteJSONString' operation from ECMA-262 (24.3.2.2),
628628
* but augmented for a few select characters.
629629
* Note that this doesn't actually wrap the input in double quotes.
630630
*/

src/compiler/diagnosticInformationMap.generated.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,6 @@ module ts {
117117
const_declarations_must_be_initialized: { code: 1155, category: DiagnosticCategory.Error, key: "'const' declarations must be initialized" },
118118
const_declarations_can_only_be_declared_inside_a_block: { code: 1156, category: DiagnosticCategory.Error, key: "'const' declarations can only be declared inside a block." },
119119
let_declarations_can_only_be_declared_inside_a_block: { code: 1157, category: DiagnosticCategory.Error, key: "'let' declarations can only be declared inside a block." },
120-
Tagged_templates_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1159, category: DiagnosticCategory.Error, key: "Tagged templates are only available when targeting ECMAScript 6 and higher." },
121120
Unterminated_template_literal: { code: 1160, category: DiagnosticCategory.Error, key: "Unterminated template literal." },
122121
Unterminated_regular_expression_literal: { code: 1161, category: DiagnosticCategory.Error, key: "Unterminated regular expression literal." },
123122
An_object_member_cannot_be_declared_optional: { code: 1162, category: DiagnosticCategory.Error, key: "An object member cannot be declared optional." },

src/compiler/diagnosticMessages.json

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -459,10 +459,6 @@
459459
"category": "Error",
460460
"code": 1157
461461
},
462-
"Tagged templates are only available when targeting ECMAScript 6 and higher.": {
463-
"category": "Error",
464-
"code": 1159
465-
},
466462
"Unterminated template literal.": {
467463
"category": "Error",
468464
"code": 1160

src/compiler/emitter.ts

Lines changed: 90 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -2161,7 +2161,7 @@ module ts {
21612161
}
21622162
}
21632163

2164-
function emitParenthesized(node: Node, parenthesized: boolean) {
2164+
function emitParenthesizedIf(node: Node, parenthesized: boolean) {
21652165
if (parenthesized) {
21662166
write("(");
21672167
}
@@ -2294,6 +2294,72 @@ module ts {
22942294
function getTemplateLiteralAsStringLiteral(node: LiteralExpression): string {
22952295
return '"' + escapeString(node.text) + '"';
22962296
}
2297+
2298+
function emitDownlevelRawTemplateLiteral(node: LiteralExpression) {
2299+
// Find original source text, since we need to emit the raw strings of the tagged template.
2300+
// The raw strings contain the (escaped) strings of what the user wrote.
2301+
// Examples: `\n` is converted to "\\n", a template string with a newline to "\n".
2302+
var text = getSourceTextOfNodeFromSourceFile(currentSourceFile, node);
2303+
2304+
// text contains the original source, it will also contain quotes ("`"), dolar signs and braces ("${" and "}"),
2305+
// thus we need to remove those characters.
2306+
// First template piece starts with "`", others with "}"
2307+
// Last template piece ends with "`", others with "${"
2308+
var isLast = node.kind === SyntaxKind.NoSubstitutionTemplateLiteral || node.kind === SyntaxKind.TemplateTail;
2309+
text = text.substring(1, text.length - (isLast ? 1 : 2));
2310+
2311+
// Newline normalization:
2312+
// ES6 Spec 11.8.6.1 - Static Semantics of TV's and TRV's
2313+
// <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for both TV and TRV.
2314+
text = text.replace(/\r\n?/g, "\n");
2315+
text = escapeString(text);
2316+
2317+
write('"' + text + '"');
2318+
}
2319+
2320+
function emitDownlevelTaggedTemplateArray(node: TaggedTemplateExpression, literalEmitter: (literal: LiteralExpression) => void) {
2321+
write("[");
2322+
if (node.template.kind === SyntaxKind.NoSubstitutionTemplateLiteral) {
2323+
literalEmitter(<LiteralExpression>node.template);
2324+
}
2325+
else {
2326+
literalEmitter((<TemplateExpression>node.template).head);
2327+
forEach((<TemplateExpression>node.template).templateSpans, (child) => {
2328+
write(", ");
2329+
literalEmitter(child.literal);
2330+
});
2331+
}
2332+
write("]");
2333+
}
2334+
2335+
function emitDownlevelTaggedTemplate(node: TaggedTemplateExpression) {
2336+
var tempVariable = createAndRecordTempVariable(node);
2337+
write("(");
2338+
emit(tempVariable);
2339+
write(" = ");
2340+
emitDownlevelTaggedTemplateArray(node, emit);
2341+
write(", ");
2342+
2343+
emit(tempVariable);
2344+
write(".raw = ");
2345+
emitDownlevelTaggedTemplateArray(node, emitDownlevelRawTemplateLiteral);
2346+
write(", ");
2347+
2348+
emitParenthesizedIf(node.tag, needsParenthesisForPropertyAccessOrInvocation(node.tag));
2349+
write("(");
2350+
emit(tempVariable);
2351+
2352+
// Now we emit the expressions
2353+
if (node.template.kind === SyntaxKind.TemplateExpression) {
2354+
forEach((<TemplateExpression>node.template).templateSpans, templateSpan => {
2355+
write(", ");
2356+
var needsParens = templateSpan.expression.kind === SyntaxKind.BinaryExpression
2357+
&& (<BinaryExpression>templateSpan.expression).operatorToken.kind === SyntaxKind.CommaToken;
2358+
emitParenthesizedIf(templateSpan.expression, needsParens);
2359+
});
2360+
}
2361+
write("))");
2362+
}
22972363

22982364
function emitTemplateExpression(node: TemplateExpression): void {
22992365
// In ES6 mode and above, we can simply emit each portion of a template in order, but in
@@ -2338,7 +2404,8 @@ module ts {
23382404
write(" + ");
23392405
}
23402406

2341-
emitParenthesized(templateSpan.expression, needsParens);
2407+
emitParenthesizedIf(templateSpan.expression, needsParens);
2408+
23422409
// Only emit if the literal is non-empty.
23432410
// The binary '+' operator is left-associative, so the first string concatenation
23442411
// with the head will force the result up to this point to be a string.
@@ -2581,7 +2648,7 @@ module ts {
25812648
emit((<SpreadElementExpression>node).expression);
25822649
}
25832650

2584-
function needsParenthesisForPropertyAccess(node: Expression) {
2651+
function needsParenthesisForPropertyAccessOrInvocation(node: Expression) {
25852652
switch (node.kind) {
25862653
case SyntaxKind.Identifier:
25872654
case SyntaxKind.ArrayLiteralExpression:
@@ -2611,7 +2678,7 @@ module ts {
26112678
var e = elements[pos];
26122679
if (e.kind === SyntaxKind.SpreadElementExpression) {
26132680
e = (<SpreadElementExpression>e).expression;
2614-
emitParenthesized(e, /*parenthesized*/ group === 0 && needsParenthesisForPropertyAccess(e));
2681+
emitParenthesizedIf(e, /*parenthesized*/ group === 0 && needsParenthesisForPropertyAccessOrInvocation(e));
26152682
pos++;
26162683
}
26172684
else {
@@ -3079,9 +3146,14 @@ module ts {
30793146
}
30803147

30813148
function emitTaggedTemplateExpression(node: TaggedTemplateExpression): void {
3082-
emit(node.tag);
3083-
write(" ");
3084-
emit(node.template);
3149+
if (compilerOptions.target >= ScriptTarget.ES6) {
3150+
emit(node.tag);
3151+
write(" ");
3152+
emit(node.template);
3153+
}
3154+
else {
3155+
emitDownlevelTaggedTemplate(node);
3156+
}
30853157
}
30863158

30873159
function emitParenExpression(node: ParenthesizedExpression) {
@@ -3182,71 +3254,21 @@ module ts {
31823254

31833255
write(tokenToString(node.operatorToken.kind));
31843256

3185-
// We'd like to preserve newlines found in the original binary expression. i.e. if a user has:
3186-
//
3187-
// Foo() ||
3188-
// Bar();
3189-
//
3190-
// Then we'd like to emit it as such. It seems like we'd only need to check for a newline and
3191-
// then just indent and emit. However, that will lead to a problem with deeply nested code.
3192-
// i.e. if you have:
3193-
//
3194-
// Foo() ||
3195-
// Bar() ||
3196-
// Baz();
3197-
//
3198-
// Then we don't want to emit it as:
3199-
//
3200-
// Foo() ||
3201-
// Bar() ||
3202-
// Baz();
3203-
//
3204-
// So we only indent if the right side of the binary expression starts further in on the line
3205-
// versus the left.
3206-
var operatorEnd = getLineAndCharacterOfPosition(currentSourceFile, node.operatorToken.end);
3207-
var rightStart = getLineAndCharacterOfPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.right.pos));
3208-
32093257
// Check if the right expression is on a different line versus the operator itself. If so,
32103258
// we'll emit newline.
3211-
var onDifferentLine = operatorEnd.line !== rightStart.line;
3212-
if (onDifferentLine) {
3213-
// Also, if the right expression starts further in on the line than the left, then we'll indent.
3214-
var exprStart = getLineAndCharacterOfPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.pos));
3215-
var firstCharOfExpr = getFirstNonWhitespaceCharacterIndexOnLine(exprStart.line);
3216-
var shouldIndent = rightStart.character > firstCharOfExpr;
3217-
3218-
if (shouldIndent) {
3219-
increaseIndent();
3220-
}
3221-
3259+
if (!nodeEndIsOnSameLineAsNodeStart(node.operatorToken, node.right)) {
3260+
increaseIndent();
32223261
writeLine();
3262+
emit(node.right);
3263+
decreaseIndent();
32233264
}
32243265
else {
32253266
write(" ");
3226-
}
3227-
3228-
emit(node.right);
3229-
3230-
if (shouldIndent) {
3231-
decreaseIndent();
3267+
emit(node.right);
32323268
}
32333269
}
32343270
}
32353271

3236-
function getFirstNonWhitespaceCharacterIndexOnLine(line: number): number {
3237-
var lineStart = getLineStarts(currentSourceFile)[line];
3238-
var text = currentSourceFile.text;
3239-
3240-
for (var i = lineStart; i < text.length; i++) {
3241-
var ch = text.charCodeAt(i);
3242-
if (!isWhiteSpace(text.charCodeAt(i)) || isLineBreak(ch)) {
3243-
break;
3244-
}
3245-
}
3246-
3247-
return i - lineStart;
3248-
}
3249-
32503272
function emitConditionalExpression(node: ConditionalExpression) {
32513273
emit(node.condition);
32523274
write(" ? ");
@@ -3301,7 +3323,7 @@ module ts {
33013323
}
33023324

33033325
function emitExpressionStatement(node: ExpressionStatement) {
3304-
emitParenthesized(node.expression, /*parenthesized*/ node.expression.kind === SyntaxKind.ArrowFunction);
3326+
emitParenthesizedIf(node.expression, /*parenthesized*/ node.expression.kind === SyntaxKind.ArrowFunction);
33053327
write(";");
33063328
}
33073329

@@ -4196,58 +4218,21 @@ module ts {
41964218
}
41974219

41984220
function emitBlockFunctionBody(node: FunctionLikeDeclaration, body: Block) {
4199-
// If the body has no statements, and we know there's no code that would cause any
4200-
// prologue to be emitted, then just do a simple emit if the empty block.
4201-
if (body.statements.length === 0 && !anyParameterHasBindingPatternOrInitializer(node)) {
4202-
emitFunctionBodyWithNoStatements(node, body);
4203-
}
4204-
else {
4205-
emitFunctionBodyWithStatements(node, body);
4206-
}
4207-
}
4208-
4209-
function anyParameterHasBindingPatternOrInitializer(func: FunctionLikeDeclaration) {
4210-
return forEach(func.parameters, hasBindingPatternOrInitializer);
4211-
}
4212-
4213-
function hasBindingPatternOrInitializer(parameter: ParameterDeclaration) {
4214-
return parameter.initializer || isBindingPattern(parameter.name);
4215-
}
4216-
4217-
function emitFunctionBodyWithNoStatements(node: FunctionLikeDeclaration, body: Block) {
4218-
var singleLine = isSingleLineEmptyBlock(node.body);
4219-
4220-
write(" {");
4221-
if (singleLine) {
4222-
write(" ");
4223-
}
4224-
else {
4225-
increaseIndent();
4226-
writeLine();
4227-
}
4228-
4229-
emitLeadingCommentsOfPosition(body.statements.end);
4230-
4231-
if (!singleLine) {
4232-
decreaseIndent();
4233-
}
4234-
4235-
emitToken(SyntaxKind.CloseBraceToken, body.statements.end);
4236-
}
4237-
4238-
function emitFunctionBodyWithStatements(node: FunctionLikeDeclaration, body: Block) {
42394221
write(" {");
42404222
scopeEmitStart(node);
42414223

4242-
var outPos = writer.getTextPos();
4224+
var initialTextPos = writer.getTextPos();
42434225

42444226
increaseIndent();
42454227
emitDetachedComments(body.statements);
4228+
4229+
// Emit all the directive prologues (like "use strict"). These have to come before
4230+
// any other preamble code we write (like parameter initializers).
42464231
var startIndex = emitDirectivePrologues(body.statements, /*startWithNewLine*/ true);
42474232
emitFunctionBodyPreamble(node);
42484233
decreaseIndent();
42494234

4250-
var preambleEmitted = writer.getTextPos() !== outPos;
4235+
var preambleEmitted = writer.getTextPos() !== initialTextPos;
42514236

42524237
if (!preambleEmitted && nodeEndIsOnSameLineAsNodeStart(body, body)) {
42534238
for (var i = 0, n = body.statements.length; i < n; i++) {

0 commit comments

Comments
 (0)