Merge branch 'master' into sourceFileUpdate

This commit is contained in:
Cyrus Najmabadi 2014-12-11 15:07:49 -08:00
commit 63dbb78d02
48 changed files with 399 additions and 28 deletions

View File

@ -4622,8 +4622,8 @@ module ts {
// Get the narrowed type of a given symbol at a given location
function getNarrowedTypeOfSymbol(symbol: Symbol, node: Node) {
var type = getTypeOfSymbol(symbol);
// Only narrow when symbol is variable of a structured type
if (node && (symbol.flags & SymbolFlags.Variable && type.flags & TypeFlags.Structured)) {
// Only narrow when symbol is variable of an object, union, or type parameter type
if (node && symbol.flags & SymbolFlags.Variable && type.flags & (TypeFlags.ObjectType | TypeFlags.Union | TypeFlags.TypeParameter)) {
loop: while (node.parent) {
var child = node;
node = node.parent;
@ -6587,12 +6587,12 @@ module ts {
return numberType;
}
// Return true if type is any, an object type, a type parameter, or a union type composed of only those kinds of types
// Return true if type an object type, a type parameter, or a union type composed of only those kinds of types
function isStructuredType(type: Type): boolean {
if (type.flags & TypeFlags.Union) {
return !forEach((<UnionType>type).types, t => !isStructuredType(t));
}
return (type.flags & TypeFlags.Structured) !== 0;
return (type.flags & (TypeFlags.ObjectType | TypeFlags.TypeParameter)) !== 0;
}
function isConstEnumObjectType(type: Type): boolean {
@ -6609,11 +6609,11 @@ module ts {
// and the right operand to be of type Any or a subtype of the 'Function' interface type.
// The result is always of the Boolean primitive type.
// NOTE: do not raise error if leftType is unknown as related error was already reported
if (leftType !== unknownType && !isStructuredType(leftType)) {
if (!(leftType.flags & TypeFlags.Any || isStructuredType(leftType))) {
error(node.left, Diagnostics.The_left_hand_side_of_an_instanceof_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
// NOTE: do not raise error if right is unknown as related error was already reported
if (rightType !== unknownType && rightType !== anyType && !isTypeSubtypeOf(rightType, globalFunctionType)) {
if (!(rightType.flags & TypeFlags.Any || isTypeSubtypeOf(rightType, globalFunctionType))) {
error(node.right, Diagnostics.The_right_hand_side_of_an_instanceof_expression_must_be_of_type_any_or_of_a_type_assignable_to_the_Function_interface_type);
}
return booleanType;
@ -6627,7 +6627,7 @@ module ts {
if (leftType !== anyType && leftType !== stringType && leftType !== numberType) {
error(node.left, Diagnostics.The_left_hand_side_of_an_in_expression_must_be_of_types_any_string_or_number);
}
if (!isStructuredType(rightType)) {
if (!(rightType.flags & TypeFlags.Any || isStructuredType(rightType))) {
error(node.right, Diagnostics.The_right_hand_side_of_an_in_expression_must_be_of_type_any_an_object_type_or_a_type_parameter);
}
return booleanType;
@ -7975,7 +7975,7 @@ module ts {
var exprType = checkExpression(node.expression);
// unknownType is returned i.e. if node.expression is identifier whose name cannot be resolved
// in this case error about missing name is already reported - do not report extra one
if (!isStructuredType(exprType) && exprType !== unknownType) {
if (!(exprType.flags & TypeFlags.Any || isStructuredType(exprType))) {
error(node.expression, Diagnostics.The_right_hand_side_of_a_for_in_statement_must_be_of_type_any_an_object_type_or_a_type_parameter);
}

View File

@ -591,27 +591,44 @@ module ts {
return path;
}
var escapedCharsRegExp = /[\t\v\f\b\0\r\n\"\\\u2028\u2029\u0085]/g;
var backslashOrDoubleQuote = /[\"\\]/g;
var escapedCharsRegExp = /[\0-\19\t\v\f\b\0\r\n\u2028\u2029\u0085]/g;
var escapedCharsMap: Map<string> = {
"\0": "\\0",
"\t": "\\t",
"\v": "\\v",
"\f": "\\f",
"\b": "\\b",
"\0": "\\0",
"\r": "\\r",
"\n": "\\n",
"\\": "\\\\",
"\"": "\\\"",
"\u2028": "\\u2028", // lineSeparator
"\u2029": "\\u2029", // paragraphSeparator
"\u0085": "\\u0085" // nextLine
};
/** NOTE: This *does not* support the full escape characters, it only supports the subset that can be used in file names
* or string literals. If the information encoded in the map changes, this needs to be revisited. */
/**
* Based heavily on the abstract 'Quote' operation from ECMA-262 (24.3.2.2),
* but augmented for a few select characters.
* Note that this doesn't actually wrap the input in double quotes.
*/
export function escapeString(s: string): string {
return escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, c => {
return escapedCharsMap[c] || c;
}) : s;
// Prioritize '"' and '\'
s = backslashOrDoubleQuote.test(s) ? s.replace(backslashOrDoubleQuote, getReplacement) : s;
s = escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, getReplacement) : s;
return s;
function getReplacement(c: string) {
return escapedCharsMap[c] || unicodeEscape(c);
}
function unicodeEscape(c: string): string {
var hexCharCode = c.charCodeAt(0).toString(16);
var paddedHexCode = ("0000" + hexCharCode).slice(-4);
return "\\u" + paddedHexCode;
}
}
export interface ObjectAllocator {

View File

@ -640,14 +640,14 @@ module ts {
// Speculated ECMAScript 6 Spec 11.8.6.1:
// <CR><LF> and <CR> LineTerminatorSequences are normalized to <LF> for Template Values
// An explicit EscapeSequence is needed to include a <CR> or <CR><LF> sequence.
if (currChar === CharacterCodes.carriageReturn) {
contents += text.substring(start, pos);
pos++;
if (pos + 1 < len && text.charCodeAt(pos + 1) === CharacterCodes.lineFeed) {
if (pos < len && text.charCodeAt(pos) === CharacterCodes.lineFeed) {
pos++;
}
pos++;
contents += "\n";
start = pos;
continue;

View File

@ -1251,7 +1251,6 @@ module ts {
StringLike = String | StringLiteral,
NumberLike = Number | Enum,
ObjectType = Class | Interface | Reference | Tuple | Anonymous,
Structured = Any | ObjectType | Union | TypeParameter
}
// Properties common to all types
@ -1876,4 +1875,4 @@ module ts {
return createTextChangeRange(createTextSpanFromBounds(oldStartN, oldEndN), /*newLength: */newEndN - oldStartN);
}
}
}

View File

@ -70,14 +70,18 @@ module Utils {
}
}
/** Splits the given string on \r\n or on only \n if that fails */
/** Splits the given string on \r\n, or on only \n if that fails, or on only \r if *that* fails. */
export function splitContentByNewlines(content: string) {
// Split up the input file by line
// Note: IE JS engine incorrectly handles consecutive delimiters here when using RegExp split, so
// we have to string-based splitting instead and try to figure out the delimiting chars
// we have to use string-based splitting instead and try to figure out the delimiting chars
var lines = content.split('\r\n');
if (lines.length === 1) {
lines = content.split('\n');
if (lines.length === 1) {
lines = content.split("\r");
}
}
return lines;
}
@ -1020,6 +1024,10 @@ module Harness {
var lineStarts = ts.computeLineStarts(inputFile.content);
var lines = inputFile.content.split('\n');
if (lines.length === 1) {
lines = lines[0].split("\r");
}
lines.forEach((line, lineIndex) => {
if (line.length > 0 && line.charAt(line.length - 1) === '\r') {
line = line.substr(0, line.length - 1);

View File

@ -142,6 +142,9 @@ module Harness.LanguageService {
constructor(private cancellationToken: ts.CancellationToken = CancellationToken.None) {
}
public trace(s: string) {
}
public addDefaultLibrary() {
this.addScript(Harness.Compiler.defaultLibFileName, Harness.Compiler.defaultLibSourceFile.text);
}

View File

@ -622,14 +622,21 @@ module ts.formatting {
var tokenStart = sourceFile.getLineAndCharacterFromPosition(currentTokenInfo.token.pos);
if (isTokenInRange) {
var rangeHasError = rangeContainsError(currentTokenInfo.token);
// save prevStartLine since processRange will overwrite this value with current ones
var prevStartLine = previousRangeStartLine;
lineAdded = processRange(currentTokenInfo.token, tokenStart, parent, childContextNode, dynamicIndentation);
if (lineAdded !== undefined) {
indentToken = lineAdded;
if (rangeHasError) {
// do not indent comments\token if token range overlaps with some error
indentToken = false;
}
else {
indentToken = lastTriviaWasNewLine && tokenStart.line !== prevStartLine;
if (lineAdded !== undefined) {
indentToken = lineAdded;
}
else {
indentToken = lastTriviaWasNewLine && tokenStart.line !== prevStartLine;
}
}
}

View File

@ -14,6 +14,9 @@
/// <reference path='formatting.ts' />
module ts {
export var servicesVersion = "0.4"
export interface Node {
getSourceFile(): SourceFile;
getChildCount(sourceFile?: SourceFile): number;
@ -846,6 +849,8 @@ module ts {
export interface Logger {
log(s: string): void;
trace(s: string): void;
error(s: string): void;
}
//

View File

@ -341,6 +341,14 @@ module ts {
this.shimHost.log(s);
}
public trace(s: string): void {
this.shimHost.trace(s);
}
public error(s: string): void {
this.shimHost.error(s);
}
public getCompilationSettings(): CompilerOptions {
var settingsJson = this.shimHost.getCompilationSettings();
if (settingsJson == null || settingsJson == "") {
@ -859,6 +867,13 @@ module ts {
private _shims: Shim[] = [];
private documentRegistry: DocumentRegistry = createDocumentRegistry();
/*
* Returns script API version.
*/
public getServicesVersion(): string {
return servicesVersion;
}
public createLanguageServiceShim(host: LanguageServiceShimHost): LanguageServiceShim {
try {
var hostAdapter = new LanguageServiceShimHostAdapter(host);

View File

@ -342,6 +342,7 @@ module ts.formatting {
case SyntaxKind.VariableDeclaration:
case SyntaxKind.ExportAssignment:
case SyntaxKind.ReturnStatement:
case SyntaxKind.ConditionalExpression:
return true;
}
return false;

View File

@ -0,0 +1,11 @@
//// [templateStringMultiline1.ts]
// newlines are <CR><LF>
`
\
`
//// [templateStringMultiline1.js]
// newlines are <CR><LF>
"\n";

View File

@ -0,0 +1,8 @@
=== tests/cases/conformance/es6/templates/templateStringMultiline1.ts ===
No type information for this code.
No type information for this code.// newlines are <CR><LF>
No type information for this code.`
No type information for this code.\
No type information for this code.`
No type information for this code.

View File

@ -0,0 +1,12 @@
//// [templateStringMultiline1_ES6.ts]
// newlines are <CR><LF>
`
\
`
//// [templateStringMultiline1_ES6.js]
// newlines are <CR><LF>
`
\
`;

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/es6/templates/templateStringMultiline1_ES6.ts ===
No type information for this code.// newlines are <CR><LF>
No type information for this code.`
No type information for this code.\
No type information for this code.`
No type information for this code.

View File

@ -0,0 +1,11 @@
//// [templateStringMultiline2.ts]
// newlines are <LF>
`
\
`
//// [templateStringMultiline2.js]
// newlines are <LF>
"\n";

View File

@ -0,0 +1,8 @@
=== tests/cases/conformance/es6/templates/templateStringMultiline2.ts ===
No type information for this code.
No type information for this code.// newlines are <LF>
No type information for this code.`
No type information for this code.\
No type information for this code.`
No type information for this code.

View File

@ -0,0 +1,12 @@
//// [templateStringMultiline2_ES6.ts]
// newlines are <LF>
`
\
`
//// [templateStringMultiline2_ES6.js]
// newlines are <LF>
`
\
`;

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/es6/templates/templateStringMultiline2_ES6.ts ===
No type information for this code.// newlines are <LF>
No type information for this code.`
No type information for this code.\
No type information for this code.`
No type information for this code.

View File

@ -0,0 +1,11 @@
//// [templateStringMultiline3.ts]
// newlines are <CR>
`
\
`
//// [templateStringMultiline3.js]
// newlines are <CR>
"\n";

View File

@ -0,0 +1,8 @@
=== tests/cases/conformance/es6/templates/templateStringMultiline3.ts ===
No type information for this code.
No type information for this code.// newlines are <CR>
No type information for this code.`
No type information for this code.\
No type information for this code.`
No type information for this code.

View File

@ -0,0 +1,12 @@
//// [templateStringMultiline3_ES6.ts]
// newlines are <CR>
`
\
`
//// [templateStringMultiline3_ES6.js]
// newlines are <CR>
`
\
`;

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/es6/templates/templateStringMultiline3_ES6.ts ===
No type information for this code.// newlines are <CR>
No type information for this code.`
No type information for this code.\
No type information for this code.`
No type information for this code.

View File

@ -3,4 +3,4 @@
`\\`
//// [templateStringTermination2.js]
"\";
"\\";

View File

@ -3,4 +3,4 @@
`\\\\`
//// [templateStringTermination4.js]
"\\";
"\\\\";

View File

@ -3,4 +3,4 @@
`\\\\\\`
//// [templateStringTermination5.js]
"\\\";
"\\\\\\";

View File

@ -0,0 +1,7 @@
//// [templateStringWhitespaceEscapes1.ts]
`\t\n\v\f\r`;
//// [templateStringWhitespaceEscapes1.js]
"\t\n\v\f\r";

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1.ts ===
No type information for this code.
No type information for this code.`\t\n\v\f\r`;
No type information for this code.

View File

@ -0,0 +1,6 @@
//// [templateStringWhitespaceEscapes1_ES6.ts]
`\t\n\v\f\r`;
//// [templateStringWhitespaceEscapes1_ES6.js]
`\t\n\v\f\r`;

View File

@ -0,0 +1,4 @@
=== tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes1_ES6.ts ===
No type information for this code.`\t\n\v\f\r`;
No type information for this code.

View File

@ -0,0 +1,9 @@
//// [templateStringWhitespaceEscapes2.ts]
// <TAB>, <VT>, <FF>, <SP>, <NBSP>, <BOM>
`\u0009\u000B\u000C\u0020\u00A0\uFEFF`;
//// [templateStringWhitespaceEscapes2.js]
// <TAB>, <VT>, <FF>, <SP>, <NBSP>, <BOM>
"\t\v\f  ";

View File

@ -0,0 +1,6 @@
=== tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2.ts ===
No type information for this code.
No type information for this code.// <TAB>, <VT>, <FF>, <SP>, <NBSP>, <BOM>
No type information for this code.`\u0009\u000B\u000C\u0020\u00A0\uFEFF`;
No type information for this code.

View File

@ -0,0 +1,8 @@
//// [templateStringWhitespaceEscapes2_ES6.ts]
// <TAB>, <VT>, <FF>, <SP>, <NBSP>, <BOM>
`\u0009\u000B\u000C\u0020\u00A0\uFEFF`;
//// [templateStringWhitespaceEscapes2_ES6.js]
// <TAB>, <VT>, <FF>, <SP>, <NBSP>, <BOM>
`\u0009\u000B\u000C\u0020\u00A0\uFEFF`;

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/es6/templates/templateStringWhitespaceEscapes2_ES6.ts ===
No type information for this code.// <TAB>, <VT>, <FF>, <SP>, <NBSP>, <BOM>
No type information for this code.`\u0009\u000B\u000C\u0020\u00A0\uFEFF`;
No type information for this code.

View File

@ -0,0 +1,18 @@
//// [typeGuardsWithAny.ts]
var x: any = { p: 0 };
if (x instanceof Object) {
x.p; // No error, type any unaffected by type guard
}
else {
x.p; // No error, type any unaffected by type guard
}
//// [typeGuardsWithAny.js]
var x = { p: 0 };
if (x instanceof Object) {
x.p; // No error, type any unaffected by type guard
}
else {
x.p; // No error, type any unaffected by type guard
}

View File

@ -0,0 +1,23 @@
=== tests/cases/conformance/expressions/typeGuards/typeGuardsWithAny.ts ===
var x: any = { p: 0 };
>x : any
>{ p: 0 } : { p: number; }
>p : number
if (x instanceof Object) {
>x instanceof Object : boolean
>x : any
>Object : ObjectConstructor
x.p; // No error, type any unaffected by type guard
>x.p : any
>x : any
>p : any
}
else {
x.p; // No error, type any unaffected by type guard
>x.p : any
>x : any
>p : any
}

View File

@ -0,0 +1,6 @@

// newlines are <CR><LF>
`
\
`

View File

@ -0,0 +1,6 @@
//@target: es6
// newlines are <CR><LF>
`
\
`

View File

@ -0,0 +1,6 @@

// newlines are <LF>
`
\
`

View File

@ -0,0 +1,6 @@
//@target: es6
// newlines are <LF>
`
\
`

View File

@ -0,0 +1 @@
 // newlines are <CR> ` \ `

View File

@ -0,0 +1 @@
//@target: es6 // newlines are <CR> ` \ `

View File

@ -0,0 +1,3 @@

`\t\n\v\f\r`;

View File

@ -0,0 +1,3 @@
//@target: es6
`\t\n\v\f\r`;

View File

@ -0,0 +1,4 @@

// <TAB>, <VT>, <FF>, <SP>, <NBSP>, <BOM>
`\u0009\u000B\u000C\u0020\u00A0\uFEFF`;

View File

@ -0,0 +1,4 @@
//@target: es6
// <TAB>, <VT>, <FF>, <SP>, <NBSP>, <BOM>
`\u0009\u000B\u000C\u0020\u00A0\uFEFF`;

View File

@ -0,0 +1,7 @@
var x: any = { p: 0 };
if (x instanceof Object) {
x.p; // No error, type any unaffected by type guard
}
else {
x.p; // No error, type any unaffected by type guard
}

View File

@ -0,0 +1,20 @@
/// <reference path='fourslash.ts' />
////module A {
//// interface B {
//// // a
//// // b
//// baz();
/////*0*/ // d /*1*/asd a
//// // e
//// foo();
//// // f asd
//// // g as
//// bar();
//// }
////}
goTo.marker("1");
edit.insert("\n");
goTo.marker("0");
verify.currentLineContentIs(" // d ");

View File

@ -0,0 +1,44 @@
/// <reference path='fourslash.ts' />
////var v =
/////*0*/a === b
/////*1*/? c
/////*2*/: d;
////var v = a === b
/////*3*/? c
/////*4*/: d;
////var x =
/////*5*/a
/////*6*/? function(){
/////*7*/var z = 1
/////*8*/}
/////*9*/: function(){
/////*10*/var z = 2
/////*11*/}
function verifyLine(marker: string, content: string) {
goTo.marker(marker);
verify.currentLineContentIs(content);
}
format.document();
verifyLine("0", " a === b");
verifyLine("1", " ? c");
verifyLine("2", " : d;");
verifyLine("3", " ? c");
verifyLine("4", " : d;");
verifyLine("5", " a");
verifyLine("6", " ? function() {");
verifyLine("7", " var z = 1");
verifyLine("8", " }");
verifyLine("9", " : function() {");
verifyLine("10", " var z = 2");
verifyLine("11", " }");