From 1688394c5cb4db840a83c79b2dd6e61b7445d388 Mon Sep 17 00:00:00 2001 From: Jeremy Elbourn Date: Tue, 28 Jul 2015 17:27:33 -0700 Subject: [PATCH] fix(decorators): stop directives inheriting parent class decorators. Fixes #2291 --- modules/angular2/src/util/decorators.ts | 2 +- .../compiler/directive_metadata_reader_spec.ts | 9 +++++++++ modules/angular2/test/util/decorators_spec.ts | 17 ++++++++++++++--- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/modules/angular2/src/util/decorators.ts b/modules/angular2/src/util/decorators.ts index 0d24ef528797e1..afd7a4b82f7508 100644 --- a/modules/angular2/src/util/decorators.ts +++ b/modules/angular2/src/util/decorators.ts @@ -246,7 +246,7 @@ export function makeDecorator(annotationCls, chainFn: (fn: Function) => void = n isFunction(this) && this.annotations instanceof Array ? this.annotations : []; chainAnnotation.push(annotationInstance); var TypeDecorator: TypeDecorator = function TypeDecorator(cls) { - var annotations = Reflect.getMetadata('annotations', cls); + var annotations = Reflect.getOwnMetadata('annotations', cls); annotations = annotations || []; annotations.push(annotationInstance); Reflect.defineMetadata('annotations', annotations, cls); diff --git a/modules/angular2/test/core/compiler/directive_metadata_reader_spec.ts b/modules/angular2/test/core/compiler/directive_metadata_reader_spec.ts index 019174c3d6eeb4..7be276f5275f68 100644 --- a/modules/angular2/test/core/compiler/directive_metadata_reader_spec.ts +++ b/modules/angular2/test/core/compiler/directive_metadata_reader_spec.ts @@ -7,6 +7,10 @@ import * as dirAnn from 'angular2/src/core/annotations_impl/annotations'; class SomeDirective { } +@Directive({selector: 'someChildDirective'}) +class SomeChildDirective extends SomeDirective { +} + class SomeDirectiveWithoutAnnotation {} export function main() { @@ -24,5 +28,10 @@ export function main() { expect(() => { reader.resolve(SomeDirectiveWithoutAnnotation); }) .toThrowError('No Directive annotation found on SomeDirectiveWithoutAnnotation'); }); + + it('should not read parent class Directive annotations', function() { + var directiveMetadata = reader.resolve(SomeChildDirective); + expect(directiveMetadata).toEqual(new dirAnn.Directive({selector: 'someChildDirective'})); + }); }); } diff --git a/modules/angular2/test/util/decorators_spec.ts b/modules/angular2/test/util/decorators_spec.ts index 1ef66461c2aa46..85c734ea0a9de6 100644 --- a/modules/angular2/test/util/decorators_spec.ts +++ b/modules/angular2/test/util/decorators_spec.ts @@ -23,16 +23,18 @@ class TerminalAnnotation { terminal = true; } +class DecoratedParent {} +class DecoratedChild extends DecoratedParent {} + export function main() { var Reflect = global.Reflect; var TerminalDecorator = makeDecorator(TerminalAnnotation); var TestDecorator = makeDecorator(TestAnnotation, (fn: any) => fn.Terminal = TerminalDecorator); - var TestParamDecorator = makeParamDecorator(TestAnnotation); describe('decorators', () => { - it('shoulld invoke as decorator', () => { - function Type(){}; + it('should invoke as decorator', () => { + function Type() {} TestDecorator({marker: 'WORKS'})(Type); var annotations = Reflect.getMetadata('annotations', Type); expect(annotations[0].arg.marker).toEqual('WORKS'); @@ -53,6 +55,15 @@ export function main() { expect(chain.annotations[1] instanceof TerminalAnnotation).toEqual(true); }); + it('should not apply decorators from the prototype chain', function() { + TestDecorator({marker: 'parent'})(DecoratedParent); + TestDecorator({marker: 'child'})(DecoratedChild); + + var annotations = Reflect.getOwnMetadata('annotations', DecoratedChild); + expect(annotations.length).toBe(1); + expect(annotations[0].arg.marker).toEqual('child'); + }); + describe('Class', () => { it('should create a class', () => { var i0, i1;