Compare commits
120 Commits
ts_library
...
7.2.2
Author | SHA1 | Date | |
---|---|---|---|
5c5fe34241 | |||
32737a6bf7 | |||
7642308c14 | |||
f1c08d83b0 | |||
617412f9c3 | |||
cf716684a9 | |||
54565ed389 | |||
ab08385336 | |||
eb8ccf65d1 | |||
cb93027f32 | |||
607fd8e970 | |||
f4ac96d0ff | |||
1c7d156abd | |||
4c00059260 | |||
93d78c9c51 | |||
49bee4c0d8 | |||
d8c75f1bb0 | |||
6d40ef2d6b | |||
4ea6c27dcf | |||
a4d9192fbc | |||
7b772e93a3 | |||
05168395b0 | |||
03293c4fec | |||
479019f457 | |||
68515818b9 | |||
8bc369f828 | |||
3d1a4d5cc3 | |||
5c56b778e0 | |||
585e871c96 | |||
6ae7aee2c3 | |||
701270d039 | |||
02a852a34a | |||
531f940212 | |||
de80f1b6dd | |||
ca3965afe0 | |||
f269e433a7 | |||
8750b09fca | |||
ea2eef737b | |||
0ceab97a03 | |||
fbbdaaacc0 | |||
080de58a88 | |||
5390948360 | |||
0d860051af | |||
edbba24b60 | |||
6ae8d7691d | |||
af3cf36ce9 | |||
1be2f11965 | |||
495ce325b2 | |||
92411043d1 | |||
aa3f75b3c9 | |||
d64aadf57a | |||
51f7f081a3 | |||
b9fd62413f | |||
c5664bf245 | |||
c66a076614 | |||
28d34b699d | |||
47840bee71 | |||
305331f634 | |||
5e6c24cb01 | |||
0ec4e1372a | |||
84c1bad3a1 | |||
1640832f56 | |||
8ab036262d | |||
76e8c0ac7b | |||
0e81e418fb | |||
60255b68c0 | |||
ae7b3c8d45 | |||
9556ba7bca | |||
80994b25b9 | |||
2f154b980f | |||
342d352a00 | |||
f240ae5084 | |||
e4fc8bad35 | |||
5c680d4aa8 | |||
f05c5f82c8 | |||
2e0c58ec3e | |||
21093b9090 | |||
a6153accf0 | |||
dee789c204 | |||
12dd552fcd | |||
079bcffe07 | |||
30256e8fe8 | |||
8ee69831fc | |||
c3d8e2888d | |||
bea677136b | |||
11728bbbd9 | |||
1da4b03940 | |||
54ba0f021f | |||
836a5c72a0 | |||
f589933440 | |||
ef3ec34aa3 | |||
37a6d2d033 | |||
354f3639bb | |||
c4b06868b1 | |||
e3853e842e | |||
aee5cbd057 | |||
e9614eff1a | |||
80f9f7e8ef | |||
7d2589556f | |||
468fcab59d | |||
f720e972d4 | |||
b51ae7e59a | |||
eedb06936f | |||
ee5a094424 | |||
9773b5a173 | |||
eed171839e | |||
1057b52def | |||
302506e940 | |||
cc35feb445 | |||
21b875d4d0 | |||
dac9c09235 | |||
5cba438eb5 | |||
2b001cb2b1 | |||
0be8487f09 | |||
e1e69ca828 | |||
f376c46d78 | |||
fad4145f48 | |||
6b394f62be | |||
16aad8b2d8 | |||
25bbcbcbe5 |
16
.bazelrc
16
.bazelrc
@ -22,12 +22,18 @@ test:debug --test_arg=--node_options=--inspect-brk --test_output=streamed --test
|
||||
# Filesystem interactions #
|
||||
###############################
|
||||
|
||||
# Don't create symlinks like bazel-out in the project.
|
||||
# These cause VSCode to traverse a massive tree, opening file handles and
|
||||
# Create symlinks in the project:
|
||||
# - dist/bin for outputs
|
||||
# - dist/testlogs, dist/genfiles
|
||||
# - bazel-out
|
||||
# NB: bazel-out should be excluded from the editor configuration.
|
||||
# The checked-in /.vscode/settings.json does this for VSCode.
|
||||
# Other editors may require manual config to ignore this directory.
|
||||
# In the past, we say a problem where VSCode traversed a massive tree, opening file handles and
|
||||
# eventually a surprising failure with auto-discovery of the C++ toolchain in
|
||||
# MacOS High Sierra.
|
||||
# See https://github.com/bazelbuild/bazel/issues/4603
|
||||
build --symlink_prefix=/
|
||||
build --symlink_prefix=dist/
|
||||
|
||||
# Performance: avoid stat'ing input files
|
||||
build --watchfs
|
||||
@ -43,9 +49,7 @@ test --nolegacy_external_runfiles
|
||||
###############################
|
||||
|
||||
# Releases should always be stamped with version control info
|
||||
# This command assumes node on the path and is a workaround for
|
||||
# https://github.com/bazelbuild/bazel/issues/4802
|
||||
build:release --workspace_status_command="node ./tools/bazel_stamp_vars.js"
|
||||
build:release --workspace_status_command=./tools/bazel_stamp_vars.sh
|
||||
|
||||
###############################
|
||||
# Output #
|
||||
|
@ -5,9 +5,9 @@
|
||||
|
||||
# VM creation:
|
||||
# In Google Cloud Platform, create a Compute Engine instance.
|
||||
# We recommend machine type n1-standard-16 (16 vCPUs, 60 GB memory).
|
||||
# Use a recent windows boot disk with container support such as
|
||||
# "Windows Server version 1803 Datacenter Core for Containers", and add a 128GB disk.
|
||||
# We recommend machine type n1-highcpu-16 (16 vCPUs, 14.4 GB memory).
|
||||
# Use a windows boot disk with container support such as
|
||||
# "Windows Server version 1803 Datacenter Core for Containers".
|
||||
# Give it a name, then click "Create".
|
||||
|
||||
# VM setup:
|
||||
@ -54,8 +54,6 @@ Write-Host "Installing Git for Windows."
|
||||
Invoke-WebRequest -Uri https://github.com/git-for-windows/git/releases/download/v2.19.1.windows.1/Git-2.19.1-64-bit.exe -OutFile git.exe
|
||||
.\git.exe /VERYSILENT /NORESTART /NOCANCEL /SP- /CLOSEAPPLICATIONS /RESTARTAPPLICATIONS /COMPONENTS="icons,ext\reg\shellhere,assoc,assoc_sh" /DIR="C:\git"
|
||||
Add-Path "C:\git\bin"
|
||||
# Sleep for 15s while git is installed. Trying to remove the git.exe before it finishes install causes an error.
|
||||
Start-Sleep -s 15
|
||||
Remove-Item git.exe
|
||||
|
||||
# Download NSSM (https://nssm.cc/) to run the BuildKite agent as a service.
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -1,7 +1,7 @@
|
||||
.DS_STORE
|
||||
|
||||
/dist/
|
||||
/bazel-*
|
||||
/bazel-out/
|
||||
/integration/bazel/bazel-*
|
||||
e2e_test.*
|
||||
node_modules
|
||||
@ -13,9 +13,9 @@ pubspec.lock
|
||||
.c9
|
||||
.idea/
|
||||
.settings/
|
||||
.vscode/launch.json
|
||||
*.swo
|
||||
modules/.settings
|
||||
.vscode
|
||||
modules/.vscode
|
||||
|
||||
# Don't check in secret files
|
||||
|
15
.vscode/settings.json
vendored
Normal file
15
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"files.watcherExclude": {
|
||||
"**/.git/objects/**": true,
|
||||
"**/.git/subtree-cache/**": true,
|
||||
"**/node_modules/**": true,
|
||||
"**/bazel-out/**": true,
|
||||
"**/dist/**": true,
|
||||
},
|
||||
"search.exclude": {
|
||||
"**/node_modules": true,
|
||||
"**/bower_components": true,
|
||||
"**/bazel-out": true,
|
||||
"**/dist": true,
|
||||
},
|
||||
}
|
27
CHANGELOG.md
27
CHANGELOG.md
@ -1,32 +1,17 @@
|
||||
<a name="8.0.0-beta.0"></a>
|
||||
# [8.0.0-beta.0](https://github.com/angular/angular/compare/7.2.0...8.0.0-beta.0) (2019-01-16)
|
||||
<a name="7.2.2"></a>
|
||||
## [7.2.2](https://github.com/angular/angular/compare/7.2.1...7.2.2) (2019-01-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **bazel:** Add [@bazel](https://github.com/bazel)/bazel to dev deps ([#28032](https://github.com/angular/angular/issues/28032)) ([5a0deb8](https://github.com/angular/angular/commit/5a0deb8))
|
||||
* **bazel:** Add /bazel-out to .gitignore ([#27874](https://github.com/angular/angular/issues/27874)) ([b05baa5](https://github.com/angular/angular/commit/b05baa5))
|
||||
* **bazel:** Add ibazel to deps of Bazel project ([#28090](https://github.com/angular/angular/issues/28090)) ([605f450](https://github.com/angular/angular/commit/605f450))
|
||||
* **bazel:** Bazel schematics should add router package ([#28141](https://github.com/angular/angular/issues/28141)) ([06e5bf1](https://github.com/angular/angular/commit/06e5bf1))
|
||||
* **bazel:** flat module misses AMD module name on windows ([#27839](https://github.com/angular/angular/issues/27839)) ([935ce63](https://github.com/angular/angular/commit/935ce63))
|
||||
* **bazel:** incorrectly always uses ngc-wrapped from "npm" workspace ([#28137](https://github.com/angular/angular/issues/28137)) ([d12db4e](https://github.com/angular/angular/commit/d12db4e))
|
||||
* **bazel:** ng_package creates invalid typings reexport on windows ([#27829](https://github.com/angular/angular/issues/27829)) ([4caf654](https://github.com/angular/angular/commit/4caf654))
|
||||
* **bazel:** packager not properly removing amd directives on windows ([#27829](https://github.com/angular/angular/issues/27829)) ([8473d68](https://github.com/angular/angular/commit/8473d68))
|
||||
* **bazel:** protractor rule does not run spec files with underscore ([#28022](https://github.com/angular/angular/issues/28022)) ([65e72e9](https://github.com/angular/angular/commit/65e72e9))
|
||||
* **bazel:** protractor utils cannot start server on windows ([#27915](https://github.com/angular/angular/issues/27915)) ([9de9c8a](https://github.com/angular/angular/commit/9de9c8a))
|
||||
* **bazel:** replay compilation uses wrong compiler for building esm5 ([#28053](https://github.com/angular/angular/issues/28053)) ([cd04513](https://github.com/angular/angular/commit/cd04513))
|
||||
* **bazel:** ts_web_test_suite now properly includes init_browser_spec.js ([#27965](https://github.com/angular/angular/issues/27965)) ([ce51dfb](https://github.com/angular/angular/commit/ce51dfb))
|
||||
* **service-worker:** navigation urls backwards compatibility ([#27244](https://github.com/angular/angular/issues/27244)) ([d49d1e7](https://github.com/angular/angular/commit/d49d1e7))
|
||||
* **bazel:** Fix integration test after v8 bump ([#28194](https://github.com/angular/angular/issues/28194)) ([7b772e9](https://github.com/angular/angular/commit/7b772e9)), closes [#28142](https://github.com/angular/angular/issues/28142)
|
||||
* **router:** `skipLocationChange` with named outlets ([#28301](https://github.com/angular/angular/issues/28301)) ([32737a6](https://github.com/angular/angular/commit/32737a6)), closes [#27680](https://github.com/angular/angular/issues/27680) [#28200](https://github.com/angular/angular/issues/28200)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **forms:** export NumberValueAccessor & RangeValueAccessor directives ([#27743](https://github.com/angular/angular/issues/27743)) ([ac15717](https://github.com/angular/angular/commit/ac15717))
|
||||
|
||||
|
||||
### Performance Improvements
|
||||
|
||||
* **platform-server:** use shared `DomElementSchemaRegistry` instance ([#28150](https://github.com/angular/angular/issues/28150)) ([#28151](https://github.com/angular/angular/issues/28151)) ([ce3a746](https://github.com/angular/angular/commit/ce3a746))
|
||||
* **bazel:** Add support for SASS ([#28167](https://github.com/angular/angular/issues/28167)) ([a4d9192](https://github.com/angular/angular/commit/a4d9192))
|
||||
* **compiler-cli:** resolve generated Sass/Less files to .css inputs ([#28166](https://github.com/angular/angular/issues/28166)) ([4c00059](https://github.com/angular/angular/commit/4c00059))
|
||||
|
||||
|
||||
|
||||
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2019 Google LLC. http://angular.io/license
|
||||
Copyright (c) 2014-2018 Google, Inc. http://angular.io
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -3796,7 +3796,7 @@ The relevant *Crisis Center* code for this milestone follows.
|
||||
|
||||
</code-pane>
|
||||
|
||||
<code-pane header="crisis-detail.component.html" path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.html">
|
||||
<code-pane header="crisis-detail.component.ts" path="router/src/app/crisis-center/crisis-detail/crisis-detail.component.ts">
|
||||
|
||||
</code-pane>
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
@description
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2010-2019 Google LLC. http://angular.io/license
|
||||
Copyright (c) 2014-2018 Google, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
@ -17,7 +17,7 @@
|
||||
"build": "yarn ~~build",
|
||||
"prebuild-local": "yarn setup-local",
|
||||
"build-local": "yarn ~~build",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 4ae713b5a",
|
||||
"extract-cli-command-docs": "node tools/transforms/cli-docs-package/extract-cli-commands.js 02d2ec250",
|
||||
"lint": "yarn check-env && yarn docs-lint && ng lint && yarn example-lint && yarn tools-lint",
|
||||
"test": "yarn check-env && ng test",
|
||||
"pree2e": "yarn check-env && yarn update-webdriver",
|
||||
|
@ -52,7 +52,7 @@ describe('AppComponent', () => {
|
||||
await newDocPromise; // Wait for the new document to be fetched.
|
||||
fixture.detectChanges(); // Propagate document change to the view (i.e to `DocViewer`).
|
||||
await docRenderedPromise; // Wait for the `docRendered` event.
|
||||
};
|
||||
}
|
||||
|
||||
function initializeTest(waitForDoc = true) {
|
||||
fixture = TestBed.createComponent(AppComponent);
|
||||
@ -73,7 +73,7 @@ describe('AppComponent', () => {
|
||||
tocService = de.injector.get<TocService>(TocService);
|
||||
|
||||
return waitForDoc && awaitDocRendered();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
describe('with proper DocViewer', () => {
|
||||
|
@ -125,7 +125,7 @@ export class ApiListComponent implements OnInit {
|
||||
return status === 'all' ||
|
||||
status === item.stability ||
|
||||
(status === 'security-risk' && item.securityRisk);
|
||||
};
|
||||
}
|
||||
|
||||
function matchesType() {
|
||||
return type === 'all' || type === item.docType;
|
||||
|
@ -54,7 +54,7 @@ export class ApiService implements OnDestroy {
|
||||
section.items.every(item => item.stability === 'deprecated');
|
||||
});
|
||||
}));
|
||||
};
|
||||
}
|
||||
|
||||
constructor(private http: HttpClient, private logger: Logger) { }
|
||||
|
||||
|
@ -79,7 +79,7 @@ describe('ContributorListComponent', () => {
|
||||
return comp;
|
||||
}
|
||||
|
||||
interface SearchResult { [index: string]: string; };
|
||||
interface SearchResult { [index: string]: string; }
|
||||
|
||||
class TestLocationService {
|
||||
searchResult: SearchResult = {};
|
||||
|
@ -245,7 +245,7 @@ class FakeComponentFactory extends ComponentFactory<any> {
|
||||
rootSelectorOrNode?: string | any,
|
||||
ngModule?: NgModuleRef<any>): ComponentRef<any> {
|
||||
return jasmine.createSpy('ComponentRef') as any;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class FakeComponentFactoryResolver extends ComponentFactoryResolver {
|
||||
|
@ -37,6 +37,6 @@ describe('Getting Started NgFor Component', () => {
|
||||
|
||||
component.parseError$.subscribe(error => {
|
||||
expect(error).toBeTruthy();
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -46,6 +46,6 @@ describe('Getting Started NgIf Component', () => {
|
||||
|
||||
component.parseError$.subscribe(error => {
|
||||
expect(error).toBeTruthy();
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -26,7 +26,7 @@ export class ResourceService {
|
||||
|
||||
(categories as ConnectableObservable<Category[]>).connect();
|
||||
return categories;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Extract sorted Category[] from resource JSON data
|
||||
|
@ -100,9 +100,10 @@ export class DocViewerComponent implements OnDestroy {
|
||||
if (needsToc && !embeddedToc) {
|
||||
// Add an embedded ToC if it's needed and there isn't one in the content already.
|
||||
titleEl!.insertAdjacentHTML('afterend', '<aio-toc class="embedded"></aio-toc>');
|
||||
} else if (!needsToc && embeddedToc) {
|
||||
} else if (!needsToc && embeddedToc && embeddedToc.parentNode !== null) {
|
||||
// Remove the embedded Toc if it's there and not needed.
|
||||
embeddedToc.remove();
|
||||
// We cannot use ChildNode.remove() because of IE11
|
||||
embeddedToc.parentNode.removeChild(embeddedToc);
|
||||
}
|
||||
|
||||
return () => {
|
||||
|
@ -1,20 +1,23 @@
|
||||
<div class="grid-fluid">
|
||||
<div class="footer-block" *ngFor="let node of nodes">
|
||||
<h3>{{node.title}}</h3>
|
||||
<ul>
|
||||
<li *ngFor="let item of node.children">
|
||||
<a class="link" [href]="item.url" [title]="item.tooltip || item.title">{{ item.title }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Super-powered by Google ©2010-2019.
|
||||
Code licensed under an <a href="license" title="License text">MIT-style License</a>.
|
||||
Documentation licensed under
|
||||
<a href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
|
||||
</p>
|
||||
<p>
|
||||
Version {{versionInfo?.full}}.
|
||||
</p>
|
||||
<div class="grid-fluid">
|
||||
<div class="footer-block" *ngFor="let node of nodes">
|
||||
<h3>{{node.title}}</h3>
|
||||
<ul>
|
||||
<li *ngFor="let item of node.children">
|
||||
<a class="link" [href]="item.url"
|
||||
[title]="item.tooltip || item.title">{{ item.title }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
Powered by Google ©2010-2018.
|
||||
Code licensed under an <a href="license" title="License text" >MIT-style License</a>.
|
||||
Documentation licensed under
|
||||
<a href="http://creativecommons.org/licenses/by/4.0/">CC BY 4.0</a>.
|
||||
</p>
|
||||
<p>
|
||||
Version {{versionInfo?.full}}.
|
||||
</p>
|
||||
<!-- TODO: twitter widget (but only on pages that use twitter) -->
|
||||
|
@ -1,3 +1,9 @@
|
||||
/*
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
|
||||
import { NgZone, Injectable } from '@angular/core';
|
||||
import { ConnectableObservable, Observable, race, ReplaySubject, timer } from 'rxjs';
|
||||
import { concatMap, first, publishReplay } from 'rxjs/operators';
|
||||
|
@ -14,4 +14,4 @@ export class Deployment {
|
||||
mode: string = this.location.search()['mode'] || environment.mode;
|
||||
|
||||
constructor(private location: LocationService) {}
|
||||
};
|
||||
}
|
||||
|
@ -68,7 +68,10 @@ export class TocService {
|
||||
}
|
||||
}
|
||||
// now remove the anchor
|
||||
anchorLink.remove();
|
||||
if (anchorLink.parentNode !== null) {
|
||||
// We cannot use ChildNode.remove() because of IE11
|
||||
anchorLink.parentNode.removeChild(anchorLink);
|
||||
}
|
||||
}
|
||||
// security: the document element which provides this heading content
|
||||
// is always authored by the documentation team and is considered to be safe
|
||||
|
@ -1,3 +1,9 @@
|
||||
/*
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
|
||||
import {NgZone} from '@angular/core';
|
||||
import {Observable} from 'rxjs';
|
||||
|
||||
|
@ -1,10 +1,3 @@
|
||||
/*
|
||||
Copyright Google LLC. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* WEB VERSION FOR CURRENT ANGULAR BUILD
|
||||
* (based on systemjs.config.js in angular.io)
|
||||
@ -101,3 +94,9 @@ can be found in the LICENSE file at http://angular.io/license
|
||||
});
|
||||
|
||||
})(this);
|
||||
|
||||
/*
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
|
@ -1,9 +1,3 @@
|
||||
/*
|
||||
Copyright Google LLC. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
|
||||
/**
|
||||
* WEB ANGULAR VERSION
|
||||
* (based on systemjs.config.js in angular.io)
|
||||
@ -86,3 +80,9 @@ can be found in the LICENSE file at http://angular.io/license
|
||||
});
|
||||
|
||||
})(this);
|
||||
|
||||
/*
|
||||
Copyright 2016 Google Inc. All Rights Reserved.
|
||||
Use of this source code is governed by an MIT-style license that
|
||||
can be found in the LICENSE file at http://angular.io/license
|
||||
*/
|
||||
|
@ -51,9 +51,9 @@ class StackblitzBuilder {
|
||||
}
|
||||
|
||||
_buildCopyrightStrings() {
|
||||
var copyright = 'Copyright Google LLC. All Rights Reserved.\n' +
|
||||
'Use of this source code is governed by an MIT-style license that\n' +
|
||||
'can be found in the LICENSE file at http://angular.io/license';
|
||||
var copyright = 'Copyright 2017-2018 Google Inc. All Rights Reserved.\n'
|
||||
+ 'Use of this source code is governed by an MIT-style license that\n'
|
||||
+ 'can be found in the LICENSE file at http://angular.io/license';
|
||||
var pad = '\n\n';
|
||||
this.copyrights.jsCss = `${pad}/*\n${copyright}\n*/`;
|
||||
this.copyrights.html = `${pad}<!-- \n${copyright}\n-->`;
|
||||
|
@ -75,6 +75,7 @@
|
||||
],
|
||||
"radix": true,
|
||||
"semicolon": [
|
||||
true,
|
||||
"always"
|
||||
],
|
||||
"triple-equals": [
|
||||
|
@ -133,7 +133,7 @@ Bazel supports the ability to include non-hermetic information from the version
|
||||
You can see an overview at https://www.kchodorow.com/blog/2017/03/27/stamping-your-builds/
|
||||
In our repo, here is how it's configured:
|
||||
|
||||
1) In `tools/bazel_stamp_vars.js` we run the `git` commands to generate our versioning info.
|
||||
1) In `tools/bazel_stamp_vars.sh` we run the `git` commands to generate our versioning info.
|
||||
1) In `.bazelrc` we register this script as the value for the `workspace_status_command` flag. Bazel will run the script when it needs to stamp a binary.
|
||||
|
||||
Note that Bazel has a `--stamp` argument to `yarn bazel build`, but this has no effect since our stamping takes place in Skylark rules. See https://github.com/bazelbuild/bazel/issues/1054
|
||||
|
@ -65,7 +65,6 @@ What kind of problem is this?
|
||||
## Caretaker Triage Process (Primary Triage)
|
||||
|
||||
It is the caretaker's responsibility to assign `comp: *` to each new issue as they come in.
|
||||
Issues that haven't been triaged can be found by selecting the issues with no milestone.
|
||||
|
||||
If it's obvious that the issue or PR is related to a release regression, the caretaker is also responsible for assigning the `severity(5): regression` label to make the issue or PR highly visible.
|
||||
|
||||
@ -73,12 +72,10 @@ The primary triage should be done on a daily basis so that the issues become ava
|
||||
|
||||
The reason why we limit the responsibility of the caretaker to this one label is that it is likely that without domain knowledge the caretaker could mislabel issues or lack knowledge of duplicate issues.
|
||||
|
||||
Once the primary triage is done, the ng-bot automatically adds the milestone `needsTriage`.
|
||||
|
||||
|
||||
## Component's owner Triage Process
|
||||
|
||||
The component owner is responsible for assigning one of the labels from each of these categories to the issues that have the milestone `needsTriage`:
|
||||
The component owner is responsible for assigning one of the labels from each of these categories:
|
||||
|
||||
- `type: *`
|
||||
- `frequency: *`
|
||||
@ -86,8 +83,6 @@ The component owner is responsible for assigning one of the labels from each of
|
||||
|
||||
We've adopted the issue categorization based on [user pain](http://www.lostgarden.com/2008/05/improving-bug-triage-with-user-pain.html) used by AngularJS. In this system every issue is assigned frequency and severity based on which the total user pain score is calculated.
|
||||
|
||||
The issues with type `type: feature`, `type: refactor` and `type: RFC / Discussion / question` do not require a frequency and severity.
|
||||
|
||||
Following is the definition of various frequency and severity levels:
|
||||
|
||||
1. `freq(score): *` – How often does this issue come up? How many developers does this affect?
|
||||
@ -110,16 +105,10 @@ These criteria are then used to calculate a "user pain" score as follows:
|
||||
|
||||
This score can then be used to estimate the impact of the issue which helps with prioritization.
|
||||
|
||||
Once the component's owner triage is done, the ng-bot automatically changes the milestone from `needsTriage` to `Backlog`.
|
||||
|
||||
|
||||
## Triaging PRs
|
||||
|
||||
Triaging PRs is the same as triaging issues, except that the labels `frequency: *` and `severity: *` are replaced by:
|
||||
- `effort*`
|
||||
- `risk: *`
|
||||
|
||||
PRs also have additional label categories that should be used to signal their state.
|
||||
Triaging PRs is the same as triaging issues, except that PRs have additional label categories that should be used to signal their state.
|
||||
|
||||
Every triaged PR must have a `pr_action` label assigned to it:
|
||||
|
||||
@ -149,7 +138,7 @@ To communicate the target we use the following labels:
|
||||
* `PR target: LTS-only`: the PR should be merged only into the active LTS branch(es). Only security and critical fixes are allowed in these branches. Always send a new PR targeting just the LTS branch and request review approval from @IgorMinar.
|
||||
* `PR target: TBD`: the target is yet to be determined.
|
||||
|
||||
If a PR is missing the `PR target: *` label, or if the label is set to "TBD" when the PR is sent to the caretaker, the caretaker should reject the PR and request the appropriate target label to be applied before the PR is merged.
|
||||
If a PR is missing the "PR target: *" label, or if the label is set to "TBD" when the PR is sent to the caretaker, the caretaker should reject the PR and request the appropriate target label to be applied before the PR is merged.
|
||||
|
||||
|
||||
## PR Approvals
|
||||
@ -172,10 +161,3 @@ Only issues with `cla:yes` should be merged into master.
|
||||
|
||||
### `aio: preview`
|
||||
Applying this label to a PR makes the angular.io preview available regardless of the author. [More info](../aio/aio-builds-setup/docs/overview--security-model.md)
|
||||
|
||||
### `PR action: merge-assistance`
|
||||
This label can be added to let the caretaker know that the PR needs special attention.
|
||||
There should always be a comment added to the PR to explain why the caretaker's assistance is needed.
|
||||
The comment should be formatted like this: `merge-assistance: <explain what kind of assistance you need, and if not obvious why>`
|
||||
|
||||
For example, the PR owner might not be a Googler and needs help to run g3sync; or one of the checks is failing due to external causes and the PR should still be merged.
|
@ -3,7 +3,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime": 1497,
|
||||
"main": 187437,
|
||||
"main": 187112,
|
||||
"polyfills": 59608
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@
|
||||
"master": {
|
||||
"uncompressed": {
|
||||
"runtime": 1440,
|
||||
"main": 584077,
|
||||
"main": 507677,
|
||||
"polyfills": 38390
|
||||
}
|
||||
}
|
||||
|
@ -13,3 +13,6 @@ build --local_resources=14336,8.0,1.0
|
||||
|
||||
# Use the Angular 6 compiler
|
||||
build --define=compile=legacy
|
||||
|
||||
# Don't create symlinks
|
||||
build --symlink_prefix=/
|
||||
|
@ -37,14 +37,9 @@ ts_devserver(
|
||||
|
||||
load("@build_bazel_rules_nodejs//:defs.bzl", "nodejs_binary", "rollup_bundle")
|
||||
|
||||
filegroup(
|
||||
name = "empty_node_modules",
|
||||
)
|
||||
|
||||
rollup_bundle(
|
||||
name = "bundle",
|
||||
entry_point = "src/main",
|
||||
node_modules = ":empty_node_modules",
|
||||
deps = ["//src"],
|
||||
)
|
||||
|
||||
|
@ -2,24 +2,24 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@bazel/bazel-darwin_x64@0.20.0":
|
||||
version "0.20.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-darwin_x64/-/bazel-darwin_x64-0.20.0.tgz#648d61c32a3c5fccb7bf70b753071b6e54b11f21"
|
||||
integrity sha512-zeoeVK504341GfnaxdaB4pFzQV0YOK1HLiYj3/ocamPFxAJRh9abvKB8iOpqD5Oal0j7VsINxnXCjovp9a4urA==
|
||||
"@bazel/bazel-darwin_x64@0.18.0":
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-darwin_x64/-/bazel-darwin_x64-0.18.0.tgz#bab437605a702279d42f59caa4741bb327eb7dbc"
|
||||
integrity sha512-um2OzgLL2Gd/W6joOpvrSTcqpnupliPNpwe/uE7sB0huBSJ/4Im0w2IlCTI6C7OfgMcbpUj4YxgUa9T6u6WY6w==
|
||||
|
||||
"@bazel/bazel-linux_x64@0.20.0":
|
||||
version "0.20.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-linux_x64/-/bazel-linux_x64-0.20.0.tgz#2568628a0d0b85dcc69d0ab701b1d6e10551357d"
|
||||
integrity sha512-PpHzoEqfXty8dc1/p1tVFXtbPyrE1n0N79QmYePjJ5mJMyW7uBF/zV4IajYY8+IpJEcDVq5v4BavSexOmVJRmA==
|
||||
"@bazel/bazel-linux_x64@0.18.0":
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-linux_x64/-/bazel-linux_x64-0.18.0.tgz#0c02b2404ec95c180e17615cc7079ee07df48a69"
|
||||
integrity sha512-Rq8X8bL6SgQvbOHnfPhSgF6hp+f6Fbt2w6pRmBlFvV1J+CeUyrSrrRXfnnO1bjIuq05Ur3mV8ULA0qK6rtA5lQ==
|
||||
|
||||
"@bazel/bazel-win32_x64@0.20.0":
|
||||
version "0.20.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-win32_x64/-/bazel-win32_x64-0.20.0.tgz#af7d041dae4c066e7aa8618949e2de1aad07495e"
|
||||
integrity sha512-3bqHXFBvLnbvNzr1KCQ1zryTYvHMoQffaWVekbckgPyT2VPEj3abuB91+DrRYmZdPjcgPYnjnyanxZHDkKuF2g==
|
||||
"@bazel/bazel-win32_x64@0.18.0":
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@bazel/bazel-win32_x64/-/bazel-win32_x64-0.18.0.tgz#aa4575fb00066dcf59a6d464971774dea6a0bafd"
|
||||
integrity sha512-U2TbfK8B7dc3JqXSFwj2oXCQrxEaSzCCUkAHjAOIGOKzx/HLKIKs+NJj9IQkLLr7BsMU+Qqzo8aqo11E+Vs+aA==
|
||||
|
||||
"@bazel/bazel@file:../../node_modules/@bazel/bazel":
|
||||
version "0.20.0"
|
||||
version "0.18.0"
|
||||
optionalDependencies:
|
||||
"@bazel/bazel-darwin_x64" "0.20.0"
|
||||
"@bazel/bazel-linux_x64" "0.20.0"
|
||||
"@bazel/bazel-win32_x64" "0.20.0"
|
||||
"@bazel/bazel-darwin_x64" "0.18.0"
|
||||
"@bazel/bazel-linux_x64" "0.18.0"
|
||||
"@bazel/bazel-win32_x64" "0.18.0"
|
||||
|
@ -1,3 +1 @@
|
||||
*.js
|
||||
tsserver.log
|
||||
ti-*.log
|
||||
*.js
|
@ -0,0 +1,260 @@
|
||||
[
|
||||
{
|
||||
"type": "response",
|
||||
"command": "configure",
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"type": "response",
|
||||
"command": "compilerOptionsForInferredProjects",
|
||||
"success": true,
|
||||
"body": true
|
||||
},
|
||||
{
|
||||
"type": "response",
|
||||
"command": "completions",
|
||||
"success": true,
|
||||
"body": [
|
||||
{
|
||||
"name": "anchor",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "anchor"
|
||||
},
|
||||
{
|
||||
"name": "big",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "big"
|
||||
},
|
||||
{
|
||||
"name": "blink",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "blink"
|
||||
},
|
||||
{
|
||||
"name": "bold",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "bold"
|
||||
},
|
||||
{
|
||||
"name": "charAt",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "charAt"
|
||||
},
|
||||
{
|
||||
"name": "charCodeAt",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "charCodeAt"
|
||||
},
|
||||
{
|
||||
"name": "codePointAt",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "codePointAt"
|
||||
},
|
||||
{
|
||||
"name": "concat",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "concat"
|
||||
},
|
||||
{
|
||||
"name": "endsWith",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "endsWith"
|
||||
},
|
||||
{
|
||||
"name": "fixed",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "fixed"
|
||||
},
|
||||
{
|
||||
"name": "fontcolor",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "fontcolor"
|
||||
},
|
||||
{
|
||||
"name": "fontsize",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "fontsize"
|
||||
},
|
||||
{
|
||||
"name": "includes",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "includes"
|
||||
},
|
||||
{
|
||||
"name": "indexOf",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "indexOf"
|
||||
},
|
||||
{
|
||||
"name": "italics",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "italics"
|
||||
},
|
||||
{
|
||||
"name": "lastIndexOf",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "lastIndexOf"
|
||||
},
|
||||
{
|
||||
"name": "length",
|
||||
"kind": "property",
|
||||
"kindModifiers": "",
|
||||
"sortText": "length"
|
||||
},
|
||||
{
|
||||
"name": "link",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "link"
|
||||
},
|
||||
{
|
||||
"name": "localeCompare",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "localeCompare"
|
||||
},
|
||||
{
|
||||
"name": "match",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "match"
|
||||
},
|
||||
{
|
||||
"name": "normalize",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "normalize"
|
||||
},
|
||||
{
|
||||
"name": "repeat",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "repeat"
|
||||
},
|
||||
{
|
||||
"name": "replace",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "replace"
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "search"
|
||||
},
|
||||
{
|
||||
"name": "slice",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "slice"
|
||||
},
|
||||
{
|
||||
"name": "small",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "small"
|
||||
},
|
||||
{
|
||||
"name": "split",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "split"
|
||||
},
|
||||
{
|
||||
"name": "startsWith",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "startsWith"
|
||||
},
|
||||
{
|
||||
"name": "strike",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "strike"
|
||||
},
|
||||
{
|
||||
"name": "sub",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "sub"
|
||||
},
|
||||
{
|
||||
"name": "substr",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "substr"
|
||||
},
|
||||
{
|
||||
"name": "substring",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "substring"
|
||||
},
|
||||
{
|
||||
"name": "sup",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "sup"
|
||||
},
|
||||
{
|
||||
"name": "toLocaleLowerCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toLocaleLowerCase"
|
||||
},
|
||||
{
|
||||
"name": "toLocaleUpperCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toLocaleUpperCase"
|
||||
},
|
||||
{
|
||||
"name": "toLowerCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toLowerCase"
|
||||
},
|
||||
{
|
||||
"name": "toString",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toString"
|
||||
},
|
||||
{
|
||||
"name": "toUpperCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toUpperCase"
|
||||
},
|
||||
{
|
||||
"name": "trim",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "trim"
|
||||
},
|
||||
{
|
||||
"name": "valueOf",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "valueOf"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
@ -0,0 +1,68 @@
|
||||
[
|
||||
{
|
||||
"seq": 0,
|
||||
"type": "request",
|
||||
"command": "configure",
|
||||
"arguments": {
|
||||
"hostInfo": "vscode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 1,
|
||||
"type": "request",
|
||||
"command": "compilerOptionsForInferredProjects",
|
||||
"arguments": {
|
||||
"options": {
|
||||
"module": "CommonJS",
|
||||
"target": "ES6",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowNonTsExtensions": true,
|
||||
"allowJs": true,
|
||||
"jsx": "Preserve"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 4,
|
||||
"type": "request",
|
||||
"command": "open",
|
||||
"arguments": {
|
||||
"file": "$$PWD$$/project/app/app.component.ts",
|
||||
"fileContent": "import { Component } from '@angular/core';\n\n@Component({\n selector: 'my-app',\n template: `<h1>Hello {{name}}</h1>`,\n})\nexport class AppComponent { name = 'Angular'; }\n"
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 7,
|
||||
"type": "request",
|
||||
"command": "geterr",
|
||||
"arguments": {
|
||||
"delay": 0,
|
||||
"files": [
|
||||
"$$PWD$$/project/app/app.component.ts"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 12,
|
||||
"type": "request",
|
||||
"command": "change",
|
||||
"arguments": {
|
||||
"file": "$$PWD$$/project/app/app.component.ts",
|
||||
"line": 5,
|
||||
"offset": 30,
|
||||
"endLine": 5,
|
||||
"endOffset": 30,
|
||||
"insertString": "."
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 13,
|
||||
"type": "request",
|
||||
"command": "completions",
|
||||
"arguments": {
|
||||
"file": "$$PWD$$/project/app/app.component.ts",
|
||||
"line": 5,
|
||||
"offset": 31
|
||||
}
|
||||
}
|
||||
]
|
@ -1,8 +1,13 @@
|
||||
{
|
||||
"seq": 0,
|
||||
[
|
||||
{
|
||||
"type": "response",
|
||||
"command": "configure",
|
||||
"success": true
|
||||
},
|
||||
{
|
||||
"type": "response",
|
||||
"command": "compilerOptionsForInferredProjects",
|
||||
"request_seq": 1,
|
||||
"success": true,
|
||||
"body": true
|
||||
}
|
||||
}
|
||||
]
|
45
integration/language_service_plugin/fixtures/smokeTest.json
Normal file
45
integration/language_service_plugin/fixtures/smokeTest.json
Normal file
@ -0,0 +1,45 @@
|
||||
[
|
||||
{
|
||||
"seq": 0,
|
||||
"type": "request",
|
||||
"command": "configure",
|
||||
"arguments": {
|
||||
"hostInfo": "vscode"
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 1,
|
||||
"type": "request",
|
||||
"command": "compilerOptionsForInferredProjects",
|
||||
"arguments": {
|
||||
"options": {
|
||||
"module": "CommonJS",
|
||||
"target": "ES6",
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"allowNonTsExtensions": true,
|
||||
"allowJs": true,
|
||||
"jsx": "Preserve"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 2,
|
||||
"type": "request",
|
||||
"command": "open",
|
||||
"arguments": {
|
||||
"file": "$$PWD$$/app/app.module.ts",
|
||||
"fileContent": ""
|
||||
}
|
||||
},
|
||||
{
|
||||
"seq": 3,
|
||||
"type": "request",
|
||||
"command": "geterr",
|
||||
"arguments": {
|
||||
"delay": 0,
|
||||
"files": [
|
||||
"$$PWD$$/app/app.module.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
@ -1,22 +0,0 @@
|
||||
/**
|
||||
* @fileOverview
|
||||
* This file serves as the entry point for generating goldens file for the
|
||||
* language service integration test. It expects each golden file that needs
|
||||
* to be generated to be passed in as command line arguments.
|
||||
* For example, to generate golden file for the 'configure' request, run
|
||||
* `yarn golden configure.json`.
|
||||
* To generate multiple golden files, run
|
||||
* `yarn golden configure.json completionInfo.json`.
|
||||
*
|
||||
* This is different from just running `yarn jasmine test.js` because this
|
||||
* allows passing in arbitrary arguments.
|
||||
*/
|
||||
|
||||
import Jasmine = require('jasmine');
|
||||
|
||||
function main() {
|
||||
const jasmine = new Jasmine({});
|
||||
jasmine.execute(['test.js']);
|
||||
}
|
||||
|
||||
main()
|
@ -1,266 +0,0 @@
|
||||
{
|
||||
"seq": 0,
|
||||
"type": "response",
|
||||
"command": "completionInfo",
|
||||
"request_seq": 5,
|
||||
"success": true,
|
||||
"body": {
|
||||
"isGlobalCompletion": false,
|
||||
"isMemberCompletion": false,
|
||||
"isNewIdentifierLocation": false,
|
||||
"entries": [
|
||||
{
|
||||
"name": "anchor",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "anchor"
|
||||
},
|
||||
{
|
||||
"name": "big",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "big"
|
||||
},
|
||||
{
|
||||
"name": "blink",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "blink"
|
||||
},
|
||||
{
|
||||
"name": "bold",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "bold"
|
||||
},
|
||||
{
|
||||
"name": "charAt",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "charAt"
|
||||
},
|
||||
{
|
||||
"name": "charCodeAt",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "charCodeAt"
|
||||
},
|
||||
{
|
||||
"name": "codePointAt",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "codePointAt"
|
||||
},
|
||||
{
|
||||
"name": "concat",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "concat"
|
||||
},
|
||||
{
|
||||
"name": "endsWith",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "endsWith"
|
||||
},
|
||||
{
|
||||
"name": "fixed",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "fixed"
|
||||
},
|
||||
{
|
||||
"name": "fontcolor",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "fontcolor"
|
||||
},
|
||||
{
|
||||
"name": "fontsize",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "fontsize"
|
||||
},
|
||||
{
|
||||
"name": "includes",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "includes"
|
||||
},
|
||||
{
|
||||
"name": "indexOf",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "indexOf"
|
||||
},
|
||||
{
|
||||
"name": "italics",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "italics"
|
||||
},
|
||||
{
|
||||
"name": "lastIndexOf",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "lastIndexOf"
|
||||
},
|
||||
{
|
||||
"name": "length",
|
||||
"kind": "property",
|
||||
"kindModifiers": "",
|
||||
"sortText": "length"
|
||||
},
|
||||
{
|
||||
"name": "link",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "link"
|
||||
},
|
||||
{
|
||||
"name": "localeCompare",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "localeCompare"
|
||||
},
|
||||
{
|
||||
"name": "match",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "match"
|
||||
},
|
||||
{
|
||||
"name": "normalize",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "normalize"
|
||||
},
|
||||
{
|
||||
"name": "repeat",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "repeat"
|
||||
},
|
||||
{
|
||||
"name": "replace",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "replace"
|
||||
},
|
||||
{
|
||||
"name": "search",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "search"
|
||||
},
|
||||
{
|
||||
"name": "slice",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "slice"
|
||||
},
|
||||
{
|
||||
"name": "small",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "small"
|
||||
},
|
||||
{
|
||||
"name": "split",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "split"
|
||||
},
|
||||
{
|
||||
"name": "startsWith",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "startsWith"
|
||||
},
|
||||
{
|
||||
"name": "strike",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "strike"
|
||||
},
|
||||
{
|
||||
"name": "sub",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "sub"
|
||||
},
|
||||
{
|
||||
"name": "substr",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "substr"
|
||||
},
|
||||
{
|
||||
"name": "substring",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "substring"
|
||||
},
|
||||
{
|
||||
"name": "sup",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "sup"
|
||||
},
|
||||
{
|
||||
"name": "toLocaleLowerCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toLocaleLowerCase"
|
||||
},
|
||||
{
|
||||
"name": "toLocaleUpperCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toLocaleUpperCase"
|
||||
},
|
||||
{
|
||||
"name": "toLowerCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toLowerCase"
|
||||
},
|
||||
{
|
||||
"name": "toString",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toString"
|
||||
},
|
||||
{
|
||||
"name": "toUpperCase",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "toUpperCase"
|
||||
},
|
||||
{
|
||||
"name": "trim",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "trim"
|
||||
},
|
||||
{
|
||||
"name": "trimLeft",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "trimLeft"
|
||||
},
|
||||
{
|
||||
"name": "trimRight",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "trimRight"
|
||||
},
|
||||
{
|
||||
"name": "valueOf",
|
||||
"kind": "method",
|
||||
"kindModifiers": "",
|
||||
"sortText": "valueOf"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
{
|
||||
"seq": 0,
|
||||
"type": "response",
|
||||
"command": "configure",
|
||||
"request_seq": 0,
|
||||
"success": true
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
import { writeFileSync } from 'fs';
|
||||
|
||||
const goldens: string[] = process.argv.slice(2);
|
||||
|
||||
export const goldenMatcher: jasmine.CustomMatcherFactories = {
|
||||
toMatchGolden(util: jasmine.MatchersUtil): jasmine.CustomMatcher {
|
||||
return {
|
||||
compare(actual: {command: string}, golden: string): jasmine.CustomMatcherResult {
|
||||
const expected = require(`./goldens/${golden}`);
|
||||
const pass = util.equals(actual, expected);
|
||||
if (!pass && goldens.indexOf(golden) >= 0) {
|
||||
console.error(`Writing golden file ${golden}`);
|
||||
writeFileSync(`./goldens/${golden}`, JSON.stringify(actual, null, 2));
|
||||
return { pass : true };
|
||||
}
|
||||
return {
|
||||
pass,
|
||||
message: `Expected response for '${actual.command}' to match golden file ${golden}.\n` +
|
||||
`To generate new golden file, run "yarn golden ${golden}".`,
|
||||
};
|
||||
}
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
declare global {
|
||||
namespace jasmine {
|
||||
interface Matchers<T> {
|
||||
toMatchGolden(golden: string): void
|
||||
}
|
||||
}
|
||||
}
|
@ -4,16 +4,23 @@
|
||||
"license": "MIT",
|
||||
"description": "Angular Language Service plugin integration test",
|
||||
"dependencies": {
|
||||
"@angular/animations": "file:../../dist/packages-dist/animations",
|
||||
"@angular/common": "file:../../dist/packages-dist/common",
|
||||
"@angular/compiler": "file:../../dist/packages-dist/compiler",
|
||||
"@angular/compiler-cli": "file:../../dist/packages-dist/compiler-cli",
|
||||
"@angular/core": "file:../../dist/packages-dist/core",
|
||||
"@angular/language-service": "file:../../dist/packages-dist/language-service",
|
||||
"@types/node": "file:../../node_modules/@types/node",
|
||||
"jasmine": "file:../../node_modules/jasmine",
|
||||
"typescript": "file:../../node_modules/typescript"
|
||||
"@angular/platform-browser": "file:../../dist/packages-dist/platform-browser",
|
||||
"@angular/platform-server": "file:../../dist/packages-dist/platform-server",
|
||||
"@types/minimist": "^1.2.0",
|
||||
"@types/node": "^7.0.5",
|
||||
"minimist": "^1.2.0",
|
||||
"rxjs": "file:../../node_modules/rxjs",
|
||||
"typescript": "file:../../node_modules/typescript",
|
||||
"zone.js": "file:../../node_modules/zone.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -p tsconfig.json",
|
||||
"cleanup": "rm -rf ti-*.log tsserver.log",
|
||||
"golden": "node generate.js",
|
||||
"test": "yarn cleanup && yarn build && jasmine test.js"
|
||||
"postinstall": "scripts/install.sh",
|
||||
"test": "tsc -p tools && scripts/test.sh"
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,9 @@
|
||||
"experimentalDecorators": true,
|
||||
"lib": [ "es2015", "dom" ],
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
"suppressImplicitAnyIndexErrors": true,
|
||||
"plugins": [
|
||||
{ "name": "@angular/language-service" }
|
||||
]
|
||||
}
|
||||
}
|
||||
|
2
integration/language_service_plugin/scripts/env.sh
Executable file
2
integration/language_service_plugin/scripts/env.sh
Executable file
@ -0,0 +1,2 @@
|
||||
TYPESCRIPTS=2.3
|
||||
FIXTURES="smokeTest getCompletions"
|
16
integration/language_service_plugin/scripts/install.sh
Executable file
16
integration/language_service_plugin/scripts/install.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex -o pipefail
|
||||
|
||||
cd `dirname $0`
|
||||
cd ..
|
||||
source scripts/env.sh
|
||||
|
||||
# Setup TypeScripts
|
||||
for TYPESCRIPT in ${TYPESCRIPTS[@]}
|
||||
do
|
||||
(
|
||||
cd typescripts/$TYPESCRIPT
|
||||
yarn
|
||||
)
|
||||
done
|
30
integration/language_service_plugin/scripts/test.sh
Executable file
30
integration/language_service_plugin/scripts/test.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex -o pipefail
|
||||
|
||||
cd `dirname $0`
|
||||
cd ..
|
||||
source scripts/env.sh
|
||||
|
||||
HOST="node tools/typescript_host.js"
|
||||
VALIDATE="node tools/typescript_validator.js"
|
||||
|
||||
# Ensure the languages service can load correctly in node before typescript loads it.
|
||||
# This verifies its dependencies and emits any exceptions, both of which are only
|
||||
# emitted to the typescript logs (not the validated output).
|
||||
node tools/load_test.js
|
||||
|
||||
for TYPESCRIPT in ${TYPESCRIPTS[@]}
|
||||
do
|
||||
SERVER="node typescripts/$TYPESCRIPT/node_modules/typescript/lib/tsserver.js"
|
||||
for FIXTURE_BASE in ${FIXTURES[@]}
|
||||
do
|
||||
FIXTURE=fixtures/$FIXTURE_BASE.json
|
||||
EXPECTED=fixtures/$FIXTURE_BASE-expected-$TYPESCRIPT.json
|
||||
if [[ ${UPDATE_GOLDEN} == true ]]; then
|
||||
$HOST --file $FIXTURE --pwd $(pwd) | $SERVER | $VALIDATE --golden > $EXPECTED
|
||||
else
|
||||
$HOST --file $FIXTURE --pwd $(pwd) | $SERVER | $VALIDATE --expect $EXPECTED
|
||||
fi
|
||||
done
|
||||
done
|
8
integration/language_service_plugin/scripts/update_golden.sh
Executable file
8
integration/language_service_plugin/scripts/update_golden.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -ex -o pipefail
|
||||
|
||||
cd `dirname $0`
|
||||
cd ..
|
||||
|
||||
UPDATE_GOLDEN=true scripts/test.sh
|
@ -1,104 +0,0 @@
|
||||
import { fork, ChildProcess } from 'child_process';
|
||||
import { join } from 'path';
|
||||
import { Client } from './tsclient';
|
||||
import { goldenMatcher } from './matcher';
|
||||
|
||||
describe('Angular Language Service', () => {
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000; /* 10 seconds */
|
||||
const PWD = process.env.PWD!;
|
||||
const SERVER_PATH = "./node_modules/typescript/lib/tsserver.js";
|
||||
let server: ChildProcess;
|
||||
let client: Client;
|
||||
|
||||
beforeEach(() => {
|
||||
jasmine.addMatchers(goldenMatcher);
|
||||
server = fork(SERVER_PATH, [
|
||||
'--globalPlugins', '@angular/language-service',
|
||||
'--logVerbosity', 'verbose',
|
||||
'--logFile', join(PWD, 'tsserver.log'),
|
||||
], {
|
||||
stdio: ['pipe', 'pipe', 'inherit', 'ipc'],
|
||||
});
|
||||
client = new Client(server);
|
||||
client.listen();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
client.sendRequest('exit', {});
|
||||
|
||||
// Give server process some time to flush all messages
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
});
|
||||
|
||||
it('should be launched as tsserver plugin', async () => {
|
||||
let response = await client.sendRequest('configure', {
|
||||
hostInfo: 'vscode',
|
||||
});
|
||||
expect(response).toMatchGolden('configure.json');
|
||||
response = await client.sendRequest('compilerOptionsForInferredProjects', {
|
||||
"options": {
|
||||
module: "CommonJS",
|
||||
target: "ES6",
|
||||
allowSyntheticDefaultImports: true,
|
||||
allowNonTsExtensions: true,
|
||||
allowJs: true,
|
||||
jsx: "Preserve"
|
||||
}
|
||||
});
|
||||
expect(response).toMatchGolden('compilerOptionsForInferredProjects.json');
|
||||
// Server does not send response to open request
|
||||
// https://github.com/Microsoft/TypeScript/blob/master/lib/protocol.d.ts#L1055
|
||||
client.sendRequest('open', {
|
||||
file: `${PWD}/project/app/app.module.ts`,
|
||||
fileContent: ""
|
||||
});
|
||||
// Server does not send response to geterr request
|
||||
// https://github.com/Microsoft/TypeScript/blob/master/lib/protocol.d.ts#L1770
|
||||
client.sendRequest('geterr', {
|
||||
delay: 0,
|
||||
files: [`${PWD}/project/app/app.module.ts`]
|
||||
});
|
||||
});
|
||||
|
||||
it('should perform completions', async () => {
|
||||
await client.sendRequest('configure', {
|
||||
hostInfo: 'vscode',
|
||||
});
|
||||
await client.sendRequest('compilerOptionsForInferredProjects', {
|
||||
"options": {
|
||||
module: "CommonJS",
|
||||
target: "ES6",
|
||||
allowSyntheticDefaultImports: true,
|
||||
allowNonTsExtensions: true,
|
||||
allowJs: true,
|
||||
jsx: "Preserve"
|
||||
}
|
||||
});
|
||||
|
||||
client.sendRequest('open', {
|
||||
file: `${PWD}/project/app/app.component.ts`,
|
||||
fileContent: "import { Component } from '@angular/core';\n\n@Component({\n selector: 'my-app',\n template: `<h1>Hello {{name}}</h1>`,\n})\nexport class AppComponent { name = 'Angular'; }\n"
|
||||
});
|
||||
|
||||
client.sendRequest('geterr', {
|
||||
delay: 0,
|
||||
files: [`${PWD}/project/app/app.component.ts`]
|
||||
});
|
||||
|
||||
client.sendRequest('change', {
|
||||
file: `${PWD}/project/app/app.component.ts`,
|
||||
line: 5,
|
||||
offset: 30,
|
||||
endLine: 5,
|
||||
endOffset: 30,
|
||||
insertString: '.',
|
||||
});
|
||||
|
||||
const response = await client.sendRequest('completionInfo', {
|
||||
file: `${PWD}/project/app/app.component.ts`,
|
||||
line: 5,
|
||||
offset: 31,
|
||||
});
|
||||
expect(response).toMatchGolden('completionInfo.json');
|
||||
});
|
||||
});
|
35
integration/language_service_plugin/tools/load_test.ts
Normal file
35
integration/language_service_plugin/tools/load_test.ts
Normal file
@ -0,0 +1,35 @@
|
||||
const ts = require('typescript');
|
||||
const Module = require('module');
|
||||
|
||||
const existingRequire = Module.prototype.require;
|
||||
|
||||
const recordedRequires: string[] = [];
|
||||
|
||||
function recordingRequire(path: string) {
|
||||
recordedRequires.push(path);
|
||||
return existingRequire.call(this, path);
|
||||
}
|
||||
|
||||
Module.prototype.require = recordingRequire;
|
||||
|
||||
try {
|
||||
const lsf = require('@angular/language-service');
|
||||
const ls = lsf({typescript: ts});
|
||||
|
||||
// Assert that the only module that should have been required are '@angular/language-service', 'fs', and 'path'
|
||||
|
||||
const allowedLoads = new Set(["@angular/language-service", "fs", "path"]);
|
||||
|
||||
const invalidModules = recordedRequires.filter(m => !allowedLoads.has(m));
|
||||
|
||||
if (invalidModules.length > 0) {
|
||||
console.error(`FAILED: Loading the language service required: ${invalidModules.join(', ')}`);
|
||||
process.exit(1);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error(`FAILED: Loading the language service caused the following exception: ${e.stack || e}`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log('SUCCESS: Loading passed')
|
||||
process.exit(0);
|
19
integration/language_service_plugin/tools/tsconfig.json
Normal file
19
integration/language_service_plugin/tools/tsconfig.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es5",
|
||||
"noImplicitAny": true,
|
||||
"skipLibCheck": true,
|
||||
"sourceMap": false,
|
||||
"lib": ["es2015", "dom"],
|
||||
"types": [
|
||||
"node",
|
||||
"minimist"
|
||||
]
|
||||
},
|
||||
"files": [
|
||||
"typescript_host.ts",
|
||||
"typescript_validator.ts",
|
||||
"load_test.ts"
|
||||
]
|
||||
}
|
77
integration/language_service_plugin/tools/typescript_host.ts
Normal file
77
integration/language_service_plugin/tools/typescript_host.ts
Normal file
@ -0,0 +1,77 @@
|
||||
import * as fs from 'fs';
|
||||
import * as minimist from 'minimist';
|
||||
|
||||
const RE_PWD = /\$\$PWD\$\$/g;
|
||||
|
||||
let errorsDetected = false;
|
||||
|
||||
function reportError(arg: string): boolean {
|
||||
console.error(`Unknown argument: ${arg}`);
|
||||
errorsDetected = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function help() {
|
||||
console.log('TypeScript Host')
|
||||
console.log(`${process.argv[1]} --file <file-name> [--pwd <pwd>]`);
|
||||
console.log(`
|
||||
Send JSON message using the JSON RPC protocol to stdout.
|
||||
`)
|
||||
}
|
||||
|
||||
let args = minimist(process.argv.slice(2), { string: ['file', 'pwd'], unknown: reportError });
|
||||
|
||||
if (errorsDetected) {
|
||||
help();
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
const file = args['file'];
|
||||
if (!file) {
|
||||
console.log('stdin form not supported yet.')
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Sender
|
||||
const pending: string[] = [];
|
||||
let writing = false;
|
||||
|
||||
function writeMessage(message: string) {
|
||||
writing = true;
|
||||
process.stdout.write(message + '\n', checkPending);
|
||||
}
|
||||
|
||||
function checkPending() {
|
||||
writing = false;
|
||||
if (pending.length) {
|
||||
writeMessage(pending.shift());
|
||||
}
|
||||
}
|
||||
|
||||
function send(message: string) {
|
||||
if (writing) {
|
||||
pending.push(message);
|
||||
} else {
|
||||
writeMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
let content = fs.readFileSync(file, 'utf8');
|
||||
if (args['pwd']) {
|
||||
content = content.replace(RE_PWD, args['pwd']);
|
||||
}
|
||||
|
||||
const json = JSON.parse(content);
|
||||
|
||||
if (Array.isArray(json)) {
|
||||
for (const message of json) {
|
||||
send(JSON.stringify(message));
|
||||
}
|
||||
} else {
|
||||
throw Error('Expected an array for input messages.')
|
||||
}
|
||||
} catch(e) {
|
||||
console.error(`Error: ${e.message}`);
|
||||
process.exit(2);
|
||||
}
|
@ -0,0 +1,164 @@
|
||||
import * as fs from 'fs';
|
||||
import * as minimist from 'minimist';
|
||||
|
||||
let errorsDetected = false;
|
||||
|
||||
const start = Date.now();
|
||||
|
||||
function reportError(arg: string): boolean {
|
||||
console.error(`Unknown argument: ${arg}`);
|
||||
errorsDetected = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function help() {
|
||||
console.log('TypeScript Validator')
|
||||
console.log(`${process.argv[1]} [--expect <file-name> | --golden] [--pwd <dir>]`);
|
||||
console.log(`
|
||||
Validate that the emitted output produces the expect JSON.`)
|
||||
}
|
||||
|
||||
let args = minimist(process.argv.slice(2), { string: ['expect', 'pwd'], boolean: ['golden'], unknown: reportError });
|
||||
|
||||
if (!args.golden && !args.expect) {
|
||||
console.log('Expected -golden or -expect');
|
||||
errorsDetected = true;
|
||||
}
|
||||
|
||||
if (args.golden && args.expect) {
|
||||
console.log('Expected -golded or -expect but not both');
|
||||
errorsDetected = true;
|
||||
}
|
||||
|
||||
if (errorsDetected) {
|
||||
help();
|
||||
process.exit(2);
|
||||
}
|
||||
|
||||
var expected: any;
|
||||
if (args.expect) {
|
||||
expected = JSON.parse(fs.readFileSync(args.expect, 'utf8'));
|
||||
}
|
||||
|
||||
// Reader
|
||||
let pending = Buffer.alloc(0);
|
||||
|
||||
const prefix = 'Content-Length: ';
|
||||
|
||||
function tryReadMessage(cb: (message: any) => void) {
|
||||
const firstLine = pending.indexOf(10);
|
||||
if (firstLine >= 1) {
|
||||
const line = pending.toString('utf8', 0, firstLine);
|
||||
if (!line.startsWith(prefix)) {
|
||||
throw Error(`Unexpected input: ${line}`);
|
||||
}
|
||||
const length = +line.substring(prefix.length, firstLine - 1);
|
||||
const dataStart = firstLine + 2;
|
||||
const messageText = pending.toString('utf8', dataStart, dataStart + length);
|
||||
const message = JSON.parse(messageText);
|
||||
pending = pending.slice(dataStart + length + 1);
|
||||
cb(message);
|
||||
tryReadMessage(cb);
|
||||
}
|
||||
}
|
||||
|
||||
function collect(cb: (error: any, messages: any[]) => void) {
|
||||
const result: any[] = [];
|
||||
|
||||
function report(error: any, messages: any[]) {
|
||||
cb(error, messages);
|
||||
cb = () => {};
|
||||
}
|
||||
|
||||
process.stdin.on('error', report);
|
||||
process.stdin.on('data', (data: Buffer) => {
|
||||
try {
|
||||
pending = Buffer.concat([pending, data], pending.length + data.length);
|
||||
tryReadMessage((message: any) => {
|
||||
result.push(message);
|
||||
});
|
||||
} catch (e) {
|
||||
report(e, []);
|
||||
}
|
||||
});
|
||||
|
||||
process.stdin.on('close', () => {
|
||||
report(null, result);
|
||||
});
|
||||
}
|
||||
|
||||
function sanitize(messages: any[]): any[] {
|
||||
return messages.filter((message: any) => {
|
||||
return message && message.type == 'response';
|
||||
}).map((message: any) => {
|
||||
// Only preserve a fixed set of fields.
|
||||
const result: any = {};
|
||||
if (message.type != null) result.type = message.type;
|
||||
if (message.command != null) result.command = message.command;
|
||||
if (message.success != null) result.success = message.success;
|
||||
if (message.body != null) result.body = message.body;
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function isPrimitive(value: any): boolean {
|
||||
return Object(value) !== value;
|
||||
}
|
||||
|
||||
function expectPrimitive(received: any, expected: any) {
|
||||
if (received !== expected) {
|
||||
throw new Error(`Expected ${expected} but received ${received}`);
|
||||
}
|
||||
}
|
||||
|
||||
function expectArray(received: any, expected: any[]) {
|
||||
if (!Array.isArray(received)) {
|
||||
throw new Error(`Expected an array, received ${JSON.stringify(received)}`);
|
||||
}
|
||||
if (received.length != expected.length) {
|
||||
throw new Error(`Expected an array length ${expected.length}, received ${JSON.stringify(received)}`);
|
||||
}
|
||||
for (let i = 0; i < expected.length; i++) {
|
||||
expect(received[i], expected[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function expectObject(received: any, expected: any) {
|
||||
for (const name of Object.getOwnPropertyNames(expected)) {
|
||||
if (!received.hasOwnProperty(name)) {
|
||||
throw new Error(`Expected object an object containing a field ${name}, received ${JSON.stringify(expected)}`);
|
||||
}
|
||||
expect(received[name], expected[name]);
|
||||
}
|
||||
}
|
||||
|
||||
function expect(received: any, expected: any) {
|
||||
if (isPrimitive(expected)) {
|
||||
expectPrimitive(received, expected);
|
||||
} else if (Array.isArray(expected)) {
|
||||
expectArray(received, expected);
|
||||
} else {
|
||||
expectObject(received, expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
collect((err: any, messages: any[]) => {
|
||||
if (err) {
|
||||
console.error(err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
if (args.golden) {
|
||||
console.log(JSON.stringify(sanitize(messages), null, ' '));
|
||||
} else {
|
||||
try {
|
||||
expect(sanitize(messages), expected);
|
||||
console.log('PASSED:', Date.now() - start, 'ms');
|
||||
process.exit(0);
|
||||
} catch(e) {
|
||||
console.log('FAILED:', e.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
});
|
@ -1,70 +0,0 @@
|
||||
import { ChildProcess } from "child_process";
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
/**
|
||||
* Provides a client for tsserver. Tsserver does not use standard JSON-RPC
|
||||
* protocol thus the need for this custom client.
|
||||
*/
|
||||
export class Client {
|
||||
private data: Buffer|undefined;
|
||||
private id = 0;
|
||||
private responseEmitter = new EventEmitter();
|
||||
|
||||
constructor(private readonly server: ChildProcess) {}
|
||||
|
||||
listen() {
|
||||
this.server.stdout.on('data', (data: Buffer) => {
|
||||
this.data = this.data ? Buffer.concat([this.data, data]) : data;
|
||||
const CONTENT_LENGTH = 'Content-Length: '
|
||||
const index = this.data.indexOf(CONTENT_LENGTH);
|
||||
if (index < 0) {
|
||||
return;
|
||||
}
|
||||
let start = index + CONTENT_LENGTH.length;
|
||||
let end = this.data.indexOf('\r\n', start);
|
||||
if (end < start) {
|
||||
return;
|
||||
}
|
||||
const contentLengthStr = this.data.slice(start, end).toString();
|
||||
const contentLength = Number(contentLengthStr);
|
||||
if (isNaN(contentLength) || contentLength < 0) {
|
||||
return;
|
||||
}
|
||||
start = end + 4;
|
||||
end = start + contentLength;
|
||||
if (end > this.data.length) {
|
||||
return;
|
||||
}
|
||||
const content = this.data.slice(start, end).toString();
|
||||
this.data = this.data.slice(end);
|
||||
try {
|
||||
const payload = JSON.parse(content);
|
||||
if (payload.type === "event") {
|
||||
return;
|
||||
}
|
||||
this.responseEmitter.emit('response', payload);
|
||||
}
|
||||
catch (error) {
|
||||
this.responseEmitter.emit('error', error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async send(type: string, command: string, params: {}) {
|
||||
const request = {
|
||||
seq: this.id++,
|
||||
type,
|
||||
command,
|
||||
arguments: params
|
||||
};
|
||||
this.server.stdin.write(JSON.stringify(request) + '\r\n');
|
||||
return new Promise((resolve, reject) => {
|
||||
this.responseEmitter.once('response', resolve);
|
||||
this.responseEmitter.once('error', reject);
|
||||
});
|
||||
}
|
||||
|
||||
async sendRequest(command: string, params: {}) {
|
||||
return this.send('request', command, params);
|
||||
}
|
||||
}
|
@ -1,60 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
"target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
|
||||
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
|
||||
// "lib": [], /* Specify library files to be included in the compilation. */
|
||||
// "allowJs": true, /* Allow javascript files to be compiled. */
|
||||
// "checkJs": true, /* Report errors in .js files. */
|
||||
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
|
||||
// "declaration": true, /* Generates corresponding '.d.ts' file. */
|
||||
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
||||
// "sourceMap": true, /* Generates corresponding '.map' file. */
|
||||
// "outFile": "./", /* Concatenate and emit output to single file. */
|
||||
// "outDir": "./", /* Redirect output structure to the directory. */
|
||||
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
|
||||
// "composite": true, /* Enable project compilation */
|
||||
// "removeComments": true, /* Do not emit comments to output. */
|
||||
// "noEmit": true, /* Do not emit outputs. */
|
||||
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
|
||||
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
|
||||
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true, /* Enable all strict type-checking options. */
|
||||
// "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
|
||||
// "strictNullChecks": true, /* Enable strict null checks. */
|
||||
// "strictFunctionTypes": true, /* Enable strict checking of function types. */
|
||||
// "strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
|
||||
// "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
|
||||
// "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
|
||||
|
||||
/* Additional Checks */
|
||||
// "noUnusedLocals": true, /* Report errors on unused locals. */
|
||||
// "noUnusedParameters": true, /* Report errors on unused parameters. */
|
||||
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
|
||||
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
|
||||
|
||||
/* Module Resolution Options */
|
||||
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
|
||||
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
|
||||
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
|
||||
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
|
||||
// "typeRoots": [], /* List of folders to include type definitions from. */
|
||||
// "types": [], /* Type declaration files to be included in compilation. */
|
||||
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
|
||||
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
|
||||
|
||||
/* Source Map Options */
|
||||
// "sourceRoot": "", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
|
||||
// "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */
|
||||
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
|
||||
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
|
||||
|
||||
/* Experimental Options */
|
||||
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
|
||||
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
|
||||
},
|
||||
"include": ["*.ts"]
|
||||
"target": "es5",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"emitDecoratorMetadata": true,
|
||||
"experimentalDecorators": true,
|
||||
"lib": [ "es2015", "dom" ],
|
||||
"noImplicitAny": true,
|
||||
"suppressImplicitAnyIndexErrors": true
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "2.3",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"typescript": "2.3.0"
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
typescript@2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.3.0.tgz#2e63e09284392bc8158a2444c33e2093795c0418"
|
File diff suppressed because it is too large
Load Diff
@ -39,12 +39,6 @@ ivy-ngcc
|
||||
grep "static ngInjectorDef: ɵngcc0.InjectorDef<ApplicationModule>;" node_modules/@angular/core/src/application_module.d.ts
|
||||
if [[ $? != 0 ]]; then exit 1; fi
|
||||
|
||||
# Did it generate a base factory call for synthesized constructors correctly?
|
||||
grep "const ɵMatTable_BaseFactory = ɵngcc0.ɵgetInheritedFactory(MatTable);" node_modules/@angular/material/esm2015/table.js
|
||||
if [[ $? != 0 ]]; then exit 1; fi
|
||||
grep "const ɵMatTable_BaseFactory = ɵngcc0.ɵgetInheritedFactory(MatTable);" node_modules/@angular/material/esm5/table.es5.js
|
||||
if [[ $? != 0 ]]; then exit 1; fi
|
||||
|
||||
# Can it be safely run again (as a noop)?
|
||||
ivy-ngcc
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
"@angular/animations@file:../../dist/packages-dist/animations":
|
||||
version "7.2.0-rc.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
@ -17,12 +17,12 @@
|
||||
parse5 "^5.0.0"
|
||||
|
||||
"@angular/common@file:../../dist/packages-dist/common":
|
||||
version "0.0.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli":
|
||||
version "0.0.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
canonical-path "1.0.0"
|
||||
chokidar "^1.4.2"
|
||||
@ -37,22 +37,22 @@
|
||||
yargs "9.0.1"
|
||||
|
||||
"@angular/compiler@file:../../dist/packages-dist/compiler":
|
||||
version "7.2.0-rc.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/core@file:../../dist/packages-dist/core":
|
||||
version "0.0.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/forms@file:../../dist/packages-dist/forms":
|
||||
version "0.0.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/http@file:../../dist/packages-dist/http":
|
||||
version "7.2.0-rc.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
@ -66,17 +66,17 @@
|
||||
parse5 "^5.0.0"
|
||||
|
||||
"@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic":
|
||||
version "7.2.0-rc.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/platform-browser@file:../../dist/packages-dist/platform-browser":
|
||||
version "0.0.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
"@angular/router@file:../../dist/packages-dist/router":
|
||||
version "0.0.0"
|
||||
version "7.1.0"
|
||||
dependencies:
|
||||
tslib "^1.9.0"
|
||||
|
||||
@ -3278,7 +3278,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0:
|
||||
integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=
|
||||
|
||||
"typescript@file:../../node_modules/typescript":
|
||||
version "3.2.2"
|
||||
version "3.1.1"
|
||||
|
||||
ua-parser-js@0.7.17:
|
||||
version "0.7.17"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "angular-srcs",
|
||||
"version": "8.0.0-beta.0",
|
||||
"version": "7.2.2",
|
||||
"private": true,
|
||||
"branchPattern": "2.0.*",
|
||||
"description": "Angular - a web framework for modern web apps",
|
||||
@ -36,7 +36,7 @@
|
||||
"@angular-devkit/core": "^7.0.4",
|
||||
"@angular-devkit/schematics": "^7.0.4",
|
||||
"@bazel/karma": "~0.22.1",
|
||||
"@bazel/typescript": "0.22.1-7-g68fed6a",
|
||||
"@bazel/typescript": "~0.22.1",
|
||||
"@schematics/angular": "^7.0.4",
|
||||
"@types/chokidar": "1.7.3",
|
||||
"@types/convert-source-map": "^1.5.1",
|
||||
@ -146,5 +146,9 @@
|
||||
"vlq": "0.2.2",
|
||||
"vrsource-tslint-rules": "5.1.1",
|
||||
"webpack": "1.12.9"
|
||||
},
|
||||
"// 4": "natives is needed for gulp to work with node >= 10.13, see #28213",
|
||||
"resolutions": {
|
||||
"natives": "1.1.6"
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ ng_module(
|
||||
"src/**/*.ts",
|
||||
],
|
||||
),
|
||||
module_name = "@angular/animations",
|
||||
deps = [
|
||||
"//packages/core",
|
||||
],
|
||||
|
@ -12,6 +12,7 @@ ng_module(
|
||||
"src/**/*.ts",
|
||||
],
|
||||
),
|
||||
module_name = "@angular/animations/browser",
|
||||
deps = [
|
||||
"//packages/animations",
|
||||
"//packages/core",
|
||||
|
@ -66,8 +66,8 @@ export class AnimationEngine {
|
||||
this._transitionEngine.insertNode(namespaceId, element, parent, insertBefore);
|
||||
}
|
||||
|
||||
onRemove(namespaceId: string, element: any, context: any, isHostElement?: boolean): void {
|
||||
this._transitionEngine.removeNode(namespaceId, element, isHostElement || false, context);
|
||||
onRemove(namespaceId: string, element: any, context: any): void {
|
||||
this._transitionEngine.removeNode(namespaceId, element, context);
|
||||
}
|
||||
|
||||
disableAnimations(element: any, disable: boolean) {
|
||||
|
@ -708,23 +708,17 @@ export class TransitionAnimationEngine {
|
||||
}
|
||||
}
|
||||
|
||||
removeNode(namespaceId: string, element: any, isHostElement: boolean, context: any): void {
|
||||
if (isElementNode(element)) {
|
||||
const ns = namespaceId ? this._fetchNamespace(namespaceId) : null;
|
||||
if (ns) {
|
||||
ns.removeNode(element, context);
|
||||
} else {
|
||||
this.markElementAsRemoved(namespaceId, element, false, context);
|
||||
}
|
||||
|
||||
if (isHostElement) {
|
||||
const hostNS = this.namespacesByHostElement.get(element);
|
||||
if (hostNS && hostNS.id !== namespaceId) {
|
||||
hostNS.removeNode(element, context);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
removeNode(namespaceId: string, element: any, context: any): void {
|
||||
if (!isElementNode(element)) {
|
||||
this._onRemovalComplete(element, context);
|
||||
return;
|
||||
}
|
||||
|
||||
const ns = namespaceId ? this._fetchNamespace(namespaceId) : null;
|
||||
if (ns) {
|
||||
ns.removeNode(element, context);
|
||||
} else {
|
||||
this.markElementAsRemoved(namespaceId, element, false, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,7 +111,7 @@ const DEFAULT_NAMESPACE_ID = 'id';
|
||||
|
||||
expect(engine.elementContainsData(DEFAULT_NAMESPACE_ID, element)).toBeTruthy();
|
||||
|
||||
engine.removeNode(DEFAULT_NAMESPACE_ID, element, true, true);
|
||||
engine.removeNode(DEFAULT_NAMESPACE_ID, element, true);
|
||||
engine.flush();
|
||||
|
||||
expect(engine.elementContainsData(DEFAULT_NAMESPACE_ID, element)).toBeTruthy();
|
||||
|
@ -7,6 +7,7 @@ load("//tools:defaults.bzl", "ng_module")
|
||||
ng_module(
|
||||
name = "testing",
|
||||
srcs = glob(["**/*.ts"]),
|
||||
module_name = "@angular/animations/browser/testing",
|
||||
deps = [
|
||||
"//packages/animations",
|
||||
"//packages/animations/browser",
|
||||
|
@ -285,8 +285,6 @@ _EXTRA_NODE_OPTIONS_FLAGS = [
|
||||
"--node_options=--expose-gc",
|
||||
# Show ~full stack traces, instead of cutting off after 10 items.
|
||||
"--node_options=--stack-trace-limit=100",
|
||||
# Give 2 GB RAM to node to make bigger google3 modules to compile, we should be able to drop this after Ivy/ngtsc is the default in g3
|
||||
"--node_options=--max-old-space-size=2048",
|
||||
]
|
||||
|
||||
def ngc_compile_action(
|
||||
|
@ -27,19 +27,7 @@ load(
|
||||
load("@build_bazel_rules_nodejs//internal:collect_es6_sources.bzl", collect_es2015_sources = "collect_es6_sources")
|
||||
load(":esm5.bzl", "esm5_outputs_aspect", "esm5_root_dir", "flatten_esm5")
|
||||
|
||||
PACKAGES = [
|
||||
# Generated paths when using ng_rollup_bundle outside this monorepo.
|
||||
"external/angular/packages/core/src",
|
||||
"external/angular/packages/common/src",
|
||||
"external/angular/packages/compiler/src",
|
||||
"external/angular/packages/platform-browser/src",
|
||||
"external/rxjs",
|
||||
# Generated paths when using ng_rollup_bundle inside this monorepo.
|
||||
"packages/core/src",
|
||||
"packages/common/src",
|
||||
"packages/compiler/src",
|
||||
"packages/platform-browser/src",
|
||||
]
|
||||
PACKAGES = ["packages/core/src", "packages/common/src", "packages/compiler/src", "external/rxjs"]
|
||||
PLUGIN_CONFIG = "{sideEffectFreeModules: [\n%s]}" % ",\n".join(
|
||||
[" '.esm5/{0}'".format(p) for p in PACKAGES],
|
||||
)
|
||||
|
@ -1,82 +1,5 @@
|
||||
# Schematics for Bazel
|
||||
|
||||
## WARNING
|
||||
|
||||
Schematics in `@angular/bazel` is still highly experimental as of January 2019,
|
||||
please use with caution. For feedbacks and comments, please open an issue on
|
||||
GitHub and ping [@mgechev](https://github.com/mgechev) or
|
||||
[@kyliau](https://github.com/kyliau).
|
||||
|
||||
## Create a Bazel-managed Angular project
|
||||
|
||||
To create a new Angular project that builds with Bazel, all you need to do is install the `@angular/bazel` package.
|
||||
|
||||
The example below assumes that you have a global installation of Angular CLI.
|
||||
If not, please run `yarn global add @angular/cli`.
|
||||
|
||||
Install the latest `@angular/bazel` for generating Bazel schematics.
|
||||
|
||||
```
|
||||
$ yarn global add @angular/bazel
|
||||
```
|
||||
|
||||
Create a new project using `@angular/bazel` schematics for `ng new`.
|
||||
|
||||
```
|
||||
$ ng new demo --collection=@angular/bazel --defaults
|
||||
```
|
||||
|
||||
In addition to the regular files generated by CLI, the following files that are
|
||||
specific to a Bazel workspace are also created.
|
||||
|
||||
```
|
||||
...
|
||||
CREATE demo/BUILD.bazel (190 bytes)
|
||||
CREATE demo/WORKSPACE (2951 bytes)
|
||||
CREATE demo/.bazelignore (18 bytes)
|
||||
CREATE demo/.bazelrc (828 bytes)
|
||||
CREATE demo/e2e/BUILD.bazel (1230 bytes)
|
||||
CREATE demo/e2e/protractor.on-prepare.js (1101 bytes)
|
||||
CREATE demo/src/BUILD.bazel (2626 bytes)
|
||||
CREATE demo/src/initialize_testbed.ts (432 bytes)
|
||||
CREATE demo/src/main.dev.ts (185 bytes)
|
||||
CREATE demo/src/main.prod.ts (249 bytes)
|
||||
```
|
||||
|
||||
Note that in a Bazel-managed project, there is a Bazel WORKSPACE file and a few BUILD.bazel files.
|
||||
There are also some files specific to a Bazel-managed project, namely `main.dev.ts` and `main.prod.ts`.
|
||||
This is because all Angular projects built with Bazel must be AOT only.
|
||||
In a Bazel project, `main.ts` generated by CLI is not used.
|
||||
|
||||
By default, `ng new` for Bazel does not perform `yarn install`.
|
||||
This is because the `node_modules` are managed by Bazel and it is Bazel's
|
||||
responsibility to perform the install.
|
||||
|
||||
Next, let's try to build the project using Bazel.
|
||||
All existing `ng` commands would work as before.
|
||||
|
||||
```
|
||||
cd demo
|
||||
# The following yarn step is needed so that `ng build` works correctly.
|
||||
# Alternatively, you can skip this step if you choose to not use `ng` commands.
|
||||
# In which case, you'd execute `yarn bazel build //src:bundle`. This is
|
||||
# equivalent to running `ng build`.
|
||||
yarn
|
||||
ng build
|
||||
ng serve
|
||||
```
|
||||
|
||||
If you encounter a warning about version mismatch, update `ANGULAR_VERSION` in
|
||||
the WORKSPACE file to match the version of `@angular/bazel` installed from NPM.
|
||||
|
||||
Bring up the dev server using `ibazel run` command.
|
||||
|
||||
```
|
||||
yarn ibazel run //src:devserver
|
||||
```
|
||||
|
||||
Make some changes to the code, and verify that the dev server automatically refreshes.
|
||||
|
||||
## Development notes
|
||||
|
||||
To test any local changes, run
|
||||
|
@ -91,7 +91,7 @@ Hello
|
||||
|
||||
/**
|
||||
* @license Angular v0.0.0
|
||||
* (c) 2010-2019 Google LLC. https://angular.io/
|
||||
* (c) 2010-2018 Google, Inc. https://angular.io/
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
@ -165,7 +165,7 @@ Hello
|
||||
|
||||
/**
|
||||
* @license Angular v0.0.0
|
||||
* (c) 2010-2019 Google LLC. https://angular.io/
|
||||
* (c) 2010-2018 Google, Inc. https://angular.io/
|
||||
* License: MIT
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core")):"function"==typeof define&&define.amd?define("example/secondary",["exports","@angular/core"],t):t(((e=e||self).example=e.example||{},e.example.secondary={}),e.ng.core)}(this,function(e,t){"use strict";
|
||||
@ -190,7 +190,7 @@ e.SecondaryModule=o,e.a=1,Object.defineProperty(e,"__esModule",{value:!0})});
|
||||
|
||||
/**
|
||||
* @license Angular v0.0.0
|
||||
* (c) 2010-2019 Google LLC. https://angular.io/
|
||||
* (c) 2010-2018 Google, Inc. https://angular.io/
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
@ -262,7 +262,7 @@ e.SecondaryModule=o,e.a=1,Object.defineProperty(e,"__esModule",{value:!0})});
|
||||
|
||||
/**
|
||||
* @license Angular v0.0.0
|
||||
* (c) 2010-2019 Google LLC. https://angular.io/
|
||||
* (c) 2010-2018 Google, Inc. https://angular.io/
|
||||
* License: MIT
|
||||
*/
|
||||
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("@angular/core")):"function"==typeof define&&define.amd?define("example",["exports","@angular/core"],t):t((e=e||self).example={},e.ng.core)}(this,function(e,t){"use strict";
|
||||
@ -502,7 +502,7 @@ export * from './index';
|
||||
|
||||
/**
|
||||
* @license Angular v0.0.0
|
||||
* (c) 2010-2019 Google LLC. https://angular.io/
|
||||
* (c) 2010-2018 Google, Inc. https://angular.io/
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
@ -537,7 +537,7 @@ export { SecondaryModule, a };
|
||||
|
||||
/**
|
||||
* @license Angular v0.0.0
|
||||
* (c) 2010-2019 Google LLC. https://angular.io/
|
||||
* (c) 2010-2018 Google, Inc. https://angular.io/
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
@ -570,7 +570,7 @@ export { MyModule };
|
||||
|
||||
/**
|
||||
* @license Angular v0.0.0
|
||||
* (c) 2010-2019 Google LLC. https://angular.io/
|
||||
* (c) 2010-2018 Google, Inc. https://angular.io/
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
@ -614,7 +614,7 @@ export { SecondaryModule, a };
|
||||
|
||||
/**
|
||||
* @license Angular v0.0.0
|
||||
* (c) 2010-2019 Google LLC. https://angular.io/
|
||||
* (c) 2010-2018 Google, Inc. https://angular.io/
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
@ -749,7 +749,7 @@ export declare const a = 1;
|
||||
|
||||
/**
|
||||
* @license Angular v0.0.0
|
||||
* (c) 2010-2019 Google LLC. https://angular.io/
|
||||
* (c) 2010-2018 Google, Inc. https://angular.io/
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
|
@ -10,6 +10,7 @@ ts_library(
|
||||
"src/**/*.ts",
|
||||
],
|
||||
),
|
||||
module_name = "@angular/benchpress",
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/core",
|
||||
|
@ -10,6 +10,7 @@ ng_module(
|
||||
"src/**/*.ts",
|
||||
],
|
||||
),
|
||||
module_name = "@angular/common",
|
||||
deps = [
|
||||
"//packages/core",
|
||||
"@rxjs",
|
||||
|
@ -12,6 +12,7 @@ ng_module(
|
||||
"src/**/*.ts",
|
||||
],
|
||||
),
|
||||
module_name = "@angular/common/http",
|
||||
deps = [
|
||||
"//packages/common",
|
||||
"//packages/core",
|
||||
|
@ -12,6 +12,7 @@ ng_module(
|
||||
"src/**/*.ts",
|
||||
],
|
||||
),
|
||||
module_name = "@angular/common/http/testing",
|
||||
deps = [
|
||||
"//packages/common/http",
|
||||
"//packages/core",
|
||||
|
@ -8,6 +8,7 @@ ts_library(
|
||||
["**/*.ts"],
|
||||
exclude = ["closure-locale.ts"],
|
||||
),
|
||||
module_name = "@angular/common/locales",
|
||||
)
|
||||
|
||||
npm_package(
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {Directive, DoCheck, EmbeddedViewRef, Input, IterableChangeRecord, IterableChanges, IterableDiffer, IterableDiffers, NgIterable, TemplateRef, TrackByFunction, ViewContainerRef, forwardRef, isDevMode} from '@angular/core';
|
||||
import {ChangeDetectorRef, Directive, DoCheck, EmbeddedViewRef, Input, IterableChangeRecord, IterableChanges, IterableDiffer, IterableDiffers, NgIterable, TemplateRef, TrackByFunction, ViewContainerRef, forwardRef, isDevMode} from '@angular/core';
|
||||
|
||||
/**
|
||||
* @publicApi
|
||||
@ -151,7 +151,7 @@ export class NgForOf<T> implements DoCheck {
|
||||
this._differ = this._differs.find(value).create(this.ngForTrackBy);
|
||||
} catch {
|
||||
throw new Error(
|
||||
`Cannot find a differ supporting object '${value}' of type '${getTypeName(value)}'. NgFor only supports binding to Iterables such as Arrays.`);
|
||||
`Cannot find a differ supporting object '${value}' of type '${getTypeNameForDebugging(value)}'. NgFor only supports binding to Iterables such as Arrays.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -218,6 +218,6 @@ class RecordViewTuple<T> {
|
||||
constructor(public record: any, public view: EmbeddedViewRef<NgForOfContext<T>>) {}
|
||||
}
|
||||
|
||||
function getTypeName(type: any): string {
|
||||
export function getTypeNameForDebugging(type: any): string {
|
||||
return type['name'] || typeof type;
|
||||
}
|
||||
|
@ -12,21 +12,35 @@ import {Directive, DoCheck, ElementRef, Input, KeyValueChanges, KeyValueDiffer,
|
||||
* @ngModule CommonModule
|
||||
*
|
||||
* @usageNotes
|
||||
*
|
||||
* Set the font of the containing element to the result of an expression.
|
||||
*
|
||||
* ```
|
||||
* <some-element [ngStyle]="{'font-style': styleExp}">...</some-element>
|
||||
* ```
|
||||
*
|
||||
* Set the width of the containing element to a pixel value returned by an expression.
|
||||
*
|
||||
* ```
|
||||
* <some-element [ngStyle]="{'max-width.px': widthExp}">...</some-element>
|
||||
* ```
|
||||
*
|
||||
* Set a collection of style values using an expression that returns key-value pairs.
|
||||
*
|
||||
* ```
|
||||
* <some-element [ngStyle]="objExp">...</some-element>
|
||||
* ```
|
||||
*
|
||||
* @description
|
||||
*
|
||||
* Update an HTML element styles.
|
||||
*
|
||||
* The styles are updated according to the value of the expression evaluation:
|
||||
* - keys are style names with an optional `.<unit>` suffix (ie 'top.px', 'font-style.em'),
|
||||
* - values are the values assigned to those properties (expressed in the given unit).
|
||||
* An attribute directive that updates styles for the containing HTML element.
|
||||
* Sets one or more style properties, specified as colon-separated key-value pairs.
|
||||
* The key is a style name, with an optional `.<unit>` suffix
|
||||
* (such as 'top.px', 'font-style.em').
|
||||
* The value is an expression to be evaluated.
|
||||
* The resulting non-null value, expressed in the given unit,
|
||||
* is assigned to the given style property.
|
||||
* If the result of evaluation is null, the corresponding style is removed.
|
||||
*
|
||||
* @publicApi
|
||||
*/
|
||||
@ -41,13 +55,24 @@ export class NgStyle implements DoCheck {
|
||||
private _differs: KeyValueDiffers, private _ngEl: ElementRef, private _renderer: Renderer2) {}
|
||||
|
||||
@Input()
|
||||
set ngStyle(values: {[key: string]: string}) {
|
||||
set ngStyle(
|
||||
/**
|
||||
* A map of style properties, specified as colon-separated
|
||||
* key-value pairs.
|
||||
* * The key is a style name, with an optional `.<unit>` suffix
|
||||
* (such as 'top.px', 'font-style.em').
|
||||
* * The value is an expression to be evaluated.
|
||||
*/
|
||||
values: {[key: string]: string}) {
|
||||
this._ngStyle = values;
|
||||
if (!this._differ && values) {
|
||||
this._differ = this._differs.find(values).create();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the new styles if needed.
|
||||
*/
|
||||
ngDoCheck() {
|
||||
if (this._differ) {
|
||||
const changes = this._differ.diff(this._ngStyle);
|
||||
|
@ -34,20 +34,14 @@ import {Directive, EmbeddedViewRef, Input, OnChanges, SimpleChange, SimpleChange
|
||||
*/
|
||||
@Directive({selector: '[ngTemplateOutlet]'})
|
||||
export class NgTemplateOutlet implements OnChanges {
|
||||
private _viewRef: EmbeddedViewRef<any>|null = null;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
private _viewRef !: EmbeddedViewRef<any>;
|
||||
|
||||
/**
|
||||
* A context object to attach to the {@link EmbeddedViewRef}. This should be an
|
||||
* object, the object's keys will be available for binding by the local template `let`
|
||||
* declarations.
|
||||
* Using the key `$implicit` in the context object will set its value as default.
|
||||
*/
|
||||
@Input() public ngTemplateOutletContext: Object|null = null;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@Input() public ngTemplateOutletContext !: Object;
|
||||
|
||||
/**
|
||||
* A string defining the template reference and optionally the context object for the template.
|
||||
*/
|
||||
@Input() public ngTemplateOutlet: TemplateRef<any>|null = null;
|
||||
// TODO(issue/24571): remove '!'.
|
||||
@Input() public ngTemplateOutlet !: TemplateRef<any>;
|
||||
|
||||
constructor(private _viewContainerRef: ViewContainerRef) {}
|
||||
|
||||
@ -103,7 +97,7 @@ export class NgTemplateOutlet implements OnChanges {
|
||||
|
||||
private _updateExistingContext(ctx: Object): void {
|
||||
for (let propName of Object.keys(ctx)) {
|
||||
(<any>this._viewRef !.context)[propName] = (<any>this.ngTemplateOutletContext)[propName];
|
||||
(<any>this._viewRef.context)[propName] = (<any>this.ngTemplateOutletContext)[propName];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,7 @@ load("//tools:defaults.bzl", "ng_module")
|
||||
ng_module(
|
||||
name = "testing",
|
||||
srcs = glob(["**/*.ts"]),
|
||||
module_name = "@angular/common/testing",
|
||||
deps = [
|
||||
"//packages/common",
|
||||
"//packages/core",
|
||||
|
@ -20,20 +20,17 @@ ts_library(
|
||||
"src/integrationtest/**/*.ts",
|
||||
],
|
||||
),
|
||||
module_name = "@angular/compiler-cli",
|
||||
tsconfig = ":tsconfig",
|
||||
deps = [
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli/src/ngtsc/annotations",
|
||||
"//packages/compiler-cli/src/ngtsc/diagnostics",
|
||||
"//packages/compiler-cli/src/ngtsc/entry_point",
|
||||
"//packages/compiler-cli/src/ngtsc/imports",
|
||||
"//packages/compiler-cli/src/ngtsc/partial_evaluator",
|
||||
"//packages/compiler-cli/src/ngtsc/reflection",
|
||||
"//packages/compiler-cli/src/ngtsc/metadata",
|
||||
"//packages/compiler-cli/src/ngtsc/shims",
|
||||
"//packages/compiler-cli/src/ngtsc/switch",
|
||||
"//packages/compiler-cli/src/ngtsc/transform",
|
||||
"//packages/compiler-cli/src/ngtsc/typecheck",
|
||||
"//packages/compiler-cli/src/ngtsc/util",
|
||||
"@ngdeps//@bazel/typescript",
|
||||
"@ngdeps//@types",
|
||||
"@ngdeps//tsickle",
|
||||
|
@ -24,4 +24,3 @@ export {CompilerOptions as AngularCompilerOptions} from './src/transformers/api'
|
||||
export {NgTools_InternalApi_NG_2 as __NGTOOLS_PRIVATE_API_2} from './src/ngtools_api';
|
||||
|
||||
export {ngToTsDiagnostic} from './src/transformers/util';
|
||||
export {NgTscPlugin} from './src/ngtsc/tsc_plugin';
|
||||
|
@ -9,6 +9,7 @@
|
||||
import {Component, INJECTOR, Injectable, NgModule} from '@angular/core';
|
||||
import {TestBed} from '@angular/core/testing';
|
||||
import {renderModuleFactory} from '@angular/platform-server';
|
||||
import {fixmeIvy} from '@angular/private/testing';
|
||||
import {BasicAppModuleNgFactory} from 'app_built/src/basic.ngfactory';
|
||||
import {DepAppModuleNgFactory} from 'app_built/src/dep.ngfactory';
|
||||
import {HierarchyAppModuleNgFactory} from 'app_built/src/hierarchy.ngfactory';
|
||||
@ -167,20 +168,21 @@ describe('ngInjectableDef Bazel Integration', () => {
|
||||
expect(TestBed.get(INJECTOR).get('foo')).toEqual('bar');
|
||||
});
|
||||
|
||||
it('Component injector understands requests for INJECTABLE', () => {
|
||||
@Component({
|
||||
selector: 'test-cmp',
|
||||
template: 'test',
|
||||
providers: [{provide: 'foo', useValue: 'bar'}],
|
||||
})
|
||||
class TestCmp {
|
||||
}
|
||||
fixmeIvy('FW-854: NodeInjector does not know how to get itself (INJECTOR)')
|
||||
.it('Component injector understands requests for INJECTABLE', () => {
|
||||
@Component({
|
||||
selector: 'test-cmp',
|
||||
template: 'test',
|
||||
providers: [{provide: 'foo', useValue: 'bar'}],
|
||||
})
|
||||
class TestCmp {
|
||||
}
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [TestCmp],
|
||||
});
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [TestCmp],
|
||||
});
|
||||
|
||||
const fixture = TestBed.createComponent(TestCmp);
|
||||
expect(fixture.componentRef.injector.get(INJECTOR).get('foo')).toEqual('bar');
|
||||
});
|
||||
const fixture = TestBed.createComponent(TestCmp);
|
||||
expect(fixture.componentRef.injector.get(INJECTOR).get('foo')).toEqual('bar');
|
||||
});
|
||||
});
|
||||
|
@ -8,13 +8,13 @@ ts_library(
|
||||
"*.ts",
|
||||
"**/*.ts",
|
||||
]),
|
||||
module_name = "@angular/compiler-cli/src/ngcc",
|
||||
deps = [
|
||||
"//packages:types",
|
||||
"//packages/compiler",
|
||||
"//packages/compiler-cli/src/ngtsc/annotations",
|
||||
"//packages/compiler-cli/src/ngtsc/imports",
|
||||
"//packages/compiler-cli/src/ngtsc/partial_evaluator",
|
||||
"//packages/compiler-cli/src/ngtsc/reflection",
|
||||
"//packages/compiler-cli/src/ngtsc/host",
|
||||
"//packages/compiler-cli/src/ngtsc/metadata",
|
||||
"//packages/compiler-cli/src/ngtsc/transform",
|
||||
"//packages/compiler-cli/src/ngtsc/translator",
|
||||
"@ngdeps//@types/convert-source-map",
|
||||
|
@ -11,8 +11,6 @@ import * as fs from 'fs';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {BaseDefDecoratorHandler, ComponentDecoratorHandler, DirectiveDecoratorHandler, InjectableDecoratorHandler, NgModuleDecoratorHandler, PipeDecoratorHandler, ReferencesRegistry, ResourceLoader, SelectorScopeRegistry} from '../../../ngtsc/annotations';
|
||||
import {TsReferenceResolver} from '../../../ngtsc/imports';
|
||||
import {PartialEvaluator} from '../../../ngtsc/partial_evaluator';
|
||||
import {CompileResult, DecoratorHandler} from '../../../ngtsc/transform';
|
||||
import {DecoratedClass} from '../host/decorated_class';
|
||||
import {NgccReflectionHost} from '../host/ngcc_host';
|
||||
@ -46,14 +44,12 @@ export interface MatchingHandler<A, M> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple class that resolves and loads files directly from the filesystem.
|
||||
* `ResourceLoader` which directly uses the filesystem to resolve resources synchronously.
|
||||
*/
|
||||
class NgccResourceLoader implements ResourceLoader {
|
||||
canPreload = false;
|
||||
preload(): undefined|Promise<void> { throw new Error('Not implemented.'); }
|
||||
load(url: string): string { return fs.readFileSync(url, 'utf8'); }
|
||||
resolve(url: string, containingFile: string): string {
|
||||
return path.resolve(path.dirname(containingFile), url);
|
||||
export class FileResourceLoader implements ResourceLoader {
|
||||
load(url: string, containingFile: string): string {
|
||||
url = path.resolve(path.dirname(containingFile), url);
|
||||
return fs.readFileSync(url, 'utf8');
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,41 +57,34 @@ class NgccResourceLoader implements ResourceLoader {
|
||||
* This Analyzer will analyze the files that have decorated classes that need to be transformed.
|
||||
*/
|
||||
export class DecorationAnalyzer {
|
||||
resourceManager = new NgccResourceLoader();
|
||||
resolver = new TsReferenceResolver(this.program, this.typeChecker, this.options, this.host);
|
||||
scopeRegistry = new SelectorScopeRegistry(this.typeChecker, this.reflectionHost, this.resolver);
|
||||
evaluator = new PartialEvaluator(this.reflectionHost, this.typeChecker, this.resolver);
|
||||
resourceLoader = new FileResourceLoader();
|
||||
scopeRegistry = new SelectorScopeRegistry(this.typeChecker, this.host);
|
||||
handlers: DecoratorHandler<any, any>[] = [
|
||||
new BaseDefDecoratorHandler(this.reflectionHost, this.evaluator),
|
||||
new BaseDefDecoratorHandler(this.typeChecker, this.host),
|
||||
new ComponentDecoratorHandler(
|
||||
this.reflectionHost, this.evaluator, this.scopeRegistry, this.isCore, this.resourceManager,
|
||||
this.rootDirs, /* defaultPreserveWhitespaces */ false,
|
||||
/* i18nUseExternalIds */ true),
|
||||
new DirectiveDecoratorHandler(
|
||||
this.reflectionHost, this.evaluator, this.scopeRegistry, this.isCore),
|
||||
new InjectableDecoratorHandler(this.reflectionHost, this.isCore),
|
||||
this.typeChecker, this.host, this.scopeRegistry, this.isCore, this.resourceLoader,
|
||||
this.rootDirs, /* defaultPreserveWhitespaces */ false, /* i18nUseExternalIds */ true),
|
||||
new DirectiveDecoratorHandler(this.typeChecker, this.host, this.scopeRegistry, this.isCore),
|
||||
new InjectableDecoratorHandler(this.host, this.isCore),
|
||||
new NgModuleDecoratorHandler(
|
||||
this.reflectionHost, this.evaluator, this.scopeRegistry, this.referencesRegistry,
|
||||
this.isCore),
|
||||
new PipeDecoratorHandler(this.reflectionHost, this.evaluator, this.scopeRegistry, this.isCore),
|
||||
this.typeChecker, this.host, this.scopeRegistry, this.referencesRegistry, this.isCore),
|
||||
new PipeDecoratorHandler(this.typeChecker, this.host, this.scopeRegistry, this.isCore),
|
||||
];
|
||||
|
||||
constructor(
|
||||
private program: ts.Program, private options: ts.CompilerOptions,
|
||||
private host: ts.CompilerHost, private typeChecker: ts.TypeChecker,
|
||||
private reflectionHost: NgccReflectionHost, private referencesRegistry: ReferencesRegistry,
|
||||
private rootDirs: string[], private isCore: boolean) {}
|
||||
private typeChecker: ts.TypeChecker, private host: NgccReflectionHost,
|
||||
private referencesRegistry: ReferencesRegistry, private rootDirs: string[],
|
||||
private isCore: boolean) {}
|
||||
|
||||
/**
|
||||
* Analyze a program to find all the decorated files should be transformed.
|
||||
*
|
||||
* @param program The program whose files should be analysed.
|
||||
* @returns a map of the source files to the analysis for those files.
|
||||
*/
|
||||
analyzeProgram(): DecorationAnalyses {
|
||||
analyzeProgram(program: ts.Program): DecorationAnalyses {
|
||||
const decorationAnalyses = new DecorationAnalyses();
|
||||
const analysedFiles = this.program.getSourceFiles()
|
||||
.map(sourceFile => this.analyzeFile(sourceFile))
|
||||
.filter(isDefined);
|
||||
const analysedFiles =
|
||||
program.getSourceFiles().map(sourceFile => this.analyzeFile(sourceFile)).filter(isDefined);
|
||||
const compiledFiles = analysedFiles.map(analysedFile => this.compileFile(analysedFile));
|
||||
compiledFiles.forEach(
|
||||
compiledFile => decorationAnalyses.set(compiledFile.sourceFile, compiledFile));
|
||||
@ -103,7 +92,7 @@ export class DecorationAnalyzer {
|
||||
}
|
||||
|
||||
protected analyzeFile(sourceFile: ts.SourceFile): AnalyzedFile|undefined {
|
||||
const decoratedClasses = this.reflectionHost.findDecoratedClasses(sourceFile);
|
||||
const decoratedClasses = this.host.findDecoratedClasses(sourceFile);
|
||||
return decoratedClasses.length ? {
|
||||
sourceFile,
|
||||
analyzedClasses: decoratedClasses.map(clazz => this.analyzeClass(clazz)).filter(isDefined)
|
||||
|
@ -8,8 +8,8 @@
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ReferencesRegistry} from '../../../ngtsc/annotations';
|
||||
import {ResolvedReference} from '../../../ngtsc/imports';
|
||||
import {Declaration} from '../../../ngtsc/reflection';
|
||||
import {Declaration} from '../../../ngtsc/host';
|
||||
import {ResolvedReference} from '../../../ngtsc/metadata';
|
||||
import {NgccReflectionHost} from '../host/ngcc_host';
|
||||
import {isDefined} from '../utils';
|
||||
|
||||
@ -62,8 +62,7 @@ export class ModuleWithProvidersAnalyzer {
|
||||
`The referenced NgModule in ${fn.declaration.getText()} is not a class declaration in the typings program; instead we get ${dtsNgModule.getText()}`);
|
||||
}
|
||||
// Record the usage of the internal module as it needs to become an exported symbol
|
||||
this.referencesRegistry.add(
|
||||
ngModule.node, new ResolvedReference(ngModule.node, fn.ngModule));
|
||||
this.referencesRegistry.add(new ResolvedReference(ngModule.node, fn.ngModule));
|
||||
|
||||
ngModule = {node: dtsNgModule, viaModule: null};
|
||||
}
|
||||
|
@ -8,8 +8,8 @@
|
||||
|
||||
import * as ts from 'typescript';
|
||||
import {ReferencesRegistry} from '../../../ngtsc/annotations';
|
||||
import {Reference, ResolvedReference} from '../../../ngtsc/imports';
|
||||
import {Declaration, ReflectionHost} from '../../../ngtsc/reflection';
|
||||
import {Declaration, ReflectionHost} from '../../../ngtsc/host';
|
||||
import {Reference, ResolvedReference} from '../../../ngtsc/metadata';
|
||||
import {hasNameIdentifier} from '../utils';
|
||||
|
||||
/**
|
||||
@ -29,7 +29,7 @@ export class NgccReferencesRegistry implements ReferencesRegistry {
|
||||
* Only `ResolveReference` references are stored. Other types are ignored.
|
||||
* @param references A collection of references to register.
|
||||
*/
|
||||
add(source: ts.Declaration, ...references: Reference<ts.Declaration>[]): void {
|
||||
add(...references: Reference<ts.Declaration>[]): void {
|
||||
references.forEach(ref => {
|
||||
// Only store resolved references. We are not interested in literals.
|
||||
if (ref instanceof ResolvedReference && hasNameIdentifier(ref.node)) {
|
||||
|
@ -7,10 +7,10 @@
|
||||
*/
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {Declaration} from '../../../ngtsc/reflection';
|
||||
import {ReferencesRegistry} from '../../../ngtsc/annotations';
|
||||
import {Declaration} from '../../../ngtsc/host';
|
||||
import {NgccReflectionHost} from '../host/ngcc_host';
|
||||
import {hasNameIdentifier, isDefined} from '../utils';
|
||||
import {NgccReferencesRegistry} from './ngcc_references_registry';
|
||||
|
||||
export interface ExportInfo {
|
||||
identifier: string;
|
||||
@ -24,8 +24,7 @@ export type PrivateDeclarationsAnalyses = ExportInfo[];
|
||||
* (i.e. on an NgModule) that are not publicly exported via an entry-point.
|
||||
*/
|
||||
export class PrivateDeclarationsAnalyzer {
|
||||
constructor(
|
||||
private host: NgccReflectionHost, private referencesRegistry: NgccReferencesRegistry) {}
|
||||
constructor(private host: NgccReflectionHost, private referencesRegistry: ReferencesRegistry) {}
|
||||
|
||||
analyzeProgram(program: ts.Program): PrivateDeclarationsAnalyses {
|
||||
const rootFiles = this.getRootFiles(program);
|
||||
|
@ -7,7 +7,7 @@
|
||||
*/
|
||||
|
||||
import * as ts from 'typescript';
|
||||
import {Decorator} from '../../../ngtsc/reflection';
|
||||
import {Decorator} from '../../../ngtsc/host';
|
||||
|
||||
/**
|
||||
* A simple container that holds the details of a decorated class that has been
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ClassMember, ClassMemberKind, CtorParameter, Decorator, Import, TypeScriptReflectionHost, reflectObjectLiteral} from '../../../ngtsc/reflection';
|
||||
import {ClassMember, ClassMemberKind, CtorParameter, Decorator, Import} from '../../../ngtsc/host';
|
||||
import {TypeScriptReflectionHost, reflectObjectLiteral} from '../../../ngtsc/metadata';
|
||||
import {BundleProgram} from '../packages/bundle_program';
|
||||
import {findAll, getNameText, isDefined} from '../utils';
|
||||
|
||||
@ -661,10 +662,8 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
*/
|
||||
protected getHelperCall(statement: ts.Statement, helperName: string): ts.CallExpression|null {
|
||||
if (ts.isExpressionStatement(statement)) {
|
||||
let expression = statement.expression;
|
||||
while (isAssignment(expression)) {
|
||||
expression = expression.right;
|
||||
}
|
||||
const expression =
|
||||
isAssignmentStatement(statement) ? statement.expression.right : statement.expression;
|
||||
if (ts.isCallExpression(expression) && getCalleeName(expression) === helperName) {
|
||||
return expression;
|
||||
}
|
||||
@ -802,16 +801,10 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N
|
||||
if (constructorSymbol) {
|
||||
// For some reason the constructor does not have a `valueDeclaration` ?!?
|
||||
const constructor = constructorSymbol.declarations &&
|
||||
constructorSymbol.declarations[0] as ts.ConstructorDeclaration | undefined;
|
||||
if (!constructor) {
|
||||
return [];
|
||||
}
|
||||
if (constructor.parameters.length > 0) {
|
||||
constructorSymbol.declarations[0] as ts.ConstructorDeclaration;
|
||||
if (constructor && constructor.parameters) {
|
||||
return Array.from(constructor.parameters);
|
||||
}
|
||||
if (isSynthesizedConstructor(constructor)) {
|
||||
return null;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
return null;
|
||||
@ -1236,52 +1229,3 @@ function collectExportedDeclarations(
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A constructor function may have been "synthesized" by TypeScript during JavaScript emit,
|
||||
* in the case no user-defined constructor exists and e.g. property initializers are used.
|
||||
* Those initializers need to be emitted into a constructor in JavaScript, so the TypeScript
|
||||
* compiler generates a synthetic constructor.
|
||||
*
|
||||
* We need to identify such constructors as ngcc needs to be able to tell if a class did
|
||||
* originally have a constructor in the TypeScript source. When a class has a superclass,
|
||||
* a synthesized constructor must not be considered as a user-defined constructor as that
|
||||
* prevents a base factory call from being created by ngtsc, resulting in a factory function
|
||||
* that does not inject the dependencies of the superclass. Hence, we identify a default
|
||||
* synthesized super call in the constructor body, according to the structure that TypeScript
|
||||
* emits during JavaScript emit:
|
||||
* https://github.com/Microsoft/TypeScript/blob/v3.2.2/src/compiler/transformers/ts.ts#L1068-L1082
|
||||
*
|
||||
* @param constructor a constructor function to test
|
||||
* @returns true if the constructor appears to have been synthesized
|
||||
*/
|
||||
function isSynthesizedConstructor(constructor: ts.ConstructorDeclaration): boolean {
|
||||
if (!constructor.body) return false;
|
||||
|
||||
const firstStatement = constructor.body.statements[0];
|
||||
if (!firstStatement || !ts.isExpressionStatement(firstStatement)) return false;
|
||||
|
||||
return isSynthesizedSuperCall(firstStatement.expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the expression appears to have been synthesized by TypeScript, i.e. whether
|
||||
* it is of the following form:
|
||||
*
|
||||
* ```
|
||||
* super(...arguments);
|
||||
* ```
|
||||
*
|
||||
* @param expression the expression that is to be tested
|
||||
* @returns true if the expression appears to be a synthesized super call
|
||||
*/
|
||||
function isSynthesizedSuperCall(expression: ts.Expression): boolean {
|
||||
if (!ts.isCallExpression(expression)) return false;
|
||||
if (expression.expression.kind !== ts.SyntaxKind.SuperKeyword) return false;
|
||||
if (expression.arguments.length !== 1) return false;
|
||||
|
||||
const argument = expression.arguments[0];
|
||||
return ts.isSpreadElement(argument) && ts.isIdentifier(argument.expression) &&
|
||||
argument.expression.text === 'arguments';
|
||||
}
|
||||
|
@ -8,7 +8,8 @@
|
||||
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ClassMember, ClassMemberKind, Decorator, FunctionDefinition, Parameter, reflectObjectLiteral} from '../../../ngtsc/reflection';
|
||||
import {ClassMember, ClassMemberKind, Decorator, FunctionDefinition, Parameter} from '../../../ngtsc/host';
|
||||
import {reflectObjectLiteral} from '../../../ngtsc/metadata';
|
||||
import {getNameText} from '../utils';
|
||||
|
||||
import {Esm2015ReflectionHost, ParamInfo, getPropertyValueFromSymbol, isAssignmentStatement} from './esm2015_host';
|
||||
@ -41,24 +42,6 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost {
|
||||
return super.isClass(node) || !!this.getClassSymbol(node);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the given declaration has a base class.
|
||||
*
|
||||
* In ES5, we need to determine if the IIFE wrapper takes a `_super` parameter .
|
||||
*/
|
||||
hasBaseClass(node: ts.Declaration): boolean {
|
||||
const classSymbol = this.getClassSymbol(node);
|
||||
if (!classSymbol) return false;
|
||||
|
||||
const iifeBody = classSymbol.valueDeclaration.parent;
|
||||
if (!iifeBody || !ts.isBlock(iifeBody)) return false;
|
||||
|
||||
const iife = iifeBody.parent;
|
||||
if (!iife || !ts.isFunctionExpression(iife)) return false;
|
||||
|
||||
return iife.parameters.length === 1 && isSuperIdentifier(iife.parameters[0].name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a symbol for a node that we think is a class.
|
||||
*
|
||||
@ -155,15 +138,11 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost {
|
||||
* @returns an array of `ts.ParameterDeclaration` objects representing each of the parameters in
|
||||
* the class's constructor or null if there is no constructor.
|
||||
*/
|
||||
protected getConstructorParameterDeclarations(classSymbol: ts.Symbol):
|
||||
ts.ParameterDeclaration[]|null {
|
||||
protected getConstructorParameterDeclarations(classSymbol: ts.Symbol): ts.ParameterDeclaration[] {
|
||||
const constructor = classSymbol.valueDeclaration as ts.FunctionDeclaration;
|
||||
if (constructor.parameters.length > 0) {
|
||||
if (constructor && constructor.parameters) {
|
||||
return Array.from(constructor.parameters);
|
||||
}
|
||||
if (isSynthesizedConstructor(constructor)) {
|
||||
return null;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -275,147 +254,6 @@ function reflectArrayElement(element: ts.Expression) {
|
||||
return ts.isObjectLiteralExpression(element) ? reflectObjectLiteral(element) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* A constructor function may have been "synthesized" by TypeScript during JavaScript emit,
|
||||
* in the case no user-defined constructor exists and e.g. property initializers are used.
|
||||
* Those initializers need to be emitted into a constructor in JavaScript, so the TypeScript
|
||||
* compiler generates a synthetic constructor.
|
||||
*
|
||||
* We need to identify such constructors as ngcc needs to be able to tell if a class did
|
||||
* originally have a constructor in the TypeScript source. For ES5, we can not tell an
|
||||
* empty constructor apart from a synthesized constructor, but fortunately that does not
|
||||
* matter for the code generated by ngtsc.
|
||||
*
|
||||
* When a class has a superclass however, a synthesized constructor must not be considered
|
||||
* as a user-defined constructor as that prevents a base factory call from being created by
|
||||
* ngtsc, resulting in a factory function that does not inject the dependencies of the
|
||||
* superclass. Hence, we identify a default synthesized super call in the constructor body,
|
||||
* according to the structure that TypeScript's ES2015 to ES5 transformer generates in
|
||||
* https://github.com/Microsoft/TypeScript/blob/v3.2.2/src/compiler/transformers/es2015.ts#L1082-L1098
|
||||
*
|
||||
* @param constructor a constructor function to test
|
||||
* @returns true if the constructor appears to have been synthesized
|
||||
*/
|
||||
function isSynthesizedConstructor(constructor: ts.FunctionDeclaration): boolean {
|
||||
if (!constructor.body) return false;
|
||||
|
||||
const firstStatement = constructor.body.statements[0];
|
||||
if (!firstStatement) return false;
|
||||
|
||||
return isSynthesizedSuperThisAssignment(firstStatement) ||
|
||||
isSynthesizedSuperReturnStatement(firstStatement);
|
||||
}
|
||||
|
||||
/**
|
||||
* Identifies a synthesized super call of the form:
|
||||
*
|
||||
* ```
|
||||
* var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
* ```
|
||||
*
|
||||
* @param statement a statement that may be a synthesized super call
|
||||
* @returns true if the statement looks like a synthesized super call
|
||||
*/
|
||||
function isSynthesizedSuperThisAssignment(statement: ts.Statement): boolean {
|
||||
if (!ts.isVariableStatement(statement)) return false;
|
||||
|
||||
const variableDeclarations = statement.declarationList.declarations;
|
||||
if (variableDeclarations.length !== 1) return false;
|
||||
|
||||
const variableDeclaration = variableDeclarations[0];
|
||||
if (!ts.isIdentifier(variableDeclaration.name) ||
|
||||
!variableDeclaration.name.text.startsWith('_this'))
|
||||
return false;
|
||||
|
||||
const initializer = variableDeclaration.initializer;
|
||||
if (!initializer) return false;
|
||||
|
||||
return isSynthesizedDefaultSuperCall(initializer);
|
||||
}
|
||||
/**
|
||||
* Identifies a synthesized super call of the form:
|
||||
*
|
||||
* ```
|
||||
* return _super !== null && _super.apply(this, arguments) || this;
|
||||
* ```
|
||||
*
|
||||
* @param statement a statement that may be a synthesized super call
|
||||
* @returns true if the statement looks like a synthesized super call
|
||||
*/
|
||||
function isSynthesizedSuperReturnStatement(statement: ts.Statement): boolean {
|
||||
if (!ts.isReturnStatement(statement)) return false;
|
||||
|
||||
const expression = statement.expression;
|
||||
if (!expression) return false;
|
||||
|
||||
return isSynthesizedDefaultSuperCall(expression);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the expression is of the form:
|
||||
*
|
||||
* ```
|
||||
* _super !== null && _super.apply(this, arguments) || this;
|
||||
* ```
|
||||
*
|
||||
* This structure is generated by TypeScript when transforming ES2015 to ES5, see
|
||||
* https://github.com/Microsoft/TypeScript/blob/v3.2.2/src/compiler/transformers/es2015.ts#L1148-L1163
|
||||
*
|
||||
* @param expression an expression that may represent a default super call
|
||||
* @returns true if the expression corresponds with the above form
|
||||
*/
|
||||
function isSynthesizedDefaultSuperCall(expression: ts.Expression): boolean {
|
||||
if (!isBinaryExpr(expression, ts.SyntaxKind.BarBarToken)) return false;
|
||||
if (expression.right.kind !== ts.SyntaxKind.ThisKeyword) return false;
|
||||
|
||||
const left = expression.left;
|
||||
if (!isBinaryExpr(left, ts.SyntaxKind.AmpersandAmpersandToken)) return false;
|
||||
|
||||
return isSuperNotNull(left.left) && isSuperApplyCall(left.right);
|
||||
}
|
||||
|
||||
function isSuperNotNull(expression: ts.Expression): boolean {
|
||||
return isBinaryExpr(expression, ts.SyntaxKind.ExclamationEqualsEqualsToken) &&
|
||||
isSuperIdentifier(expression.left);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the expression is of the form
|
||||
*
|
||||
* ```
|
||||
* _super.apply(this, arguments)
|
||||
* ```
|
||||
*
|
||||
* @param expression an expression that may represent a default super call
|
||||
* @returns true if the expression corresponds with the above form
|
||||
*/
|
||||
function isSuperApplyCall(expression: ts.Expression): boolean {
|
||||
if (!ts.isCallExpression(expression) || expression.arguments.length !== 2) return false;
|
||||
|
||||
const targetFn = expression.expression;
|
||||
if (!ts.isPropertyAccessExpression(targetFn)) return false;
|
||||
if (!isSuperIdentifier(targetFn.expression)) return false;
|
||||
if (targetFn.name.text !== 'apply') return false;
|
||||
|
||||
const thisArgument = expression.arguments[0];
|
||||
if (thisArgument.kind !== ts.SyntaxKind.ThisKeyword) return false;
|
||||
|
||||
const argumentsArgument = expression.arguments[1];
|
||||
return ts.isIdentifier(argumentsArgument) && argumentsArgument.text === 'arguments';
|
||||
}
|
||||
|
||||
function isBinaryExpr(
|
||||
expression: ts.Expression, operator: ts.BinaryOperator): expression is ts.BinaryExpression {
|
||||
return ts.isBinaryExpression(expression) && expression.operatorToken.kind === operator;
|
||||
}
|
||||
|
||||
function isSuperIdentifier(node: ts.Node): boolean {
|
||||
// Verify that the identifier is prefixed with `_super`. We don't test for equivalence
|
||||
// as TypeScript may have suffixed the name, e.g. `_super_1` to avoid name conflicts.
|
||||
// Requiring only a prefix should be sufficiently accurate.
|
||||
return ts.isIdentifier(node) && node.text.startsWith('_super');
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the statement to extract the ESM5 parameter initializer if there is one.
|
||||
* If one is found, add it to the appropriate parameter in the `parameters` collection.
|
||||
|
@ -6,7 +6,7 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
import * as ts from 'typescript';
|
||||
import {ReflectionHost} from '../../../ngtsc/reflection';
|
||||
import {ReflectionHost} from '../../../ngtsc/host';
|
||||
import {DecoratedClass} from './decorated_class';
|
||||
|
||||
export const PRE_R3_MARKER = '__PRE_R3__';
|
||||
|
@ -19,8 +19,6 @@ import * as ts from 'typescript';
|
||||
*/
|
||||
export interface BundleProgram {
|
||||
program: ts.Program;
|
||||
options: ts.CompilerOptions;
|
||||
host: ts.CompilerHost;
|
||||
path: string;
|
||||
file: ts.SourceFile;
|
||||
r3SymbolsPath: string|null;
|
||||
@ -39,7 +37,7 @@ export function makeBundleProgram(
|
||||
const file = program.getSourceFile(path) !;
|
||||
const r3SymbolsFile = r3SymbolsPath && program.getSourceFile(r3SymbolsPath) || null;
|
||||
|
||||
return {program, options, host, path, file, r3SymbolsPath, r3SymbolsFile};
|
||||
return {program, path, file, r3SymbolsPath, r3SymbolsFile};
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -110,9 +110,8 @@ export class Transformer {
|
||||
const switchMarkerAnalyses = switchMarkerAnalyzer.analyzeProgram(bundle.src.program);
|
||||
|
||||
const decorationAnalyzer = new DecorationAnalyzer(
|
||||
bundle.src.program, bundle.src.options, bundle.src.host, typeChecker, reflectionHost,
|
||||
referencesRegistry, bundle.rootDirs, isCore);
|
||||
const decorationAnalyses = decorationAnalyzer.analyzeProgram();
|
||||
typeChecker, reflectionHost, referencesRegistry, bundle.rootDirs, isCore);
|
||||
const decorationAnalyses = decorationAnalyzer.analyzeProgram(bundle.src.program);
|
||||
|
||||
const moduleWithProvidersAnalyzer =
|
||||
bundle.dts && new ModuleWithProvidersAnalyzer(reflectionHost, referencesRegistry);
|
||||
|
@ -0,0 +1,22 @@
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ImportManager} from '../../../ngtsc/translator';
|
||||
|
||||
export class NgccImportManager extends ImportManager {
|
||||
constructor(private isFlat: boolean, isCore: boolean, prefix?: string) { super(isCore, prefix); }
|
||||
|
||||
generateNamedImport(moduleName: string, symbol: string):
|
||||
{moduleImport: string | null, symbol: string} {
|
||||
if (this.isFlat && this.isCore && moduleName === '@angular/core') {
|
||||
return {moduleImport: null, symbol: this.rewriteSymbol(moduleName, symbol)};
|
||||
}
|
||||
return super.generateNamedImport(moduleName, symbol);
|
||||
}
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
|
||||
/**
|
||||
* @license
|
||||
* Copyright Google Inc. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by an MIT-style license that can be
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ImportRewriter, validateAndRewriteCoreSymbol} from '../../../ngtsc/imports';
|
||||
|
||||
export class NgccFlatImportRewriter implements ImportRewriter {
|
||||
shouldImportSymbol(symbol: string, specifier: string): boolean {
|
||||
if (specifier === '@angular/core') {
|
||||
// Don't use imports for @angular/core symbols in a flat bundle, as they'll be visible
|
||||
// directly.
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
rewriteSymbol(symbol: string, specifier: string): string {
|
||||
if (specifier === '@angular/core') {
|
||||
return validateAndRewriteCoreSymbol(symbol);
|
||||
} else {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
|
||||
rewriteSpecifier(originalModulePath: string, inContextOfFile: string): string {
|
||||
return originalModulePath;
|
||||
}
|
||||
}
|
@ -13,10 +13,10 @@ import {basename, dirname, relative, resolve} from 'canonical-path';
|
||||
import {SourceMapConsumer, SourceMapGenerator, RawSourceMap} from 'source-map';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {NoopImportRewriter, ImportRewriter, R3SymbolsImportRewriter} from '@angular/compiler-cli/src/ngtsc/imports';
|
||||
import {Decorator} from '../../../ngtsc/host';
|
||||
import {CompileResult} from '@angular/compiler-cli/src/ngtsc/transform';
|
||||
import {translateStatement, translateType, ImportManager} from '../../../ngtsc/translator';
|
||||
import {NgccFlatImportRewriter} from './ngcc_import_rewriter';
|
||||
import {NgccImportManager} from './ngcc_import_manager';
|
||||
import {CompiledClass, CompiledFile, DecorationAnalyses} from '../analysis/decoration_analyzer';
|
||||
import {ModuleWithProvidersInfo, ModuleWithProvidersAnalyses} from '../analysis/module_with_providers_analyzer';
|
||||
import {PrivateDeclarationsAnalyses, ExportInfo} from '../analysis/private_declarations_analyzer';
|
||||
@ -136,8 +136,7 @@ export abstract class Renderer {
|
||||
}
|
||||
|
||||
if (compiledFile) {
|
||||
const importManager = new ImportManager(
|
||||
this.getImportRewriter(this.bundle.src.r3SymbolsFile, this.bundle.isFlat), IMPORT_PREFIX);
|
||||
const importManager = new NgccImportManager(this.bundle.isFlat, this.isCore, IMPORT_PREFIX);
|
||||
|
||||
// TODO: remove constructor param metadata and property decorators (we need info from the
|
||||
// handlers to do this)
|
||||
@ -154,7 +153,9 @@ export abstract class Renderer {
|
||||
renderConstantPool(compiledFile.sourceFile, compiledFile.constantPool, importManager),
|
||||
compiledFile.sourceFile);
|
||||
|
||||
this.addImports(outputText, importManager.getAllImports(compiledFile.sourceFile.fileName));
|
||||
this.addImports(
|
||||
outputText, importManager.getAllImports(
|
||||
compiledFile.sourceFile.fileName, this.bundle.src.r3SymbolsFile));
|
||||
}
|
||||
|
||||
// Add exports to the entry-point file
|
||||
@ -169,8 +170,7 @@ export abstract class Renderer {
|
||||
renderDtsFile(dtsFile: ts.SourceFile, renderInfo: DtsRenderInfo): FileInfo[] {
|
||||
const input = this.extractSourceMap(dtsFile);
|
||||
const outputText = new MagicString(input.source);
|
||||
const importManager = new ImportManager(
|
||||
this.getImportRewriter(this.bundle.dts !.r3SymbolsFile, false), IMPORT_PREFIX);
|
||||
const importManager = new NgccImportManager(false, this.isCore, IMPORT_PREFIX);
|
||||
|
||||
renderInfo.classInfo.forEach(dtsClass => {
|
||||
const endOfClass = dtsClass.dtsDeclaration.getEnd();
|
||||
@ -182,7 +182,8 @@ export abstract class Renderer {
|
||||
});
|
||||
|
||||
this.addModuleWithProvidersParams(outputText, renderInfo.moduleWithProviders, importManager);
|
||||
this.addImports(outputText, importManager.getAllImports(dtsFile.fileName));
|
||||
this.addImports(
|
||||
outputText, importManager.getAllImports(dtsFile.fileName, this.bundle.dts !.r3SymbolsFile));
|
||||
|
||||
this.addExports(outputText, dtsFile.fileName, renderInfo.privateExports);
|
||||
|
||||
@ -199,7 +200,7 @@ export abstract class Renderer {
|
||||
*/
|
||||
protected addModuleWithProvidersParams(
|
||||
outputText: MagicString, moduleWithProviders: ModuleWithProvidersInfo[],
|
||||
importManager: ImportManager): void {
|
||||
importManager: NgccImportManager): void {
|
||||
moduleWithProviders.forEach(info => {
|
||||
const ngModuleName = (info.ngModule.node as ts.ClassDeclaration).name !.text;
|
||||
const declarationFile = info.declaration.getSourceFile().fileName;
|
||||
@ -417,16 +418,6 @@ export abstract class Renderer {
|
||||
return (
|
||||
id && id.name === 'ModuleWithProviders' && (this.isCore || id.from === '@angular/core'));
|
||||
}
|
||||
|
||||
private getImportRewriter(r3SymbolsFile: ts.SourceFile|null, isFlat: boolean): ImportRewriter {
|
||||
if (this.isCore && isFlat) {
|
||||
return new NgccFlatImportRewriter();
|
||||
} else if (this.isCore) {
|
||||
return new R3SymbolsImportRewriter(r3SymbolsFile !.fileName);
|
||||
} else {
|
||||
return new NoopImportRewriter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -461,7 +452,7 @@ export function mergeSourceMaps(
|
||||
* Render the constant pool as source code for the given class.
|
||||
*/
|
||||
export function renderConstantPool(
|
||||
sourceFile: ts.SourceFile, constantPool: ConstantPool, imports: ImportManager): string {
|
||||
sourceFile: ts.SourceFile, constantPool: ConstantPool, imports: NgccImportManager): string {
|
||||
const printer = ts.createPrinter();
|
||||
return constantPool.statements.map(stmt => translateStatement(stmt, imports))
|
||||
.map(stmt => printer.printNode(ts.EmitHint.Unspecified, stmt, sourceFile))
|
||||
@ -477,7 +468,7 @@ export function renderConstantPool(
|
||||
* @param imports An object that tracks the imports that are needed by the rendered definitions.
|
||||
*/
|
||||
export function renderDefinitions(
|
||||
sourceFile: ts.SourceFile, compiledClass: CompiledClass, imports: ImportManager): string {
|
||||
sourceFile: ts.SourceFile, compiledClass: CompiledClass, imports: NgccImportManager): string {
|
||||
const printer = ts.createPrinter();
|
||||
const name = (compiledClass.declaration as ts.NamedDeclaration).name !;
|
||||
const definitions =
|
||||
|
@ -10,9 +10,8 @@ ts_library(
|
||||
]),
|
||||
deps = [
|
||||
"//packages/compiler-cli/src/ngcc",
|
||||
"//packages/compiler-cli/src/ngtsc/imports",
|
||||
"//packages/compiler-cli/src/ngtsc/partial_evaluator",
|
||||
"//packages/compiler-cli/src/ngtsc/reflection",
|
||||
"//packages/compiler-cli/src/ngtsc/host",
|
||||
"//packages/compiler-cli/src/ngtsc/metadata",
|
||||
"//packages/compiler-cli/src/ngtsc/testing",
|
||||
"//packages/compiler-cli/src/ngtsc/transform",
|
||||
"@ngdeps//@types/convert-source-map",
|
||||
|
@ -7,12 +7,13 @@
|
||||
*/
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {Decorator} from '../../../ngtsc/reflection';
|
||||
import {Decorator} from '../../../ngtsc/host';
|
||||
import {DecoratorHandler} from '../../../ngtsc/transform';
|
||||
import {DecorationAnalyses, DecorationAnalyzer} from '../../src/analysis/decoration_analyzer';
|
||||
import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry';
|
||||
import {Esm2015ReflectionHost} from '../../src/host/esm2015_host';
|
||||
import {makeTestBundleProgram} from '../helpers/utils';
|
||||
|
||||
import {makeTestProgram} from '../helpers/utils';
|
||||
|
||||
const TEST_PROGRAM = {
|
||||
name: 'test.js',
|
||||
@ -83,17 +84,14 @@ describe('DecorationAnalyzer', () => {
|
||||
let result: DecorationAnalyses;
|
||||
|
||||
beforeEach(() => {
|
||||
const {options, host, ...bundle} = makeTestBundleProgram([TEST_PROGRAM]);
|
||||
program = bundle.program;
|
||||
|
||||
const reflectionHost = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
||||
const referencesRegistry = new NgccReferencesRegistry(reflectionHost);
|
||||
const analyzer = new DecorationAnalyzer(
|
||||
program, options, host, program.getTypeChecker(), reflectionHost, referencesRegistry,
|
||||
[''], false);
|
||||
program = makeTestProgram(TEST_PROGRAM);
|
||||
const host = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
||||
const referencesRegistry = new NgccReferencesRegistry(host);
|
||||
const analyzer =
|
||||
new DecorationAnalyzer(program.getTypeChecker(), host, referencesRegistry, [''], false);
|
||||
testHandler = createTestHandler();
|
||||
analyzer.handlers = [testHandler];
|
||||
result = analyzer.analyzeProgram();
|
||||
result = analyzer.analyzeProgram(program);
|
||||
});
|
||||
|
||||
it('should return an object containing a reference to the original source file', () => {
|
||||
@ -129,15 +127,14 @@ describe('DecorationAnalyzer', () => {
|
||||
// is not yet solved.
|
||||
it('should analyze an internally imported component, which is not publicly exported from the entry-point',
|
||||
() => {
|
||||
const {program, options, host} = makeTestBundleProgram(INTERNAL_COMPONENT_PROGRAM);
|
||||
const reflectionHost = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
||||
const referencesRegistry = new NgccReferencesRegistry(reflectionHost);
|
||||
const program = makeTestProgram(...INTERNAL_COMPONENT_PROGRAM);
|
||||
const host = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
||||
const referencesRegistry = new NgccReferencesRegistry(host);
|
||||
const analyzer = new DecorationAnalyzer(
|
||||
program, options, host, program.getTypeChecker(), reflectionHost, referencesRegistry,
|
||||
[''], false);
|
||||
program.getTypeChecker(), host, referencesRegistry, [''], false);
|
||||
const testHandler = createTestHandler();
|
||||
analyzer.handlers = [testHandler];
|
||||
const result = analyzer.analyzeProgram();
|
||||
const result = analyzer.analyzeProgram(program);
|
||||
const file = program.getSourceFile('component.js') !;
|
||||
const analysis = result.get(file) !;
|
||||
expect(analysis).toBeDefined();
|
||||
@ -147,15 +144,14 @@ describe('DecorationAnalyzer', () => {
|
||||
});
|
||||
|
||||
it('should analyze an internally defined component, which is not exported at all', () => {
|
||||
const {program, options, host} = makeTestBundleProgram(INTERNAL_COMPONENT_PROGRAM);
|
||||
const reflectionHost = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
||||
const referencesRegistry = new NgccReferencesRegistry(reflectionHost);
|
||||
const analyzer = new DecorationAnalyzer(
|
||||
program, options, host, program.getTypeChecker(), reflectionHost, referencesRegistry,
|
||||
[''], false);
|
||||
const program = makeTestProgram(...INTERNAL_COMPONENT_PROGRAM);
|
||||
const host = new Esm2015ReflectionHost(false, program.getTypeChecker());
|
||||
const referencesRegistry = new NgccReferencesRegistry(host);
|
||||
const analyzer =
|
||||
new DecorationAnalyzer(program.getTypeChecker(), host, referencesRegistry, [''], false);
|
||||
const testHandler = createTestHandler();
|
||||
analyzer.handlers = [testHandler];
|
||||
const result = analyzer.analyzeProgram();
|
||||
const result = analyzer.analyzeProgram(program);
|
||||
const file = program.getSourceFile('entrypoint.js') !;
|
||||
const analysis = result.get(file) !;
|
||||
expect(analysis).toBeDefined();
|
||||
|
@ -6,9 +6,9 @@
|
||||
* found in the LICENSE file at https://angular.io/license
|
||||
*/
|
||||
|
||||
import {ResolvedReference} from '@angular/compiler-cli/src/ngtsc/metadata';
|
||||
import * as ts from 'typescript';
|
||||
|
||||
import {ResolvedReference} from '../../../ngtsc/imports';
|
||||
import {NgccReferencesRegistry} from '../../src/analysis/ngcc_references_registry';
|
||||
import {PrivateDeclarationsAnalyzer} from '../../src/analysis/private_declarations_analyzer';
|
||||
import {Esm2015ReflectionHost} from '../../src/host/esm2015_host';
|
||||
@ -137,18 +137,15 @@ describe('PrivateDeclarationsAnalyzer', () => {
|
||||
const publicComponentDeclaration =
|
||||
getDeclaration(program, '/src/a.js', 'PublicComponent', ts.isClassDeclaration);
|
||||
referencesRegistry.add(
|
||||
null !,
|
||||
new ResolvedReference(publicComponentDeclaration, publicComponentDeclaration.name !));
|
||||
const privateComponentDeclaration =
|
||||
getDeclaration(program, '/src/b.js', 'PrivateComponent', ts.isClassDeclaration);
|
||||
referencesRegistry.add(
|
||||
null !, new ResolvedReference(
|
||||
privateComponentDeclaration, privateComponentDeclaration.name !));
|
||||
referencesRegistry.add(new ResolvedReference(
|
||||
privateComponentDeclaration, privateComponentDeclaration.name !));
|
||||
const internalComponentDeclaration =
|
||||
getDeclaration(program, '/src/c.js', 'InternalComponent', ts.isClassDeclaration);
|
||||
referencesRegistry.add(
|
||||
null !, new ResolvedReference(
|
||||
internalComponentDeclaration, internalComponentDeclaration.name !));
|
||||
referencesRegistry.add(new ResolvedReference(
|
||||
internalComponentDeclaration, internalComponentDeclaration.name !));
|
||||
|
||||
const analyses = analyzer.analyzeProgram(program);
|
||||
expect(analyses.length).toEqual(2);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user