I'm logging this to document an additional use-case for this DEP and to double-check that the use-case is covered.
Angular 2 defines an annotation for users to specify which directives are used by a component. To illustrate, here's a simplified version:
// Defined by Angular 2
class View {
final List<Type> directives;
const View(this.directives);
}
The user uses this annotation as follows:
// User code
@View(const [Foo, NgIf])
class MyComponent {}
Here the annotation means "I intend to use directives Foo and NgIf in MyComponent".
Problem
It turns out that the vast majority of components end up using NgIf, NgFor and other standard directives. Only very code size conscious users would want to hand pick every single directive for their component. We therefore would like to define two annotations, @BaseView and an extension of it @View. The latter would automatically include several popular directives so the user doesn't have to specify them. Here's how we would like to define them:
/// Use this if you want to specify every directive used by a component.
class BaseView {
final List<Type> directives;
const BaseView(this.directives);
}
/// Use this if you want to specify only non-standard directives. Standard
/// directives are included by default.
class View extends BaseView {
static const STANDARD_DIRECTIVES = const [NgIf, NgFor, NgClass];
const View(List<Type> directives)
: super(const [STANDARD_DIRECTIVES, directives]);
}
The user would then use them as follows:
// User specifies _precisely_ what they want
@BaseView(const [Foo, NgIf])
// User doesn't care much about extra size in JS output but
// doesn't like boilerplate. It's ok include all common directives,
// even though they only use some of them
@View(const [Foo])
The catch
The catch is that the initializer list of View is invalid Dart, as it expects that View may be used in a non-const context. If I understand this DEP correctly, it addresses this problem by allowing the initializer list to be the following:
const View(List<Type> directives)
: super([STANDARD_DIRECTIVES, directives]);
It would "inject" const into the list literal expression depending on whether the invocation is in a const context (which it is for annotations) or not.
Alternative: const class
A const class indicates that a class may only be instantiated as part of a const expression. new is not allowed. Here's how it would be declared:
const class View {
static const STANDARD_DIRECTIVES = const [NgIf, NgFor, NgClass];
const View(List<Type> directives)
: super(const [STANDARD_DIRECTIVES, directives]);
}
Because the const modifier guarantees that the constructor is always invoked in a const context, it is safe to assume that directives constructor parameter is also a const value thus making the list literal expression valid.
I'm logging this to document an additional use-case for this DEP and to double-check that the use-case is covered.
Angular 2 defines an annotation for users to specify which directives are used by a component. To illustrate, here's a simplified version:
The user uses this annotation as follows:
Here the annotation means "I intend to use directives
FooandNgIfinMyComponent".Problem
It turns out that the vast majority of components end up using
NgIf,NgForand other standard directives. Only very code size conscious users would want to hand pick every single directive for their component. We therefore would like to define two annotations,@BaseViewand an extension of it@View. The latter would automatically include several popular directives so the user doesn't have to specify them. Here's how we would like to define them:The user would then use them as follows:
The catch
The catch is that the initializer list of
Viewis invalid Dart, as it expects thatViewmay be used in a non-constcontext. If I understand this DEP correctly, it addresses this problem by allowing the initializer list to be the following:It would "inject"
constinto the list literal expression depending on whether the invocation is in aconstcontext (which it is for annotations) or not.Alternative:
const classA
const classindicates that a class may only be instantiated as part of aconstexpression.newis not allowed. Here's how it would be declared:Because the
constmodifier guarantees that the constructor is always invoked in aconstcontext, it is safe to assume thatdirectivesconstructor parameter is also aconstvalue thus making the list literal expression valid.