midway through response to ron's comments

This commit is contained in:
Arthur Ozga
2017-03-27 00:34:48 -07:00
parent fb4e3d87bd
commit a39bb0aaaa
3 changed files with 110 additions and 127 deletions

View File

@@ -2384,13 +2384,13 @@ namespace ts {
function createMappedTypeNodeFromType(type: MappedType) {
Debug.assert(!!(type.flags & TypeFlags.Object));
const typeParameter = getTypeParameterFromMappedType(<MappedType>type);
const typeParameter = getTypeParameterFromMappedType(type);
const typeParameterNode = typeParameterToDeclaration(typeParameter);
const templateType = getTemplateTypeFromMappedType(<MappedType>type);
const templateTypeNode = templateType && typeToTypeNodeHelper(templateType);
const readonlyToken = (<MappedType>type).declaration && (<MappedType>type).declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined;
const questionToken = (<MappedType>type).declaration && (<MappedType>type).declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined;
const templateType = getTemplateTypeFromMappedType(type);
const templateTypeNode = typeToTypeNodeHelper(templateType);
const readonlyToken = type.declaration && type.declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined;
const questionToken = type.declaration && type.declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined;
return createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode);
}
@@ -2402,7 +2402,7 @@ namespace ts {
if (symbol.flags & SymbolFlags.Class && !getBaseTypeVariableOfClass(symbol) ||
symbol.flags & (SymbolFlags.Enum | SymbolFlags.ValueModule) ||
shouldWriteTypeOfFunctionSymbol()) {
return createTypeQueryNodeFromType(type);
return createTypeQueryNodeFromSymbol(symbol);
}
else if (contains(context.symbolStack, symbol)) {
// If type is an anonymous type literal in a type alias declaration, use type alias name
@@ -2477,12 +2477,9 @@ namespace ts {
return createTypeLiteralNode(members);
}
function createTypeQueryNodeFromType(type: Type) {
const symbol = type.symbol;
if (symbol) {
const entityName = symbolToName(symbol, /*expectsIdentifier*/ false);
return createTypeQueryNode(entityName);
}
function createTypeQueryNodeFromSymbol(symbol: Symbol) {
const entityName = symbolToName(symbol, /*expectsIdentifier*/ false);
return createTypeQueryNode(entityName);
}
function typeReferenceToTypeNode(type: TypeReference) {
@@ -2542,7 +2539,7 @@ namespace ts {
entityName = nameIdentifier;
}
const typeParameterCount = (type.target.typeParameters || emptyArray).length;
const typeArgumentNodes = typeArguments.length > 0 ? mapToTypeNodeArray(typeArguments.slice(i, typeParameterCount - i)) : undefined;
const typeArgumentNodes = some(typeArguments) ? mapToTypeNodeArray(typeArguments.slice(i, typeParameterCount - i)) : undefined;
return createTypeReferenceNode(entityName, typeArgumentNodes);
}
}
@@ -2604,13 +2601,13 @@ namespace ts {
const name = getNameFromIndexInfo(indexInfo);
const indexingParameter = createParameter(
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
/*decorators*/ undefined,
/*modifiers*/ undefined,
/*dotDotDotToken*/ undefined,
name,
/*questionToken*/ undefined,
/*questionToken*/ undefined,
indexerTypeNode,
/*initializer*/ undefined);
/*initializer*/ undefined);
const typeNode = typeToTypeNodeHelper(indexInfo.type);
return createIndexSignatureDeclaration(
[indexingParameter],
@@ -2623,21 +2620,14 @@ namespace ts {
const typeParameters = signature.typeParameters && signature.typeParameters.map(parameter => typeParameterToDeclaration(parameter));
const parameters = signature.parameters.map(parameter => symbolToParameterDeclaration(parameter));
const returnTypeNode = typeToTypeNodeExceptAny(getReturnTypeOfSignature(signature));
const returnType = getReturnTypeOfSignature(signature);
const returnTypeNode = returnType && typeToTypeNodeHelper(returnType);
const returnTypeNodeExceptAny = returnTypeNode && returnTypeNode.kind !== SyntaxKind.AnyKeyword ? returnTypeNode : undefined;
return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNode);
function typeToTypeNodeExceptAny(type: Type): TypeNode | undefined {
const typeNode = type && typeToTypeNodeHelper(type);
return typeNode && typeNode.kind !== SyntaxKind.AnyKeyword ? typeNode : undefined;
}
return createSignatureDeclaration(kind, typeParameters, parameters, returnTypeNodeExceptAny);
}
function typeParameterToDeclaration(type: TypeParameter): TypeParameterDeclaration {
if (!(type && type.symbol && type.flags & TypeFlags.TypeParameter)) {
return undefined;
}
const constraint = getConstraintFromTypeParameter(type);
const constraintNode = constraint && typeToTypeNodeHelper(constraint);
const defaultParameter = getDefaultFromTypeParameter(type);
@@ -2647,10 +2637,10 @@ namespace ts {
}
function symbolToParameterDeclaration(parameterSymbol: Symbol): ParameterDeclaration {
const parameterDeclaration = parameterSymbol.declarations[0] as ParameterDeclaration;
const parameterDeclaration = <ParameterDeclaration>getDeclarationOfKind(parameterSymbol, SyntaxKind.Parameter);
const parameterType = getTypeOfSymbol(parameterSymbol);
const parameterTypeNode = typeToTypeNodeHelper(parameterType);
// TODO(aozgaa): check initializer accessibility correctly.
// TODO(aozgaa): In the future, check initializer accessibility.
const parameterNode = createParameter(
parameterDeclaration.decorators,
parameterDeclaration.modifiers,
@@ -2666,7 +2656,6 @@ namespace ts {
function symbolToName(symbol: Symbol, expectsIdentifier: true): Identifier;
function symbolToName(symbol: Symbol, expectsIdentifier: false): EntityName;
function symbolToName(symbol: Symbol, expectsIdentifier: boolean): EntityName {
let parentSymbol: Symbol;
// Try to get qualified name if the symbol is not a type parameter and there is an enclosing declaration.
let chain: Symbol[];
@@ -2679,8 +2668,6 @@ namespace ts {
chain = [symbol];
}
parentSymbol = undefined;
if (expectsIdentifier && chain.length !== 1
&& !context.encounteredError
&& !(context.flags & NodeBuilderFlags.allowQualifedNameInPlaceOfIdentifier)) {
@@ -2728,6 +2715,7 @@ namespace ts {
/** @param endOfChain Set to false for recursive calls; non-recursive calls should always output something. */
function getSymbolChain(symbol: Symbol, meaning: SymbolFlags, endOfChain: boolean): Symbol[] | undefined {
let accessibleSymbolChain = getAccessibleSymbolChain(symbol, context.enclosingDeclaration, meaning, /*useOnlyExternalAliasing*/false);
let parentSymbol: Symbol;
if (!accessibleSymbolChain ||
needsQualification(accessibleSymbolChain[0], context.enclosingDeclaration, accessibleSymbolChain.length === 1 ? meaning : getQualifiedLeftMeaning(meaning))) {
@@ -2737,6 +2725,7 @@ namespace ts {
if (parent) {
const parentChain = getSymbolChain(parent, getQualifiedLeftMeaning(meaning), /*endOfChain*/ false);
if (parentChain) {
parentSymbol = parent;
accessibleSymbolChain = parentChain.concat(accessibleSymbolChain || [symbol]);
}
}
@@ -2745,8 +2734,7 @@ namespace ts {
if (accessibleSymbolChain) {
return accessibleSymbolChain;
}
else if (
if (
// If this is the last part of outputting the symbol, always output. The cases apply only to parent symbols.
endOfChain ||
// If a parent symbol is an external module, don't write it. (We prefer just `x` vs `"foo/bar".x`.)
@@ -2759,8 +2747,8 @@ namespace ts {
}
function getNameOfSymbol(symbol: Symbol): string {
if (symbol.declarations && symbol.declarations.length) {
const declaration = symbol.declarations[0];
const declaration = firstOrUndefined(symbol.declarations);
if (declaration) {
if (declaration.name) {
return declarationNameToString(declaration.name);
}

View File

@@ -46,9 +46,6 @@ namespace ts {
*/
/* @internal */
export function getSynthesizedClone<T extends Node>(node: T | undefined): T {
if (node === undefined) {
return undefined;
}
// We don't use "clone" from core.ts here, as we need to preserve the prototype chain of
// the original node. We also need to exclude specific properties and only include own-
// properties (to skip members already defined on the shared prototype).
@@ -169,23 +166,23 @@ namespace ts {
// Reserved words
export function createSuper() {
return <PrimaryExpression>createSynthesizedNode(SyntaxKind.SuperKeyword);
return <SuperExpression>createSynthesizedNode(SyntaxKind.SuperKeyword);
}
export function createThis() {
return <PrimaryExpression & TypeNode>createSynthesizedNode(SyntaxKind.ThisKeyword);
return <ThisExpression & Token<SyntaxKind.ThisKeyword>>createSynthesizedNode(SyntaxKind.ThisKeyword);
}
export function createNull() {
return <PrimaryExpression & TypeNode>createSynthesizedNode(SyntaxKind.NullKeyword);
return <NullLiteral & Token<SyntaxKind.NullKeyword>>createSynthesizedNode(SyntaxKind.NullKeyword);
}
export function createTrue() {
return <BooleanLiteral & TypeNode>createSynthesizedNode(SyntaxKind.TrueKeyword);
return <BooleanLiteral & Token<SyntaxKind.TrueKeyword>>createSynthesizedNode(SyntaxKind.TrueKeyword);
}
export function createFalse() {
return <BooleanLiteral & TypeNode>createSynthesizedNode(SyntaxKind.FalseKeyword);
return <BooleanLiteral & Token<SyntaxKind.FalseKeyword>>createSynthesizedNode(SyntaxKind.FalseKeyword);
}
// Names
@@ -218,11 +215,74 @@ namespace ts {
// Type Elements
// TODO: add signatures
export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
const signatureDeclaration = createSynthesizedNode(kind) as SignatureDeclaration;
signatureDeclaration.typeParameters = asNodeArray(typeParameters);
signatureDeclaration.parameters = asNodeArray(parameters);
signatureDeclaration.type = type;
return signatureDeclaration;
}
function updateSignatureDeclaration(node: SignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return node.typeParameters !== typeParameters
|| node.parameters !== parameters
|| node.type !== type
? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node)
: node;
}
export function createFunctionTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode;
}
export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return <FunctionTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode;
}
export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return <ConstructorTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createCallSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration;
}
export function updateCallSignatureDeclaration(node: CallSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return <CallSignatureDeclaration>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createConstructSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration;
}
export function updateConstructSignatureDeclaration(node: ConstructSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return <ConstructSignatureDeclaration>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined) {
const methodSignature = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature;
methodSignature.name = asName(name);
methodSignature.questionToken = questionToken;
return methodSignature;
}
export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined, name: PropertyName, questionToken: QuestionToken | undefined) {
return node.typeParameters !== typeParameters
|| node.parameters !== parameters
|| node.type !== type
|| node.name !== name
|| node.questionToken !== questionToken
? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node)
: node;
}
// Types
export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]): KeywordTypeNode {
export function createKeywordTypeNode(kind: KeywordTypeNode["kind"]) {
return <KeywordTypeNode>createSynthesizedNode(kind);
}
@@ -259,10 +319,10 @@ namespace ts {
}
export function updateTypeQueryNode(node: TypeQueryNode, exprName: EntityName) {
return node.exprName !== exprName ? updateNode(createTypeQueryNode(exprName) , node) : node;
return node.exprName !== exprName ? updateNode(createTypeQueryNode(exprName), node) : node;
}
export function createArrayTypeNode(elementType: TypeNode): ArrayTypeNode {
export function createArrayTypeNode(elementType: TypeNode) {
const arrayTypeNode = createSynthesizedNode(SyntaxKind.ArrayType) as ArrayTypeNode;
arrayTypeNode.elementType = elementType;
return arrayTypeNode;
@@ -277,9 +337,9 @@ namespace ts {
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType, types: TypeNode[]): UnionTypeNode;
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.IntersectionType, types: TypeNode[]): IntersectionTypeNode;
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]): UnionOrIntersectionTypeNode;
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]): UnionOrIntersectionTypeNode {
export function createUnionOrIntersectionTypeNode(kind: SyntaxKind.UnionType | SyntaxKind.IntersectionType, types: TypeNode[]) {
const unionTypeNode = createSynthesizedNode(kind) as UnionTypeNode | IntersectionTypeNode;
unionTypeNode.types = asNodeArray(types);
unionTypeNode.types = createNodeArray(types);
return unionTypeNode;
}
@@ -291,7 +351,7 @@ namespace ts {
export function createTypeLiteralNode(members: TypeElement[]) {
const typeLiteralNode = createSynthesizedNode(SyntaxKind.TypeLiteral) as TypeLiteralNode;
typeLiteralNode.members = asNodeArray(members);
typeLiteralNode.members = createNodeArray(members);
return typeLiteralNode;
}
@@ -303,7 +363,7 @@ namespace ts {
export function createTupleTypeNode(elementTypes: TypeNode[]) {
const tupleTypeNode = createSynthesizedNode(SyntaxKind.TupleType) as TupleTypeNode;
tupleTypeNode.elementTypes = asNodeArray(elementTypes);
tupleTypeNode.elementTypes = createNodeArray(elementTypes);
return tupleTypeNode;
}
@@ -349,7 +409,6 @@ namespace ts {
return indexedAccessTypeNode;
}
export function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode) {
return node.objectType !== objectType
|| node.indexType !== indexType
@@ -357,86 +416,22 @@ namespace ts {
: node;
}
// Type Declarations
export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultParameter: TypeNode | undefined) {
export function createTypeParameterDeclaration(name: string | Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) {
const typeParameter = createSynthesizedNode(SyntaxKind.TypeParameter) as TypeParameterDeclaration;
typeParameter.name = asName(name);
typeParameter.constraint = constraint;
typeParameter.default = defaultParameter;
typeParameter.default = defaultType;
return typeParameter;
}
export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultParameter: TypeNode | undefined) {
export function updateTypeParameterDeclaration(node: TypeParameterDeclaration, name: Identifier, constraint: TypeNode | undefined, defaultType: TypeNode | undefined) {
return node.name !== name
|| node.constraint !== constraint
|| node.default !== defaultParameter
? updateNode(createTypeParameterDeclaration(name, constraint, defaultParameter), node)
: node;
}
// TODO: Split according to AST nodes.
export function createSignatureDeclaration(kind: SyntaxKind, typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined) {
const signatureDeclaration = createSynthesizedNode(kind) as SignatureDeclaration;
signatureDeclaration.typeParameters = asNodeArray(typeParameters);
signatureDeclaration.parameters = asNodeArray(parameters);
signatureDeclaration.type = type;
return signatureDeclaration;
}
export function updateSignatureDeclaration(node: SignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined) {
return node.typeParameters !== typeParameters
|| node.parameters !== parameters
|| node.type !== type
? updateNode(createSignatureDeclaration(node.kind, typeParameters, parameters, type), node)
: node;
}
export function createFunctionTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): FunctionTypeNode {
return createSignatureDeclaration(SyntaxKind.FunctionType, typeParameters, parameters, type) as FunctionTypeNode;
}
export function updateFunctionTypeNode(node: FunctionTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): FunctionTypeNode {
return <FunctionTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createConstructorTypeNode(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): ConstructorTypeNode {
return createSignatureDeclaration(SyntaxKind.ConstructorType, typeParameters, parameters, type) as ConstructorTypeNode;
}
export function updateConstructorTypeNode(node: ConstructorTypeNode, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): ConstructorTypeNode {
return <ConstructorTypeNode>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createCallSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): CallSignatureDeclaration {
return createSignatureDeclaration(SyntaxKind.CallSignature, typeParameters, parameters, type) as CallSignatureDeclaration;
}
export function updateCallSignatureDeclaration(node: CallSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): CallSignatureDeclaration {
return <CallSignatureDeclaration>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createConstructSignatureDeclaration(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined): ConstructSignatureDeclaration {
return createSignatureDeclaration(SyntaxKind.ConstructSignature, typeParameters, parameters, type) as ConstructSignatureDeclaration;
}
export function updateConstructSignatureDeclaration(node: ConstructSignatureDeclaration, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined): ConstructSignatureDeclaration {
return <ConstructSignatureDeclaration>updateSignatureDeclaration(node, typeParameters, parameters, type);
}
export function createMethodSignature(typeParameters: TypeParameterDeclaration[] | undefined, parameters: ParameterDeclaration[], type: TypeNode | undefined, name: string | PropertyName, questionToken: QuestionToken | undefined): MethodSignature {
const methodSignature = createSignatureDeclaration(SyntaxKind.MethodSignature, typeParameters, parameters, type) as MethodSignature;
methodSignature.name = asName(name);
methodSignature.questionToken = questionToken;
return methodSignature;
}
export function updateMethodSignature(node: MethodSignature, typeParameters: NodeArray<TypeParameterDeclaration> | undefined, parameters: NodeArray<ParameterDeclaration>, type: TypeNode | undefined, name?: PropertyName, questionToken?: QuestionToken): MethodSignature {
return node.typeParameters !== typeParameters
|| node.parameters !== parameters
|| node.type !== type
|| node.name !== name
|| node.questionToken !== questionToken
? updateNode(createMethodSignature(typeParameters, parameters, type, name, questionToken), node)
|| node.default !== defaultType
? updateNode(createTypeParameterDeclaration(name, constraint, defaultType), node)
: node;
}

View File

@@ -1034,15 +1034,15 @@ namespace ts {
_primaryExpressionBrand: any;
}
export interface NullLiteral extends PrimaryExpression {
export interface NullLiteral extends PrimaryExpression, TypeNode {
kind: SyntaxKind.NullKeyword;
}
export interface BooleanLiteral extends PrimaryExpression {
export interface BooleanLiteral extends PrimaryExpression, TypeNode {
kind: SyntaxKind.TrueKeyword | SyntaxKind.FalseKeyword;
}
export interface ThisExpression extends PrimaryExpression {
export interface ThisExpression extends PrimaryExpression, TypeNode {
kind: SyntaxKind.ThisKeyword;
}