From 7ef2cfeaebe48dc6e996f56b4d917591c0c9996a Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Tue, 2 Jun 2015 16:05:01 -0700 Subject: [PATCH] Simple changes to the compiler to make the jsDoc work easier. --- src/compiler/binder.ts | 10 ++--- src/compiler/checker.ts | 77 +++++++++++++++++++++++---------------- src/compiler/emitter.ts | 4 +- src/compiler/utilities.ts | 8 ---- 4 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 82cfd59a5d6..b6352d14efd 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -111,12 +111,12 @@ module ts { return (node.name).text; } switch (node.kind) { - case SyntaxKind.ConstructorType: case SyntaxKind.Constructor: return "__constructor"; case SyntaxKind.FunctionType: case SyntaxKind.CallSignature: return "__call"; + case SyntaxKind.ConstructorType: case SyntaxKind.ConstructSignature: return "__new"; case SyntaxKind.IndexSignature: @@ -380,7 +380,7 @@ module ts { let typeLiteralSymbol = createSymbol(SymbolFlags.TypeLiteral, "__type"); addDeclarationToSymbol(typeLiteralSymbol, node, SymbolFlags.TypeLiteral); typeLiteralSymbol.members = {}; - typeLiteralSymbol.members[node.kind === SyntaxKind.FunctionType ? "__call" : "__new"] = symbol + typeLiteralSymbol.members[symbol.name] = symbol } function bindAnonymousDeclaration(node: Declaration, symbolKind: SymbolFlags, name: string, isBlockScopeContainer: boolean) { @@ -592,10 +592,8 @@ module ts { bindChildren(node, 0, /*isBlockScopeContainer*/ true); break; default: - let saveParent = parent; - parent = node; - forEachChild(node, bind); - parent = saveParent; + bindChildren(node, 0, /*isBlockScopeContainer:*/ false); + break; } } diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c6c2373f706..fad7293412e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1799,11 +1799,12 @@ module ts { } function buildParameterDisplay(p: Symbol, writer: SymbolWriter, enclosingDeclaration?: Node, flags?: TypeFormatFlags, typeStack?: Type[]) { - if (hasDotDotDotToken(p.valueDeclaration)) { + let parameterNode = p.valueDeclaration; + if (isRestParameter(parameterNode)) { writePunctuation(writer, SyntaxKind.DotDotDotToken); } appendSymbolNameOnly(p, writer); - if (hasQuestionToken(p.valueDeclaration) || (p.valueDeclaration).initializer) { + if (isOptionalParameter(parameterNode)) { writePunctuation(writer, SyntaxKind.QuestionToken); } writePunctuation(writer, SyntaxKind.ColonToken); @@ -3197,6 +3198,10 @@ module ts { return result; } + function isOptionalParameter(node: ParameterDeclaration) { + return hasQuestionToken(node) || !!node.initializer; + } + function getSignatureFromDeclaration(declaration: SignatureDeclaration): Signature { let links = getNodeLinks(declaration); if (!links.resolvedSignature) { @@ -3244,7 +3249,7 @@ module ts { } links.resolvedSignature = createSignature(declaration, typeParameters, parameters, returnType, - minArgumentCount, hasRestParameters(declaration), hasStringLiterals); + minArgumentCount, hasRestParameter(declaration), hasStringLiterals); } return links.resolvedSignature; } @@ -3520,42 +3525,50 @@ module ts { type = unknownType; } else { - type = getDeclaredTypeOfSymbol(symbol); - if (type.flags & (TypeFlags.Class | TypeFlags.Interface) && type.flags & TypeFlags.Reference) { - // In a type reference, the outer type parameters of the referenced class or interface are automatically - // supplied as type arguments and the type reference only specifies arguments for the local type parameters - // of the class or interface. - let localTypeParameters = (type).localTypeParameters; - let expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; - let typeArgCount = node.typeArguments ? node.typeArguments.length : 0; - if (typeArgCount === expectedTypeArgCount) { - // When no type arguments are expected we already have the right type because all outer type parameters - // have themselves as default type arguments. - if (typeArgCount) { - type = createTypeReference(type, concatenate((type).outerTypeParameters, - map(node.typeArguments, getTypeFromTypeNode))); - } - } - else { - error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), expectedTypeArgCount); - type = undefined; - } - } - else { - if (node.typeArguments) { - error(node, Diagnostics.Type_0_is_not_generic, typeToString(type)); - type = undefined; - } - } + type = createTypeReferenceIfGeneric( + getDeclaredTypeOfSymbol(symbol), + node, node.typeArguments); } } } links.resolvedType = type || unknownType; } + return links.resolvedType; } + function createTypeReferenceIfGeneric(type: Type, node: Node, typeArguments: NodeArray): Type { + if (type.flags & (TypeFlags.Class | TypeFlags.Interface) && type.flags & TypeFlags.Reference) { + // In a type reference, the outer type parameters of the referenced class or interface are automatically + // supplied as type arguments and the type reference only specifies arguments for the local type parameters + // of the class or interface. + let localTypeParameters = (type).localTypeParameters; + let expectedTypeArgCount = localTypeParameters ? localTypeParameters.length : 0; + let typeArgCount = typeArguments ? typeArguments.length : 0; + if (typeArgCount === expectedTypeArgCount) { + // When no type arguments are expected we already have the right type because all outer type parameters + // have themselves as default type arguments. + if (typeArgCount) { + return createTypeReference(type, concatenate((type).outerTypeParameters, + map(typeArguments, getTypeFromTypeNode))); + } + } + else { + error(node, Diagnostics.Generic_type_0_requires_1_type_argument_s, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType), expectedTypeArgCount); + return undefined; + } + } + else { + if (typeArguments) { + error(node, Diagnostics.Type_0_is_not_generic, typeToString(type)); + return undefined; + } + } + + return type; + } + function getTypeFromTypeQueryNode(node: TypeQueryNode): Type { let links = getNodeLinks(node); if (!links.resolvedType) { @@ -5858,7 +5871,7 @@ module ts { let contextualSignature = getContextualSignature(func); if (contextualSignature) { - let funcHasRestParameters = hasRestParameters(func); + let funcHasRestParameters = hasRestParameter(func); let len = func.parameters.length - (funcHasRestParameters ? 1 : 0); let indexOfParameter = indexOf(func.parameters, parameter); if (indexOfParameter < len) { @@ -9330,7 +9343,7 @@ module ts { function checkCollisionWithArgumentsInGeneratedCode(node: SignatureDeclaration) { // no rest parameters \ declaration context \ overload - no codegen impact - if (!hasRestParameters(node) || isInAmbientContext(node) || nodeIsMissing((node).body)) { + if (!hasRestParameter(node) || isInAmbientContext(node) || nodeIsMissing((node).body)) { return; } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 92afacdafca..d0d65aec2fb 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -3205,7 +3205,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { } function emitRestParameter(node: FunctionLikeDeclaration) { - if (languageVersion < ScriptTarget.ES6 && hasRestParameters(node)) { + if (languageVersion < ScriptTarget.ES6 && hasRestParameter(node)) { let restIndex = node.parameters.length - 1; let restParam = node.parameters[restIndex]; @@ -3333,7 +3333,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { write("("); if (node) { let parameters = node.parameters; - let omitCount = languageVersion < ScriptTarget.ES6 && hasRestParameters(node) ? 1 : 0; + let omitCount = languageVersion < ScriptTarget.ES6 && hasRestParameter(node) ? 1 : 0; emitList(parameters, 0, parameters.length - omitCount, /*multiLine*/ false, /*trailingComma*/ false); } write(")"); diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 6ac59b6a6ea..133be3d3d83 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -963,10 +963,6 @@ module ts { } } - export function hasDotDotDotToken(node: Node) { - return node && node.kind === SyntaxKind.Parameter && (node).dotDotDotToken !== undefined; - } - export function hasQuestionToken(node: Node) { if (node) { switch (node.kind) { @@ -986,10 +982,6 @@ module ts { return false; } - export function hasRestParameters(s: SignatureDeclaration): boolean { - return s.parameters.length > 0 && lastOrUndefined(s.parameters).dotDotDotToken !== undefined; - } - export function isJSDocConstructSignature(node: Node) { return node.kind === SyntaxKind.JSDocFunctionType && (node).parameters.length > 0 &&