Clone this repo:
  1. 6cfe14e Fix new plugin: analyzer version and plugin protocol version (#351) by Michael R Fairhurst · 12 hours ago master
  2. 2941b6d Remove redundant let error (#350) by Max Kim · 28 hours ago
  3. 6a8995d Fix reference vs. let logic (#348) by Max Kim · 2 days ago
  4. cb7889a Fix #320 'read' value is ignored and creates errors (#347) by Michael R Fairhurst · 4 days ago
  5. 71ac109 Issue 329 - Custom defined for alternative names no longer trigger errors. Deduping added. (#343) by Max Kim · 6 days ago

Angular2 Dart Analysis Plugins

Integration with Dart Analysis Server

To provide information for DAS clients the server_plugin plugin contributes several extensions.

  • Angular analysis errors are automatically merged into normal errors notifications for Dart and HTML files.

Preview gif

Check the pubspec.yaml in your project for transformers. They are not supported. You must manually add CORE_DIRECTIVES to your components right now for this plugin to work.

Building & Installing -- Version One (recommended but soon to be deprecated)

Download chrome depot tools, and clone this repository.

Then run

./tools/get_deps.sh
cd server_plugin/bin
./make_snapshot

Back up sdk_path/snapshots/analysis_server.dart.snapshot and replace it with server.snapshot. Restart the dart analysis server by clicking the skull.

Building -- Version Two (not usable yet, but this will soon be the future)

Under the next system, you will not need to build to install (woo hoo!). However, these steps currently don't produce anything usable. Installation steps will come once its ready.

Download chrome depot tools, and clone this repository.

Then run

./tools/get_deps.sh
cd analyze_angular/tools/plugin
cp pubspec.yaml.defaults pubspec.yaml

Modify pubspec.yaml in this folder to fix the absolute paths. They must be absolute for the moment! Once they can be relative this step will not be required.

Then run pub get.

You can now use this in projects on your local system which a correctly configured pubspec. For instance, playground/. Note that you must import 'package:analyze_angular/' in your project to get the analysis.

Chart of Current Features

All regular dart errors (that is to say, errors defined purely by the dart language spec) are not shown in this list.

Autocomplete is available in a branch, and only in editors that support it, and maybe with bugs (many don't replace the correct content during autocomplete within html, for instance).

BootstrappingValidationAuto-CompleteNavigationRefactoring
bootstrap(AppComponent, [MyService, provide(...)]);:no_pedestrians::no_pedestrians::no_pedestrians::no_pedestrians:
Template syntaxValidationAuto-CompleteNavigationRefactoring
<input [value]="firstName">:white_check_mark: soundness of expression, type of expression, existence of value on element or directive:last_quarter_moon: in some editors:x::x:
<input bind-value="firstName">:white_check_mark::last_quarter_moon: in some editors; complete inside binding but binding not suggested:x::x:
<div [attr.role]="myAriaRole">:last_quarter_moon: soundness of expression, but no other validation:last_quarter_moon: in some editors; complete inside binding but binding not suggested:x::x:
<div [class.extra-sparkle]="isDelightful">:white_check_mark: validity of clasname, soundness of expression, type of expression must be bool:last_quarter_moon: in some editors; complete inside binding but binding not suggested:x::x:
<div [style.width.px]="mySize">:waning_gibbous_moon: soundness of expression, css properties are generally checked but not against a dictionary, same for units, expression must type to int if units are present:last_quarter_moon: in some editors; complete inside binding but binding not suggested:x::x:
<button (click)="readRainbow($event)">:white_check_mark: in some editors; soundness of expression, type of $event, existence of output on component/element and DOM events which propagate can be tracked anywhere:last_quarter_moon: in some editors:x::x:
<button on-click="readRainbow($event)">:white_check_mark:last_quarter_moon: in some editors; complete inside binding but binding not suggested:x::x:
<div title="Hello {{ponyName}}">:white_check_mark: in some editors; soundness of expression, matching mustache delimiters:last_quarter_moon: in some editors:x::x:
<p>Hello {{ponyName}}</p>:white_check_mark: in some editors; soundness of expression, matching mustache delimiters:last_quarter_moon: in some editors:x::x:
<my-cmp></my-cmp>:white_check_mark: in some editors; Existence of directive:last_quarter_moon: in some editors:x::x:
<my-cmp [(title)]="name">:white_check_mark: soundness of expression, existence of title input and titleChange output on directive or component with proper type:last_quarter_moon: in some editors; complete inside binding but binding not suggested:x::x:
<video #movieplayer ...></video><button (click)="movieplayer.play()">:white_check_mark: in some editors; Type of new variable tracked and checked in other expressions:last_quarter_moon: in some editors:x::x:
<video ref-movieplayer ...></video><button (click)="movieplayer.play()">:white_check_mark: in some editors:last_quarter_moon: in some editors:x::x:
<p *myUnless="myExpression">...</p>:white_check_mark: desugared to <template [myUnless]="myExpression"><p>... and checked from there:last_quarter_moon: in some editors; complete inside binding but binding not suggested:x::x:
`Card No.: {{cardNumbermyCardNumberFormatter}}`:x: Pipes are not typechecked yet:x::x:
Built-in directivesValidationAuto-CompleteNavigationRefactoring
<section *ngIf="showSection">:white_check_mark: type checking, check for the star:last_quarter_moon: in some editors; complete inside binding but binding not suggested:x::x:
<li *ngFor="let item of list">:white_check_mark: type checking and new var, check for the star, catch accidental usage of #item:last_quarter_moon: in some editors; complete after of only:x::x:
<div [ngClass]="{active: isActive, disabled: isDisabled}">:warning: Requires quotes around key value strings to work:last_quarter_moon: in some editors;:x::x:
FormsValidationAuto-CompleteNavigationRefactoring
<input [(ngModel)]="userName">:white_check_mark::last_quarter_moon: in some editors; completion inside binding but binding not suggested:x::x:
<form #myform="ngForm">:white_check_mark: if ngForm is not an exported directive:last_quarter_moon: in some editors; completion of variable but ngForm not suggested:x::x:
Class decoratorsValidationAuto-CompleteNavigationRefactoring
@Component(...) class MyComponent {}:white_check_mark: Validates directives list is all directives, that the template file exists, that a template is specified via string or URL but not both, requires a valid selector:no_pedestrians::no_pedestrians::no_pedestrians:
@View(...) class MyComponent {}:warning: Supported, requires @Directive or @Component, but doesn't catch ambigous cases such as templates defined in the @View as well as @Component:no_pedestrians::no_pedestrians::no_pedestrians:
@Directive(...) class MyDirective {}:white_check_mark: Validates directives list is all directives, that the template file exists, that a template is specified via string or URL but not both, requires a valid selector:no_pedestrians::no_pedestrians::no_pedestrians:
@Pipe(...) class MyPipe {}:x::no_pedestrians::no_pedestrians::x:
@Injectable() class MyService {}:x::no_pedestrians::no_pedestrians::x:
Directive configurationValidationAuto-CompleteNavigationRefactoring
@Directive(property1: value1, ...):warning: deprecated, but supported:no_pedestrians::no_pedestrians::no_pedestrians:
selector: '.cool-button:not(a)':white_check_mark::no_pedestrians::x::x:
providers: [MyService, provide(...)]:x::x::x::x:
inputs: ['myprop', 'myprop2: byname']:white_check_mark::x::x::x:
outputs: ['myprop', 'myprop2: byname']:white_check_mark::x::x::x:

@Component extends @Directive, so the @Directive configuration applies to components as well

Component ConfigurationValidationAuto-CompleteNavigationRefactoring
viewProviders: [MyService, provide(...)]:x::x::x::x:
template: 'Hello {{name}}':white_check_mark::last_quarter_moon: in some editors:x::x:
templateUrl: 'my-component.html':white_check_mark::x::x::x:
styles: ['.primary {color: red}']:x::no_pedestrians::no_pedestrians::no_pedestrians:
styleUrls: ['my-component.css']:x::x::x::x:
directives: [MyDirective, MyComponent]:white_check_mark: must be directives or lists of directives, configuration affects view errors:x::x::x:
pipes: [MyPipe, OtherPipe]:x::x::x::x:
Class field decorators for directives and componentsValidationAuto-CompleteNavigationRefactoring
@Input() myProperty;:white_check_mark::no_pedestrians::x::x:
@Input("name") myProperty;:white_check_mark::no_pedestrians::x::x:
@Output() myEvent = new EventEmitter();:white_check_mark: Subtype of Stream<T> required, streamed type determines $event type:no_pedestrians::x::x:
@Output("name") myEvent = new EventEmitter();:white_check_mark::no_pedestrians::x::x:
@Attribute("name") String ctorArg:white_check_mark::x::x::x:
@HostBinding('[class.valid]') isValid;:x::no_pedestrians::no_pedestrians::no_pedestrians:
@HostListener('click', ['$event']) onClick(e) {...}:x::x::x::x:
@ContentChild(myPredicate) myChildComponent;:x::no_pedestrians::x::x:
@ContentChildren(myPredicate) myChildComponents;:x::no_pedestrians::x::x:
@ViewChild(myPredicate) myChildComponent;:x::no_pedestrians::x::x:
@ViewChildren(myPredicate) myChildComponents;:x::no_pedestrians::x::x:
TransclusionsValidationAuto-CompleteNavigationRefactoring
<ng-content></ng-content>:white_check_mark::no_pedestrians::no_pedestrians::no_pedestrians:
<my-comp>text content</my-comp>:white_check_mark::x::x::x:
<ng-content select="foo"></ng-content>:white_check_mark::last_quarter_moon: in some editors:x::x:
<my-comp><foo></foo></my-comp>:white_check_mark::last_quarter_moon: in some editors:x::x:
<ng-content select=".foo[bar]"></ng-content>:white_check_mark::last_quarter_moon: in some editors:x::x:
<my-comp><div class="foo" bar></div></my-comp>:white_check_mark::last_quarter_moon: in some editors:x::x:
Directive and component change detection and lifecycle hooks (implemented as class methods)ValidationAuto-CompleteNavigationRefactoring
MyAppComponent(MyService myService, ...) { ... }:x::no_pedestrians::no_pedestrians::x:
ngOnChanges(changeRecord) { ... }:x::no_pedestrians::no_pedestrians::x:
ngOnInit() { ... }:x::no_pedestrians::no_pedestrians::x:
ngDoCheck() { ... }:x::no_pedestrians::no_pedestrians::x:
ngAfterContentInit() { ... }:x::no_pedestrians::no_pedestrians::x:
ngAfterContentChecked() { ... }:x::no_pedestrians::no_pedestrians::x:
ngAfterViewInit() { ... }:x::no_pedestrians::no_pedestrians::x:
ngAfterViewChecked() { ... }:no_pedestrians::no_pedestrians::x::x:
ngOnDestroy() { ... }:x::no_pedestrians::no_pedestrians::x:
Dependency injection configurationValidationAuto-CompleteNavigationRefactoring
provide(MyService, useClass: MyMockService):x::no_pedestrians::no_pedestrians::x:
provide(MyService, useFactory: myFactory):x::no_pedestrians::no_pedestrians::x:
provide(MyValue, useValue: 41):x::no_pedestrians::no_pedestrians::x:
Routing and navigationValidationAuto-CompleteNavigationRefactoring
@RouteConfig(const [ const Route(...) ]):x::no_pedestrians::no_pedestrians::no_pedestrians:
<router-outlet></router-outlet>:no_pedestrians::x::no_pedestrians::no_pedestrians:
<a [routerLink]="[ '/MyCmp', {myParam: 'value' } ]">:question::x::no_pedestrians::no_pedestrians:
@CanActivate(() => ...)class MyComponent() {}:x::no_pedestrians::no_pedestrians::no_pedestrians:
routerOnActivate(nextInstruction, prevInstruction) { ... }:x::no_pedestrians::no_pedestrians::no_pedestrians:
routerCanReuse(nextInstruction, prevInstruction) { ... }:x::no_pedestrians::no_pedestrians::no_pedestrians:
routerOnReuse(nextInstruction, prevInstruction) { ... }:x::x::no_pedestrians::no_pedestrians:
routerCanDeactivate(nextInstruction, prevInstruction) { ... }:x::no_pedestrians::no_pedestrians::no_pedestrians:
routerOnDeactivate(nextInstruction, prevInstruction) { ... }:x::no_pedestrians::no_pedestrians::no_pedestrians: