Skip to content

Commit

Permalink
Merge branch 'master' into fix36604
Browse files Browse the repository at this point in the history
  • Loading branch information
ahejlsberg committed Mar 4, 2020
2 parents 669797a + 5c8def9 commit 1a5911a
Show file tree
Hide file tree
Showing 21 changed files with 342 additions and 26 deletions.
17 changes: 12 additions & 5 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10510,7 +10510,7 @@ namespace ts {
const signature = getSignatureFromDeclaration(node.parent);
const parameterIndex = node.parent.parameters.indexOf(node);
Debug.assert(parameterIndex >= 0);
return parameterIndex >= getMinArgumentCount(signature);
return parameterIndex >= getMinArgumentCount(signature, /*strongArityForUntypedJS*/ true);
}
const iife = getImmediatelyInvokedFunctionExpression(node.parent);
if (iife) {
Expand Down Expand Up @@ -10601,6 +10601,9 @@ namespace ts {
isValueSignatureDeclaration(declaration) &&
!hasJSDocParameterTags(declaration) &&
!getJSDocType(declaration);
if (isUntypedSignatureInJSFile) {
flags |= SignatureFlags.IsUntypedSignatureInJSFile;
}

// If this is a JSDoc construct signature, then skip the first parameter in the
// parameter list. The first parameter represents the return type of the construct
Expand Down Expand Up @@ -10631,7 +10634,6 @@ namespace ts {
const isOptionalParameter = isOptionalJSDocParameterTag(param) ||
param.initializer || param.questionToken || param.dotDotDotToken ||
iife && parameters.length > iife.arguments.length && !type ||
isUntypedSignatureInJSFile ||
isJSDocOptionalParameter(param);
if (!isOptionalParameter) {
minArgumentCount = parameters.length;
Expand Down Expand Up @@ -21107,8 +21109,10 @@ namespace ts {
if (isInJS && className) {
const classSymbol = checkExpression(className).symbol;
if (classSymbol && classSymbol.members && (classSymbol.flags & SymbolFlags.Function)) {
const classType = (getDeclaredTypeOfSymbol(classSymbol) as InterfaceType).thisType!;
return getFlowTypeOfReference(node, classType);
const classType = (getDeclaredTypeOfSymbol(classSymbol) as InterfaceType).thisType;
if (classType) {
return getFlowTypeOfReference(node, classType);
}
}
}
// Check if it's a constructor definition, can be either a variable decl or function decl
Expand Down Expand Up @@ -26377,7 +26381,7 @@ namespace ts {
return length;
}

function getMinArgumentCount(signature: Signature) {
function getMinArgumentCount(signature: Signature, strongArityForUntypedJS?: boolean) {
if (signatureHasRestParameter(signature)) {
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
if (isTupleType(restType)) {
Expand All @@ -26387,6 +26391,9 @@ namespace ts {
}
}
}
if (!strongArityForUntypedJS && signature.flags & SignatureFlags.IsUntypedSignatureInJSFile) {
return 0;
}
return signature.minArgumentCount;
}

Expand Down
9 changes: 7 additions & 2 deletions src/compiler/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2273,7 +2273,7 @@ namespace ts {

function emitPropertyAccessExpression(node: PropertyAccessExpression) {
const expression = cast(emitExpression(node.expression), isExpression);
const token = getDotOrQuestionDotToken(node);
const token = node.questionDotToken || createNode(SyntaxKind.DotToken, node.expression.end, node.name.pos) as DotToken;
const indentBeforeDot = needsIndentation(node, node.expression, token);
const indentAfterDot = needsIndentation(node, token, node.name);

Expand All @@ -2289,7 +2289,12 @@ namespace ts {
writePunctuation(".");
}

emitTokenWithComment(token.kind, node.expression.end, writePunctuation, node);
if (node.questionDotToken) {
emit(token);
}
else {
emitTokenWithComment(token.kind, node.expression.end, writePunctuation, node);
}
increaseIndentIf(indentAfterDot, /*writeSpaceIfNotIndenting*/ false);
emit(node.name);
decreaseIndentIf(indentBeforeDot, indentAfterDot);
Expand Down
1 change: 1 addition & 0 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4817,6 +4817,7 @@ namespace ts {
HasLiteralTypes = 1 << 1, // Indicates signature is specialized
IsInnerCallChain = 1 << 2, // Indicates signature comes from a CallChain nested in an outer OptionalChain
IsOuterCallChain = 1 << 3, // Indicates signature comes from a CallChain that is the outermost chain of an optional expression
IsUntypedSignatureInJSFile = 1 << 4, // Indicates signature is from a js file and has no types

// We do not propagate `IsInnerCallChain` to instantiated signatures, as that would result in us
// attempting to add `| undefined` on each recursive call to `getReturnTypeOfSignature` when
Expand Down
4 changes: 0 additions & 4 deletions src/compiler/utilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5052,10 +5052,6 @@ namespace ts {
}
}

export function getDotOrQuestionDotToken(node: PropertyAccessExpression) {
return node.questionDotToken || createNode(SyntaxKind.DotToken, node.expression.end, node.name.pos) as DotToken;
}

export function isNamedImportsOrExports(node: Node): node is NamedImportsOrExports {
return node.kind === SyntaxKind.NamedImports || node.kind === SyntaxKind.NamedExports;
}
Expand Down
16 changes: 8 additions & 8 deletions src/compiler/visitorPublic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ namespace ts {
if (node.flags & NodeFlags.OptionalChain) {
return updatePropertyAccessChain(<PropertyAccessChain>node,
visitNode((<PropertyAccessChain>node).expression, visitor, isExpression),
visitNode((<PropertyAccessChain>node).questionDotToken, visitor, isToken),
visitNode((<PropertyAccessChain>node).questionDotToken, tokenVisitor, isToken),
visitNode((<PropertyAccessChain>node).name, visitor, isIdentifier));
}
return updatePropertyAccess(<PropertyAccessExpression>node,
Expand All @@ -470,7 +470,7 @@ namespace ts {
if (node.flags & NodeFlags.OptionalChain) {
return updateElementAccessChain(<ElementAccessChain>node,
visitNode((<ElementAccessChain>node).expression, visitor, isExpression),
visitNode((<ElementAccessChain>node).questionDotToken, visitor, isToken),
visitNode((<ElementAccessChain>node).questionDotToken, tokenVisitor, isToken),
visitNode((<ElementAccessChain>node).argumentExpression, visitor, isExpression));
}
return updateElementAccess(<ElementAccessExpression>node,
Expand All @@ -481,7 +481,7 @@ namespace ts {
if (node.flags & NodeFlags.OptionalChain) {
return updateCallChain(<CallChain>node,
visitNode((<CallChain>node).expression, visitor, isExpression),
visitNode((<CallChain>node).questionDotToken, visitor, isToken),
visitNode((<CallChain>node).questionDotToken, tokenVisitor, isToken),
nodesVisitor((<CallChain>node).typeArguments, visitor, isTypeNode),
nodesVisitor((<CallChain>node).arguments, visitor, isExpression));
}
Expand Down Expand Up @@ -527,7 +527,7 @@ namespace ts {
nodesVisitor((<ArrowFunction>node).typeParameters, visitor, isTypeParameterDeclaration),
visitParameterList((<ArrowFunction>node).parameters, visitor, context, nodesVisitor),
visitNode((<ArrowFunction>node).type, visitor, isTypeNode),
visitNode((<ArrowFunction>node).equalsGreaterThanToken, visitor, isToken),
visitNode((<ArrowFunction>node).equalsGreaterThanToken, tokenVisitor, isToken),
visitFunctionBody((<ArrowFunction>node).body, visitor, context));

case SyntaxKind.DeleteExpression:
Expand Down Expand Up @@ -558,14 +558,14 @@ namespace ts {
return updateBinary(<BinaryExpression>node,
visitNode((<BinaryExpression>node).left, visitor, isExpression),
visitNode((<BinaryExpression>node).right, visitor, isExpression),
visitNode((<BinaryExpression>node).operatorToken, visitor, isToken));
visitNode((<BinaryExpression>node).operatorToken, tokenVisitor, isToken));

case SyntaxKind.ConditionalExpression:
return updateConditional(<ConditionalExpression>node,
visitNode((<ConditionalExpression>node).condition, visitor, isExpression),
visitNode((<ConditionalExpression>node).questionToken, visitor, isToken),
visitNode((<ConditionalExpression>node).questionToken, tokenVisitor, isToken),
visitNode((<ConditionalExpression>node).whenTrue, visitor, isExpression),
visitNode((<ConditionalExpression>node).colonToken, visitor, isToken),
visitNode((<ConditionalExpression>node).colonToken, tokenVisitor, isToken),
visitNode((<ConditionalExpression>node).whenFalse, visitor, isExpression));

case SyntaxKind.TemplateExpression:
Expand Down Expand Up @@ -659,7 +659,7 @@ namespace ts {

case SyntaxKind.ForOfStatement:
return updateForOf(<ForOfStatement>node,
visitNode((<ForOfStatement>node).awaitModifier, visitor, isToken),
visitNode((<ForOfStatement>node).awaitModifier, tokenVisitor, isToken),
visitNode((<ForOfStatement>node).initializer, visitor, isForInitializer),
visitNode((<ForOfStatement>node).expression, visitor, isExpression),
visitNode((<ForOfStatement>node).statement, visitor, isStatement, liftToBlock));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7020,6 +7020,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Only_named_exports_may_use_export_type_1383" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Only named exports may use 'export type'.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Only public and protected methods of the base class are accessible via the 'super' keyword.]]></Val>
Expand Down Expand Up @@ -7047,11 +7053,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_0_can_only_be_specified_in_tsconfig_json_file_6064" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line_6230" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '{0}' can only be specified in 'tsconfig.json' file or set to 'false' or 'null' on command line.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La opción "{0}" solo puede especificarse en el archivo "tsconfig.json" o establecerse en "false" o "null" en la línea de comandos.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line_6064" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '{0}' can only be specified in 'tsconfig.json' file.]]></Val>
<Val><![CDATA[Option '{0}' can only be specified in 'tsconfig.json' file or set to 'null' on command line.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La opción '{0}' solo se puede especificar en el archivo 'tsconfig.json'.]]></Val>
<Val><![CDATA[La opción "{0}" solo puede especificarse en el archivo "tsconfig.json" o establecerse en "null" en la línea de comandos.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
Expand Down Expand Up @@ -9543,6 +9558,9 @@
<Item ItemId=";Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3_6229" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Tag '{0}' expects at least '{1}' arguments, but the JSX factory '{2}' provides at most '{3}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[La etiqueta "{0}" espera al menos "{1}" argumentos, pero el generador de JSX "{2}" proporciona como máximo "{3}".]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
Expand Down Expand Up @@ -10869,6 +10887,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Type_of_property_0_circularly_references_itself_in_mapped_type_1_2615" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Type of property '{0}' circularly references itself in mapped type '{1}'.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member.]]></Val>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7008,6 +7008,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Only_named_exports_may_use_export_type_1383" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Only named exports may use 'export type'.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword_2340" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Only public and protected methods of the base class are accessible via the 'super' keyword.]]></Val>
Expand Down Expand Up @@ -7035,11 +7041,20 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_0_can_only_be_specified_in_tsconfig_json_file_6064" ItemType="0" PsrId="306" Leaf="true">
<Item ItemId=";Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_false_or_null_on_command_line_6230" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '{0}' can only be specified in 'tsconfig.json' file or set to 'false' or 'null' on command line.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[L'opzione '{0}' può essere specificata solo nel file 'tsconfig.json' oppure impostata su 'false' o 'null' sulla riga di comando.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Option_0_can_only_be_specified_in_tsconfig_json_file_or_set_to_null_on_command_line_6064" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Option '{0}' can only be specified in 'tsconfig.json' file.]]></Val>
<Val><![CDATA[Option '{0}' can only be specified in 'tsconfig.json' file or set to 'null' on command line.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[L'opzione '{0}' può essere specificata solo nel file 'tsconfig.json'.]]></Val>
<Val><![CDATA[L'opzione '{0}' può essere specificata solo nel file 'tsconfig.json' oppure impostata su 'null' sulla riga di comando.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
Expand Down Expand Up @@ -9531,6 +9546,9 @@
<Item ItemId=";Tag_0_expects_at_least_1_arguments_but_the_JSX_factory_2_provides_at_most_3_6229" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Tag '{0}' expects at least '{1}' arguments, but the JSX factory '{2}' provides at most '{3}'.]]></Val>
<Tgt Cat="Text" Stat="Loc" Orig="New">
<Val><![CDATA[Con il tag '{0}' sono previsti almeno '{1}' argomenti, ma la factory JSX '{2}' ne fornisce al massimo '{3}'.]]></Val>
</Tgt>
</Str>
<Disp Icon="Str" />
</Item>
Expand Down Expand Up @@ -10857,6 +10875,12 @@
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Type_of_property_0_circularly_references_itself_in_mapped_type_1_2615" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Type of property '{0}' circularly references itself in mapped type '{1}'.]]></Val>
</Str>
<Disp Icon="Str" />
</Item>
<Item ItemId=";Type_of_yield_operand_in_an_async_generator_must_either_be_a_valid_promise_or_must_not_contain_a_cal_1321" ItemType="0" PsrId="306" Leaf="true">
<Str Cat="Text">
<Val><![CDATA[Type of 'yield' operand in an async generator must either be a valid promise or must not contain a callable 'then' member.]]></Val>
Expand Down
1 change: 0 additions & 1 deletion src/services/textChanges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -966,7 +966,6 @@ namespace ts.textChanges {
function createWriter(newLine: string): TextChangesWriter {
let lastNonTriviaPosition = 0;


const writer = createTextWriter(newLine);
const onEmitNode: PrintHandlers["onEmitNode"] = (hint, node, printCallback) => {
if (node) {
Expand Down
16 changes: 16 additions & 0 deletions tests/baselines/reference/allowJsClassThisTypeCrash.symbols
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
=== tests/cases/compiler/app.js ===
const f = function() {};
>f : Symbol(f, Decl(app.js, 0, 5))

var g = f;
>g : Symbol(g, Decl(app.js, 1, 3))
>f : Symbol(f, Decl(app.js, 0, 5))

g.prototype.m = function () {
>g.prototype : Symbol(g.m, Decl(app.js, 1, 10))
>g : Symbol(g, Decl(app.js, 1, 3))
>prototype : Symbol(Function.prototype, Decl(lib.es5.d.ts, --, --))
>m : Symbol(g.m, Decl(app.js, 1, 10))

this;
};
22 changes: 22 additions & 0 deletions tests/baselines/reference/allowJsClassThisTypeCrash.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
=== tests/cases/compiler/app.js ===
const f = function() {};
>f : () => void
>function() {} : () => void

var g = f;
>g : () => void
>f : () => void

g.prototype.m = function () {
>g.prototype.m = function () { this;} : () => void
>g.prototype.m : any
>g.prototype : any
>g : () => void
>prototype : any
>m : any
>function () { this;} : () => void

this;
>this : any

};
27 changes: 27 additions & 0 deletions tests/baselines/reference/jsDeclarationsClassLeadingOptional.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//// [bar.js]
export class Z {
f(x = 1, y) {
return [x, y];
}
}

//// [bar.js]
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Z = void 0;
var Z = /** @class */ (function () {
function Z() {
}
Z.prototype.f = function (x, y) {
if (x === void 0) { x = 1; }
return [x, y];
};
return Z;
}());
exports.Z = Z;


//// [bar.d.ts]
export class Z {
f(x: number, y: any): any[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
=== tests/cases/conformance/jsdoc/declarations/bar.js ===
export class Z {
>Z : Symbol(Z, Decl(bar.js, 0, 0))

f(x = 1, y) {
>f : Symbol(Z.f, Decl(bar.js, 0, 16))
>x : Symbol(x, Decl(bar.js, 1, 6))
>y : Symbol(y, Decl(bar.js, 1, 12))

return [x, y];
>x : Symbol(x, Decl(bar.js, 1, 6))
>y : Symbol(y, Decl(bar.js, 1, 12))
}
}
16 changes: 16 additions & 0 deletions tests/baselines/reference/jsDeclarationsClassLeadingOptional.types
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
=== tests/cases/conformance/jsdoc/declarations/bar.js ===
export class Z {
>Z : Z

f(x = 1, y) {
>f : (x: number, y: any) => any[]
>x : number
>1 : 1
>y : any

return [x, y];
>[x, y] : any[]
>x : number
>y : any
}
}
Loading

0 comments on commit 1a5911a

Please sign in to comment.