diff --git a/integration/ngcc/package.json b/integration/ngcc/package.json index facabdb2f9..ee0bd13c77 100644 --- a/integration/ngcc/package.json +++ b/integration/ngcc/package.json @@ -4,13 +4,13 @@ "license": "MIT", "dependencies": { "@angular/animations": "file:../../dist/packages-dist/animations", - "@angular/cdk": "^7.0.0-rc.1", + "@angular/cdk": "^8.0.0", "@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/forms": "file:../../dist/packages-dist/forms", - "@angular/material": "7.0.0-rc.1", + "@angular/material": "8.0.0", "@angular/platform-browser": "file:../../dist/packages-dist/platform-browser", "@angular/platform-browser-dynamic": "file:../../dist/packages-dist/platform-browser-dynamic", "@angular/router": "file:../../dist/packages-dist/router", diff --git a/integration/ngcc/test.sh b/integration/ngcc/test.sh index 6f573e5ed8..741010b2d8 100755 --- a/integration/ngcc/test.sh +++ b/integration/ngcc/test.sh @@ -61,6 +61,12 @@ 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 +# Did it generate a base definition for undecorated classes with inputs and view queries? +grep "_MatMenuBase.ngBaseDef = ɵngcc0.ɵɵdefineBase({ inputs: {" node_modules/@angular/material/esm2015/menu.js +if [[ $? != 0 ]]; then exit 1; fi +grep "_MatMenuBase.ngBaseDef = ɵngcc0.ɵɵdefineBase({ inputs: {" node_modules/@angular/material/esm5/menu.es5.js +if [[ $? != 0 ]]; then exit 1; fi + # Can it be safely run again (as a noop)? # And check that it logged skipping compilation as expected ivy-ngcc -l debug | grep 'Skipping' diff --git a/integration/ngcc/yarn.lock b/integration/ngcc/yarn.lock index 5b6056513c..d9f777eec8 100644 --- a/integration/ngcc/yarn.lock +++ b/integration/ngcc/yarn.lock @@ -3,26 +3,26 @@ "@angular/animations@file:../../dist/packages-dist/animations": - version "8.0.0-beta.10" + version "8.1.0-beta.0" dependencies: tslib "^1.9.0" -"@angular/cdk@^7.0.0-rc.1": - version "7.0.2" - resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-7.0.2.tgz#35081cd27a8f5214568b6ad1acf8cb3b3c315f99" - integrity sha512-MAugJsjQ3ye2RX7vNjd9IN1c7enAxJaCz9UZBFuzfo/pNxvjaEObFmF2NUKyU1DctknqjyOzZYYg0e+bBxrBbQ== +"@angular/cdk@^8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-8.0.0.tgz#34ca95e71d71780b29b5ba07318c88c4577bdc25" + integrity sha512-2vsRWEHNARe0iRmqgzvM67gwfRy+aKvdef4Qu9L+ndSsTrrZT3tSgG8SMn1v9SfBHnx5G8mo4d1AMquXG69AuQ== dependencies: tslib "^1.7.1" optionalDependencies: parse5 "^5.0.0" "@angular/common@file:../../dist/packages-dist/common": - version "8.0.0-beta.10" + version "8.1.0-beta.0" dependencies: tslib "^1.9.0" "@angular/compiler-cli@file:../../dist/packages-dist/compiler-cli": - version "8.0.0-beta.10" + version "8.1.0-beta.0" dependencies: canonical-path "1.0.0" chokidar "^2.1.1" @@ -34,44 +34,42 @@ shelljs "^0.8.1" source-map "^0.6.1" tslib "^1.9.0" - yargs "9.0.1" + yargs "13.1.0" "@angular/compiler@file:../../dist/packages-dist/compiler": - version "8.0.0-beta.10" + version "8.1.0-beta.0" dependencies: tslib "^1.9.0" "@angular/core@file:../../dist/packages-dist/core": - version "8.0.0-beta.10" + version "8.1.0-beta.0" dependencies: tslib "^1.9.0" "@angular/forms@file:../../dist/packages-dist/forms": - version "8.0.0-beta.10" + version "8.1.0-beta.0" dependencies: tslib "^1.9.0" -"@angular/material@7.0.0-rc.1": - version "7.0.0-rc.1" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-7.0.0-rc.1.tgz#e9a88c8b6f6b48b87ed3d1da3037d14a0e3e8290" - integrity sha512-4LC3y5ZorNjdF1lEkVN/3zwOEnBwjfWLCY92tA06Kdvs1yENZdu0fGTRwcu9Hz4y+t84sL/KEKC9VjKN3Z7PSg== +"@angular/material@8.0.0": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-8.0.0.tgz#21dd15c318d1e29eb4d1a2dd888ddb027897eb49" + integrity sha512-c7O7GhZd46xF2WB6T/YPam5lJkTgQLdIS53IqwZIFhL427+SEfPvejVzRnVfZCI3NdrKiWt/5VsvtQZwWzlGvw== dependencies: tslib "^1.7.1" - optionalDependencies: - parse5 "^5.0.0" "@angular/platform-browser-dynamic@file:../../dist/packages-dist/platform-browser-dynamic": - version "8.0.0-beta.10" + version "8.1.0-beta.0" dependencies: tslib "^1.9.0" "@angular/platform-browser@file:../../dist/packages-dist/platform-browser": - version "8.0.0-beta.10" + version "8.1.0-beta.0" dependencies: tslib "^1.9.0" "@angular/router@file:../../dist/packages-dist/router": - version "8.0.0-beta.10" + version "8.1.0-beta.0" dependencies: tslib "^1.9.0" @@ -150,6 +148,11 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= +ansi-regex@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" + integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== + ansi-styles@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" @@ -517,10 +520,10 @@ camelcase@^3.0.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0= +camelcase@^5.0.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== canonical-path@1.0.0: version "1.0.0" @@ -617,6 +620,15 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + integrity sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ== + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -735,12 +747,14 @@ core-util-is@1.0.2, core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= +cross-spawn@^6.0.0: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== dependencies: - lru-cache "^4.0.1" + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" shebang-command "^1.2.0" which "^1.2.9" @@ -777,7 +791,7 @@ debug@^3.1.0: dependencies: ms "^2.1.1" -decamelize@^1.1.1: +decamelize@^1.1.1, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -889,11 +903,23 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= +emoji-regex@^7.0.1: + version "7.0.3" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" + integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== + encodeurl@~1.0.1, encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= +end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + integrity sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q== + dependencies: + once "^1.4.0" + engine.io-client@~3.2.0: version "3.2.1" resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-3.2.1.tgz#6f54c0475de487158a1a7c77d10178708b6add36" @@ -973,13 +999,13 @@ eventemitter3@1.x.x: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" integrity sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg= -execa@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" - integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= +execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== dependencies: - cross-spawn "^5.0.1" - get-stream "^3.0.0" + cross-spawn "^6.0.0" + get-stream "^4.0.0" is-stream "^1.1.0" npm-run-path "^2.0.0" p-finally "^1.0.0" @@ -1126,12 +1152,12 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= +find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== dependencies: - locate-path "^2.0.0" + locate-path "^3.0.0" follow-redirects@^1.2.5: version "1.5.9" @@ -1234,10 +1260,17 @@ get-caller-file@^1.0.1: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== -get-stream@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" - integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= +get-caller-file@^2.0.1: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" @@ -1487,6 +1520,11 @@ invert-kv@^1.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= +invert-kv@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" + integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== + is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" @@ -1840,6 +1878,13 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" +lcid@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" + integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== + dependencies: + invert-kv "^2.0.0" + lie@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" @@ -1874,16 +1919,6 @@ load-json-file@^1.0.0: pinkie-promise "^2.0.0" strip-bom "^2.0.0" -load-json-file@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-2.0.0.tgz#7947e42149af80d696cbf797bcaabcfe1fe29ca8" - integrity sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg= - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - strip-bom "^3.0.0" - localtunnel@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.9.1.tgz#1d1737eab658add5a40266d8e43f389b646ee3b1" @@ -1894,12 +1929,12 @@ localtunnel@1.9.1: openurl "1.1.1" yargs "6.6.0" -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= +locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== dependencies: - p-locate "^2.0.0" + p-locate "^3.0.0" path-exists "^3.0.0" lodash.debounce@^4.0.8: @@ -1917,14 +1952,6 @@ lodash@^4.11.1, lodash@^4.17.10, lodash@^4.5.1: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== -lru-cache@^4.0.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" - integrity sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - magic-string@^0.25.0: version "0.25.1" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.1.tgz#b1c248b399cd7485da0fe7385c2fc7011843266e" @@ -1932,6 +1959,13 @@ magic-string@^0.25.0: dependencies: sourcemap-codec "^1.4.1" +map-age-cleaner@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" @@ -1949,12 +1983,14 @@ math-random@^1.0.1: resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" integrity sha1-izqsWIuKZuSXXjzepn97sylgH6w= -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= +mem@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" + integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== dependencies: - mimic-fn "^1.0.0" + map-age-cleaner "^0.1.1" + mimic-fn "^2.0.0" + p-is-promise "^2.0.0" micromatch@2.3.11: version "2.3.11" @@ -2011,10 +2047,10 @@ mime@1.4.1: resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" integrity sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ== -mimic-fn@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" - integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ== +mimic-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== minimatch@^3.0.2, minimatch@^3.0.4: version "3.0.4" @@ -2124,6 +2160,11 @@ negotiator@0.6.1: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= +nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + node-pre-gyp@^0.10.0: version "0.10.3" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" @@ -2263,7 +2304,7 @@ on-finished@~2.3.0: dependencies: ee-first "1.1.1" -once@^1.3.0: +once@^1.3.0, once@^1.3.1, once@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= @@ -2302,14 +2343,14 @@ os-locale@^1.4.0: dependencies: lcid "^1.0.0" -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== +os-locale@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" + integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" + execa "^1.0.0" + lcid "^2.0.0" + mem "^4.0.0" os-tmpdir@^1.0.0, os-tmpdir@~1.0.1: version "1.0.2" @@ -2324,29 +2365,39 @@ osenv@^0.1.4: os-homedir "^1.0.0" os-tmpdir "^1.0.0" +p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" +p-is-promise@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" + integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= +p-limit@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.0.tgz#417c9941e6027a9abcba5092dd2904e255b5fbc2" + integrity sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ== dependencies: - p-limit "^1.1.0" + p-try "^2.0.0" -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= +p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== pako@~1.0.2: version "1.0.10" @@ -2426,7 +2477,7 @@ path-is-inside@^1.0.1: resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= -path-key@^2.0.0: +path-key@^2.0.0, path-key@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= @@ -2445,13 +2496,6 @@ path-type@^1.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -path-type@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-2.0.0.tgz#f012ccb8415b7096fc2daa1054c3d72389594c73" - integrity sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM= - dependencies: - pify "^2.0.0" - performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -2516,16 +2560,19 @@ process-nextick-args@~2.0.0: webdriver-js-extender "2.1.0" webdriver-manager "^12.0.6" -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM= - psl@^1.1.24: version "1.1.29" resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" integrity sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ== +pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" @@ -2593,14 +2640,6 @@ read-pkg-up@^1.0.1: find-up "^1.0.0" read-pkg "^1.0.0" -read-pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-2.0.0.tgz#6b72a8048984e0c41e79510fd5e9fa99b3b549be" - integrity sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4= - dependencies: - find-up "^2.0.0" - read-pkg "^2.0.0" - read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -2610,15 +2649,6 @@ read-pkg@^1.0.0: normalize-package-data "^2.3.2" path-type "^1.0.0" -read-pkg@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-2.0.0.tgz#8ef1c0623c6a6db0dc6713c4bfac46332b2368f8" - integrity sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg= - dependencies: - load-json-file "^2.0.0" - normalize-package-data "^2.3.2" - path-type "^2.0.0" - readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@~2.3.6: version "2.3.6" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" @@ -2719,6 +2749,11 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= +require-main-filename@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" + integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== + requires-port@1.x.x: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" @@ -2822,6 +2857,11 @@ selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== +semver@^5.5.0: + version "5.7.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.0.tgz#790a7cf6fea5459bac96110b29b60412dc8ff96b" + integrity sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA== + send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" @@ -3137,7 +3177,7 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0: +"string-width@^1.0.2 || 2", string-width@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== @@ -3145,6 +3185,15 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^2.0.0" strip-ansi "^4.0.0" +string-width@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" + integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== + dependencies: + emoji-regex "^7.0.1" + is-fullwidth-code-point "^2.0.0" + strip-ansi "^5.1.0" + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -3173,6 +3222,13 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" +strip-ansi@^5.1.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" + integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== + dependencies: + ansi-regex "^4.1.0" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" @@ -3180,11 +3236,6 @@ strip-bom@^2.0.0: dependencies: is-utf8 "^0.2.0" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM= - strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -3306,7 +3357,7 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= "typescript@file:../../node_modules/typescript": - version "3.3.3333" + version "3.4.2" ua-parser-js@0.7.17: version "0.7.17" @@ -3502,16 +3553,24 @@ y18n@^3.2.1: resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI= +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== yallist@^3.0.0, yallist@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" integrity sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k= +yargs-parser@^13.0.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.0.tgz#7016b6dd03e28e1418a510e258be4bff5a31138f" + integrity sha512-Yq+32PrijHRri0vVKQEm+ys8mbqWjLiwQkMFNXEENutzLPP0bE4Lcd4iA3OQY5HF+GD3xXxf0MEHb8E4/SA3AA== + dependencies: + camelcase "^5.0.0" + decamelize "^1.2.0" + yargs-parser@^4.1.0, yargs-parser@^4.2.0: version "4.2.1" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" @@ -3519,12 +3578,22 @@ yargs-parser@^4.1.0, yargs-parser@^4.2.0: dependencies: camelcase "^3.0.0" -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= +yargs@13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.1.0.tgz#b2729ce4bfc0c584939719514099d8a916ad2301" + integrity sha512-1UhJbXfzHiPqkfXNHYhiz79qM/kZqjTE8yGlEjZa85Q+3+OwcV6NRkV7XOV1W2Eom2bzILeUn55pQYffjVOLAg== dependencies: - camelcase "^4.1.0" + cliui "^4.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" + os-locale "^3.1.0" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.0.0" yargs@6.4.0: version "6.4.0" @@ -3565,29 +3634,10 @@ yargs@6.6.0: y18n "^3.2.1" yargs-parser "^4.2.0" -yargs@9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" - integrity sha1-UqzCP+7Kw0BCB47njAwAf1CF20w= - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - yeast@0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419" integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk= "zone.js@file:../../node_modules/zone.js": - version "0.9.0" + version "0.9.1" diff --git a/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts b/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts index 602f8d4829..d483365ba7 100644 --- a/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts +++ b/packages/compiler-cli/ngcc/src/analysis/decoration_analyzer.ts @@ -14,10 +14,10 @@ import {AbsoluteModuleStrategy, LocalIdentifierStrategy, LogicalProjectStrategy, import {CompoundMetadataReader, CompoundMetadataRegistry, DtsMetadataReader, LocalMetadataRegistry} from '../../../src/ngtsc/metadata'; import {PartialEvaluator} from '../../../src/ngtsc/partial_evaluator'; import {AbsoluteFsPath, LogicalFileSystem} from '../../../src/ngtsc/path'; +import {ClassDeclaration, ClassSymbol, Decorator} from '../../../src/ngtsc/reflection'; import {LocalModuleScopeRegistry, MetadataDtsModuleScopeResolver} from '../../../src/ngtsc/scope'; import {CompileResult, DecoratorHandler, DetectResult, HandlerPrecedence} from '../../../src/ngtsc/transform'; import {FileSystem} from '../file_system/file_system'; -import {DecoratedClass} from '../host/decorated_class'; import {NgccReflectionHost} from '../host/ngcc_host'; import {isDefined} from '../utils'; @@ -26,7 +26,10 @@ export interface AnalyzedFile { analyzedClasses: AnalyzedClass[]; } -export interface AnalyzedClass extends DecoratedClass { +export interface AnalyzedClass { + name: string; + decorators: Decorator[]|null; + declaration: ClassDeclaration; diagnostics?: ts.Diagnostic[]; matches: {handler: DecoratorHandler; analysis: any;}[]; } @@ -133,19 +136,18 @@ export class DecorationAnalyzer { } protected analyzeFile(sourceFile: ts.SourceFile): AnalyzedFile|undefined { - const decoratedClasses = this.reflectionHost.findDecoratedClasses(sourceFile); - return decoratedClasses.length ? { - sourceFile, - analyzedClasses: decoratedClasses.map(clazz => this.analyzeClass(clazz)).filter(isDefined) - } : - undefined; + const analyzedClasses = this.reflectionHost.findClassSymbols(sourceFile) + .map(symbol => this.analyzeClass(symbol)) + .filter(isDefined); + return analyzedClasses.length ? {sourceFile, analyzedClasses} : undefined; } - protected analyzeClass(clazz: DecoratedClass): AnalyzedClass|null { + protected analyzeClass(symbol: ClassSymbol): AnalyzedClass|null { + const declaration = symbol.valueDeclaration; + const decorators = this.reflectionHost.getDecoratorsOfSymbol(symbol); const matchingHandlers = this.handlers .map(handler => { - const detected = - handler.detect(clazz.declaration, clazz.decorators); + const detected = handler.detect(declaration, decorators); return {handler, detected}; }) .filter(isMatchingHandler); @@ -183,13 +185,19 @@ export class DecorationAnalyzer { const matches: {handler: DecoratorHandler, analysis: any}[] = []; const allDiagnostics: ts.Diagnostic[] = []; for (const {handler, detected} of detections) { - const {analysis, diagnostics} = handler.analyze(clazz.declaration, detected.metadata); + const {analysis, diagnostics} = handler.analyze(declaration, detected.metadata); if (diagnostics !== undefined) { allDiagnostics.push(...diagnostics); } matches.push({handler, analysis}); } - return {...clazz, matches, diagnostics: allDiagnostics.length > 0 ? allDiagnostics : undefined}; + return { + name: symbol.name, + declaration, + decorators, + matches, + diagnostics: allDiagnostics.length > 0 ? allDiagnostics : undefined + }; } protected compileFile(analyzedFile: AnalyzedFile): CompiledFile { diff --git a/packages/compiler-cli/ngcc/src/host/decorated_class.ts b/packages/compiler-cli/ngcc/src/host/decorated_class.ts deleted file mode 100644 index 15c570ade2..0000000000 --- a/packages/compiler-cli/ngcc/src/host/decorated_class.ts +++ /dev/null @@ -1,28 +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 {ClassDeclaration, Decorator} from '../../../src/ngtsc/reflection'; - -/** - * A simple container that holds the details of a decorated class that has been - * found in a `DecoratedFile`. - */ -export class DecoratedClass { - /** - * Initialize a `DecoratedClass` that was found in a `DecoratedFile`. - * @param name The name of the class that has been found. This is mostly used - * for informational purposes. - * @param declaration The TypeScript AST node where this class is declared. In ES5 code, where a - * class can be represented by both a variable declaration and a function declaration (inside an - * IIFE), `declaration` will always refer to the outer variable declaration, which represents the - * class to the rest of the program. - * @param decorators The collection of decorators that have been found on this class. - */ - constructor( - public name: string, public declaration: ClassDeclaration, public decorators: Decorator[]) {} -} diff --git a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts index 044b523d61..4949a3ef65 100644 --- a/packages/compiler-cli/ngcc/src/host/esm2015_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm2015_host.ts @@ -13,7 +13,6 @@ import {Logger} from '../logging/logger'; import {BundleProgram} from '../packages/bundle_program'; import {findAll, getNameText, hasNameIdentifier, isDefined} from '../utils'; -import {DecoratedClass} from './decorated_class'; import {ModuleWithProvidersFunction, NgccReflectionHost, PRE_R3_MARKER, SwitchableVariableDeclaration, isSwitchableVariableDeclaration} from './ngcc_host'; export const DECORATORS = 'decorators' as ts.__String; @@ -233,6 +232,16 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N return superDeclaration; } + /** Gets all decorators of the given class symbol. */ + getDecoratorsOfSymbol(symbol: ClassSymbol): Decorator[]|null { + const decoratorsProperty = this.getStaticProperty(symbol, DECORATORS); + if (decoratorsProperty) { + return this.getClassDecoratorsFromStaticProperty(decoratorsProperty); + } else { + return this.getClassDecoratorsFromHelperCall(symbol); + } + } + /** * Search the given module for variable declarations in which the initializer * is an identifier marked with the `PRE_R3_MARKER`. @@ -306,24 +315,24 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N } /** - * Find all the classes that contain decorations in a given file. - * @param sourceFile The source file to search for decorated classes. - * @returns An array of decorated classes. + * Find all top-level class symbols in the given file. + * @param sourceFile The source file to search for classes. + * @returns An array of class symbols. */ - findDecoratedClasses(sourceFile: ts.SourceFile): DecoratedClass[] { - const classes: DecoratedClass[] = []; + findClassSymbols(sourceFile: ts.SourceFile): ClassSymbol[] { + const classes: ClassSymbol[] = []; this.getModuleStatements(sourceFile).forEach(statement => { if (ts.isVariableStatement(statement)) { statement.declarationList.declarations.forEach(declaration => { - const decoratedClass = this.getDecoratedClassFromSymbol(this.getClassSymbol(declaration)); - if (decoratedClass) { - classes.push(decoratedClass); + const classSymbol = this.getClassSymbol(declaration); + if (classSymbol) { + classes.push(classSymbol); } }); } else if (ts.isClassDeclaration(statement)) { - const decoratedClass = this.getDecoratedClassFromSymbol(this.getClassSymbol(statement)); - if (decoratedClass) { - classes.push(decoratedClass); + const classSymbol = this.getClassSymbol(statement); + if (classSymbol) { + classes.push(classSymbol); } } }); @@ -488,25 +497,6 @@ export class Esm2015ReflectionHost extends TypeScriptReflectionHost implements N return Array.from(sourceFile.statements); } - protected getDecoratorsOfSymbol(symbol: ClassSymbol): Decorator[]|null { - const decoratorsProperty = this.getStaticProperty(symbol, DECORATORS); - if (decoratorsProperty) { - return this.getClassDecoratorsFromStaticProperty(decoratorsProperty); - } else { - return this.getClassDecoratorsFromHelperCall(symbol); - } - } - - protected getDecoratedClassFromSymbol(symbol: ClassSymbol|undefined): DecoratedClass|null { - if (symbol) { - const decorators = this.getDecoratorsOfSymbol(symbol); - if (decorators && decorators.length) { - return new DecoratedClass(symbol.name, symbol.valueDeclaration, decorators); - } - } - return null; - } - /** * Walk the AST looking for an assignment to the specified symbol. * @param node The current node we are searching. diff --git a/packages/compiler-cli/ngcc/src/host/esm5_host.ts b/packages/compiler-cli/ngcc/src/host/esm5_host.ts index 8efa7d8797..0a893c4623 100644 --- a/packages/compiler-cli/ngcc/src/host/esm5_host.ts +++ b/packages/compiler-cli/ngcc/src/host/esm5_host.ts @@ -211,6 +211,16 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { return this.getMembersOfSymbol(innerFunctionSymbol); } + /** Gets all decorators of the given class symbol. */ + getDecoratorsOfSymbol(symbol: ClassSymbol): Decorator[]|null { + // The necessary info is on the inner function declaration (inside the ES5 class IIFE). + const innerFunctionSymbol = + this.getInnerFunctionSymbolFromClassDeclaration(symbol.valueDeclaration); + if (!innerFunctionSymbol) return null; + + return super.getDecoratorsOfSymbol(innerFunctionSymbol); + } + ///////////// Protected Helpers ///////////// @@ -321,15 +331,6 @@ export class Esm5ReflectionHost extends Esm2015ReflectionHost { return super.getConstructorParamInfo(innerFunctionSymbol, parameterNodes); } - protected getDecoratorsOfSymbol(symbol: ClassSymbol): Decorator[]|null { - // The necessary info is on the inner function declaration (inside the ES5 class IIFE). - const innerFunctionSymbol = - this.getInnerFunctionSymbolFromClassDeclaration(symbol.valueDeclaration); - if (!innerFunctionSymbol) return null; - - return super.getDecoratorsOfSymbol(innerFunctionSymbol); - } - /** * Get the parameter type and decorators for the constructor of a class, * where the information is stored on a static method of the class. diff --git a/packages/compiler-cli/ngcc/src/host/ngcc_host.ts b/packages/compiler-cli/ngcc/src/host/ngcc_host.ts index f1462db497..1730b1b029 100644 --- a/packages/compiler-cli/ngcc/src/host/ngcc_host.ts +++ b/packages/compiler-cli/ngcc/src/host/ngcc_host.ts @@ -6,8 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ import * as ts from 'typescript'; -import {ClassDeclaration, ClassSymbol, Declaration, ReflectionHost} from '../../../src/ngtsc/reflection'; -import {DecoratedClass} from './decorated_class'; +import {ClassDeclaration, ClassSymbol, Declaration, Decorator, ReflectionHost} from '../../../src/ngtsc/reflection'; export const PRE_R3_MARKER = '__PRE_R3__'; export const POST_R3_MARKER = '__POST_R3__'; @@ -64,11 +63,18 @@ export interface NgccReflectionHost extends ReflectionHost { getSwitchableDeclarations(module: ts.Node): SwitchableVariableDeclaration[]; /** - * Find all the classes that contain decorations in a given file. - * @param sourceFile The source file to search for decorated classes. - * @returns An array of decorated classes. + * Retrieves all decorators of a given class symbol. + * @param symbol Class symbol that can refer to a declaration which can hold decorators. + * @returns An array of decorators or null if none are declared. */ - findDecoratedClasses(sourceFile: ts.SourceFile): DecoratedClass[]; + getDecoratorsOfSymbol(symbol: ClassSymbol): Decorator[]|null; + + /** + * Retrieves all class symbols of a given source file. + * @param sourceFile The source file to search for classes. + * @returns An array of found class symbols. + */ + findClassSymbols(sourceFile: ts.SourceFile): ClassSymbol[]; /** * Search the given source file for exported functions and static class methods that return diff --git a/packages/compiler-cli/ngcc/src/rendering/renderer.ts b/packages/compiler-cli/ngcc/src/rendering/renderer.ts index 136c401fee..3624db0133 100644 --- a/packages/compiler-cli/ngcc/src/rendering/renderer.ts +++ b/packages/compiler-cli/ngcc/src/rendering/renderer.ts @@ -122,6 +122,10 @@ export class Renderer { private computeDecoratorsToRemove(classes: CompiledClass[]): RedundantDecoratorMap { const decoratorsToRemove = new RedundantDecoratorMap(); classes.forEach(clazz => { + if (clazz.decorators === null) { + return; + } + clazz.decorators.forEach(dec => { const decoratorArray = dec.node.parent !; if (!decoratorsToRemove.has(decoratorArray)) { diff --git a/packages/compiler-cli/ngcc/test/analysis/decoration_analyzer_spec.ts b/packages/compiler-cli/ngcc/test/analysis/decoration_analyzer_spec.ts index 7dddb28c6b..55e9ce36e7 100644 --- a/packages/compiler-cli/ngcc/test/analysis/decoration_analyzer_spec.ts +++ b/packages/compiler-cli/ngcc/test/analysis/decoration_analyzer_spec.ts @@ -95,8 +95,13 @@ describe('DecorationAnalyzer', () => { ]); // Only detect the Component and Directive decorators handler.detect.and.callFake( - (node: ts.Declaration, decorators: Decorator[]): DetectResult| undefined => { - logs.push(`detect: ${(node as any).name.text}@${decorators.map(d => d.name)}`); + (node: ts.Declaration, decorators: Decorator[] | null): DetectResult| undefined => { + const className = (node as any).name.text; + if (decorators === null) { + logs.push(`detect: ${className} (no decorators)`); + } else { + logs.push(`detect: ${className}@${decorators.map(d => d.name)}`); + } if (!decorators) { return undefined; } @@ -160,12 +165,13 @@ describe('DecorationAnalyzer', () => { it('should call detect on the decorator handlers with each class from the parsed file', () => { - expect(testHandler.detect).toHaveBeenCalledTimes(4); - expect(testHandler.detect.calls.allArgs().map(args => args[1][0])).toEqual([ - jasmine.objectContaining({name: 'Component'}), - jasmine.objectContaining({name: 'Directive'}), - jasmine.objectContaining({name: 'Injectable'}), - jasmine.objectContaining({name: 'Component'}), + expect(testHandler.detect).toHaveBeenCalledTimes(5); + expect(testHandler.detect.calls.allArgs().map(args => args[1])).toEqual([ + null, + jasmine.arrayContaining([jasmine.objectContaining({name: 'Component'})]), + jasmine.arrayContaining([jasmine.objectContaining({name: 'Directive'})]), + jasmine.arrayContaining([jasmine.objectContaining({name: 'Injectable'})]), + jasmine.arrayContaining([jasmine.objectContaining({name: 'Component'})]), ]); }); @@ -190,6 +196,8 @@ describe('DecorationAnalyzer', () => { it('should analyze, resolve and compile the classes that are detected', () => { expect(logs).toEqual([ + // Classes without decorators should also be detected. + 'detect: InjectionToken (no decorators)', // First detect and (potentially) analyze. 'detect: MyComponent@Component', 'analyze: MyComponent@Component', diff --git a/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts b/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts index 9d02cba996..95be061397 100644 --- a/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/commonjs_host_spec.ts @@ -1587,27 +1587,41 @@ describe('CommonJsReflectionHost', () => { }); }); - describe('findDecoratedClasses()', () => { - it('should return an array of all decorated classes in the given source file', () => { + describe('findClassSymbols()', () => { + it('should return an array of all classes in the given source file', () => { const {program, host: compilerHost} = makeTestBundleProgram(DECORATED_FILES); const host = new CommonJsReflectionHost(new MockLogger(), false, program, compilerHost); - const primary = program.getSourceFile(DECORATED_FILES[0].name) !; + const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !; + const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !; - const primaryDecoratedClasses = host.findDecoratedClasses(primary); - expect(primaryDecoratedClasses.length).toEqual(2); - const classA = primaryDecoratedClasses.find(c => c.name === 'A') !; - expect(classA.decorators.map(decorator => decorator.name)).toEqual(['Directive']); - // Note that `B` is not exported from `primary.js` - const classB = primaryDecoratedClasses.find(c => c.name === 'B') !; - expect(classB.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + const classSymbolsPrimary = host.findClassSymbols(primaryFile); + expect(classSymbolsPrimary.length).toEqual(2); + expect(classSymbolsPrimary.map(c => c.name)).toEqual(['A', 'B']); - const secondary = program.getSourceFile(DECORATED_FILES[1].name) !; - const secondaryDecoratedClasses = host.findDecoratedClasses(secondary); - expect(secondaryDecoratedClasses.length).toEqual(1); - // Note that `D` is exported from `secondary.js` but not exported from `primary.js` - const classD = secondaryDecoratedClasses.find(c => c.name === 'D') !; - expect(classD.name).toEqual('D'); - expect(classD.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + const classSymbolsSecondary = host.findClassSymbols(secondaryFile); + expect(classSymbolsSecondary.length).toEqual(1); + expect(classSymbolsSecondary.map(c => c.name)).toEqual(['D']); + }); + }); + + describe('getDecoratorsOfSymbol()', () => { + it('should return decorators of class symbol', () => { + const {program, host: compilerHost} = makeTestBundleProgram(DECORATED_FILES); + const host = new CommonJsReflectionHost(new MockLogger(), false, program, compilerHost); + const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !; + const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !; + + const classSymbolsPrimary = host.findClassSymbols(primaryFile); + const classDecoratorsPrimary = classSymbolsPrimary.map(s => host.getDecoratorsOfSymbol(s)); + expect(classDecoratorsPrimary.length).toEqual(2); + expect(classDecoratorsPrimary[0] !.map(d => d.name)).toEqual(['Directive']); + expect(classDecoratorsPrimary[1] !.map(d => d.name)).toEqual(['Directive']); + + const classSymbolsSecondary = host.findClassSymbols(secondaryFile); + const classDecoratorsSecondary = + classSymbolsSecondary.map(s => host.getDecoratorsOfSymbol(s)); + expect(classDecoratorsSecondary.length).toEqual(1); + expect(classDecoratorsSecondary[0] !.map(d => d.name)).toEqual(['Directive']); }); }); diff --git a/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts b/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts index 33c4c8e533..c4dcd6569b 100644 --- a/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/esm2015_host_spec.ts @@ -1539,30 +1539,42 @@ describe('Esm2015ReflectionHost', () => { }); }); - describe('findDecoratedClasses()', () => { - it('should return an array of all decorated classes in the given source file', () => { + describe('findClassSymbols()', () => { + it('should return an array of all classes in the given source file', () => { const program = makeTestProgram(...DECORATED_FILES); const host = new Esm2015ReflectionHost(new MockLogger(), false, program.getTypeChecker()); const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !; const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !; - const primaryDecoratedClasses = host.findDecoratedClasses(primaryFile); - expect(primaryDecoratedClasses.length).toEqual(2); - const classA = primaryDecoratedClasses.find(c => c.name === 'A') !; - expect(ts.isClassDeclaration(classA.declaration)).toBeTruthy(); - expect(classA.decorators.map(decorator => decorator.name)).toEqual(['Directive']); - // Note that `B` is not exported from `primary.js` - const classB = primaryDecoratedClasses.find(c => c.name === 'B') !; - expect(ts.isClassDeclaration(classB.declaration)).toBeTruthy(); - expect(classA.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + const classSymbolsPrimary = host.findClassSymbols(primaryFile); + expect(classSymbolsPrimary.length).toEqual(3); + expect(classSymbolsPrimary.map(c => c.name)).toEqual(['A', 'B', 'C']); - const secondaryDecoratedClasses = host.findDecoratedClasses(secondaryFile) !; - expect(secondaryDecoratedClasses.length).toEqual(1); - // Note that `D` is exported from `secondary.js` but not exported from `primary.js` - const classD = secondaryDecoratedClasses.find(c => c.name === 'D') !; - expect(classD.name).toEqual('D'); - expect(ts.isClassDeclaration(classD.declaration)).toBeTruthy(); - expect(classD.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + const classSymbolsSecondary = host.findClassSymbols(secondaryFile); + expect(classSymbolsSecondary.length).toEqual(1); + expect(classSymbolsSecondary.map(c => c.name)).toEqual(['D']); + }); + }); + + describe('getDecoratorsOfSymbol()', () => { + it('should return decorators of class symbol', () => { + const program = makeTestProgram(...DECORATED_FILES); + const host = new Esm2015ReflectionHost(new MockLogger(), false, program.getTypeChecker()); + const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !; + const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !; + + const classSymbolsPrimary = host.findClassSymbols(primaryFile); + const classDecoratorsPrimary = classSymbolsPrimary.map(s => host.getDecoratorsOfSymbol(s)); + expect(classDecoratorsPrimary.length).toEqual(3); + expect(classDecoratorsPrimary[0] !.map(d => d.name)).toEqual(['Directive']); + expect(classDecoratorsPrimary[1] !.map(d => d.name)).toEqual(['Directive']); + expect(classDecoratorsPrimary[2]).toBe(null); + + const classSymbolsSecondary = host.findClassSymbols(secondaryFile); + const classDecoratorsSecondary = + classSymbolsSecondary.map(s => host.getDecoratorsOfSymbol(s)); + expect(classDecoratorsSecondary.length).toEqual(1); + expect(classDecoratorsSecondary[0] !.map(d => d.name)).toEqual(['Directive']); }); }); diff --git a/packages/compiler-cli/ngcc/test/host/esm5_host_import_helper_spec.ts b/packages/compiler-cli/ngcc/test/host/esm5_host_import_helper_spec.ts index 65b02de6ff..a6c5161d73 100644 --- a/packages/compiler-cli/ngcc/test/host/esm5_host_import_helper_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/esm5_host_import_helper_spec.ts @@ -309,24 +309,46 @@ describe('Esm5ReflectionHost [import helper style]', () => { }); }); - describe('findDecoratedClasses', () => { - it('should return an array of all decorated classes in the given source file', () => { + describe('findClassSymbols()', () => { + it('should return an array of all classes in the given source file', () => { const program = makeTestProgram(...fileSystem.files); const host = new Esm5ReflectionHost(new MockLogger(), false, program.getTypeChecker()); const ngModuleFile = program.getSourceFile('/ngmodule.js') !; - const ngModuleClasses = host.findDecoratedClasses(ngModuleFile); + const ngModuleClasses = host.findClassSymbols(ngModuleFile); expect(ngModuleClasses.length).toEqual(1); - const ngModuleClass = ngModuleClasses.find(c => c.name === 'HttpClientXsrfModule') !; - expect(ngModuleClass.decorators.map(decorator => decorator.name)).toEqual(['NgModule']); + expect(ngModuleClasses[0].name).toBe('HttpClientXsrfModule'); const someDirectiveFile = program.getSourceFile('/some_directive.js') !; - const someDirectiveClasses = host.findDecoratedClasses(someDirectiveFile); - expect(someDirectiveClasses.length).toEqual(1); - const someDirectiveClass = someDirectiveClasses.find(c => c.name === 'SomeDirective') !; - expect(someDirectiveClass.decorators.map(decorator => decorator.name)).toEqual([ - 'Directive' - ]); + const someDirectiveClasses = host.findClassSymbols(someDirectiveFile); + expect(someDirectiveClasses.length).toEqual(3); + expect(someDirectiveClasses[0].name).toBe('ViewContainerRef'); + expect(someDirectiveClasses[1].name).toBe('TemplateRef'); + expect(someDirectiveClasses[2].name).toBe('SomeDirective'); + }); + }); + + describe('getDecoratorsOfSymbol()', () => { + it('should return decorators of class symbol', () => { + const program = makeTestProgram(...fileSystem.files); + const host = new Esm5ReflectionHost(new MockLogger(), false, program.getTypeChecker()); + + const ngModuleFile = program.getSourceFile('/ngmodule.js') !; + const ngModuleClasses = host.findClassSymbols(ngModuleFile); + const ngModuleDecorators = ngModuleClasses.map(s => host.getDecoratorsOfSymbol(s)); + + expect(ngModuleClasses.length).toEqual(1); + expect(ngModuleDecorators[0] !.map(d => d.name)).toEqual(['NgModule']); + + const someDirectiveFile = program.getSourceFile('/some_directive.js') !; + const someDirectiveClasses = host.findClassSymbols(someDirectiveFile); + const someDirectiveDecorators = + someDirectiveClasses.map(s => host.getDecoratorsOfSymbol(s)); + + expect(someDirectiveDecorators.length).toEqual(3); + expect(someDirectiveDecorators[0]).toBe(null); + expect(someDirectiveDecorators[1]).toBe(null); + expect(someDirectiveDecorators[2] !.map(d => d.name)).toEqual(['Directive']); }); }); diff --git a/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts b/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts index a4dd0a2c08..32abcc6c7f 100644 --- a/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/esm5_host_spec.ts @@ -1787,27 +1787,41 @@ describe('Esm5ReflectionHost', () => { }); }); - describe('findDecoratedClasses()', () => { - it('should return an array of all decorated classes in the given source file', () => { + describe('findClassSymbols()', () => { + it('should return an array of all classes in the given source file', () => { const program = makeTestProgram(...DECORATED_FILES); const host = new Esm5ReflectionHost(new MockLogger(), false, program.getTypeChecker()); - const primary = program.getSourceFile(DECORATED_FILES[0].name) !; + const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !; + const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !; - const primaryDecoratedClasses = host.findDecoratedClasses(primary); - expect(primaryDecoratedClasses.length).toEqual(2); - const classA = primaryDecoratedClasses.find(c => c.name === 'A') !; - expect(classA.decorators.map(decorator => decorator.name)).toEqual(['Directive']); - // Note that `B` is not exported from `primary.js` - const classB = primaryDecoratedClasses.find(c => c.name === 'B') !; - expect(classB.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + const classSymbolsPrimary = host.findClassSymbols(primaryFile); + expect(classSymbolsPrimary.length).toEqual(2); + expect(classSymbolsPrimary.map(c => c.name)).toEqual(['A', 'B']); - const secondary = program.getSourceFile(DECORATED_FILES[1].name) !; - const secondaryDecoratedClasses = host.findDecoratedClasses(secondary); - expect(secondaryDecoratedClasses.length).toEqual(1); - // Note that `D` is exported from `secondary.js` but not exported from `primary.js` - const classD = secondaryDecoratedClasses.find(c => c.name === 'D') !; - expect(classD.name).toEqual('D'); - expect(classD.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + const classSymbolsSecondary = host.findClassSymbols(secondaryFile); + expect(classSymbolsSecondary.length).toEqual(1); + expect(classSymbolsSecondary.map(c => c.name)).toEqual(['D']); + }); + }); + + describe('getDecoratorsOfSymbol()', () => { + it('should return decorators of class symbol', () => { + const program = makeTestProgram(...DECORATED_FILES); + const host = new Esm5ReflectionHost(new MockLogger(), false, program.getTypeChecker()); + const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !; + const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !; + + const classSymbolsPrimary = host.findClassSymbols(primaryFile); + const classDecoratorsPrimary = classSymbolsPrimary.map(s => host.getDecoratorsOfSymbol(s)); + expect(classDecoratorsPrimary.length).toEqual(2); + expect(classDecoratorsPrimary[0] !.map(d => d.name)).toEqual(['Directive']); + expect(classDecoratorsPrimary[1] !.map(d => d.name)).toEqual(['Directive']); + + const classSymbolsSecondary = host.findClassSymbols(secondaryFile); + const classDecoratorsSecondary = + classSymbolsSecondary.map(s => host.getDecoratorsOfSymbol(s)); + expect(classDecoratorsSecondary.length).toEqual(1); + expect(classDecoratorsSecondary[0] !.map(d => d.name)).toEqual(['Directive']); }); }); diff --git a/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts b/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts index 444e281c93..85c4962902 100644 --- a/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts +++ b/packages/compiler-cli/ngcc/test/host/umd_host_spec.ts @@ -1681,27 +1681,41 @@ describe('UmdReflectionHost', () => { }); }); - describe('findDecoratedClasses()', () => { - it('should return an array of all decorated classes in the given source file', () => { + describe('findClassSymbols()', () => { + it('should return an array of all classes in the given source file', () => { const {program, host: compilerHost} = makeTestBundleProgram(DECORATED_FILES); const host = new UmdReflectionHost(new MockLogger(), false, program, compilerHost); - const primary = program.getSourceFile(DECORATED_FILES[0].name) !; + const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !; + const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !; - const primaryDecoratedClasses = host.findDecoratedClasses(primary); - expect(primaryDecoratedClasses.length).toEqual(2); - const classA = primaryDecoratedClasses.find(c => c.name === 'A') !; - expect(classA.decorators.map(decorator => decorator.name)).toEqual(['Directive']); - // Note that `B` is not exported from `primary.js` - const classB = primaryDecoratedClasses.find(c => c.name === 'B') !; - expect(classB.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + const classSymbolsPrimary = host.findClassSymbols(primaryFile); + expect(classSymbolsPrimary.length).toEqual(2); + expect(classSymbolsPrimary.map(c => c.name)).toEqual(['A', 'B']); - const secondary = program.getSourceFile(DECORATED_FILES[1].name) !; - const secondaryDecoratedClasses = host.findDecoratedClasses(secondary); - expect(secondaryDecoratedClasses.length).toEqual(1); - // Note that `D` is exported from `secondary.js` but not exported from `primary.js` - const classD = secondaryDecoratedClasses.find(c => c.name === 'D') !; - expect(classD.name).toEqual('D'); - expect(classD.decorators.map(decorator => decorator.name)).toEqual(['Directive']); + const classSymbolsSecondary = host.findClassSymbols(secondaryFile); + expect(classSymbolsSecondary.length).toEqual(1); + expect(classSymbolsSecondary.map(c => c.name)).toEqual(['D']); + }); + }); + + describe('getDecoratorsOfSymbol()', () => { + it('should return decorators of class symbol', () => { + const {program, host: compilerHost} = makeTestBundleProgram(DECORATED_FILES); + const host = new UmdReflectionHost(new MockLogger(), false, program, compilerHost); + const primaryFile = program.getSourceFile(DECORATED_FILES[0].name) !; + const secondaryFile = program.getSourceFile(DECORATED_FILES[1].name) !; + + const classSymbolsPrimary = host.findClassSymbols(primaryFile); + const classDecoratorsPrimary = classSymbolsPrimary.map(s => host.getDecoratorsOfSymbol(s)); + expect(classDecoratorsPrimary.length).toEqual(2); + expect(classDecoratorsPrimary[0] !.map(d => d.name)).toEqual(['Directive']); + expect(classDecoratorsPrimary[1] !.map(d => d.name)).toEqual(['Directive']); + + const classSymbolsSecondary = host.findClassSymbols(secondaryFile); + const classDecoratorsSecondary = + classSymbolsSecondary.map(s => host.getDecoratorsOfSymbol(s)); + expect(classDecoratorsSecondary.length).toEqual(1); + expect(classDecoratorsSecondary[0] !.map(d => d.name)).toEqual(['Directive']); }); }); diff --git a/packages/compiler-cli/ngcc/test/rendering/commonjs_rendering_formatter_spec.ts b/packages/compiler-cli/ngcc/test/rendering/commonjs_rendering_formatter_spec.ts index 6199050edb..7ea5a4789a 100644 --- a/packages/compiler-cli/ngcc/test/rendering/commonjs_rendering_formatter_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/commonjs_rendering_formatter_spec.ts @@ -326,7 +326,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'A') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -345,7 +345,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'B') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -366,7 +366,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'C') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -389,7 +389,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'A') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -406,7 +406,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'B') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -424,7 +424,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'C') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); diff --git a/packages/compiler-cli/ngcc/test/rendering/esm5_rendering_formatter_spec.ts b/packages/compiler-cli/ngcc/test/rendering/esm5_rendering_formatter_spec.ts index 4f8e69e5ca..27df790454 100644 --- a/packages/compiler-cli/ngcc/test/rendering/esm5_rendering_formatter_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/esm5_rendering_formatter_spec.ts @@ -318,7 +318,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'A') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -336,7 +336,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'B') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -355,7 +355,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'C') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -376,7 +376,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'A') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -393,7 +393,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'B') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -411,7 +411,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'C') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); diff --git a/packages/compiler-cli/ngcc/test/rendering/esm_rendering_formatter_spec.ts b/packages/compiler-cli/ngcc/test/rendering/esm_rendering_formatter_spec.ts index fc68fee711..1b0defc741 100644 --- a/packages/compiler-cli/ngcc/test/rendering/esm_rendering_formatter_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/esm_rendering_formatter_spec.ts @@ -226,7 +226,7 @@ A.decorators = [ const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'A') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -245,7 +245,7 @@ A.decorators = [ const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'B') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -264,7 +264,7 @@ A.decorators = [ const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'C') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -324,7 +324,7 @@ export { D }; const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'A') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -341,7 +341,7 @@ export { D }; const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'B') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -359,7 +359,7 @@ export { D }; const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'C') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); diff --git a/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts b/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts index 56546265de..78e31282ad 100644 --- a/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts @@ -234,6 +234,38 @@ describe('Renderer', () => { .toEqual(`{ type: Directive, args: [{ selector: '[a]' }] }`); }); + it('should render classes without decorators if handler matches', () => { + const {renderer, decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses, + testFormatter} = createTestRenderer('test-package', [{ + name: '/src/file.js', + contents: ` + import { Directive, ViewChild } from '@angular/core'; + + export class UndecoratedBase { test = null; } + + UndecoratedBase.propDecorators = { + test: [{ + type: ViewChild, + args: ["test", {static: true}] + }], + }; + ` + }]); + + renderer.renderProgram( + decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses); + + const addDefinitionsSpy = testFormatter.addDefinitions as jasmine.Spy; + expect(addDefinitionsSpy.calls.first().args[2]) + .toEqual( + `UndecoratedBase.ngBaseDef = ɵngcc0.ɵɵdefineBase({ viewQuery: function (rf, ctx) { if (rf & 1) { + ɵngcc0.ɵɵstaticViewQuery(_c0, true, null); + } if (rf & 2) { + var _t; + ɵngcc0.ɵɵqueryRefresh(_t = ɵngcc0.ɵɵloadViewQuery()) && (ctx.test = _t.first); + } } });`); + }); + it('should call renderImports after other abstract methods', () => { // This allows the other methods to add additional imports if necessary const {renderer, decorationAnalyses, switchMarkerAnalyses, privateDeclarationsAnalyses, diff --git a/packages/compiler-cli/ngcc/test/rendering/umd_rendering_formatter_spec.ts b/packages/compiler-cli/ngcc/test/rendering/umd_rendering_formatter_spec.ts index 8d6e09d6b1..4341c0b3b1 100644 --- a/packages/compiler-cli/ngcc/test/rendering/umd_rendering_formatter_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/umd_rendering_formatter_spec.ts @@ -377,7 +377,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'A') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -396,7 +396,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'B') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -417,7 +417,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'C') !; - const decorator = compiledClass.decorators[0]; + const decorator = compiledClass.decorators ![0]; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -439,7 +439,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'A') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -456,7 +456,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'B') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove); @@ -474,7 +474,7 @@ SOME DEFINITION TEXT const output = new MagicString(PROGRAM_DECORATE_HELPER.contents); const compiledClass = decorationAnalyses.get(sourceFile) !.compiledClasses.find(c => c.name === 'C') !; - const decorator = compiledClass.decorators.find(d => d.name === 'Directive') !; + const decorator = compiledClass.decorators !.find(d => d.name === 'Directive') !; const decoratorsToRemove = new Map(); decoratorsToRemove.set(decorator.node.parent !, [decorator.node]); renderer.removeDecorators(output, decoratorsToRemove);