@@ -494,5 +494,124 @@ index 095ee29..439621e 100644
494494 This is file2` )
495495 ) . toMatchSnapshot ( ) ;
496496 } ) ;
497+
498+ test ( 'merge commit with 2 parents' , async function ( ) {
499+ // Source: the TypeScript repo
500+ expect (
501+ await transform ( `
502+ commit 3f504f4fbc1caf9c10814d48d8897a34f8a34dec
503+ Merge: 2439767601 fbcdb8cf4f
504+ Author: Gabriela Araujo Britto <gabrielaa@microsoft.com>
505+ Date: Thu Dec 21 17:57:42 2023 -0800
506+
507+ Merge branch 'main' into gabritto/d2
508+
509+ diff --cc src/compiler/binder.ts
510+ index b2f0d9f384,6ea9b82695..c638984e3b
511+ --- a/src/compiler/binder.ts
512+ +++ b/src/compiler/binder.ts
513+ @@@ -137,9 -136,9 +137,10 @@@ import
514+ isBlock,
515+ isBlockOrCatchScoped,
516+ IsBlockScopedContainer,
517+ + isBooleanLiteral,
518+ isCallExpression,
519+ isClassStaticBlockDeclaration,
520+ + isConditionalExpression,
521+ isConditionalTypeNode,
522+ IsContainer,
523+ isDeclaration,
524+ diff --cc src/compiler/types.ts
525+ index 2e204671f7,e56bba5ab4..ab6229d1b6
526+ --- a/src/compiler/types.ts
527+ +++ b/src/compiler/types.ts
528+ @@@ -5985,8 -6063,7 +6063,8 @@@ export interface NodeLinks
529+ decoratorSignature?: Signature; // Signature for decorator as if invoked by the runtime.
530+ spreadIndices?: { first: number | undefined, last: number | undefined }; // Indices of first and last spread elements in array literal
531+ parameterInitializerContainsUndefined?: boolean; // True if this is a parameter declaration whose type annotation contains "undefined".
532+ - fakeScopeForSignatureDeclaration?: boolean; // True if this is a fake scope injected into an enclosing declaration chain.
533+ + contextualReturnType?: Type; // If the node is a return statement's expression, then this is the contextual return type.
534+ + fakeScopeForSignatureDeclaration?: "params" | "typeParams"; // If present, this is a fake scope injected into an enclosing declaration chain.
535+ assertionExpressionType?: Type; // Cached type of the expression of a type assertion
536+ }` )
537+ ) . toMatchSnapshot ( ) ;
538+ } ) ;
539+
540+ test ( 'merge commit with 3 parents' , async function ( ) {
541+ // Source: the TypeScript repo
542+ expect (
543+ await transform ( `
544+ commit d6d6a4aedfa78794c1b611c13d2ed1d3a66e1798
545+ Merge: 0dc976df1e 5f16a48236 3eadbf6c96
546+ Author: Andy Hanson <anhans@microsoft.com>
547+ Date: Thu Sep 1 12:52:42 2016 -0700
548+
549+ Merge branch 'goto_definition_super', remote-tracking branch 'origin' into constructor_references
550+
551+ diff --cc src/services/services.ts
552+ index b95feb9207,c19eb487d7,83a2192659..7e9a356e73
553+ --- a/src/services/services.ts
554+ +++ b/src/services/services.ts
555+ @@@@ -2788,26 -2792,18 -2788,34 +2792,42 @@@@ namespace ts
556+ return node && node.parent && node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node;
557+ }
558+
559+ + function climbPastPropertyAccess(node: Node) {
560+ + return isRightSideOfPropertyAccess(node) ? node.parent : node;
561+ + }
562+ +
563+ - function climbPastManyPropertyAccesses(node: Node): Node {
564+ - return isRightSideOfPropertyAccess(node) ? climbPastManyPropertyAccesses(node.parent) : node;
565+ +++ /** Get \`C\` given \`N\` if \`N\` is in the position \`class C extends N\` or \`class C extends foo.N\` where \`N\` is an identifier. */
566+ +++ function tryGetClassExtendingIdentifier(node: Node): ClassLikeDeclaration | undefined {
567+ +++ return tryGetClassExtendingExpressionWithTypeArguments(climbPastPropertyAccess(node).parent);
568+ ++ }
569+ ++
570+ function isCallExpressionTarget(node: Node): boolean {
571+ - if (isRightSideOfPropertyAccess(node)) {
572+ - node = node.parent;
573+ - }
574+ - node = climbPastPropertyAccess(node);
575+ -- return node && node.parent && node.parent.kind === SyntaxKind.CallExpression && (<CallExpression>node.parent).expression === node;
576+ ++ return isCallOrNewExpressionTarget(node, SyntaxKind.CallExpression);
577+ }
578+
579+ function isNewExpressionTarget(node: Node): boolean {
580+ - if (isRightSideOfPropertyAccess(node)) {
581+ - node = node.parent;
582+ - }
583+ - node = climbPastPropertyAccess(node);
584+ -- return node && node.parent && node.parent.kind === SyntaxKind.NewExpression && (<CallExpression>node.parent).expression === node;
585+ ++ return isCallOrNewExpressionTarget(node, SyntaxKind.NewExpression);
586+ ++ }
587+ ++
588+ ++ function isCallOrNewExpressionTarget(node: Node, kind: SyntaxKind) {
589+ ++ const target = climbPastPropertyAccess(node);
590+ ++ return target && target.parent && target.parent.kind === kind && (<CallExpression>target.parent).expression === target;
591+ ++ }
592+ ++
593+ - /** Get \`C\` given \`N\` if \`N\` is in the position \`class C extends N\` or \`class C extends foo.N\` where \`N\` is an identifier. */
594+ - function tryGetClassExtendingIdentifier(node: Node): ClassLikeDeclaration | undefined {
595+ - return tryGetClassExtendingExpressionWithTypeArguments(climbPastPropertyAccess(node).parent);
596+ +++ function climbPastManyPropertyAccesses(node: Node): Node {
597+ +++ return isRightSideOfPropertyAccess(node) ? climbPastManyPropertyAccesses(node.parent) : node;
598+ ++ }
599+ ++
600+ ++ /** Returns a CallLikeExpression where \`node\` is the target being invoked. */
601+ ++ function getAncestorCallLikeExpression(node: Node): CallLikeExpression | undefined {
602+ ++ const target = climbPastManyPropertyAccesses(node);
603+ ++ const callLike = target.parent;
604+ ++ return callLike && isCallLikeExpression(callLike) && getInvokedExpression(callLike) === target && callLike;
605+ ++ }
606+ ++
607+ ++ function tryGetSignatureDeclaration(typeChecker: TypeChecker, node: Node): SignatureDeclaration | undefined {
608+ ++ const callLike = getAncestorCallLikeExpression(node);
609+ ++ return callLike && typeChecker.getResolvedSignature(callLike).declaration;
610+ }
611+
612+ function isNameOfModuleDeclaration(node: Node) {
613+ ` )
614+ ) . toMatchSnapshot ( ) ;
615+ } ) ;
497616 } ) ;
498617}
0 commit comments