Skip to content
This repository has been archived by the owner on Sep 16, 2022. It is now read-only.

Commit

Permalink
misc(Goldens): Add some examples of template expressions.
Browse files Browse the repository at this point in the history
Most of these correctly are emitted as expressions that are non-dynamic.

Notably:
  * Using collection literals (`[]`, `{}`) causes a dynamic call.
  * Using nested `*ngFor` causes a dynamic call.

There are probably other ways to (accidentally) cause a dynamic call that otherwise appears to be static. We should continue to add examples, as these would block the use of advanced Dart language features such as dart-lang/language#41 or dart-lang/sdk#35084 in the template.

PiperOrigin-RevId: 221693970
  • Loading branch information
matanlurey authored and alorenzen committed Nov 30, 2018
1 parent 564e492 commit bbb2f0a
Show file tree
Hide file tree
Showing 3 changed files with 849 additions and 0 deletions.
116 changes: 116 additions & 0 deletions _goldens/test/_files/templates/dynamic_expressions.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import 'package:angular/angular.dart';

// OK: Compiles to "_ctx.a + _ctx.b"
@Component(
selector: 'comp-1',
template: '{{a + b}}',
)
class Comp1 {
var a = 1;
var b = 2;
}

// OK: Compiles to "_ctx.a.b(_ctx.c)"
@Component(
selector: 'comp-2',
template: '{{a.b(c)}}',
)
class Comp2 {
var a = Comp2Model();
}

class Comp2Model {
String b(String c) => c;
}

// OK: Compiles to "import1.Comp3.max(_ctx.a, _ctx.b).isEven"
@Component(
selector: 'comp-3',
template: '{{max(a, b).isEven}}',
)
class Comp3 {
static T max<T extends Comparable<T>>(T a, T b) {
return a.compareTo(b) < 0 ? b : a;
}

var a = 0;
var b = 1;
}

// Dynamic :(
//
// Compiles to:
// "List<dynamic> Function(dynamic, dynamic) _arr_0;"
// "_arr_0 = import6.pureProxy2((p0, p1) => [p0, p1])"
// ...
// "_arr_0(_ctx.a, _ctx.b).first.inMilliseconds"
@Component(
selector: 'comp-4',
template: '{{[a, b].first.inMilliseconds}}',
)
class Comp4 {
var a = Duration(seconds: 1);
var b = Duration(seconds: 2);
}

// Dynamic :(
//
// Compiles to:
// "Map<String, dynamic> Function(dynamic) _map_0;"
// "_map_0 = import6.pureProxy1((p0) => {'1': p0}))"
// ...
// "_map_0(_ctx.b).values.first.inMilliseconds"
@Component(
selector: 'comp-5',
template: '{{{"1": b}.values.first.inMilliseconds}}}',
)
class Comp5 {
var v = Duration(seconds: 1);
}

// OK!
//
// Compiles to:
// "final local_duration = import7.unsafeCast<Duration>(locals['\$implicit']);"
// "final currVal_0 = import6.interpolate0(local_duration.inMilliseconds);"
@Component(
selector: 'comp-6',
directives: [NgFor],
template: r'''
<ng-container *ngFor="let duration of durations">
{{duration.inMilliseconds}}
</ng-container>
''',
)
class Comp6 {
var durations = [Duration(seconds: 1)];
}

// Dynamic :(
//
// Compiles to:
// "final local_durations = import7.unsafeCast<List<Duration>>(locals['\$implicit']);"
// "final currVal_0 = local_durations;"
// "if (import6.checkBinding(_expr_0, currVal_0)) {"
// "_NgFor_0_9.ngForOf = currVal_0;"
// "_expr_0 = currVal_0;"
// "}"
// ...
// "final local_duration = locals['\$implicit'];"
// "final currVal_0 = import6.interpolate0(local_duration.inMilliseconds);"
@Component(
selector: 'comp-7',
directives: [NgFor],
template: r'''
<ng-container *ngFor="let durations of items">
<ng-container *ngFor="let duration of durations">
{{duration.inMilliseconds}}
</ng-container>
</ng-container>
''',
)
class Comp7 {
var items = [
[Duration(seconds: 1)]
];
}
67 changes: 67 additions & 0 deletions _goldens/test/_files/templates/dynamic_expressions.outline.golden
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// ignore_for_file: library_prefixes,unused_import,no_default_super_constructor_explicit
// The .template.dart files also export the user code.
export 'dynamic_expressions.dart';

// Required for referencing runtime code.
import 'dart:html' as _html;
import 'package:angular/angular.dart' as _ng;
import 'package:angular/src/core/change_detection/directive_change_detector.dart' as _ng;
import 'package:angular/src/core/linker/app_view.dart' as _ng;

// Required for specifically referencing user code.
import 'dynamic_expressions.dart';

// Required for "type inference" (scoping).
import 'package:angular/angular.dart';

// For @Component class Comp1.
external List<dynamic> get styles$Comp1;
external _ng.ComponentFactory<Comp1> get Comp1NgFactory;
external _ng.AppView<Comp1> viewFactory_Comp10(_ng.AppView<dynamic> parentView, int parentIndex);
class ViewComp10 extends _ng.AppView<Comp1> {
external ViewComp10(_ng.AppView<dynamic> parentView, int parentIndex);
}
// For @Component class Comp2.
external List<dynamic> get styles$Comp2;
external _ng.ComponentFactory<Comp2> get Comp2NgFactory;
external _ng.AppView<Comp2> viewFactory_Comp20(_ng.AppView<dynamic> parentView, int parentIndex);
class ViewComp20 extends _ng.AppView<Comp2> {
external ViewComp20(_ng.AppView<dynamic> parentView, int parentIndex);
}
// For @Component class Comp3.
external List<dynamic> get styles$Comp3;
external _ng.ComponentFactory<Comp3> get Comp3NgFactory;
external _ng.AppView<Comp3> viewFactory_Comp30(_ng.AppView<dynamic> parentView, int parentIndex);
class ViewComp30 extends _ng.AppView<Comp3> {
external ViewComp30(_ng.AppView<dynamic> parentView, int parentIndex);
}
// For @Component class Comp4.
external List<dynamic> get styles$Comp4;
external _ng.ComponentFactory<Comp4> get Comp4NgFactory;
external _ng.AppView<Comp4> viewFactory_Comp40(_ng.AppView<dynamic> parentView, int parentIndex);
class ViewComp40 extends _ng.AppView<Comp4> {
external ViewComp40(_ng.AppView<dynamic> parentView, int parentIndex);
}
// For @Component class Comp5.
external List<dynamic> get styles$Comp5;
external _ng.ComponentFactory<Comp5> get Comp5NgFactory;
external _ng.AppView<Comp5> viewFactory_Comp50(_ng.AppView<dynamic> parentView, int parentIndex);
class ViewComp50 extends _ng.AppView<Comp5> {
external ViewComp50(_ng.AppView<dynamic> parentView, int parentIndex);
}
// For @Component class Comp6.
external List<dynamic> get styles$Comp6;
external _ng.ComponentFactory<Comp6> get Comp6NgFactory;
external _ng.AppView<Comp6> viewFactory_Comp60(_ng.AppView<dynamic> parentView, int parentIndex);
class ViewComp60 extends _ng.AppView<Comp6> {
external ViewComp60(_ng.AppView<dynamic> parentView, int parentIndex);
}
// For @Component class Comp7.
external List<dynamic> get styles$Comp7;
external _ng.ComponentFactory<Comp7> get Comp7NgFactory;
external _ng.AppView<Comp7> viewFactory_Comp70(_ng.AppView<dynamic> parentView, int parentIndex);
class ViewComp70 extends _ng.AppView<Comp7> {
external ViewComp70(_ng.AppView<dynamic> parentView, int parentIndex);
}

external void initReflector();
Loading

0 comments on commit bbb2f0a

Please sign in to comment.