Merge branch 'master' into LSAPICleanup

This commit is contained in:
Mohamed Hegazy
2015-02-02 13:55:45 -08:00
84 changed files with 1750 additions and 332 deletions
+58 -30
View File
@@ -1069,7 +1069,7 @@ module ts {
* Enclosing declaration is optional when we don't want to get qualified name in the enclosing declaration scope
* Meaning needs to be specified if the enclosing declaration is given
*/
function buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags): void {
function buildSymbolDisplay(symbol: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, meaning?: SymbolFlags, flags?: SymbolFormatFlags, typeFlags?: TypeFormatFlags): void {
var parentSymbol: Symbol;
function appendParentTypeArgumentsAndSymbolName(symbol: Symbol): void {
if (parentSymbol) {
@@ -1131,11 +1131,12 @@ module ts {
}
}
// Get qualified name
if (enclosingDeclaration &&
// TypeParameters do not need qualification
!(symbol.flags & SymbolFlags.TypeParameter)) {
// Get qualified name if the symbol is not a type parameter
// and there is an enclosing declaration or we specifically
// asked for it
var isTypeParameter = symbol.flags & SymbolFlags.TypeParameter;
var typeFormatFlag = TypeFormatFlags.UseFullyQualifiedType & typeFlags;
if (!isTypeParameter && (enclosingDeclaration || typeFormatFlag)) {
walkSymbol(symbol, meaning);
return;
}
@@ -1158,7 +1159,8 @@ module ts {
writeTypeReference(<TypeReference>type, flags);
}
else if (type.flags & (TypeFlags.Class | TypeFlags.Interface | TypeFlags.Enum | TypeFlags.TypeParameter)) {
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type);
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
else if (type.flags & TypeFlags.Tuple) {
writeTupleType(<TupleType>type);
@@ -1229,17 +1231,18 @@ module ts {
function writeAnonymousType(type: ObjectType, flags: TypeFormatFlags) {
// Always use 'typeof T' for type of class, enum, and module objects
if (type.symbol && type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Enum | SymbolFlags.ValueModule)) {
writeTypeofSymbol(type);
writeTypeofSymbol(type, flags);
}
// Use 'typeof T' for types of functions and methods that circularly reference themselves
else if (shouldWriteTypeOfFunctionSymbol()) {
writeTypeofSymbol(type);
writeTypeofSymbol(type, flags);
}
else if (typeStack && contains(typeStack, type)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
var typeAlias = getTypeAliasForTypeLiteral(type);
if (typeAlias) {
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type);
// The specified symbol flags need to be reinterpreted as type flags
buildSymbolDisplay(typeAlias, writer, enclosingDeclaration, SymbolFlags.Type, SymbolFormatFlags.None, flags);
}
else {
// Recursive usage, use any
@@ -1273,10 +1276,10 @@ module ts {
}
}
function writeTypeofSymbol(type: ObjectType) {
function writeTypeofSymbol(type: ObjectType, typeFormatFlags?: TypeFormatFlags) {
writeKeyword(writer, SyntaxKind.TypeOfKeyword);
writeSpace(writer);
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Value);
buildSymbolDisplay(type.symbol, writer, enclosingDeclaration, SymbolFlags.Value, SymbolFormatFlags.None, typeFormatFlags);
}
function getIndexerParameterName(type: ObjectType, indexKind: IndexKind, fallbackName: string): string {
@@ -3562,7 +3565,13 @@ module ts {
}
if (reportErrors) {
headMessage = headMessage || Diagnostics.Type_0_is_not_assignable_to_type_1;
reportError(headMessage, typeToString(source), typeToString(target));
var sourceType = typeToString(source);
var targetType = typeToString(target);
if (sourceType === targetType) {
sourceType = typeToString(source, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
targetType = typeToString(target, /*enclosingDeclaration*/ undefined, TypeFormatFlags.UseFullyQualifiedType);
}
reportError(headMessage, sourceType, targetType);
}
return Ternary.False;
}
@@ -4331,6 +4340,9 @@ module ts {
}
function inferFromTypes(source: Type, target: Type) {
if (source === anyFunctionType) {
return;
}
if (target.flags & TypeFlags.TypeParameter) {
// If target is a type parameter, make an inference
var typeParameters = context.typeParameters;
@@ -4849,6 +4861,16 @@ module ts {
function checkIdentifier(node: Identifier): Type {
var symbol = getResolvedSymbol(node);
// As noted in ECMAScript 6 language spec, arrow functions never have an arguments objects.
// Although in down-level emit of arrow function, we emit it using function expression which means that
// arguments objects will be bound to the inner object; emitting arrow function natively in ES6, arguments objects
// will be bound to non-arrow function that contain this arrow function. This results in inconsistent behavior.
// To avoid that we will give an error to users if they use arguments objects in arrow function so that they
// can explicitly bound arguments objects
if (symbol === argumentsSymbol && getContainingFunction(node).kind === SyntaxKind.ArrowFunction) {
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression);
}
if (symbol.flags & SymbolFlags.Import) {
var symbolLinks = getSymbolLinks(symbol);
if (!symbolLinks.referenced) {
@@ -4903,7 +4925,9 @@ module ts {
// Now skip arrow functions to get the "real" owner of 'this'.
if (container.kind === SyntaxKind.ArrowFunction) {
container = getThisContainer(container, /* includeArrowFunctions */ false);
needToCaptureLexicalThis = true;
// When targeting es6, arrow function lexically bind "this" so we do not need to do the work of binding "this" in emitted code
needToCaptureLexicalThis = (languageVersion < ScriptTarget.ES6);
}
switch (container.kind) {
@@ -5895,28 +5919,31 @@ module ts {
return getSignatureInstantiation(signature, getInferredTypes(context));
}
function inferTypeArguments(signature: Signature, args: Expression[], excludeArgument?: boolean[]): InferenceContext {
function inferTypeArguments(signature: Signature, args: Expression[], excludeArgument: boolean[]): InferenceContext {
var typeParameters = signature.typeParameters;
var context = createInferenceContext(typeParameters, /*inferUnionTypes*/ false);
var mapper = createInferenceMapper(context);
// First infer from arguments that are not context sensitive
var inferenceMapper = createInferenceMapper(context);
// We perform two passes over the arguments. In the first pass we infer from all arguments, but use
// wildcards for all context sensitive function expressions.
for (var i = 0; i < args.length; i++) {
if (args[i].kind === SyntaxKind.OmittedExpression) {
continue;
}
if (!excludeArgument || excludeArgument[i] === undefined) {
var parameterType = getTypeAtPosition(signature, i);
if (i === 0 && args[i].parent.kind === SyntaxKind.TaggedTemplateExpression) {
inferTypes(context, globalTemplateStringsArrayType, parameterType);
continue;
}
inferTypes(context, checkExpressionWithContextualType(args[i], parameterType, mapper), parameterType);
var parameterType = getTypeAtPosition(signature, i);
if (i === 0 && args[i].parent.kind === SyntaxKind.TaggedTemplateExpression) {
inferTypes(context, globalTemplateStringsArrayType, parameterType);
continue;
}
// For context sensitive arguments we pass the identityMapper, which is a signal to treat all
// context sensitive function expressions as wildcards
var mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : inferenceMapper;
inferTypes(context, checkExpressionWithContextualType(args[i], parameterType, mapper), parameterType);
}
// Next, infer from those context sensitive arguments that are no longer excluded
// In the second pass we visit only context sensitive arguments, and only those that aren't excluded, this
// time treating function expressions normally (which may cause previously inferred type arguments to be fixed
// as we construct types for contextually typed parameters)
if (excludeArgument) {
for (var i = 0; i < args.length; i++) {
if (args[i].kind === SyntaxKind.OmittedExpression) {
@@ -5925,10 +5952,11 @@ module ts {
// No need to special-case tagged templates; their excludeArgument value will be 'undefined'.
if (excludeArgument[i] === false) {
var parameterType = getTypeAtPosition(signature, i);
inferTypes(context, checkExpressionWithContextualType(args[i], parameterType, mapper), parameterType);
inferTypes(context, checkExpressionWithContextualType(args[i], parameterType, inferenceMapper), parameterType);
}
}
}
var inferredTypes = getInferredTypes(context);
// Inference has failed if the inferenceFailureType type is in list of inferences
context.failedTypeParameterIndex = indexOf(inferredTypes, inferenceFailureType);
@@ -6622,7 +6650,7 @@ module ts {
}
// The identityMapper object is used to indicate that function expressions are wildcards
if (contextualMapper === identityMapper) {
if (contextualMapper === identityMapper && isContextSensitive(node)) {
return anyFunctionType;
}
var links = getNodeLinks(node);
@@ -7296,7 +7324,7 @@ module ts {
case SyntaxKind.TypeAssertionExpression:
return checkTypeAssertion(<TypeAssertion>node);
case SyntaxKind.ParenthesizedExpression:
return checkExpression((<ParenthesizedExpression>node).expression);
return checkExpression((<ParenthesizedExpression>node).expression, contextualMapper);
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
return checkFunctionExpressionOrObjectLiteralMethod(<FunctionExpression>node, contextualMapper);
@@ -452,5 +452,6 @@ module ts {
You_cannot_rename_this_element: { code: 8000, category: DiagnosticCategory.Error, key: "You cannot rename this element." },
yield_expressions_are_not_currently_supported: { code: 9000, category: DiagnosticCategory.Error, key: "'yield' expressions are not currently supported.", isEarly: true },
Generators_are_not_currently_supported: { code: 9001, category: DiagnosticCategory.Error, key: "Generators are not currently supported.", isEarly: true },
The_arguments_object_cannot_be_referenced_in_an_arrow_function_Consider_using_a_standard_function_expression: { code: 9002, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression." },
};
}
+7 -3
View File
@@ -1612,7 +1612,7 @@
"Property '{0}' does not exist on 'const' enum '{1}'.": {
"category": "Error",
"code": 4088,
"isEarly": true
"isEarly": true
},
"The current host does not support the '{0}' option.": {
"category": "Error",
@@ -1902,11 +1902,15 @@
"'yield' expressions are not currently supported.": {
"category": "Error",
"code": 9000,
"isEarly": true
"isEarly": true
},
"Generators are not currently supported.": {
"category": "Error",
"code": 9001,
"isEarly": true
"isEarly": true
},
"The 'arguments' object cannot be referenced in an arrow function. Consider using a standard function expression.": {
"category": "Error",
"code": 9002
}
}
+31 -3
View File
@@ -1487,7 +1487,6 @@ module ts {
// targetSourceFile is when users only want one file in entire project to be emitted. This is used in compilerOnSave feature
export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFile?: SourceFile): EmitResult {
// var program = resolver.getProgram();
var compilerOptions = host.getCompilerOptions();
var languageVersion = compilerOptions.target || ScriptTarget.ES3;
var sourceMapDataList: SourceMapData[] = compilerOptions.sourceMap ? [] : undefined;
@@ -3240,6 +3239,10 @@ module ts {
emitSignatureAndBody(node);
}
function shouldEmitAsArrowFunction(node: FunctionLikeDeclaration): boolean {
return node.kind === SyntaxKind.ArrowFunction && languageVersion >= ScriptTarget.ES6;
}
function emitFunctionDeclaration(node: FunctionLikeDeclaration) {
if (nodeIsMissing(node.body)) {
return emitPinnedOrTripleSlashComments(node);
@@ -3249,7 +3252,13 @@ module ts {
// Methods will emit the comments as part of emitting method declaration
emitLeadingComments(node);
}
write("function ");
// For targeting below es6, emit functions-like declaration including arrow function using function keyword.
// When targeting ES6, emit arrow function natively in ES6 by omitting function keyword and using fat arrow instead
if (!shouldEmitAsArrowFunction(node)) {
write("function ");
}
if (node.kind === SyntaxKind.FunctionDeclaration || (node.kind === SyntaxKind.FunctionExpression && node.name)) {
emit(node.name);
}
@@ -3280,6 +3289,15 @@ module ts {
decreaseIndent();
}
function emitSignatureParametersForArrow(node: FunctionLikeDeclaration) {
// Check whether the parameter list needs parentheses and preserve no-parenthesis
if (node.parameters.length === 1 && node.pos === node.parameters[0].pos) {
emit(node.parameters[0]);
return;
}
emitSignatureParameters(node);
}
function emitSignatureAndBody(node: FunctionLikeDeclaration) {
var saveTempCount = tempCount;
var saveTempVariables = tempVariables;
@@ -3287,7 +3305,16 @@ module ts {
tempCount = 0;
tempVariables = undefined;
tempParameters = undefined;
emitSignatureParameters(node);
// When targeting ES6, emit arrow function natively in ES6
if (shouldEmitAsArrowFunction(node)) {
emitSignatureParametersForArrow(node);
write(" =>");
}
else {
emitSignatureParameters(node);
}
write(" {");
scopeEmitStart(node);
increaseIndent();
@@ -3299,6 +3326,7 @@ module ts {
startIndex = emitDirectivePrologues((<Block>node.body).statements, /*startWithNewLine*/ true);
}
var outPos = writer.getTextPos();
emitCaptureThisForNodeIfNecessary(node);
emitDefaultValueAssignments(node);
emitRestParameter(node);
+1
View File
@@ -1080,6 +1080,7 @@ module ts {
WriteOwnNameForAnyLike = 0x00000010, // Write symbol's own name instead of 'any' for any like types (eg. unknown, __resolving__ etc)
WriteTypeArgumentsOfSignature = 0x00000020, // Write the type arguments instead of type parameters of the signature
InElementType = 0x00000040, // Writing an array or union element type
UseFullyQualifiedType = 0x00000080, // Write out the fully qualified type name (eg. Module.Type, instead of Type)
}
export const enum SymbolFormatFlags {
+1 -1
View File
@@ -107,7 +107,7 @@ module Utils {
export function memoize<T extends Function>(f: T): T {
var cache: { [idx: string]: any } = {};
return <any>(() => {
return <any>(function () {
var key = Array.prototype.join.call(arguments);
var cachedResult = cache[key];
if (cachedResult) {
+1 -1
View File
@@ -138,7 +138,7 @@ module Playback {
function recordReplay<T extends Function>(original: T, underlying: any) {
function createWrapper(record: T, replay: T): T {
return <any>(() => {
return <any>(function () {
if (replayLog !== undefined) {
return replay.apply(undefined, arguments);
} else if (recordLog !== undefined) {
+1 -1
View File
@@ -186,7 +186,7 @@ class ProjectRunner extends RunnerBase {
function createCompilerHost(): ts.CompilerHost {
return {
getSourceFile,
getDefaultLibFilename: options => options.target === ts.ScriptTarget.ES6 ? "lib.es6.d.ts" : "lib.d.ts",
getDefaultLibFilename: options => Harness.Compiler.defaultLibFileName,
writeFile,
getCurrentDirectory,
getCanonicalFileName: Harness.Compiler.getCanonicalFileName,