Skip to content

Commit d07b845

Browse files
committed
Merge branch 'master' into cleanup
2 parents 1fe4a52 + c72e157 commit d07b845

File tree

93 files changed

+2181
-806
lines changed

Some content is hidden

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

93 files changed

+2181
-806
lines changed

Jakefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ var servicesSources = [
5454
}).concat([
5555
"services.ts",
5656
"shims.ts",
57+
"signatureHelp.ts",
58+
"utilities.ts"
5759
].map(function (f) {
5860
return path.join(servicesDirectory, f);
5961
}));

src/compiler/checker.ts

Lines changed: 122 additions & 71 deletions
Large diffs are not rendered by default.

src/compiler/core.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ module ts {
1111
var result: U;
1212
if (array) {
1313
for (var i = 0, len = array.length; i < len; i++) {
14-
if (result = callback(array[i])) break;
14+
if (result = callback(array[i])) {
15+
break;
16+
}
1517
}
1618
}
1719
return result;
@@ -39,6 +41,18 @@ module ts {
3941
return -1;
4042
}
4143

44+
export function countWhere<T>(array: T[], predicate: (x: T) => boolean): number {
45+
var count = 0;
46+
if (array) {
47+
for (var i = 0, len = array.length; i < len; i++) {
48+
if (predicate(array[i])) {
49+
count++;
50+
}
51+
}
52+
}
53+
return count;
54+
}
55+
4256
export function filter<T>(array: T[], f: (x: T) => boolean): T[] {
4357
if (array) {
4458
var result: T[] = [];

src/compiler/emitter.ts

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -748,23 +748,46 @@ module ts {
748748
}
749749
}
750750

751-
function emitCommaList(nodes: Node[], count?: number) {
752-
if (!(count >= 0)) count = nodes.length;
751+
function emitTrailingCommaIfPresent(nodeList: NodeArray<Node>, isMultiline: boolean): void {
752+
if (nodeList.hasTrailingComma) {
753+
write(",");
754+
if (isMultiline) {
755+
writeLine();
756+
}
757+
}
758+
}
759+
760+
function emitCommaList(nodes: NodeArray<Node>, includeTrailingComma: boolean, count?: number) {
761+
if (!(count >= 0)) {
762+
count = nodes.length;
763+
}
753764
if (nodes) {
754765
for (var i = 0; i < count; i++) {
755-
if (i) write(", ");
766+
if (i) {
767+
write(", ");
768+
}
756769
emit(nodes[i]);
757770
}
771+
772+
if (includeTrailingComma) {
773+
emitTrailingCommaIfPresent(nodes, /*isMultiline*/ false);
774+
}
758775
}
759776
}
760777

761-
function emitMultiLineList(nodes: Node[]) {
778+
function emitMultiLineList(nodes: NodeArray<Node>, includeTrailingComma: boolean) {
762779
if (nodes) {
763780
for (var i = 0; i < nodes.length; i++) {
764-
if (i) write(",");
781+
if (i) {
782+
write(",");
783+
}
765784
writeLine();
766785
emit(nodes[i]);
767786
}
787+
788+
if (includeTrailingComma) {
789+
emitTrailingCommaIfPresent(nodes, /*isMultiline*/ true);
790+
}
768791
}
769792
}
770793

@@ -876,14 +899,14 @@ module ts {
876899
if (node.flags & NodeFlags.MultiLine) {
877900
write("[");
878901
increaseIndent();
879-
emitMultiLineList(node.elements);
902+
emitMultiLineList(node.elements, /*includeTrailingComma*/ true);
880903
decreaseIndent();
881904
writeLine();
882905
write("]");
883906
}
884907
else {
885908
write("[");
886-
emitCommaList(node.elements);
909+
emitCommaList(node.elements, /*includeTrailingComma*/ true);
887910
write("]");
888911
}
889912
}
@@ -895,14 +918,14 @@ module ts {
895918
else if (node.flags & NodeFlags.MultiLine) {
896919
write("{");
897920
increaseIndent();
898-
emitMultiLineList(node.properties);
921+
emitMultiLineList(node.properties, /*includeTrailingComma*/ compilerOptions.target >= ScriptTarget.ES5);
899922
decreaseIndent();
900923
writeLine();
901924
write("}");
902925
}
903926
else {
904927
write("{ ");
905-
emitCommaList(node.properties);
928+
emitCommaList(node.properties, /*includeTrailingComma*/ compilerOptions.target >= ScriptTarget.ES5);
906929
write(" }");
907930
}
908931
}
@@ -949,13 +972,13 @@ module ts {
949972
emitThis(node.func);
950973
if (node.arguments.length) {
951974
write(", ");
952-
emitCommaList(node.arguments);
975+
emitCommaList(node.arguments, /*includeTrailingComma*/ false);
953976
}
954977
write(")");
955978
}
956979
else {
957980
write("(");
958-
emitCommaList(node.arguments);
981+
emitCommaList(node.arguments, /*includeTrailingComma*/ false);
959982
write(")");
960983
}
961984
}
@@ -965,7 +988,7 @@ module ts {
965988
emit(node.func);
966989
if (node.arguments) {
967990
write("(");
968-
emitCommaList(node.arguments);
991+
emitCommaList(node.arguments, /*includeTrailingComma*/ false);
969992
write(")");
970993
}
971994
}
@@ -1138,7 +1161,7 @@ module ts {
11381161
if (node.declarations) {
11391162
emitToken(SyntaxKind.VarKeyword, endPos);
11401163
write(" ");
1141-
emitCommaList(node.declarations);
1164+
emitCommaList(node.declarations, /*includeTrailingComma*/ false);
11421165
}
11431166
if (node.initializer) {
11441167
emit(node.initializer);
@@ -1286,7 +1309,7 @@ module ts {
12861309
function emitVariableStatement(node: VariableStatement) {
12871310
emitLeadingComments(node);
12881311
if (!(node.flags & NodeFlags.Export)) write("var ");
1289-
emitCommaList(node.declarations);
1312+
emitCommaList(node.declarations, /*includeTrailingComma*/ false);
12901313
write(";");
12911314
emitTrailingComments(node);
12921315
}
@@ -1395,7 +1418,7 @@ module ts {
13951418
increaseIndent();
13961419
write("(");
13971420
if (node) {
1398-
emitCommaList(node.parameters, node.parameters.length - (hasRestParameters(node) ? 1 : 0));
1421+
emitCommaList(node.parameters, /*includeTrailingComma*/ false, node.parameters.length - (hasRestParameters(node) ? 1 : 0));
13991422
}
14001423
write(")");
14011424
decreaseIndent();

src/compiler/parser.ts

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -628,12 +628,6 @@ module ts {
628628
Parameters, // Parameters in parameter list
629629
}
630630

631-
enum TrailingCommaBehavior {
632-
Disallow,
633-
Allow,
634-
Preserve
635-
}
636-
637631
// Tracks whether we nested (directly or indirectly) in a certain control block.
638632
// Used for validating break and continue statements.
639633
enum ControlBlockContext {
@@ -1205,7 +1199,7 @@ module ts {
12051199
}
12061200

12071201
// Parses a comma-delimited list of elements
1208-
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, trailingCommaBehavior: TrailingCommaBehavior): NodeArray<T> {
1202+
function parseDelimitedList<T extends Node>(kind: ParsingContext, parseElement: () => T, allowTrailingComma: boolean): NodeArray<T> {
12091203
var saveParsingContext = parsingContext;
12101204
parsingContext |= 1 << kind;
12111205
var result = <NodeArray<T>>[];
@@ -1230,15 +1224,14 @@ module ts {
12301224
else if (isListTerminator(kind)) {
12311225
// Check if the last token was a comma.
12321226
if (commaStart >= 0) {
1233-
if (trailingCommaBehavior === TrailingCommaBehavior.Disallow) {
1227+
if (!allowTrailingComma) {
12341228
if (file.syntacticErrors.length === errorCountBeforeParsingList) {
12351229
// Report a grammar error so we don't affect lookahead
12361230
grammarErrorAtPos(commaStart, scanner.getStartPos() - commaStart, Diagnostics.Trailing_comma_not_allowed);
12371231
}
12381232
}
1239-
else if (trailingCommaBehavior === TrailingCommaBehavior.Preserve) {
1240-
result.push(<T>createNode(SyntaxKind.OmittedExpression));
1241-
}
1233+
// Always preserve a trailing comma by marking it on the NodeArray
1234+
result.hasTrailingComma = true;
12421235
}
12431236

12441237
break;
@@ -1273,7 +1266,7 @@ module ts {
12731266

12741267
function parseBracketedList<T extends Node>(kind: ParsingContext, parseElement: () => T, startToken: SyntaxKind, endToken: SyntaxKind): NodeArray<T> {
12751268
if (parseExpected(startToken)) {
1276-
var result = parseDelimitedList(kind, parseElement, TrailingCommaBehavior.Disallow);
1269+
var result = parseDelimitedList(kind, parseElement, /*allowTrailingComma*/ false);
12771270
parseExpected(endToken);
12781271
return result;
12791272
}
@@ -2174,10 +2167,10 @@ module ts {
21742167
// The identifier eval or arguments may not appear as the LeftHandSideExpression of an
21752168
// Assignment operator(11.13) or of a PostfixExpression(11.3) or as the UnaryExpression
21762169
// operated upon by a Prefix Increment(11.4.4) or a Prefix Decrement(11.4.5) operator
2177-
if ((token === SyntaxKind.PlusPlusToken || token === SyntaxKind.MinusMinusToken) && isEvalOrArgumentsIdentifier(operand)) {
2170+
if ((operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken) && isEvalOrArgumentsIdentifier(operand)) {
21782171
reportInvalidUseInStrictMode(<Identifier>operand);
21792172
}
2180-
else if (token === SyntaxKind.DeleteKeyword && operand.kind === SyntaxKind.Identifier) {
2173+
else if (operator === SyntaxKind.DeleteKeyword && operand.kind === SyntaxKind.Identifier) {
21812174
// When a delete operator occurs within strict mode code, a SyntaxError is thrown if its
21822175
// UnaryExpression is a direct reference to a variable, function argument, or function name
21832176
grammarErrorOnNode(operand, Diagnostics.delete_cannot_be_called_on_an_identifier_in_strict_mode);
@@ -2309,7 +2302,11 @@ module ts {
23092302
else {
23102303
parseExpected(SyntaxKind.OpenParenToken);
23112304
}
2312-
callExpr.arguments = parseDelimitedList(ParsingContext.ArgumentExpressions, parseAssignmentExpression, TrailingCommaBehavior.Disallow);
2305+
// It is an error to have a trailing comma in an argument list. However, the checker
2306+
// needs evidence of a trailing comma in order to give good results for signature help.
2307+
// That is why we do not allow a trailing comma, but we "preserve" a trailing comma.
2308+
callExpr.arguments = parseDelimitedList(ParsingContext.ArgumentExpressions,
2309+
parseArgumentExpression, /*allowTrailingComma*/ false);
23132310
parseExpected(SyntaxKind.CloseParenToken);
23142311
expr = finishNode(callExpr);
23152312
continue;
@@ -2378,15 +2375,33 @@ module ts {
23782375
return finishNode(node);
23792376
}
23802377

2378+
function parseAssignmentExpressionOrOmittedExpression(omittedExpressionDiagnostic: DiagnosticMessage): Expression {
2379+
if (token === SyntaxKind.CommaToken) {
2380+
if (omittedExpressionDiagnostic) {
2381+
var errorStart = scanner.getTokenPos();
2382+
var errorLength = scanner.getTextPos() - errorStart;
2383+
grammarErrorAtPos(errorStart, errorLength, omittedExpressionDiagnostic);
2384+
}
2385+
return createNode(SyntaxKind.OmittedExpression);
2386+
}
2387+
2388+
return parseAssignmentExpression();
2389+
}
2390+
23812391
function parseArrayLiteralElement(): Expression {
2382-
return token === SyntaxKind.CommaToken ? createNode(SyntaxKind.OmittedExpression) : parseAssignmentExpression();
2392+
return parseAssignmentExpressionOrOmittedExpression(/*omittedExpressionDiagnostic*/ undefined);
2393+
}
2394+
2395+
function parseArgumentExpression(): Expression {
2396+
return parseAssignmentExpressionOrOmittedExpression(Diagnostics.Argument_expression_expected);
23832397
}
23842398

23852399
function parseArrayLiteral(): ArrayLiteral {
23862400
var node = <ArrayLiteral>createNode(SyntaxKind.ArrayLiteral);
23872401
parseExpected(SyntaxKind.OpenBracketToken);
23882402
if (scanner.hasPrecedingLineBreak()) node.flags |= NodeFlags.MultiLine;
2389-
node.elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers, parseArrayLiteralElement, TrailingCommaBehavior.Preserve);
2403+
node.elements = parseDelimitedList(ParsingContext.ArrayLiteralMembers,
2404+
parseArrayLiteralElement, /*allowTrailingComma*/ true);
23902405
parseExpected(SyntaxKind.CloseBracketToken);
23912406
return finishNode(node);
23922407
}
@@ -2428,10 +2443,7 @@ module ts {
24282443
node.flags |= NodeFlags.MultiLine;
24292444
}
24302445

2431-
// ES3 itself does not accept a trailing comma in an object literal, however, we'd like to preserve it in ES5.
2432-
var trailingCommaBehavior = languageVersion === ScriptTarget.ES3 ? TrailingCommaBehavior.Allow : TrailingCommaBehavior.Preserve;
2433-
2434-
node.properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralMember, trailingCommaBehavior);
2446+
node.properties = parseDelimitedList(ParsingContext.ObjectLiteralMembers, parseObjectLiteralMember, /*allowTrailingComma*/ true);
24352447
parseExpected(SyntaxKind.CloseBraceToken);
24362448

24372449
var seen: Map<SymbolFlags> = {};
@@ -2520,7 +2532,11 @@ module ts {
25202532
parseExpected(SyntaxKind.NewKeyword);
25212533
node.func = parseCallAndAccess(parsePrimaryExpression(), /* inNewExpression */ true);
25222534
if (parseOptional(SyntaxKind.OpenParenToken) || token === SyntaxKind.LessThanToken && (node.typeArguments = tryParse(parseTypeArgumentsAndOpenParen))) {
2523-
node.arguments = parseDelimitedList(ParsingContext.ArgumentExpressions, parseAssignmentExpression, TrailingCommaBehavior.Disallow);
2535+
// It is an error to have a trailing comma in an argument list. However, the checker
2536+
// needs evidence of a trailing comma in order to give good results for signature help.
2537+
// That is why we do not allow a trailing comma, but we "preserve" a trailing comma.
2538+
node.arguments = parseDelimitedList(ParsingContext.ArgumentExpressions,
2539+
parseArgumentExpression, /*allowTrailingComma*/ false);
25242540
parseExpected(SyntaxKind.CloseParenToken);
25252541
}
25262542
return finishNode(node);
@@ -3089,7 +3105,8 @@ module ts {
30893105
}
30903106

30913107
function parseVariableDeclarationList(flags: NodeFlags, noIn?: boolean): NodeArray<VariableDeclaration> {
3092-
return parseDelimitedList(ParsingContext.VariableDeclarations, () => parseVariableDeclaration(flags, noIn), TrailingCommaBehavior.Disallow);
3108+
return parseDelimitedList(ParsingContext.VariableDeclarations,
3109+
() => parseVariableDeclaration(flags, noIn), /*allowTrailingComma*/ false);
30933110
}
30943111

30953112
function parseVariableStatement(pos?: number, flags?: NodeFlags): VariableStatement {
@@ -3488,7 +3505,8 @@ module ts {
34883505
var implementsKeywordLength: number;
34893506
if (parseOptional(SyntaxKind.ImplementsKeyword)) {
34903507
implementsKeywordLength = scanner.getStartPos() - implementsKeywordStart;
3491-
node.implementedTypes = parseDelimitedList(ParsingContext.BaseTypeReferences, parseTypeReference, TrailingCommaBehavior.Disallow);
3508+
node.implementedTypes = parseDelimitedList(ParsingContext.BaseTypeReferences,
3509+
parseTypeReference, /*allowTrailingComma*/ false);
34923510
}
34933511
var errorCountBeforeClassBody = file.syntacticErrors.length;
34943512
if (parseExpected(SyntaxKind.OpenBraceToken)) {
@@ -3516,7 +3534,8 @@ module ts {
35163534
var extendsKeywordLength: number;
35173535
if (parseOptional(SyntaxKind.ExtendsKeyword)) {
35183536
extendsKeywordLength = scanner.getStartPos() - extendsKeywordStart;
3519-
node.baseTypes = parseDelimitedList(ParsingContext.BaseTypeReferences, parseTypeReference, TrailingCommaBehavior.Disallow);
3537+
node.baseTypes = parseDelimitedList(ParsingContext.BaseTypeReferences,
3538+
parseTypeReference, /*allowTrailingComma*/ false);
35203539
}
35213540
var errorCountBeforeInterfaceBody = file.syntacticErrors.length;
35223541
node.members = parseTypeLiteral().members;
@@ -3580,7 +3599,8 @@ module ts {
35803599
parseExpected(SyntaxKind.EnumKeyword);
35813600
node.name = parseIdentifier();
35823601
if (parseExpected(SyntaxKind.OpenBraceToken)) {
3583-
node.members = parseDelimitedList(ParsingContext.EnumMembers, parseAndCheckEnumMember, TrailingCommaBehavior.Allow);
3602+
node.members = parseDelimitedList(ParsingContext.EnumMembers,
3603+
parseAndCheckEnumMember, /*allowTrailingComma*/ true);
35843604
parseExpected(SyntaxKind.CloseBraceToken);
35853605
}
35863606
else {

src/compiler/types.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,9 @@ module ts {
228228
FirstPunctuation = OpenBraceToken,
229229
LastPunctuation = CaretEqualsToken,
230230
FirstToken = EndOfFileToken,
231-
LastToken = StringKeyword
231+
LastToken = StringKeyword,
232+
FirstTriviaToken = SingleLineCommentTrivia,
233+
LastTriviaToken = WhitespaceTrivia
232234
}
233235

234236
export enum NodeFlags {
@@ -259,7 +261,9 @@ module ts {
259261
localSymbol?: Symbol; // Local symbol declared by node (initialized by binding only for exported nodes)
260262
}
261263

262-
export interface NodeArray<T> extends Array<T>, TextRange { }
264+
export interface NodeArray<T> extends Array<T>, TextRange {
265+
hasTrailingComma?: boolean;
266+
}
263267

264268
export interface Identifier extends Node {
265269
text: string; // Text of identifier (with escapes converted to characters)
@@ -646,6 +650,7 @@ module ts {
646650
getAugmentedPropertiesOfApparentType(type: Type): Symbol[];
647651
getRootSymbol(symbol: Symbol): Symbol;
648652
getContextualType(node: Node): Type;
653+
getResolvedSignature(node: CallExpression, candidatesOutArray?: Signature[]): Signature;
649654

650655
// Returns the constant value of this enum member, or 'undefined' if the enum member has a
651656
// computed value.
@@ -933,7 +938,7 @@ module ts {
933938
resolvedReturnType: Type; // Resolved return type
934939
minArgumentCount: number; // Number of non-optional parameters
935940
hasRestParameter: boolean; // True if last parameter is rest parameter
936-
hasStringLiterals: boolean; // True if instantiated
941+
hasStringLiterals: boolean; // True if specialized
937942
target?: Signature; // Instantiation target
938943
mapper?: TypeMapper; // Instantiation mapper
939944
erasedSignatureCache?: Signature; // Erased version of signature (deferred)

0 commit comments

Comments
 (0)