diff --git a/packages/compiler/src/aot/static_reflector.ts b/packages/compiler/src/aot/static_reflector.ts index 2c60f9e6a0..813dbbadca 100644 --- a/packages/compiler/src/aot/static_reflector.ts +++ b/packages/compiler/src/aot/static_reflector.ts @@ -44,6 +44,7 @@ export class StaticReflector implements CompileReflector { private methodCache = new Map(); private conversionMap = new Map any>(); private injectionToken: StaticSymbol; + private opaqueToken: StaticSymbol; private ROUTES: StaticSymbol; private ANALYZE_FOR_ENTRY_COMPONENTS: StaticSymbol; private annotationForParentClassWithSummaryKind = @@ -270,6 +271,7 @@ export class StaticReflector implements CompileReflector { private initializeConversionMap(): void { this.injectionToken = this.findDeclaration(ANGULAR_CORE, 'InjectionToken'); + this.opaqueToken = this.findDeclaration(ANGULAR_CORE, 'OpaqueToken'); this.ROUTES = this.tryFindDeclaration(ANGULAR_ROUTER, 'ROUTES'); this.ANALYZE_FOR_ENTRY_COMPONENTS = this.findDeclaration(ANGULAR_CORE, 'ANALYZE_FOR_ENTRY_COMPONENTS'); @@ -561,9 +563,12 @@ export class StaticReflector implements CompileReflector { staticSymbol = simplifyInContext( context, expression['expression'], depth + 1, /* references */ 0); if (staticSymbol instanceof StaticSymbol) { - if (staticSymbol === self.injectionToken) { + if (staticSymbol === self.injectionToken || staticSymbol === self.opaqueToken) { // if somebody calls new InjectionToken, don't create an InjectionToken, // but rather return the symbol to which the InjectionToken is assigned to. + + // OpaqueToken is supported too as it is required by the language service to + // support v4 and prior versions of Angular. return context; } const argExpressions: any[] = expression['arguments'] || []; diff --git a/packages/language-service/test/diagnostics_spec.ts b/packages/language-service/test/diagnostics_spec.ts index d8b85f1063..db22fc3b58 100644 --- a/packages/language-service/test/diagnostics_spec.ts +++ b/packages/language-service/test/diagnostics_spec.ts @@ -314,6 +314,28 @@ describe('diagnostics', () => { expect(diagnostic).toEqual([]); }); + it('should not report errors for using the now removed OpaqueToken (support for v4)', () => { + const app_component = ` + import { Component, Inject, OpaqueToken } from '@angular/core'; + import { NgForm } from '@angular/common'; + + export const token = new OpaqueToken(); + + @Component({ + selector: 'example-app', + template: '...' + }) + export class AppComponent { + constructor (@Inject(token) value: string) {} + onSubmit(form: NgForm) {} + } + `; + const fileName = '/app/app.component.ts'; + mockHost.override(fileName, app_component); + const diagnostics = ngService.getDiagnostics(fileName); + expect(diagnostics).toEqual([]); + }); + function addCode(code: string, cb: (fileName: string, content?: string) => void) { const fileName = '/app/app.component.ts'; const originalContent = mockHost.getFileContent(fileName);