fix(perf): support prod mode again

After splitting the facades into multiple modules,
enabling prod mode for code had no effect for the compiler.

Also in a change between RC1 and RC2 we created the `CompilerConfig`
via a provider with `useValue` and not via a `useFactory`, which reads
the prod mode too early.

Closes #9318
Closes #8508
Closes #9318
This commit is contained in:
Tobias Bosch 2016-06-17 14:09:19 -07:00
parent 5c8d3154d7
commit c0f2a22a08
21 changed files with 110 additions and 112 deletions

View File

@ -4,9 +4,12 @@ require('zone.js/dist/zone-node.js');
require('zone.js/dist/long-stack-trace-zone.js');
import {AnimateCmpNgFactory} from '../src/animate.ngfactory';
import {ReflectiveInjector, DebugElement, getDebugNode} from '@angular/core';
import {ReflectiveInjector, DebugElement, getDebugNode, lockRunMode} from '@angular/core';
import {browserPlatform, BROWSER_APP_PROVIDERS} from '@angular/platform-browser';
// Need to lock the mode explicitely as this test is not using Angular's testing framework.
lockRunMode();
describe('template codegen output', () => {
function findTargetElement(elm: DebugElement): DebugElement {
// the open-close-container is a child of the main container

View File

@ -10,9 +10,12 @@ import * as fs from 'fs';
import * as path from 'path';
import {BasicNgFactory} from '../src/basic.ngfactory';
import {MyComp} from '../src/a/multiple_components';
import {ReflectiveInjector, DebugElement, getDebugNode} from '@angular/core';
import {ReflectiveInjector, DebugElement, getDebugNode, lockRunMode} from '@angular/core';
import {browserPlatform, BROWSER_APP_PROVIDERS} from '@angular/platform-browser';
// Need to lock the mode explicitely as this test is not using Angular's testing framework.
lockRunMode();
describe('template codegen output', () => {
const outDir = 'src';

View File

@ -1,9 +1,12 @@
import {DebugElement, ReflectiveInjector, getDebugNode} from '@angular/core';
import {DebugElement, ReflectiveInjector, getDebugNode, lockRunMode} from '@angular/core';
import {BROWSER_APP_PROVIDERS, By, browserPlatform} from '@angular/platform-browser';
import {CompWithProjection} from '../src/projection';
import {MainCompNgFactory} from '../src/projection.ngfactory';
// Need to lock the mode explicitely as this test is not using Angular's testing framework.
lockRunMode();
describe('content projection', () => {
it('should support basic content projection', () => {
const appInjector =

View File

@ -3,7 +3,7 @@
* Intended to be used in a build step.
*/
import * as compiler from '@angular/compiler';
import {ViewEncapsulation} from '@angular/core';
import {ViewEncapsulation, lockRunMode} from '@angular/core';
import {Parse5DomAdapter} from '@angular/platform-server';
import {AngularCompilerOptions} from '@angular/tsc-wrapped';
import * as path from 'path';
@ -29,7 +29,9 @@ export class CodeGenerator {
private options: AngularCompilerOptions, private program: ts.Program,
public host: ts.CompilerHost, private staticReflector: StaticReflector,
private resolver: CompileMetadataResolver, private compiler: compiler.OfflineCompiler,
private reflectorHost: ReflectorHost) {}
private reflectorHost: ReflectorHost) {
lockRunMode();
}
private generateSource(metadatas: compiler.CompileDirectiveMetadata[]) {
const normalize = (metadata: compiler.CompileDirectiveMetadata) => {

View File

@ -11,7 +11,7 @@ import * as ts from 'typescript';
import * as tsc from '@angular/tsc-wrapped';
import * as path from 'path';
import * as compiler from '@angular/compiler';
import {ViewEncapsulation} from '@angular/core';
import {ViewEncapsulation, lockRunMode} from '@angular/core';
import {StaticReflector} from './static_reflector';
import {CompileMetadataResolver, HtmlParser, DirectiveNormalizer, Lexer, Parser, TemplateParser, DomElementSchemaRegistry, StyleCompiler, ViewCompiler, TypeScriptEmitter, MessageExtractor, removeDuplicates, ExtractionResult, Message, ParseError, serializeXmb,} from './compiler_private';
@ -35,7 +35,9 @@ class Extractor {
private _options: tsc.AngularCompilerOptions, private _program: ts.Program,
public host: ts.CompilerHost, private staticReflector: StaticReflector,
private _resolver: CompileMetadataResolver, private _compiler: compiler.OfflineCompiler,
private _reflectorHost: ReflectorHost, private _extractor: MessageExtractor) {}
private _reflectorHost: ReflectorHost, private _extractor: MessageExtractor) {
lockRunMode();
}
private _extractCmpMessages(metadatas: compiler.CompileDirectiveMetadata[]):
Promise<ExtractionResult> {

View File

@ -1,8 +1,10 @@
import {isDevMode} from '@angular/core';
import {BaseException} from '../src/facade/exceptions';
import {assertionsEnabled, isArray, isBlank, isString} from '../src/facade/lang';
import {isArray, isBlank, isString} from '../src/facade/lang';
export function assertArrayOfStrings(identifier: string, value: any) {
if (!assertionsEnabled() || isBlank(value)) {
if (!isDevMode() || isBlank(value)) {
return;
}
if (!isArray(value)) {

View File

@ -1,7 +1,6 @@
import {ViewEncapsulation} from '@angular/core';
import {ViewEncapsulation, isDevMode} from '@angular/core';
import {unimplemented} from '../src/facade/exceptions';
import {assertionsEnabled} from '../src/facade/lang';
import {CompileIdentifierMetadata} from './compile_metadata';
import {Identifiers} from './identifiers';
@ -9,16 +8,16 @@ import {Identifiers} from './identifiers';
export class CompilerConfig {
public renderTypes: RenderTypes;
public defaultEncapsulation: ViewEncapsulation;
public genDebugInfo: boolean;
public logBindingUpdate: boolean;
private _genDebugInfo: boolean;
private _logBindingUpdate: boolean;
public useJit: boolean;
public platformDirectives: any[];
public platformPipes: any[];
constructor(
{renderTypes = new DefaultRenderTypes(), defaultEncapsulation = ViewEncapsulation.Emulated,
genDebugInfo = assertionsEnabled(), logBindingUpdate = assertionsEnabled(), useJit = true,
platformDirectives = [], platformPipes = []}: {
genDebugInfo, logBindingUpdate, useJit = true, platformDirectives = [],
platformPipes = []}: {
renderTypes?: RenderTypes,
defaultEncapsulation?: ViewEncapsulation,
genDebugInfo?: boolean,
@ -29,12 +28,19 @@ export class CompilerConfig {
} = {}) {
this.renderTypes = renderTypes;
this.defaultEncapsulation = defaultEncapsulation;
this.genDebugInfo = genDebugInfo;
this.logBindingUpdate = logBindingUpdate;
this._genDebugInfo = genDebugInfo;
this._logBindingUpdate = logBindingUpdate;
this.useJit = useJit;
this.platformDirectives = platformDirectives;
this.platformPipes = platformPipes;
}
get genDebugInfo(): boolean {
return this._genDebugInfo === void 0 ? isDevMode() : this._genDebugInfo;
}
get logBindingUpdate(): boolean {
return this._logBindingUpdate === void 0 ? isDevMode() : this._logBindingUpdate;
}
}
/**

View File

@ -3,7 +3,6 @@ library angular2.core;
export './src/core/angular_entrypoint.dart' show AngularEntrypoint;
export './src/core/metadata.dart';
export './src/core/util.dart';
export 'package:angular2/src/facade/lang.dart' show enableProdMode;
export './src/core/di.dart' hide ForwardRefFn, resolveForwardRef, forwardRef;
export './src/facade/facade.dart';
export './src/core/application_ref.dart' show createPlatform, assertPlatform,

View File

@ -6,7 +6,7 @@
export * from './src/metadata';
export * from './src/util';
export * from './src/di';
export {createPlatform, assertPlatform, disposePlatform, getPlatform, coreBootstrap, coreLoadAndBootstrap, createNgZone, PlatformRef, ApplicationRef} from './src/application_ref';
export {createPlatform, assertPlatform, disposePlatform, getPlatform, coreBootstrap, coreLoadAndBootstrap, createNgZone, PlatformRef, ApplicationRef, enableProdMode, lockRunMode, isDevMode} from './src/application_ref';
export {APP_ID, APP_INITIALIZER, PACKAGE_ROOT_URL, PLATFORM_INITIALIZER} from './src/application_tokens';
export * from './src/zone';
export * from './src/render';
@ -19,7 +19,7 @@ export * from './src/platform_common_providers';
export * from './src/application_common_providers';
export {wtfCreateScope, wtfLeave, wtfStartTimeRange, wtfEndTimeRange, WtfScopeFn} from './src/profile/profile';
export {Type, enableProdMode} from './src/facade/lang';
export {Type} from './src/facade/lang';
export {EventEmitter} from './src/facade/async';
export {ExceptionHandler, WrappedException, BaseException} from './src/facade/exceptions';
export * from './private_export';

View File

@ -1,7 +1,7 @@
import {ObservableWrapper, PromiseWrapper} from '../src/facade/async';
import {ListWrapper} from '../src/facade/collection';
import {BaseException, ExceptionHandler, unimplemented} from '../src/facade/exceptions';
import {IS_DART, Type, assertionsEnabled, isBlank, isPresent, isPromise, lockMode} from '../src/facade/lang';
import {IS_DART, Type, isBlank, isPresent, isPromise} from '../src/facade/lang';
import {APP_INITIALIZER, PLATFORM_INITIALIZER} from './application_tokens';
import {ChangeDetectorRef} from './change_detection/change_detector_ref';
@ -13,18 +13,58 @@ import {WtfScopeFn, wtfCreateScope, wtfLeave} from './profile/profile';
import {Testability, TestabilityRegistry} from './testability/testability';
import {NgZone, NgZoneError} from './zone/ng_zone';
/**
* Create an Angular zone.
* @experimental
*/
export function createNgZone(): NgZone {
return new NgZone({enableLongStackTrace: assertionsEnabled()});
return new NgZone({enableLongStackTrace: isDevMode()});
}
var _devMode: boolean = true;
var _runModeLocked: boolean = false;
var _platform: PlatformRef;
var _inPlatformCreate: boolean = false;
/**
* Disable Angular's development mode, which turns off assertions and other
* checks within the framework.
*
* One important assertion this disables verifies that a change detection pass
* does not result in additional changes to any bindings (also known as
* unidirectional data flow).
* @stable
*/
export function enableProdMode(): void {
if (_runModeLocked) {
// Cannot use BaseException as that ends up importing from facade/lang.
throw new BaseException('Cannot enable prod mode after platform setup.');
}
_devMode = false;
}
/**
* Returns whether Angular is in development mode.
* This can only be read after `lockRunMode` has been called.
*
* By default, this is true, unless a user calls `enableProdMode`.
*/
export function isDevMode(): boolean {
if (!_runModeLocked) {
throw new BaseException(`Dev mode can't be read before bootstrap!`);
}
return _devMode;
}
/**
* Locks the run mode of Angular. After this has been called,
* it can't be changed any more. I.e. `isDevMode()` will always
* return the same value.
*/
export function lockRunMode(): void {
_runModeLocked = true;
}
/**
* Creates a platform.
* Platforms have to be eagerly created via this function.
@ -38,7 +78,7 @@ export function createPlatform(injector: Injector): PlatformRef {
throw new BaseException(
'There can be only one platform. Destroy the previous one to create a new one.');
}
lockMode();
lockRunMode();
_inPlatformCreate = true;
try {
_platform = injector.get(PlatformRef);
@ -281,7 +321,7 @@ export class ApplicationRef_ extends ApplicationRef {
constructor(private _platform: PlatformRef_, private _zone: NgZone, private _injector: Injector) {
super();
var zone: NgZone = _injector.get(NgZone);
this._enforceNoNewChanges = assertionsEnabled();
this._enforceNoNewChanges = isDevMode();
zone.run(() => { this._exceptionHandler = _injector.get(ExceptionHandler); });
this._asyncInitDonePromise = this.run(() => {
let inits: Function[] = _injector.get(APP_INITIALIZER, null);
@ -373,7 +413,7 @@ export class ApplicationRef_ extends ApplicationRef {
this._loadComponent(compRef);
let c: Console = this._injector.get(Console);
if (assertionsEnabled()) {
if (isDevMode()) {
let prodDescription = IS_DART ? 'Production mode is disabled in Dart.' :
'Call enableProdMode() to enable the production mode.';
c.log(`Angular 2 is running in the development mode. ${prodDescription}`);

View File

@ -1,6 +1,6 @@
import {ObservableWrapper} from '../facade/async';
import {ListWrapper, Map, MapWrapper, StringMapWrapper} from '../facade/collection';
import {Type, assertionsEnabled, isArray, isBlank, isNumber, isPresent, isPrimitive, isString, stringify} from '../facade/lang';
import {Type, isArray, isBlank, isNumber, isPresent, isPrimitive, isString, stringify} from '../facade/lang';
import {RenderComponentType, RenderDebugInfo, Renderer, RootRenderer} from '../render/api';
import {AppElement} from './element';

View File

@ -1 +0,0 @@
export {enableProdMode} from '../src/facade/lang';

View File

@ -1,21 +1,9 @@
import {IS_DART, assertionsEnabled} from '../../router/src/facade/lang';
import {isDevMode} from '@angular/core';
import {beforeEach, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '../testing';
export function main() {
describe('dev mode', () => {
it('is enabled in our tests by default', () => { expect(assertionsEnabled()).toBe(true); });
it('is enabled in our tests by default', () => { expect(isDevMode()).toBe(true); });
});
if (IS_DART) {
describe('checked mode', () => {
it('is enabled in our tests', () => {
try {
var s: string = <any>42;
expect(s).toEqual(42); // without it, dart analyzer will complain that `s` is not used.
throw 'should not be reached';
} catch (e) {
}
});
});
}
}

View File

@ -1,4 +1,5 @@
import {PLATFORM_INITIALIZER, Provider, ReflectiveInjector, Type} from '../index';
import {lockRunMode} from '../src/application_ref';
import {ListWrapper} from '../src/facade/collection';
import {BaseException} from '../src/facade/exceptions';
import {FunctionWrapper, isPresent} from '../src/facade/lang';
@ -33,6 +34,7 @@ export class TestInjector {
}
createInjector() {
lockRunMode();
var rootInjector = ReflectiveInjector.resolveAndCreate(this.platformProviders);
this._injector = rootInjector.resolveAndCreateChild(
ListWrapper.concat(this.applicationProviders, this._providers));

View File

@ -310,36 +310,6 @@ warn(o) {
print(o);
}
// Functions below are noop in Dart. Imperatively controlling dev mode kills
// tree shaking. We should only rely on `assertionsEnabled`.
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')
void lockMode() {}
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')
void enableDevMode() {}
@Deprecated('Do not use this function. It is for JS only. There is no alternative.')
void enableProdMode() {}
/// Use this function to guard debugging code. When Dart is compiled in
/// production mode, the code guarded using this function will be tree
/// shaken away, reducing code size.
///
/// WARNING: DO NOT CHANGE THIS METHOD! This method is designed to have no
/// more AST nodes than the maximum allowed by dart2js to inline it. In
/// addition, the use of `assert` allows the compiler to statically compute
/// the value returned by this function and tree shake conditions guarded by
/// it.
///
/// Example:
///
/// if (assertionsEnabled()) {
/// ...code here is tree shaken away in prod mode...
/// }
bool assertionsEnabled() {
var k = false;
assert((k = true));
return k;
}
// Can't be all uppercase as our transpiler would think it is a special directive...
class Json {
static parse(String s) => convert.JSON.decode(s);

View File

@ -77,34 +77,6 @@ export function getTypeNameForDebugging(type: Type): string {
export var Math = _global.Math;
export var Date = _global.Date;
var _devMode: boolean = true;
var _modeLocked: boolean = false;
export function lockMode() {
_modeLocked = true;
}
/**
* Disable Angular's development mode, which turns off assertions and other
* checks within the framework.
*
* One important assertion this disables verifies that a change detection pass
* does not result in additional changes to any bindings (also known as
* unidirectional data flow).
* @stable
*/
export function enableProdMode() {
if (_modeLocked) {
// Cannot use BaseException as that ends up importing from facade/lang.
throw 'Cannot enable prod mode after platform setup.';
}
_devMode = false;
}
export function assertionsEnabled(): boolean {
return _devMode;
}
// TODO: remove calls to assert in production environment
// Note: Can't just export this and import in in other files
// as `assert` is a reserved keyword in Dart

View File

@ -1,7 +1,6 @@
import {ApplicationRef, DebugNode, NgZone, RootRenderer, getDebugNode} from '@angular/core';
import {ApplicationRef, DebugNode, NgZone, RootRenderer, getDebugNode, isDevMode} from '@angular/core';
import {DebugDomRootRenderer} from '../../../core_private';
import {assertionsEnabled} from '../../facade/lang';
import {getDOM} from '../dom_adapter';
import {DomRootRenderer} from '../dom_renderer';
@ -24,7 +23,7 @@ export function inspectNativeElement(element: any /** TODO #9100 */): DebugNode
}
function _createConditionalRootRenderer(rootRenderer: any /** TODO #9100 */) {
if (assertionsEnabled()) {
if (isDevMode()) {
return _createRootRenderer(rootRenderer);
}
return rootRenderer;

View File

@ -1,9 +1,11 @@
import {isDevMode} from '@angular/core';
import {DomAdapter, getDOM} from '../dom/dom_adapter';
import {assertionsEnabled} from '../facade/lang';
import {sanitizeUrl} from './url_sanitizer';
/** A <body> element that can be safely used to parse untrusted HTML. Lazily initialized below. */
let inertElement: HTMLElement = null;
/** Lazily initialized to make sure the DOM adapter gets set before use. */
@ -256,7 +258,7 @@ export function sanitizeHtml(unsafeHtml: string): string {
DOM.removeChild(parent, child);
}
if (assertionsEnabled() && safeHtml !== unsafeHtml) {
if (isDevMode() && safeHtml !== unsafeHtml) {
DOM.log('WARNING: sanitizing HTML stripped some content.');
}

View File

@ -1,8 +1,10 @@
import {isDevMode} from '@angular/core';
import {getDOM} from '../dom/dom_adapter';
import {assertionsEnabled} from '../facade/lang';
import {sanitizeUrl} from './url_sanitizer';
/**
* Regular expression for safe style values.
*
@ -81,7 +83,7 @@ export function sanitizeStyle(value: string): string {
return value; // Safe style values.
}
if (assertionsEnabled()) getDOM().log('WARNING: sanitizing unsafe style value ' + value);
if (isDevMode()) getDOM().log('WARNING: sanitizing unsafe style value ' + value);
return 'unsafe';
}

View File

@ -1,5 +1,7 @@
import {isDevMode} from '@angular/core';
import {getDOM} from '../dom/dom_adapter';
import {assertionsEnabled} from '../facade/lang';
/**
* A pattern that recognizes a commonly useful subset of URLs that are safe.
@ -37,7 +39,7 @@ export function sanitizeUrl(url: string): string {
url = String(url);
if (url.match(SAFE_URL_PATTERN) || url.match(DATA_URL_PATTERN)) return url;
if (assertionsEnabled()) getDOM().log('WARNING: sanitizing unsafe URL value ' + url);
if (isDevMode()) getDOM().log('WARNING: sanitizing unsafe URL value ' + url);
return 'unsafe:' + url;
}

View File

@ -254,7 +254,7 @@ const CORE = [
'EmbeddedViewRef.destroy():any',
'EmbeddedViewRef.rootNodes:any[]',
'EmbeddedViewRef<C>',
'enableProdMode():any',
'enableProdMode():void',
'EventEmitter.constructor(isAsync:boolean=false)',
'EventEmitter.emit(value:T):any',
'EventEmitter.next(value:any):any',
@ -311,6 +311,7 @@ const CORE = [
'InstantiationError.wrapperMessage:string',
'InvalidProviderError',
'InvalidProviderError.constructor(provider:any)',
'isDevMode():boolean',
'IterableDiffer',
'IterableDiffer.diff(object:any):any',
'IterableDiffer.onDestroy():any',
@ -342,6 +343,7 @@ const CORE = [
'KeyValueDiffers.extend(factories:KeyValueDifferFactory[]):Provider',
'KeyValueDiffers.factories:KeyValueDifferFactory[]',
'KeyValueDiffers.find(kv:Object):KeyValueDifferFactory',
'lockRunMode():void',
'NgZone',
'NgZone.assertInAngularZone():void',
'NgZone.assertNotInAngularZone():void',
@ -1217,7 +1219,7 @@ const COMPILER = [
'CompileQueryMetadata.selectors:Array<CompileTokenMetadata>',
'CompileQueryMetadata.toJson():{[key:string]:any}',
'CompilerConfig',
'CompilerConfig.constructor({renderTypes=newDefaultRenderTypes(),defaultEncapsulation=ViewEncapsulation.Emulated,genDebugInfo=assertionsEnabled(),logBindingUpdate=assertionsEnabled(),useJit=true,platformDirectives=[],platformPipes=[]}:{renderTypes?:RenderTypes, defaultEncapsulation?:ViewEncapsulation, genDebugInfo?:boolean, logBindingUpdate?:boolean, useJit?:boolean, platformDirectives?:any[], platformPipes?:any[]}={})',
'CompilerConfig.constructor({renderTypes=newDefaultRenderTypes(),defaultEncapsulation=ViewEncapsulation.Emulated,genDebugInfo,logBindingUpdate,useJit=true,platformDirectives=[],platformPipes=[]}:{renderTypes?:RenderTypes, defaultEncapsulation?:ViewEncapsulation, genDebugInfo?:boolean, logBindingUpdate?:boolean, useJit?:boolean, platformDirectives?:any[], platformPipes?:any[]}={})',
'CompilerConfig.defaultEncapsulation:ViewEncapsulation',
'CompilerConfig.genDebugInfo:boolean',
'CompilerConfig.logBindingUpdate:boolean',