Skip to content

Commit 29c5b40

Browse files
committed
Merge branch 'master' into objectLiteralCompletion
2 parents 2e9a20f + e5b6bfb commit 29c5b40

18 files changed

+279
-66
lines changed

Jakefile

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ var servicesSources = [
5858
"shims.ts",
5959
"signatureHelp.ts",
6060
"utilities.ts",
61-
"navigationBar.ts"
61+
"navigationBar.ts",
62+
"outliningElementsCollector.ts"
6263
].map(function (f) {
6364
return path.join(servicesDirectory, f);
6465
}));
@@ -127,6 +128,7 @@ function concatenateFiles(destinationFile, sourceFiles) {
127128
}
128129

129130
var useDebugMode = false;
131+
var generateDeclarations = false;
130132
var host = (process.env.host || process.env.TYPESCRIPT_HOST || "node");
131133
var compilerFilename = "tsc.js";
132134
/* Compiles a file from a list of sources
@@ -141,6 +143,9 @@ function compileFile(outFile, sources, prereqs, prefixes, useBuiltCompiler, noOu
141143
file(outFile, prereqs, function() {
142144
var dir = useBuiltCompiler ? builtLocalDirectory : LKGDirectory;
143145
var options = "-removeComments --module commonjs -noImplicitAny "; //" -propagateEnumConstants "
146+
if (generateDeclarations) {
147+
options += "--declaration ";
148+
}
144149

145150
var cmd = host + " " + dir + compilerFilename + " " + options + " ";
146151
if (useDebugMode) {
@@ -249,7 +254,7 @@ task("local", ["generate-diagnostics", "lib", tscFile, servicesFile]);
249254
// Local target to build the compiler and services
250255
desc("Emit debug mode files with sourcemaps");
251256
task("debug", function() {
252-
useDebugMode = true;
257+
useDebugMode = true;
253258
});
254259

255260

@@ -263,6 +268,12 @@ task("clean", function() {
263268
jake.rmRf(builtDirectory);
264269
});
265270

271+
// generate declarations for compiler and services
272+
desc("Generate declarations for compiler and services");
273+
task("declaration", function() {
274+
generateDeclarations = true;
275+
});
276+
266277
// Generate Markdown spec
267278
var word2mdJs = path.join(scriptsDirectory, "word2md.js");
268279
var word2mdTs = path.join(scriptsDirectory, "word2md.ts");
@@ -282,12 +293,12 @@ compileFile(word2mdJs,
282293
// The generated spec.md; built for the 'generate-spec' task
283294
file(specMd, [word2mdJs, specWord], function () {
284295
jake.cpR(headerMd, specMd, {silent: true});
285-
var specWordFullPath = path.resolve(specWord);
296+
var specWordFullPath = path.resolve(specWord);
286297
var cmd = "cscript //nologo " + word2mdJs + ' "' + specWordFullPath + '" >>' + specMd;
287-
console.log(cmd);
288-
child_process.exec(cmd, function () {
289-
complete();
290-
});
298+
console.log(cmd);
299+
child_process.exec(cmd, function () {
300+
complete();
301+
});
291302
}, {async: true})
292303

293304

src/compiler/emitter.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3231,21 +3231,27 @@ module ts {
32313231
}
32323232

32333233
if (targetSourceFile === undefined) {
3234+
// No targetSourceFile is specified (e.g. calling emitter from batch compiler)
32343235
forEach(program.getSourceFiles(), sourceFile => {
32353236
if (shouldEmitToOwnFile(sourceFile, compilerOptions)) {
32363237
var jsFilePath = getOwnEmitOutputFilePath(sourceFile, ".js");
32373238
emitFile(jsFilePath, sourceFile);
32383239
}
32393240
});
3240-
}
3241-
else {
3242-
// Emit only one file specified in targetFilename. This is mainly used in compilerOnSave feature
3243-
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, ".js");
3244-
emitFile(jsFilePath, targetSourceFile);
3245-
}
32463241

3247-
if (compilerOptions.out) {
3248-
emitFile(compilerOptions.out);
3242+
if (compilerOptions.out) {
3243+
emitFile(compilerOptions.out);
3244+
}
3245+
} else {
3246+
// targetSourceFile is specified (e.g calling emitter from language service)
3247+
if (shouldEmitToOwnFile(targetSourceFile, compilerOptions)) {
3248+
// If shouldEmitToOwnFile is true or targetSourceFile is an external module file, then emit targetSourceFile in its own output file
3249+
var jsFilePath = getOwnEmitOutputFilePath(targetSourceFile, ".js");
3250+
emitFile(jsFilePath, targetSourceFile);
3251+
} else {
3252+
// If shouldEmitToOwnFile is false, then emit all, non-external-module file, into one single output file
3253+
emitFile(compilerOptions.out);
3254+
}
32493255
}
32503256

32513257
// Sort and make the unique list of diagnostics

src/compiler/parser.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2397,9 +2397,6 @@ module ts {
23972397
else {
23982398
parseExpected(SyntaxKind.OpenParenToken);
23992399
}
2400-
// It is an error to have a trailing comma in an argument list. However, the checker
2401-
// needs evidence of a trailing comma in order to give good results for signature help.
2402-
// That is why we do not allow a trailing comma, but we "preserve" a trailing comma.
24032400
callExpr.arguments = parseDelimitedList(ParsingContext.ArgumentExpressions,
24042401
parseArgumentExpression, /*allowTrailingComma*/ false);
24052402
parseExpected(SyntaxKind.CloseParenToken);
@@ -2627,9 +2624,6 @@ module ts {
26272624
parseExpected(SyntaxKind.NewKeyword);
26282625
node.func = parseCallAndAccess(parsePrimaryExpression(), /* inNewExpression */ true);
26292626
if (parseOptional(SyntaxKind.OpenParenToken) || token === SyntaxKind.LessThanToken && (node.typeArguments = tryParse(parseTypeArgumentsAndOpenParen))) {
2630-
// It is an error to have a trailing comma in an argument list. However, the checker
2631-
// needs evidence of a trailing comma in order to give good results for signature help.
2632-
// That is why we do not allow a trailing comma, but we "preserve" a trailing comma.
26332627
node.arguments = parseDelimitedList(ParsingContext.ArgumentExpressions,
26342628
parseArgumentExpression, /*allowTrailingComma*/ false);
26352629
parseExpected(SyntaxKind.CloseParenToken);

src/services/navigationBar.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ module ts.NavigationBar {
148148
var item = createItem(child);
149149
if (item !== undefined) {
150150
if (item.text.length > 0) {
151-
var key = item.text + "-" + item.kind;
151+
var key = item.text + "-" + item.kind + "-" + item.indent;
152152

153153
var itemWithSameName = keyToItem[key];
154154
if (itemWithSameName) {

src/services/outliningElementsCollector.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ module ts {
3333
export module OutliningElementsCollector {
3434
export function collectElements(sourceFile: SourceFile): OutliningSpan[] {
3535
var elements: OutliningSpan[] = [];
36+
var collapseText = "...";
3637

3738
function addOutliningSpan(hintSpanNode: Node, startElement: Node, endElement: Node, autoCollapse: boolean) {
3839
if (hintSpanNode && startElement && endElement) {
3940
var span: OutliningSpan = {
4041
textSpan: TypeScript.TextSpan.fromBounds(startElement.pos, endElement.end),
4142
hintSpan: TypeScript.TextSpan.fromBounds(hintSpanNode.getStart(), hintSpanNode.end),
42-
bannerText: "...",
43+
bannerText: collapseText,
4344
autoCollapse: autoCollapse
4445
};
4546
elements.push(span);
@@ -66,10 +67,39 @@ module ts {
6667
}
6768
switch (n.kind) {
6869
case SyntaxKind.Block:
70+
var parent = n.parent;
71+
var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);
72+
var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile);
73+
74+
// Check if the block is standalone, or 'attached' to some parent statement.
75+
// If the latter, we want to collaps the block, but consider its hint span
76+
// to be the entire span of the parent.
77+
if (parent.kind === SyntaxKind.DoStatement ||
78+
parent.kind === SyntaxKind.ForInStatement ||
79+
parent.kind === SyntaxKind.ForStatement ||
80+
parent.kind === SyntaxKind.IfStatement ||
81+
parent.kind === SyntaxKind.WhileStatement ||
82+
parent.kind === SyntaxKind.WithStatement) {
83+
84+
addOutliningSpan(parent, openBrace, closeBrace, autoCollapse(n));
85+
}
86+
else {
87+
// Block was a standalone block. In this case we want to only collapse
88+
// the span of the block, independent of any parent span.
89+
var span = TypeScript.TextSpan.fromBounds(n.getStart(), n.end);
90+
elements.push({
91+
textSpan: span,
92+
hintSpan: span,
93+
bannerText: collapseText,
94+
autoCollapse: autoCollapse(n)
95+
});
96+
}
97+
break;
98+
99+
69100
case SyntaxKind.FunctionBlock:
70101
case SyntaxKind.ModuleBlock:
71102
case SyntaxKind.TryBlock:
72-
case SyntaxKind.TryBlock:
73103
case SyntaxKind.CatchBlock:
74104
case SyntaxKind.FinallyBlock:
75105
var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile);

src/services/services.ts

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -504,47 +504,65 @@ module ts {
504504
if (!this.namedDeclarations) {
505505
var sourceFile = this;
506506
var namedDeclarations: Declaration[] = [];
507-
var isExternalModule = ts.isExternalModule(sourceFile);
508507

509-
forEachChild(sourceFile, function visit(node: Node): boolean {
508+
forEachChild(sourceFile, function visit(node: Node): void {
510509
switch (node.kind) {
510+
case SyntaxKind.FunctionDeclaration:
511+
case SyntaxKind.Method:
512+
var functionDeclaration = <FunctionDeclaration>node;
513+
514+
if (functionDeclaration.name && functionDeclaration.name.kind !== SyntaxKind.Missing) {
515+
var lastDeclaration = namedDeclarations.length > 0 ?
516+
namedDeclarations[namedDeclarations.length - 1] :
517+
undefined;
518+
519+
// Check whether this declaration belongs to an "overload group".
520+
if (lastDeclaration && functionDeclaration.symbol === lastDeclaration.symbol) {
521+
// Overwrite the last declaration if it was an overload
522+
// and this one is an implementation.
523+
if (functionDeclaration.body && !(<FunctionDeclaration>lastDeclaration).body) {
524+
namedDeclarations[namedDeclarations.length - 1] = functionDeclaration;
525+
}
526+
}
527+
else {
528+
namedDeclarations.push(node);
529+
}
530+
531+
forEachChild(node, visit);
532+
}
533+
break;
534+
511535
case SyntaxKind.ClassDeclaration:
512536
case SyntaxKind.InterfaceDeclaration:
513537
case SyntaxKind.EnumDeclaration:
514538
case SyntaxKind.ModuleDeclaration:
515539
case SyntaxKind.ImportDeclaration:
516-
case SyntaxKind.Method:
517-
case SyntaxKind.FunctionDeclaration:
518-
case SyntaxKind.Constructor:
519540
case SyntaxKind.GetAccessor:
520541
case SyntaxKind.SetAccessor:
521542
case SyntaxKind.TypeLiteral:
522543
if ((<Declaration>node).name) {
523544
namedDeclarations.push(<Declaration>node);
524545
}
525-
forEachChild(node, visit);
526-
break;
527-
546+
// fall through
547+
case SyntaxKind.Constructor:
528548
case SyntaxKind.VariableStatement:
529549
case SyntaxKind.ModuleBlock:
530550
case SyntaxKind.FunctionBlock:
531551
forEachChild(node, visit);
532552
break;
533553

534554
case SyntaxKind.Parameter:
555+
// Only consider properties defined as constructor parameters
535556
if (!(node.flags & NodeFlags.AccessibilityModifier)) {
536-
// Only consider properties defined as constructor parameters
537557
break;
538558
}
559+
// fall through
539560
case SyntaxKind.VariableDeclaration:
540561
case SyntaxKind.EnumMember:
541562
case SyntaxKind.Property:
542563
namedDeclarations.push(<Declaration>node);
543564
break;
544565
}
545-
546-
// do not go any deeper
547-
return undefined;
548566
});
549567

550568
this.namedDeclarations = namedDeclarations;
@@ -3889,7 +3907,8 @@ module ts {
38893907
filename = TypeScript.switchToForwardSlashes(filename);
38903908
var compilerOptions = program.getCompilerOptions();
38913909
var targetSourceFile = program.getSourceFile(filename); // Current selected file to be output
3892-
var emitToSingleFile = ts.shouldEmitToOwnFile(targetSourceFile, compilerOptions);
3910+
// If --out flag is not specified, shouldEmitToOwnFile is true. Otherwise shouldEmitToOwnFile is false.
3911+
var shouldEmitToOwnFile = ts.shouldEmitToOwnFile(targetSourceFile, compilerOptions);
38933912
var emitDeclaration = compilerOptions.declaration;
38943913
var emitOutput: EmitOutput = {
38953914
outputFiles: [],
@@ -3910,7 +3929,7 @@ module ts {
39103929
var syntacticDiagnostics: Diagnostic[] = [];
39113930
var containSyntacticErrors = false;
39123931

3913-
if (emitToSingleFile) {
3932+
if (shouldEmitToOwnFile) {
39143933
// Check only the file we want to emit
39153934
containSyntacticErrors = containErrors(program.getDiagnostics(targetSourceFile));
39163935
} else {
@@ -3937,7 +3956,7 @@ module ts {
39373956
// Perform semantic and force a type check before emit to ensure that all symbols are updated
39383957
// EmitFiles will report if there is an error from TypeChecker and Emitter
39393958
// Depend whether we will have to emit into a single file or not either emit only selected file in the project, emit all files into a single file
3940-
var emitFilesResult = emitToSingleFile ? getFullTypeCheckChecker().emitFiles(targetSourceFile) : getFullTypeCheckChecker().emitFiles();
3959+
var emitFilesResult = getFullTypeCheckChecker().emitFiles(targetSourceFile);
39413960
emitOutput.emitOutputStatus = emitFilesResult.emitResultStatus;
39423961

39433962
// Reset writer back to undefined to make sure that we produce an error message if CompilerHost.writeFile method is called when we are not in getEmitOutput

src/services/shims.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ module ts {
174174
}
175175

176176
/// TODO: delete this, it is only needed until the VS interface is updated
177-
enum LanguageVersion {
177+
export enum LanguageVersion {
178178
EcmaScript3 = 0,
179179
EcmaScript5 = 1,
180180
}
@@ -502,7 +502,8 @@ module ts {
502502
start: diagnostic.start,
503503
length: diagnostic.length,
504504
/// TODO: no need for the tolowerCase call
505-
category: DiagnosticCategory[diagnostic.category].toLowerCase()
505+
category: DiagnosticCategory[diagnostic.category].toLowerCase(),
506+
code: diagnostic.code
506507
};
507508
}
508509

src/services/signatureHelp.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,12 @@ module ts.SignatureHelp {
241241
return undefined;
242242
}
243243

244+
// If the node is not a subspan of its parent, this is a big problem.
245+
// There have been crashes that might be caused by this violation.
246+
if (n.pos < n.parent.pos || n.end > n.parent.end) {
247+
Debug.fail("Node of kind " + SyntaxKind[n.kind] + " is not a subspan of its parent of kind " + SyntaxKind[n.parent.kind]);
248+
}
249+
244250
var argumentInfo = getImmediatelyContainingArgumentInfo(n);
245251
if (argumentInfo) {
246252
return argumentInfo;

src/services/utilities.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,18 @@ module ts {
2727
// for the position of the relevant node (or comma).
2828
var syntaxList = forEach(node.parent.getChildren(), c => {
2929
// find syntax list that covers the span of the node
30-
if (c.kind == SyntaxKind.SyntaxList && c.pos <= node.pos && c.end >= node.end) {
30+
if (c.kind === SyntaxKind.SyntaxList && c.pos <= node.pos && c.end >= node.end) {
3131
return c;
3232
}
3333
});
3434

35+
// syntaxList should not be undefined here. If it is, there is a problem. Find out if
36+
// there at least is a child that is a list.
37+
if (!syntaxList) {
38+
Debug.assert(findChildOfKind(node.parent, SyntaxKind.SyntaxList),
39+
"Node of kind " + SyntaxKind[node.parent.kind] + " has no list children");
40+
}
41+
3542
return syntaxList;
3643
}
3744

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
EmitOutputStatus : Succeeded
2+
Filename : declSingleFile.js
3+
var x = 5;
4+
var Bar = (function () {
5+
function Bar() {
6+
}
7+
return Bar;
8+
})();
9+

0 commit comments

Comments
 (0)