mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into LSAPICleanup
This commit is contained in:
+58
-30
@@ -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." },
|
||||
};
|
||||
}
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user