From 1bab8daae55e09efd3d15a97784fc02e5ac648eb Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Wed, 15 Aug 2018 16:19:54 -0700 Subject: [PATCH 01/12] Test for existence of diagnostic whene running tests --- src/testRunner/unittests/convertToAsyncFunction.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/testRunner/unittests/convertToAsyncFunction.ts b/src/testRunner/unittests/convertToAsyncFunction.ts index f39b8080ed234..f3bdc889c34db 100644 --- a/src/testRunner/unittests/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/convertToAsyncFunction.ts @@ -362,11 +362,11 @@ interface Array {}` const diagnostics = languageService.getSuggestionDiagnostics(f.path); const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === description.message); - assert.isNotNull(diagnostic); + assert.exists(diagnostic); const actions = codefix.getFixes(context); const action = find(actions, action => action.description === description.message)!; - assert.isNotNull(action); + assert.exists(action); const data: string[] = []; data.push(`// ==ORIGINAL==`); From 3da6c39fec57a948daf3a6817cb872b57008cfbd Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Thu, 16 Aug 2018 08:53:48 -0700 Subject: [PATCH 02/12] Look for correct description --- src/testRunner/unittests/convertToAsyncFunction.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/testRunner/unittests/convertToAsyncFunction.ts b/src/testRunner/unittests/convertToAsyncFunction.ts index f3bdc889c34db..a1e8169e45d56 100644 --- a/src/testRunner/unittests/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/convertToAsyncFunction.ts @@ -319,7 +319,7 @@ interface String { charAt: any; } interface Array {}` }; - function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, description: DiagnosticMessage, includeLib?: boolean) { + function testConvertToAsyncFunction(caption: string, text: string, baselineFolder: string, diagnosticDescription: DiagnosticMessage, codeFixDescription: DiagnosticMessage, includeLib?: boolean) { const t = getTest(text); const selectionRange = t.ranges.get("selection")!; if (!selectionRange) { @@ -361,11 +361,11 @@ interface Array {}` }; const diagnostics = languageService.getSuggestionDiagnostics(f.path); - const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === description.message); + const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === diagnosticDescription.message); assert.exists(diagnostic); const actions = codefix.getFixes(context); - const action = find(actions, action => action.description === description.message)!; + const action = find(actions, action => action.description === codeFixDescription.message)!; assert.exists(action); const data: string[] = []; @@ -380,7 +380,7 @@ interface Array {}` const diagProgram = makeProgram({ path, content: newText }, includeLib)!; assert.isFalse(hasSyntacticDiagnostics(diagProgram)); - Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, data.join(newLineCharacter)); + Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, () => data.join(newLineCharacter)); } function makeProgram(f: { path: string, content: string }, includeLib?: boolean) { @@ -1182,7 +1182,7 @@ function [#|f|]() { }); function _testConvertToAsyncFunction(caption: string, text: string) { - testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", Diagnostics.Convert_to_async_function, /*includeLib*/ true); + testConvertToAsyncFunction(caption, text, "convertToAsyncFunction", Diagnostics.This_may_be_converted_to_an_async_function, Diagnostics.Convert_to_async_function, /*includeLib*/ true); } function _testConvertToAsyncFunctionFailed(caption: string, text: string) { From 22446133b3c87ebad050dd542c0848035bb83233 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Thu, 16 Aug 2018 08:54:18 -0700 Subject: [PATCH 03/12] Get type of whole function, not just return type --- src/services/suggestionDiagnostics.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 51a1701c351dd..23a9b82a8ae42 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -114,9 +114,13 @@ namespace ts { } function addConvertToAsyncFunctionDiagnostics(node: FunctionLikeDeclaration, checker: TypeChecker, diags: DiagnosticWithLocation[]): void { + if (isAsyncFunction(node) || !node.body) { + return; + } + + const functionType = checker.getTypeAtLocation(node); - const functionType = node.type ? checker.getTypeFromTypeNode(node.type) : undefined; - if (isAsyncFunction(node) || !node.body || !functionType) { + if (!functionType) { return; } From fbc53a2aa7614ffb5f622dae7f2a2c95b6b3a6c8 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Fri, 24 Aug 2018 09:05:13 -0700 Subject: [PATCH 04/12] Fix error introduced by rebase --- src/testRunner/unittests/convertToAsyncFunction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testRunner/unittests/convertToAsyncFunction.ts b/src/testRunner/unittests/convertToAsyncFunction.ts index a1e8169e45d56..a597b453dc52b 100644 --- a/src/testRunner/unittests/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/convertToAsyncFunction.ts @@ -380,7 +380,7 @@ interface Array {}` const diagProgram = makeProgram({ path, content: newText }, includeLib)!; assert.isFalse(hasSyntacticDiagnostics(diagProgram)); - Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, () => data.join(newLineCharacter)); + Harness.Baseline.runBaseline(`${baselineFolder}/${caption}${extension}`, data.join(newLineCharacter)); } function makeProgram(f: { path: string, content: string }, includeLib?: boolean) { From b90e13fb4b4e1fec44ce9bb43dff5aed58409cf5 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Mon, 27 Aug 2018 11:26:58 -0700 Subject: [PATCH 05/12] Add comment to clarify organization of suggestion diagnostics --- src/services/suggestionDiagnostics.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 23a9b82a8ae42..2089b540597f2 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -1,5 +1,7 @@ /* @internal */ namespace ts { + // Syntactic suggestion diagnostics should be calculated in the check function here. + // Semantic suggestion diagnostics should be calculated while typechecking, and be reported via program.getSuggestionDiagnostics. export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] { program.getSemanticDiagnostics(sourceFile, cancellationToken); const diags: DiagnosticWithLocation[] = []; From 04ec8f077471f20466d8a2c66e0e7d6f1c9f2f8d Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 11:01:27 -0700 Subject: [PATCH 06/12] Add suggestion diagnostics while doing full check --- src/compiler/checker.ts | 379 ++++++++++++++------------ src/compiler/utilities.ts | 34 +++ src/services/suggestionDiagnostics.ts | 30 -- 3 files changed, 234 insertions(+), 209 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cb3fc5614fb86..4387bff37a93b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -837,7 +837,7 @@ namespace ts { target.flags |= source.flags; if (source.valueDeclaration && (!target.valueDeclaration || - isEffectiveModuleDeclaration(target.valueDeclaration) && !isEffectiveModuleDeclaration(source.valueDeclaration))) { + isEffectiveModuleDeclaration(target.valueDeclaration) && !isEffectiveModuleDeclaration(source.valueDeclaration))) { // other kinds of value declarations take precedence over modules target.valueDeclaration = source.valueDeclaration; } @@ -1247,7 +1247,7 @@ namespace ts { case SyntaxKind.SourceFile: if (!isExternalOrCommonJsModule(location)) break; isInExternalModule = true; - // falls through + // falls through case SyntaxKind.ModuleDeclaration: const moduleExports = getSymbolOfNode(location as SourceFile | ModuleDeclaration).exports!; if (location.kind === SyntaxKind.SourceFile || isAmbientModule(location)) { @@ -1512,7 +1512,7 @@ namespace ts { // we want to check for block-scoped if (errorLocation && (meaning & SymbolFlags.BlockScopedVariable || - ((meaning & SymbolFlags.Class || meaning & SymbolFlags.Enum) && (meaning & SymbolFlags.Value) === SymbolFlags.Value))) { + ((meaning & SymbolFlags.Class || meaning & SymbolFlags.Enum) && (meaning & SymbolFlags.Value) === SymbolFlags.Value))) { const exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result); if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & SymbolFlags.Class || exportOrLocalSymbol.flags & SymbolFlags.Enum) { checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); @@ -1620,7 +1620,7 @@ namespace ts { if (isEntityNameExpression((node).expression)) { return (node).expression; } - // falls through + // falls through default: return undefined; } @@ -2395,7 +2395,7 @@ namespace ts { function getExportsOfSymbol(symbol: Symbol): SymbolTable { return symbol.flags & SymbolFlags.Class ? getResolvedMembersOrExportsOfSymbol(symbol, MembersOrExportsResolutionKind.resolvedExports) : symbol.flags & SymbolFlags.Module ? getExportsOfModule(symbol) : - symbol.exports || emptySymbols; + symbol.exports || emptySymbols; } function getExportsOfModule(moduleSymbol: Symbol): SymbolTable { @@ -2662,7 +2662,7 @@ namespace ts { if (!isExternalOrCommonJsModule(location)) { break; } - // falls through + // falls through case SyntaxKind.ModuleDeclaration: if (result = callback(getSymbolOfNode(location as ModuleDeclaration).exports!)) { return result; @@ -3762,9 +3762,9 @@ namespace ts { const dotDotDotToken = isRest ? createToken(SyntaxKind.DotDotDotToken) : undefined; const name = parameterDeclaration ? parameterDeclaration.name ? - parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) : + parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) : parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) : - cloneBindingName(parameterDeclaration.name) : + cloneBindingName(parameterDeclaration.name) : symbolName(parameterSymbol) : symbolName(parameterSymbol); const isOptional = parameterDeclaration && isOptionalParameter(parameterDeclaration) || getCheckFlags(parameterSymbol) & CheckFlags.OptionalParameter; @@ -3993,7 +3993,7 @@ namespace ts { const symbol = chain[index]; if (index === 0) { - context.flags |= NodeBuilderFlags.InInitialEntityName; + context.flags |= NodeBuilderFlags.InInitialEntityName; } const symbolName = getNameOfSymbolAsWritten(symbol, context); context.approximateLength += symbolName.length + 1; @@ -4200,10 +4200,10 @@ namespace ts { if (context && symbol.escapedName === InternalSymbolName.Default && !(context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope) && // If it's not the first part of an entity name, it must print as `default` (!(context.flags & NodeBuilderFlags.InInitialEntityName) || - // if the symbol is synthesized, it will only be referenced externally it must print as `default` - !symbol.declarations || - // if not in the same binding context (source file, module declaration), it must print as `default` - (context.enclosingDeclaration && findAncestor(symbol.declarations[0], isDefaultBindingContext) !== findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) { + // if the symbol is synthesized, it will only be referenced externally it must print as `default` + !symbol.declarations || + // if not in the same binding context (source file, module declaration), it must print as `default` + (context.enclosingDeclaration && findAncestor(symbol.declarations[0], isDefaultBindingContext) !== findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) { return "default"; } if (symbol.declarations && symbol.declarations.length) { @@ -4263,7 +4263,7 @@ namespace ts { // If the binding pattern is empty, this variable declaration is not visible return false; } - // falls through + // falls through case SyntaxKind.ModuleDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: @@ -4294,8 +4294,8 @@ namespace ts { // Private/protected properties/methods are not visible return false; } - // Public properties/methods are visible if its parents are visible, so: - // falls through + // Public properties/methods are visible if its parents are visible, so: + // falls through case SyntaxKind.Constructor: case SyntaxKind.ConstructSignature: @@ -4441,7 +4441,7 @@ namespace ts { } function getDeclarationContainer(node: Node): Node { - return findAncestor(getRootDeclaration(node), node => { + return findAncestor(getRootDeclaration(node), node => { switch (node.kind) { case SyntaxKind.VariableDeclaration: case SyntaxKind.VariableDeclarationList: @@ -4576,7 +4576,7 @@ namespace ts { const nameType = isLate ? checkComputedPropertyName(name as ComputedPropertyName) as LiteralType | UniqueESSymbolType : undefined; const text = isLate ? getLateBoundNameFromType(nameType!) : isWellKnown ? getPropertyNameForKnownSymbolName(idText(((name as ComputedPropertyName).expression as PropertyAccessExpression).name)) : - getTextOfPropertyName(name); + getTextOfPropertyName(name); // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) { @@ -5140,10 +5140,10 @@ namespace ts { type = tryGetTypeFromEffectiveTypeNode(declaration) || checkObjectLiteralMethod(declaration, CheckMode.Normal); } else if (isParameter(declaration) - || isPropertyDeclaration(declaration) - || isPropertySignature(declaration) - || isVariableDeclaration(declaration) - || isBindingElement(declaration)) { + || isPropertyDeclaration(declaration) + || isPropertySignature(declaration) + || isVariableDeclaration(declaration) + || isBindingElement(declaration)) { type = getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true); } else { @@ -5284,7 +5284,7 @@ namespace ts { return anyType; } else if (declaration.kind === SyntaxKind.BinaryExpression || - declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) { + declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) { return getWidenedTypeFromJSPropertyAssignments(symbol); } else if (symbol.flags & SymbolFlags.ValueModule && declaration && isSourceFile(declaration) && declaration.commonJsModuleIndicator) { @@ -6216,7 +6216,7 @@ namespace ts { const isStatic = resolutionKind === MembersOrExportsResolutionKind.resolvedExports; const earlySymbols = !isStatic ? symbol.members : symbol.flags & SymbolFlags.Module ? getExportsOfModuleWorker(symbol) : - symbol.exports; + symbol.exports; // In the event we recursively resolve the members/exports of the symbol, we // set the initial value of resolvedMembers/resolvedExports to the early-bound @@ -6722,7 +6722,7 @@ namespace ts { // mode, if the underlying property is optional we remove 'undefined' from the type. prop.type = strictNullChecks && isOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) : strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : - propType; + propType; if (modifiersProp) { prop.syntheticOrigin = modifiersProp; prop.declarations = modifiersProp.declarations; @@ -6922,8 +6922,8 @@ namespace ts { function getConstraintOfType(type: InstantiableType | UnionOrIntersectionType): Type | undefined { return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(type) : type.flags & TypeFlags.IndexedAccess ? getConstraintOfIndexedAccess(type) : - type.flags & TypeFlags.Conditional ? getConstraintOfConditionalType(type) : - getBaseConstraintOfType(type); + type.flags & TypeFlags.Conditional ? getConstraintOfConditionalType(type) : + getBaseConstraintOfType(type); } function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type | undefined { @@ -7191,13 +7191,13 @@ namespace ts { const t = type.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(type) || emptyObjectType : type; return getObjectFlags(t) & ObjectFlags.Mapped ? getApparentTypeOfMappedType(t) : t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t) : - t.flags & TypeFlags.StringLike ? globalStringType : - t.flags & TypeFlags.NumberLike ? globalNumberType : - t.flags & TypeFlags.BooleanLike ? globalBooleanType : - t.flags & TypeFlags.ESSymbolLike ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : - t.flags & TypeFlags.NonPrimitive ? emptyObjectType : - t.flags & TypeFlags.Index ? keyofConstraintType : - t; + t.flags & TypeFlags.StringLike ? globalStringType : + t.flags & TypeFlags.NumberLike ? globalNumberType : + t.flags & TypeFlags.BooleanLike ? globalBooleanType : + t.flags & TypeFlags.ESSymbolLike ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : + t.flags & TypeFlags.NonPrimitive ? emptyObjectType : + t.flags & TypeFlags.Index ? keyofConstraintType : + t; } function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined { @@ -7763,8 +7763,8 @@ namespace ts { } let type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper!) : signature.unionSignatures ? getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype) : - getReturnTypeFromAnnotation(signature.declaration!) || - (nodeIsMissing((signature.declaration).body) ? anyType : getReturnTypeFromBody(signature.declaration)); + getReturnTypeFromAnnotation(signature.declaration!) || + (nodeIsMissing((signature.declaration).body) ? anyType : getReturnTypeFromBody(signature.declaration)); if (!popTypeResolution()) { if (signature.declaration) { const typeNode = getEffectiveReturnTypeNode(signature.declaration); @@ -8090,11 +8090,11 @@ namespace ts { const missingAugmentsTag = isJs && node.parent.kind !== SyntaxKind.JSDocAugmentsTag; const diag = minTypeArgumentCount === typeParameters.length ? missingAugmentsTag - ? Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag - : Diagnostics.Generic_type_0_requires_1_type_argument_s - : missingAugmentsTag - ? Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag - : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments; + ? Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag + : Diagnostics.Generic_type_0_requires_1_type_argument_s + : missingAugmentsTag + ? Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag + : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments; const typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType); error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length); if (!isJs) { @@ -8136,12 +8136,12 @@ namespace ts { const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { error(node, - minTypeArgumentCount === typeParameters.length - ? Diagnostics.Generic_type_0_requires_1_type_argument_s - : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, - symbolToString(symbol), - minTypeArgumentCount, - typeParameters.length); + minTypeArgumentCount === typeParameters.length + ? Diagnostics.Generic_type_0_requires_1_type_argument_s + : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, + symbolToString(symbol), + minTypeArgumentCount, + typeParameters.length); return errorType; } return getTypeAliasInstantiation(symbol, typeArguments); @@ -8262,7 +8262,7 @@ namespace ts { function getImpliedConstraint(typeVariable: TypeVariable, checkNode: TypeNode, extendsNode: TypeNode): Type | undefined { return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, (checkNode).elementTypes[0], (extendsNode).elementTypes[0]) : getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) : - undefined; + undefined; } function getConstrainedTypeVariable(typeVariable: TypeVariable, node: Node) { @@ -8902,8 +8902,8 @@ namespace ts { } else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type) && !(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && - type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && - containsIdenticalType(typeSet, type))) { + type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && + containsIdenticalType(typeSet, type))) { typeSet.push(type); } } @@ -8942,8 +8942,8 @@ namespace ts { if (!containsType(u.types, type)) { const primitive = type.flags & TypeFlags.StringLiteral ? stringType : type.flags & TypeFlags.NumberLiteral ? numberType : - type.flags & TypeFlags.UniqueESSymbol ? esSymbolType : - undefined; + type.flags & TypeFlags.UniqueESSymbol ? esSymbolType : + undefined; if (!primitive || !containsType(u.types, primitive)) { return false; } @@ -9087,7 +9087,7 @@ namespace ts { const name = prop.valueDeclaration && getNameOfDeclaration(prop.valueDeclaration); type = name && isNumericLiteral(name) ? getLiteralType(+name.text) : name && name.kind === SyntaxKind.ComputedPropertyName && isNumericLiteral(name.expression) ? getLiteralType(+name.expression.text) : - getLiteralType(symbolName(prop)); + getLiteralType(symbolName(prop)); } if (type && type.flags & include) { return type; @@ -9108,14 +9108,14 @@ namespace ts { function getIndexType(type: Type, stringsOnly = keyofStringsOnly): Type { return type.flags & TypeFlags.Union ? getIntersectionType(map((type).types, t => getIndexType(t, stringsOnly))) : type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly))) : - maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : - getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : - type === wildcardType ? wildcardType : - type.flags & TypeFlags.Any ? keyofConstraintType : - stringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : - getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : - getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : - getLiteralTypeFromPropertyNames(type, TypeFlags.StringOrNumberLiteralOrUnique); + maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : + getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : + type === wildcardType ? wildcardType : + type.flags & TypeFlags.Any ? keyofConstraintType : + stringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : + getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : + getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : + getLiteralTypeFromPropertyNames(type, TypeFlags.StringOrNumberLiteralOrUnique); } function getExtractStringType(type: Type) { @@ -9776,7 +9776,7 @@ namespace ts { function getRegularTypeOfLiteralType(type: Type): Type { return type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral ? (type).regularType : type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getRegularTypeOfLiteralType)) : - type; + type; } function getLiteralType(value: string | number, enumId?: number, symbol?: Symbol) { @@ -9981,7 +9981,7 @@ namespace ts { Debug.assert(targets === undefined || sources.length === targets.length); return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : - makeArrayTypeMapper(sources, targets); + makeArrayTypeMapper(sources, targets); } function createTypeEraser(sources: ReadonlyArray): TypeMapper { @@ -10218,8 +10218,8 @@ namespace ts { const replacementMapper = createReplacementMapper(typeVariable, t, mapper); return isArrayType(t) ? createArrayType(instantiateMappedTypeTemplate(type, numberType, /*isOptional*/ true, replacementMapper)) : isReadonlyArrayType(t) ? createReadonlyArrayType(instantiateMappedTypeTemplate(type, numberType, /*isOptional*/ true, replacementMapper)) : - isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) : - instantiateAnonymousType(type, replacementMapper); + isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) : + instantiateAnonymousType(type, replacementMapper); } return t; }); @@ -10235,7 +10235,7 @@ namespace ts { const modifiers = getMappedTypeModifiers(mappedType); const newMinLength = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : modifiers & MappedTypeModifiers.ExcludeOptional ? getTypeReferenceArity(tupleType) - (tupleType.target.hasRestElement ? 1 : 0) : - minLength; + minLength; return createTupleType(elementTypes, newMinLength, tupleType.target.hasRestElement, tupleType.target.associatedNames); } @@ -10245,7 +10245,7 @@ namespace ts { const modifiers = getMappedTypeModifiers(type); return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) : strictNullChecks && modifiers & MappedTypeModifiers.ExcludeOptional && isOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : - propType; + propType; } function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType { @@ -10491,10 +10491,10 @@ namespace ts { function isTypeDerivedFrom(source: Type, target: Type): boolean { return source.flags & TypeFlags.Union ? every((source).types, t => isTypeDerivedFrom(t, target)) : target.flags & TypeFlags.Union ? some((target).types, t => isTypeDerivedFrom(source, t)) : - source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) : - target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) : - hasBaseType(source, getTargetType(target)); - } + source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) : + target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) : + hasBaseType(source, getTargetType(target)); + } /** * This is *not* a bi-directional relationship. @@ -10880,9 +10880,9 @@ namespace ts { function isEmptyObjectType(type: Type): boolean { return type.flags & TypeFlags.Object ? isEmptyResolvedType(resolveStructuredTypeMembers(type)) : type.flags & TypeFlags.NonPrimitive ? true : - type.flags & TypeFlags.Union ? some((type).types, isEmptyObjectType) : - type.flags & TypeFlags.Intersection ? every((type).types, isEmptyObjectType) : - false; + type.flags & TypeFlags.Union ? some((type).types, isEmptyObjectType) : + type.flags & TypeFlags.Intersection ? every((type).types, isEmptyObjectType) : + false; } function isEnumTypeRelatedTo(sourceSymbol: Symbol, targetSymbol: Symbol, errorReporter?: ErrorReporter) { @@ -11864,7 +11864,7 @@ namespace ts { // that S and T are contra-variant whereas X and Y are co-variant. function mappedTypeRelatedTo(source: MappedType, target: MappedType, reportErrors: boolean): Ternary { const modifiersRelated = relation === comparableRelation || (relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) : - getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target)); + getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target)); if (modifiersRelated) { let result: Ternary; if (result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { @@ -12658,31 +12658,31 @@ namespace ts { function isLiteralType(type: Type): boolean { return type.flags & TypeFlags.Boolean ? true : type.flags & TypeFlags.Union ? type.flags & TypeFlags.EnumLiteral ? true : every((type).types, isUnitType) : - isUnitType(type); + isUnitType(type); } function getBaseTypeOfLiteralType(type: Type): Type { return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(type) : type.flags & TypeFlags.StringLiteral ? stringType : - type.flags & TypeFlags.NumberLiteral ? numberType : - type.flags & TypeFlags.BooleanLiteral ? booleanType : - type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getBaseTypeOfLiteralType)) : - type; + type.flags & TypeFlags.NumberLiteral ? numberType : + type.flags & TypeFlags.BooleanLiteral ? booleanType : + type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getBaseTypeOfLiteralType)) : + type; } function getWidenedLiteralType(type: Type): Type { return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(type) : type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.FreshLiteral ? stringType : - type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType : - type.flags & TypeFlags.BooleanLiteral ? booleanType : - type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getWidenedLiteralType)) : - type; + type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType : + type.flags & TypeFlags.BooleanLiteral ? booleanType : + type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getWidenedLiteralType)) : + type; } function getWidenedUniqueESSymbolType(type: Type): Type { return type.flags & TypeFlags.UniqueESSymbol ? esSymbolType : type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getWidenedUniqueESSymbolType)) : - type; + type; } function getWidenedLiteralLikeTypeForContextualType(type: Type, contextualType: Type | undefined) { @@ -12722,9 +12722,9 @@ namespace ts { function getFalsyFlags(type: Type): TypeFlags { return type.flags & TypeFlags.Union ? getFalsyFlagsOfTypes((type).types) : type.flags & TypeFlags.StringLiteral ? (type).value === "" ? TypeFlags.StringLiteral : 0 : - type.flags & TypeFlags.NumberLiteral ? (type).value === 0 ? TypeFlags.NumberLiteral : 0 : - type.flags & TypeFlags.BooleanLiteral ? type === falseType ? TypeFlags.BooleanLiteral : 0 : - type.flags & TypeFlags.PossiblyFalsy; + type.flags & TypeFlags.NumberLiteral ? (type).value === 0 ? TypeFlags.NumberLiteral : 0 : + type.flags & TypeFlags.BooleanLiteral ? type === falseType ? TypeFlags.BooleanLiteral : 0 : + type.flags & TypeFlags.PossiblyFalsy; } function removeDefinitelyFalsyTypes(type: Type): Type { @@ -12740,11 +12740,11 @@ namespace ts { function getDefinitelyFalsyPartOfType(type: Type): Type { return type.flags & TypeFlags.String ? emptyStringType : type.flags & TypeFlags.Number ? zeroType : - type.flags & TypeFlags.Boolean || type === falseType ? falseType : - type.flags & (TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null) || - type.flags & TypeFlags.StringLiteral && (type).value === "" || - type.flags & TypeFlags.NumberLiteral && (type).value === 0 ? type : - neverType; + type.flags & TypeFlags.Boolean || type === falseType ? falseType : + type.flags & (TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null) || + type.flags & TypeFlags.StringLiteral && (type).value === "" || + type.flags & TypeFlags.NumberLiteral && (type).value === 0 ? type : + neverType; } /** @@ -12756,8 +12756,8 @@ namespace ts { const missing = (flags & ~type.flags) & (TypeFlags.Undefined | TypeFlags.Null); return missing === 0 ? type : missing === TypeFlags.Undefined ? getUnionType([type, undefinedType]) : - missing === TypeFlags.Null ? getUnionType([type, nullType]) : - getUnionType([type, undefinedType, nullType]); + missing === TypeFlags.Null ? getUnionType([type, nullType]) : + getUnionType([type, undefinedType, nullType]); } function getOptionalType(type: Type): Type { @@ -13053,8 +13053,8 @@ namespace ts { const targetHasRest = hasEffectiveRestParameter(target); const maxCount = sourceHasRest && targetHasRest ? Math.max(sourceCount, targetCount) : sourceHasRest ? targetCount : - targetHasRest ? sourceCount : - Math.min(sourceCount, targetCount); + targetHasRest ? sourceCount : + Math.min(sourceCount, targetCount); const targetGenericRestType = getGenericRestType(target); const paramCount = targetGenericRestType ? Math.min(targetCount - 1, maxCount) : maxCount; for (let i = 0; i < paramCount; i++) { @@ -13244,7 +13244,7 @@ namespace ts { function getTypeFromInference(inference: InferenceInfo) { return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : inference.contraCandidates ? getIntersectionType(inference.contraCandidates) : - emptyObjectType; + emptyObjectType; } function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) { @@ -13657,7 +13657,7 @@ namespace ts { (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); const baseCandidates = primitiveConstraint ? sameMap(candidates, getRegularTypeOfLiteralType) : widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : - candidates; + candidates; // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if // union types were requested or if all inferences were made from the return type position, infer a // union type. Otherwise, infer a common supertype. @@ -13811,7 +13811,7 @@ namespace ts { } } else { - return "" + parent.elements.indexOf(element); + return "" + parent.elements.indexOf(element); } } @@ -13835,7 +13835,7 @@ namespace ts { const t = target as PropertyAccessExpression; if (t.name.escapedText !== getBindingElementNameText(source as BindingElement)) return false; if (source.parent.parent.kind === SyntaxKind.BindingElement && isMatchingReference(source.parent.parent, t.expression)) { - return true; + return true; } if (source.parent.parent.kind === SyntaxKind.VariableDeclaration) { const maybeId = (source.parent.parent as VariableDeclaration).initializer; @@ -13848,7 +13848,7 @@ namespace ts { function getAccessedPropertyName(access: PropertyAccessExpression | ElementAccessExpression): __String | undefined { return isPropertyAccessExpression(access) ? access.name.escapedText : isStringLiteral(access.argumentExpression) || isNumericLiteral(access.argumentExpression) ? escapeLeadingUnderscores(access.argumentExpression.text) : - undefined; + undefined; } function containsMatchingReference(source: Node, target: Node) { @@ -15328,7 +15328,7 @@ namespace ts { // declaration container are the same). const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.AnyOrUnknown) !== 0 || - isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || + isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || node.parent.kind === SyntaxKind.NonNullExpression || declaration.kind === SyntaxKind.VariableDeclaration && (declaration).exclamationToken || declaration.flags & NodeFlags.Ambient; @@ -15593,7 +15593,7 @@ namespace ts { // * /** @constructor */ function [name]() { ... } // * /** @constructor */ var x = function() { ... } else if ((container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) && - getJSDocClassTag(container)) { + getJSDocClassTag(container)) { const classType = getJavascriptClassType(container.symbol); if (classType) { return getFlowTypeOfReference(node, classType); @@ -16334,7 +16334,7 @@ namespace ts { return getContextualTypeForReturnExpression(node); case SyntaxKind.YieldExpression: return getContextualTypeForYieldOperand(parent); - case SyntaxKind.CallExpression: + case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: return getContextualTypeForArgument(parent, node); case SyntaxKind.TypeAssertionExpression: @@ -16825,7 +16825,7 @@ namespace ts { isObjectLiteralMethod(memberDecl)) { let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) : memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(memberDecl.name, checkMode) : - checkObjectLiteralMethod(memberDecl, checkMode); + checkObjectLiteralMethod(memberDecl, checkMode); if (isInJSFile) { const jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl); if (jsDocType) { @@ -17763,12 +17763,12 @@ namespace ts { return false; } - /** - * Check whether the given attributes of JSX opening-like element is assignable to the tagName attributes. - * Get the attributes type of the opening-like element through resolving the tagName, "target attributes" - * Check assignablity between given attributes property, "source attributes", and the "target attributes" - * @param openingLikeElement an opening-like JSX element to check its JSXAttributes - */ + /** + * Check whether the given attributes of JSX opening-like element is assignable to the tagName attributes. + * Get the attributes type of the opening-like element through resolving the tagName, "target attributes" + * Check assignablity between given attributes property, "source attributes", and the "target attributes" + * @param openingLikeElement an opening-like JSX element to check its JSXAttributes + */ function checkJsxAttributesAssignableToTagNameAttributes(openingLikeElement: JsxOpeningLikeElement, checkMode: CheckMode | undefined) { // The function involves following steps: // 1. Figure out expected attributes type by resolving tagName of the JSX opening-like element, targetAttributesType. @@ -18681,7 +18681,7 @@ namespace ts { getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) : instantiatedType; const inferenceTargetType = getReturnTypeOfSignature(signature); - // Inferences made from return types have lower priority than all other inferences. + // Inferences made from return types have lower priority than all other inferences. inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType); } } @@ -18992,7 +18992,7 @@ namespace ts { const hasRestParameter = some(signatures, hasEffectiveRestParameter); const paramRange = hasRestParameter ? min : min < max ? min + "-" + max : - min; + min; const hasSpreadArgument = getSpreadArgumentIndex(args) > -1; if (argCount <= max && hasSpreadArgument) { argCount--; @@ -19001,7 +19001,7 @@ namespace ts { if (hasRestParameter || hasSpreadArgument) { const error = hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more : hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 : - Diagnostics.Expected_0_arguments_but_got_1_or_more; + Diagnostics.Expected_0_arguments_but_got_1_or_more; return createDiagnosticForNode(node, error, paramRange, argCount); } if (min < argCount && argCount < max) { @@ -19598,7 +19598,7 @@ namespace ts { invocationErrorRecovery(apparentType, kind, error(node, kind === SignatureKind.Call ? Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures : Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature - , typeToString(apparentType))); + , typeToString(apparentType))); } function invocationErrorRecovery(apparentType: Type, kind: SignatureKind, diagnostic: Diagnostic) { @@ -19800,8 +19800,8 @@ namespace ts { // If the symbol of the node has members, treat it like a constructor. const symbol = isFunctionDeclaration(node) || isFunctionExpression(node) ? getSymbolOfNode(node) : - isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) : - undefined; + isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) : + undefined; return !!symbol && symbol.members !== undefined; } @@ -19836,8 +19836,8 @@ namespace ts { const decl = symbol.valueDeclaration; const assignmentSymbol = decl && decl.parent && (isFunctionDeclaration(decl) && getSymbolOfNode(decl) || - isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) || - isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent)); + isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) || + isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent)); if (assignmentSymbol) { const prototype = forEach(assignmentSymbol.declarations, getAssignedJavascriptPrototype); if (prototype) { @@ -20407,7 +20407,7 @@ namespace ts { if (isUnitType(type)) { let contextualType = !contextualSignature ? undefined : contextualSignature === getSignatureFromDeclaration(func) ? type : - getReturnTypeOfSignature(contextualSignature); + getReturnTypeOfSignature(contextualSignature); if (contextualType) { switch (functionFlags & FunctionFlags.AsyncGenerator) { case FunctionFlags.AsyncGenerator: @@ -20682,6 +20682,8 @@ namespace ts { getReturnTypeOfSignature(getSignatureFromDeclaration(node)); } + checkForAsyncCodeFix(node); + if (node.body.kind === SyntaxKind.Block) { checkSourceElement(node.body); } @@ -20840,7 +20842,7 @@ namespace ts { const facts = getTypeFacts(operandType) & (TypeFacts.Truthy | TypeFacts.Falsy); return facts === TypeFacts.Truthy ? falseType : facts === TypeFacts.Falsy ? trueType : - booleanType; + booleanType; case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), @@ -21052,7 +21054,7 @@ namespace ts { const propName = "" + elementIndex as __String; const type = isTypeAny(sourceType) ? sourceType : isTupleLikeType(sourceType) ? getTupleElementType(sourceType, elementIndex) : - elementType; + elementType; if (type) { return checkDestructuringAssignment(element, type, checkMode); } @@ -21173,7 +21175,7 @@ namespace ts { return false; } return isSideEffectFree((node as BinaryExpression).left) && - isSideEffectFree((node as BinaryExpression).right); + isSideEffectFree((node as BinaryExpression).right); case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.PostfixUnaryExpression: @@ -21288,8 +21290,8 @@ namespace ts { resultType = numberType; } else if (isTypeAssignableToKind(leftType, TypeFlags.StringLike, /*strict*/ true) || isTypeAssignableToKind(rightType, TypeFlags.StringLike, /*strict*/ true)) { - // If one or both operands are of the String primitive type, the result is of the String primitive type. - resultType = stringType; + // If one or both operands are of the String primitive type, the result is of the String primitive type. + resultType = stringType; } else if (isTypeAny(leftType) || isTypeAny(rightType)) { // Otherwise, the result is of type Any. @@ -21478,7 +21480,7 @@ namespace ts { case SyntaxKind.ExclamationEqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: return error(errNode, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "true", leftStr, rightStr); - } + } return undefined; } } @@ -21789,7 +21791,7 @@ namespace ts { (node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).expression === node) || (node.parent.kind === SyntaxKind.ElementAccessExpression && (node.parent).expression === node) || ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node) || - (node.parent.kind === SyntaxKind.TypeQuery && (node.parent).exprName === node)); + (node.parent.kind === SyntaxKind.TypeQuery && (node.parent).exprName === node)); if (!ok) { error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query); @@ -21842,7 +21844,7 @@ namespace ts { if ((node).expression.kind === SyntaxKind.ImportKeyword) { return checkImportCallExpression(node); } - /* falls through */ + /* falls through */ case SyntaxKind.NewExpression: return checkCallExpression(node); case SyntaxKind.TaggedTemplateExpression: @@ -22006,7 +22008,7 @@ namespace ts { let hasReportedError = false; for (const { name } of parent.parameters) { if (isBindingPattern(name) && - checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) { + checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) { hasReportedError = true; break; } @@ -22147,6 +22149,19 @@ namespace ts { } } + function checkForAsyncCodeFix(node: FunctionDeclaration | FunctionExpression | MethodDeclaration | ArrowFunction) { + if (!isAsyncFunction(node)) { + const returnType = getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + if (getPromisedTypeOfPromise(returnType)) { + const returnStatements = getReturnStatementsWithPromiseHandlers(node); + if (returnStatements.length > 0) { + const nodeToReport = isVariableDeclaration(node.parent) ? node.parent.name : node; + errorOrSuggestion(/*isError*/ false, nodeToReport, Diagnostics.This_may_be_converted_to_an_async_function); + } + } + } + } + function checkClassForDuplicateDeclarations(node: ClassLikeDeclaration) { const enum Declaration { Getter = 1, @@ -22992,7 +23007,7 @@ namespace ts { return DeclarationSpaces.ExportValue; } d = (d as ExportAssignment).expression; - /* falls through */ + /* falls through */ // The below options all declare an Alias, which is allowed to merge with other values within the importing module case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.NamespaceImport: @@ -23557,8 +23572,8 @@ namespace ts { node.typeExpression && node.typeExpression.type && !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) { error(node.name, - Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, - idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name)); + Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, + idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name)); } } } @@ -23650,18 +23665,24 @@ namespace ts { checkAllCodePathsInNonVoidFunctionReturnOrThrow(node, returnOrPromisedType); } - if (produceDiagnostics && !getEffectiveReturnTypeNode(node)) { - // Report an implicit any error if there is no body, no explicit return type, and node is not a private method - // in an ambient context - if (noImplicitAny && nodeIsMissing(body) && !isPrivateWithinAmbient(node)) { - reportImplicitAnyError(node, anyType); + if (produceDiagnostics) { + if (!getEffectiveReturnTypeNode(node)) { + // Report an implicit any error if there is no body, no explicit return type, and node is not a private method + // in an ambient context + if (noImplicitAny && nodeIsMissing(body) && !isPrivateWithinAmbient(node)) { + reportImplicitAnyError(node, anyType); + } + + if (functionFlags & FunctionFlags.Generator && nodeIsPresent(body)) { + // A generator with a body and no type annotation can still cause errors. It can error if the + // yielded values have no common supertype, or it can give an implicit any error if it has no + // yielded values. The only way to trigger these errors is to try checking its return type. + getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + } } - if (functionFlags & FunctionFlags.Generator && nodeIsPresent(body)) { - // A generator with a body and no type annotation can still cause errors. It can error if the - // yielded values have no common supertype, or it can give an implicit any error if it has no - // yielded values. The only way to trigger these errors is to try checking its return type. - getReturnTypeOfSignature(getSignatureFromDeclaration(node)); + if (node.kind !== SyntaxKind.MethodSignature) { + checkForAsyncCodeFix(node); } } @@ -24204,7 +24225,7 @@ namespace ts { const enclosingContainer = getEnclosingBlockScopeContainer(symbol.valueDeclaration); if (enclosingContainer === func) { if (symbol.valueDeclaration.kind === SyntaxKind.Parameter || - symbol.valueDeclaration.kind === SyntaxKind.BindingElement) { + symbol.valueDeclaration.kind === SyntaxKind.BindingElement) { // it is ok to reference parameter in initializer if either // - parameter is located strictly on the left of current parameter declaration if (symbol.valueDeclaration.pos < node.pos) { @@ -24221,9 +24242,9 @@ namespace ts { // computed property names/initializers in instance property declaration of class like entities // are executed in constructor and thus deferred (current.parent.kind === SyntaxKind.PropertyDeclaration && - !(hasModifier(current.parent, ModifierFlags.Static)) && - isClassLike(current.parent.parent)); - })) { + !(hasModifier(current.parent, ModifierFlags.Static)) && + isClassLike(current.parent.parent)); + })) { return; } // fall through to report error @@ -25059,16 +25080,16 @@ namespace ts { // Grammar checking if (!checkGrammarStatementInAmbientContext(node)) { findAncestor(node.parent, - current => { - if (isFunctionLike(current)) { - return "quit"; - } - if (current.kind === SyntaxKind.LabeledStatement && (current).label.escapedText === node.label.escapedText) { - grammarErrorOnNode(node.label, Diagnostics.Duplicate_label_0, getTextOfNode(node.label)); - return true; - } - return false; - }); + current => { + if (isFunctionLike(current)) { + return "quit"; + } + if (current.kind === SyntaxKind.LabeledStatement && (current).label.escapedText === node.label.escapedText) { + grammarErrorOnNode(node.label, Diagnostics.Duplicate_label_0, getTextOfNode(node.label)); + return true; + } + return false; + }); } // ensure that label is unique @@ -25195,8 +25216,8 @@ namespace ts { let errorNode: Node | undefined; if (propDeclaration && name && (propDeclaration.kind === SyntaxKind.BinaryExpression || - name.kind === SyntaxKind.ComputedPropertyName || - prop.parent === containingType.symbol)) { + name.kind === SyntaxKind.ComputedPropertyName || + prop.parent === containingType.symbol)) { errorNode = propDeclaration; } else if (indexDeclaration) { @@ -25902,7 +25923,7 @@ namespace ts { return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression && isConstantMemberAccess((node).expression) || node.kind === SyntaxKind.ElementAccessExpression && isConstantMemberAccess((node).expression) && - (node).argumentExpression.kind === SyntaxKind.StringLiteral; + (node).argumentExpression.kind === SyntaxKind.StringLiteral; } function checkEnumDeclaration(node: EnumDeclaration) { @@ -26119,7 +26140,7 @@ namespace ts { } break; } - // falls through + // falls through case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.FunctionDeclaration: @@ -26463,7 +26484,7 @@ namespace ts { function isNotOverload(declaration: Declaration): boolean { return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) || - !!(declaration as FunctionDeclaration).body; + !!(declaration as FunctionDeclaration).body; } function checkSourceElement(node: Node | undefined): void { @@ -26552,7 +26573,7 @@ namespace ts { return checkJSDocParameterTag(node as JSDocParameterTag); case SyntaxKind.JSDocFunctionType: checkSignatureDeclaration(node as JSDocFunctionType); - // falls through + // falls through case SyntaxKind.JSDocNonNullableType: case SyntaxKind.JSDocNullableType: case SyntaxKind.JSDocAllType: @@ -27257,7 +27278,7 @@ namespace ts { if (isInExpressionContext(node)) { return checkExpression(node as Expression).symbol; } - // falls through + // falls through case SyntaxKind.ThisType: return getTypeFromThisTypeNode(node as ThisExpression | ThisTypeNode).symbol; @@ -27286,7 +27307,7 @@ namespace ts { ) { return resolveExternalModuleName(node, node); } - // falls through + // falls through case SyntaxKind.NumericLiteral: // index access @@ -27506,7 +27527,7 @@ namespace ts { const { leftSpread, rightSpread, syntheticOrigin } = symbol as TransientSymbol; return leftSpread ? [leftSpread, rightSpread!] : syntheticOrigin ? [syntheticOrigin] - : singleElementArray(tryGetAliasTarget(symbol)); + : singleElementArray(tryGetAliasTarget(symbol)); } return undefined; } @@ -27514,7 +27535,7 @@ namespace ts { let target: Symbol | undefined; let next: Symbol | undefined = symbol; while (next = getSymbolLinks(next).target) { - target = next; + target = next; } return target; } @@ -27706,8 +27727,8 @@ namespace ts { case SyntaxKind.ExportAssignment: return (node).expression && (node).expression.kind === SyntaxKind.Identifier - ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) - : true; + ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) + : true; } return false; } @@ -28779,15 +28800,15 @@ namespace ts { if (type.flags & TypeFlags.String || type.flags & TypeFlags.Number) { return grammarErrorOnNode(parameter.name, - Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, - getTextOfNode(parameter.name), - typeToString(type), - typeToString(getTypeFromTypeNode(node.type!))); + Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, + getTextOfNode(parameter.name), + typeToString(type), + typeToString(getTypeFromTypeNode(node.type!))); } if (type.flags & TypeFlags.Union && allTypesAssignableToKind(type, TypeFlags.StringLiteral, /*strict*/ true)) { return grammarErrorOnNode(parameter.name, - Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead); + Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead); } return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_or_number); @@ -28992,7 +29013,7 @@ namespace ts { if (name.kind === SyntaxKind.NumericLiteral) { checkGrammarNumericLiteral(name); } - // falls through + // falls through case SyntaxKind.MethodDeclaration: currentKind = Flags.Property; break; @@ -29129,9 +29150,9 @@ namespace ts { } else if (!doesAccessorHaveCorrectParameterCount(accessor)) { return grammarErrorOnNode(accessor.name, - kind === SyntaxKind.GetAccessor ? - Diagnostics.A_get_accessor_cannot_have_parameters : - Diagnostics.A_set_accessor_must_have_exactly_one_parameter); + kind === SyntaxKind.GetAccessor ? + Diagnostics.A_get_accessor_cannot_have_parameters : + Diagnostics.A_set_accessor_must_have_exactly_one_parameter); } else if (kind === SyntaxKind.SetAccessor) { if (accessor.type) { @@ -29579,7 +29600,7 @@ namespace ts { node.kind === SyntaxKind.ExportAssignment || node.kind === SyntaxKind.NamespaceExportDeclaration || hasModifier(node, ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) { - return false; + return false; } return grammarErrorOnFirstToken(node, Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index d04f921ec959d..3322fad55a1f4 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4870,6 +4870,40 @@ namespace ts { return unescapeLeadingUnderscores(symbol.escapedName); } + export function getReturnStatementsWithPromiseHandlers(node: Node): Node[] { + const returnStatements: Node[] = []; + if (isFunctionLike(node)) { + forEachChild(node, visit); + } + else { + visit(node); + } + + function visit(child: Node) { + if (isFunctionLike(child)) { + return; + } + + if (isReturnStatement(child)) { + forEachChild(child, addHandlers); + } + + function addHandlers(returnChild: Node) { + if (isPromiseHandler(returnChild)) { + returnStatements.push(child as ReturnStatement); + } + } + + forEachChild(child, visit); + } + return returnStatements; + } + + function isPromiseHandler(node: Node): boolean { + return (isCallExpression(node) && isPropertyAccessExpression(node.expression) && + (node.expression.name.escapedText === "then" || node.expression.name.escapedText === "catch")); + } + /** * A JSDocTypedef tag has an _optional_ name field - if a name is not directly present, we should * attempt to draw the name from the node the declaration is on (as that declaration is what its' symbol diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index 2089b540597f2..bd1b698dca64c 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -5,7 +5,6 @@ namespace ts { export function computeSuggestionDiagnostics(sourceFile: SourceFile, program: Program, cancellationToken: CancellationToken): DiagnosticWithLocation[] { program.getSemanticDiagnostics(sourceFile, cancellationToken); const diags: DiagnosticWithLocation[] = []; - const checker = program.getDiagnosticsProducingTypeChecker(); if (sourceFile.commonJsModuleIndicator && (programContainsEs6Modules(program) || compilerOptionsIndicateEs6Modules(program.getCompilerOptions())) && @@ -71,9 +70,6 @@ namespace ts { } } - if (isFunctionLikeDeclaration(node)) { - addConvertToAsyncFunctionDiagnostics(node, checker, diags); - } node.forEachChild(check); } } @@ -115,32 +111,6 @@ namespace ts { } } - function addConvertToAsyncFunctionDiagnostics(node: FunctionLikeDeclaration, checker: TypeChecker, diags: DiagnosticWithLocation[]): void { - if (isAsyncFunction(node) || !node.body) { - return; - } - - const functionType = checker.getTypeAtLocation(node); - - if (!functionType) { - return; - } - - const callSignatures = checker.getSignaturesOfType(functionType, SignatureKind.Call); - const returnType = callSignatures.length ? checker.getReturnTypeOfSignature(callSignatures[0]) : undefined; - - if (!returnType || !checker.getPromisedTypeOfPromise(returnType)) { - return; - } - - // collect all the return statements - // check that a property access expression exists in there and that it is a handler - const returnStatements = getReturnStatementsWithPromiseHandlers(node); - if (returnStatements.length > 0) { - diags.push(createDiagnosticForNode(isVariableDeclaration(node.parent) ? node.parent.name : node, Diagnostics.This_may_be_converted_to_an_async_function)); - } - } - function getErrorNodeFromCommonJsIndicator(commonJsModuleIndicator: Node): Node { return isBinaryExpression(commonJsModuleIndicator) ? commonJsModuleIndicator.left : commonJsModuleIndicator; } From d4eb19378cc83abe9f6768740c393b3ad82047e6 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 11:12:32 -0700 Subject: [PATCH 07/12] Fix accidental spacing changes --- src/compiler/checker.ts | 338 ++++++++++++++++++++-------------------- 1 file changed, 169 insertions(+), 169 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4387bff37a93b..1e7d342fefcef 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -837,7 +837,7 @@ namespace ts { target.flags |= source.flags; if (source.valueDeclaration && (!target.valueDeclaration || - isEffectiveModuleDeclaration(target.valueDeclaration) && !isEffectiveModuleDeclaration(source.valueDeclaration))) { + isEffectiveModuleDeclaration(target.valueDeclaration) && !isEffectiveModuleDeclaration(source.valueDeclaration))) { // other kinds of value declarations take precedence over modules target.valueDeclaration = source.valueDeclaration; } @@ -1247,7 +1247,7 @@ namespace ts { case SyntaxKind.SourceFile: if (!isExternalOrCommonJsModule(location)) break; isInExternalModule = true; - // falls through + // falls through case SyntaxKind.ModuleDeclaration: const moduleExports = getSymbolOfNode(location as SourceFile | ModuleDeclaration).exports!; if (location.kind === SyntaxKind.SourceFile || isAmbientModule(location)) { @@ -1512,7 +1512,7 @@ namespace ts { // we want to check for block-scoped if (errorLocation && (meaning & SymbolFlags.BlockScopedVariable || - ((meaning & SymbolFlags.Class || meaning & SymbolFlags.Enum) && (meaning & SymbolFlags.Value) === SymbolFlags.Value))) { + ((meaning & SymbolFlags.Class || meaning & SymbolFlags.Enum) && (meaning & SymbolFlags.Value) === SymbolFlags.Value))) { const exportOrLocalSymbol = getExportSymbolOfValueSymbolIfExported(result); if (exportOrLocalSymbol.flags & SymbolFlags.BlockScopedVariable || exportOrLocalSymbol.flags & SymbolFlags.Class || exportOrLocalSymbol.flags & SymbolFlags.Enum) { checkResolvedBlockScopedVariable(exportOrLocalSymbol, errorLocation); @@ -1620,7 +1620,7 @@ namespace ts { if (isEntityNameExpression((node).expression)) { return (node).expression; } - // falls through + // falls through default: return undefined; } @@ -2395,7 +2395,7 @@ namespace ts { function getExportsOfSymbol(symbol: Symbol): SymbolTable { return symbol.flags & SymbolFlags.Class ? getResolvedMembersOrExportsOfSymbol(symbol, MembersOrExportsResolutionKind.resolvedExports) : symbol.flags & SymbolFlags.Module ? getExportsOfModule(symbol) : - symbol.exports || emptySymbols; + symbol.exports || emptySymbols; } function getExportsOfModule(moduleSymbol: Symbol): SymbolTable { @@ -2662,7 +2662,7 @@ namespace ts { if (!isExternalOrCommonJsModule(location)) { break; } - // falls through + // falls through case SyntaxKind.ModuleDeclaration: if (result = callback(getSymbolOfNode(location as ModuleDeclaration).exports!)) { return result; @@ -3762,9 +3762,9 @@ namespace ts { const dotDotDotToken = isRest ? createToken(SyntaxKind.DotDotDotToken) : undefined; const name = parameterDeclaration ? parameterDeclaration.name ? - parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) : + parameterDeclaration.name.kind === SyntaxKind.Identifier ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name), EmitFlags.NoAsciiEscaping) : parameterDeclaration.name.kind === SyntaxKind.QualifiedName ? setEmitFlags(getSynthesizedClone(parameterDeclaration.name.right), EmitFlags.NoAsciiEscaping) : - cloneBindingName(parameterDeclaration.name) : + cloneBindingName(parameterDeclaration.name) : symbolName(parameterSymbol) : symbolName(parameterSymbol); const isOptional = parameterDeclaration && isOptionalParameter(parameterDeclaration) || getCheckFlags(parameterSymbol) & CheckFlags.OptionalParameter; @@ -3993,7 +3993,7 @@ namespace ts { const symbol = chain[index]; if (index === 0) { - context.flags |= NodeBuilderFlags.InInitialEntityName; + context.flags |= NodeBuilderFlags.InInitialEntityName; } const symbolName = getNameOfSymbolAsWritten(symbol, context); context.approximateLength += symbolName.length + 1; @@ -4200,10 +4200,10 @@ namespace ts { if (context && symbol.escapedName === InternalSymbolName.Default && !(context.flags & NodeBuilderFlags.UseAliasDefinedOutsideCurrentScope) && // If it's not the first part of an entity name, it must print as `default` (!(context.flags & NodeBuilderFlags.InInitialEntityName) || - // if the symbol is synthesized, it will only be referenced externally it must print as `default` - !symbol.declarations || - // if not in the same binding context (source file, module declaration), it must print as `default` - (context.enclosingDeclaration && findAncestor(symbol.declarations[0], isDefaultBindingContext) !== findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) { + // if the symbol is synthesized, it will only be referenced externally it must print as `default` + !symbol.declarations || + // if not in the same binding context (source file, module declaration), it must print as `default` + (context.enclosingDeclaration && findAncestor(symbol.declarations[0], isDefaultBindingContext) !== findAncestor(context.enclosingDeclaration, isDefaultBindingContext)))) { return "default"; } if (symbol.declarations && symbol.declarations.length) { @@ -4263,7 +4263,7 @@ namespace ts { // If the binding pattern is empty, this variable declaration is not visible return false; } - // falls through + // falls through case SyntaxKind.ModuleDeclaration: case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: @@ -4294,8 +4294,8 @@ namespace ts { // Private/protected properties/methods are not visible return false; } - // Public properties/methods are visible if its parents are visible, so: - // falls through + // Public properties/methods are visible if its parents are visible, so: + // falls through case SyntaxKind.Constructor: case SyntaxKind.ConstructSignature: @@ -4441,7 +4441,7 @@ namespace ts { } function getDeclarationContainer(node: Node): Node { - return findAncestor(getRootDeclaration(node), node => { + return findAncestor(getRootDeclaration(node), node => { switch (node.kind) { case SyntaxKind.VariableDeclaration: case SyntaxKind.VariableDeclarationList: @@ -4576,7 +4576,7 @@ namespace ts { const nameType = isLate ? checkComputedPropertyName(name as ComputedPropertyName) as LiteralType | UniqueESSymbolType : undefined; const text = isLate ? getLateBoundNameFromType(nameType!) : isWellKnown ? getPropertyNameForKnownSymbolName(idText(((name as ComputedPropertyName).expression as PropertyAccessExpression).name)) : - getTextOfPropertyName(name); + getTextOfPropertyName(name); // Relax null check on ambient destructuring parameters, since the parameters have no implementation and are just documentation if (strictNullChecks && declaration.flags & NodeFlags.Ambient && isParameterDeclaration(declaration)) { @@ -5140,10 +5140,10 @@ namespace ts { type = tryGetTypeFromEffectiveTypeNode(declaration) || checkObjectLiteralMethod(declaration, CheckMode.Normal); } else if (isParameter(declaration) - || isPropertyDeclaration(declaration) - || isPropertySignature(declaration) - || isVariableDeclaration(declaration) - || isBindingElement(declaration)) { + || isPropertyDeclaration(declaration) + || isPropertySignature(declaration) + || isVariableDeclaration(declaration) + || isBindingElement(declaration)) { type = getWidenedTypeForVariableLikeDeclaration(declaration, /*includeOptionality*/ true); } else { @@ -5284,7 +5284,7 @@ namespace ts { return anyType; } else if (declaration.kind === SyntaxKind.BinaryExpression || - declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) { + declaration.kind === SyntaxKind.PropertyAccessExpression && declaration.parent.kind === SyntaxKind.BinaryExpression) { return getWidenedTypeFromJSPropertyAssignments(symbol); } else if (symbol.flags & SymbolFlags.ValueModule && declaration && isSourceFile(declaration) && declaration.commonJsModuleIndicator) { @@ -6216,7 +6216,7 @@ namespace ts { const isStatic = resolutionKind === MembersOrExportsResolutionKind.resolvedExports; const earlySymbols = !isStatic ? symbol.members : symbol.flags & SymbolFlags.Module ? getExportsOfModuleWorker(symbol) : - symbol.exports; + symbol.exports; // In the event we recursively resolve the members/exports of the symbol, we // set the initial value of resolvedMembers/resolvedExports to the early-bound @@ -6722,7 +6722,7 @@ namespace ts { // mode, if the underlying property is optional we remove 'undefined' from the type. prop.type = strictNullChecks && isOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) : strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : - propType; + propType; if (modifiersProp) { prop.syntheticOrigin = modifiersProp; prop.declarations = modifiersProp.declarations; @@ -6922,8 +6922,8 @@ namespace ts { function getConstraintOfType(type: InstantiableType | UnionOrIntersectionType): Type | undefined { return type.flags & TypeFlags.TypeParameter ? getConstraintOfTypeParameter(type) : type.flags & TypeFlags.IndexedAccess ? getConstraintOfIndexedAccess(type) : - type.flags & TypeFlags.Conditional ? getConstraintOfConditionalType(type) : - getBaseConstraintOfType(type); + type.flags & TypeFlags.Conditional ? getConstraintOfConditionalType(type) : + getBaseConstraintOfType(type); } function getConstraintOfTypeParameter(typeParameter: TypeParameter): Type | undefined { @@ -7191,13 +7191,13 @@ namespace ts { const t = type.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(type) || emptyObjectType : type; return getObjectFlags(t) & ObjectFlags.Mapped ? getApparentTypeOfMappedType(t) : t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t) : - t.flags & TypeFlags.StringLike ? globalStringType : - t.flags & TypeFlags.NumberLike ? globalNumberType : - t.flags & TypeFlags.BooleanLike ? globalBooleanType : - t.flags & TypeFlags.ESSymbolLike ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : - t.flags & TypeFlags.NonPrimitive ? emptyObjectType : - t.flags & TypeFlags.Index ? keyofConstraintType : - t; + t.flags & TypeFlags.StringLike ? globalStringType : + t.flags & TypeFlags.NumberLike ? globalNumberType : + t.flags & TypeFlags.BooleanLike ? globalBooleanType : + t.flags & TypeFlags.ESSymbolLike ? getGlobalESSymbolType(/*reportErrors*/ languageVersion >= ScriptTarget.ES2015) : + t.flags & TypeFlags.NonPrimitive ? emptyObjectType : + t.flags & TypeFlags.Index ? keyofConstraintType : + t; } function createUnionOrIntersectionProperty(containingType: UnionOrIntersectionType, name: __String): Symbol | undefined { @@ -7763,8 +7763,8 @@ namespace ts { } let type = signature.target ? instantiateType(getReturnTypeOfSignature(signature.target), signature.mapper!) : signature.unionSignatures ? getUnionType(map(signature.unionSignatures, getReturnTypeOfSignature), UnionReduction.Subtype) : - getReturnTypeFromAnnotation(signature.declaration!) || - (nodeIsMissing((signature.declaration).body) ? anyType : getReturnTypeFromBody(signature.declaration)); + getReturnTypeFromAnnotation(signature.declaration!) || + (nodeIsMissing((signature.declaration).body) ? anyType : getReturnTypeFromBody(signature.declaration)); if (!popTypeResolution()) { if (signature.declaration) { const typeNode = getEffectiveReturnTypeNode(signature.declaration); @@ -8090,11 +8090,11 @@ namespace ts { const missingAugmentsTag = isJs && node.parent.kind !== SyntaxKind.JSDocAugmentsTag; const diag = minTypeArgumentCount === typeParameters.length ? missingAugmentsTag - ? Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag - : Diagnostics.Generic_type_0_requires_1_type_argument_s - : missingAugmentsTag - ? Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag - : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments; + ? Diagnostics.Expected_0_type_arguments_provide_these_with_an_extends_tag + : Diagnostics.Generic_type_0_requires_1_type_argument_s + : missingAugmentsTag + ? Diagnostics.Expected_0_1_type_arguments_provide_these_with_an_extends_tag + : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments; const typeStr = typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType); error(node, diag, typeStr, minTypeArgumentCount, typeParameters.length); if (!isJs) { @@ -8136,12 +8136,12 @@ namespace ts { const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { error(node, - minTypeArgumentCount === typeParameters.length - ? Diagnostics.Generic_type_0_requires_1_type_argument_s - : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, - symbolToString(symbol), - minTypeArgumentCount, - typeParameters.length); + minTypeArgumentCount === typeParameters.length + ? Diagnostics.Generic_type_0_requires_1_type_argument_s + : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, + symbolToString(symbol), + minTypeArgumentCount, + typeParameters.length); return errorType; } return getTypeAliasInstantiation(symbol, typeArguments); @@ -8262,7 +8262,7 @@ namespace ts { function getImpliedConstraint(typeVariable: TypeVariable, checkNode: TypeNode, extendsNode: TypeNode): Type | undefined { return isUnaryTupleTypeNode(checkNode) && isUnaryTupleTypeNode(extendsNode) ? getImpliedConstraint(typeVariable, (checkNode).elementTypes[0], (extendsNode).elementTypes[0]) : getActualTypeVariable(getTypeFromTypeNode(checkNode)) === typeVariable ? getTypeFromTypeNode(extendsNode) : - undefined; + undefined; } function getConstrainedTypeVariable(typeVariable: TypeVariable, node: Node) { @@ -8902,8 +8902,8 @@ namespace ts { } else if ((strictNullChecks || !(flags & TypeFlags.Nullable)) && !contains(typeSet, type) && !(flags & TypeFlags.Object && (type).objectFlags & ObjectFlags.Anonymous && - type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && - containsIdenticalType(typeSet, type))) { + type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method) && + containsIdenticalType(typeSet, type))) { typeSet.push(type); } } @@ -8942,8 +8942,8 @@ namespace ts { if (!containsType(u.types, type)) { const primitive = type.flags & TypeFlags.StringLiteral ? stringType : type.flags & TypeFlags.NumberLiteral ? numberType : - type.flags & TypeFlags.UniqueESSymbol ? esSymbolType : - undefined; + type.flags & TypeFlags.UniqueESSymbol ? esSymbolType : + undefined; if (!primitive || !containsType(u.types, primitive)) { return false; } @@ -9087,7 +9087,7 @@ namespace ts { const name = prop.valueDeclaration && getNameOfDeclaration(prop.valueDeclaration); type = name && isNumericLiteral(name) ? getLiteralType(+name.text) : name && name.kind === SyntaxKind.ComputedPropertyName && isNumericLiteral(name.expression) ? getLiteralType(+name.expression.text) : - getLiteralType(symbolName(prop)); + getLiteralType(symbolName(prop)); } if (type && type.flags & include) { return type; @@ -9108,14 +9108,14 @@ namespace ts { function getIndexType(type: Type, stringsOnly = keyofStringsOnly): Type { return type.flags & TypeFlags.Union ? getIntersectionType(map((type).types, t => getIndexType(t, stringsOnly))) : type.flags & TypeFlags.Intersection ? getUnionType(map((type).types, t => getIndexType(t, stringsOnly))) : - maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : - getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : - type === wildcardType ? wildcardType : - type.flags & TypeFlags.Any ? keyofConstraintType : - stringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : - getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : - getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : - getLiteralTypeFromPropertyNames(type, TypeFlags.StringOrNumberLiteralOrUnique); + maybeTypeOfKind(type, TypeFlags.InstantiableNonPrimitive) ? getIndexTypeForGenericType(type, stringsOnly) : + getObjectFlags(type) & ObjectFlags.Mapped ? getConstraintTypeFromMappedType(type) : + type === wildcardType ? wildcardType : + type.flags & TypeFlags.Any ? keyofConstraintType : + stringsOnly ? getIndexInfoOfType(type, IndexKind.String) ? stringType : getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral) : + getIndexInfoOfType(type, IndexKind.String) ? getUnionType([stringType, numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.UniqueESSymbol)]) : + getNonEnumNumberIndexInfo(type) ? getUnionType([numberType, getLiteralTypeFromPropertyNames(type, TypeFlags.StringLiteral | TypeFlags.UniqueESSymbol)]) : + getLiteralTypeFromPropertyNames(type, TypeFlags.StringOrNumberLiteralOrUnique); } function getExtractStringType(type: Type) { @@ -9776,7 +9776,7 @@ namespace ts { function getRegularTypeOfLiteralType(type: Type): Type { return type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral ? (type).regularType : type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getRegularTypeOfLiteralType)) : - type; + type; } function getLiteralType(value: string | number, enumId?: number, symbol?: Symbol) { @@ -9981,7 +9981,7 @@ namespace ts { Debug.assert(targets === undefined || sources.length === targets.length); return sources.length === 1 ? makeUnaryTypeMapper(sources[0], targets ? targets[0] : anyType) : sources.length === 2 ? makeBinaryTypeMapper(sources[0], targets ? targets[0] : anyType, sources[1], targets ? targets[1] : anyType) : - makeArrayTypeMapper(sources, targets); + makeArrayTypeMapper(sources, targets); } function createTypeEraser(sources: ReadonlyArray): TypeMapper { @@ -10218,8 +10218,8 @@ namespace ts { const replacementMapper = createReplacementMapper(typeVariable, t, mapper); return isArrayType(t) ? createArrayType(instantiateMappedTypeTemplate(type, numberType, /*isOptional*/ true, replacementMapper)) : isReadonlyArrayType(t) ? createReadonlyArrayType(instantiateMappedTypeTemplate(type, numberType, /*isOptional*/ true, replacementMapper)) : - isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) : - instantiateAnonymousType(type, replacementMapper); + isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) : + instantiateAnonymousType(type, replacementMapper); } return t; }); @@ -10235,7 +10235,7 @@ namespace ts { const modifiers = getMappedTypeModifiers(mappedType); const newMinLength = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : modifiers & MappedTypeModifiers.ExcludeOptional ? getTypeReferenceArity(tupleType) - (tupleType.target.hasRestElement ? 1 : 0) : - minLength; + minLength; return createTupleType(elementTypes, newMinLength, tupleType.target.hasRestElement, tupleType.target.associatedNames); } @@ -10245,7 +10245,7 @@ namespace ts { const modifiers = getMappedTypeModifiers(type); return strictNullChecks && modifiers & MappedTypeModifiers.IncludeOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) : strictNullChecks && modifiers & MappedTypeModifiers.ExcludeOptional && isOptional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : - propType; + propType; } function instantiateAnonymousType(type: AnonymousType, mapper: TypeMapper): AnonymousType { @@ -10491,10 +10491,10 @@ namespace ts { function isTypeDerivedFrom(source: Type, target: Type): boolean { return source.flags & TypeFlags.Union ? every((source).types, t => isTypeDerivedFrom(t, target)) : target.flags & TypeFlags.Union ? some((target).types, t => isTypeDerivedFrom(source, t)) : - source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) : - target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) : - hasBaseType(source, getTargetType(target)); - } + source.flags & TypeFlags.InstantiableNonPrimitive ? isTypeDerivedFrom(getBaseConstraintOfType(source) || emptyObjectType, target) : + target === globalObjectType || target === globalFunctionType ? isTypeSubtypeOf(source, target) : + hasBaseType(source, getTargetType(target)); + } /** * This is *not* a bi-directional relationship. @@ -10880,9 +10880,9 @@ namespace ts { function isEmptyObjectType(type: Type): boolean { return type.flags & TypeFlags.Object ? isEmptyResolvedType(resolveStructuredTypeMembers(type)) : type.flags & TypeFlags.NonPrimitive ? true : - type.flags & TypeFlags.Union ? some((type).types, isEmptyObjectType) : - type.flags & TypeFlags.Intersection ? every((type).types, isEmptyObjectType) : - false; + type.flags & TypeFlags.Union ? some((type).types, isEmptyObjectType) : + type.flags & TypeFlags.Intersection ? every((type).types, isEmptyObjectType) : + false; } function isEnumTypeRelatedTo(sourceSymbol: Symbol, targetSymbol: Symbol, errorReporter?: ErrorReporter) { @@ -11864,7 +11864,7 @@ namespace ts { // that S and T are contra-variant whereas X and Y are co-variant. function mappedTypeRelatedTo(source: MappedType, target: MappedType, reportErrors: boolean): Ternary { const modifiersRelated = relation === comparableRelation || (relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) : - getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target)); + getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target)); if (modifiersRelated) { let result: Ternary; if (result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { @@ -12658,31 +12658,31 @@ namespace ts { function isLiteralType(type: Type): boolean { return type.flags & TypeFlags.Boolean ? true : type.flags & TypeFlags.Union ? type.flags & TypeFlags.EnumLiteral ? true : every((type).types, isUnitType) : - isUnitType(type); + isUnitType(type); } function getBaseTypeOfLiteralType(type: Type): Type { return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(type) : type.flags & TypeFlags.StringLiteral ? stringType : - type.flags & TypeFlags.NumberLiteral ? numberType : - type.flags & TypeFlags.BooleanLiteral ? booleanType : - type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getBaseTypeOfLiteralType)) : - type; + type.flags & TypeFlags.NumberLiteral ? numberType : + type.flags & TypeFlags.BooleanLiteral ? booleanType : + type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getBaseTypeOfLiteralType)) : + type; } function getWidenedLiteralType(type: Type): Type { return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(type) : type.flags & TypeFlags.StringLiteral && type.flags & TypeFlags.FreshLiteral ? stringType : - type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType : - type.flags & TypeFlags.BooleanLiteral ? booleanType : - type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getWidenedLiteralType)) : - type; + type.flags & TypeFlags.NumberLiteral && type.flags & TypeFlags.FreshLiteral ? numberType : + type.flags & TypeFlags.BooleanLiteral ? booleanType : + type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getWidenedLiteralType)) : + type; } function getWidenedUniqueESSymbolType(type: Type): Type { return type.flags & TypeFlags.UniqueESSymbol ? esSymbolType : type.flags & TypeFlags.Union ? getUnionType(sameMap((type).types, getWidenedUniqueESSymbolType)) : - type; + type; } function getWidenedLiteralLikeTypeForContextualType(type: Type, contextualType: Type | undefined) { @@ -12722,9 +12722,9 @@ namespace ts { function getFalsyFlags(type: Type): TypeFlags { return type.flags & TypeFlags.Union ? getFalsyFlagsOfTypes((type).types) : type.flags & TypeFlags.StringLiteral ? (type).value === "" ? TypeFlags.StringLiteral : 0 : - type.flags & TypeFlags.NumberLiteral ? (type).value === 0 ? TypeFlags.NumberLiteral : 0 : - type.flags & TypeFlags.BooleanLiteral ? type === falseType ? TypeFlags.BooleanLiteral : 0 : - type.flags & TypeFlags.PossiblyFalsy; + type.flags & TypeFlags.NumberLiteral ? (type).value === 0 ? TypeFlags.NumberLiteral : 0 : + type.flags & TypeFlags.BooleanLiteral ? type === falseType ? TypeFlags.BooleanLiteral : 0 : + type.flags & TypeFlags.PossiblyFalsy; } function removeDefinitelyFalsyTypes(type: Type): Type { @@ -12740,11 +12740,11 @@ namespace ts { function getDefinitelyFalsyPartOfType(type: Type): Type { return type.flags & TypeFlags.String ? emptyStringType : type.flags & TypeFlags.Number ? zeroType : - type.flags & TypeFlags.Boolean || type === falseType ? falseType : - type.flags & (TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null) || - type.flags & TypeFlags.StringLiteral && (type).value === "" || - type.flags & TypeFlags.NumberLiteral && (type).value === 0 ? type : - neverType; + type.flags & TypeFlags.Boolean || type === falseType ? falseType : + type.flags & (TypeFlags.Void | TypeFlags.Undefined | TypeFlags.Null) || + type.flags & TypeFlags.StringLiteral && (type).value === "" || + type.flags & TypeFlags.NumberLiteral && (type).value === 0 ? type : + neverType; } /** @@ -12756,8 +12756,8 @@ namespace ts { const missing = (flags & ~type.flags) & (TypeFlags.Undefined | TypeFlags.Null); return missing === 0 ? type : missing === TypeFlags.Undefined ? getUnionType([type, undefinedType]) : - missing === TypeFlags.Null ? getUnionType([type, nullType]) : - getUnionType([type, undefinedType, nullType]); + missing === TypeFlags.Null ? getUnionType([type, nullType]) : + getUnionType([type, undefinedType, nullType]); } function getOptionalType(type: Type): Type { @@ -13053,8 +13053,8 @@ namespace ts { const targetHasRest = hasEffectiveRestParameter(target); const maxCount = sourceHasRest && targetHasRest ? Math.max(sourceCount, targetCount) : sourceHasRest ? targetCount : - targetHasRest ? sourceCount : - Math.min(sourceCount, targetCount); + targetHasRest ? sourceCount : + Math.min(sourceCount, targetCount); const targetGenericRestType = getGenericRestType(target); const paramCount = targetGenericRestType ? Math.min(targetCount - 1, maxCount) : maxCount; for (let i = 0; i < paramCount; i++) { @@ -13244,7 +13244,7 @@ namespace ts { function getTypeFromInference(inference: InferenceInfo) { return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : inference.contraCandidates ? getIntersectionType(inference.contraCandidates) : - emptyObjectType; + emptyObjectType; } function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) { @@ -13657,7 +13657,7 @@ namespace ts { (inference.isFixed || !isTypeParameterAtTopLevel(getReturnTypeOfSignature(signature), inference.typeParameter)); const baseCandidates = primitiveConstraint ? sameMap(candidates, getRegularTypeOfLiteralType) : widenLiteralTypes ? sameMap(candidates, getWidenedLiteralType) : - candidates; + candidates; // If all inferences were made from contravariant positions, infer a common subtype. Otherwise, if // union types were requested or if all inferences were made from the return type position, infer a // union type. Otherwise, infer a common supertype. @@ -13811,7 +13811,7 @@ namespace ts { } } else { - return "" + parent.elements.indexOf(element); + return "" + parent.elements.indexOf(element); } } @@ -13835,7 +13835,7 @@ namespace ts { const t = target as PropertyAccessExpression; if (t.name.escapedText !== getBindingElementNameText(source as BindingElement)) return false; if (source.parent.parent.kind === SyntaxKind.BindingElement && isMatchingReference(source.parent.parent, t.expression)) { - return true; + return true; } if (source.parent.parent.kind === SyntaxKind.VariableDeclaration) { const maybeId = (source.parent.parent as VariableDeclaration).initializer; @@ -13848,7 +13848,7 @@ namespace ts { function getAccessedPropertyName(access: PropertyAccessExpression | ElementAccessExpression): __String | undefined { return isPropertyAccessExpression(access) ? access.name.escapedText : isStringLiteral(access.argumentExpression) || isNumericLiteral(access.argumentExpression) ? escapeLeadingUnderscores(access.argumentExpression.text) : - undefined; + undefined; } function containsMatchingReference(source: Node, target: Node) { @@ -15328,7 +15328,7 @@ namespace ts { // declaration container are the same). const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & TypeFlags.AnyOrUnknown) !== 0 || - isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || + isInTypeQuery(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || node.parent.kind === SyntaxKind.NonNullExpression || declaration.kind === SyntaxKind.VariableDeclaration && (declaration).exclamationToken || declaration.flags & NodeFlags.Ambient; @@ -15593,7 +15593,7 @@ namespace ts { // * /** @constructor */ function [name]() { ... } // * /** @constructor */ var x = function() { ... } else if ((container.kind === SyntaxKind.FunctionExpression || container.kind === SyntaxKind.FunctionDeclaration) && - getJSDocClassTag(container)) { + getJSDocClassTag(container)) { const classType = getJavascriptClassType(container.symbol); if (classType) { return getFlowTypeOfReference(node, classType); @@ -16334,7 +16334,7 @@ namespace ts { return getContextualTypeForReturnExpression(node); case SyntaxKind.YieldExpression: return getContextualTypeForYieldOperand(parent); - case SyntaxKind.CallExpression: + case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: return getContextualTypeForArgument(parent, node); case SyntaxKind.TypeAssertionExpression: @@ -16825,7 +16825,7 @@ namespace ts { isObjectLiteralMethod(memberDecl)) { let type = memberDecl.kind === SyntaxKind.PropertyAssignment ? checkPropertyAssignment(memberDecl, checkMode) : memberDecl.kind === SyntaxKind.ShorthandPropertyAssignment ? checkExpressionForMutableLocation(memberDecl.name, checkMode) : - checkObjectLiteralMethod(memberDecl, checkMode); + checkObjectLiteralMethod(memberDecl, checkMode); if (isInJSFile) { const jsDocType = getTypeForDeclarationFromJSDocComment(memberDecl); if (jsDocType) { @@ -17763,12 +17763,12 @@ namespace ts { return false; } - /** - * Check whether the given attributes of JSX opening-like element is assignable to the tagName attributes. - * Get the attributes type of the opening-like element through resolving the tagName, "target attributes" - * Check assignablity between given attributes property, "source attributes", and the "target attributes" - * @param openingLikeElement an opening-like JSX element to check its JSXAttributes - */ + /** + * Check whether the given attributes of JSX opening-like element is assignable to the tagName attributes. + * Get the attributes type of the opening-like element through resolving the tagName, "target attributes" + * Check assignablity between given attributes property, "source attributes", and the "target attributes" + * @param openingLikeElement an opening-like JSX element to check its JSXAttributes + */ function checkJsxAttributesAssignableToTagNameAttributes(openingLikeElement: JsxOpeningLikeElement, checkMode: CheckMode | undefined) { // The function involves following steps: // 1. Figure out expected attributes type by resolving tagName of the JSX opening-like element, targetAttributesType. @@ -18681,7 +18681,7 @@ namespace ts { getOrCreateTypeFromSignature(getSignatureInstantiationWithoutFillingInTypeArguments(contextualSignature, contextualSignature.typeParameters)) : instantiatedType; const inferenceTargetType = getReturnTypeOfSignature(signature); - // Inferences made from return types have lower priority than all other inferences. + // Inferences made from return types have lower priority than all other inferences. inferTypes(context.inferences, inferenceSourceType, inferenceTargetType, InferencePriority.ReturnType); } } @@ -18992,7 +18992,7 @@ namespace ts { const hasRestParameter = some(signatures, hasEffectiveRestParameter); const paramRange = hasRestParameter ? min : min < max ? min + "-" + max : - min; + min; const hasSpreadArgument = getSpreadArgumentIndex(args) > -1; if (argCount <= max && hasSpreadArgument) { argCount--; @@ -19001,7 +19001,7 @@ namespace ts { if (hasRestParameter || hasSpreadArgument) { const error = hasRestParameter && hasSpreadArgument ? Diagnostics.Expected_at_least_0_arguments_but_got_1_or_more : hasRestParameter ? Diagnostics.Expected_at_least_0_arguments_but_got_1 : - Diagnostics.Expected_0_arguments_but_got_1_or_more; + Diagnostics.Expected_0_arguments_but_got_1_or_more; return createDiagnosticForNode(node, error, paramRange, argCount); } if (min < argCount && argCount < max) { @@ -19598,7 +19598,7 @@ namespace ts { invocationErrorRecovery(apparentType, kind, error(node, kind === SignatureKind.Call ? Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures : Diagnostics.Cannot_use_new_with_an_expression_whose_type_lacks_a_call_or_construct_signature - , typeToString(apparentType))); + , typeToString(apparentType))); } function invocationErrorRecovery(apparentType: Type, kind: SignatureKind, diagnostic: Diagnostic) { @@ -19800,8 +19800,8 @@ namespace ts { // If the symbol of the node has members, treat it like a constructor. const symbol = isFunctionDeclaration(node) || isFunctionExpression(node) ? getSymbolOfNode(node) : - isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) : - undefined; + isVariableDeclaration(node) && node.initializer && isFunctionExpression(node.initializer) ? getSymbolOfNode(node.initializer) : + undefined; return !!symbol && symbol.members !== undefined; } @@ -19836,8 +19836,8 @@ namespace ts { const decl = symbol.valueDeclaration; const assignmentSymbol = decl && decl.parent && (isFunctionDeclaration(decl) && getSymbolOfNode(decl) || - isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) || - isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent)); + isBinaryExpression(decl.parent) && getSymbolOfNode(decl.parent.left) || + isVariableDeclaration(decl.parent) && getSymbolOfNode(decl.parent)); if (assignmentSymbol) { const prototype = forEach(assignmentSymbol.declarations, getAssignedJavascriptPrototype); if (prototype) { @@ -20407,7 +20407,7 @@ namespace ts { if (isUnitType(type)) { let contextualType = !contextualSignature ? undefined : contextualSignature === getSignatureFromDeclaration(func) ? type : - getReturnTypeOfSignature(contextualSignature); + getReturnTypeOfSignature(contextualSignature); if (contextualType) { switch (functionFlags & FunctionFlags.AsyncGenerator) { case FunctionFlags.AsyncGenerator: @@ -20842,7 +20842,7 @@ namespace ts { const facts = getTypeFacts(operandType) & (TypeFacts.Truthy | TypeFacts.Falsy); return facts === TypeFacts.Truthy ? falseType : facts === TypeFacts.Falsy ? trueType : - booleanType; + booleanType; case SyntaxKind.PlusPlusToken: case SyntaxKind.MinusMinusToken: const ok = checkArithmeticOperandType(node.operand, checkNonNullType(operandType, node.operand), @@ -21054,7 +21054,7 @@ namespace ts { const propName = "" + elementIndex as __String; const type = isTypeAny(sourceType) ? sourceType : isTupleLikeType(sourceType) ? getTupleElementType(sourceType, elementIndex) : - elementType; + elementType; if (type) { return checkDestructuringAssignment(element, type, checkMode); } @@ -21175,7 +21175,7 @@ namespace ts { return false; } return isSideEffectFree((node as BinaryExpression).left) && - isSideEffectFree((node as BinaryExpression).right); + isSideEffectFree((node as BinaryExpression).right); case SyntaxKind.PrefixUnaryExpression: case SyntaxKind.PostfixUnaryExpression: @@ -21290,8 +21290,8 @@ namespace ts { resultType = numberType; } else if (isTypeAssignableToKind(leftType, TypeFlags.StringLike, /*strict*/ true) || isTypeAssignableToKind(rightType, TypeFlags.StringLike, /*strict*/ true)) { - // If one or both operands are of the String primitive type, the result is of the String primitive type. - resultType = stringType; + // If one or both operands are of the String primitive type, the result is of the String primitive type. + resultType = stringType; } else if (isTypeAny(leftType) || isTypeAny(rightType)) { // Otherwise, the result is of type Any. @@ -21480,7 +21480,7 @@ namespace ts { case SyntaxKind.ExclamationEqualsEqualsToken: case SyntaxKind.ExclamationEqualsToken: return error(errNode, Diagnostics.This_condition_will_always_return_0_since_the_types_1_and_2_have_no_overlap, "true", leftStr, rightStr); - } + } return undefined; } } @@ -21791,7 +21791,7 @@ namespace ts { (node.parent.kind === SyntaxKind.PropertyAccessExpression && (node.parent).expression === node) || (node.parent.kind === SyntaxKind.ElementAccessExpression && (node.parent).expression === node) || ((node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.QualifiedName) && isInRightSideOfImportOrExportAssignment(node) || - (node.parent.kind === SyntaxKind.TypeQuery && (node.parent).exprName === node)); + (node.parent.kind === SyntaxKind.TypeQuery && (node.parent).exprName === node)); if (!ok) { error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query); @@ -21844,7 +21844,7 @@ namespace ts { if ((node).expression.kind === SyntaxKind.ImportKeyword) { return checkImportCallExpression(node); } - /* falls through */ + /* falls through */ case SyntaxKind.NewExpression: return checkCallExpression(node); case SyntaxKind.TaggedTemplateExpression: @@ -22008,7 +22008,7 @@ namespace ts { let hasReportedError = false; for (const { name } of parent.parameters) { if (isBindingPattern(name) && - checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) { + checkIfTypePredicateVariableIsDeclaredInBindingPattern(name, parameterName, typePredicate.parameterName)) { hasReportedError = true; break; } @@ -23007,7 +23007,7 @@ namespace ts { return DeclarationSpaces.ExportValue; } d = (d as ExportAssignment).expression; - /* falls through */ + /* falls through */ // The below options all declare an Alias, which is allowed to merge with other values within the importing module case SyntaxKind.ImportEqualsDeclaration: case SyntaxKind.NamespaceImport: @@ -23572,8 +23572,8 @@ namespace ts { node.typeExpression && node.typeExpression.type && !isArrayType(getTypeFromTypeNode(node.typeExpression.type))) { error(node.name, - Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, - idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name)); + Diagnostics.JSDoc_param_tag_has_name_0_but_there_is_no_parameter_with_that_name_It_would_match_arguments_if_it_had_an_array_type, + idText(node.name.kind === SyntaxKind.QualifiedName ? node.name.right : node.name)); } } } @@ -24225,7 +24225,7 @@ namespace ts { const enclosingContainer = getEnclosingBlockScopeContainer(symbol.valueDeclaration); if (enclosingContainer === func) { if (symbol.valueDeclaration.kind === SyntaxKind.Parameter || - symbol.valueDeclaration.kind === SyntaxKind.BindingElement) { + symbol.valueDeclaration.kind === SyntaxKind.BindingElement) { // it is ok to reference parameter in initializer if either // - parameter is located strictly on the left of current parameter declaration if (symbol.valueDeclaration.pos < node.pos) { @@ -24242,9 +24242,9 @@ namespace ts { // computed property names/initializers in instance property declaration of class like entities // are executed in constructor and thus deferred (current.parent.kind === SyntaxKind.PropertyDeclaration && - !(hasModifier(current.parent, ModifierFlags.Static)) && - isClassLike(current.parent.parent)); - })) { + !(hasModifier(current.parent, ModifierFlags.Static)) && + isClassLike(current.parent.parent)); + })) { return; } // fall through to report error @@ -25080,16 +25080,16 @@ namespace ts { // Grammar checking if (!checkGrammarStatementInAmbientContext(node)) { findAncestor(node.parent, - current => { - if (isFunctionLike(current)) { - return "quit"; - } - if (current.kind === SyntaxKind.LabeledStatement && (current).label.escapedText === node.label.escapedText) { - grammarErrorOnNode(node.label, Diagnostics.Duplicate_label_0, getTextOfNode(node.label)); - return true; - } - return false; - }); + current => { + if (isFunctionLike(current)) { + return "quit"; + } + if (current.kind === SyntaxKind.LabeledStatement && (current).label.escapedText === node.label.escapedText) { + grammarErrorOnNode(node.label, Diagnostics.Duplicate_label_0, getTextOfNode(node.label)); + return true; + } + return false; + }); } // ensure that label is unique @@ -25216,8 +25216,8 @@ namespace ts { let errorNode: Node | undefined; if (propDeclaration && name && (propDeclaration.kind === SyntaxKind.BinaryExpression || - name.kind === SyntaxKind.ComputedPropertyName || - prop.parent === containingType.symbol)) { + name.kind === SyntaxKind.ComputedPropertyName || + prop.parent === containingType.symbol)) { errorNode = propDeclaration; } else if (indexDeclaration) { @@ -25923,7 +25923,7 @@ namespace ts { return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PropertyAccessExpression && isConstantMemberAccess((node).expression) || node.kind === SyntaxKind.ElementAccessExpression && isConstantMemberAccess((node).expression) && - (node).argumentExpression.kind === SyntaxKind.StringLiteral; + (node).argumentExpression.kind === SyntaxKind.StringLiteral; } function checkEnumDeclaration(node: EnumDeclaration) { @@ -26140,7 +26140,7 @@ namespace ts { } break; } - // falls through + // falls through case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.FunctionDeclaration: @@ -26484,7 +26484,7 @@ namespace ts { function isNotOverload(declaration: Declaration): boolean { return (declaration.kind !== SyntaxKind.FunctionDeclaration && declaration.kind !== SyntaxKind.MethodDeclaration) || - !!(declaration as FunctionDeclaration).body; + !!(declaration as FunctionDeclaration).body; } function checkSourceElement(node: Node | undefined): void { @@ -26573,7 +26573,7 @@ namespace ts { return checkJSDocParameterTag(node as JSDocParameterTag); case SyntaxKind.JSDocFunctionType: checkSignatureDeclaration(node as JSDocFunctionType); - // falls through + // falls through case SyntaxKind.JSDocNonNullableType: case SyntaxKind.JSDocNullableType: case SyntaxKind.JSDocAllType: @@ -27278,7 +27278,7 @@ namespace ts { if (isInExpressionContext(node)) { return checkExpression(node as Expression).symbol; } - // falls through + // falls through case SyntaxKind.ThisType: return getTypeFromThisTypeNode(node as ThisExpression | ThisTypeNode).symbol; @@ -27307,7 +27307,7 @@ namespace ts { ) { return resolveExternalModuleName(node, node); } - // falls through + // falls through case SyntaxKind.NumericLiteral: // index access @@ -27527,7 +27527,7 @@ namespace ts { const { leftSpread, rightSpread, syntheticOrigin } = symbol as TransientSymbol; return leftSpread ? [leftSpread, rightSpread!] : syntheticOrigin ? [syntheticOrigin] - : singleElementArray(tryGetAliasTarget(symbol)); + : singleElementArray(tryGetAliasTarget(symbol)); } return undefined; } @@ -27535,7 +27535,7 @@ namespace ts { let target: Symbol | undefined; let next: Symbol | undefined = symbol; while (next = getSymbolLinks(next).target) { - target = next; + target = next; } return target; } @@ -27727,8 +27727,8 @@ namespace ts { case SyntaxKind.ExportAssignment: return (node).expression && (node).expression.kind === SyntaxKind.Identifier - ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) - : true; + ? isAliasResolvedToValue(getSymbolOfNode(node) || unknownSymbol) + : true; } return false; } @@ -28800,15 +28800,15 @@ namespace ts { if (type.flags & TypeFlags.String || type.flags & TypeFlags.Number) { return grammarErrorOnNode(parameter.name, - Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, - getTextOfNode(parameter.name), - typeToString(type), - typeToString(getTypeFromTypeNode(node.type!))); + Diagnostics.An_index_signature_parameter_type_cannot_be_a_type_alias_Consider_writing_0_Colon_1_Colon_2_instead, + getTextOfNode(parameter.name), + typeToString(type), + typeToString(getTypeFromTypeNode(node.type!))); } if (type.flags & TypeFlags.Union && allTypesAssignableToKind(type, TypeFlags.StringLiteral, /*strict*/ true)) { return grammarErrorOnNode(parameter.name, - Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead); + Diagnostics.An_index_signature_parameter_type_cannot_be_a_union_type_Consider_using_a_mapped_object_type_instead); } return grammarErrorOnNode(parameter.name, Diagnostics.An_index_signature_parameter_type_must_be_string_or_number); @@ -29013,7 +29013,7 @@ namespace ts { if (name.kind === SyntaxKind.NumericLiteral) { checkGrammarNumericLiteral(name); } - // falls through + // falls through case SyntaxKind.MethodDeclaration: currentKind = Flags.Property; break; @@ -29150,9 +29150,9 @@ namespace ts { } else if (!doesAccessorHaveCorrectParameterCount(accessor)) { return grammarErrorOnNode(accessor.name, - kind === SyntaxKind.GetAccessor ? - Diagnostics.A_get_accessor_cannot_have_parameters : - Diagnostics.A_set_accessor_must_have_exactly_one_parameter); + kind === SyntaxKind.GetAccessor ? + Diagnostics.A_get_accessor_cannot_have_parameters : + Diagnostics.A_set_accessor_must_have_exactly_one_parameter); } else if (kind === SyntaxKind.SetAccessor) { if (accessor.type) { @@ -29600,7 +29600,7 @@ namespace ts { node.kind === SyntaxKind.ExportAssignment || node.kind === SyntaxKind.NamespaceExportDeclaration || hasModifier(node, ModifierFlags.Ambient | ModifierFlags.Export | ModifierFlags.Default)) { - return false; + return false; } return grammarErrorOnFirstToken(node, Diagnostics.A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file); From 244dfd09b719f8af894dab13d9946dbfbb69427b Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 14:27:18 -0700 Subject: [PATCH 08/12] Mark utility function as internal --- src/compiler/utilities.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 3322fad55a1f4..610e7a1bcd3fe 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -4870,6 +4870,7 @@ namespace ts { return unescapeLeadingUnderscores(symbol.escapedName); } + /** @internal */ export function getReturnStatementsWithPromiseHandlers(node: Node): Node[] { const returnStatements: Node[] = []; if (isFunctionLike(node)) { From 6b878f6ecc8137ca67d27c6a6a420a79ff63d908 Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 14:27:35 -0700 Subject: [PATCH 09/12] Removed extra definition of utility function --- src/services/suggestionDiagnostics.ts | 35 --------------------------- 1 file changed, 35 deletions(-) diff --git a/src/services/suggestionDiagnostics.ts b/src/services/suggestionDiagnostics.ts index bd1b698dca64c..9c2859bcc8d9a 100644 --- a/src/services/suggestionDiagnostics.ts +++ b/src/services/suggestionDiagnostics.ts @@ -114,39 +114,4 @@ namespace ts { function getErrorNodeFromCommonJsIndicator(commonJsModuleIndicator: Node): Node { return isBinaryExpression(commonJsModuleIndicator) ? commonJsModuleIndicator.left : commonJsModuleIndicator; } - - /** @internal */ - export function getReturnStatementsWithPromiseHandlers(node: Node): Node[] { - const returnStatements: Node[] = []; - if (isFunctionLike(node)) { - forEachChild(node, visit); - } - else { - visit(node); - } - - function visit(child: Node) { - if (isFunctionLike(child)) { - return; - } - - if (isReturnStatement(child)) { - forEachChild(child, addHandlers); - } - - function addHandlers(returnChild: Node) { - if (isPromiseHandler(returnChild)) { - returnStatements.push(child as ReturnStatement); - } - } - - forEachChild(child, visit); - } - return returnStatements; - } - - function isPromiseHandler(node: Node): boolean { - return (isCallExpression(node) && isPropertyAccessExpression(node.expression) && - (node.expression.name.text === "then" || node.expression.name.text === "catch")); - } } From a908dc0f0ee20036200d5380a4c55d0ddee7801c Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 14:28:11 -0700 Subject: [PATCH 10/12] Allow codefix to apply to function expression in variable declaration --- src/services/codefixes/convertToAsyncFunction.ts | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 195586c6b6eba..1650baac0ea41 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -42,7 +42,16 @@ namespace ts.codefix { function convertToAsyncFunction(changes: textChanges.ChangeTracker, sourceFile: SourceFile, position: number, checker: TypeChecker, context: CodeFixContextBase): void { // get the function declaration - returns a promise - const functionToConvert: FunctionLikeDeclaration = getContainingFunction(getTokenAtPosition(sourceFile, position)) as FunctionLikeDeclaration; + const tokenAtPosition = getTokenAtPosition(sourceFile, position); + let functionToConvert: FunctionLikeDeclaration; + if (isIdentifier(tokenAtPosition) && isVariableDeclaration(tokenAtPosition.parent) && + tokenAtPosition.parent.initializer && isFunctionLikeDeclaration(tokenAtPosition.parent.initializer)) { + functionToConvert = tokenAtPosition.parent.initializer; + } + else { + functionToConvert = getContainingFunction(getTokenAtPosition(sourceFile, position)) as FunctionLikeDeclaration; + } + if (!functionToConvert) { return; } From 7b21820497a52f7b7360eb8bef246ac1df596cda Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 14:28:58 -0700 Subject: [PATCH 11/12] Add tests and validate diagnostic spans --- .../unittests/convertToAsyncFunction.ts | 16 ++++++++++++++++ ...tToAsyncFunction_ArrowFunctionNoAnnotation.js | 11 +++++++++++ ...tToAsyncFunction_ArrowFunctionNoAnnotation.ts | 11 +++++++++++ ...oAsyncFunction_basicNoReturnTypeAnnotation.js | 11 +++++++++++ ...oAsyncFunction_basicNoReturnTypeAnnotation.ts | 11 +++++++++++ ...rtToAsyncFunction_simpleFunctionExpression.js | 12 ++++++++++++ ...rtToAsyncFunction_simpleFunctionExpression.ts | 12 ++++++++++++ 7 files changed, 84 insertions(+) create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.js create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.ts create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.js create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.ts create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.js create mode 100644 tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.ts diff --git a/src/testRunner/unittests/convertToAsyncFunction.ts b/src/testRunner/unittests/convertToAsyncFunction.ts index a597b453dc52b..99788e1310e98 100644 --- a/src/testRunner/unittests/convertToAsyncFunction.ts +++ b/src/testRunner/unittests/convertToAsyncFunction.ts @@ -363,6 +363,8 @@ interface Array {}` const diagnostics = languageService.getSuggestionDiagnostics(f.path); const diagnostic = find(diagnostics, diagnostic => diagnostic.messageText === diagnosticDescription.message); assert.exists(diagnostic); + assert.equal(diagnostic!.start, context.span.start); + assert.equal(diagnostic!.length, context.span.length); const actions = codefix.getFixes(context); const action = find(actions, action => action.description === codeFixDescription.message)!; @@ -423,6 +425,10 @@ interface Array {}` _testConvertToAsyncFunction("convertToAsyncFunction_basic", ` function [#|f|](): Promise{ return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +}`); + _testConvertToAsyncFunction("convertToAsyncFunction_basicNoReturnTypeAnnotation", ` +function [#|f|]() { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); }`); _testConvertToAsyncFunction("convertToAsyncFunction_basicWithComments", ` function [#|f|](): Promise{ @@ -436,6 +442,10 @@ function [#|f|](): Promise{ _testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunction", ` [#|():Promise => {|] return fetch('https://typescriptlang.org').then(result => console.log(result)); +}`); + _testConvertToAsyncFunction("convertToAsyncFunction_ArrowFunctionNoAnnotation", ` +[#|() => {|] + return fetch('https://typescriptlang.org').then(result => console.log(result)); }`); _testConvertToAsyncFunction("convertToAsyncFunction_Catch", ` function [#|f|]():Promise { @@ -1178,6 +1188,12 @@ function [#|f|]() { } `); + _testConvertToAsyncFunction("convertToAsyncFunction_simpleFunctionExpression", ` +const [#|foo|] = function () { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} +`); + }); diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.js b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.js new file mode 100644 index 0000000000000..500d546971bfb --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.js @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +/*[#|*/() => {/*|]*/ + return fetch('https://typescriptlang.org').then(result => console.log(result)); +} +// ==ASYNC FUNCTION::Convert to async function== + +async () => { + const result = await fetch('https://typescriptlang.org'); + return console.log(result); +} \ No newline at end of file diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.ts b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.ts new file mode 100644 index 0000000000000..500d546971bfb --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_ArrowFunctionNoAnnotation.ts @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +/*[#|*/() => {/*|]*/ + return fetch('https://typescriptlang.org').then(result => console.log(result)); +} +// ==ASYNC FUNCTION::Convert to async function== + +async () => { + const result = await fetch('https://typescriptlang.org'); + return console.log(result); +} \ No newline at end of file diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.js b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.js new file mode 100644 index 0000000000000..8aec78c667066 --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.js @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +function /*[#|*/f/*|]*/() { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} +// ==ASYNC FUNCTION::Convert to async function== + +async function f() { + const result = await fetch('https://typescriptlang.org'); + console.log(result); +} \ No newline at end of file diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.ts b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.ts new file mode 100644 index 0000000000000..8aec78c667066 --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_basicNoReturnTypeAnnotation.ts @@ -0,0 +1,11 @@ +// ==ORIGINAL== + +function /*[#|*/f/*|]*/() { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} +// ==ASYNC FUNCTION::Convert to async function== + +async function f() { + const result = await fetch('https://typescriptlang.org'); + console.log(result); +} \ No newline at end of file diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.js b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.js new file mode 100644 index 0000000000000..a92497ca937d9 --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.js @@ -0,0 +1,12 @@ +// ==ORIGINAL== + +const /*[#|*/foo/*|]*/ = function () { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} + +// ==ASYNC FUNCTION::Convert to async function== + +const foo = async function () { + const result = await fetch('https://typescriptlang.org'); + console.log(result); +} diff --git a/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.ts b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.ts new file mode 100644 index 0000000000000..a92497ca937d9 --- /dev/null +++ b/tests/baselines/reference/convertToAsyncFunction/convertToAsyncFunction_simpleFunctionExpression.ts @@ -0,0 +1,12 @@ +// ==ORIGINAL== + +const /*[#|*/foo/*|]*/ = function () { + return fetch('https://typescriptlang.org').then(result => { console.log(result) }); +} + +// ==ASYNC FUNCTION::Convert to async function== + +const foo = async function () { + const result = await fetch('https://typescriptlang.org'); + console.log(result); +} From ab32e4d5074480dc9bef6da7f1277e385708726a Mon Sep 17 00:00:00 2001 From: Benjamin Lichtman Date: Tue, 28 Aug 2018 14:37:09 -0700 Subject: [PATCH 12/12] Add comment explaining special casing --- src/services/codefixes/convertToAsyncFunction.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/codefixes/convertToAsyncFunction.ts b/src/services/codefixes/convertToAsyncFunction.ts index 1650baac0ea41..6162e311266a7 100644 --- a/src/services/codefixes/convertToAsyncFunction.ts +++ b/src/services/codefixes/convertToAsyncFunction.ts @@ -44,6 +44,8 @@ namespace ts.codefix { // get the function declaration - returns a promise const tokenAtPosition = getTokenAtPosition(sourceFile, position); let functionToConvert: FunctionLikeDeclaration; + + // if the parent of a FunctionLikeDeclaration is a variable declaration, the convertToAsync diagnostic will be reported on the variable name if (isIdentifier(tokenAtPosition) && isVariableDeclaration(tokenAtPosition.parent) && tokenAtPosition.parent.initializer && isFunctionLikeDeclaration(tokenAtPosition.parent.initializer)) { functionToConvert = tokenAtPosition.parent.initializer;