diff --git a/packages/compiler/src/compile_metadata.ts b/packages/compiler/src/compile_metadata.ts index 22113aad6c..72046a041e 100644 --- a/packages/compiler/src/compile_metadata.ts +++ b/packages/compiler/src/compile_metadata.ts @@ -79,6 +79,8 @@ function _sanitizeIdentifier(name: string): string { } let _anonymousTypeIndex = 0; +let symbolId = 0; +const symbolIds = new Map(); export function identifierName(compileIdentifier: CompileIdentifierMetadata): string { if (!compileIdentifier || !compileIdentifier.reference) { @@ -88,6 +90,14 @@ export function identifierName(compileIdentifier: CompileIdentifierMetadata): st if (ref instanceof StaticSymbol) { return ref.name; } + if (isSymbol(ref)) { + if (symbolIds.has(ref)) { + return symbolIds.get(ref); + } + const symbolStr = `_symbol_${_sanitizeIdentifier(ref.toString())}_${symbolId++}`; + symbolIds.set(ref, symbolStr); + return symbolStr; + } if (ref['__anonymousType']) { return ref['__anonymousType']; } @@ -102,6 +112,10 @@ export function identifierName(compileIdentifier: CompileIdentifierMetadata): st return identifier; } +function isSymbol(sym: any): sym is Symbol { + return typeof sym === 'symbol'; +} + export function identifierModuleUrl(compileIdentifier: CompileIdentifierMetadata): string { const ref = compileIdentifier.reference; if (ref instanceof StaticSymbol) { diff --git a/packages/compiler/test/integration_spec.ts b/packages/compiler/test/integration_spec.ts index a4d995a2b4..60dadec980 100644 --- a/packages/compiler/test/integration_spec.ts +++ b/packages/compiler/test/integration_spec.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Component, Directive, Input} from '@angular/core'; +import {Component, Directive, Inject, Input} from '@angular/core'; import {ComponentFixture, TestBed, async} from '@angular/core/testing'; import {By} from '@angular/platform-browser/src/dom/debug/by'; import {expect} from '@angular/platform-browser/testing/src/matchers'; @@ -38,6 +38,31 @@ export function main() { })); }); + it('should not throw when Symbol is used as DI token', async(() => { + const SOME_SYMBOL = Symbol('Symbol'); + const ANOTHER_SYMBOL = Symbol('Symbol'); + + @Component({selector: 'symbol', template: ''}) + class CmpWithSymbol { + constructor( + @Inject(SOME_SYMBOL) public symbol: string, + @Inject(ANOTHER_SYMBOL) public anotherSymbol: string) {} + } + + TestBed.configureTestingModule({ + declarations: [CmpWithSymbol], + providers: [ + {provide: SOME_SYMBOL, useValue: 'value'}, + {provide: SOME_SYMBOL, useValue: 'override'}, + {provide: ANOTHER_SYMBOL, useValue: 'another value'} + ] + }); + + const fixture = TestBed.createComponent(CmpWithSymbol); + fixture.detectChanges(); + expect(fixture.componentInstance.symbol).toEqual('override'); + expect(fixture.componentInstance.anotherSymbol).toEqual('another value'); + })); }); }