diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 71aa2ce1a07..b6efabcd6ef 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -118,10 +118,7 @@ namespace ts { let globalIterableIteratorType: GenericType; let anyArrayType: Type; - let getGlobalClassDecoratorType: () => ObjectType; - let getGlobalParameterDecoratorType: () => ObjectType; - let getGlobalPropertyDecoratorType: () => ObjectType; - let getGlobalMethodDecoratorType: () => ObjectType; + let getGlobalTypedPropertyDescriptorType: () => ObjectType; let tupleTypes: Map = {}; let unionTypes: Map = {}; @@ -3793,6 +3790,16 @@ namespace ts { return globalESSymbolConstructorSymbol || (globalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol")); } + /** + * Creates a TypeReference for a generic `TypedPropertyDescriptor`. + */ + function createTypedPropertyDescriptorType(propertyType: Type): Type { + let globalTypedPropertyDescriptorType = getGlobalTypedPropertyDescriptorType(); + return globalTypedPropertyDescriptorType !== emptyObjectType + ? createTypeReference(globalTypedPropertyDescriptorType, [propertyType]) + : emptyObjectType; + } + /** * Instantiates a global type that is generic with some element type, and returns that instantiation. */ @@ -4276,8 +4283,8 @@ namespace ts { return checkTypeRelatedTo(source, target, subtypeRelation, errorNode, headMessage, containingMessageChain); } - function checkTypeAssignableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage): boolean { - return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage); + function checkTypeAssignableTo(source: Type, target: Type, errorNode: Node, headMessage?: DiagnosticMessage, containingMessageChain?: DiagnosticMessageChain): boolean { + return checkTypeRelatedTo(source, target, assignableRelation, errorNode, headMessage, containingMessageChain); } function isSignatureAssignableTo(source: Signature, target: Signature): boolean { @@ -6938,7 +6945,7 @@ namespace ts { if (node.kind === SyntaxKind.TaggedTemplateExpression) { checkExpression((node).template); } - else { + else if (node.kind !== SyntaxKind.Decorator) { forEach((node).arguments, argument => { checkExpression(argument); }); @@ -7007,7 +7014,8 @@ namespace ts { function getSpreadArgumentIndex(args: Expression[]): number { for (let i = 0; i < args.length; i++) { - if (args[i].kind === SyntaxKind.SpreadElementExpression) { + let arg = args[i]; + if (arg && arg.kind === SyntaxKind.SpreadElementExpression) { return i; } } @@ -7018,7 +7026,9 @@ namespace ts { let adjustedArgCount: number; // Apparent number of arguments we will have in this call let typeArguments: NodeArray; // Type arguments (undefined if none) let callIsIncomplete: boolean; // In incomplete call we want to be lenient when we have too few arguments - + let isDecorator: boolean; + let spreadArgIndex = -1; + if (node.kind === SyntaxKind.TaggedTemplateExpression) { let tagExpression = node; @@ -7044,6 +7054,11 @@ namespace ts { callIsIncomplete = !!templateLiteral.isUnterminated; } } + else if (node.kind === SyntaxKind.Decorator) { + isDecorator = true; + typeArguments = undefined; + adjustedArgCount = getEffectiveArgumentCount(node, /*args*/ undefined, signature); + } else { let callExpression = node; if (!callExpression.arguments) { @@ -7060,6 +7075,7 @@ namespace ts { callIsIncomplete = (callExpression).arguments.end === callExpression.end; typeArguments = callExpression.typeArguments; + spreadArgIndex = getSpreadArgumentIndex(args); } // If the user supplied type arguments, but the number of type arguments does not match @@ -7072,7 +7088,6 @@ namespace ts { // If spread arguments are present, check that they correspond to a rest parameter. If so, no // further checking is necessary. - let spreadArgIndex = getSpreadArgumentIndex(args); if (spreadArgIndex >= 0) { return signature.hasRestParameter && spreadArgIndex >= signature.parameters.length - 1; } @@ -7109,7 +7124,7 @@ namespace ts { return getSignatureInstantiation(signature, getInferredTypes(context)); } - function inferTypeArguments(signature: Signature, args: Expression[], excludeArgument: boolean[], context: InferenceContext): void { + function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: Expression[], excludeArgument: boolean[], context: InferenceContext): void { let typeParameters = signature.typeParameters; let inferenceMapper = createInferenceMapper(context); @@ -7137,20 +7152,23 @@ namespace ts { // We perform two passes over the arguments. In the first pass we infer from all arguments, but use // wildcards for all context sensitive function expressions. - for (let i = 0; i < args.length; i++) { - let arg = args[i]; - if (arg.kind !== SyntaxKind.OmittedExpression) { + let argCount = getEffectiveArgumentCount(node, args, signature); + for (let i = 0; i < argCount; i++) { + let arg = getEffectiveArgument(node, args, i); + // If the effective argument is 'undefined', then it is an argument that is present but is synthetic. + if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) { let paramType = getTypeAtPosition(signature, i); - let argType: Type; - if (i === 0 && args[i].parent.kind === SyntaxKind.TaggedTemplateExpression) { - argType = globalTemplateStringsArrayType; - } - else { + let argType = getEffectiveArgumentType(node, i, arg); + + // If the effective argument type is 'undefined', there is no synthetic type + // for the argument. In that case, we should check the argument. + if (argType === undefined) { // For context sensitive arguments we pass the identityMapper, which is a signal to treat all // context sensitive function expressions as wildcards let mapper = excludeArgument && excludeArgument[i] !== undefined ? identityMapper : inferenceMapper; argType = checkExpressionWithContextualType(arg, paramType, mapper); } + inferTypes(context, argType, paramType); } } @@ -7158,8 +7176,10 @@ namespace ts { // In the second pass we visit only context sensitive arguments, and only those that aren't excluded, this // time treating function expressions normally (which may cause previously inferred type arguments to be fixed // as we construct types for contextually typed parameters) + // Decorators will not have `excludeArgument`, as their arguments cannot be contextually typed. + // Tagged template expressions will always have `undefined` for `excludeArgument[0]`. if (excludeArgument) { - for (let i = 0; i < args.length; i++) { + for (let i = 0; i < argCount; i++) { // No need to check for omitted args and template expressions, their exlusion value is always undefined if (excludeArgument[i] === false) { let arg = args[i]; @@ -7172,7 +7192,7 @@ namespace ts { getInferredTypes(context); } - function checkTypeArguments(signature: Signature, typeArguments: TypeNode[], typeArgumentResultTypes: Type[], reportErrors: boolean): boolean { + function checkTypeArguments(signature: Signature, typeArguments: TypeNode[], typeArgumentResultTypes: Type[], reportErrors: boolean, headMessage?: DiagnosticMessage): boolean { let typeParameters = signature.typeParameters; let typeArgumentsAreAssignable = true; for (let i = 0; i < typeParameters.length; i++) { @@ -7183,35 +7203,53 @@ namespace ts { if (typeArgumentsAreAssignable /* so far */) { let constraint = getConstraintOfTypeParameter(typeParameters[i]); if (constraint) { - typeArgumentsAreAssignable = checkTypeAssignableTo(typeArgument, constraint, reportErrors ? typeArgNode : undefined, - Diagnostics.Type_0_does_not_satisfy_the_constraint_1); + let errorInfo: DiagnosticMessageChain; + let typeArgumentHeadMessage = Diagnostics.Type_0_does_not_satisfy_the_constraint_1; + if (reportErrors && headMessage) { + errorInfo = chainDiagnosticMessages(errorInfo, typeArgumentHeadMessage); + typeArgumentHeadMessage = headMessage; + } + + typeArgumentsAreAssignable = checkTypeAssignableTo( + typeArgument, + constraint, + reportErrors ? typeArgNode : undefined, + typeArgumentHeadMessage, + errorInfo); } } } + return typeArgumentsAreAssignable; } function checkApplicableSignature(node: CallLikeExpression, args: Expression[], signature: Signature, relation: Map, excludeArgument: boolean[], reportErrors: boolean) { - for (let i = 0; i < args.length; i++) { - let arg = args[i]; - if (arg.kind !== SyntaxKind.OmittedExpression) { + let argCount = getEffectiveArgumentCount(node, args, signature); + for (let i = 0; i < argCount; i++) { + let arg = getEffectiveArgument(node, args, i); + // If the effective argument is 'undefined', then it is an argument that is present but is synthetic. + if (arg === undefined || arg.kind !== SyntaxKind.OmittedExpression) { // Check spread elements against rest type (from arity check we know spread argument corresponds to a rest parameter) let paramType = getTypeAtPosition(signature, i); - // A tagged template expression provides a special first argument, and string literals get string literal types - // unless we're reporting errors - let argType = i === 0 && node.kind === SyntaxKind.TaggedTemplateExpression - ? globalTemplateStringsArrayType - : arg.kind === SyntaxKind.StringLiteral && !reportErrors + let argType = getEffectiveArgumentType(node, i, arg); + + // If the effective argument type is 'undefined', there is no synthetic type + // for the argument. In that case, we should check the argument. + if (argType === undefined) { + argType = arg.kind === SyntaxKind.StringLiteral && !reportErrors ? getStringLiteralType(arg) : checkExpressionWithContextualType(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined); + } // Use argument expression as error location when reporting errors - if (!checkTypeRelatedTo(argType, paramType, relation, reportErrors ? arg : undefined, - Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1)) { + let errorNode = reportErrors ? getEffectiveArgumentErrorNode(node, i, arg) : undefined; + let headMessage = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1; + if (!checkTypeRelatedTo(argType, paramType, relation, errorNode, headMessage)) { return false; } } } + return true; } @@ -7220,20 +7258,27 @@ namespace ts { * * If 'node' is a CallExpression or a NewExpression, then its argument list is returned. * If 'node' is a TaggedTemplateExpression, a new argument list is constructed from the substitution - * expressions, where the first element of the list is the template for error reporting purposes. + * expressions, where the first element of the list is `undefined`. + * If 'node' is a Decorator, the argument list will be `undefined`, and its arguments and types + * will be supplied from calls to `getEffectiveArgumentCount` and `getEffectiveArgumentType`. */ function getEffectiveCallArguments(node: CallLikeExpression): Expression[] { let args: Expression[]; if (node.kind === SyntaxKind.TaggedTemplateExpression) { let template = (node).template; - args = [template]; - + args = [undefined]; if (template.kind === SyntaxKind.TemplateExpression) { forEach((template).templateSpans, span => { args.push(span.expression); }); } } + else if (node.kind === SyntaxKind.Decorator) { + // For a decorator, we return undefined as we will determine + // the number and types of arguments for a decorator using + // `getEffectiveArgumentCount` and `getEffectiveArgumentType` below. + return undefined; + } else { args = (node).arguments || emptyArray; } @@ -7241,12 +7286,284 @@ namespace ts { return args; } - function resolveCall(node: CallLikeExpression, signatures: Signature[], candidatesOutArray: Signature[]): Signature { + + /** + * Returns the effective argument count for a node that works like a function invocation. + * If 'node' is a Decorator, the number of arguments is derived from the decoration + * target and the signature: + * If 'node.target' is a class declaration or class expression, the effective argument + * count is 1. + * If 'node.target' is a parameter declaration, the effective argument count is 3. + * If 'node.target' is a property declaration, the effective argument count is 2. + * If 'node.target' is a method or accessor declaration, the effective argument count + * is 3, although it can be 2 if the signature only accepts two arguments, allowing + * us to match a property decorator. + * Otherwise, the argument count is the length of the 'args' array. + */ + function getEffectiveArgumentCount(node: CallLikeExpression, args: Expression[], signature: Signature) { + if (node.kind === SyntaxKind.Decorator) { + switch (node.parent.kind) { + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + // A class decorator will have one argument (see `ClassDecorator` in core.d.ts) + return 1; + + case SyntaxKind.PropertyDeclaration: + // A property declaration decorator will have two arguments (see + // `PropertyDecorator` in core.d.ts) + return 2; + + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + // A method or accessor declaration decorator will have two or three arguments (see + // `PropertyDecorator` and `MethodDecorator` in core.d.ts) + // If the method decorator signature only accepts a target and a key, we will only + // type check those arguments. + return signature.parameters.length >= 3 ? 3 : 2; + + case SyntaxKind.Parameter: + // A parameter declaration decorator will have three arguments (see + // `ParameterDecorator` in core.d.ts) + + return 3; + } + } + else { + return args.length; + } + } + + /** + * Returns the effective type of the first argument to a decorator. + * If 'node' is a class declaration or class expression, the effective argument type + * is the type of the static side of the class. + * If 'node' is a parameter declaration, the effective argument type is either the type + * of the static or instance side of the class for the parameter's parent method, + * depending on whether the method is declared static. + * For a constructor, the type is always the type of the static side of the class. + * If 'node' is a property, method, or accessor declaration, the effective argument + * type is the type of the static or instance side of the parent class for class + * element, depending on whether the element is declared static. + */ + function getEffectiveDecoratorFirstArgumentType(node: Node): Type { + // The first argument to a decorator is its `target`. + switch (node.kind) { + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + // For a class decorator, the `target` is the type of the class (e.g. the + // "static" or "constructor" side of the class) + let classSymbol = getSymbolOfNode(node); + return getTypeOfSymbol(classSymbol); + + case SyntaxKind.Parameter: + // For a parameter decorator, the `target` is the parent type of the + // parameter's containing method. + node = node.parent; + if (node.kind === SyntaxKind.Constructor) { + let classSymbol = getSymbolOfNode(node); + return getTypeOfSymbol(classSymbol); + } + + // fall-through + + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + // For a property or method decorator, the `target` is the + // "static"-side type of the parent of the member if the member is + // declared "static"; otherwise, it is the "instance"-side type of the + // parent of the member. + return getParentTypeOfClassElement(node); + + default: + Debug.fail("Unsupported decorator target."); + return unknownType; + } + } + + /** + * Returns the effective type for the second argument to a decorator. + * If 'node' is a parameter, its effective argument type is one of the following: + * If 'node.parent' is a constructor, the effective argument type is 'any', as we + * will emit `undefined`. + * If 'node.parent' is a member with an identifier, numeric, or string literal name, + * the effective argument type will be a string literal type for the member name. + * If 'node.parent' is a computed property name, the effective argument type will + * either be a symbol type or the string type. + * If 'node' is a member with an identifier, numeric, or string literal name, the + * effective argument type will be a string literal type for the member name. + * If 'node' is a computed property name, the effective argument type will either + * be a symbol type or the string type. + * A class decorator does not have a second argument type. + */ + function getEffectiveDecoratorSecondArgumentType(node: Node) { + // The second argument to a decorator is its `propertyKey` + switch (node.kind) { + case SyntaxKind.ClassDeclaration: + Debug.fail("Class decorators should not have a second synthetic argument."); + return unknownType; + + case SyntaxKind.Parameter: + node = node.parent; + if (node.kind === SyntaxKind.Constructor) { + // For a constructor parameter decorator, the `propertyKey` will be `undefined`. + return anyType; + } + + // For a non-constructor parameter decorator, the `propertyKey` will be either + // a string or a symbol, based on the name of the parameter's containing method. + + // fall-through + + case SyntaxKind.PropertyDeclaration: + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + // The `propertyKey` for a property or method decorator will be a + // string literal type if the member name is an identifier, number, or string; + // otherwise, if the member name is a computed property name it will + // be either string or symbol. + let element = node; + switch (element.name.kind) { + case SyntaxKind.Identifier: + case SyntaxKind.NumericLiteral: + case SyntaxKind.StringLiteral: + return getStringLiteralType(element.name); + + case SyntaxKind.ComputedPropertyName: + let nameType = checkComputedPropertyName(element.name); + if (allConstituentTypesHaveKind(nameType, TypeFlags.ESSymbol)) { + return nameType; + } + else { + return stringType; + } + + default: + Debug.fail("Unsupported property name."); + return unknownType; + } + + + default: + Debug.fail("Unsupported decorator target."); + return unknownType; + } + } + + /** + * Returns the effective argument type for the third argument to a decorator. + * If 'node' is a parameter, the effective argument type is the number type. + * If 'node' is a method or accessor, the effective argument type is a + * `TypedPropertyDescriptor` instantiated with the type of the member. + * Class and property decorators do not have a third effective argument. + */ + function getEffectiveDecoratorThirdArgumentType(node: Node) { + // The third argument to a decorator is either its `descriptor` for a method decorator + // or its `parameterIndex` for a paramter decorator + switch (node.kind) { + case SyntaxKind.ClassDeclaration: + Debug.fail("Class decorators should not have a third synthetic argument."); + return unknownType; + + case SyntaxKind.Parameter: + // The `parameterIndex` for a parameter decorator is always a number + return numberType; + + case SyntaxKind.PropertyDeclaration: + Debug.fail("Property decorators should not have a third synthetic argument."); + return unknownType; + + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + // The `descriptor` for a method decorator will be a `TypedPropertyDescriptor` + // for the type of the member. + let propertyType = getTypeOfNode(node); + return createTypedPropertyDescriptorType(propertyType); + + default: + Debug.fail("Unsupported decorator target."); + return unknownType; + } + } + + /** + * Returns the effective argument type for the provided argument to a decorator. + */ + function getEffectiveDecoratorArgumentType(node: Decorator, argIndex: number): Type { + if (argIndex === 0) { + return getEffectiveDecoratorFirstArgumentType(node.parent); + } + else if (argIndex === 1) { + return getEffectiveDecoratorSecondArgumentType(node.parent); + } + else if (argIndex === 2) { + return getEffectiveDecoratorThirdArgumentType(node.parent); + } + + Debug.fail("Decorators should not have a fourth synthetic argument."); + return unknownType; + } + + /** + * Gets the effective argument type for an argument in a call expression. + */ + function getEffectiveArgumentType(node: CallLikeExpression, argIndex: number, arg: Expression): Type { + // Decorators provide special arguments, a tagged template expression provides + // a special first argument, and string literals get string literal types + // unless we're reporting errors + if (node.kind === SyntaxKind.Decorator) { + return getEffectiveDecoratorArgumentType(node, argIndex); + } + else if (argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression) { + return globalTemplateStringsArrayType; + } + + // This is not a synthetic argument, so we return 'undefined' + // to signal that the caller needs to check the argument. + return undefined; + } + + /** + * Gets the effective argument expression for an argument in a call expression. + */ + function getEffectiveArgument(node: CallLikeExpression, args: Expression[], argIndex: number) { + // For a decorator or the first argument of a tagged template expression we return undefined. + if (node.kind === SyntaxKind.Decorator || + (argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression)) { + return undefined; + } + + return args[argIndex]; + } + + /** + * Gets the error node to use when reporting errors for an effective argument. + */ + function getEffectiveArgumentErrorNode(node: CallLikeExpression, argIndex: number, arg: Expression) { + if (node.kind === SyntaxKind.Decorator) { + // For a decorator, we use the expression of the decorator for error reporting. + return (node).expression; + } + else if (argIndex === 0 && node.kind === SyntaxKind.TaggedTemplateExpression) { + // For a the first argument of a tagged template expression, we use the template of the tag for error reporting. + return (node).template; + } + else { + return arg; + } + } + + function resolveCall(node: CallLikeExpression, signatures: Signature[], candidatesOutArray: Signature[], headMessage?: DiagnosticMessage): Signature { let isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression; + let isDecorator = node.kind === SyntaxKind.Decorator; let typeArguments: TypeNode[]; - if (!isTaggedTemplate) { + if (!isTaggedTemplate && !isDecorator) { typeArguments = (node).typeArguments; // We already perform checking on the type arguments on the class declaration itself. @@ -7259,7 +7576,7 @@ namespace ts { // reorderCandidates fills up the candidates array directly reorderCandidates(signatures, candidates); if (!candidates.length) { - error(node, Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target); + reportError(Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target); return resolveErrorCall(node); } @@ -7276,13 +7593,20 @@ namespace ts { // // For a tagged template, then the first argument be 'undefined' if necessary // because it represents a TemplateStringsArray. + // + // For a decorator, no arguments are susceptible to contextual typing due to the fact + // decorators are applied to a declaration by the emitter, and not to an expression. let excludeArgument: boolean[]; - for (let i = isTaggedTemplate ? 1 : 0; i < args.length; i++) { - if (isContextSensitive(args[i])) { - if (!excludeArgument) { - excludeArgument = new Array(args.length); + if (!isDecorator) { + // We do not need to call `getEffectiveArgumentCount` here as it only + // applies when calculating the number of arguments for a decorator. + for (let i = isTaggedTemplate ? 1 : 0; i < args.length; i++) { + if (isContextSensitive(args[i])) { + if (!excludeArgument) { + excludeArgument = new Array(args.length); + } + excludeArgument[i] = true; } - excludeArgument[i] = true; } } @@ -7349,8 +7673,8 @@ namespace ts { checkApplicableSignature(node, args, candidateForArgumentError, assignableRelation, /*excludeArgument*/ undefined, /*reportErrors*/ true); } else if (candidateForTypeArgumentError) { - if (!isTaggedTemplate && typeArguments) { - checkTypeArguments(candidateForTypeArgumentError, typeArguments, [], /*reportErrors*/ true) + if (!isTaggedTemplate && !isDecorator && typeArguments) { + checkTypeArguments(candidateForTypeArgumentError, (node).typeArguments, [], /*reportErrors*/ true, headMessage) } else { Debug.assert(resultOfFailedInference.failedTypeParameterIndex >= 0); @@ -7360,12 +7684,16 @@ namespace ts { let diagnosticChainHead = chainDiagnosticMessages(/*details*/ undefined, // details will be provided by call to reportNoCommonSupertypeError Diagnostics.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly, typeToString(failedTypeParameter)); + + if (headMessage) { + diagnosticChainHead = chainDiagnosticMessages(diagnosticChainHead, headMessage); + } reportNoCommonSupertypeError(inferenceCandidates, (node).expression || (node).tag, diagnosticChainHead); } } else { - error(node, Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target); + reportError(Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target); } // No signature was applicable. We have already reported the errors for the invalid signature. @@ -7382,6 +7710,16 @@ namespace ts { } return resolveErrorCall(node); + + function reportError(message: DiagnosticMessage, arg0?: string, arg1?: string, arg2?: string): void { + let errorInfo: DiagnosticMessageChain; + errorInfo = chainDiagnosticMessages(errorInfo, message, arg0, arg1, arg2); + if (headMessage) { + errorInfo = chainDiagnosticMessages(errorInfo, headMessage); + } + + diagnostics.add(createDiagnosticForNodeFromMessageChain(node, errorInfo)); + } function chooseOverload(candidates: Signature[], relation: Map) { for (let originalCandidate of candidates) { @@ -7404,7 +7742,7 @@ namespace ts { typeArgumentsAreValid = checkTypeArguments(candidate, typeArguments, typeArgumentTypes, /*reportErrors*/ false) } else { - inferTypeArguments(candidate, args, excludeArgument, inferenceContext); + inferTypeArguments(node, candidate, args, excludeArgument, inferenceContext); typeArgumentsAreValid = inferenceContext.failedTypeParameterIndex === undefined; typeArgumentTypes = inferenceContext.inferredTypes; } @@ -7588,6 +7926,55 @@ namespace ts { return resolveCall(node, callSignatures, candidatesOutArray); } + + /** + * Gets the localized diagnostic head message to use for errors when resolving a decorator as a call expression. + */ + function getDiagnosticHeadMessageForDecoratorResolution(node: Decorator) { + switch (node.parent.kind) { + case SyntaxKind.ClassDeclaration: + case SyntaxKind.ClassExpression: + return Diagnostics.Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression; + + case SyntaxKind.Parameter: + return Diagnostics.Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression; + + case SyntaxKind.PropertyDeclaration: + return Diagnostics.Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression; + + case SyntaxKind.MethodDeclaration: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return Diagnostics.Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression; + } + } + + /** + * Resolves a decorator as if it were a call expression. + */ + function resolveDecorator(node: Decorator, candidatesOutArray: Signature[]): Signature { + let funcType = checkExpression(node.expression); + let apparentType = getApparentType(funcType); + if (apparentType === unknownType) { + return resolveErrorCall(node); + } + + let callSignatures = getSignaturesOfType(apparentType, SignatureKind.Call); + if (funcType === anyType || (!callSignatures.length && !(funcType.flags & TypeFlags.Union) && isTypeAssignableTo(funcType, globalFunctionType))) { + return resolveUntypedCall(node); + } + + let headMessage = getDiagnosticHeadMessageForDecoratorResolution(node); + if (!callSignatures.length) { + let errorInfo: DiagnosticMessageChain; + errorInfo = chainDiagnosticMessages(errorInfo, Diagnostics.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature); + errorInfo = chainDiagnosticMessages(errorInfo, headMessage); + diagnostics.add(createDiagnosticForNodeFromMessageChain(node, errorInfo)); + return resolveErrorCall(node); + } + + return resolveCall(node, callSignatures, candidatesOutArray, headMessage); + } // candidatesOutArray is passed by signature help in the language service, and collectCandidates // must fill it up with the appropriate candidate signatures @@ -7609,6 +7996,9 @@ namespace ts { else if (node.kind === SyntaxKind.TaggedTemplateExpression) { links.resolvedSignature = resolveTaggedTemplateExpression(node, candidatesOutArray); } + else if (node.kind === SyntaxKind.Decorator) { + links.resolvedSignature = resolveDecorator(node, candidatesOutArray); + } else { Debug.fail("Branch in 'getResolvedSignature' should be unreachable."); } @@ -9404,35 +9794,54 @@ namespace ts { /** Check a decorator */ function checkDecorator(node: Decorator): void { - let expression: Expression = node.expression; - let exprType = checkExpression(expression); - + let signature = getResolvedSignature(node); + let returnType = getReturnTypeOfSignature(signature); + if (returnType.flags & TypeFlags.Any) { + return; + } + + let expectedReturnType: Type; + let headMessage = getDiagnosticHeadMessageForDecoratorResolution(node); + let errorInfo: DiagnosticMessageChain; switch (node.parent.kind) { case SyntaxKind.ClassDeclaration: let classSymbol = getSymbolOfNode(node.parent); let classConstructorType = getTypeOfSymbol(classSymbol); - let classDecoratorType = instantiateSingleCallFunctionType(getGlobalClassDecoratorType(), [classConstructorType]); - checkTypeAssignableTo(exprType, classDecoratorType, node); + expectedReturnType = getUnionType([classConstructorType, voidType]); break; + case SyntaxKind.Parameter: + expectedReturnType = voidType; + errorInfo = chainDiagnosticMessages( + errorInfo, + Diagnostics.The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any); + + break; + case SyntaxKind.PropertyDeclaration: - checkTypeAssignableTo(exprType, getGlobalPropertyDecoratorType(), node); + expectedReturnType = voidType; + errorInfo = chainDiagnosticMessages( + errorInfo, + Diagnostics.The_return_type_of_a_property_decorator_function_must_be_either_void_or_any); break; case SyntaxKind.MethodDeclaration: case SyntaxKind.GetAccessor: case SyntaxKind.SetAccessor: let methodType = getTypeOfNode(node.parent); - let methodDecoratorType = instantiateSingleCallFunctionType(getGlobalMethodDecoratorType(), [methodType]); - checkTypeAssignableTo(exprType, methodDecoratorType, node); - break; - - case SyntaxKind.Parameter: - checkTypeAssignableTo(exprType, getGlobalParameterDecoratorType(), node); + let descriptorType = createTypedPropertyDescriptorType(methodType); + expectedReturnType = getUnionType([descriptorType, voidType]); break; } + + checkTypeAssignableTo( + returnType, + expectedReturnType, + node, + headMessage, + errorInfo); } - + /** Checks a type reference node as an expression. */ function checkTypeNodeAsExpression(node: TypeNode) { // When we are emitting type metadata for decorators, we need to try to check the type @@ -12058,6 +12467,17 @@ namespace ts { return checkExpression(expr); } + /** + * Gets either the static or instance type of a class element, based on + * whether the element is declared as "static". + */ + function getParentTypeOfClassElement(node: ClassElement) { + let classSymbol = getSymbolOfNode(node.parent); + return node.flags & NodeFlags.Static + ? getTypeOfSymbol(classSymbol) + : getDeclaredTypeOfSymbol(classSymbol); + } + // Return the list of properties of the given type, augmented with properties from Function // if the type has call or construct signatures function getAugmentedPropertiesOfType(type: Type): Symbol[] { @@ -12594,10 +13014,7 @@ namespace ts { globalNumberType = getGlobalType("Number"); globalBooleanType = getGlobalType("Boolean"); globalRegExpType = getGlobalType("RegExp"); - getGlobalClassDecoratorType = memoize(() => getGlobalType("ClassDecorator")); - getGlobalPropertyDecoratorType = memoize(() => getGlobalType("PropertyDecorator")); - getGlobalMethodDecoratorType = memoize(() => getGlobalType("MethodDecorator")); - getGlobalParameterDecoratorType = memoize(() => getGlobalType("ParameterDecorator")); + getGlobalTypedPropertyDescriptorType = memoize(() => getGlobalType("TypedPropertyDescriptor", /*arity*/ 1)); // If we're in ES6 mode, load the TemplateStringsArray. // Otherwise, default to 'unknown' for the purposes of type checking in LS scenarios. diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index bfe103757c5..d94777fd561 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -191,6 +191,12 @@ namespace ts { An_export_declaration_can_only_be_used_in_a_module: { code: 1233, category: DiagnosticCategory.Error, key: "An export declaration can only be used in a module." }, An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: { code: 1234, category: DiagnosticCategory.Error, key: "An ambient module declaration is only allowed at the top level in a file." }, A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: { code: 1235, category: DiagnosticCategory.Error, key: "A namespace declaration is only allowed in a namespace or module." }, + The_return_type_of_a_property_decorator_function_must_be_either_void_or_any: { code: 1236, category: DiagnosticCategory.Error, key: "The return type of a property decorator function must be either 'void' or 'any'." }, + The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any: { code: 1237, category: DiagnosticCategory.Error, key: "The return type of a parameter decorator function must be either 'void' or 'any'." }, + Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression: { code: 1238, category: DiagnosticCategory.Error, key: "Unable to resolve signature of class decorator when called as an expression." }, + Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression: { code: 1239, category: DiagnosticCategory.Error, key: "Unable to resolve signature of parameter decorator when called as an expression." }, + Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression: { code: 1240, category: DiagnosticCategory.Error, key: "Unable to resolve signature of property decorator when called as an expression." }, + Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression: { code: 1241, category: DiagnosticCategory.Error, key: "Unable to resolve signature of method decorator when called as an expression." }, Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." }, Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." }, Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 3e4ef26507f..a4c9cb0fdda 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -753,6 +753,31 @@ }, + "The return type of a property decorator function must be either 'void' or 'any'.": { + "category": "Error", + "code": 1236 + }, + "The return type of a parameter decorator function must be either 'void' or 'any'.": { + "category": "Error", + "code": 1237 + }, + "Unable to resolve signature of class decorator when called as an expression.": { + "category": "Error", + "code": 1238 + }, + "Unable to resolve signature of parameter decorator when called as an expression.": { + "category": "Error", + "code": 1239 + }, + "Unable to resolve signature of property decorator when called as an expression.": { + "category": "Error", + "code": 1240 + }, + "Unable to resolve signature of method decorator when called as an expression.": { + "category": "Error", + "code": 1241 + }, + "Duplicate identifier '{0}'.": { "category": "Error", "code": 2300 diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f9a2fa3b7b4..d858e430ab6 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -797,7 +797,7 @@ namespace ts { template: LiteralExpression | TemplateExpression; } - export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression; + export type CallLikeExpression = CallExpression | NewExpression | TaggedTemplateExpression | Decorator; export interface TypeAssertion extends UnaryExpression { type: TypeNode; diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f9ecdbe43ba..4ebab1e91f1 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -752,8 +752,8 @@ namespace ts { return (node).tag; } - // Will either be a CallExpression or NewExpression. - return (node).expression; + // Will either be a CallExpression, NewExpression, or Decorator. + return (node).expression; } export function nodeCanBeDecorated(node: Node): boolean { diff --git a/tests/baselines/reference/decoratedClassFromExternalModule.js b/tests/baselines/reference/decoratedClassFromExternalModule.js index 163a4a094b4..aca1d28b952 100644 --- a/tests/baselines/reference/decoratedClassFromExternalModule.js +++ b/tests/baselines/reference/decoratedClassFromExternalModule.js @@ -1,7 +1,7 @@ //// [tests/cases/conformance/decorators/class/decoratedClassFromExternalModule.ts] //// //// [decorated.ts] -function decorate() { } +function decorate(target: any) { } @decorate export default class Decorated { } @@ -18,7 +18,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, case 4: return decorators.reduceRight(function(o, d) { return (d && d(target, key, o)) || o; }, desc); } }; -function decorate() { } +function decorate(target) { } let Decorated = class { }; Decorated = __decorate([ diff --git a/tests/baselines/reference/decoratedClassFromExternalModule.symbols b/tests/baselines/reference/decoratedClassFromExternalModule.symbols index aa17dde616a..60e4a892ec0 100644 --- a/tests/baselines/reference/decoratedClassFromExternalModule.symbols +++ b/tests/baselines/reference/decoratedClassFromExternalModule.symbols @@ -1,12 +1,13 @@ === tests/cases/conformance/decorators/class/decorated.ts === -function decorate() { } +function decorate(target: any) { } >decorate : Symbol(decorate, Decl(decorated.ts, 0, 0)) +>target : Symbol(target, Decl(decorated.ts, 0, 18)) @decorate >decorate : Symbol(decorate, Decl(decorated.ts, 0, 0)) export default class Decorated { } ->Decorated : Symbol(Decorated, Decl(decorated.ts, 0, 23)) +>Decorated : Symbol(Decorated, Decl(decorated.ts, 0, 34)) === tests/cases/conformance/decorators/class/undecorated.ts === import Decorated from 'decorated'; diff --git a/tests/baselines/reference/decoratedClassFromExternalModule.types b/tests/baselines/reference/decoratedClassFromExternalModule.types index 4234b6a4b15..d4bc3239e46 100644 --- a/tests/baselines/reference/decoratedClassFromExternalModule.types +++ b/tests/baselines/reference/decoratedClassFromExternalModule.types @@ -1,9 +1,10 @@ === tests/cases/conformance/decorators/class/decorated.ts === -function decorate() { } ->decorate : () => void +function decorate(target: any) { } +>decorate : (target: any) => void +>target : any @decorate ->decorate : () => void +>decorate : (target: any) => void export default class Decorated { } >Decorated : Decorated diff --git a/tests/baselines/reference/decoratorChecksFunctionBodies.errors.txt b/tests/baselines/reference/decoratorChecksFunctionBodies.errors.txt index c8166b538fd..cef2f90f704 100644 --- a/tests/baselines/reference/decoratorChecksFunctionBodies.errors.txt +++ b/tests/baselines/reference/decoratorChecksFunctionBodies.errors.txt @@ -8,7 +8,7 @@ tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts(9,14): } class A { - @(x => { + @((x, p) => { var a = 3; func(a); ~ diff --git a/tests/baselines/reference/decoratorChecksFunctionBodies.js b/tests/baselines/reference/decoratorChecksFunctionBodies.js index 020bc775aea..adb710efccc 100644 --- a/tests/baselines/reference/decoratorChecksFunctionBodies.js +++ b/tests/baselines/reference/decoratorChecksFunctionBodies.js @@ -5,7 +5,7 @@ function func(s: string): void { } class A { - @(x => { + @((x, p) => { var a = 3; func(a); return x; @@ -34,7 +34,7 @@ var A = (function () { }; Object.defineProperty(A.prototype, "m", __decorate([ - (function (x) { + (function (x, p) { var a = 3; func(a); return x; diff --git a/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.js b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.js index 313d77fa5ce..08ba6e9ea7e 100644 --- a/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.js +++ b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.js @@ -9,7 +9,7 @@ export var test = 'abc'; import { test } from './a'; function filter(handler: any) { - return function (target: any) { + return function (target: any, propertyKey: string) { // ... }; } @@ -35,7 +35,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, }; var a_1 = require('./a'); function filter(handler) { - return function (target) { + return function (target, propertyKey) { // ... }; } diff --git a/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.symbols b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.symbols index 5088e740a57..f7c96097caf 100644 --- a/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.symbols +++ b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.symbols @@ -12,8 +12,9 @@ function filter(handler: any) { >filter : Symbol(filter, Decl(b.ts, 0, 27)) >handler : Symbol(handler, Decl(b.ts, 2, 16)) - return function (target: any) { + return function (target: any, propertyKey: string) { >target : Symbol(target, Decl(b.ts, 3, 21)) +>propertyKey : Symbol(propertyKey, Decl(b.ts, 3, 33)) // ... }; diff --git a/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.types b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.types index 18d993af9bb..d0f930b7ad4 100644 --- a/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.types +++ b/tests/baselines/reference/decoratorInstantiateModulesInFunctionBodies.types @@ -10,12 +10,13 @@ import { test } from './a'; >test : string function filter(handler: any) { ->filter : (handler: any) => (target: any) => void +>filter : (handler: any) => (target: any, propertyKey: string) => void >handler : any - return function (target: any) { ->function (target: any) { // ... } : (target: any) => void + return function (target: any, propertyKey: string) { +>function (target: any, propertyKey: string) { // ... } : (target: any, propertyKey: string) => void >target : any +>propertyKey : string // ... }; @@ -25,8 +26,8 @@ class Wat { >Wat : Wat @filter(() => test == 'abc') ->filter(() => test == 'abc') : (target: any) => void ->filter : (handler: any) => (target: any) => void +>filter(() => test == 'abc') : (target: any, propertyKey: string) => void +>filter : (handler: any) => (target: any, propertyKey: string) => void >() => test == 'abc' : () => boolean >test == 'abc' : boolean >test : string diff --git a/tests/baselines/reference/decoratorOnClass8.errors.txt b/tests/baselines/reference/decoratorOnClass8.errors.txt index 0a9fbf2956c..f9ca7fca210 100644 --- a/tests/baselines/reference/decoratorOnClass8.errors.txt +++ b/tests/baselines/reference/decoratorOnClass8.errors.txt @@ -1,4 +1,5 @@ -tests/cases/conformance/decorators/class/decoratorOnClass8.ts(3,1): error TS2322: Type '(target: Function, paramIndex: number) => void' is not assignable to type '(target: typeof C) => void | typeof C'. +tests/cases/conformance/decorators/class/decoratorOnClass8.ts(3,1): error TS1238: Unable to resolve signature of class decorator when called as an expression. + Supplied parameters do not match any signature of call target. ==== tests/cases/conformance/decorators/class/decoratorOnClass8.ts (1 errors) ==== @@ -6,6 +7,7 @@ tests/cases/conformance/decorators/class/decoratorOnClass8.ts(3,1): error TS2322 @dec() ~~~~~~ -!!! error TS2322: Type '(target: Function, paramIndex: number) => void' is not assignable to type '(target: typeof C) => void | typeof C'. +!!! error TS1238: Unable to resolve signature of class decorator when called as an expression. +!!! error TS1238: Supplied parameters do not match any signature of call target. class C { } \ No newline at end of file diff --git a/tests/baselines/reference/decoratorOnClassMethod10.errors.txt b/tests/baselines/reference/decoratorOnClassMethod10.errors.txt index cd331473b7c..6499aa44e53 100644 --- a/tests/baselines/reference/decoratorOnClassMethod10.errors.txt +++ b/tests/baselines/reference/decoratorOnClassMethod10.errors.txt @@ -1,7 +1,5 @@ -tests/cases/conformance/decorators/class/method/decoratorOnClassMethod10.ts(4,5): error TS2322: Type '(target: Function, paramIndex: number) => void' is not assignable to type '(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<() => void>) => void | TypedPropertyDescriptor<() => void>'. - Types of parameters 'paramIndex' and 'propertyKey' are incompatible. - Type 'number' is not assignable to type 'string | symbol'. - Type 'number' is not assignable to type 'symbol'. +tests/cases/conformance/decorators/class/method/decoratorOnClassMethod10.ts(4,6): error TS2345: Argument of type 'C' is not assignable to parameter of type 'Function'. + Property 'apply' is missing in type 'C'. ==== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod10.ts (1 errors) ==== @@ -9,9 +7,7 @@ tests/cases/conformance/decorators/class/method/decoratorOnClassMethod10.ts(4,5) class C { @dec method() {} - ~~~~ -!!! error TS2322: Type '(target: Function, paramIndex: number) => void' is not assignable to type '(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<() => void>) => void | TypedPropertyDescriptor<() => void>'. -!!! error TS2322: Types of parameters 'paramIndex' and 'propertyKey' are incompatible. -!!! error TS2322: Type 'number' is not assignable to type 'string | symbol'. -!!! error TS2322: Type 'number' is not assignable to type 'symbol'. + ~~~ +!!! error TS2345: Argument of type 'C' is not assignable to parameter of type 'Function'. +!!! error TS2345: Property 'apply' is missing in type 'C'. } \ No newline at end of file diff --git a/tests/baselines/reference/decoratorOnClassMethod13.js b/tests/baselines/reference/decoratorOnClassMethod13.js index 967cc05ba4d..b39fa63686a 100644 --- a/tests/baselines/reference/decoratorOnClassMethod13.js +++ b/tests/baselines/reference/decoratorOnClassMethod13.js @@ -1,5 +1,5 @@ //// [decoratorOnClassMethod13.ts] -declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; +declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { @dec ["1"]() { } diff --git a/tests/baselines/reference/decoratorOnClassMethod13.symbols b/tests/baselines/reference/decoratorOnClassMethod13.symbols index af3819924f4..42f44d885ee 100644 --- a/tests/baselines/reference/decoratorOnClassMethod13.symbols +++ b/tests/baselines/reference/decoratorOnClassMethod13.symbols @@ -1,17 +1,17 @@ === tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts === -declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; +declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; >dec : Symbol(dec, Decl(decoratorOnClassMethod13.ts, 0, 0)) ->T : Symbol(T, Decl(decoratorOnClassMethod13.ts, 0, 25)) ->target : Symbol(target, Decl(decoratorOnClassMethod13.ts, 0, 28)) ->propertyKey : Symbol(propertyKey, Decl(decoratorOnClassMethod13.ts, 0, 40)) ->descriptor : Symbol(descriptor, Decl(decoratorOnClassMethod13.ts, 0, 61)) +>T : Symbol(T, Decl(decoratorOnClassMethod13.ts, 0, 21)) +>target : Symbol(target, Decl(decoratorOnClassMethod13.ts, 0, 24)) +>propertyKey : Symbol(propertyKey, Decl(decoratorOnClassMethod13.ts, 0, 36)) +>descriptor : Symbol(descriptor, Decl(decoratorOnClassMethod13.ts, 0, 57)) >TypedPropertyDescriptor : Symbol(TypedPropertyDescriptor, Decl(lib.d.ts, 1171, 36)) ->T : Symbol(T, Decl(decoratorOnClassMethod13.ts, 0, 25)) +>T : Symbol(T, Decl(decoratorOnClassMethod13.ts, 0, 21)) >TypedPropertyDescriptor : Symbol(TypedPropertyDescriptor, Decl(lib.d.ts, 1171, 36)) ->T : Symbol(T, Decl(decoratorOnClassMethod13.ts, 0, 25)) +>T : Symbol(T, Decl(decoratorOnClassMethod13.ts, 0, 21)) class C { ->C : Symbol(C, Decl(decoratorOnClassMethod13.ts, 0, 132)) +>C : Symbol(C, Decl(decoratorOnClassMethod13.ts, 0, 126)) @dec ["1"]() { } >dec : Symbol(dec, Decl(decoratorOnClassMethod13.ts, 0, 0)) diff --git a/tests/baselines/reference/decoratorOnClassMethod13.types b/tests/baselines/reference/decoratorOnClassMethod13.types index 2858f8877bd..5fdbe071828 100644 --- a/tests/baselines/reference/decoratorOnClassMethod13.types +++ b/tests/baselines/reference/decoratorOnClassMethod13.types @@ -1,6 +1,6 @@ === tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts === -declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; ->dec : () => (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor +declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; +>dec : (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor >T : T >target : any >propertyKey : string @@ -14,10 +14,10 @@ class C { >C : C @dec ["1"]() { } ->dec : () => (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor +>dec : (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor >"1" : string @dec ["b"]() { } ->dec : () => (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor +>dec : (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor >"b" : string } diff --git a/tests/baselines/reference/decoratorOnClassMethod6.errors.txt b/tests/baselines/reference/decoratorOnClassMethod6.errors.txt new file mode 100644 index 00000000000..c8ee66717ef --- /dev/null +++ b/tests/baselines/reference/decoratorOnClassMethod6.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts(4,5): error TS1241: Unable to resolve signature of method decorator when called as an expression. + Supplied parameters do not match any signature of call target. + + +==== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts (1 errors) ==== + declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; + + class C { + @dec ["method"]() {} + ~~~~ +!!! error TS1241: Unable to resolve signature of method decorator when called as an expression. +!!! error TS1241: Supplied parameters do not match any signature of call target. + } \ No newline at end of file diff --git a/tests/baselines/reference/decoratorOnClassMethod6.symbols b/tests/baselines/reference/decoratorOnClassMethod6.symbols deleted file mode 100644 index 8dcdd99a8e9..00000000000 --- a/tests/baselines/reference/decoratorOnClassMethod6.symbols +++ /dev/null @@ -1,18 +0,0 @@ -=== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts === -declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; ->dec : Symbol(dec, Decl(decoratorOnClassMethod6.ts, 0, 0)) ->T : Symbol(T, Decl(decoratorOnClassMethod6.ts, 0, 25)) ->target : Symbol(target, Decl(decoratorOnClassMethod6.ts, 0, 28)) ->propertyKey : Symbol(propertyKey, Decl(decoratorOnClassMethod6.ts, 0, 40)) ->descriptor : Symbol(descriptor, Decl(decoratorOnClassMethod6.ts, 0, 61)) ->TypedPropertyDescriptor : Symbol(TypedPropertyDescriptor, Decl(lib.d.ts, 1171, 36)) ->T : Symbol(T, Decl(decoratorOnClassMethod6.ts, 0, 25)) ->TypedPropertyDescriptor : Symbol(TypedPropertyDescriptor, Decl(lib.d.ts, 1171, 36)) ->T : Symbol(T, Decl(decoratorOnClassMethod6.ts, 0, 25)) - -class C { ->C : Symbol(C, Decl(decoratorOnClassMethod6.ts, 0, 132)) - - @dec ["method"]() {} ->dec : Symbol(dec, Decl(decoratorOnClassMethod6.ts, 0, 0)) -} diff --git a/tests/baselines/reference/decoratorOnClassMethod6.types b/tests/baselines/reference/decoratorOnClassMethod6.types deleted file mode 100644 index 9da71791763..00000000000 --- a/tests/baselines/reference/decoratorOnClassMethod6.types +++ /dev/null @@ -1,19 +0,0 @@ -=== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod6.ts === -declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; ->dec : () => (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor ->T : T ->target : any ->propertyKey : string ->descriptor : TypedPropertyDescriptor ->TypedPropertyDescriptor : TypedPropertyDescriptor ->T : T ->TypedPropertyDescriptor : TypedPropertyDescriptor ->T : T - -class C { ->C : C - - @dec ["method"]() {} ->dec : () => (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor ->"method" : string -} diff --git a/tests/baselines/reference/decoratorOnClassMethod8.errors.txt b/tests/baselines/reference/decoratorOnClassMethod8.errors.txt new file mode 100644 index 00000000000..f522dc01df9 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClassMethod8.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/decorators/class/method/decoratorOnClassMethod8.ts(4,5): error TS1241: Unable to resolve signature of method decorator when called as an expression. + Supplied parameters do not match any signature of call target. + + +==== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod8.ts (1 errors) ==== + declare function dec(target: T): T; + + class C { + @dec method() {} + ~~~~ +!!! error TS1241: Unable to resolve signature of method decorator when called as an expression. +!!! error TS1241: Supplied parameters do not match any signature of call target. + } \ No newline at end of file diff --git a/tests/baselines/reference/decoratorOnClassMethod8.symbols b/tests/baselines/reference/decoratorOnClassMethod8.symbols deleted file mode 100644 index 84b68b81421..00000000000 --- a/tests/baselines/reference/decoratorOnClassMethod8.symbols +++ /dev/null @@ -1,15 +0,0 @@ -=== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod8.ts === -declare function dec(target: T): T; ->dec : Symbol(dec, Decl(decoratorOnClassMethod8.ts, 0, 0)) ->T : Symbol(T, Decl(decoratorOnClassMethod8.ts, 0, 21)) ->target : Symbol(target, Decl(decoratorOnClassMethod8.ts, 0, 24)) ->T : Symbol(T, Decl(decoratorOnClassMethod8.ts, 0, 21)) ->T : Symbol(T, Decl(decoratorOnClassMethod8.ts, 0, 21)) - -class C { ->C : Symbol(C, Decl(decoratorOnClassMethod8.ts, 0, 38)) - - @dec method() {} ->dec : Symbol(dec, Decl(decoratorOnClassMethod8.ts, 0, 0)) ->method : Symbol(method, Decl(decoratorOnClassMethod8.ts, 2, 9)) -} diff --git a/tests/baselines/reference/decoratorOnClassMethod8.types b/tests/baselines/reference/decoratorOnClassMethod8.types deleted file mode 100644 index 20890b09846..00000000000 --- a/tests/baselines/reference/decoratorOnClassMethod8.types +++ /dev/null @@ -1,15 +0,0 @@ -=== tests/cases/conformance/decorators/class/method/decoratorOnClassMethod8.ts === -declare function dec(target: T): T; ->dec : (target: T) => T ->T : T ->target : T ->T : T ->T : T - -class C { ->C : C - - @dec method() {} ->dec : (target: T) => T ->method : () => void -} diff --git a/tests/baselines/reference/decoratorOnClassMethodParameter1.js b/tests/baselines/reference/decoratorOnClassMethodParameter1.js index 4a3ed36eec5..a6ab1704acc 100644 --- a/tests/baselines/reference/decoratorOnClassMethodParameter1.js +++ b/tests/baselines/reference/decoratorOnClassMethodParameter1.js @@ -1,5 +1,5 @@ //// [decoratorOnClassMethodParameter1.ts] -declare function dec(target: Function, propertyKey: string | symbol, parameterIndex: number): void; +declare function dec(target: Object, propertyKey: string | symbol, parameterIndex: number): void; class C { method(@dec p: number) {} diff --git a/tests/baselines/reference/decoratorOnClassMethodParameter1.symbols b/tests/baselines/reference/decoratorOnClassMethodParameter1.symbols index 0ced8829766..47c5999ff47 100644 --- a/tests/baselines/reference/decoratorOnClassMethodParameter1.symbols +++ b/tests/baselines/reference/decoratorOnClassMethodParameter1.symbols @@ -1,13 +1,13 @@ === tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts === -declare function dec(target: Function, propertyKey: string | symbol, parameterIndex: number): void; +declare function dec(target: Object, propertyKey: string | symbol, parameterIndex: number): void; >dec : Symbol(dec, Decl(decoratorOnClassMethodParameter1.ts, 0, 0)) >target : Symbol(target, Decl(decoratorOnClassMethodParameter1.ts, 0, 21)) ->Function : Symbol(Function, Decl(lib.d.ts, 223, 38), Decl(lib.d.ts, 269, 11)) ->propertyKey : Symbol(propertyKey, Decl(decoratorOnClassMethodParameter1.ts, 0, 38)) ->parameterIndex : Symbol(parameterIndex, Decl(decoratorOnClassMethodParameter1.ts, 0, 68)) +>Object : Symbol(Object, Decl(lib.d.ts, 92, 1), Decl(lib.d.ts, 223, 11)) +>propertyKey : Symbol(propertyKey, Decl(decoratorOnClassMethodParameter1.ts, 0, 36)) +>parameterIndex : Symbol(parameterIndex, Decl(decoratorOnClassMethodParameter1.ts, 0, 66)) class C { ->C : Symbol(C, Decl(decoratorOnClassMethodParameter1.ts, 0, 99)) +>C : Symbol(C, Decl(decoratorOnClassMethodParameter1.ts, 0, 97)) method(@dec p: number) {} >method : Symbol(method, Decl(decoratorOnClassMethodParameter1.ts, 2, 9)) diff --git a/tests/baselines/reference/decoratorOnClassMethodParameter1.types b/tests/baselines/reference/decoratorOnClassMethodParameter1.types index 0b75471471f..74aa04a8985 100644 --- a/tests/baselines/reference/decoratorOnClassMethodParameter1.types +++ b/tests/baselines/reference/decoratorOnClassMethodParameter1.types @@ -1,8 +1,8 @@ === tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts === -declare function dec(target: Function, propertyKey: string | symbol, parameterIndex: number): void; ->dec : (target: Function, propertyKey: string | symbol, parameterIndex: number) => void ->target : Function ->Function : Function +declare function dec(target: Object, propertyKey: string | symbol, parameterIndex: number): void; +>dec : (target: Object, propertyKey: string | symbol, parameterIndex: number) => void +>target : Object +>Object : Object >propertyKey : string | symbol >parameterIndex : number @@ -11,6 +11,6 @@ class C { method(@dec p: number) {} >method : (p: number) => void ->dec : (target: Function, propertyKey: string | symbol, parameterIndex: number) => void +>dec : (target: Object, propertyKey: string | symbol, parameterIndex: number) => void >p : number } diff --git a/tests/baselines/reference/decoratorOnClassProperty11.errors.txt b/tests/baselines/reference/decoratorOnClassProperty11.errors.txt new file mode 100644 index 00000000000..6ff700564e8 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClassProperty11.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts(4,5): error TS1240: Unable to resolve signature of property decorator when called as an expression. + Supplied parameters do not match any signature of call target. + + +==== tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts (1 errors) ==== + declare function dec(): (target: any, propertyKey: string) => void; + + class C { + @dec prop; + ~~~~ +!!! error TS1240: Unable to resolve signature of property decorator when called as an expression. +!!! error TS1240: Supplied parameters do not match any signature of call target. + } \ No newline at end of file diff --git a/tests/baselines/reference/decoratorOnClassProperty11.symbols b/tests/baselines/reference/decoratorOnClassProperty11.symbols deleted file mode 100644 index c7d6e39c713..00000000000 --- a/tests/baselines/reference/decoratorOnClassProperty11.symbols +++ /dev/null @@ -1,14 +0,0 @@ -=== tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts === -declare function dec(): (target: any, propertyKey: string) => void; ->dec : Symbol(dec, Decl(decoratorOnClassProperty11.ts, 0, 0)) ->T : Symbol(T, Decl(decoratorOnClassProperty11.ts, 0, 25)) ->target : Symbol(target, Decl(decoratorOnClassProperty11.ts, 0, 28)) ->propertyKey : Symbol(propertyKey, Decl(decoratorOnClassProperty11.ts, 0, 40)) - -class C { ->C : Symbol(C, Decl(decoratorOnClassProperty11.ts, 0, 70)) - - @dec prop; ->dec : Symbol(dec, Decl(decoratorOnClassProperty11.ts, 0, 0)) ->prop : Symbol(prop, Decl(decoratorOnClassProperty11.ts, 2, 9)) -} diff --git a/tests/baselines/reference/decoratorOnClassProperty11.types b/tests/baselines/reference/decoratorOnClassProperty11.types deleted file mode 100644 index 5caa467d3ba..00000000000 --- a/tests/baselines/reference/decoratorOnClassProperty11.types +++ /dev/null @@ -1,14 +0,0 @@ -=== tests/cases/conformance/decorators/class/property/decoratorOnClassProperty11.ts === -declare function dec(): (target: any, propertyKey: string) => void; ->dec : () => (target: any, propertyKey: string) => void ->T : T ->target : any ->propertyKey : string - -class C { ->C : C - - @dec prop; ->dec : () => (target: any, propertyKey: string) => void ->prop : any -} diff --git a/tests/baselines/reference/decoratorOnClassProperty6.errors.txt b/tests/baselines/reference/decoratorOnClassProperty6.errors.txt new file mode 100644 index 00000000000..dbb104e8cd3 --- /dev/null +++ b/tests/baselines/reference/decoratorOnClassProperty6.errors.txt @@ -0,0 +1,13 @@ +tests/cases/conformance/decorators/class/property/decoratorOnClassProperty6.ts(4,5): error TS1240: Unable to resolve signature of property decorator when called as an expression. + Supplied parameters do not match any signature of call target. + + +==== tests/cases/conformance/decorators/class/property/decoratorOnClassProperty6.ts (1 errors) ==== + declare function dec(target: Function): void; + + class C { + @dec prop; + ~~~~ +!!! error TS1240: Unable to resolve signature of property decorator when called as an expression. +!!! error TS1240: Supplied parameters do not match any signature of call target. + } \ No newline at end of file diff --git a/tests/baselines/reference/decoratorOnClassProperty6.symbols b/tests/baselines/reference/decoratorOnClassProperty6.symbols deleted file mode 100644 index 7b9857e0a19..00000000000 --- a/tests/baselines/reference/decoratorOnClassProperty6.symbols +++ /dev/null @@ -1,13 +0,0 @@ -=== tests/cases/conformance/decorators/class/property/decoratorOnClassProperty6.ts === -declare function dec(target: Function): void; ->dec : Symbol(dec, Decl(decoratorOnClassProperty6.ts, 0, 0)) ->target : Symbol(target, Decl(decoratorOnClassProperty6.ts, 0, 21)) ->Function : Symbol(Function, Decl(lib.d.ts, 223, 38), Decl(lib.d.ts, 269, 11)) - -class C { ->C : Symbol(C, Decl(decoratorOnClassProperty6.ts, 0, 45)) - - @dec prop; ->dec : Symbol(dec, Decl(decoratorOnClassProperty6.ts, 0, 0)) ->prop : Symbol(prop, Decl(decoratorOnClassProperty6.ts, 2, 9)) -} diff --git a/tests/baselines/reference/decoratorOnClassProperty6.types b/tests/baselines/reference/decoratorOnClassProperty6.types deleted file mode 100644 index 59d03678330..00000000000 --- a/tests/baselines/reference/decoratorOnClassProperty6.types +++ /dev/null @@ -1,13 +0,0 @@ -=== tests/cases/conformance/decorators/class/property/decoratorOnClassProperty6.ts === -declare function dec(target: Function): void; ->dec : (target: Function) => void ->target : Function ->Function : Function - -class C { ->C : C - - @dec prop; ->dec : (target: Function) => void ->prop : any -} diff --git a/tests/baselines/reference/decoratorOnClassProperty7.errors.txt b/tests/baselines/reference/decoratorOnClassProperty7.errors.txt index 8b93d0ab38e..41396acd17e 100644 --- a/tests/baselines/reference/decoratorOnClassProperty7.errors.txt +++ b/tests/baselines/reference/decoratorOnClassProperty7.errors.txt @@ -1,4 +1,5 @@ -tests/cases/conformance/decorators/class/property/decoratorOnClassProperty7.ts(4,5): error TS2322: Type '(target: Function, propertyKey: string | symbol, paramIndex: number) => void' is not assignable to type '(target: Object, propertyKey: string | symbol) => void'. +tests/cases/conformance/decorators/class/property/decoratorOnClassProperty7.ts(4,5): error TS1240: Unable to resolve signature of property decorator when called as an expression. + Supplied parameters do not match any signature of call target. ==== tests/cases/conformance/decorators/class/property/decoratorOnClassProperty7.ts (1 errors) ==== @@ -7,5 +8,6 @@ tests/cases/conformance/decorators/class/property/decoratorOnClassProperty7.ts(4 class C { @dec prop; ~~~~ -!!! error TS2322: Type '(target: Function, propertyKey: string | symbol, paramIndex: number) => void' is not assignable to type '(target: Object, propertyKey: string | symbol) => void'. +!!! error TS1240: Unable to resolve signature of property decorator when called as an expression. +!!! error TS1240: Supplied parameters do not match any signature of call target. } \ No newline at end of file diff --git a/tests/baselines/reference/missingDecoratorType.errors.txt b/tests/baselines/reference/missingDecoratorType.errors.txt index 0b159a8fcb2..f2af7d49b57 100644 --- a/tests/baselines/reference/missingDecoratorType.errors.txt +++ b/tests/baselines/reference/missingDecoratorType.errors.txt @@ -1,7 +1,7 @@ -error TS2318: Cannot find global type 'ClassDecorator'. +error TS2318: Cannot find global type 'TypedPropertyDescriptor'. -!!! error TS2318: Cannot find global type 'ClassDecorator'. +!!! error TS2318: Cannot find global type 'TypedPropertyDescriptor'. ==== tests/cases/conformance/decorators/a.ts (0 errors) ==== interface Object { } @@ -14,10 +14,11 @@ error TS2318: Cannot find global type 'ClassDecorator'. interface IArguments { } ==== tests/cases/conformance/decorators/b.ts (0 errors) ==== - declare var dec: any; + declare function dec(t, k, d); - @dec class C { + @dec + method() {} } \ No newline at end of file diff --git a/tests/baselines/reference/missingDecoratorType.js b/tests/baselines/reference/missingDecoratorType.js index 4460abdc798..ad6be3a646e 100644 --- a/tests/baselines/reference/missingDecoratorType.js +++ b/tests/baselines/reference/missingDecoratorType.js @@ -12,10 +12,11 @@ interface RegExp { } interface IArguments { } //// [b.ts] -declare var dec: any; +declare function dec(t, k, d); -@dec class C { + @dec + method() {} } @@ -33,8 +34,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key, var C = (function () { function C() { } - C = __decorate([ - dec - ], C); + C.prototype.method = function () { }; + Object.defineProperty(C.prototype, "method", + __decorate([ + dec + ], C.prototype, "method", Object.getOwnPropertyDescriptor(C.prototype, "method"))); return C; })(); diff --git a/tests/baselines/reference/noEmitHelpers2.js b/tests/baselines/reference/noEmitHelpers2.js index 1bd42377679..66e2ff78b64 100644 --- a/tests/baselines/reference/noEmitHelpers2.js +++ b/tests/baselines/reference/noEmitHelpers2.js @@ -1,6 +1,6 @@ //// [noEmitHelpers2.ts] -function decorator() { } +declare var decorator: any; @decorator class A { @@ -9,7 +9,6 @@ class A { } //// [noEmitHelpers2.js] -function decorator() { } var A = (function () { function A(a, b) { } diff --git a/tests/baselines/reference/noEmitHelpers2.symbols b/tests/baselines/reference/noEmitHelpers2.symbols index 3a3e3ec94c7..044026a3db7 100644 --- a/tests/baselines/reference/noEmitHelpers2.symbols +++ b/tests/baselines/reference/noEmitHelpers2.symbols @@ -1,17 +1,17 @@ === tests/cases/compiler/noEmitHelpers2.ts === -function decorator() { } ->decorator : Symbol(decorator, Decl(noEmitHelpers2.ts, 0, 0)) +declare var decorator: any; +>decorator : Symbol(decorator, Decl(noEmitHelpers2.ts, 1, 11)) @decorator ->decorator : Symbol(decorator, Decl(noEmitHelpers2.ts, 0, 0)) +>decorator : Symbol(decorator, Decl(noEmitHelpers2.ts, 1, 11)) class A { ->A : Symbol(A, Decl(noEmitHelpers2.ts, 1, 24)) +>A : Symbol(A, Decl(noEmitHelpers2.ts, 1, 27)) constructor(a: number, @decorator b: string) { >a : Symbol(a, Decl(noEmitHelpers2.ts, 5, 16)) ->decorator : Symbol(decorator, Decl(noEmitHelpers2.ts, 0, 0)) +>decorator : Symbol(decorator, Decl(noEmitHelpers2.ts, 1, 11)) >b : Symbol(b, Decl(noEmitHelpers2.ts, 5, 26)) } } diff --git a/tests/baselines/reference/noEmitHelpers2.types b/tests/baselines/reference/noEmitHelpers2.types index 2a5b5413a7e..14260e4f95c 100644 --- a/tests/baselines/reference/noEmitHelpers2.types +++ b/tests/baselines/reference/noEmitHelpers2.types @@ -1,17 +1,17 @@ === tests/cases/compiler/noEmitHelpers2.ts === -function decorator() { } ->decorator : () => void +declare var decorator: any; +>decorator : any @decorator ->decorator : () => void +>decorator : any class A { >A : A constructor(a: number, @decorator b: string) { >a : number ->decorator : () => void +>decorator : any >b : string } } diff --git a/tests/baselines/reference/sourceMapValidationDecorators.js b/tests/baselines/reference/sourceMapValidationDecorators.js index f858aeff586..5196d3b0dd8 100644 --- a/tests/baselines/reference/sourceMapValidationDecorators.js +++ b/tests/baselines/reference/sourceMapValidationDecorators.js @@ -3,8 +3,8 @@ declare function ClassDecorator1(target: Function): void; declare function ClassDecorator2(x: number): (target: Function) => void; declare function PropertyDecorator1(target: Object, key: string | symbol, descriptor?: PropertyDescriptor): void; declare function PropertyDecorator2(x: number): (target: Object, key: string | symbol, descriptor?: PropertyDescriptor) => void; -declare function ParameterDecorator1(target: Function, key: string | symbol, paramIndex: number): void; -declare function ParameterDecorator2(x: number): (target: Function, key: string | symbol, paramIndex: number) => void; +declare function ParameterDecorator1(target: Object, key: string | symbol, paramIndex: number): void; +declare function ParameterDecorator2(x: number): (target: Object, key: string | symbol, paramIndex: number) => void; @ClassDecorator1 @ClassDecorator2(10) diff --git a/tests/baselines/reference/sourceMapValidationDecorators.sourcemap.txt b/tests/baselines/reference/sourceMapValidationDecorators.sourcemap.txt index 68ad353db9f..b7036723a85 100644 --- a/tests/baselines/reference/sourceMapValidationDecorators.sourcemap.txt +++ b/tests/baselines/reference/sourceMapValidationDecorators.sourcemap.txt @@ -26,8 +26,8 @@ sourceFile:sourceMapValidationDecorators.ts >declare function ClassDecorator2(x: number): (target: Function) => void; >declare function PropertyDecorator1(target: Object, key: string | symbol, descriptor?: PropertyDescriptor): void; >declare function PropertyDecorator2(x: number): (target: Object, key: string | symbol, descriptor?: PropertyDescriptor) => void; - >declare function ParameterDecorator1(target: Function, key: string | symbol, paramIndex: number): void; - >declare function ParameterDecorator2(x: number): (target: Function, key: string | symbol, paramIndex: number) => void; + >declare function ParameterDecorator1(target: Object, key: string | symbol, paramIndex: number): void; + >declare function ParameterDecorator2(x: number): (target: Object, key: string | symbol, paramIndex: number) => void; > > 1 >Emitted(12, 1) Source(8, 1) + SourceIndex(0) diff --git a/tests/baselines/reference/sourceMapValidationDecorators.symbols b/tests/baselines/reference/sourceMapValidationDecorators.symbols index 37db95d3e05..e22afb7b7fc 100644 --- a/tests/baselines/reference/sourceMapValidationDecorators.symbols +++ b/tests/baselines/reference/sourceMapValidationDecorators.symbols @@ -27,20 +27,20 @@ declare function PropertyDecorator2(x: number): (target: Object, key: string | s >descriptor : Symbol(descriptor, Decl(sourceMapValidationDecorators.ts, 3, 86)) >PropertyDescriptor : Symbol(PropertyDescriptor, Decl(lib.d.ts, 79, 66)) -declare function ParameterDecorator1(target: Function, key: string | symbol, paramIndex: number): void; +declare function ParameterDecorator1(target: Object, key: string | symbol, paramIndex: number): void; >ParameterDecorator1 : Symbol(ParameterDecorator1, Decl(sourceMapValidationDecorators.ts, 3, 128)) >target : Symbol(target, Decl(sourceMapValidationDecorators.ts, 4, 37)) ->Function : Symbol(Function, Decl(lib.d.ts, 223, 38), Decl(lib.d.ts, 269, 11)) ->key : Symbol(key, Decl(sourceMapValidationDecorators.ts, 4, 54)) ->paramIndex : Symbol(paramIndex, Decl(sourceMapValidationDecorators.ts, 4, 76)) +>Object : Symbol(Object, Decl(lib.d.ts, 92, 1), Decl(lib.d.ts, 223, 11)) +>key : Symbol(key, Decl(sourceMapValidationDecorators.ts, 4, 52)) +>paramIndex : Symbol(paramIndex, Decl(sourceMapValidationDecorators.ts, 4, 74)) -declare function ParameterDecorator2(x: number): (target: Function, key: string | symbol, paramIndex: number) => void; ->ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 103)) +declare function ParameterDecorator2(x: number): (target: Object, key: string | symbol, paramIndex: number) => void; +>ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 101)) >x : Symbol(x, Decl(sourceMapValidationDecorators.ts, 5, 37)) >target : Symbol(target, Decl(sourceMapValidationDecorators.ts, 5, 50)) ->Function : Symbol(Function, Decl(lib.d.ts, 223, 38), Decl(lib.d.ts, 269, 11)) ->key : Symbol(key, Decl(sourceMapValidationDecorators.ts, 5, 67)) ->paramIndex : Symbol(paramIndex, Decl(sourceMapValidationDecorators.ts, 5, 89)) +>Object : Symbol(Object, Decl(lib.d.ts, 92, 1), Decl(lib.d.ts, 223, 11)) +>key : Symbol(key, Decl(sourceMapValidationDecorators.ts, 5, 65)) +>paramIndex : Symbol(paramIndex, Decl(sourceMapValidationDecorators.ts, 5, 87)) @ClassDecorator1 >ClassDecorator1 : Symbol(ClassDecorator1, Decl(sourceMapValidationDecorators.ts, 0, 0)) @@ -49,14 +49,14 @@ declare function ParameterDecorator2(x: number): (target: Function, key: string >ClassDecorator2 : Symbol(ClassDecorator2, Decl(sourceMapValidationDecorators.ts, 0, 57)) class Greeter { ->Greeter : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 118)) +>Greeter : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 116)) constructor( @ParameterDecorator1 >ParameterDecorator1 : Symbol(ParameterDecorator1, Decl(sourceMapValidationDecorators.ts, 3, 128)) @ParameterDecorator2(20) ->ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 103)) +>ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 101)) public greeting: string, >greeting : Symbol(greeting, Decl(sourceMapValidationDecorators.ts, 10, 16)) @@ -65,7 +65,7 @@ class Greeter { >ParameterDecorator1 : Symbol(ParameterDecorator1, Decl(sourceMapValidationDecorators.ts, 3, 128)) @ParameterDecorator2(30) ->ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 103)) +>ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 101)) ...b: string[]) { >b : Symbol(b, Decl(sourceMapValidationDecorators.ts, 13, 30)) @@ -82,7 +82,7 @@ class Greeter { return "

" + this.greeting + "

"; >this.greeting : Symbol(greeting, Decl(sourceMapValidationDecorators.ts, 10, 16)) ->this : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 118)) +>this : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 116)) >greeting : Symbol(greeting, Decl(sourceMapValidationDecorators.ts, 10, 16)) } @@ -111,14 +111,14 @@ class Greeter { >ParameterDecorator1 : Symbol(ParameterDecorator1, Decl(sourceMapValidationDecorators.ts, 3, 128)) @ParameterDecorator2(70) ->ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 103)) +>ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 101)) x: number) { >x : Symbol(x, Decl(sourceMapValidationDecorators.ts, 34, 15)) return this.greeting; >this.greeting : Symbol(greeting, Decl(sourceMapValidationDecorators.ts, 10, 16)) ->this : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 118)) +>this : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 116)) >greeting : Symbol(greeting, Decl(sourceMapValidationDecorators.ts, 10, 16)) } @@ -133,7 +133,7 @@ class Greeter { return this.greeting; >this.greeting : Symbol(greeting, Decl(sourceMapValidationDecorators.ts, 10, 16)) ->this : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 118)) +>this : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 116)) >greeting : Symbol(greeting, Decl(sourceMapValidationDecorators.ts, 10, 16)) } @@ -144,14 +144,14 @@ class Greeter { >ParameterDecorator1 : Symbol(ParameterDecorator1, Decl(sourceMapValidationDecorators.ts, 3, 128)) @ParameterDecorator2(90) ->ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 103)) +>ParameterDecorator2 : Symbol(ParameterDecorator2, Decl(sourceMapValidationDecorators.ts, 4, 101)) greetings: string) { >greetings : Symbol(greetings, Decl(sourceMapValidationDecorators.ts, 47, 18)) this.greeting = greetings; >this.greeting : Symbol(greeting, Decl(sourceMapValidationDecorators.ts, 10, 16)) ->this : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 118)) +>this : Symbol(Greeter, Decl(sourceMapValidationDecorators.ts, 5, 116)) >greeting : Symbol(greeting, Decl(sourceMapValidationDecorators.ts, 10, 16)) >greetings : Symbol(greetings, Decl(sourceMapValidationDecorators.ts, 47, 18)) } diff --git a/tests/baselines/reference/sourceMapValidationDecorators.types b/tests/baselines/reference/sourceMapValidationDecorators.types index 182f68570bc..9e83bb03509 100644 --- a/tests/baselines/reference/sourceMapValidationDecorators.types +++ b/tests/baselines/reference/sourceMapValidationDecorators.types @@ -27,18 +27,18 @@ declare function PropertyDecorator2(x: number): (target: Object, key: string | s >descriptor : PropertyDescriptor >PropertyDescriptor : PropertyDescriptor -declare function ParameterDecorator1(target: Function, key: string | symbol, paramIndex: number): void; ->ParameterDecorator1 : (target: Function, key: string | symbol, paramIndex: number) => void ->target : Function ->Function : Function +declare function ParameterDecorator1(target: Object, key: string | symbol, paramIndex: number): void; +>ParameterDecorator1 : (target: Object, key: string | symbol, paramIndex: number) => void +>target : Object +>Object : Object >key : string | symbol >paramIndex : number -declare function ParameterDecorator2(x: number): (target: Function, key: string | symbol, paramIndex: number) => void; ->ParameterDecorator2 : (x: number) => (target: Function, key: string | symbol, paramIndex: number) => void +declare function ParameterDecorator2(x: number): (target: Object, key: string | symbol, paramIndex: number) => void; +>ParameterDecorator2 : (x: number) => (target: Object, key: string | symbol, paramIndex: number) => void >x : number ->target : Function ->Function : Function +>target : Object +>Object : Object >key : string | symbol >paramIndex : number @@ -55,22 +55,22 @@ class Greeter { constructor( @ParameterDecorator1 ->ParameterDecorator1 : (target: Function, key: string | symbol, paramIndex: number) => void +>ParameterDecorator1 : (target: Object, key: string | symbol, paramIndex: number) => void @ParameterDecorator2(20) ->ParameterDecorator2(20) : (target: Function, key: string | symbol, paramIndex: number) => void ->ParameterDecorator2 : (x: number) => (target: Function, key: string | symbol, paramIndex: number) => void +>ParameterDecorator2(20) : (target: Object, key: string | symbol, paramIndex: number) => void +>ParameterDecorator2 : (x: number) => (target: Object, key: string | symbol, paramIndex: number) => void >20 : number public greeting: string, >greeting : string @ParameterDecorator1 ->ParameterDecorator1 : (target: Function, key: string | symbol, paramIndex: number) => void +>ParameterDecorator1 : (target: Object, key: string | symbol, paramIndex: number) => void @ParameterDecorator2(30) ->ParameterDecorator2(30) : (target: Function, key: string | symbol, paramIndex: number) => void ->ParameterDecorator2 : (x: number) => (target: Function, key: string | symbol, paramIndex: number) => void +>ParameterDecorator2(30) : (target: Object, key: string | symbol, paramIndex: number) => void +>ParameterDecorator2 : (x: number) => (target: Object, key: string | symbol, paramIndex: number) => void >30 : number ...b: string[]) { @@ -125,11 +125,11 @@ class Greeter { >fn : (x: number) => string @ParameterDecorator1 ->ParameterDecorator1 : (target: Function, key: string | symbol, paramIndex: number) => void +>ParameterDecorator1 : (target: Object, key: string | symbol, paramIndex: number) => void @ParameterDecorator2(70) ->ParameterDecorator2(70) : (target: Function, key: string | symbol, paramIndex: number) => void ->ParameterDecorator2 : (x: number) => (target: Function, key: string | symbol, paramIndex: number) => void +>ParameterDecorator2(70) : (target: Object, key: string | symbol, paramIndex: number) => void +>ParameterDecorator2 : (x: number) => (target: Object, key: string | symbol, paramIndex: number) => void >70 : number x: number) { @@ -162,11 +162,11 @@ class Greeter { >greetings : string @ParameterDecorator1 ->ParameterDecorator1 : (target: Function, key: string | symbol, paramIndex: number) => void +>ParameterDecorator1 : (target: Object, key: string | symbol, paramIndex: number) => void @ParameterDecorator2(90) ->ParameterDecorator2(90) : (target: Function, key: string | symbol, paramIndex: number) => void ->ParameterDecorator2 : (x: number) => (target: Function, key: string | symbol, paramIndex: number) => void +>ParameterDecorator2(90) : (target: Object, key: string | symbol, paramIndex: number) => void +>ParameterDecorator2 : (x: number) => (target: Object, key: string | symbol, paramIndex: number) => void >90 : number greetings: string) { diff --git a/tests/cases/compiler/noEmitHelpers2.ts b/tests/cases/compiler/noEmitHelpers2.ts index ccc17f7066e..2487ffa1dd8 100644 --- a/tests/cases/compiler/noEmitHelpers2.ts +++ b/tests/cases/compiler/noEmitHelpers2.ts @@ -3,7 +3,7 @@ // @emitdecoratormetadata: true // @target: es5 -function decorator() { } +declare var decorator: any; @decorator class A { diff --git a/tests/cases/compiler/sourceMapValidationDecorators.ts b/tests/cases/compiler/sourceMapValidationDecorators.ts index 898d3f729b2..b600691e04b 100644 --- a/tests/cases/compiler/sourceMapValidationDecorators.ts +++ b/tests/cases/compiler/sourceMapValidationDecorators.ts @@ -5,8 +5,8 @@ declare function ClassDecorator1(target: Function): void; declare function ClassDecorator2(x: number): (target: Function) => void; declare function PropertyDecorator1(target: Object, key: string | symbol, descriptor?: PropertyDescriptor): void; declare function PropertyDecorator2(x: number): (target: Object, key: string | symbol, descriptor?: PropertyDescriptor) => void; -declare function ParameterDecorator1(target: Function, key: string | symbol, paramIndex: number): void; -declare function ParameterDecorator2(x: number): (target: Function, key: string | symbol, paramIndex: number) => void; +declare function ParameterDecorator1(target: Object, key: string | symbol, paramIndex: number): void; +declare function ParameterDecorator2(x: number): (target: Object, key: string | symbol, paramIndex: number) => void; @ClassDecorator1 @ClassDecorator2(10) diff --git a/tests/cases/conformance/decorators/class/decoratedClassFromExternalModule.ts b/tests/cases/conformance/decorators/class/decoratedClassFromExternalModule.ts index 95f8bf4ab97..f2d9076cce2 100644 --- a/tests/cases/conformance/decorators/class/decoratedClassFromExternalModule.ts +++ b/tests/cases/conformance/decorators/class/decoratedClassFromExternalModule.ts @@ -1,7 +1,7 @@ // @target: es6 // @experimentaldecorators: true // @Filename: decorated.ts -function decorate() { } +function decorate(target: any) { } @decorate export default class Decorated { } diff --git a/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts b/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts index b1cbd1a679c..36237f3cb58 100644 --- a/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts +++ b/tests/cases/conformance/decorators/class/decoratorChecksFunctionBodies.ts @@ -6,7 +6,7 @@ function func(s: string): void { } class A { - @(x => { + @((x, p) => { var a = 3; func(a); return x; diff --git a/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts b/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts index 9163ed0c384..7ba5a6839b9 100644 --- a/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts +++ b/tests/cases/conformance/decorators/class/decoratorInstantiateModulesInFunctionBodies.ts @@ -10,7 +10,7 @@ export var test = 'abc'; import { test } from './a'; function filter(handler: any) { - return function (target: any) { + return function (target: any, propertyKey: string) { // ... }; } diff --git a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts index f41481d4ad0..5ab3b39d7ab 100644 --- a/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts +++ b/tests/cases/conformance/decorators/class/method/decoratorOnClassMethod13.ts @@ -1,6 +1,6 @@ // @target: ES6 // @experimentaldecorators: true -declare function dec(): (target: any, propertyKey: string, descriptor: TypedPropertyDescriptor) => TypedPropertyDescriptor; +declare function dec(target: any, propertyKey: string, descriptor: TypedPropertyDescriptor): TypedPropertyDescriptor; class C { @dec ["1"]() { } diff --git a/tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts b/tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts index 18a7fff6dd0..64de61bb8a9 100644 --- a/tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts +++ b/tests/cases/conformance/decorators/class/method/parameter/decoratorOnClassMethodParameter1.ts @@ -1,6 +1,6 @@ // @target:es5 // @experimentaldecorators: true -declare function dec(target: Function, propertyKey: string | symbol, parameterIndex: number): void; +declare function dec(target: Object, propertyKey: string | symbol, parameterIndex: number): void; class C { method(@dec p: number) {} diff --git a/tests/cases/conformance/decorators/missingDecoratorType.ts b/tests/cases/conformance/decorators/missingDecoratorType.ts index 905edaf0756..9b8cdd276f2 100644 --- a/tests/cases/conformance/decorators/missingDecoratorType.ts +++ b/tests/cases/conformance/decorators/missingDecoratorType.ts @@ -13,9 +13,10 @@ interface RegExp { } interface IArguments { } // @Filename: b.ts -declare var dec: any; +declare function dec(t, k, d); -@dec class C { + @dec + method() {} }