Skip to content

Create type node#14709

Merged
aozgaa merged 81 commits into
microsoft:masterfrom
aozgaa:createTypeNode
Mar 27, 2017
Merged

Create type node#14709
aozgaa merged 81 commits into
microsoft:masterfrom
aozgaa:createTypeNode

Conversation

@aozgaa
Copy link
Copy Markdown
Contributor

@aozgaa aozgaa commented Mar 17, 2017

Migrating away from typeToString in codefixes, with the eventual hope of eliminating typeToString.

While there is still work to be done, I'm putting this up now to solicit feedback.
Known issues:

vladima and others added 30 commits March 3, 2017 13:50
…existing node factory, formatter and printer
This reverts commit fd65966.

Accidentally pushed to the wrong branch.
Fix assigning positions to node array
* create type reference node from type parameters
* expose index signature synthesis
* widen types in helpers
* format unions
* use deep cloning
Comment thread src/compiler/transformers/es2017.ts Outdated
visitNodes(node.modifiers, visitor, isModifier),
node.asteriskToken,
node.name,
node.questionToken,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

questionToken is TypeScript syntax. You might as well just pass undefined here, as this property should always be undefined by the time the es2017 transform runs. We do the same for decorators, typeParameters, and type here as well.

Comment thread src/compiler/transformers/esnext.ts Outdated
/*modifiers*/ undefined,
node.dotDotDotToken,
getGeneratedNameForNode(node),
node.questionToken,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pass undefined here.

Comment thread src/compiler/transformers/esnext.ts Outdated
? undefined
: node.asteriskToken,
visitNode(node.name, visitor, isPropertyName),
visitNode(node.questionToken, visitor, isToken),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pass undefined here.

Comment thread src/compiler/transformers/ts.ts Outdated
visitNodes(node.modifiers, modifierVisitor, isModifier),
node.asteriskToken,
visitPropertyNameOfClassElement(node),
node.questionToken,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should pass undefined here.

Comment thread src/compiler/utilities.ts
|| kind === SyntaxKind.BooleanKeyword
|| kind === SyntaxKind.StringKeyword
|| kind === SyntaxKind.SymbolKeyword
|| kind === SyntaxKind.ThisKeyword
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep in mind this and null can also be expressions. I would check to be sure that isTypeNode (which calls isTypeNodeKind) isn't used to skip visiting a TypeNode that could also be an expression.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resolved offline: we decided that conflating this as a type node and expression isn't a problem for now because it has no children and we would only rely on the distinction for now when aggregating modifier flags from children.

We may want to introduce a distinction as we have with StringLiteral and LiteralType in the future.

Comment thread src/compiler/factory.ts Outdated
// Type Elements

export function createConstructSignature() {
throw new Error("not implemented.");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why have this if it is not implemented?

Comment thread src/compiler/factory.ts Outdated

export function createTypeReferenceNode(typeName: string | EntityName, typeArguments: NodeArray<TypeNode> | undefined) {
const typeReference = createSynthesizedNode(SyntaxKind.TypeReference) as TypeReferenceNode;
typeReference.typeName = isQualifiedName(<EntityName>typeName) ? <QualifiedName>typeName : asName(<string | Identifier>typeName);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isQualifiedName test is unnecessary, just add an overload to asName for EntityName just as we do for BindingName and PropertyName

Comment thread src/compiler/types.ts Outdated
getNonNullableType(type: Type): Type;

/** Note that the resulting nodes cannot be checked. */
createTypeNode(type: Type, enclosingDeclaration: Node): TypeNode;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would recommend calling these:
typeToTypeNode and signatureToSingatureDeclaration to match typeToString and signatureToString.

I would also remove createSignatureParts, possibly extract it to a helper if needed.

}

let typeString = "any";
let typeNode: TypeNode = createKeywordTypeNode(SyntaxKind.AnyKeyword);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move this to use site, no need to create it all the time.

Comment thread src/services/codefixes/helpers.ts Outdated
const visibility = getVisibilityPrefixWithSpace(getModifierFlags(declaration));

const type = checker.getTypeOfSymbolAtLocation(symbol, enclosingDeclaration);
const name = declaration.name ? getSynthesizedDeepClone(declaration.name) as PropertyName : undefined;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not think you need a clone here, just use the same node

Comment thread src/services/codefixes/helpers.ts Outdated
/*decorators*/undefined,
modifiers,
name,
/*questionToken*/ undefined,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you should be able to know if the parent property is optional or not, and then add the questiontoken as needed.

Comment thread src/compiler/checker.ts Outdated

function createTypeNodeWorker(type: Type): TypeNode {
if (!type) {
if (undefinedArgumentIsError) { encounteredError = true; }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would make it always an error.

Comment thread src/compiler/checker.ts Outdated
return (<IntrinsicType>type).intrinsicName === "true" ? createTrue() : createFalse();
}
if (type.flags & TypeFlags.EnumLiteral) {
throw new Error("enum literal not implemented");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should work, e.g. var x: E.value

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so i would remove this then.

Comment thread src/compiler/checker.ts Outdated
return createAnonymousTypeNode(<ObjectType>type);
}

// TODO (aozgaa): implement string and number literals here once there is a testable case.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these are already handled earlier.

Comment thread src/compiler/checker.ts Outdated
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this check? Are we being defensive against third parties or ourselves? If ourselves, then this check shouldn't be strictly necessary.

Comment thread src/compiler/checker.ts
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this closure? We just tear off the functions and add them to TypeChecker.

Comment thread src/compiler/checker.ts Outdated
return createKeywordTypeNode(SyntaxKind.NeverKeyword);
}
if (type.flags & TypeFlags.ESSymbol) {
throw new Error("ESSymbol not implemented");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be createKeywordTypeNode(SyntaxKind.SymbolKeyword)?

Comment thread src/compiler/checker.ts Outdated
throw new Error("ESSymbol not implemented");
}
if (type.flags & TypeFlags.NonPrimitive) {
throw new Error("Non primitive not implemented");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be createKeywordTypeNode(SyntaxKind.ObjectKeyword)?

Comment thread src/compiler/checker.ts Outdated
}
};

function typeToTypeNodeHelper(type: Type, enclosingDeclaration: Node, flags: NodeBuilderFlags): TypeNode {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving the inObjectTypeLiteral, checkAlias, and symbolStack variables to a state object and call typeToTypeNodeHelper recursively instead.


function signatureToMethodDeclaration(signature: Signature, enclosingDeclaration: Node, body?: Block) {
const signatureDeclaration = <MethodDeclaration>checker.signatureToSignatureDeclaration(signature, SyntaxKind.MethodDeclaration, enclosingDeclaration);
if (signatureDeclaration) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May introduce new hidden class? Ensure decorators is assigned to undefined either here or in signatureToSignatureDeclaration.

Comment thread src/services/codefixes/helpers.ts Outdated
newSignatureDeclaration.parent = enclosingDeclaration;
newSignatureDeclaration.name = signatures[0].getDeclaration().name;
function createMethodImplementingSignatures(signatures: Signature[], name: PropertyName, optional: boolean, modifiers: Modifier[] | undefined): MethodDeclaration {
Debug.assert(signatures && signatures.length > 0);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you need this assert?

Comment thread src/services/codefixes/helpers.ts Outdated
if (nonRestLength > maxNonRestArgs) {
maxNonRestArgs = nonRestLength;
maxArgsIndex = i;
someSigHasRestParameter = someSigHasRestParameter || sig.hasRestParameter;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unecessary assignments, consider:

if (sig.hasRestParameter) someSigHasRestParameter = true;

Comment thread src/services/textChanges.ts Outdated
* for them separators are treated as the part of the node.
* This function should be used to insert nodes in lists when nodes don't carry separators as the part of the node range,
* i.e. arguments in arguments lists, parameters in parameter lists etc.
* Note that separators are art of the node in statements and class elements.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/art/part

Comment thread src/services/textChanges.ts Outdated
// order changes by start position
const normalized = stableSort(changes, (a, b) => a.range.pos - b.range.pos);
// verify that end position of the change is less than start position of the next change
// verify that change intervals to not overlap, except possible at end points.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/to/do

@aozgaa aozgaa merged commit 5e4b8d6 into microsoft:master Mar 27, 2017
@aozgaa aozgaa mentioned this pull request Aug 11, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 21, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants