Merge branch 'master' into sourceFileUpdate

This commit is contained in:
Cyrus Najmabadi
2014-12-11 15:07:49 -08:00
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;