Skip to content

Commit a88bfbd

Browse files
committed
Merge branch 'master' into reuseAndCache
2 parents 405db82 + 5fbe3fc commit a88bfbd

File tree

148 files changed

+5230
-986
lines changed

Some content is hidden

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

148 files changed

+5230
-986
lines changed

package.json

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,11 @@
4343
"build:compiler": "jake local",
4444
"build:tests": "jake tests",
4545
"clean": "jake clean"
46-
}
46+
},
47+
"browser": {
48+
"buffer": false,
49+
"fs": false,
50+
"os": false,
51+
"path": false
52+
}
4753
}

src/compiler/binder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ namespace ts {
7474
// If the current node is a container that also container that also contains locals. Examples:
7575
//
7676
// Functions, Methods, Modules, Source-files.
77-
IsContainerWithLocals = IsContainer | HasLocals
77+
IsContainerWithLocals = IsContainer | HasLocals
7878
}
7979

8080
export function bindSourceFile(file: SourceFile) {
@@ -1062,4 +1062,4 @@ namespace ts {
10621062
: declareSymbolAndAddToSymbolTable(node, symbolFlags, symbolExcludes);
10631063
}
10641064
}
1065-
}
1065+
}

src/compiler/checker.ts

Lines changed: 115 additions & 70 deletions
Large diffs are not rendered by default.

src/compiler/core.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,13 @@ namespace ts {
198198
return array[array.length - 1];
199199
}
200200

201+
/**
202+
* Performs a binary search, finding the index at which 'value' occurs in 'array'.
203+
* If no such index is found, returns the 2's-complement of first index at which
204+
* number[index] exceeds number.
205+
* @param array A sorted array whose first element must be no larger than number
206+
* @param number The value to be searched for in the array.
207+
*/
201208
export function binarySearch(array: number[], value: number): number {
202209
let low = 0;
203210
let high = array.length - 1;

src/compiler/declarationEmitter.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -750,14 +750,18 @@ namespace ts {
750750
}
751751

752752
function writeTypeAliasDeclaration(node: TypeAliasDeclaration) {
753+
let prevEnclosingDeclaration = enclosingDeclaration;
754+
enclosingDeclaration = node;
753755
emitJsDocComments(node);
754756
emitModuleElementDeclarationFlags(node);
755757
write("type ");
756758
writeTextOfNode(currentSourceFile, node.name);
759+
emitTypeParameters(node.typeParameters);
757760
write(" = ");
758761
emitTypeWithNewGetSymbolAccessibilityDiagnostic(node.type, getTypeAliasDeclarationVisibilityError);
759762
write(";");
760763
writeLine();
764+
enclosingDeclaration = prevEnclosingDeclaration;
761765

762766
function getTypeAliasDeclarationVisibilityError(symbolAccesibilityResult: SymbolAccessiblityResult): SymbolAccessibilityDiagnostic {
763767
return {
@@ -1497,11 +1501,8 @@ namespace ts {
14971501
// emit : declare function foo({y: [a, b, c]}: { y: [any, any, any] }) void;
14981502
writeTextOfNode(currentSourceFile, bindingElement.propertyName);
14991503
write(": ");
1500-
1501-
// If bindingElement has propertyName property, then its name must be another bindingPattern of SyntaxKind.ObjectBindingPattern
1502-
emitBindingPattern(<BindingPattern>bindingElement.name);
15031504
}
1504-
else if (bindingElement.name) {
1505+
if (bindingElement.name) {
15051506
if (isBindingPattern(bindingElement.name)) {
15061507
// If it is a nested binding pattern, we will recursively descend into each element and emit each one separately.
15071508
// In the case of rest element, we will omit rest element.

src/compiler/emitter.ts

Lines changed: 187 additions & 124 deletions
Large diffs are not rendered by default.

src/compiler/parser.ts

Lines changed: 44 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -844,6 +844,10 @@ namespace ts {
844844
return token = scanner.scanJsxIdentifier();
845845
}
846846

847+
function scanJsxText(): SyntaxKind {
848+
return token = scanner.scanJsxToken();
849+
}
850+
847851
function speculationHelper<T>(callback: () => T, isLookAhead: boolean): T {
848852
// Keep track of the state we'll need to rollback to if lookahead fails (or if the
849853
// caller asked us to always reset our state).
@@ -913,9 +917,11 @@ namespace ts {
913917
return token > SyntaxKind.LastReservedWord;
914918
}
915919

916-
function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage): boolean {
920+
function parseExpected(kind: SyntaxKind, diagnosticMessage?: DiagnosticMessage, shouldAdvance = true): boolean {
917921
if (token === kind) {
918-
nextToken();
922+
if (shouldAdvance) {
923+
nextToken();
924+
}
919925
return true;
920926
}
921927

@@ -3178,7 +3184,7 @@ namespace ts {
31783184
return parseTypeAssertion();
31793185
}
31803186
if (lookAhead(nextTokenIsIdentifierOrKeyword)) {
3181-
return parseJsxElementOrSelfClosingElement();
3187+
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ true);
31823188
}
31833189
// Fall through
31843190
default:
@@ -3308,14 +3314,14 @@ namespace ts {
33083314
return finishNode(node);
33093315
}
33103316

3311-
function parseJsxElementOrSelfClosingElement(): JsxElement|JsxSelfClosingElement {
3312-
let opening = parseJsxOpeningOrSelfClosingElement();
3317+
function parseJsxElementOrSelfClosingElement(inExpressionContext: boolean): JsxElement | JsxSelfClosingElement {
3318+
let opening = parseJsxOpeningOrSelfClosingElement(inExpressionContext);
33133319
if (opening.kind === SyntaxKind.JsxOpeningElement) {
33143320
let node = <JsxElement>createNode(SyntaxKind.JsxElement, opening.pos);
33153321
node.openingElement = opening;
33163322

33173323
node.children = parseJsxChildren(node.openingElement.tagName);
3318-
node.closingElement = parseJsxClosingElement();
3324+
node.closingElement = parseJsxClosingElement(inExpressionContext);
33193325
return finishNode(node);
33203326
}
33213327
else {
@@ -3336,9 +3342,9 @@ namespace ts {
33363342
case SyntaxKind.JsxText:
33373343
return parseJsxText();
33383344
case SyntaxKind.OpenBraceToken:
3339-
return parseJsxExpression();
3345+
return parseJsxExpression(/*inExpressionContext*/ false);
33403346
case SyntaxKind.LessThanToken:
3341-
return parseJsxElementOrSelfClosingElement();
3347+
return parseJsxElementOrSelfClosingElement(/*inExpressionContext*/ false);
33423348
}
33433349
Debug.fail("Unknown JSX child kind " + token);
33443350
}
@@ -3368,7 +3374,7 @@ namespace ts {
33683374
return result;
33693375
}
33703376

3371-
function parseJsxOpeningOrSelfClosingElement(): JsxOpeningElement|JsxSelfClosingElement {
3377+
function parseJsxOpeningOrSelfClosingElement(inExpressionContext: boolean): JsxOpeningElement|JsxSelfClosingElement {
33723378
let fullStart = scanner.getStartPos();
33733379

33743380
parseExpected(SyntaxKind.LessThanToken);
@@ -3378,12 +3384,22 @@ namespace ts {
33783384
let attributes = parseList(ParsingContext.JsxAttributes, parseJsxAttribute);
33793385
let node: JsxOpeningLikeElement;
33803386

3381-
if (parseOptional(SyntaxKind.GreaterThanToken)) {
3387+
if (token === SyntaxKind.GreaterThanToken) {
3388+
// Closing tag, so scan the immediately-following text with the JSX scanning instead
3389+
// of regular scanning to avoid treating illegal characters (e.g. '#') as immediate
3390+
// scanning errors
33823391
node = <JsxOpeningElement>createNode(SyntaxKind.JsxOpeningElement, fullStart);
3392+
scanJsxText();
33833393
}
33843394
else {
33853395
parseExpected(SyntaxKind.SlashToken);
3386-
parseExpected(SyntaxKind.GreaterThanToken);
3396+
if (inExpressionContext) {
3397+
parseExpected(SyntaxKind.GreaterThanToken);
3398+
}
3399+
else {
3400+
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*advance*/ false);
3401+
scanJsxText();
3402+
}
33873403
node = <JsxSelfClosingElement>createNode(SyntaxKind.JsxSelfClosingElement, fullStart);
33883404
}
33893405

@@ -3406,14 +3422,20 @@ namespace ts {
34063422
return elementName;
34073423
}
34083424

3409-
function parseJsxExpression(): JsxExpression {
3425+
function parseJsxExpression(inExpressionContext: boolean): JsxExpression {
34103426
let node = <JsxExpression>createNode(SyntaxKind.JsxExpression);
34113427

34123428
parseExpected(SyntaxKind.OpenBraceToken);
34133429
if (token !== SyntaxKind.CloseBraceToken) {
34143430
node.expression = parseExpression();
34153431
}
3416-
parseExpected(SyntaxKind.CloseBraceToken);
3432+
if (inExpressionContext) {
3433+
parseExpected(SyntaxKind.CloseBraceToken);
3434+
}
3435+
else {
3436+
parseExpected(SyntaxKind.CloseBraceToken, /*message*/ undefined, /*advance*/ false);
3437+
scanJsxText();
3438+
}
34173439

34183440
return finishNode(node);
34193441
}
@@ -3432,7 +3454,7 @@ namespace ts {
34323454
node.initializer = parseLiteralNode();
34333455
break;
34343456
default:
3435-
node.initializer = parseJsxExpression();
3457+
node.initializer = parseJsxExpression(/*inExpressionContext*/ true);
34363458
break;
34373459
}
34383460
}
@@ -3448,11 +3470,17 @@ namespace ts {
34483470
return finishNode(node);
34493471
}
34503472

3451-
function parseJsxClosingElement(): JsxClosingElement {
3473+
function parseJsxClosingElement(inExpressionContext: boolean): JsxClosingElement {
34523474
let node = <JsxClosingElement>createNode(SyntaxKind.JsxClosingElement);
34533475
parseExpected(SyntaxKind.LessThanSlashToken);
34543476
node.tagName = parseJsxElementName();
3455-
parseExpected(SyntaxKind.GreaterThanToken);
3477+
if (inExpressionContext) {
3478+
parseExpected(SyntaxKind.GreaterThanToken);
3479+
}
3480+
else {
3481+
parseExpected(SyntaxKind.GreaterThanToken, /*diagnostic*/ undefined, /*advance*/ false);
3482+
scanJsxText();
3483+
}
34563484
return finishNode(node);
34573485
}
34583486

src/compiler/scanner.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -319,14 +319,21 @@ namespace ts {
319319
}
320320

321321
/* @internal */
322+
/**
323+
* We assume the first line starts at position 0 and 'position' is non-negative.
324+
*/
322325
export function computeLineAndCharacterOfPosition(lineStarts: number[], position: number) {
323326
let lineNumber = binarySearch(lineStarts, position);
324327
if (lineNumber < 0) {
325328
// If the actual position was not found,
326-
// the binary search returns the negative value of the next line start
329+
// the binary search returns the 2's-complement of the next line start
327330
// e.g. if the line starts at [5, 10, 23, 80] and the position requested was 20
328-
// then the search will return -2
331+
// then the search will return -2.
332+
//
333+
// We want the index of the previous line start, so we subtract 1.
334+
// Review 2's-complement if this is confusing.
329335
lineNumber = ~lineNumber - 1;
336+
Debug.assert(lineNumber !== -1, "position cannot precede the beginning of the file");
330337
}
331338
return {
332339
line: lineNumber,
@@ -552,13 +559,17 @@ namespace ts {
552559
return pos;
553560
}
554561

555-
// Extract comments from the given source text starting at the given position. If trailing is
556-
// false, whitespace is skipped until the first line break and comments between that location
557-
// and the next token are returned.If trailing is true, comments occurring between the given
558-
// position and the next line break are returned.The return value is an array containing a
559-
// TextRange for each comment. Single-line comment ranges include the beginning '//' characters
560-
// but not the ending line break. Multi - line comment ranges include the beginning '/* and
561-
// ending '*/' characters.The return value is undefined if no comments were found.
562+
/**
563+
* Extract comments from text prefixing the token closest following `pos`.
564+
* The return value is an array containing a TextRange for each comment.
565+
* Single-line comment ranges include the beginning '//' characters but not the ending line break.
566+
* Multi - line comment ranges include the beginning '/* and ending '<asterisk>/' characters.
567+
* The return value is undefined if no comments were found.
568+
* @param trailing
569+
* If false, whitespace is skipped until the first line break and comments between that location
570+
* and the next token are returned.
571+
* If true, comments occurring between the given position and the next line break are returned.
572+
*/
562573
function getCommentRanges(text: string, pos: number, trailing: boolean): CommentRange[] {
563574
let result: CommentRange[];
564575
let collecting = trailing || pos === 0;

src/compiler/sys.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,9 @@ namespace ts {
334334
if (typeof WScript !== "undefined" && typeof ActiveXObject === "function") {
335335
return getWScriptSystem();
336336
}
337-
else if (typeof module !== "undefined" && module.exports) {
337+
else if (typeof process !== "undefined" && process.nextTick && !process.browser) {
338+
// process and process.nextTick checks if current environment is node-like
339+
// process.browser check excludes webpack and browserify
338340
return getNodeSystem();
339341
}
340342
else {

src/compiler/tsc.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -363,7 +363,7 @@ namespace ts {
363363
// If we didn't have any syntactic errors, then also try getting the global and
364364
// semantic errors.
365365
if (diagnostics.length === 0) {
366-
diagnostics = program.getGlobalDiagnostics();
366+
diagnostics = program.getOptionsDiagnostics().concat(program.getGlobalDiagnostics());
367367

368368
if (diagnostics.length === 0) {
369369
diagnostics = program.getSemanticDiagnostics();

0 commit comments

Comments
 (0)