Now that issues are resolved with Closure compiler, we can move back to our desired prefix of `Δ`. PR Close #30362
		
			
				
	
	
		
			137 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| /**
 | |
|  * @license
 | |
|  * Copyright Google Inc. All Rights Reserved.
 | |
|  *
 | |
|  * Use of this source code is governed by an MIT-style license that can be
 | |
|  * found in the LICENSE file at https://angular.io/license
 | |
|  */
 | |
| 
 | |
| import {StaticSymbol} from './aot/static_symbol';
 | |
| import {CompileInjectableMetadata, CompileNgModuleMetadata, CompileProviderMetadata, identifierName} from './compile_metadata';
 | |
| import {CompileReflector} from './compile_reflector';
 | |
| import {InjectFlags, NodeFlags} from './core';
 | |
| import {Identifiers} from './identifiers';
 | |
| import * as o from './output/output_ast';
 | |
| import {convertValueToOutputAst} from './output/value_util';
 | |
| import {typeSourceSpan} from './parse_util';
 | |
| import {NgModuleProviderAnalyzer} from './provider_analyzer';
 | |
| import {OutputContext} from './util';
 | |
| import {componentFactoryResolverProviderDef, depDef, providerDef} from './view_compiler/provider_compiler';
 | |
| 
 | |
| type MapEntry = {
 | |
|   key: string,
 | |
|   quoted: boolean,
 | |
|   value: o.Expression
 | |
| };
 | |
| type MapLiteral = MapEntry[];
 | |
| 
 | |
| function mapEntry(key: string, value: o.Expression): MapEntry {
 | |
|   return {key, value, quoted: false};
 | |
| }
 | |
| 
 | |
| export class InjectableCompiler {
 | |
|   private tokenInjector: StaticSymbol;
 | |
|   constructor(private reflector: CompileReflector, private alwaysGenerateDef: boolean) {
 | |
|     this.tokenInjector = reflector.resolveExternalReference(Identifiers.Injector);
 | |
|   }
 | |
| 
 | |
|   private depsArray(deps: any[], ctx: OutputContext): o.Expression[] {
 | |
|     return deps.map(dep => {
 | |
|       let token = dep;
 | |
|       let args = [token];
 | |
|       let flags: InjectFlags = InjectFlags.Default;
 | |
|       if (Array.isArray(dep)) {
 | |
|         for (let i = 0; i < dep.length; i++) {
 | |
|           const v = dep[i];
 | |
|           if (v) {
 | |
|             if (v.ngMetadataName === 'Optional') {
 | |
|               flags |= InjectFlags.Optional;
 | |
|             } else if (v.ngMetadataName === 'SkipSelf') {
 | |
|               flags |= InjectFlags.SkipSelf;
 | |
|             } else if (v.ngMetadataName === 'Self') {
 | |
|               flags |= InjectFlags.Self;
 | |
|             } else if (v.ngMetadataName === 'Inject') {
 | |
|               token = v.token;
 | |
|             } else {
 | |
|               token = v;
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       let tokenExpr: o.Expression;
 | |
|       if (typeof token === 'string') {
 | |
|         tokenExpr = o.literal(token);
 | |
|       } else if (token === this.tokenInjector) {
 | |
|         tokenExpr = o.importExpr(Identifiers.INJECTOR);
 | |
|       } else {
 | |
|         tokenExpr = ctx.importExpr(token);
 | |
|       }
 | |
| 
 | |
|       if (flags !== InjectFlags.Default) {
 | |
|         args = [tokenExpr, o.literal(flags)];
 | |
|       } else {
 | |
|         args = [tokenExpr];
 | |
|       }
 | |
|       return o.importExpr(Identifiers.inject).callFn(args);
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   factoryFor(injectable: CompileInjectableMetadata, ctx: OutputContext): o.Expression {
 | |
|     let retValue: o.Expression;
 | |
|     if (injectable.useExisting) {
 | |
|       retValue = o.importExpr(Identifiers.inject).callFn([ctx.importExpr(injectable.useExisting)]);
 | |
|     } else if (injectable.useFactory) {
 | |
|       const deps = injectable.deps || [];
 | |
|       if (deps.length > 0) {
 | |
|         retValue = ctx.importExpr(injectable.useFactory).callFn(this.depsArray(deps, ctx));
 | |
|       } else {
 | |
|         return ctx.importExpr(injectable.useFactory);
 | |
|       }
 | |
|     } else if (injectable.useValue) {
 | |
|       retValue = convertValueToOutputAst(ctx, injectable.useValue);
 | |
|     } else {
 | |
|       const clazz = injectable.useClass || injectable.symbol;
 | |
|       const depArgs = this.depsArray(this.reflector.parameters(clazz), ctx);
 | |
|       retValue = new o.InstantiateExpr(ctx.importExpr(clazz), depArgs);
 | |
|     }
 | |
|     return o.fn(
 | |
|         [], [new o.ReturnStatement(retValue)], undefined, undefined,
 | |
|         injectable.symbol.name + '_Factory');
 | |
|   }
 | |
| 
 | |
|   injectableDef(injectable: CompileInjectableMetadata, ctx: OutputContext): o.Expression {
 | |
|     let providedIn: o.Expression = o.NULL_EXPR;
 | |
|     if (injectable.providedIn !== undefined) {
 | |
|       if (injectable.providedIn === null) {
 | |
|         providedIn = o.NULL_EXPR;
 | |
|       } else if (typeof injectable.providedIn === 'string') {
 | |
|         providedIn = o.literal(injectable.providedIn);
 | |
|       } else {
 | |
|         providedIn = ctx.importExpr(injectable.providedIn);
 | |
|       }
 | |
|     }
 | |
|     const def: MapLiteral = [
 | |
|       mapEntry('factory', this.factoryFor(injectable, ctx)),
 | |
|       mapEntry('token', ctx.importExpr(injectable.type.reference)),
 | |
|       mapEntry('providedIn', providedIn),
 | |
|     ];
 | |
|     return o.importExpr(Identifiers.ΔdefineInjectable).callFn([o.literalMap(def)]);
 | |
|   }
 | |
| 
 | |
|   compile(injectable: CompileInjectableMetadata, ctx: OutputContext): void {
 | |
|     if (this.alwaysGenerateDef || injectable.providedIn !== undefined) {
 | |
|       const className = identifierName(injectable.type) !;
 | |
|       const clazz = new o.ClassStmt(
 | |
|           className, null,
 | |
|           [
 | |
|             new o.ClassField(
 | |
|                 'ngInjectableDef', o.INFERRED_TYPE, [o.StmtModifier.Static],
 | |
|                 this.injectableDef(injectable, ctx)),
 | |
|           ],
 | |
|           [], new o.ClassMethod(null, [], []), []);
 | |
|       ctx.statements.push(clazz);
 | |
|     }
 | |
|   }
 | |
| }
 |