AngularDart integration for Dart Analysis Server
Switch branches/tags
v0.0.16 v0.0.15+1 v0.0.15 v0.0.14 v0.0.13 v0.0.12 v0.0.11.1 v0.0.11 v0.0.10 v0.0.8.1 v0.0.8 v0.0.7 v0.0.6 v0.0.5 v0.0.4 v0.0.3 v0.0.2 v0.0.1 archive/435-accept-optional-parameters-in-pipes archive/void-fixes archive/view-child archive/version-tick-v.0.0.5 archive/validate-text-attrs archive/validate-attrs-are-text-inputs archive/use-streams-for-errors archive/use-preexisting-sdk-manager archive/use-dartfmt-1.25.0-dev.6.0 archive/update-readme archive/update-readme-troubleshooting archive/update-readme-sdk-version-warning archive/update-readme-angular4-release archive/update-analyzer-dep archive/unknown-tag-support3 archive/unknown-tag-support2 archive/unknown-tag-support archive/typecheck-security archive/travis-for-new-plugin archive/travis-fix-for-special-sdk-branches-at-head archive/transition-to-analysis-driver archive/tick-to-0.0.11 archive/tick-salt-for-pipes archive/tick-pub-0.0.9 archive/tick-pub-0.0.7 archive/tick-pub-0.0.6 archive/test-travis-with-pub archive/temp archive/support-functional-directives archive/support-functional-directives-step2 archive/support-focusin-and-out archive/support-exports archive/support-events-with-suffixes archive/strong-mode-in-templates archive/string-bindings-assignable-to-dynamic archive/start-changelog archive/skip-ungenerated-files archive/salt-hashes archive/run-tests-checked archive/reorder-analysis-hint-to-end archive/rename-ast-test archive/remove_occurrences_unittest archive/remove-solo-tests archive/remove-references-to-view archive/remove-front-end-reference archive/recursive-lists-of-directives archive/quotes-in-attr-selector archive/push-v0.0.11+1 archive/publish-new-version archive/publish-against-new-analyzer archive/priority-angular-analysis archive/prevent-assertion-failure-in-completion archive/performance-work-temp archive/package-consolidation archive/order-safe-inheritance-test archive/opt-in-via-yaml archive/omega-lint-fixup archive/not-rehash-html archive/ng-for-dont-suggest-brackets archive/new-plugin archive/navigation archive/nan-float-literal-range-error archive/move-performance-log archive/more-lint-fixes archive/make-compatible-with-dev-and-master-sdk-branches archive/load-angular-drivers-in-new-plugin archive/lint-on-build archive/issue-439-too-strict-string-value-expected archive/issue-394-plain-bool-inputs archive/issue-320-support-read-on-content-child archive/issue-128-rebased archive/issue-128-content-child-support archive/integration_fixes archive/integration_fixes_plus_check-reductions-are-only-on-keyup-keydown archive/improve-summary-performance archive/import-preformance-logger archive/implement-upcoming-interface-methods archive/handle-const-references-in-place-of-inline-directives-list archive/handle-angular-rename archive/google3-fixes archive/fix-uri-api-changes archive/fix-template-completer-crash
Nothing to show
Clone or download
MichaelRFairhurst Merge pull request #664 from MichaelRFairhurst/support-static-getters…
…-in-exports

Fix issues in not-exported errors, more tests.
Latest commit 3a009a7 Nov 15, 2018

README.md

Build Status pub package

Requires angular-5.0.0* and dart SDK 2.0.0-dev.31** or higher to work.

* Works with angular-4.0.0 by following the steps in the section "loading an exact version."

** Linux and Mac users should be able to an SDK version as old as 1.25.0-dev.12.0

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

Installing By Angular Version -- For Angular Developers (recommended)

Using this strategy allows the dart ecosystem to discover which version of our plugin will work best with your version of angular, and therefore is recommended.

Simply add to your analysis_options.yaml file:

analyzer:
  plugins:
    - angular

Then simply reboot your analysis server (inside IntelliJ this is done by clicking on the skull icon if it exists, or the refresh icon otherwise) and wait for the plugin to fully load, which can take a minute on the first run.

The plugin will self-upgrade if you update angular. Otherwise, you can get any version of the plugin you wish by following the steps in the next section.

Loading an Exact Version

This is much like the previous step. However, you should include this project in your pubspec:

dependencies:
  angular_analyzer_plugin: 0.0.13

and then load the plugin as itself, rather than as a dependency of angular:

analyzer:
  plugins:
    - angular_analyzer_plugin

Like the previous installation option, you then just need to reboot your analysis server after running pub get.

Troubleshooting

If you have any issues, filing an issue with us is always a welcome option. There are a few things you can try on your own, as well, to get an idea of what's going wrong:

  • Are you using angular 5 or newer? If not, are you loading a recent exact version of the plugin?
  • Are you using a bleeding edge SDK? The latest stable will not work correctly, and windows users require at least 2.0.0-dev-31.
  • Did you turn the plugin on correctly in your analysis options file?
  • From IntelliJ in the Dart Analysis panel, there's a gear icon that has "analyzer diagnostics," which opens a web page that has a section for loaded plugins. Are there any errors?
  • Does your editor support html+dart analysis, or is it an old version? Some (such as VSCode, vim) may have special steps to show errors surfaced by dart analysis inside your html files.
  • Check the directory ~/.dartServer/.plugin_manager (on Windows: \Users\you\AppData\Local\.dartServer\.plugin_manager). Does it have any subdirectories?
  • There should be a hash representing each plugin you've loaded. Can you run pub get from HASH/analyzer_plugin? (If you have multiple hashes, it should be safe to clear this directory & reload.)
  • If you run bin/plugin.dart from .plugin_manager/HASH/analyzer_plugin, do you get any import errors? (Note: this is expected to crash when launched in this way, but without import-related errors)

We may ask you any or all of these questions if you open an issue, so feel free to go run through these checks on your own to get a hint what might be wrong.

Upgrading

Any Dart users on 2.0.0-dev.48 or newer will get updates on every restart of the analysis server. If you are on an older Dart version than that, check the Troubleshooting section.

Building -- For hacking on this plugin, or using the latest unpublished.

There's an pubspec.yaml file that needs to be updated to point to your local system:

$ cd angular_analyzer_plugin/tools/analyzer_plugin
$ cp pubspec.yaml.defaults pubspec.yaml

Modify pubspec.yaml in this folder to fix the absolute paths. They must be absolute!

Then run pub get.

You can now use this in projects on your local system which a correctly configured pubspec and analysis options. For instance, playground/. Note that it imports the plugin by path, and imports it as a plugin inside analysis_options.yaml.

Chart of Current Features

We plug into many editors with varying degrees of support. In theory anything that supports Dart analysis also supports our plugin, but in practice that's not always the case.

Bootstrapping Validation Auto-Complete Navigation Refactoring
IntelliJ ⚠️ some support in EAP 🚷
Vim (special setup required) 🚷
VS Code (Dart Code w/ flag) 🚷
others let us know! let us know! let us know! let us know!

If you are using an editor with Dart support that's not in this list, then please let us know what does or doesn't work. We can sometimes contribute fixes, too!

Bootstrapping Validation Auto-Complete Navigation Refactoring
bootstrap(AppComponent, [MyService, provide(...)]); 🚷 🚷 🚷 🚷
Template syntax Validation Auto-Complete Navigation Refactoring
<div stringInput="string"> typecheck is string input on component
<input [value]="firstName"> soundness of expression, type of expression, existence of value on element or directive
<input bind-value="firstName"> 💀
<div [attr.role]="myAriaRole"> 🌗 soundness of expression, but no other validation 🌗 complete inside binding but binding not suggested 🌗 no html specific navigation
<div [attr.role.if]="myAriaRole"> 🌗 complete inside binding but binding not suggested
<div [class.extra-sparkle]="isDelightful"> validity of clasname, soundness of expression, type of expression must be bool 🌗 complete inside binding but binding not suggested 🌗 no css specific navigation
<div [style.width.px]="mySize"> 🌖 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 🌗 complete inside binding but binding not suggested 🌗 no css specific navigation
<button (click)="readRainbow($event)"> soundness of expression, type of $event, existence of output on component/element and DOM events which propagate can be tracked anywhere 🌗 no navigation for $event
<button (keyup.enter)="..."> 🌖 soundness of expression, type of $event, keycode and modifier names not checked 🌗 no navigation for $event
<button on-click="readRainbow($event)"> 💀 🌗 no navigation for $event
<div title="Hello {{ponyName}}"> soundness of expression, matching mustache delimiters
<p>Hello {{ponyName}}</p> soundness of expression, matching mustache delimiters
<my-cmp></my-cmp> existence of directive
<my-cmp [(title)]="name"> soundness of expression, existence of title input and titleChange output on directive or component with proper type navigates to the input
<video #movieplayer ...></video><button (click)="movieplayer.play()"> type of new variable tracked and checked in other expressions
<video directiveWithExportAs #moviePlayer="exportAsValue"> existence of exportAs value checked within bound directives
<video ref-movieplayer ...></video><button (click)="movieplayer.play()">
<p *myUnless="myExpression">...</p> desugared to <template [myUnless]="myExpression"><p>... and checked from there some bugs ,mostly works
<p>Card No.: {{cardNumber | myCardNumberFormatter}}</p> 🌓 Pipe name, input, and return type checked, optional argument types not yet checked
<my-component @deferred>
Built-in directives Validation Auto-Complete Navigation Refactoring
<section *ngIf="showSection"> type checking, check for the star
<li *ngFor="let item of list"> type checking and new var, check for the star, catch accidental usage of #item 🌗 some bugs, mostly works
<div [ngClass]="{active: isActive, disabled: isDisabled}"> ⚠️ Requires quotes around key value strings to work
Forms Validation Auto-Complete Navigation Refactoring
<input [(ngModel)]="userName"> goes to ngModel input
<form #myform="ngForm"> if ngForm is not an exported directive
Class decorators Validation Auto-Complete Navigation Refactoring
@Component(...) class MyComponent {} 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 🚷 🚷 🚷
@View(...) class MyComponent {} ⚠️ Supported, requires @Directive or @Component, but doesn't catch ambigous cases such as templates defined in the @View as well as @Component 🚷 🚷 🚷
@Directive(...) class MyDirective {} Validates directives list is all directives, requires a valid selector 🚷 🚷 🚷
@Directive(...) void directive(...) {} Validates directives list is all directives requires a valid selector, not exported 🚷 🚷 🚷
@Pipe(...) class MyPipe {} 🚷 🚷
@Injectable() class MyService {} 🚷 🚷
Directive configuration Validation Auto-Complete Navigation Refactoring
@Directive(property1: value1, ...) ⚠️ deprecated, but supported 🚷 🚷 🚷
selector: '.cool-button:not(a)' 🚷 selectors can be reached from matching html
providers: [MyService, provide(...)]
inputs: ['myprop', 'myprop2: byname']
outputs: ['myprop', 'myprop2: byname']

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

Component Configuration Validation Auto-Complete Navigation Refactoring
viewProviders: [MyService, provide(...)]
template: 'Hello {{name}}'
templateUrl: 'my-component.html'
styles: ['.primary {color: red}'] 🚷 🚷 🚷
styleUrls: ['my-component.css']
directives: [MyDirective, MyComponent] must be directives or lists of directives, configuration affects view errors regular navigation
pipes: [MyPipe, OtherPipe] regular navigation
exports: [Class, Enum, staticFn]
Class field decorators for directives and components Validation Auto-Complete Navigation Refactoring
@Input() myProperty; 🚷
@Input("name") myProperty; 🚷
@Output() myEvent = new Stream<X>(); Subtype of Stream<T> required, streamed type determines $event type 🚷
@Output("name") myEvent = new Stream<X>(); 🚷
@Attribute("name") String ctorArg
@HostBinding('[class.valid]') isValid; 🚷 🚷 🚷
@HostListener('click', ['$event']) onClick(e) {...}
@ContentChild(myPredicate) myChildComponent; 🚷
@ContentChildren(myPredicate) myChildComponents; 🚷
@ViewChild(myPredicate) myChildComponent; 🚷
@ViewChildren(myPredicate) myChildComponents; 🚷
Transclusions Validation Auto-Complete Navigation Refactoring
<ng-content></ng-content> 🚷 🚷 🚷
<my-comp>text content</my-comp>
<ng-content select="foo"></ng-content> navigation from where matched
<my-comp><foo></foo></my-comp> navigation to the corresponding selector
<ng-content select=".foo[bar]"></ng-content> navigation from where matched
<my-comp><div class="foo" bar></div></my-comp> navigation to the corresponding selector
Directive and component change detection and lifecycle hooks (implemented as class methods) Validation Auto-Complete Navigation Refactoring
MyAppComponent(MyService myService, ...) { ... } 🚷 🚷
ngOnChanges(changeRecord) { ... } 🚷 🚷
ngOnInit() { ... } 🚷 🚷
ngDoCheck() { ... } 🚷 🚷
ngAfterContentInit() { ... } 🚷 🚷
ngAfterContentChecked() { ... } 🚷 🚷
ngAfterViewInit() { ... } 🚷 🚷
ngAfterViewChecked() { ... } 🚷 🚷
ngOnDestroy() { ... } 🚷 🚷
Dependency injection configuration Validation Auto-Complete Navigation Refactoring
provide(MyService, useClass: MyMockService) 🚷 🚷
provide(MyService, useFactory: myFactory) 🚷 🚷
provide(MyValue, useValue: 41) 🚷 🚷
Routing and navigation Validation Auto-Complete Navigation Refactoring
@RouteConfig(const [ const Route(...) ]) 🚷 🚷 🚷
<router-outlet></router-outlet> 🚷 🚷 🚷
<a [routerLink]="[ '/MyCmp', {myParam: 'value' } ]"> 🚷 🚷
@CanActivate(() => ...)class MyComponent() {} 🚷 🚷 🚷
routerOnActivate(nextInstruction, prevInstruction) { ... } 🚷 🚷 🚷
routerCanReuse(nextInstruction, prevInstruction) { ... } 🚷 🚷 🚷
routerOnReuse(nextInstruction, prevInstruction) { ... } 🚷 🚷
routerCanDeactivate(nextInstruction, prevInstruction) { ... } 🚷 🚷 🚷
routerOnDeactivate(nextInstruction, prevInstruction) { ... } 🚷 🚷 🚷