Skip to content

Commit 0a8d0a5

Browse files
committed
Merge branch 'master' into lsImportResolution
2 parents 7c2cc76 + 9c27fb1 commit 0a8d0a5

File tree

217 files changed

+2028
-653
lines changed

Some content is hidden

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

217 files changed

+2028
-653
lines changed

src/compiler/checker.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10295,11 +10295,12 @@ module ts {
1029510295

1029610296
case SyntaxKind.StringLiteral:
1029710297
// External module name in an import declaration
10298-
if (isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
10299-
getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) {
10300-
var importSymbol = getSymbolOfNode(node.parent.parent);
10301-
var moduleType = getTypeOfSymbol(importSymbol);
10302-
return moduleType ? moduleType.symbol : undefined;
10298+
var moduleName: Expression;
10299+
if ((isExternalModuleImportEqualsDeclaration(node.parent.parent) &&
10300+
getExternalModuleImportEqualsDeclarationExpression(node.parent.parent) === node) ||
10301+
((node.parent.kind === SyntaxKind.ImportDeclaration || node.parent.kind === SyntaxKind.ExportDeclaration) &&
10302+
(<ImportDeclaration>node.parent).moduleSpecifier === node)) {
10303+
return resolveExternalModuleName(node, <LiteralExpression>node);
1030310304
}
1030410305

1030510306
// 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/emitter.ts

Lines changed: 10 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -3088,71 +3088,21 @@ module ts {
30883088

30893089
write(tokenToString(node.operatorToken.kind));
30903090

3091-
// We'd like to preserve newlines found in the original binary expression. i.e. if a user has:
3092-
//
3093-
// Foo() ||
3094-
// Bar();
3095-
//
3096-
// Then we'd like to emit it as such. It seems like we'd only need to check for a newline and
3097-
// then just indent and emit. However, that will lead to a problem with deeply nested code.
3098-
// i.e. if you have:
3099-
//
3100-
// Foo() ||
3101-
// Bar() ||
3102-
// Baz();
3103-
//
3104-
// Then we don't want to emit it as:
3105-
//
3106-
// Foo() ||
3107-
// Bar() ||
3108-
// Baz();
3109-
//
3110-
// So we only indent if the right side of the binary expression starts further in on the line
3111-
// versus the left.
3112-
var operatorEnd = getLineAndCharacterOfPosition(currentSourceFile, node.operatorToken.end);
3113-
var rightStart = getLineAndCharacterOfPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.right.pos));
3114-
31153091
// Check if the right expression is on a different line versus the operator itself. If so,
31163092
// we'll emit newline.
3117-
var onDifferentLine = operatorEnd.line !== rightStart.line;
3118-
if (onDifferentLine) {
3119-
// Also, if the right expression starts further in on the line than the left, then we'll indent.
3120-
var exprStart = getLineAndCharacterOfPosition(currentSourceFile, skipTrivia(currentSourceFile.text, node.pos));
3121-
var firstCharOfExpr = getFirstNonWhitespaceCharacterIndexOnLine(exprStart.line);
3122-
var shouldIndent = rightStart.character > firstCharOfExpr;
3123-
3124-
if (shouldIndent) {
3125-
increaseIndent();
3126-
}
3127-
3093+
if (!nodeEndIsOnSameLineAsNodeStart(node.operatorToken, node.right)) {
3094+
increaseIndent();
31283095
writeLine();
3096+
emit(node.right);
3097+
decreaseIndent();
31293098
}
31303099
else {
31313100
write(" ");
3132-
}
3133-
3134-
emit(node.right);
3135-
3136-
if (shouldIndent) {
3137-
decreaseIndent();
3101+
emit(node.right);
31383102
}
31393103
}
31403104
}
31413105

3142-
function getFirstNonWhitespaceCharacterIndexOnLine(line: number): number {
3143-
var lineStart = getLineStarts(currentSourceFile)[line];
3144-
var text = currentSourceFile.text;
3145-
3146-
for (var i = lineStart; i < text.length; i++) {
3147-
var ch = text.charCodeAt(i);
3148-
if (!isWhiteSpace(text.charCodeAt(i)) || isLineBreak(ch)) {
3149-
break;
3150-
}
3151-
}
3152-
3153-
return i - lineStart;
3154-
}
3155-
31563106
function emitConditionalExpression(node: ConditionalExpression) {
31573107
emit(node.condition);
31583108
write(" ? ");
@@ -3992,58 +3942,21 @@ module ts {
39923942
}
39933943

39943944
function emitBlockFunctionBody(node: FunctionLikeDeclaration, body: Block) {
3995-
// If the body has no statements, and we know there's no code that would cause any
3996-
// prologue to be emitted, then just do a simple emit if the empty block.
3997-
if (body.statements.length === 0 && !anyParameterHasBindingPatternOrInitializer(node)) {
3998-
emitFunctionBodyWithNoStatements(node, body);
3999-
}
4000-
else {
4001-
emitFunctionBodyWithStatements(node, body);
4002-
}
4003-
}
4004-
4005-
function anyParameterHasBindingPatternOrInitializer(func: FunctionLikeDeclaration) {
4006-
return forEach(func.parameters, hasBindingPatternOrInitializer);
4007-
}
4008-
4009-
function hasBindingPatternOrInitializer(parameter: ParameterDeclaration) {
4010-
return parameter.initializer || isBindingPattern(parameter.name);
4011-
}
4012-
4013-
function emitFunctionBodyWithNoStatements(node: FunctionLikeDeclaration, body: Block) {
4014-
var singleLine = isSingleLineEmptyBlock(node.body);
4015-
4016-
write(" {");
4017-
if (singleLine) {
4018-
write(" ");
4019-
}
4020-
else {
4021-
increaseIndent();
4022-
writeLine();
4023-
}
4024-
4025-
emitLeadingCommentsOfPosition(body.statements.end);
4026-
4027-
if (!singleLine) {
4028-
decreaseIndent();
4029-
}
4030-
4031-
emitToken(SyntaxKind.CloseBraceToken, body.statements.end);
4032-
}
4033-
4034-
function emitFunctionBodyWithStatements(node: FunctionLikeDeclaration, body: Block) {
40353945
write(" {");
40363946
scopeEmitStart(node);
40373947

4038-
var outPos = writer.getTextPos();
3948+
var initialTextPos = writer.getTextPos();
40393949

40403950
increaseIndent();
40413951
emitDetachedComments(body.statements);
3952+
3953+
// Emit all the directive prologues (like "use strict"). These have to come before
3954+
// any other preamble code we write (like parameter initializers).
40423955
var startIndex = emitDirectivePrologues(body.statements, /*startWithNewLine*/ true);
40433956
emitFunctionBodyPreamble(node);
40443957
decreaseIndent();
40453958

4046-
var preambleEmitted = writer.getTextPos() !== outPos;
3959+
var preambleEmitted = writer.getTextPos() !== initialTextPos;
40473960

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

src/compiler/program.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,10 +177,15 @@ module ts {
177177
return { diagnostics: [], sourceMaps: undefined, emitSkipped: true };
178178
}
179179

180+
// Create the emit resolver outside of the "emitTime" tracking code below. That way
181+
// any cost associated with it (like type checking) are appropriate associated with
182+
// the type-checking counter.
183+
var emitResolver = getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile);
184+
180185
var start = new Date().getTime();
181186

182187
var emitResult = emitFiles(
183-
getDiagnosticsProducingTypeChecker().getEmitResolver(sourceFile),
188+
emitResolver,
184189
getEmitHost(writeFileCallback),
185190
sourceFile);
186191

src/compiler/types.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ module ts {
121121
WithKeyword,
122122
// Strict mode reserved words
123123
AsKeyword,
124-
FromKeyword,
125124
ImplementsKeyword,
126125
InterfaceKeyword,
127126
LetKeyword,
@@ -131,7 +130,7 @@ module ts {
131130
PublicKeyword,
132131
StaticKeyword,
133132
YieldKeyword,
134-
// TypeScript keywords
133+
// Contextual keywords
135134
AnyKeyword,
136135
BooleanKeyword,
137136
ConstructorKeyword,
@@ -144,7 +143,9 @@ module ts {
144143
StringKeyword,
145144
SymbolKeyword,
146145
TypeKeyword,
146+
FromKeyword,
147147
OfKeyword, // LastKeyword and LastToken
148+
148149
// Parse tree nodes
149150

150151
// Names
@@ -279,7 +280,7 @@ module ts {
279280
FirstPunctuation = OpenBraceToken,
280281
LastPunctuation = CaretEqualsToken,
281282
FirstToken = Unknown,
282-
LastToken = OfKeyword,
283+
LastToken = LastKeyword,
283284
FirstTriviaToken = SingleLineCommentTrivia,
284285
LastTriviaToken = ConflictMarkerTrivia,
285286
FirstLiteralToken = NumericLiteral,

src/compiler/utilities.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,6 +745,12 @@ module ts {
745745
}
746746

747747
var parent = name.parent;
748+
if (parent.kind === SyntaxKind.ImportSpecifier || parent.kind === SyntaxKind.ExportSpecifier) {
749+
if ((<ImportOrExportSpecifier>parent).propertyName) {
750+
return true;
751+
}
752+
}
753+
748754
if (isDeclaration(parent) || parent.kind === SyntaxKind.FunctionExpression) {
749755
return (<Declaration>parent).name === name;
750756
}

src/server/editorServices.ts

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -101,13 +101,7 @@ module ts.server {
101101
}
102102

103103
getScriptFileNames() {
104-
var filenames: string[] = [];
105-
for (var filename in this.filenameToScript) {
106-
if (this.filenameToScript[filename] && this.filenameToScript[filename].isOpen) {
107-
filenames.push(filename);
108-
}
109-
}
110-
return filenames;
104+
return this.roots.map(root => root.fileName);
111105
}
112106

113107
getScriptVersion(filename: string) {
@@ -536,15 +530,35 @@ module ts.server {
536530
updateProjectStructure() {
537531
this.log("updating project structure from ...", "Info");
538532
this.printProjects();
533+
534+
// First loop through all open files that are referenced by projects but are not
535+
// project roots. For each referenced file, see if the default project still
536+
// references that file. If so, then just keep the file in the referenced list.
537+
// If not, add the file to an unattached list, to be rechecked later.
538+
539+
var openFilesReferenced: ScriptInfo[] = [];
540+
var unattachedOpenFiles: ScriptInfo[] = [];
541+
539542
for (var i = 0, len = this.openFilesReferenced.length; i < len; i++) {
540-
var refdFile = this.openFilesReferenced[i];
541-
refdFile.defaultProject.updateGraph();
542-
var sourceFile = refdFile.defaultProject.getSourceFile(refdFile);
543-
if (!sourceFile) {
544-
this.openFilesReferenced = copyListRemovingItem(refdFile, this.openFilesReferenced);
545-
this.addOpenFile(refdFile);
543+
var referencedFile = this.openFilesReferenced[i];
544+
referencedFile.defaultProject.updateGraph();
545+
var sourceFile = referencedFile.defaultProject.getSourceFile(referencedFile);
546+
if (sourceFile) {
547+
openFilesReferenced.push(referencedFile);
548+
}
549+
else {
550+
unattachedOpenFiles.push(referencedFile);
546551
}
547552
}
553+
this.openFilesReferenced = openFilesReferenced;
554+
555+
// Then, loop through all of the open files that are project roots.
556+
// For each root file, note the project that it roots. Then see if
557+
// any other projects newly reference the file. If zero projects
558+
// newly reference the file, keep it as a root. If one or more
559+
// projects newly references the file, remove its project from the
560+
// inferred projects list (since it is no longer a root) and add
561+
// the file to the open, referenced file list.
548562
var openFileRoots: ScriptInfo[] = [];
549563
for (var i = 0, len = this.openFileRoots.length; i < len; i++) {
550564
var rootFile = this.openFileRoots[i];
@@ -555,12 +569,19 @@ module ts.server {
555569
openFileRoots.push(rootFile);
556570
}
557571
else {
558-
// remove project from inferred projects list
572+
// remove project from inferred projects list because root captured
559573
this.inferredProjects = copyListRemovingItem(rootedProject, this.inferredProjects);
560574
this.openFilesReferenced.push(rootFile);
561575
}
562576
}
563577
this.openFileRoots = openFileRoots;
578+
579+
// Finally, if we found any open, referenced files that are no longer
580+
// referenced by their default project, treat them as newly opened
581+
// by the editor.
582+
for (var i = 0, len = unattachedOpenFiles.length; i < len; i++) {
583+
this.addOpenFile(unattachedOpenFiles[i]);
584+
}
564585
this.printProjects();
565586
}
566587

src/server/server.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,10 @@ module ts.server {
206206
}
207207

208208
};
209-
209+
var ioSession = new IOSession(ts.sys, logger);
210+
process.on('uncaughtException', function(err: Error) {
211+
ioSession.logError(err, "unknown");
212+
});
210213
// Start listening
211-
new IOSession(ts.sys, logger).listen();
214+
ioSession.listen();
212215
}

src/server/session.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -181,18 +181,29 @@ module ts.server {
181181
}
182182

183183
semanticCheck(file: string, project: Project) {
184-
var diags = project.compilerService.languageService.getSemanticDiagnostics(file);
185-
if (diags) {
186-
var bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
187-
this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag");
184+
try {
185+
var diags = project.compilerService.languageService.getSemanticDiagnostics(file);
186+
187+
if (diags) {
188+
var bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
189+
this.event({ file: file, diagnostics: bakedDiags }, "semanticDiag");
190+
}
191+
}
192+
catch (err) {
193+
this.logError(err, "semantic check");
188194
}
189195
}
190196

191197
syntacticCheck(file: string, project: Project) {
192-
var diags = project.compilerService.languageService.getSyntacticDiagnostics(file);
193-
if (diags) {
194-
var bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
195-
this.event({ file: file, diagnostics: bakedDiags }, "syntaxDiag");
198+
try {
199+
var diags = project.compilerService.languageService.getSyntacticDiagnostics(file);
200+
if (diags) {
201+
var bakedDiags = diags.map((diag) => formatDiag(file, project, diag));
202+
this.event({ file: file, diagnostics: bakedDiags }, "syntaxDiag");
203+
}
204+
}
205+
catch (err) {
206+
this.logError(err, "syntactic check");
196207
}
197208
}
198209

@@ -553,10 +564,7 @@ module ts.server {
553564
compilerService.host.editScript(file, start, end, insertString);
554565
this.changeSeq++;
555566
}
556-
// update project structure on idle commented out
557-
// until we can have the host return only the root files
558-
// from getScriptFileNames()
559-
//this.updateProjectStructure(this.changeSeq, (n) => n == this.changeSeq);
567+
this.updateProjectStructure(this.changeSeq, (n) => n == this.changeSeq);
560568
}
561569
}
562570

0 commit comments

Comments
 (0)