UNPKG

@angular/compiler

Version:

Angular - the compiler library

858 lines • 160 kB
/** * @license * Copyright Google LLC 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 */ (function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define("@angular/compiler/src/aot/static_reflector", ["require", "exports", "tslib", "@angular/compiler/src/compile_metadata", "@angular/compiler/src/core", "@angular/compiler/src/util", "@angular/compiler/src/aot/formatted_error", "@angular/compiler/src/aot/static_symbol"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.StaticReflector = void 0; var tslib_1 = require("tslib"); var compile_metadata_1 = require("@angular/compiler/src/compile_metadata"); var core_1 = require("@angular/compiler/src/core"); var util_1 = require("@angular/compiler/src/util"); var formatted_error_1 = require("@angular/compiler/src/aot/formatted_error"); var static_symbol_1 = require("@angular/compiler/src/aot/static_symbol"); var ANGULAR_CORE = '@angular/core'; var ANGULAR_ROUTER = '@angular/router'; var HIDDEN_KEY = /^\$.*\$$/; var IGNORE = { __symbolic: 'ignore' }; var USE_VALUE = 'useValue'; var PROVIDE = 'provide'; var REFERENCE_SET = new Set([USE_VALUE, 'useFactory', 'data', 'id', 'loadChildren']); var TYPEGUARD_POSTFIX = 'TypeGuard'; var USE_IF = 'UseIf'; function shouldIgnore(value) { return value && value.__symbolic == 'ignore'; } /** * A static reflector implements enough of the Reflector API that is necessary to compile * templates statically. */ var StaticReflector = /** @class */ (function () { function StaticReflector(summaryResolver, symbolResolver, knownMetadataClasses, knownMetadataFunctions, errorRecorder) { var _this = this; if (knownMetadataClasses === void 0) { knownMetadataClasses = []; } if (knownMetadataFunctions === void 0) { knownMetadataFunctions = []; } this.summaryResolver = summaryResolver; this.symbolResolver = symbolResolver; this.errorRecorder = errorRecorder; this.annotationCache = new Map(); this.shallowAnnotationCache = new Map(); this.propertyCache = new Map(); this.parameterCache = new Map(); this.methodCache = new Map(); this.staticCache = new Map(); this.conversionMap = new Map(); this.resolvedExternalReferences = new Map(); this.annotationForParentClassWithSummaryKind = new Map(); this.initializeConversionMap(); knownMetadataClasses.forEach(function (kc) { return _this._registerDecoratorOrConstructor(_this.getStaticSymbol(kc.filePath, kc.name), kc.ctor); }); knownMetadataFunctions.forEach(function (kf) { return _this._registerFunction(_this.getStaticSymbol(kf.filePath, kf.name), kf.fn); }); this.annotationForParentClassWithSummaryKind.set(compile_metadata_1.CompileSummaryKind.Directive, [core_1.createDirective, core_1.createComponent]); this.annotationForParentClassWithSummaryKind.set(compile_metadata_1.CompileSummaryKind.Pipe, [core_1.createPipe]); this.annotationForParentClassWithSummaryKind.set(compile_metadata_1.CompileSummaryKind.NgModule, [core_1.createNgModule]); this.annotationForParentClassWithSummaryKind.set(compile_metadata_1.CompileSummaryKind.Injectable, [core_1.createInjectable, core_1.createPipe, core_1.createDirective, core_1.createComponent, core_1.createNgModule]); } StaticReflector.prototype.componentModuleUrl = function (typeOrFunc) { var staticSymbol = this.findSymbolDeclaration(typeOrFunc); return this.symbolResolver.getResourcePath(staticSymbol); }; /** * Invalidate the specified `symbols` on program change. * @param symbols */ StaticReflector.prototype.invalidateSymbols = function (symbols) { var e_1, _a; try { for (var symbols_1 = tslib_1.__values(symbols), symbols_1_1 = symbols_1.next(); !symbols_1_1.done; symbols_1_1 = symbols_1.next()) { var symbol = symbols_1_1.value; this.annotationCache.delete(symbol); this.shallowAnnotationCache.delete(symbol); this.propertyCache.delete(symbol); this.parameterCache.delete(symbol); this.methodCache.delete(symbol); this.staticCache.delete(symbol); this.conversionMap.delete(symbol); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (symbols_1_1 && !symbols_1_1.done && (_a = symbols_1.return)) _a.call(symbols_1); } finally { if (e_1) throw e_1.error; } } }; StaticReflector.prototype.resolveExternalReference = function (ref, containingFile) { var key = undefined; if (!containingFile) { key = ref.moduleName + ":" + ref.name; var declarationSymbol_1 = this.resolvedExternalReferences.get(key); if (declarationSymbol_1) return declarationSymbol_1; } var refSymbol = this.symbolResolver.getSymbolByModule(ref.moduleName, ref.name, containingFile); var declarationSymbol = this.findSymbolDeclaration(refSymbol); if (!containingFile) { this.symbolResolver.recordModuleNameForFileName(refSymbol.filePath, ref.moduleName); this.symbolResolver.recordImportAs(declarationSymbol, refSymbol); } if (key) { this.resolvedExternalReferences.set(key, declarationSymbol); } return declarationSymbol; }; StaticReflector.prototype.findDeclaration = function (moduleUrl, name, containingFile) { return this.findSymbolDeclaration(this.symbolResolver.getSymbolByModule(moduleUrl, name, containingFile)); }; StaticReflector.prototype.tryFindDeclaration = function (moduleUrl, name, containingFile) { var _this = this; return this.symbolResolver.ignoreErrorsFor(function () { return _this.findDeclaration(moduleUrl, name, containingFile); }); }; StaticReflector.prototype.findSymbolDeclaration = function (symbol) { var resolvedSymbol = this.symbolResolver.resolveSymbol(symbol); if (resolvedSymbol) { var resolvedMetadata = resolvedSymbol.metadata; if (resolvedMetadata && resolvedMetadata.__symbolic === 'resolved') { resolvedMetadata = resolvedMetadata.symbol; } if (resolvedMetadata instanceof static_symbol_1.StaticSymbol) { return this.findSymbolDeclaration(resolvedSymbol.metadata); } } return symbol; }; StaticReflector.prototype.tryAnnotations = function (type) { var originalRecorder = this.errorRecorder; this.errorRecorder = function (error, fileName) { }; try { return this.annotations(type); } finally { this.errorRecorder = originalRecorder; } }; StaticReflector.prototype.annotations = function (type) { var _this = this; return this._annotations(type, function (type, decorators) { return _this.simplify(type, decorators); }, this.annotationCache); }; StaticReflector.prototype.shallowAnnotations = function (type) { var _this = this; return this._annotations(type, function (type, decorators) { return _this.simplify(type, decorators, true); }, this.shallowAnnotationCache); }; StaticReflector.prototype._annotations = function (type, simplify, annotationCache) { var annotations = annotationCache.get(type); if (!annotations) { annotations = []; var classMetadata = this.getTypeMetadata(type); var parentType = this.findParentType(type, classMetadata); if (parentType) { var parentAnnotations = this.annotations(parentType); annotations.push.apply(annotations, tslib_1.__spread(parentAnnotations)); } var ownAnnotations_1 = []; if (classMetadata['decorators']) { ownAnnotations_1 = simplify(type, classMetadata['decorators']); if (ownAnnotations_1) { annotations.push.apply(annotations, tslib_1.__spread(ownAnnotations_1)); } } if (parentType && !this.summaryResolver.isLibraryFile(type.filePath) && this.summaryResolver.isLibraryFile(parentType.filePath)) { var summary = this.summaryResolver.resolveSummary(parentType); if (summary && summary.type) { var requiredAnnotationTypes = this.annotationForParentClassWithSummaryKind.get(summary.type.summaryKind); var typeHasRequiredAnnotation = requiredAnnotationTypes.some(function (requiredType) { return ownAnnotations_1.some(function (ann) { return requiredType.isTypeOf(ann); }); }); if (!typeHasRequiredAnnotation) { this.reportError(formatMetadataError(metadataError("Class " + type.name + " in " + type.filePath + " extends from a " + compile_metadata_1.CompileSummaryKind[summary.type.summaryKind] + " in another compilation unit without duplicating the decorator", /* summary */ undefined, "Please add a " + requiredAnnotationTypes.map(function (type) { return type.ngMetadataName; }) .join(' or ') + " decorator to the class"), type), type); } } } annotationCache.set(type, annotations.filter(function (ann) { return !!ann; })); } return annotations; }; StaticReflector.prototype.propMetadata = function (type) { var _this = this; var propMetadata = this.propertyCache.get(type); if (!propMetadata) { var classMetadata = this.getTypeMetadata(type); propMetadata = {}; var parentType = this.findParentType(type, classMetadata); if (parentType) { var parentPropMetadata_1 = this.propMetadata(parentType); Object.keys(parentPropMetadata_1).forEach(function (parentProp) { propMetadata[parentProp] = parentPropMetadata_1[parentProp]; }); } var members_1 = classMetadata['members'] || {}; Object.keys(members_1).forEach(function (propName) { var propData = members_1[propName]; var prop = propData .find(function (a) { return a['__symbolic'] == 'property' || a['__symbolic'] == 'method'; }); var decorators = []; // hasOwnProperty() is used here to make sure we do not look up methods // on `Object.prototype`. if (propMetadata === null || propMetadata === void 0 ? void 0 : propMetadata.hasOwnProperty(propName)) { decorators.push.apply(decorators, tslib_1.__spread(propMetadata[propName])); } propMetadata[propName] = decorators; if (prop && prop['decorators']) { decorators.push.apply(decorators, tslib_1.__spread(_this.simplify(type, prop['decorators']))); } }); this.propertyCache.set(type, propMetadata); } return propMetadata; }; StaticReflector.prototype.parameters = function (type) { var _this = this; if (!(type instanceof static_symbol_1.StaticSymbol)) { this.reportError(new Error("parameters received " + JSON.stringify(type) + " which is not a StaticSymbol"), type); return []; } try { var parameters_1 = this.parameterCache.get(type); if (!parameters_1) { var classMetadata = this.getTypeMetadata(type); var parentType = this.findParentType(type, classMetadata); var members = classMetadata ? classMetadata['members'] : null; var ctorData = members ? members['__ctor__'] : null; if (ctorData) { var ctor = ctorData.find(function (a) { return a['__symbolic'] == 'constructor'; }); var rawParameterTypes = ctor['parameters'] || []; var parameterDecorators_1 = this.simplify(type, ctor['parameterDecorators'] || []); parameters_1 = []; rawParameterTypes.forEach(function (rawParamType, index) { var nestedResult = []; var paramType = _this.trySimplify(type, rawParamType); if (paramType) nestedResult.push(paramType); var decorators = parameterDecorators_1 ? parameterDecorators_1[index] : null; if (decorators) { nestedResult.push.apply(nestedResult, tslib_1.__spread(decorators)); } parameters_1.push(nestedResult); }); } else if (parentType) { parameters_1 = this.parameters(parentType); } if (!parameters_1) { parameters_1 = []; } this.parameterCache.set(type, parameters_1); } return parameters_1; } catch (e) { console.error("Failed on type " + JSON.stringify(type) + " with error " + e); throw e; } }; StaticReflector.prototype._methodNames = function (type) { var methodNames = this.methodCache.get(type); if (!methodNames) { var classMetadata = this.getTypeMetadata(type); methodNames = {}; var parentType = this.findParentType(type, classMetadata); if (parentType) { var parentMethodNames_1 = this._methodNames(parentType); Object.keys(parentMethodNames_1).forEach(function (parentProp) { methodNames[parentProp] = parentMethodNames_1[parentProp]; }); } var members_2 = classMetadata['members'] || {}; Object.keys(members_2).forEach(function (propName) { var propData = members_2[propName]; var isMethod = propData.some(function (a) { return a['__symbolic'] == 'method'; }); methodNames[propName] = methodNames[propName] || isMethod; }); this.methodCache.set(type, methodNames); } return methodNames; }; StaticReflector.prototype._staticMembers = function (type) { var staticMembers = this.staticCache.get(type); if (!staticMembers) { var classMetadata = this.getTypeMetadata(type); var staticMemberData = classMetadata['statics'] || {}; staticMembers = Object.keys(staticMemberData); this.staticCache.set(type, staticMembers); } return staticMembers; }; StaticReflector.prototype.findParentType = function (type, classMetadata) { var parentType = this.trySimplify(type, classMetadata['extends']); if (parentType instanceof static_symbol_1.StaticSymbol) { return parentType; } }; StaticReflector.prototype.hasLifecycleHook = function (type, lcProperty) { if (!(type instanceof static_symbol_1.StaticSymbol)) { this.reportError(new Error("hasLifecycleHook received " + JSON.stringify(type) + " which is not a StaticSymbol"), type); } try { return !!this._methodNames(type)[lcProperty]; } catch (e) { console.error("Failed on type " + JSON.stringify(type) + " with error " + e); throw e; } }; StaticReflector.prototype.guards = function (type) { var e_2, _a; if (!(type instanceof static_symbol_1.StaticSymbol)) { this.reportError(new Error("guards received " + JSON.stringify(type) + " which is not a StaticSymbol"), type); return {}; } var staticMembers = this._staticMembers(type); var result = {}; try { for (var staticMembers_1 = tslib_1.__values(staticMembers), staticMembers_1_1 = staticMembers_1.next(); !staticMembers_1_1.done; staticMembers_1_1 = staticMembers_1.next()) { var name_1 = staticMembers_1_1.value; if (name_1.endsWith(TYPEGUARD_POSTFIX)) { var property = name_1.substr(0, name_1.length - TYPEGUARD_POSTFIX.length); var value = void 0; if (property.endsWith(USE_IF)) { property = name_1.substr(0, property.length - USE_IF.length); value = USE_IF; } else { value = this.getStaticSymbol(type.filePath, type.name, [name_1]); } result[property] = value; } } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (staticMembers_1_1 && !staticMembers_1_1.done && (_a = staticMembers_1.return)) _a.call(staticMembers_1); } finally { if (e_2) throw e_2.error; } } return result; }; StaticReflector.prototype._registerDecoratorOrConstructor = function (type, ctor) { this.conversionMap.set(type, function (context, args) { return new (ctor.bind.apply(ctor, tslib_1.__spread([void 0], args)))(); }); }; StaticReflector.prototype._registerFunction = function (type, fn) { this.conversionMap.set(type, function (context, args) { return fn.apply(undefined, args); }); }; StaticReflector.prototype.initializeConversionMap = function () { this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Injectable'), core_1.createInjectable); 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'); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Host'), core_1.createHost); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Self'), core_1.createSelf); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'SkipSelf'), core_1.createSkipSelf); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Inject'), core_1.createInject); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Optional'), core_1.createOptional); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Attribute'), core_1.createAttribute); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'ContentChild'), core_1.createContentChild); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'ContentChildren'), core_1.createContentChildren); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'ViewChild'), core_1.createViewChild); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'ViewChildren'), core_1.createViewChildren); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Input'), core_1.createInput); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Output'), core_1.createOutput); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Pipe'), core_1.createPipe); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'HostBinding'), core_1.createHostBinding); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'HostListener'), core_1.createHostListener); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Directive'), core_1.createDirective); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Component'), core_1.createComponent); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'NgModule'), core_1.createNgModule); // Note: Some metadata classes can be used directly with Provider.deps. this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Host'), core_1.createHost); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Self'), core_1.createSelf); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'SkipSelf'), core_1.createSkipSelf); this._registerDecoratorOrConstructor(this.findDeclaration(ANGULAR_CORE, 'Optional'), core_1.createOptional); }; /** * getStaticSymbol produces a Type whose metadata is known but whose implementation is not loaded. * All types passed to the StaticResolver should be pseudo-types returned by this method. * * @param declarationFile the absolute path of the file where the symbol is declared * @param name the name of the type. */ StaticReflector.prototype.getStaticSymbol = function (declarationFile, name, members) { return this.symbolResolver.getStaticSymbol(declarationFile, name, members); }; /** * Simplify but discard any errors */ StaticReflector.prototype.trySimplify = function (context, value) { var originalRecorder = this.errorRecorder; this.errorRecorder = function (error, fileName) { }; var result = this.simplify(context, value); this.errorRecorder = originalRecorder; return result; }; /** @internal */ StaticReflector.prototype.simplify = function (context, value, lazy) { if (lazy === void 0) { lazy = false; } var self = this; var scope = BindingScope.empty; var calling = new Map(); var rootContext = context; function simplifyInContext(context, value, depth, references) { function resolveReferenceValue(staticSymbol) { var resolvedSymbol = self.symbolResolver.resolveSymbol(staticSymbol); return resolvedSymbol ? resolvedSymbol.metadata : null; } function simplifyEagerly(value) { return simplifyInContext(context, value, depth, 0); } function simplifyLazily(value) { return simplifyInContext(context, value, depth, references + 1); } function simplifyNested(nestedContext, value) { if (nestedContext === context) { // If the context hasn't changed let the exception propagate unmodified. return simplifyInContext(nestedContext, value, depth + 1, references); } try { return simplifyInContext(nestedContext, value, depth + 1, references); } catch (e) { if (isMetadataError(e)) { // Propagate the message text up but add a message to the chain that explains how we got // here. // e.chain implies e.symbol var summaryMsg = e.chain ? 'references \'' + e.symbol.name + '\'' : errorSummary(e); var summary = "'" + nestedContext.name + "' " + summaryMsg; var chain = { message: summary, position: e.position, next: e.chain }; // TODO(chuckj): retrieve the position information indirectly from the collectors node // map if the metadata is from a .ts file. self.error({ message: e.message, advise: e.advise, context: e.context, chain: chain, symbol: nestedContext }, context); } else { // It is probably an internal error. throw e; } } } function simplifyCall(functionSymbol, targetFunction, args, targetExpression) { if (targetFunction && targetFunction['__symbolic'] == 'function') { if (calling.get(functionSymbol)) { self.error({ message: 'Recursion is not supported', summary: "called '" + functionSymbol.name + "' recursively", value: targetFunction }, functionSymbol); } try { var value_1 = targetFunction['value']; if (value_1 && (depth != 0 || value_1.__symbolic != 'error')) { var parameters = targetFunction['parameters']; var defaults = targetFunction.defaults; args = args.map(function (arg) { return simplifyNested(context, arg); }) .map(function (arg) { return shouldIgnore(arg) ? undefined : arg; }); if (defaults && defaults.length > args.length) { args.push.apply(args, tslib_1.__spread(defaults.slice(args.length).map(function (value) { return simplify(value); }))); } calling.set(functionSymbol, true); var functionScope = BindingScope.build(); for (var i = 0; i < parameters.length; i++) { functionScope.define(parameters[i], args[i]); } var oldScope = scope; var result_1; try { scope = functionScope.done(); result_1 = simplifyNested(functionSymbol, value_1); } finally { scope = oldScope; } return result_1; } } finally { calling.delete(functionSymbol); } } if (depth === 0) { // If depth is 0 we are evaluating the top level expression that is describing element // decorator. In this case, it is a decorator we don't understand, such as a custom // non-angular decorator, and we should just ignore it. return IGNORE; } var position = undefined; if (targetExpression && targetExpression.__symbolic == 'resolved') { var line = targetExpression.line; var character = targetExpression.character; var fileName = targetExpression.fileName; if (fileName != null && line != null && character != null) { position = { fileName: fileName, line: line, column: character }; } } self.error({ message: FUNCTION_CALL_NOT_SUPPORTED, context: functionSymbol, value: targetFunction, position: position }, context); } function simplify(expression) { var e_3, _a, e_4, _b; if (isPrimitive(expression)) { return expression; } if (Array.isArray(expression)) { var result_2 = []; try { for (var _c = tslib_1.__values(expression), _d = _c.next(); !_d.done; _d = _c.next()) { var item = _d.value; // Check for a spread expression if (item && item.__symbolic === 'spread') { // We call with references as 0 because we require the actual value and cannot // tolerate a reference here. var spreadArray = simplifyEagerly(item.expression); if (Array.isArray(spreadArray)) { try { for (var spreadArray_1 = (e_4 = void 0, tslib_1.__values(spreadArray)), spreadArray_1_1 = spreadArray_1.next(); !spreadArray_1_1.done; spreadArray_1_1 = spreadArray_1.next()) { var spreadItem = spreadArray_1_1.value; result_2.push(spreadItem); } } catch (e_4_1) { e_4 = { error: e_4_1 }; } finally { try { if (spreadArray_1_1 && !spreadArray_1_1.done && (_b = spreadArray_1.return)) _b.call(spreadArray_1); } finally { if (e_4) throw e_4.error; } } continue; } } var value_2 = simplify(item); if (shouldIgnore(value_2)) { continue; } result_2.push(value_2); } } catch (e_3_1) { e_3 = { error: e_3_1 }; } finally { try { if (_d && !_d.done && (_a = _c.return)) _a.call(_c); } finally { if (e_3) throw e_3.error; } } return result_2; } if (expression instanceof static_symbol_1.StaticSymbol) { // Stop simplification at builtin symbols or if we are in a reference context and // the symbol doesn't have members. if (expression === self.injectionToken || self.conversionMap.has(expression) || (references > 0 && !expression.members.length)) { return expression; } else { var staticSymbol = expression; var declarationValue = resolveReferenceValue(staticSymbol); if (declarationValue != null) { return simplifyNested(staticSymbol, declarationValue); } else { return staticSymbol; } } } if (expression) { if (expression['__symbolic']) { var staticSymbol = void 0; switch (expression['__symbolic']) { case 'binop': var left = simplify(expression['left']); if (shouldIgnore(left)) return left; var right = simplify(expression['right']); if (shouldIgnore(right)) return right; switch (expression['operator']) { case '&&': return left && right; case '||': return left || right; case '|': return left | right; case '^': return left ^ right; case '&': return left & right; case '==': return left == right; case '!=': return left != right; case '===': return left === right; case '!==': return left !== right; case '<': return left < right; case '>': return left > right; case '<=': return left <= right; case '>=': return left >= right; case '<<': return left << right; case '>>': return left >> right; case '+': return left + right; case '-': return left - right; case '*': return left * right; case '/': return left / right; case '%': return left % right; } return null; case 'if': var condition = simplify(expression['condition']); return condition ? simplify(expression['thenExpression']) : simplify(expression['elseExpression']); case 'pre': var operand = simplify(expression['operand']); if (shouldIgnore(operand)) return operand; switch (expression['operator']) { case '+': return operand; case '-': return -operand; case '!': return !operand; case '~': return ~operand; } return null; case 'index': var indexTarget = simplifyEagerly(expression['expression']); var index = simplifyEagerly(expression['index']); if (indexTarget && isPrimitive(index)) return indexTarget[index]; return null; case 'select': var member = expression['member']; var selectContext = context; var selectTarget = simplify(expression['expression']); if (selectTarget instanceof static_symbol_1.StaticSymbol) { var members = selectTarget.members.concat(member); selectContext = self.getStaticSymbol(selectTarget.filePath, selectTarget.name, members); var declarationValue = resolveReferenceValue(selectContext); if (declarationValue != null) { return simplifyNested(selectContext, declarationValue); } else { return selectContext; } } if (selectTarget && isPrimitive(member)) return simplifyNested(selectContext, selectTarget[member]); return null; case 'reference': // Note: This only has to deal with variable references, as symbol references have // been converted into 'resolved' // in the StaticSymbolResolver. var name_2 = expression['name']; var localValue = scope.resolve(name_2); if (localValue != BindingScope.missing) { return localValue; } break; case 'resolved': try { return simplify(expression.symbol); } catch (e) { // If an error is reported evaluating the symbol record the position of the // reference in the error so it can // be reported in the error message generated from the exception. if (isMetadataError(e) && expression.fileName != null && expression.line != null && expression.character != null) { e.position = { fileName: expression.fileName, line: expression.line, column: expression.character }; } throw e; } case 'class': return context; case 'function': return context; case 'new': case 'call': // Determine if the function is a built-in conversion staticSymbol = simplifyInContext(context, expression['expression'], depth + 1, /* references */ 0); if (staticSymbol instanceof static_symbol_1.StaticSymbol) { 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; } var argExpressions = expression['arguments'] || []; var converter = self.conversionMap.get(staticSymbol); if (converter) { var args = argExpressions.map(function (arg) { return simplifyNested(context, arg); }) .map(function (arg) { return shouldIgnore(arg) ? undefined : arg; }); return converter(context, args); } else { // Determine if the function is one we can simplify. var targetFunction = resolveReferenceValue(staticSymbol); return simplifyCall(staticSymbol, targetFunction, argExpressions, expression['expression']); } } return IGNORE; case 'error': var message = expression.message; if (expression['line'] != null) { self.error({ message: message, context: expression.context, value: expression, position: { fileName: expression['fileName'], line: expression['line'], column: expression['character'] } }, context); } else { self.error({ message: message, context: expression.context }, context); } return IGNORE; case 'ignore': return expression; } return null; } return mapStringMap(expression, function (value, name) { if (REFERENCE_SET.has(name)) { if (name === USE_VALUE && PROVIDE in expression) { // If this is a provider expression, check for special tokens that need the value // during analysis. var provide = simplify(expression.provide); if (provide === self.ROUTES || provide == self.ANALYZE_FOR_ENTRY_COMPONENTS) { return simplify(value); } } return simplifyLazily(value); } return simplify(value); }); } return IGNORE; } return simplify(value); } var result; try { result = simplifyInContext(context, value, 0, lazy ? 1 : 0); } catch (e) { if (this.errorRecorder) { this.reportError(e, context); } else { throw formatMetadataError(e, context); } } if (shouldIgnore(result)) { return undefined; } return result; }; StaticReflector.prototype.getTypeMetadata = function (type) { var resolvedSymbol = this.symbolResolver.resolveSymbol(type); return resolvedSymbol && resolvedSymbol.metadata ? resolvedSymbol.metadata : { __symbolic: 'class' }; }; StaticReflector.prototype.reportError = function (error, context, path) { if (this.errorRecorder) { this.errorRecorder(formatMetadataError(error, context), (context && context.filePath) || path); } else { throw error; } }; StaticReflector.prototype.error = function (_a, reportingContext) { var message = _a.message, summary = _a.summary, advise = _a.advise, position = _a.position, context = _a.context, value = _a.value, symbol = _a.symbol, chain = _a.chain; this.reportError(metadataError(message, summary, advise, position, symbol, context, chain), reportingContext); }; return StaticReflector; }()); exports.StaticReflector = StaticReflector; var METADATA_ERROR = 'ngMetadataError'; function metadataError(message, summary, advise, position, symbol, context, chain) { var error = util_1.syntaxError(message); error[METADATA_ERROR] = true; if (advise) error.advise = advise; if (position) error.position = position; if (summary) error.summary = summary; if (context) error.context = context; if (chain) error.chain = chain; if (symbol) error.symbol = symbol; return error; } function isMetadataError(error) { return !!error[METADATA_ERROR]; } var REFERENCE_TO_NONEXPORTED_CLASS = 'Reference to non-exported class'; var VARIABLE_NOT_INITIALIZED = 'Variable not initialized'; var DESTRUCTURE_NOT_SUPPORTED = 'Destructuring not supported'; var COULD_NOT_RESOLVE_TYPE = 'Could not resolve type'; var FUNCTION_CALL_NOT_SUPPORTED = 'Function call not supported'; var REFERENCE_TO_LOCAL_SYMBOL = 'Reference to a local symbol'; var LAMBDA_NOT_SUPPORTED = 'Lambda not supported'; function expandedMessage(message, context) { switch (message) { case REFERENCE_TO_NONEXPORTED_CLASS: if (context && context.className) { return "References to a non-exported class are not supported in decorators but " + context.className + " was referenced."; } break; case VARIABLE_NOT_INITIALIZED: return 'Only initialized variab