Skip to content

Unable to publish due to baseline difference in .d.ts emit #39129

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
DanielRosenwasser opened this issue Jun 18, 2020 · 10 comments · Fixed by #39173
Closed

Unable to publish due to baseline difference in .d.ts emit #39129

DanielRosenwasser opened this issue Jun 18, 2020 · 10 comments · Fixed by #39173
Assignees
Labels
High Priority Infrastructure Issue relates to TypeScript team infrastructure

Comments

@DanielRosenwasser
Copy link
Member

We seem to be hitting some sort of issue with parenthesization on .d.ts files. This has been blocking nightly publishes, and will block any sort of beta publish next week.

https://typescript.visualstudio.com/TypeScript/_build/results?buildId=76918&view=logs&j=fd490c07-0b22-5182-fac9-6d67fe1e939b&t=00933dce-c782-5c03-4a85-76379ccfa50a&l=139

image

@DanielRosenwasser DanielRosenwasser added High Priority Infrastructure Issue relates to TypeScript team infrastructure labels Jun 18, 2020
@weswigham
Copy link
Member

@rbuckton is this an intended outcome of the node factory work? Should we LKG and accept the difference?

@rbuckton
Copy link
Contributor

It could be. Odd though that this didn't show up in the API tests before now.

@weswigham
Copy link
Member

Iirc, the API tests are consistently captured with the lib compiler, so it doesn't appear until you do an LKG (as is done for nightlies and publishes).

@rbuckton
Copy link
Contributor

I'm not entirely certain why this changed. factory.createUnionTypeNode calls parenthesizer.parenthesizeConstituentTypesOfUnionOrIntersectionType(types) which should do the same thing it did prior to moving the API: when unioning A & B with C it should be parenthesizing it as (A & B) | C since our parenthesizing logic for types is fairly aggressive and doesn't take precedence into account.

@weswigham
Copy link
Member

It's very likely the parenthesizer was never being invoked before, as those return type nodes are normally just copied from the source (since it's an interface)

@sheetalkamat
Copy link
Member

@weswigham if it was copied from source then it should be copied from source now as well?

@weswigham
Copy link
Member

It should be! The parenthesizer in the factory may have had other ideas when the updateUnionType method was fed back in the input nodes, though!

@rbuckton
Copy link
Contributor

Ah, I discovered the difference, and accepting the change should be fine. In 3.9 we called parenthesizeTypeParameters in declarations.ts when emitting a type reference:

case SyntaxKind.TypeReference: {
checkEntityNameVisibility(input.typeName, enclosingDeclaration);
const node = visitEachChild(input, visitDeclarationSubtree, context);
return cleanup(updateTypeReferenceNode(node, node.typeName, parenthesizeTypeParameters(node.typeArguments)));
}

And parenthesizeTypeParameters would unconditionally create a new NodeArray even if there were no changes:

export function parenthesizeTypeParameters(typeParameters: readonly TypeNode[] | undefined) {
if (some(typeParameters)) {
const params: TypeNode[] = [];
for (let i = 0; i < typeParameters.length; ++i) {
const entry = typeParameters[i];
params.push(i === 0 && isFunctionOrConstructorTypeNode(entry) && entry.typeParameters ?
createParenthesizedType(entry) :
entry);
}
return createNodeArray(params);
}
}

NOTE: It's not the call to createNodeArray but rather the initialization of params to a new array here:

const params: TypeNode[] = [];

By returning a new NodeArray here, we end up creating new nodes starting at NodeArray<TypeNode> in the union SignatureDeclaration & {typeArguments?: NodeArray<any>} | undefined, which triggers us to hit our over-aggressive parenthesization logic.

One of the node factory changes was to move the parenthesizeTypeParameters logic into the factory, as we do with all other parenthesis rules:

function createTypeReferenceNode(typeName: string | EntityName, typeArguments: readonly TypeNode[] | undefined) {
const node = createBaseNode<TypeReferenceNode>(SyntaxKind.TypeReference);
node.typeName = asName(typeName);
node.typeArguments = typeArguments && parenthesizerRules().parenthesizeTypeArguments(createNodeArray(typeArguments));
node.transformFlags = TransformFlags.ContainsTypeScript;
return node;
}

In the updated parenthesizer rules, we use sameMap instead of allocating a new array:

function parenthesizeTypeArguments(typeArguments: NodeArray<TypeNode> | undefined): NodeArray<TypeNode> | undefined {
if (some(typeArguments)) {
return factory.createNodeArray(sameMap(typeArguments, parenthesizeOrdinalTypeArgument));
}
}

This results in us just reusing the original node since there are no changes in the type reference.

@rbuckton rbuckton mentioned this issue Jun 20, 2020
@rbuckton
Copy link
Contributor

I just pushed up #39173 which runs LKG and accepts the new API baselines.

@rbuckton
Copy link
Contributor

Publish is working again:
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
High Priority Infrastructure Issue relates to TypeScript team infrastructure
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants