Skip to content

Commit

Permalink
perf: allow assertions to be removed in production mode (#20146)
Browse files Browse the repository at this point in the history
Wraps all assertions in `ngDevMode` checks so that they can be stripped away in production mode. Furthermore, changes all the places where we were using the old `isDevMode` check.
  • Loading branch information
crisbeto committed Aug 21, 2020
1 parent f343ded commit 79e4d28
Show file tree
Hide file tree
Showing 138 changed files with 453 additions and 347 deletions.
6 changes: 6 additions & 0 deletions src/BUILD.bazel
Expand Up @@ -2,6 +2,7 @@ load("@npm_bazel_typescript//:index.bzl", "ts_config")
load("//src/cdk:config.bzl", "CDK_ENTRYPOINTS")
load("//src/material:config.bzl", "MATERIAL_ENTRYPOINTS", "MATERIAL_TESTING_ENTRYPOINTS")
load("//tools/dgeni:index.bzl", "dgeni_api_docs")
load("//tools:defaults.bzl", "ts_library")

package(default_visibility = ["//visibility:public"])

Expand Down Expand Up @@ -43,3 +44,8 @@ dgeni_api_docs(
},
tags = ["docs-package"],
)

ts_library(
name = "dev_mode_types",
srcs = ["dev-mode-types.d.ts"],
)
1 change: 1 addition & 0 deletions src/cdk-experimental/combobox/BUILD.bazel
Expand Up @@ -10,6 +10,7 @@ ng_module(
),
module_name = "@angular/cdk-experimental/combobox",
deps = [
"//src:dev_mode_types",
"//src/cdk/a11y",
"//src/cdk/bidi",
"//src/cdk/collections",
Expand Down
5 changes: 3 additions & 2 deletions src/cdk-experimental/combobox/combobox.ts
Expand Up @@ -15,7 +15,7 @@ import {
Directive,
ElementRef,
EventEmitter,
Input, isDevMode,
Input,
OnDestroy,
Optional,
Output, ViewContainerRef
Expand Down Expand Up @@ -273,7 +273,8 @@ export class CdkCombobox<T = unknown> implements OnDestroy, AfterContentInit {

private _coerceOpenActionProperty(input: string | OpenAction[]): OpenAction[] {
let actions = typeof input === 'string' ? input.trim().split(/[ ,]+/) : input;
if (isDevMode() && actions.some(a => allowedOpenActions.indexOf(a) === -1)) {
if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
actions.some(a => allowedOpenActions.indexOf(a) === -1)) {
throw Error(`${input} is not a support open action for CdkCombobox`);
}
return actions as OpenAction[];
Expand Down
1 change: 1 addition & 0 deletions src/cdk-experimental/dialog/BUILD.bazel
Expand Up @@ -11,6 +11,7 @@ ng_module(
assets = [":dialog-container.css"] + glob(["**/*.html"]),
module_name = "@angular/cdk-experimental/dialog",
deps = [
"//src:dev_mode_types",
"//src/cdk/a11y",
"//src/cdk/bidi",
"//src/cdk/keycodes",
Expand Down
6 changes: 3 additions & 3 deletions src/cdk-experimental/dialog/dialog-container.ts
Expand Up @@ -171,7 +171,7 @@ export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy {
* @param portal Portal to be attached as the dialog content.
*/
attachComponentPortal<T>(portal: ComponentPortal<T>): ComponentRef<T> {
if (this._portalHost.hasAttached()) {
if (this._portalHost.hasAttached() && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throwDialogContentAlreadyAttachedError();
}

Expand All @@ -183,7 +183,7 @@ export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy {
* @param portal Portal to be attached as the dialog content.
*/
attachTemplatePortal<C>(portal: TemplatePortal<C>): EmbeddedViewRef<C> {
if (this._portalHost.hasAttached()) {
if (this._portalHost.hasAttached() && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throwDialogContentAlreadyAttachedError();
}

Expand All @@ -197,7 +197,7 @@ export class CdkDialogContainer extends BasePortalOutlet implements OnDestroy {
* @breaking-change 10.0.0
*/
attachDomPortal = (portal: DomPortal) => {
if (this._portalHost.hasAttached()) {
if (this._portalHost.hasAttached() && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throwDialogContentAlreadyAttachedError();
}

Expand Down
4 changes: 2 additions & 2 deletions src/cdk-experimental/dialog/dialog.ts
Expand Up @@ -106,7 +106,7 @@ export class Dialog implements OnDestroy {
openFromComponent<T>(component: ComponentType<T>, config?: DialogConfig): DialogRef<any> {
config = this._applyConfigDefaults(config);

if (config.id && this.getById(config.id)) {
if (config.id && this.getById(config.id) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error(`Dialog with id "${config.id}" exists already. The dialog id must be unique.`);
}

Expand All @@ -125,7 +125,7 @@ export class Dialog implements OnDestroy {
openFromTemplate<T>(template: TemplateRef<T>, config?: DialogConfig): DialogRef<any> {
config = this._applyConfigDefaults(config);

if (config.id && this.getById(config.id)) {
if (config.id && this.getById(config.id) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error(`Dialog with id "${config.id}" exists already. The dialog id must be unique.`);
}

Expand Down
1 change: 1 addition & 0 deletions src/cdk-experimental/menu/BUILD.bazel
Expand Up @@ -10,6 +10,7 @@ ng_module(
),
module_name = "@angular/cdk-experimental/menu",
deps = [
"//src:dev_mode_types",
"//src/cdk/a11y",
"//src/cdk/bidi",
"//src/cdk/coercion",
Expand Down
5 changes: 1 addition & 4 deletions src/cdk-experimental/menu/context-menu.ts
Expand Up @@ -17,7 +17,6 @@ import {
Inject,
Injectable,
InjectionToken,
isDevMode,
} from '@angular/core';
import {DOCUMENT} from '@angular/common';
import {Directionality} from '@angular/cdk/bidi';
Expand Down Expand Up @@ -110,9 +109,7 @@ export class CdkContextMenuTrigger implements OnDestroy {
return this._menuPanel;
}
set menuPanel(panel: CdkMenuPanel) {
// If the provided panel already has a stack, that means it already has a trigger configured
// TODO refactor once https://github.com/angular/components/pull/20146 lands
if (isDevMode() && panel._menuStack) {
if ((typeof ngDevMode === 'undefined' || ngDevMode) && panel._menuStack) {
throwExistingMenuStackError();
}
this._menuPanel = panel;
Expand Down
4 changes: 1 addition & 3 deletions src/cdk-experimental/menu/menu-item-trigger.ts
Expand Up @@ -16,7 +16,6 @@ import {
Inject,
OnDestroy,
Optional,
isDevMode,
} from '@angular/core';
import {Directionality} from '@angular/cdk/bidi';
import {TemplatePortal} from '@angular/cdk/portal';
Expand Down Expand Up @@ -64,8 +63,7 @@ export class CdkMenuItemTrigger implements OnDestroy {
// If the provided panel already has a stack, that means it already has a trigger configured.
// Note however that there are some edge cases where two triggers **may** share the same menu,
// e.g. two triggers in two separate menus.
// TODO refactor once https://github.com/angular/components/pull/20146 lands
if (isDevMode() && panel?._menuStack) {
if ((typeof ngDevMode === 'undefined' || ngDevMode) && panel?._menuStack) {
throwExistingMenuStackError();
}

Expand Down
1 change: 1 addition & 0 deletions src/cdk-experimental/scrolling/BUILD.bazel
Expand Up @@ -11,6 +11,7 @@ ng_module(
),
module_name = "@angular/cdk-experimental/scrolling",
deps = [
"//src:dev_mode_types",
"//src/cdk/coercion",
"//src/cdk/collections",
"//src/cdk/scrolling",
Expand Down
14 changes: 9 additions & 5 deletions src/cdk-experimental/scrolling/auto-size-virtual-scroll.ts
Expand Up @@ -72,8 +72,10 @@ export class AutoSizeVirtualScrollStrategy implements VirtualScrollStrategy {
/** @docs-private Implemented as part of VirtualScrollStrategy. */
scrolledIndexChange = new Observable<number>(() => {
// TODO(mmalerba): Implement.
throw Error('cdk-virtual-scroll: scrolledIndexChange is currently not supported for the' +
' autosize scroll strategy');
if (typeof ngDevMode === 'undefined' || ngDevMode) {
throw Error('cdk-virtual-scroll: scrolledIndexChange is currently not supported for the' +
' autosize scroll strategy');
}
});

/** The attached viewport. */
Expand Down Expand Up @@ -164,9 +166,11 @@ export class AutoSizeVirtualScrollStrategy implements VirtualScrollStrategy {

/** Scroll to the offset for the given index. */
scrollToIndex(): void {
// TODO(mmalerba): Implement.
throw Error('cdk-virtual-scroll: scrollToIndex is currently not supported for the autosize'
+ ' scroll strategy');
if (typeof ngDevMode === 'undefined' || ngDevMode) {
// TODO(mmalerba): Implement.
throw Error('cdk-virtual-scroll: scrollToIndex is currently not supported for the autosize'
+ ' scroll strategy');
}
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/cdk-experimental/selection/BUILD.bazel
Expand Up @@ -10,6 +10,7 @@ ng_module(
),
module_name = "@angular/cdk-experimental/selection",
deps = [
"//src:dev_mode_types",
"//src/cdk/coercion",
"//src/cdk/collections",
"//src/cdk/table",
Expand Down
6 changes: 3 additions & 3 deletions src/cdk-experimental/selection/select-all.ts
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {Directive, Inject, isDevMode, OnDestroy, OnInit, Optional, Self} from '@angular/core';
import {Directive, Inject, OnDestroy, OnInit, Optional, Self} from '@angular/core';
import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
import {Observable, of as observableOf, Subject} from 'rxjs';
import {switchMap, takeUntil} from 'rxjs/operators';
Expand Down Expand Up @@ -90,11 +90,11 @@ export class CdkSelectAll<T> implements OnDestroy, OnInit {
}

private _assertValidParentSelection() {
if (!this._selection && isDevMode()) {
if (!this._selection && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('CdkSelectAll: missing CdkSelection in the parent');
}

if (!this._selection.multiple && isDevMode()) {
if (!this._selection.multiple && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('CdkSelectAll: CdkSelection must have cdkSelectionMultiple set to true');
}
}
Expand Down
9 changes: 3 additions & 6 deletions src/cdk-experimental/selection/selection-column.ts
Expand Up @@ -10,7 +10,6 @@ import {CdkCellDef, CdkColumnDef, CdkHeaderCellDef, CdkTable} from '@angular/cdk
import {
Component,
Input,
isDevMode,
OnDestroy,
OnInit,
Optional,
Expand Down Expand Up @@ -77,7 +76,7 @@ export class CdkSelectionColumn<T> implements OnInit, OnDestroy {
) {}

ngOnInit() {
if (!this.selection && isDevMode()) {
if (!this.selection && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('CdkSelectionColumn: missing CdkSelection in the parent');
}

Expand All @@ -87,10 +86,8 @@ export class CdkSelectionColumn<T> implements OnInit, OnDestroy {
this._columnDef.cell = this._cell;
this._columnDef.headerCell = this._headerCell;
this._table.addColumnDef(this._columnDef);
} else {
if (isDevMode()) {
throw Error('CdkSelectionColumn: missing parent table');
}
} else if ((typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('CdkSelectionColumn: missing parent table');
}
}

Expand Down
8 changes: 4 additions & 4 deletions src/cdk-experimental/selection/selection-set.ts
Expand Up @@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license
*/

import {isDevMode, TrackByFunction} from '@angular/core';
import {TrackByFunction} from '@angular/core';
import {Subject} from 'rxjs';

/**
Expand Down Expand Up @@ -55,7 +55,7 @@ export class SelectionSet<T> implements TrackBySelection<T> {
}

select(...selects: SelectableWithIndex<T>[]) {
if (!this._multiple && selects.length > 1 && isDevMode()) {
if (!this._multiple && selects.length > 1 && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('SelectionSet: not multiple selection');
}

Expand All @@ -81,7 +81,7 @@ export class SelectionSet<T> implements TrackBySelection<T> {
}

deselect(...selects: SelectableWithIndex<T>[]) {
if (!this._multiple && selects.length > 1 && isDevMode()) {
if (!this._multiple && selects.length > 1 && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('SelectionSet: not multiple selection');
}

Expand Down Expand Up @@ -114,7 +114,7 @@ export class SelectionSet<T> implements TrackBySelection<T> {
return select.value;
}

if (select.index == null && isDevMode()) {
if (select.index == null && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('SelectionSet: index required when trackByFn is used.');
}

Expand Down
3 changes: 1 addition & 2 deletions src/cdk-experimental/selection/selection-toggle.ts
Expand Up @@ -11,7 +11,6 @@ import {
Directive,
Inject,
Input,
isDevMode,
OnDestroy,
OnInit,
Optional,
Expand Down Expand Up @@ -77,7 +76,7 @@ export class CdkSelectionToggle<T> implements OnDestroy, OnInit {
}

private _assertValidParentSelection() {
if (!this._selection && isDevMode()) {
if (!this._selection && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('CdkSelectAll: missing CdkSelection in the parent');
}
}
Expand Down
9 changes: 4 additions & 5 deletions src/cdk-experimental/selection/selection.ts
Expand Up @@ -13,7 +13,6 @@ import {
Directive,
EventEmitter,
Input,
isDevMode,
OnDestroy,
OnInit,
Output,
Expand Down Expand Up @@ -104,7 +103,7 @@ export class CdkSelection<T> implements OnInit, AfterContentChecked, CollectionV
dataStream = observableOf(this._dataSource);
}

if (dataStream == null && isDevMode()) {
if (dataStream == null && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('Unknown data source');
}

Expand Down Expand Up @@ -139,7 +138,7 @@ export class CdkSelection<T> implements OnInit, AfterContentChecked, CollectionV

/** Toggles selection for a given value. `index` is required if `trackBy` is used. */
toggleSelection(value: T, index?: number) {
if (this.trackByFn && index == null && isDevMode()) {
if (this.trackByFn && index == null && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('CdkSelection: index required when trackBy is used');
}

Expand All @@ -155,7 +154,7 @@ export class CdkSelection<T> implements OnInit, AfterContentChecked, CollectionV
* values are selected, de-select all values.
*/
toggleSelectAll() {
if (!this._multiple && isDevMode()) {
if (!this._multiple && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('CdkSelection: multiple selection not enabled');
}

Expand All @@ -168,7 +167,7 @@ export class CdkSelection<T> implements OnInit, AfterContentChecked, CollectionV

/** Checks whether a value is selected. `index` is required if `trackBy` is used. */
isSelected(value: T, index?: number) {
if (this.trackByFn && index == null && isDevMode()) {
if (this.trackByFn && index == null && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('CdkSelection: index required when trackBy is used');
}

Expand Down
3 changes: 2 additions & 1 deletion src/cdk-experimental/tsconfig-tests.json
Expand Up @@ -21,7 +21,8 @@
},
"include": [
"**/index.ts",
"**/*.spec.ts"
"**/*.spec.ts",
"../dev-mode-types.d.ts"
],
"exclude": [
"**/*.e2e.spec.ts"
Expand Down
2 changes: 1 addition & 1 deletion src/cdk-experimental/tsconfig.json
Expand Up @@ -9,5 +9,5 @@
"@angular/cdk-experimental/*": ["../cdk-experimental/*"]
}
},
"include": ["./**/*.ts"]
"include": ["./**/*.ts", "../dev-mode-types.d.ts"]
}
1 change: 1 addition & 0 deletions src/cdk/a11y/BUILD.bazel
Expand Up @@ -18,6 +18,7 @@ ng_module(
),
module_name = "@angular/cdk/a11y",
deps = [
"//src:dev_mode_types",
"//src/cdk/coercion",
"//src/cdk/keycodes",
"//src/cdk/observers",
Expand Down
4 changes: 2 additions & 2 deletions src/cdk/a11y/focus-trap/focus-trap.ts
Expand Up @@ -18,7 +18,6 @@ import {
NgZone,
OnDestroy,
DoCheck,
isDevMode,
SimpleChanges,
OnChanges,
} from '@angular/core';
Expand Down Expand Up @@ -213,7 +212,8 @@ export class FocusTrap {

// Warn the consumer if the element they've pointed to
// isn't focusable, when not in production mode.
if (isDevMode() && !this._checker.isFocusable(redirectToElement)) {
if ((typeof ngDevMode === 'undefined' || ngDevMode) &&
!this._checker.isFocusable(redirectToElement)) {
console.warn(`Element matching '[cdkFocusInitial]' is not focusable.`, redirectToElement);
}

Expand Down
3 changes: 2 additions & 1 deletion src/cdk/a11y/key-manager/list-key-manager.ts
Expand Up @@ -140,7 +140,8 @@ export class ListKeyManager<T extends ListKeyManagerOption> {
* @param debounceInterval Time to wait after the last keystroke before setting the active item.
*/
withTypeAhead(debounceInterval: number = 200): this {
if (this._items.length && this._items.some(item => typeof item.getLabel !== 'function')) {
if ((typeof ngDevMode === 'undefined' || ngDevMode) && (this._items.length &&
this._items.some(item => typeof item.getLabel !== 'function'))) {
throw Error('ListKeyManager items in typeahead mode must implement the `getLabel` method.');
}

Expand Down
1 change: 1 addition & 0 deletions src/cdk/collections/BUILD.bazel
Expand Up @@ -16,6 +16,7 @@ ng_module(
),
module_name = "@angular/cdk/collections",
deps = [
"//src:dev_mode_types",
"@npm//@angular/core",
"@npm//rxjs",
],
Expand Down

0 comments on commit 79e4d28

Please sign in to comment.