X Tutup
Skip to content

Introduce @angularEntrypoint annotation to decide where to pull in ng_deps #4865

@yjbanov

Description

@yjbanov

Currently we use poor man's pattern matching to decide which files to rewrite to swap out reflection with generated ng_deps. Instead, a developer should be able to select any file they consider an "entry point" - a test file, an app with a main method, something else - and tell us right in that file that we need to add ng_deps to imports.

Proposal

Introduce @angularEntrypoint annotation that developer applies to a function or method:

library my_test;

@angularEntrypoint
main() {  // doesn't have to be `main`; any method/function will suffice
}

Our transformer would look for this annotation and rewrite the file by adding ng_deps imports, adding calls to initReflector functions, and swapping out bootstrap for bootstrapStatic. Even if there is no call to bootstrap we would still add ng_deps. This way people can bring their own custom bootstrap API (very popular in tests).

Details

Let's say we have the following Dart file:

library has_entrypoint;

import 'a.dart';
import 'b.dart';

class App {
  @angularEntrypoint
  void start() {
    bootstrap(AComponent);
  }
}

@angularEntrypoint
main() {
  bootstrap(BComponent);
}

The transformer identifies the @angularEntrypoint annotation and rewrite this file to:

library has_entrypoint;

import 'a.dart';import 'a.ng_deps.dart' as i0;import 'b.ng_deps.dart' as i1;
import 'b.dart';

class App {
  @angularEntrypoint
  void start() {i0.initReflector();i1.initReflector();
    bootstrapStatic(AComponent);
  }
}

@angularEntrypoint
main() {i0.initReflector();i1.initReflector();
  bootstrapStatic(BComponent);
}

Notes:

  • ng_deps imports are injected in a way that does not alter line numbers for better debugging experience
  • for the same reason calls to initReflector go on the same line as the opening curly of the function/method declaration
  • both entry points are calling all initReflector even if they use only some of them (this is because otherwise we'd need to resolve the whole program to figure out which types are used where); it is up to developer to split their code into multiple libraries to get finer grained control over code size (in practice, there would rarely be production code with multiple entry points in the same file; this is mostly useful for tests)

Metadata

Metadata

Assignees

Labels

effort2: daysfeatureLabel used to distinguish feature request from other issues

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

    X Tutup