├── .gitignore ├── CHANGELOG.md ├── LICENSE.txt ├── README.md ├── build.gradle ├── gradle-retrolambda ├── build.gradle ├── settings.gradle └── src │ ├── main │ ├── groovy │ │ └── me │ │ │ └── tatarka │ │ │ ├── RetrolambdaExec.groovy │ │ │ ├── RetrolambdaExtension.groovy │ │ │ ├── RetrolambdaPlugin.groovy │ │ │ ├── RetrolambdaPluginAndroid.groovy │ │ │ ├── RetrolambdaPluginGroovy.groovy │ │ │ ├── RetrolambdaPluginJava.groovy │ │ │ ├── RetrolambdaTask.groovy │ │ │ ├── RetrolambdaTransform.groovy │ │ │ └── RetrolambdaUtil.groovy │ └── resources │ │ └── META-INF │ │ └── gradle-plugins │ │ └── me.tatarka.retrolambda.properties │ └── test │ └── java │ └── me │ └── tatarka │ ├── AndroidAppPluginTest.java │ ├── AndroidFeaturePluginTest.java │ ├── AndroidLibPluginTest.java │ ├── AndroidTestPluginTest.java │ ├── GroovyPluginTest.java │ ├── JavaPluginTest.java │ └── TestHelpers.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── sample-android-app ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── tatarka │ │ └── sample │ │ └── app │ │ └── test │ │ └── MainActivityInstrumentationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_launcher-web.png │ ├── java │ │ └── me │ │ │ └── tatarka │ │ │ └── retrolambda │ │ │ └── sample │ │ │ └── app │ │ │ ├── MainActivity.java │ │ │ ├── MyComponent.java │ │ │ ├── MyModule.java │ │ │ └── ResFunction.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ └── values │ │ ├── strings.xml │ │ └── themes.xml │ └── test │ └── java │ └── me │ └── tatarka │ └── retrolambda │ └── sample │ └── app │ └── test │ └── FunctionTest.java ├── sample-android-feature ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── me │ └── tatarka │ └── retrolambda │ └── sample │ └── feature │ ├── Feature.java │ └── Function.java ├── sample-android-lib ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── me │ └── tatarka │ └── retrolambda │ └── sample │ └── lib │ ├── Function.java │ └── Lib.java ├── sample-android-test ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── me │ └── tatarka │ └── retrolamba │ └── sample │ └── test │ └── MainActivityInstrumentationTest.java ├── sample-java-default-methods ├── build.gradle └── src │ └── main │ └── java │ └── me │ └── tatarka │ └── retrolambda │ └── sample │ ├── Interface.java │ └── Main.java ├── sample-java ├── build.gradle └── src │ ├── main │ └── java │ │ └── me │ │ └── tatarka │ │ └── retrolambda │ │ └── sample │ │ ├── Function.java │ │ └── Main.java │ └── test │ └── java │ └── me │ └── tatarka │ └── retrolambda │ └── sample │ └── test │ └── Test.java ├── settings.gradle └── test.sh /.gitignore: -------------------------------------------------------------------------------- 1 | .gradle 2 | .idea 3 | *.iml 4 | build/ 5 | local.properties -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | #### 3.7.1 2 | 2019-04-21 3 | - Support gradle 5.0+ 4 | 5 | #### 3.7.0 6 | _2017-07-23_ 7 | - Support android gradle plugin 3.0 8 | - Support android feature modules 9 | 10 | #### 3.6.1 11 | _2017-04-22_ 12 | - Support Android Gradle Plugin 2.5 13 | 14 | #### 3.6.0 15 | _2017-03-02_ 16 | - *Deprecated* oldJdk (and reading from JAVA6/JAVA7_HOME). 17 | - *Deprecated* running gradle with java 6 or 7. 18 | - Fixed incremental build sometimes leaving deleted classes (madisp) 19 | - No longer fail if old jdk is not defined. Instead run with the current jdk. 20 | - Bumped default retrolambda version to `2.5.1` 21 | 22 | #### 3.5.0 23 | _2017-01-23_ 24 | - Don't disable extractAnnotation task on android libs as it now supports java 8 sources. 25 | - Bumped default retrolambda version to `2.5.0` 26 | 27 | #### 3.4.0 28 | _2016-11-19_ 29 | - Support build dirs with custom names 30 | - Support com.android.test modules 31 | 32 | #### 3.3.1 33 | _2016-10-19_ 34 | - Fixed retrolambda classpath when running and android test with multiple flavors. 35 | 36 | #### 3.3.0 37 | _2016-09-08_ 38 | - Fixed certain cases where android tests would fail to compile because wrong classpath was used. 39 | - Bumped default retrolambda version to `2.3.0` 40 | 41 | #### 3.3.0-beta4 42 | _2016-02-05_ 43 | - Merged in all changes up to `3.2.5` 44 | - Supports running with other transforms (this is a bit hackey, hopefully we'll get per-variant 45 | transforms and it can be implemented far more cleanly). 46 | 47 | #### 3.3.0-beta3 48 | _2015-11-18_ 49 | - Supports transform api in android plugin `1.5.0` 50 | 51 | #### 3.3.0-beta2 52 | _2015-10-03_ 53 | Experimental support for the new transform api 54 | - Requires android plugin `1.4.0-beta4` 55 | 56 | http://tools.android.com/tech-docs/new-build-system/transform-api 57 | 58 | - Transform api used in library projects. 59 | - Prints retrolambda output to log level --info 60 | known issues: 61 | - include/exclude are ignored 62 | 63 | #### 3.3.0-beta1 64 | _2015-09-15_ 65 | Experimental support for the new transform api 66 | - Requires android plugin `1.4.0-beta2` 67 | 68 | http://tools.android.com/tech-docs/new-build-system/transform-api 69 | 70 | known issues: 71 | - Include/exclude are ignored. 72 | - Does not work in library projects (falls back to the old method). 73 | - Prints retrolambda output to stdout instead of log level --info. 74 | 75 | #### 3.2.5 76 | _2016-02-04_ 77 | - Bumped default retrolambda version to `2.1.0` 78 | - If the commandline parameters are over a certain limit, they will be written to files. This should 79 | prevent failures on projects with large classpaths or when a huge number of incremental changes 80 | happen. 81 | 82 | #### 3.2.4 83 | _2015-11-18_ 84 | - Bumped default retrolambda version to `2.0.6`. 85 | 86 | #### 3.2.3 87 | _2015-09-20_ 88 | - Fixed long builds times on large projects due to https://issues.gradle.org/browse/GRADLE-3283. 89 | Note: Running the retrolambda task directly will no longer work, you must run the relevant java 90 | compile task instead. 91 | 92 | #### 3.2.2 93 | _2015-08-17_ 94 | - Fixed wrongly deleting lambda classes where the related class is a prefix of the one that actually 95 | changed during incremental compilation. (thanks clemp6r!) 96 | 97 | #### 3.2.1 98 | _2015-08-10_ 99 | - Fixed unit tests on android gradle plugin `1.3.0`. 100 | - Bumped default retrolambda version to `2.0.5`. 101 | 102 | #### 3.2.0 103 | _2015-06-27_ 104 | - Support for targeting java 5 with retrolambda. 105 | - Don't depend on the android gradle plugin being on the classpath when using in pure java projects. 106 | - Delay calculating classpath for retrolambda. This fixes missing aar libs added by the android 107 | gradle plugin. 108 | 109 | #### 3.1.0 110 | _2015-05-02_ 111 | - Major refactoring of android plugin. 112 | The method for modifying the javaCompile task is now *way* less hackey. In fact, 113 | it is much closer to the original way that it was done. I had originally 114 | abandoned this approach because it was breaking increment compilation is some 115 | weird ways. However, I think I have solved it. 116 | 117 | What this means for you: It is now less fickle of plugin application order and 118 | way less likely to break other plugins. 119 | - Properly split bootclasspath if it has multiple paths 120 | 121 | #### 3.0.1 122 | _2015-04-05_ 123 | - Fixed occasional "Build exception: cannot call Task.setEnabled(boolean)" error. 124 | - Fixed minor warning typo. 125 | - Uploaded to the gradle plugin portal. 126 | 127 | #### 3.0.0 128 | _2015-03-30_ 129 | A whole bunch of changes! 130 | - Changed the default retrolambda to 2.0.0 131 | - Added support for default methods, add `defaultMethods true` to the retrolambda block. Note: due 132 | to a current limitation in retrolamba, this will require all of your class files to be fed through 133 | retrolambda on each build. This may adversely affect build times. 134 | - `incremental false` is no longer deprecated but has different semantics. Instead of being a hack 135 | around gradle-retrolambda breaking other plugins, it now only forces all of your class files to be 136 | run through retrolambda instead of only the changed ones. 137 | - Added support for android unit tests, including lambdas in the tests themselves. 138 | - No longer patch the android jar, modify the classpath instead. This should resolve issues with 139 | using gradle-retrolambda with more obscure android sdks, like google glass. This should also speed 140 | up a clean build since it doesn't have to do any zipping shenanigans. 141 | - Ensure the gradle plugin is compiled with java 6 compatibility. This should allow you to run 142 | gradle with an older version of java if you don't want java 8 set as the default. This was always 143 | the intention, but was broken in the last build. 144 | - More minor changes to how the java compile task is replaced, this should ensure better 145 | compatibility with other plugins. Note: these changes make the plugin application order more 146 | important. *Make sure you you apply this plugin last.* 147 | - Removed 'retrolambda', now you can only apply the plugin with 'me.tatarka.retrolambda'. 148 | 149 | #### 2.5.0 150 | _2014-12-14_ 151 | - A more robust fix for android-apt compatibility. Important: If you were experiencing issues with 152 | android-apt previously and updated to this version, you must run `gradle build --rerun-tasks` once. 153 | - Deprecate plugin name 'retrolambda' for 'me.tatarka.retrolambda' in preparation to publishing on 154 | the gradle plugin portal. 155 | 156 | #### 2.4.1 157 | _2014-11-01_ 158 | - Fixed compatibility with android-apt. 159 | - Fixed typo in one of the thrown exceptions. (tomxor) 160 | - Support groovy testing (ex. spock). (harningt) 161 | 162 | #### 2.4.0 163 | _2014-09-21_ 164 | - Better incremental compile method that doesn't break lint and proguard (and 165 | probably other tasks). Because of this, `retrolambda.incremental` is deprecated 166 | and does nothing. 167 | - Better handling of manually setting the retrolamba version with 168 | `retrolambConfig`. 169 | - Don't use the retrolambda javaagent if using version `1.6.0+`. 170 | - Set the default retrolambda version to `1.6.0`. 171 | 172 | #### 2.3.1 173 | _2014-09-18_ 174 | - Fixed `retrolambda.incremental false` causing the retrolambda task not to run. 175 | 176 | #### 2.3.0 177 | _2014-09-17_ 178 | - Add ability to set `retrolambda.incremental false` to disable incremental compilation, since it is 179 | incompatible with android lint/proguard. 180 | 181 | #### 2.2.3 182 | _2014-08-17_ 183 | - Change dependency back to `localGroovy()`, `org.codehaus.groovy:groovy-all:2.3.3` was causing 184 | issues. 185 | 186 | #### 2.2.2 187 | _2014-08-11_ 188 | - Support a `java.home` path that does not end in `/jre`, by using it as it is. 189 | This is an issue on OSX which may have a different directory structure. 190 | 191 | #### 2.2.1 192 | _2014-08-03_ 193 | - Ensure output directory is created even if the source set is missing files for the java plugin. 194 | Otherwise, compiling the source set would error out. 195 | 196 | #### 2.2.0 197 | _2014-07-26_ 198 | - Added way to add custom jvm arguments when running retrolambda. 199 | - Disable `extractAnnotations` tasks since they are incompatible with java 8 sources. 200 | 201 | #### 2.1.0 202 | _2014-07-14_ 203 | - Also check system property 'java.home' for the current java location. IDEs set this but not 204 | JAVA_HOME, so checking here first is more robust. (aphexcx) 205 | 206 | #### 2.0.0 207 | _2014-07-04_ 208 | - Hooks into gradle's incremental compilcation support. This should mean faster build times and less 209 | inconsistencies when changing the build script without running `clean`. To fully take advantage of 210 | this you need to use retrolambda `1.4.0+` which is now the default. 211 | 212 | #### 1.3.3 213 | _2014-06-23_ 214 | - Allow `retrolamba` plugin to be applied before or after `java` and `android` 215 | plugins 216 | 217 | #### 1.3.2 218 | _2014-05-02_ 219 | - Fixed for android gradle plugin `0.10.+` 220 | 221 | #### 1.3.1 222 | _014-03-29_ 223 | - Removed `compile` property, which didn't work anyway. Use `retrolambdaConfig` 224 | instead. 225 | - Minor error message improvement. 226 | 227 | #### 1.3.0 228 | _2014-03-02_ 229 | - Support android instrument tests. 230 | 231 | #### 1.2.0 232 | _2014-02-15_ 233 | - Support android-library projects. 234 | 235 | #### 1.1.1 236 | _2014-01-28_ 237 | - Fixed not correctly finding java 8 executable when running from java 6 or 7 on 238 | windows. (Mart-Bogdan) 239 | 240 | #### 1.1 241 | _2014-01-24_ 242 | - Fixed bug where java unit tests were not being run through retrolambda 243 | - Allow gradle to be called with java 6 or 7, i.e. Java 8 no longer has to be 244 | your default java. 245 | - Thank you Mart-Bogdan for starting these fixes. 246 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [2013] [Evan Tatarka] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Gradle Retrolambda Plugin 2 | ======================== 3 | 4 | [![Maven Central](https://maven-badges.herokuapp.com/maven-central/me.tatarka/gradle-retrolambda/badge.svg?style=flat)](https://maven-badges.herokuapp.com/maven-central/me.tatarka/gradle-retrolambda) 5 | 6 | This plugin will automatically build your java or *android* project with 7 | retrolambda, giving you lambda goodness on java 6 or 7. It relies on the 8 | wonderful [retrolambda](https://github.com/orfjackal/retrolambda) by Esko 9 | Luontola. 10 | 11 | Note: The minimum android gradle plugin is `1.5.0` and the minimum gradle plugin is `2.5`. 12 | 13 | Usage 14 | ---- 15 | 16 | 1. Download [jdk8](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) and set it as your default. 17 | 18 | 2. Add the following to your build.gradle 19 | 20 | ```groovy 21 | buildscript { 22 | repositories { 23 | mavenCentral() 24 | } 25 | 26 | dependencies { 27 | classpath 'me.tatarka:gradle-retrolambda:3.7.1' 28 | } 29 | } 30 | 31 | // Required because retrolambda is on maven central 32 | repositories { 33 | mavenCentral() 34 | } 35 | 36 | apply plugin: 'com.android.application' //or apply plugin: 'java' 37 | apply plugin: 'me.tatarka.retrolambda' 38 | ``` 39 | alternatively, you can use the new plugin syntax for gradle `2.1+` 40 | ```groovy 41 | plugins { 42 | id "me.tatarka.retrolambda" version "3.7.1" 43 | } 44 | ``` 45 | 46 | 3. There is no step three! 47 | 48 | The plugin will compile the source code with java8 and then replace the class 49 | files with the output of retrolambda. 50 | 51 | Configuration 52 | ------------- 53 | You can add a block like the following to configure the plugin: 54 | ```groovy 55 | retrolambda { 56 | javaVersion JavaVersion.VERSION_1_6 57 | jvmArgs '-arg1', '-arg2' 58 | defaultMethods false 59 | incremental true 60 | } 61 | ``` 62 | 63 | - `javaVersion` Set the java version to compile to. The default is 6. Only 5, 6 or 7 are accepted. 64 | - `include 'Debug', 'Release'` Sets which sets/variants to run through 65 | retrolambda. The default is all of them. 66 | - `exclude 'Test'` Sets which sets/variants to not run through retrolambda. Only 67 | one of either `include` or `exclude` should be defined. 68 | - `jvmArgs` Add additional jvm args when running retrolambda. 69 | - `defaultMethods` Turn on default and static methods in interfaces support. Note: due to a 70 | limitation in retrolamba, this will set `incremental` to false. The default is false. 71 | - `incremental` Setting this to false forces all of your class files to be run through retrolambda 72 | instead of only the ones that have changed. The default is true. 73 | 74 | ### Using a Different Version of the retrolambda.jar 75 | 76 | The default version of retrolambda used is 77 | `'net.orfjackal.retrolambda:retrolambda:2.5.6'`. If you want to use a different 78 | one, you can configure it in your dependencies. 79 | 80 | ```groovy 81 | dependencies { 82 | // Latest one on maven central 83 | retrolambdaConfig 'net.orfjackal.retrolambda:retrolambda:+' 84 | // Or a local version 85 | // retrolambdaConfig files('libs/retrolambda.jar') 86 | } 87 | ``` 88 | 89 | ### Deprecated Features 90 | 91 | If you are running with java 6 or 7 you should really consider updating. However, you may use the 92 | below configuration instead. 93 | 94 | Set the environment variable `JAVA8_HOME` to point to the java 8 jdk. Alternatively, you can set the 95 | `jdk` property. 96 | ```groovy 97 | retrolambda { 98 | jdk System.getenv("JAVA8_HOME") 99 | } 100 | ``` 101 | 102 | You can force unit tests to be run with an older version of java by setting 103 | `JAVA5_HOME`/`JAVA6_HOME`/`JAVA7_HOME` or with the `oldJdk` property. 104 | ```groovy 105 | retrolambda { 106 | oldJdk System.getenv("JAVA6_HOME") 107 | } 108 | ``` 109 | 110 | Android Studio Setup 111 | -------------------- 112 | Add these lines to your `build.gradle` to inform the IDE of the language level. 113 | 114 | ```groovy 115 | android { 116 | compileOptions { 117 | sourceCompatibility JavaVersion.VERSION_1_8 118 | targetCompatibility JavaVersion.VERSION_1_8 119 | } 120 | } 121 | ``` 122 | 123 | Proguard 124 | ---------- 125 | This plugin is fully compatible with proguard (since `v2.4.0`). In your proguard file, add 126 | ``` 127 | -dontwarn java.lang.invoke.* 128 | -dontwarn **$$Lambda$* 129 | ``` 130 | 131 | Known Issues 132 | --------------- 133 | ### Lint fails on java files that have lambdas. 134 | First try updating to the latest version of the android gradle plugin. Newer versions of lint are 135 | compatible with java 8 sources. If you can't for some reason, you can still use the 136 | [experimental fork](https://github.com/evant/android-retrolambda-lombok) to fix the issue. 137 | 138 | ### Using Google Play Services causes retrolambda to fail 139 | Version `5.0.77` contains bytecode that is incompatible with retrolambda. This should be fixed in 140 | newer versions of play services, if you can update, that should be the preferred solution. To work 141 | around this issue, you can either use an earlier version like `4.4.52` or add `-noverify` to the jvm 142 | args. See [orfjackal/retrolambda#25](https://github.com/orfjackal/retrolambda/issues/25) for more 143 | information. 144 | 145 | ```groovy 146 | retrolambda { 147 | jvmArgs '-noverify' 148 | } 149 | ``` 150 | 151 | Updates 152 | ------- 153 | All updates have moved to the [CHANGELOG](https://github.com/evant/gradle-retrolambda/blob/master/CHANGELOG.md). 154 | 155 | License 156 | ------- 157 | 158 | Copyright 2013 Evan Tatarka 159 | 160 | Licensed under the Apache License, Version 2.0 (the "License"); 161 | you may not use this file except in compliance with the License. 162 | You may obtain a copy of the License at 163 | 164 | http://www.apache.org/licenses/LICENSE-2.0 165 | 166 | Unless required by applicable law or agreed to in writing, software 167 | distributed under the License is distributed on an "AS IS" BASIS, 168 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 169 | See the License for the specific language governing permissions and 170 | limitations under the License. 171 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | group = project.property('group') 3 | version = project.property('version') 4 | ext.androidPluginVersion = project.property('androidPluginVersion') 5 | } 6 | 7 | task test { 8 | dependsOn gradle.includedBuild('gradle-retrolambda').task(':test') 9 | } 10 | 11 | task install { 12 | dependsOn gradle.includedBuild('gradle-retrolambda').task(':install') 13 | } 14 | 15 | task publish { 16 | dependsOn gradle.includedBuild('gradle-retrolambda').task(':publish') 17 | } 18 | 19 | task publishPlugins { 20 | dependsOn gradle.includedBuild('gradle-retrolambda').task(':publishPlugins') 21 | } 22 | -------------------------------------------------------------------------------- /gradle-retrolambda/build.gradle: -------------------------------------------------------------------------------- 1 | import org.ajoberstar.grgit.* 2 | 3 | buildscript { 4 | repositories { 5 | mavenCentral() 6 | maven { 7 | url "https://plugins.gradle.org/m2/" 8 | } 9 | } 10 | 11 | dependencies { 12 | classpath 'org.ajoberstar:gradle-git:0.11.2' 13 | classpath "com.gradle.publish:plugin-publish-plugin:0.10.0" 14 | } 15 | } 16 | 17 | apply plugin: "com.gradle.plugin-publish" 18 | apply plugin: 'maven-publish' 19 | apply plugin: 'groovy' 20 | apply plugin: 'signing' 21 | apply plugin: 'idea' 22 | 23 | Properties props = new Properties() 24 | props.load(new FileInputStream("$projectDir/../gradle.properties")) 25 | group = props['group'] 26 | version = props['version'] 27 | ext.androidPluginVersion = props['androidPluginVersion'] 28 | 29 | sourceCompatibility = '1.7' 30 | 31 | repositories { 32 | maven { url 'https://maven.google.com' } 33 | jcenter() 34 | mavenCentral() 35 | } 36 | 37 | configurations { 38 | provided 39 | } 40 | 41 | sourceSets { 42 | main { 43 | compileClasspath += configurations.provided 44 | } 45 | } 46 | 47 | dependencies { 48 | compile gradleApi() 49 | compile localGroovy() 50 | provided "com.android.tools.build:gradle:$androidPluginVersion" 51 | 52 | testCompile gradleTestKit() 53 | testCompile 'junit:junit:4.12' 54 | testCompile 'org.assertj:assertj-core:2.1.0' 55 | testCompile "com.android.tools.build:gradle:$androidPluginVersion" 56 | testCompile 'com.neenbedankt.gradle.plugins:android-apt:1.8' 57 | } 58 | 59 | idea { 60 | module { 61 | scopes.PROVIDED.plus += [configurations.provided] 62 | } 63 | } 64 | 65 | // Taken from https://docs.gradle.org/current/userguide/test_kit.html 66 | // Write the plugin's classpath to a file to share with the tests 67 | task createClasspathManifest { 68 | def outputDir = file("$buildDir/$name") 69 | 70 | inputs.files sourceSets.main.runtimeClasspath 71 | outputs.dir outputDir 72 | 73 | doLast { 74 | outputDir.mkdirs() 75 | file("$outputDir/plugin-classpath.txt").text = sourceSets.main.runtimeClasspath.join("\n") 76 | } 77 | } 78 | 79 | // Add the classpath file to the test runtime classpath 80 | dependencies { 81 | testRuntime files(createClasspathManifest) 82 | } 83 | 84 | task javadocJar(type: Jar, dependsOn: javadoc) { 85 | classifier = 'javadoc' 86 | from 'build/docs/javadoc' 87 | } 88 | 89 | task sourcesJar(type: Jar) { 90 | from sourceSets.main.allSource 91 | classifier = 'sources' 92 | } 93 | 94 | pluginBundle { 95 | website = 'https://github.com/evant/gradle-retrolambda' 96 | vcsUrl = 'https://github.com/evant/gradle-retrolambda.git' 97 | description = 'https://github.com/evant/gradle-retrolambda.git' 98 | tags = ['java', 'android', 'lambda'] 99 | 100 | plugins { 101 | retrolambdaPlugin { 102 | id = 'me.tatarka.retrolambda' 103 | displayName = 'gradle-retrolambda' 104 | } 105 | } 106 | } 107 | 108 | publishing { 109 | publications { 110 | lib(MavenPublication) { 111 | artifact jar 112 | artifact sourcesJar 113 | artifact javadocJar 114 | pom { 115 | name = 'gradle-retrolambda' 116 | description = 'A gradle plugin for getting java lambda support in java 6, 7 and android' 117 | url = 'https://github.com/evant/gradle-retrolambda' 118 | scm { 119 | url = 'git@github.com:evant/gradle-retrolambda.git' 120 | connection = 'scm:git:git@github.com:evant/gradle-retrolambda.git' 121 | developerConnection = 'scm:git:git@github.com:evant/gradle-retrolambda.git' 122 | } 123 | licenses { 124 | license { 125 | name = 'The Apache Software License, Version 2.0' 126 | url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 127 | distribution = 'repo' 128 | } 129 | } 130 | developers { 131 | developer { 132 | id = 'evant' 133 | name = 'Evan Tatarka' 134 | } 135 | } 136 | } 137 | } 138 | } 139 | repositories { 140 | maven { 141 | def releasesRepoUrl = 'https://oss.sonatype.org/service/local/staging/deploy/maven2/' 142 | def snapshotsRepoUrl = 'https://oss.sonatype.org/content/repositories/snapshots' 143 | url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl 144 | credentials { 145 | username project.findProperty('sonatype.username') 146 | password project.findProperty('sonatype.password') 147 | } 148 | } 149 | } 150 | } 151 | 152 | signing { 153 | sign publishing.publications.lib 154 | } 155 | 156 | 157 | def grgit = Grgit.open("$projectDir/..") 158 | 159 | task checkRelease { doLast { 160 | def readmeVersion = file("$project.rootProject.projectDir/../README.md").readLines().find { it.contains('me.tatarka:gradle-retrolambda:') }?.trim() 161 | 162 | if (readmeVersion == null) { 163 | throw new ProjectConfigurationException("Missing README version string", null) 164 | } 165 | 166 | if (!readmeVersion.contains(":$version")) { 167 | throw new ProjectConfigurationException("README version string: $readmeVersion must match release version: $version", null) 168 | } 169 | 170 | def changelogVersion = file("$project.rootProject.projectDir/../CHANGELOG.md").readLines().find { it.contains("### $version") } 171 | if (changelogVersion == null) { 172 | throw new ProjectConfigurationException("CHANGELOG does not contain changes for release version: $version", null) 173 | } 174 | 175 | def branchName = grgit.branch.current.name 176 | if (branchName == 'beta') { 177 | if (!version.contains('beta')) { 178 | throw new ProjectConfigurationException("Beta branch must contain 'beta' in the version name", null) 179 | } 180 | } else if (branchName != 'master') { 181 | throw new ProjectConfigurationException("Branch: $branchName must be master", null) 182 | } 183 | } } 184 | 185 | task tagRelease(dependsOn: [checkRelease]) { doLast { 186 | grgit.tag.add { 187 | name = "v$version" 188 | message = "Release of $version" 189 | } 190 | } } 191 | 192 | if (!version.endsWith('SNAPSHOT')) { 193 | uploadArchives.dependsOn(tagRelease) 194 | } 195 | -------------------------------------------------------------------------------- /gradle-retrolambda/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'gradle-retrolambda' 2 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/groovy/me/tatarka/RetrolambdaExec.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2016 Evan Tatarka 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package me.tatarka 18 | 19 | import groovy.transform.CompileStatic 20 | import org.gradle.api.Project 21 | import org.gradle.api.ProjectConfigurationException 22 | import org.gradle.api.artifacts.Configuration 23 | import org.gradle.api.artifacts.Dependency 24 | import org.gradle.api.file.FileCollection 25 | import org.gradle.process.JavaExecSpec 26 | import org.gradle.util.VersionNumber 27 | 28 | import static me.tatarka.RetrolambdaPlugin.checkIfExecutableExists 29 | 30 | /** 31 | * Runs retrolambda with the given args, used by {@link RetrolambdaTask} and {@link RetrolambdaTransform}. 32 | */ 33 | @CompileStatic 34 | class RetrolambdaExec { 35 | 36 | private static final int COMMANDLINE_LENGTH_LIMIT = 3496; 37 | 38 | FileCollection classpath 39 | File inputDir; 40 | File outputDir; 41 | FileCollection includedFiles 42 | List jvmArgs; 43 | int bytecodeVersion; 44 | boolean defaultMethods; 45 | 46 | private final Project project; 47 | 48 | RetrolambdaExec(Project project) { 49 | this.project = project; 50 | } 51 | 52 | public void exec() { 53 | project.javaexec { JavaExecSpec exec -> 54 | // Ensure retrolambda runs on java8 55 | def retrolambda = project.extensions.getByType(RetrolambdaExtension.class) 56 | def retrolambdaConfig = project.configurations.getByName("retrolambdaConfig") 57 | 58 | if (!retrolambda.onJava8) { 59 | def java = "${retrolambda.tryGetJdk()}/bin/java" 60 | if (!checkIfExecutableExists(java)) { 61 | throw new ProjectConfigurationException("Cannot find executable: $java", (Throwable) null) 62 | } 63 | exec.executable java 64 | } 65 | 66 | String path = classpath.asPath 67 | 68 | exec.classpath = project.files(retrolambdaConfig) 69 | exec.main = 'net.orfjackal.retrolambda.Main' 70 | exec.jvmArgs = (Iterable) [ 71 | '-Dretrolambda.inputDir=' + String.valueOf(inputDir), 72 | '-Dretrolambda.outputDir=' + String.valueOf(outputDir), 73 | '-Dretrolambda.classpath=' + path, 74 | '-Dretrolambda.bytecodeVersion=' + String.valueOf(bytecodeVersion), 75 | ] 76 | 77 | VersionNumber retrolambdaVersion = retrolambdaVersion(retrolambdaConfig) 78 | boolean requiresJavaAgent = !requireVersion(retrolambdaVersion, '1.6.0') 79 | if (requiresJavaAgent) { 80 | exec.jvmArgs "-javaagent:$exec.classpath.asPath" 81 | } 82 | 83 | boolean supportIncludeFiles = requireVersion(retrolambdaVersion, '2.1.0') 84 | if (supportIncludeFiles && classpathLengthGreaterThanLimit(path)) { 85 | File classpathFile = File.createTempFile("inc-", ".path") 86 | classpathFile.withWriter('UTF-8') { writer -> 87 | for (String item : this.classpath) { 88 | writer.write(item + "\n") 89 | } 90 | } 91 | classpathFile.deleteOnExit(); 92 | exec.jvmArgs "-Dretrolambda.classpathFile=${classpathFile.absolutePath}" 93 | } else { 94 | exec.jvmArgs "-Dretrolambda.classpath=${path}" 95 | } 96 | 97 | if (includedFiles != null) { 98 | if (supportIncludeFiles && changeFileLengthGreaterThanLimit(includedFiles)) { 99 | def includedFile = File.createTempFile("inc-", ".list") 100 | includedFile.withWriter('UTF-8') { writer -> 101 | for (File file : includedFiles) { 102 | writer.write(file.toString() + "\n") 103 | } 104 | } 105 | includedFile.deleteOnExit(); 106 | exec.jvmArgs "-Dretrolambda.includedFilesFile=${includedFile.absolutePath}" 107 | } else { 108 | def includedArg = "-Dretrolambda.includedFiles=${includedFiles.join(File.pathSeparator)}" 109 | exec.jvmArgs includedArg 110 | project.logger.quiet(includedArg) 111 | } 112 | 113 | } 114 | 115 | if (defaultMethods) { 116 | exec.jvmArgs "-Dretrolambda.defaultMethods=true" 117 | } 118 | 119 | for (String arg : jvmArgs) { 120 | exec.jvmArgs arg 121 | } 122 | } 123 | } 124 | 125 | private static boolean classpathLengthGreaterThanLimit(String path) { 126 | return path.length() > COMMANDLINE_LENGTH_LIMIT 127 | } 128 | 129 | private static boolean changeFileLengthGreaterThanLimit(FileCollection includedFiles) { 130 | int total = 0; 131 | for (File file : includedFiles) { 132 | total += file.toString().length(); 133 | if (total > COMMANDLINE_LENGTH_LIMIT) { 134 | return true 135 | } 136 | } 137 | return false 138 | } 139 | 140 | private static VersionNumber retrolambdaVersion(Configuration retrolambdaConfig) { 141 | retrolambdaConfig.resolve() 142 | Dependency retrolambdaDep = retrolambdaConfig.dependencies.iterator().next() 143 | if (!retrolambdaDep.version) { 144 | // Don't know version 145 | return null 146 | } 147 | return VersionNumber.parse(retrolambdaDep.version) 148 | 149 | } 150 | 151 | private 152 | static boolean requireVersion(VersionNumber retrolambdaVersion, String version, boolean fallback = false) { 153 | if (retrolambdaVersion == null) { 154 | // Don't know version, assume fallback 155 | return fallback 156 | } 157 | def targetVersionNumber = VersionNumber.parse(version) 158 | return retrolambdaVersion >= targetVersionNumber 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/groovy/me/tatarka/RetrolambdaExtension.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014 Evan Tatarka 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package me.tatarka 18 | 19 | import groovy.transform.CompileStatic 20 | import org.gradle.api.JavaVersion 21 | import org.gradle.api.Nullable 22 | import org.gradle.api.Project 23 | import org.gradle.api.ProjectConfigurationException 24 | 25 | import static me.tatarka.RetrolambdaPlugin.javaVersionToBytecode 26 | 27 | @CompileStatic 28 | public class RetrolambdaExtension { 29 | int bytecodeVersion = 50 30 | List excludes = [] 31 | List includes = [] 32 | List jvmArgs = [] 33 | boolean incremental = true 34 | boolean defaultMethods = false 35 | boolean isOnJava8 = JavaVersion.current().java8Compatible 36 | 37 | private Project project 38 | private String jdk = null 39 | private String oldJdk = null 40 | private boolean jdkSet = false 41 | private boolean oldJdkSet = false 42 | 43 | public RetrolambdaExtension(Project project) { 44 | this.project = project 45 | } 46 | 47 | public void exclude(Object... e) { 48 | excludes.addAll(e.collect { i -> i.toString() }) 49 | } 50 | 51 | public void include(Object... e) { 52 | includes.addAll(e.collect { i -> i.toString() }) 53 | } 54 | 55 | public void jvmArgs(String... args) { 56 | jvmArgs.addAll(args) 57 | } 58 | 59 | public void incremental(boolean value) { 60 | incremental = value 61 | } 62 | 63 | public void defaultMethods(boolean value) { 64 | defaultMethods = value 65 | } 66 | 67 | public boolean isIncremental() { 68 | return incremental && !defaultMethods 69 | } 70 | 71 | public void setBytecodeVersion(int v) { 72 | bytecodeVersion = v 73 | } 74 | 75 | public void setJavaVersion(JavaVersion v) { 76 | bytecodeVersion = javaVersionToBytecode(v) 77 | } 78 | 79 | public JavaVersion getJavaVersion() { 80 | switch (bytecodeVersion) { 81 | case 49: return JavaVersion.VERSION_1_5 82 | case 50: return JavaVersion.VERSION_1_6 83 | case 51: return JavaVersion.VERSION_1_7 84 | } 85 | throw new AssertionError() 86 | } 87 | 88 | public void setJdk(String path) { 89 | jdk = path 90 | jdkSet = true 91 | } 92 | 93 | public String getJdk() { 94 | if (!jdkSet) { 95 | jdk = findJdk() 96 | jdkSet = true 97 | } 98 | return jdk 99 | } 100 | 101 | String tryGetJdk() { 102 | String jdk = getJdk() 103 | if (jdk == null) { 104 | throw new ProjectConfigurationException("When running gradle with java 5, 6 or 7, you must set the path to jdk8, either with property retrolambda.jdk or environment variable JAVA8_HOME", (Throwable) null) 105 | } 106 | return jdk 107 | } 108 | 109 | @Deprecated 110 | public void setOldJdk(String path) { 111 | oldJdk = path 112 | oldJdkSet = true 113 | } 114 | 115 | @Nullable 116 | @Deprecated 117 | public String getOldJdk() { 118 | if (!oldJdkSet) { 119 | oldJdk = findOldJdk() 120 | oldJdkSet = true 121 | } 122 | if (oldJdk != null) { 123 | project.logger.warn("running unit tests with an old jdk is deprecated an will be removed in a later version.") 124 | } 125 | return oldJdk 126 | } 127 | 128 | public boolean isIncluded(String name) { 129 | if (includes.isEmpty() && excludes.isEmpty()) return true 130 | if (excludes.isEmpty() && !includes.contains(name)) return false; 131 | if (includes.isEmpty() && excludes.contains(name)) return false; 132 | return true 133 | } 134 | 135 | public boolean isOnJava8() { 136 | return isOnJava8; 137 | } 138 | 139 | private String findJdk() { 140 | String jdk 141 | if (isOnJava8) { 142 | jdk = findCurrentJdk() 143 | } else { 144 | jdk = System.getenv("JAVA8_HOME") 145 | } 146 | project.logger.info("Retrolambda $project.path found jdk: $jdk") 147 | return jdk 148 | } 149 | 150 | private String findOldJdk() { 151 | String oldJdk 152 | if (!isOnJava8) { 153 | oldJdk = findCurrentJdk() 154 | } else { 155 | switch (bytecodeVersion) { 156 | case 49: 157 | oldJdk = System.getenv("JAVA5_HOME") 158 | break 159 | case 50: 160 | oldJdk = System.getenv("JAVA6_HOME") 161 | break 162 | case 51: 163 | oldJdk = System.getenv("JAVA7_HOME") 164 | break 165 | default: 166 | oldJdk = null 167 | } 168 | } 169 | project.logger.info("Retrolambda $project.path found oldJdk: $oldJdk") 170 | return oldJdk 171 | } 172 | 173 | private static String findCurrentJdk() { 174 | String javaHomeProp = System.properties.'java.home' 175 | if (javaHomeProp) { 176 | int jreIndex = javaHomeProp.lastIndexOf("${File.separator}jre") 177 | if (jreIndex != -1) { 178 | return javaHomeProp.substring(0, jreIndex) 179 | } else { 180 | return javaHomeProp 181 | } 182 | } else { 183 | return System.getenv("JAVA_HOME") 184 | } 185 | } 186 | } 187 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/groovy/me/tatarka/RetrolambdaPlugin.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014 Evan Tatarka 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package me.tatarka 18 | 19 | import groovy.transform.CompileStatic 20 | import org.gradle.api.JavaVersion 21 | import org.gradle.api.Plugin 22 | import org.gradle.api.Project 23 | import org.gradle.api.Task 24 | import org.gradle.api.artifacts.DependencySet 25 | import org.gradle.api.plugins.ApplicationPlugin 26 | import org.gradle.api.plugins.GroovyPlugin 27 | import org.gradle.api.plugins.JavaPlugin 28 | 29 | @CompileStatic 30 | public class RetrolambdaPlugin implements Plugin { 31 | protected static String retrolambdaCompile = "net.orfjackal.retrolambda:retrolambda:2.5.6" 32 | 33 | @Override 34 | void apply(Project project) { 35 | def retrolambda = project.extensions.create('retrolambda', RetrolambdaExtension, project) 36 | def retrolambdaConfig = project.configurations.create("retrolambdaConfig") 37 | 38 | if (!retrolambda.isOnJava8) { 39 | project.logger.warn("running gradle with java ${JavaVersion.current().majorVersion} is deprecated and will be removed in a future version.") 40 | } 41 | 42 | retrolambdaConfig.defaultDependencies { DependencySet dependencies -> 43 | dependencies.add(project.dependencies.create(retrolambdaCompile)) 44 | } 45 | 46 | project.task('compileRetrolambda', dependsOn: project.tasks.matching { Task task -> 47 | !task.name.equals('compileRetrolambda') && task.name.startsWith('compileRetrolambda') 48 | }) { Task task -> 49 | task.description = "Converts all java 8 class files to java 6 or 7" 50 | task.group = "build" 51 | } 52 | 53 | project.plugins.withType(JavaPlugin) { 54 | project.apply plugin: RetrolambdaPluginJava 55 | } 56 | 57 | project.plugins.withType(GroovyPlugin) { 58 | project.apply plugin: RetrolambdaPluginGroovy 59 | } 60 | 61 | project.plugins.withId('com.android.application') { 62 | project.apply plugin: RetrolambdaPluginAndroid 63 | } 64 | 65 | project.plugins.withId('com.android.feature') { 66 | project.apply plugin: RetrolambdaPluginAndroid 67 | } 68 | 69 | project.plugins.withId('com.android.library') { 70 | project.apply plugin: RetrolambdaPluginAndroid 71 | } 72 | 73 | project.plugins.withId('com.android.test') { 74 | project.apply plugin: RetrolambdaPluginAndroid 75 | } 76 | 77 | project.plugins.withType(ApplicationPlugin) { 78 | project.tasks.findByName('run').dependsOn('compileRetrolambda') 79 | } 80 | } 81 | 82 | /** 83 | * Checks if executable file exists, in MS Windows executables has suffix `.exe' 84 | * @param file 85 | * @return 86 | */ 87 | static boolean checkIfExecutableExists(String file) { 88 | new File(file).exists() || new File(file + '.exe').exists() 89 | } 90 | 91 | static int javaVersionToBytecode(JavaVersion v) { 92 | switch (v.majorVersion) { 93 | case '5': return 49 94 | case '6': return 50 95 | case '7': return 51 96 | default: 97 | throw new RuntimeException("Unknown java version: $v, only 5, 6 or 7 are accepted") 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/groovy/me/tatarka/RetrolambdaPluginAndroid.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014 Evan Tatarka 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package me.tatarka 18 | 19 | import com.android.build.gradle.AppPlugin 20 | import com.android.build.gradle.AppExtension 21 | import com.android.build.gradle.LibraryExtension 22 | import com.android.build.gradle.LibraryPlugin 23 | import com.android.build.gradle.TestExtension 24 | import com.android.build.gradle.TestPlugin 25 | import com.android.build.gradle.FeatureExtension 26 | import com.android.build.gradle.api.BaseVariant 27 | import com.android.build.gradle.api.TestVariant 28 | import com.android.build.gradle.api.UnitTestVariant 29 | import groovy.transform.CompileStatic 30 | import org.gradle.api.Plugin 31 | import org.gradle.api.Project 32 | import org.gradle.api.ProjectConfigurationException 33 | import org.gradle.api.tasks.compile.JavaCompile 34 | import org.gradle.api.tasks.testing.Test 35 | 36 | import static me.tatarka.RetrolambdaPlugin.checkIfExecutableExists 37 | 38 | @CompileStatic 39 | class RetrolambdaPluginAndroid implements Plugin { 40 | @Override 41 | void apply(Project project) { 42 | def retrolambda = project.extensions.getByType(RetrolambdaExtension) 43 | def transform = new RetrolambdaTransform(project, retrolambda) 44 | 45 | if (project.plugins.hasPlugin(LibraryPlugin)) { 46 | def android = project.extensions.getByType(LibraryExtension) 47 | android.registerTransform(transform) 48 | 49 | android.libraryVariants.all { BaseVariant variant -> 50 | configureCompileJavaTask(project, variant, transform) 51 | } 52 | android.testVariants.all { TestVariant variant -> 53 | configureCompileJavaTask(project, variant, transform) 54 | } 55 | android.unitTestVariants.all { UnitTestVariant variant -> 56 | configureUnitTestTask(project, variant.name, variant.javaCompile) 57 | } 58 | } else if (project.plugins.hasPlugin(TestPlugin)) { 59 | def android = project.extensions.getByType(TestExtension) 60 | android.registerTransform(transform) 61 | 62 | android.applicationVariants.all { BaseVariant variant -> 63 | configureCompileJavaTask(project, variant, transform) 64 | } 65 | } else if (project.plugins.hasPlugin(AppPlugin)) { 66 | def android = project.extensions.getByType(AppExtension) 67 | android.registerTransform(transform) 68 | 69 | android.applicationVariants.all { BaseVariant variant -> 70 | configureCompileJavaTask(project, variant, transform) 71 | } 72 | android.testVariants.all { TestVariant variant -> 73 | configureCompileJavaTask(project, variant, transform) 74 | } 75 | android.unitTestVariants.all { UnitTestVariant variant -> 76 | configureUnitTestTask(project, variant.name, variant.javaCompile) 77 | } 78 | } else { 79 | //the Feature plugin doesn't exist for older versions of AGP, so we need to check 80 | //it's in the classpath 81 | try { 82 | Class.forName( "com.android.build.gradle.FeaturePlugin" ) 83 | 84 | def android = project.extensions.getByType(FeatureExtension) 85 | android.registerTransform(transform) 86 | 87 | android.featureVariants.all { BaseVariant variant -> 88 | configureCompileJavaTask(project, variant, transform) 89 | } 90 | android.libraryVariants.all { BaseVariant variant -> 91 | configureCompileJavaTask(project, variant, transform) 92 | } 93 | android.testVariants.all { TestVariant variant -> 94 | configureCompileJavaTask(project, variant, transform) 95 | } 96 | android.unitTestVariants.all { UnitTestVariant variant -> 97 | configureUnitTestTask(project, variant.name, variant.javaCompile) 98 | } 99 | } catch( ClassNotFoundException e ) { 100 | //Feature plugin doesn't exist 101 | } 102 | } 103 | } 104 | 105 | private static configureCompileJavaTask(Project project, BaseVariant variant, RetrolambdaTransform transform) { 106 | variant.javaCompile.doFirst { 107 | def retrolambda = project.extensions.getByType(RetrolambdaExtension) 108 | def rt = "$retrolambda.jdk/jre/lib/rt.jar" 109 | 110 | variant.javaCompile.classpath = variant.javaCompile.classpath + project.files(rt) 111 | ensureCompileOnJava8(retrolambda, variant.javaCompile) 112 | } 113 | 114 | transform.putVariant(variant) 115 | } 116 | 117 | private 118 | static configureUnitTestTask(Project project, String variant, JavaCompile javaCompileTask) { 119 | javaCompileTask.doFirst { 120 | def retrolambda = project.extensions.getByType(RetrolambdaExtension) 121 | def rt = "$retrolambda.jdk/jre/lib/rt.jar" 122 | 123 | // We need to add the rt to the classpath to support lambdas in the tests themselves 124 | javaCompileTask.classpath = javaCompileTask.classpath + project.files(rt) 125 | 126 | ensureCompileOnJava8(retrolambda, javaCompileTask) 127 | } 128 | 129 | Test runTask = (Test) project.tasks.findByName("test${RetrolambdaUtil.capitalize(variant)}UnitTest") 130 | if (runTask) { 131 | runTask.doFirst { 132 | def retrolambda = project.extensions.getByType(RetrolambdaExtension) 133 | ensureRunOnJava8(retrolambda, runTask) 134 | } 135 | } 136 | } 137 | 138 | private static ensureCompileOnJava8(RetrolambdaExtension retrolambda, JavaCompile javaCompile) { 139 | javaCompile.sourceCompatibility = "1.8" 140 | javaCompile.targetCompatibility = "1.8" 141 | 142 | if (!retrolambda.onJava8) { 143 | // Set JDK 8 for the compiler task 144 | def javac = "${retrolambda.tryGetJdk()}/bin/javac" 145 | if (!checkIfExecutableExists(javac)) { 146 | throw new ProjectConfigurationException("Cannot find executable: $javac", (Throwable) null) 147 | } 148 | javaCompile.options.fork = true 149 | javaCompile.options.forkOptions.executable = javac 150 | } 151 | } 152 | 153 | private static ensureRunOnJava8(RetrolambdaExtension retrolambda, Test test) { 154 | if (!retrolambda.onJava8) { 155 | def java = "${retrolambda.tryGetJdk()}/bin/java" 156 | if (!checkIfExecutableExists(java)) { 157 | throw new ProjectConfigurationException("Cannot find executable: $java", (Throwable) null) 158 | } 159 | test.executable java 160 | } 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/groovy/me/tatarka/RetrolambdaPluginGroovy.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014 Evan Tatarka 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package me.tatarka 18 | 19 | import org.gradle.api.Plugin 20 | import org.gradle.api.Project 21 | import org.gradle.api.ProjectConfigurationException 22 | import org.gradle.api.Task 23 | import org.gradle.api.tasks.SourceSet 24 | 25 | import static me.tatarka.RetrolambdaPlugin.checkIfExecutableExists 26 | 27 | public class RetrolambdaPluginGroovy implements Plugin { 28 | @Override 29 | void apply(Project project) { 30 | project.afterEvaluate { 31 | def retrolambda = project.extensions.getByType(RetrolambdaExtension) 32 | 33 | project.sourceSets.all { SourceSet set -> 34 | if (project.retrolambda.isIncluded(set.name)) { 35 | def name = RetrolambdaUtil.capitalize(set.name) 36 | def taskName = "compileRetrolambdaGroovy$name" 37 | def oldOutputDir = RetrolambdaUtil.groovyOutputDir(set) 38 | def newOutputDir = project.file("$project.buildDir/retrolambda/$set.name") 39 | 40 | /* No compileJavaTaskName present, so re-use any modifications applied to compileJava and remap to Groovy */ 41 | def compileGroovyTaskName = set.compileJavaTaskName.replace(/Java/, /Groovy/) 42 | def compileGroovyTask = project.tasks.getByName(compileGroovyTaskName) 43 | 44 | compileGroovyTask.destinationDir = newOutputDir 45 | def retrolambdaTask = project.task(taskName, dependsOn: compileGroovyTask, type: RetrolambdaTask) { 46 | inputDir = newOutputDir 47 | outputDir = oldOutputDir 48 | classpath = set.compileClasspath + project.files(newOutputDir) 49 | javaVersion = retrolambda.javaVersion 50 | jvmArgs = retrolambda.jvmArgs 51 | } 52 | 53 | // enable retrolambdaTask dynamically, based on up-to-date source set before running 54 | project.gradle.taskGraph.beforeTask { Task task -> 55 | if (task == retrolambdaTask) { 56 | retrolambdaTask.setEnabled(!set.allJava.isEmpty()) 57 | } 58 | } 59 | 60 | project.tasks.findByName(set.classesTaskName).dependsOn(retrolambdaTask) 61 | 62 | if (!project.retrolambda.onJava8) { 63 | // Set JDK 8 for compiler task 64 | compileGroovyTask.doFirst { 65 | it.options.fork = true 66 | it.options.forkOptions.executable = "${retrolambda.tryGetJdk()}/bin/javac" 67 | } 68 | } 69 | } 70 | } 71 | 72 | project.tasks.getByName("test").doFirst { 73 | if (retrolambda.onJava8) { 74 | //Run tests on java6/7 if the property is defined. 75 | String oldJdkPath = retrolambda.oldJdk 76 | if (oldJdkPath != null) { 77 | def oldJava = "$oldJdkPath/bin/java" 78 | if (!checkIfExecutableExists(oldJava)) { 79 | throw new ProjectConfigurationException("Cannot find executable: $oldJava", null) 80 | } 81 | task.executable oldJava 82 | } 83 | } 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/groovy/me/tatarka/RetrolambdaPluginJava.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014 Evan Tatarka 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package me.tatarka 18 | 19 | import groovy.transform.CompileStatic 20 | import org.gradle.api.Plugin 21 | import org.gradle.api.Project 22 | import org.gradle.api.ProjectConfigurationException 23 | import org.gradle.api.Task 24 | import org.gradle.api.plugins.JavaPluginConvention 25 | import org.gradle.api.tasks.SourceSet 26 | import org.gradle.api.tasks.compile.JavaCompile 27 | import org.gradle.api.tasks.testing.Test 28 | 29 | import static me.tatarka.RetrolambdaPlugin.checkIfExecutableExists 30 | 31 | @CompileStatic 32 | public class RetrolambdaPluginJava implements Plugin { 33 | @Override 34 | void apply(Project project) { 35 | project.afterEvaluate { 36 | def retrolambda = project.extensions.getByType(RetrolambdaExtension) 37 | def javaPlugin = project.convention.getPlugin(JavaPluginConvention) 38 | 39 | javaPlugin.sourceSets.all { SourceSet set -> 40 | if (retrolambda.isIncluded(set.name)) { 41 | def name = RetrolambdaUtil.capitalize(set.name) 42 | def taskName = "compileRetrolambda$name" 43 | def oldOutputDir = RetrolambdaUtil.javaOutputDir(set) 44 | def newOutputDir = project.file("$project.buildDir/retrolambda/$set.name") 45 | 46 | def compileJavaTask = project.tasks.getByName(set.compileJavaTaskName) as JavaCompile 47 | compileJavaTask.destinationDir = newOutputDir 48 | 49 | def retrolambdaTask = project.task(taskName, dependsOn: compileJavaTask, type: RetrolambdaTask) { Task task -> 50 | RetrolambdaTask t = task as RetrolambdaTask 51 | t.inputDir = newOutputDir 52 | t.outputDir = oldOutputDir 53 | t.classpath = set.compileClasspath + project.files(newOutputDir) 54 | t.javaVersion = retrolambda.javaVersion 55 | t.jvmArgs = retrolambda.jvmArgs 56 | t.enabled = !set.allJava.isEmpty() 57 | } 58 | 59 | // enable retrolambdaTask dynamically, based on up-to-date source set before running 60 | project.gradle.taskGraph.beforeTask { Task task -> 61 | if (task == retrolambdaTask) { 62 | retrolambdaTask.setEnabled(!set.allJava.isEmpty()) 63 | } 64 | } 65 | 66 | project.tasks.findByName(set.classesTaskName).dependsOn(retrolambdaTask) 67 | 68 | if (!retrolambda.onJava8) { 69 | // Set JDK 8 for compiler task 70 | compileJavaTask.doFirst { 71 | compileJavaTask.options.fork = true 72 | compileJavaTask.options.forkOptions.executable = "${retrolambda.tryGetJdk()}/bin/javac" 73 | } 74 | } 75 | } 76 | } 77 | 78 | project.tasks.getByName("test").doFirst { Test task -> 79 | if (retrolambda.onJava8) { 80 | //Run tests on java6/7 if the property is defined. 81 | String oldJdkPath = retrolambda.oldJdk 82 | if (oldJdkPath != null) { 83 | def oldJava = "$oldJdkPath/bin/java" 84 | if (!checkIfExecutableExists(oldJava)) { 85 | throw new ProjectConfigurationException("Cannot find executable: $oldJava", (Throwable) null) 86 | } 87 | task.executable oldJava 88 | } 89 | } 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/groovy/me/tatarka/RetrolambdaTask.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2014 Evan Tatarka 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package me.tatarka 18 | 19 | import groovy.transform.CompileStatic 20 | import org.gradle.api.DefaultTask 21 | import org.gradle.api.JavaVersion 22 | import org.gradle.api.file.FileCollection 23 | import org.gradle.api.logging.LogLevel 24 | import org.gradle.api.tasks.Input 25 | import org.gradle.api.tasks.InputDirectory 26 | import org.gradle.api.tasks.OutputDirectory 27 | import org.gradle.api.tasks.TaskAction 28 | import org.gradle.api.tasks.incremental.IncrementalTaskInputs 29 | import org.gradle.api.tasks.incremental.InputFileDetails 30 | 31 | import static me.tatarka.RetrolambdaPlugin.javaVersionToBytecode 32 | 33 | /** 34 | * A task that runs retrolambda 35 | */ 36 | @CompileStatic 37 | class RetrolambdaTask extends DefaultTask { 38 | @InputDirectory 39 | File inputDir 40 | 41 | @OutputDirectory 42 | File outputDir 43 | 44 | @Input 45 | FileCollection classpath 46 | 47 | @Input 48 | JavaVersion javaVersion = JavaVersion.VERSION_1_6 49 | 50 | @Input 51 | List jvmArgs = [] 52 | 53 | @TaskAction 54 | def execute(IncrementalTaskInputs inputs) { 55 | def retrolambda = project.extensions.getByType(RetrolambdaExtension) 56 | 57 | List changes = [] 58 | inputs.outOfDate { changes.add(it) } 59 | 60 | // Ensure output is cleared if build is not incremental. 61 | if (inputs.incremental && !changes.isEmpty() && !retrolambda.incremental) { 62 | outputDir.eachFile { it.delete() } 63 | } else { 64 | for (InputFileDetails change : changes) { 65 | if (change.modified) deleteRelated(toOutput(change.file)) 66 | } 67 | } 68 | 69 | logging.captureStandardOutput(LogLevel.INFO) 70 | 71 | if (!inputs.incremental || !changes.isEmpty()) { 72 | RetrolambdaExec exec = new RetrolambdaExec(project) 73 | exec.inputDir = inputDir 74 | exec.outputDir = outputDir 75 | exec.bytecodeVersion = javaVersionToBytecode(javaVersion) 76 | exec.classpath = classpath 77 | if (inputs.incremental && retrolambda.incremental) { 78 | exec.includedFiles = project.files(changes*.file) 79 | } 80 | exec.defaultMethods = retrolambda.defaultMethods 81 | exec.jvmArgs = jvmArgs 82 | exec.exec() 83 | } 84 | 85 | inputs.removed { InputFileDetails change -> 86 | def outFile = toOutput(change.file) 87 | outFile.delete() 88 | project.logger.debug("Deleted " + outFile) 89 | deleteRelated(outFile) 90 | } 91 | } 92 | 93 | File toOutput(File file) { 94 | return outputDir.toPath().resolve(inputDir.toPath().relativize(file.toPath())).toFile() 95 | } 96 | 97 | void deleteRelated(File file) { 98 | def className = file.name.replaceFirst(/\.class$/, '') 99 | // Delete any generated Lambda classes 100 | project.logger.debug("Deleting related for " + className + " in " + file.parentFile) 101 | file.parentFile.eachFile { 102 | if (it.name.matches(/$className\$\$/ + /Lambda.*\.class$/)) { 103 | project.logger.debug("Deleted " + it) 104 | it.delete() 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/groovy/me/tatarka/RetrolambdaTransform.groovy: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2016 Evan Tatarka 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package me.tatarka 18 | 19 | import com.android.build.api.transform.* 20 | import com.android.build.gradle.api.BaseVariant 21 | import com.google.common.collect.ImmutableMap 22 | import groovy.transform.CompileStatic 23 | import groovy.transform.TypeChecked 24 | import groovy.transform.TypeCheckingMode 25 | import org.gradle.api.Project 26 | import org.gradle.api.ProjectConfigurationException 27 | import org.gradle.api.file.FileCollection 28 | import org.gradle.api.logging.LogLevel 29 | import org.gradle.api.tasks.compile.CompileOptions 30 | 31 | import static com.android.build.api.transform.Status.* 32 | import static me.tatarka.RetrolambdaPlugin.javaVersionToBytecode 33 | 34 | /** 35 | * Transform java 8 class files to java 5, 6, or 7 use retrolambda 36 | */ 37 | @CompileStatic 38 | class RetrolambdaTransform extends Transform { 39 | 40 | private final Project project 41 | private final RetrolambdaExtension retrolambda 42 | private final List variants = new ArrayList<>() 43 | 44 | RetrolambdaTransform(Project project, RetrolambdaExtension retrolambda) { 45 | this.project = project 46 | this.retrolambda = retrolambda 47 | } 48 | 49 | /** 50 | * We need to set this later because the classpath is not fully calculated until the last 51 | * possible moment when the java compile task runs. While a Transform currently doesn't have any 52 | * variant information, we can guess the variant based off the input path. 53 | */ 54 | void putVariant(BaseVariant variant) { 55 | variants.add(variant) 56 | 57 | } 58 | 59 | @Override 60 | void transform(Context context, Collection inputs, Collection referencedInputs, TransformOutputProvider outputProvider, boolean isIncremental) throws IOException, TransformException, InterruptedException { 61 | context.logging.captureStandardOutput(LogLevel.INFO) 62 | 63 | for (TransformInput input : inputs) { 64 | def outputDir = outputProvider.getContentLocation("retrolambda", outputTypes, scopes, Format.DIRECTORY) 65 | 66 | // Instead of looping, it might be better to figure out a way to pass multiple input 67 | // dirs into retrolambda. Luckily, the common case is only one. 68 | for (DirectoryInput directoryInput : input.directoryInputs) { 69 | File inputFile = directoryInput.file 70 | FileCollection changed 71 | if (isIncremental) { 72 | changed = project.files() 73 | for (Map.Entry entry : directoryInput.changedFiles) { 74 | File file = entry.key; Status status = entry.value 75 | if (status == ADDED || status == CHANGED) { 76 | changed += project.files(file); 77 | } 78 | if (status == CHANGED || status == REMOVED) { 79 | File output = toOutput(inputFile, outputDir, file) 80 | output.delete() 81 | deleteRelated(output) 82 | } 83 | } 84 | } else { 85 | changed = null 86 | } 87 | 88 | def exec = new RetrolambdaExec(project) 89 | exec.inputDir = inputFile 90 | exec.outputDir = outputDir 91 | exec.bytecodeVersion = javaVersionToBytecode(retrolambda.javaVersion) 92 | exec.classpath = getClasspath(context, outputDir, referencedInputs) + project.files(inputFile) 93 | exec.includedFiles = changed 94 | exec.defaultMethods = retrolambda.defaultMethods 95 | exec.jvmArgs = retrolambda.jvmArgs 96 | exec.exec() 97 | } 98 | } 99 | } 100 | 101 | private static File toOutput(File inputDir, File outputDir, File file) { 102 | return outputDir.toPath().resolve(inputDir.toPath().relativize(file.toPath())).toFile() 103 | } 104 | 105 | private static void deleteRelated(File file) { 106 | def className = file.name.replaceFirst(/\.class$/, '') 107 | // Delete any generated Lambda classes 108 | file.parentFile.eachFile { 109 | if (it.name.matches(/$className\$\$/ + /Lambda.*\.class$/)) { 110 | it.delete() 111 | } 112 | } 113 | } 114 | 115 | private FileCollection getClasspath(Context context, File outputDir, Collection referencedInputs) { 116 | BaseVariant variant = getVariant(context, outputDir) 117 | 118 | if (variant == null) { 119 | throw new ProjectConfigurationException('Missing variant for output dir: ' + outputDir, (Throwable) null) 120 | } 121 | 122 | FileCollection classpathFiles = variant.javaCompile.classpath 123 | for (TransformInput input : referencedInputs) { 124 | classpathFiles += project.files(input.directoryInputs*.file) 125 | } 126 | 127 | // bootClasspath isn't set until the last possible moment because it's expensive to look 128 | // up the android sdk path. 129 | String bootClasspath = getBootClasspath(variant.javaCompile.options) 130 | if (bootClasspath) { 131 | classpathFiles += project.files(bootClasspath.tokenize(File.pathSeparator)) 132 | } else { 133 | // If this is null it means the javaCompile task didn't need to run, however, we still 134 | // need to run but can't without the bootClasspath. Just fail and ask the user to rebuild. 135 | throw new ProjectConfigurationException("Unable to obtain the bootClasspath. This may happen if your javaCompile tasks didn't run but retrolambda did. You must rebuild your project or otherwise force javaCompile to run.", (Throwable) null) 136 | } 137 | 138 | return classpathFiles 139 | } 140 | 141 | @TypeChecked(TypeCheckingMode.SKIP) 142 | private static String getBootClasspath(CompileOptions options) { 143 | if (options.hasProperty('bootClasspath')) { 144 | return options.bootClasspath 145 | } 146 | return options.bootstrapClasspath?.asPath 147 | } 148 | 149 | private BaseVariant getVariant(Context context, File outputDir) { 150 | try { 151 | String variantName = context.variantName 152 | for (BaseVariant variant : variants) { 153 | if (variant.name == variantName) { 154 | return variant 155 | } 156 | } 157 | } catch (NoSuchMethodError e) { 158 | // Extract the variant from the output path assuming it's in the form like: 159 | // - '*/intermediates/transforms/retrolambda/ 160 | // - '*/intermediates/transforms/retrolambda//folders/1/1/retrolambda 161 | // This will no longer be needed when the transform api supports per-variant transforms 162 | String[] parts = outputDir.toURI().path.split('/intermediates/transforms/retrolambda/|/folders/[0-9]+') 163 | if (parts.length < 2) { 164 | throw new ProjectConfigurationException('Could not extract variant from output dir: ' + outputDir, (Throwable) null) 165 | } 166 | String variantPath = parts[1] 167 | for (BaseVariant variant : variants) { 168 | if (variant.dirName == variantPath) { 169 | return variant 170 | } 171 | } 172 | } 173 | return null 174 | } 175 | 176 | @Override 177 | String getName() { 178 | return "retrolambda" 179 | } 180 | 181 | @Override 182 | Set getInputTypes() { 183 | return Collections. singleton(QualifiedContent.DefaultContentType.CLASSES) 184 | } 185 | 186 | @Override 187 | Set getScopes() { 188 | return Collections.singleton(QualifiedContent.Scope.PROJECT) 189 | } 190 | 191 | @Override 192 | Set getReferencedScopes() { 193 | return Collections.singleton(QualifiedContent.Scope.TESTED_CODE) 194 | } 195 | 196 | @Override 197 | Map getParameterInputs() { 198 | return ImmutableMap. builder() 199 | .put("bytecodeVersion", retrolambda.bytecodeVersion) 200 | .put("jvmArgs", retrolambda.jvmArgs) 201 | .put("incremental", retrolambda.incremental) 202 | .put("defaultMethods", retrolambda.defaultMethods) 203 | .put("jdk", retrolambda.tryGetJdk()) 204 | .build() 205 | } 206 | 207 | @Override 208 | boolean isIncremental() { 209 | return retrolambda.incremental 210 | } 211 | } 212 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/groovy/me/tatarka/RetrolambdaUtil.groovy: -------------------------------------------------------------------------------- 1 | package me.tatarka 2 | 3 | import groovy.transform.TypeChecked 4 | import groovy.transform.TypeCheckingMode 5 | import org.gradle.api.tasks.SourceSet 6 | 7 | class RetrolambdaUtil { 8 | static String capitalize(CharSequence self) { 9 | return self.length() == 0 ? "" : "" + Character.toUpperCase(self.charAt(0)) + self.subSequence(1, self.length()) 10 | } 11 | 12 | @TypeChecked(TypeCheckingMode.SKIP) 13 | static File javaOutputDir(SourceSet set) { 14 | try { 15 | return set.java.outputDir 16 | } catch (Exception e) { 17 | return set.output.classesDir 18 | } 19 | } 20 | 21 | @TypeChecked(TypeCheckingMode.SKIP) 22 | static File groovyOutputDir(SourceSet set) { 23 | try { 24 | return set.groovy.outputDir 25 | } catch (Exception e) { 26 | return set.output.classesDir 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/main/resources/META-INF/gradle-plugins/me.tatarka.retrolambda.properties: -------------------------------------------------------------------------------- 1 | implementation-class=me.tatarka.RetrolambdaPlugin -------------------------------------------------------------------------------- /gradle-retrolambda/src/test/java/me/tatarka/AndroidAppPluginTest.java: -------------------------------------------------------------------------------- 1 | package me.tatarka; 2 | 3 | import org.gradle.testkit.runner.BuildResult; 4 | import org.gradle.testkit.runner.GradleRunner; 5 | import org.gradle.testkit.runner.TaskOutcome; 6 | import org.junit.Before; 7 | import org.junit.Rule; 8 | import org.junit.Test; 9 | import org.junit.rules.TemporaryFolder; 10 | import org.junit.runner.RunWith; 11 | import org.junit.runners.Parameterized; 12 | 13 | import java.io.File; 14 | import java.io.StringWriter; 15 | import java.util.Arrays; 16 | import java.util.Collection; 17 | 18 | import static me.tatarka.TestHelpers.*; 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | @RunWith(Parameterized.class) 22 | public class AndroidAppPluginTest { 23 | 24 | @Parameterized.Parameters(name = "{0}") 25 | public static Collection data() { 26 | return Arrays.asList(new Object[][]{ 27 | oldestSupportedAndroidPluginVersion(), 28 | newestSupportedAndroidPluginVersion() 29 | }); 30 | } 31 | 32 | @Rule 33 | public final TemporaryFolder testProjectDir = new TemporaryFolder(); 34 | private final String androidVersion; 35 | private final String gradleVersion; 36 | private final String buildToolsVersion; 37 | private final String kotlinVersion; 38 | private File rootDir; 39 | private File buildFile; 40 | 41 | public AndroidAppPluginTest(String androidVersion, String gradleVersion, String buildToolsVersion, String kotlinVersion) { 42 | this.androidVersion = androidVersion; 43 | this.gradleVersion = gradleVersion; 44 | this.buildToolsVersion = buildToolsVersion; 45 | this.kotlinVersion = kotlinVersion; 46 | } 47 | 48 | @Before 49 | public void setup() throws Exception { 50 | rootDir = testProjectDir.getRoot(); 51 | buildFile = testProjectDir.newFile("build.gradle"); 52 | copyLocalPropertiesIfExists(rootDir); 53 | } 54 | 55 | @Test 56 | public void assembleDebug() throws Exception { 57 | writeFile(buildFile, 58 | //language="Groovy" 59 | "buildscript {\n" + 60 | " System.properties['com.android.build.gradle.overrideVersionCheck'] = 'true'\n" + 61 | " \n" + 62 | " repositories {\n" + 63 | " maven { url 'https://maven.google.com' }\n" + 64 | " jcenter()\n" + 65 | " }\n" + 66 | " \n" + 67 | " dependencies {\n" + 68 | " classpath files(" + getPluginClasspath() + ")\n" + 69 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 70 | " }\n" + 71 | "}\n" + 72 | "\n" + 73 | "apply plugin: 'com.android.application'\n" + 74 | "apply plugin: 'me.tatarka.retrolambda'\n" + 75 | "\n" + 76 | "repositories {\n" + 77 | " maven { url 'https://maven.google.com' }\n" + 78 | " mavenCentral()\n" + 79 | "}\n" + 80 | "\n" + 81 | "android {\n" + 82 | " compileSdkVersion 24\n" + 83 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 84 | " \n" + 85 | " defaultConfig {\n" + 86 | " minSdkVersion 15\n" + 87 | " targetSdkVersion 24\n" + 88 | " }\n" + 89 | "}"); 90 | 91 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 92 | 93 | writeFile(manifestFile, 94 | //language="XML" 95 | "\n" + 97 | " \n" + 98 | ""); 99 | 100 | File javaFile = new File(rootDir, "src/main/java/MainActivity.java"); 101 | 102 | writeFile(javaFile, "package test;" + 103 | "import android.app.Activity;" + 104 | "import android.os.Bundle;" + 105 | "import android.util.Log;" + 106 | "public class MainActivity extends Activity {\n" + 107 | " public void onCreate(Bundle savedInstanceState) {\n" + 108 | " Runnable lambda = () -> Log.d(\"MainActivity\", \"Hello, Lambda!\");\n" + 109 | " lambda.run();\n" + 110 | " }\n" + 111 | "}"); 112 | 113 | StringWriter errorOutput = new StringWriter(); 114 | BuildResult result = GradleRunner.create() 115 | .withGradleVersion(gradleVersion) 116 | .withProjectDir(rootDir) 117 | .withArguments("assembleDebug", "--stacktrace", "-Pandroid.enableAapt2=false") 118 | .forwardStdError(errorOutput) 119 | .build(); 120 | 121 | assertThat(result.task(":assembleDebug").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 122 | 123 | File mainClassFile = findFile(rootDir, "MainActivity.class"); 124 | File lambdaClassFile = findFile(rootDir, "MainActivity$$Lambda$1.class"); 125 | 126 | assertThat(mainClassFile).exists(); 127 | assertThat(lambdaClassFile).exists(); 128 | } 129 | 130 | @Test 131 | public void assembleDebugIncremental() throws Exception { 132 | writeFile(buildFile, 133 | //language="Groovy" 134 | "buildscript {\n" + 135 | " repositories {\n" + 136 | " maven { url 'https://maven.google.com' }\n" + 137 | " jcenter()\n" + 138 | " }\n" + 139 | " \n" + 140 | " dependencies {\n" + 141 | " classpath files(" + getPluginClasspath() + ")\n" + 142 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 143 | " }\n" + 144 | "}\n" + 145 | "\n" + 146 | "apply plugin: 'com.android.application'\n" + 147 | "apply plugin: 'me.tatarka.retrolambda'\n" + 148 | "\n" + 149 | "repositories {\n" + 150 | " maven { url 'https://maven.google.com' }\n" + 151 | " mavenCentral()\n" + 152 | "}\n" + 153 | "\n" + 154 | "android {\n" + 155 | " compileSdkVersion 24\n" + 156 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 157 | " \n" + 158 | " defaultConfig {\n" + 159 | " minSdkVersion 15\n" + 160 | " targetSdkVersion 24\n" + 161 | " }\n" + 162 | "}"); 163 | 164 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 165 | 166 | writeFile(manifestFile, 167 | //language="XML" 168 | "\n" + 170 | " \n" + 171 | ""); 172 | 173 | File javaFile = new File(rootDir, "src/main/java/MainActivity.java"); 174 | 175 | writeFile(javaFile, "package test;" + 176 | "import android.app.Activity;" + 177 | "import android.os.Bundle;" + 178 | "import android.util.Log;" + 179 | "public class MainActivity extends Activity {\n" + 180 | " public void onCreate(Bundle savedInstanceState) {\n" + 181 | " Runnable lambda = () -> Log.d(\"MainActivity\", \"Hello, Lambda!\");\n" + 182 | " lambda.run();\n" + 183 | " }\n" + 184 | "}"); 185 | 186 | StringWriter errorOutput = new StringWriter(); 187 | BuildResult result = GradleRunner.create() 188 | .withGradleVersion(gradleVersion) 189 | .withProjectDir(rootDir) 190 | .withArguments("assembleDebug", "--stacktrace", "-Pandroid.enableAapt2=false") 191 | .forwardStdError(errorOutput) 192 | .build(); 193 | 194 | assertThat(result.task(":assembleDebug").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 195 | 196 | writeFile(javaFile, "package test;" + 197 | "import android.app.Activity;" + 198 | "import android.os.Bundle;" + 199 | "import android.util.Log;" + 200 | "public class MainActivity extends Activity {\n" + 201 | " public void onCreate(Bundle savedInstanceState) {\n" + 202 | " Runnable lambda = () -> Log.d(\"MainActivity\", \"Hello, Lambda2!\");\n" + 203 | " lambda.run();\n" + 204 | " }\n" + 205 | "}"); 206 | 207 | errorOutput = new StringWriter(); 208 | result = GradleRunner.create() 209 | .withGradleVersion(gradleVersion) 210 | .withProjectDir(rootDir) 211 | .withArguments("assembleDebug", "--stacktrace", "-Pandroid.enableAapt2=false") 212 | .forwardStdError(errorOutput) 213 | .build(); 214 | 215 | assertThat(result.task(":assembleDebug").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 216 | 217 | File mainClassFile = findFile(rootDir, "MainActivity.class"); 218 | File lambdaClassFile = findFile(rootDir, "MainActivity$$Lambda$1.class"); 219 | 220 | assertThat(mainClassFile).exists(); 221 | assertThat(lambdaClassFile).exists(); 222 | } 223 | 224 | @Test 225 | public void assembleDebugIncrementalShouldntLeak() throws Exception { 226 | writeFile(buildFile, 227 | //language="Groovy" 228 | "buildscript {\n" + 229 | " repositories {\n" + 230 | " maven { url 'https://maven.google.com' }\n" + 231 | " jcenter()\n" + 232 | " }\n" + 233 | " \n" + 234 | " dependencies {\n" + 235 | " classpath files(" + getPluginClasspath() + ")\n" + 236 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 237 | " }\n" + 238 | "}\n" + 239 | "\n" + 240 | "apply plugin: 'com.android.application'\n" + 241 | "apply plugin: 'me.tatarka.retrolambda'\n" + 242 | "\n" + 243 | "repositories {\n" + 244 | " maven { url 'https://maven.google.com' }\n" + 245 | " mavenCentral()\n" + 246 | "}\n" + 247 | "\n" + 248 | "android {\n" + 249 | " compileSdkVersion 24\n" + 250 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 251 | " \n" + 252 | " defaultConfig {\n" + 253 | " minSdkVersion 15\n" + 254 | " targetSdkVersion 24\n" + 255 | " }\n" + 256 | "}"); 257 | 258 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 259 | 260 | writeFile(manifestFile, 261 | //language="XML" 262 | "\n" + 264 | " \n" + 265 | ""); 266 | 267 | File javaFile = new File(rootDir, "src/main/java/MainActivity.java"); 268 | 269 | writeFile(javaFile, "package test;" + 270 | "import android.app.Activity;" + 271 | "import android.os.Bundle;" + 272 | "import android.util.Log;" + 273 | "public class MainActivity extends Activity {\n" + 274 | " public void onCreate(Bundle savedInstanceState) {\n" + 275 | " Runnable lambda = () -> Log.d(\"MainActivity\", \"Hello, Lambda!\");\n" + 276 | " lambda.run();\n" + 277 | " }\n" + 278 | "}"); 279 | 280 | StringWriter errorOutput = new StringWriter(); 281 | BuildResult result = GradleRunner.create() 282 | .withGradleVersion(gradleVersion) 283 | .withProjectDir(rootDir) 284 | .withArguments("assembleDebug", "--stacktrace", "-Pandroid.enableAapt2=false") 285 | .forwardStdError(errorOutput) 286 | .build(); 287 | 288 | assertThat(result.task(":assembleDebug").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 289 | 290 | 291 | File mainClassFile = findFile(rootDir, "MainActivity.class"); 292 | File lambdaClassFile = findFile(rootDir, "MainActivity$$Lambda$1.class"); 293 | 294 | assertThat(mainClassFile).exists(); 295 | assertThat(lambdaClassFile).exists(); 296 | 297 | // delete the java file 298 | if (!javaFile.delete()) { 299 | throw new Exception("Failed to delete file: " + javaFile); 300 | } 301 | 302 | errorOutput = new StringWriter(); 303 | result = GradleRunner.create() 304 | .withGradleVersion(gradleVersion) 305 | .withProjectDir(rootDir) 306 | .withArguments("assembleDebug", "--stacktrace", "-Pandroid.enableAapt2=false", "--debug") 307 | .forwardStdError(errorOutput) 308 | .build(); 309 | 310 | assertThat(result.task(":assembleDebug").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 311 | 312 | assertThat(mainClassFile).doesNotExist(); 313 | assertThat(lambdaClassFile).doesNotExist(); 314 | } 315 | 316 | @Test 317 | public void unitTest() throws Exception { 318 | writeFile(buildFile, 319 | //language="Groovy" 320 | "buildscript {\n" + 321 | " repositories {\n" + 322 | " maven { url 'https://maven.google.com' }\n" + 323 | " jcenter()\n" + 324 | " }\n" + 325 | " \n" + 326 | " dependencies {\n" + 327 | " classpath files(" + getPluginClasspath() + ")\n" + 328 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 329 | " }\n" + 330 | "}\n" + 331 | "\n" + 332 | "apply plugin: 'com.android.application'\n" + 333 | "apply plugin: 'me.tatarka.retrolambda'\n" + 334 | "\n" + 335 | "repositories {\n" + 336 | " maven { url 'https://maven.google.com' }\n" + 337 | " mavenCentral()\n" + 338 | "}\n" + 339 | "\n" + 340 | "android {\n" + 341 | " compileSdkVersion 24\n" + 342 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 343 | " \n" + 344 | " defaultConfig {\n" + 345 | " minSdkVersion 15\n" + 346 | " targetSdkVersion 24\n" + 347 | " }\n" + 348 | "}\n" + 349 | "\n" + 350 | "dependencies {\n" + 351 | " testCompile 'junit:junit:4.12'\n" + 352 | "}"); 353 | 354 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 355 | 356 | writeFile(manifestFile, 357 | //language="XML" 358 | "\n" + 360 | " \n" + 361 | ""); 362 | 363 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 364 | 365 | writeFile(javaFile, "import java.util.concurrent.Callable;\n" + 366 | "\n" + 367 | "public class Main {\n" + 368 | " public static Callable f() {\n" + 369 | " return () -> \"Hello, Lambda Test!\";\n" + 370 | " }\n" + 371 | "}"); 372 | 373 | File testJavaFile = new File(rootDir, "src/test/java/Test.java"); 374 | 375 | writeFile(testJavaFile, "import org.junit.Assert;\n" + 376 | "import org.junit.runner.RunWith;\n" + 377 | "import org.junit.runners.JUnit4;\n" + 378 | "\n" + 379 | "import java.util.concurrent.Callable;\n" + 380 | "\n" + 381 | "@RunWith(JUnit4.class)\n" + 382 | "public class Test {\n" + 383 | " @org.junit.Test\n" + 384 | " public void test() throws Exception {\n" + 385 | " Runnable lambda = () -> Assert.assertTrue(true);\n" + 386 | " lambda.run();\n" + 387 | " Assert.assertEquals(\"Hello, Lambda Test!\", Main.f().call());\n" + 388 | " }\n" + 389 | "}"); 390 | 391 | StringWriter errorOutput = new StringWriter(); 392 | BuildResult result = GradleRunner.create() 393 | .withGradleVersion(gradleVersion) 394 | .withProjectDir(rootDir) 395 | .withArguments("test", "--stacktrace", "-Pandroid.enableAapt2=false") 396 | .forwardStdError(errorOutput) 397 | .build(); 398 | 399 | assertThat(result.task(":test").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 400 | } 401 | 402 | @Test 403 | public void androidTest() throws Exception { 404 | writeFile(buildFile, 405 | //language="Groovy" 406 | "buildscript {\n" + 407 | " repositories {\n" + 408 | " maven { url 'https://maven.google.com' }\n" + 409 | " jcenter()\n" + 410 | " }\n" + 411 | " \n" + 412 | " dependencies {\n" + 413 | " classpath files(" + getPluginClasspath() + ")\n" + 414 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 415 | " }\n" + 416 | "}\n" + 417 | "\n" + 418 | "apply plugin: 'com.android.application'\n" + 419 | "apply plugin: 'me.tatarka.retrolambda'\n" + 420 | "\n" + 421 | "repositories {\n" + 422 | " maven { url 'https://maven.google.com' }\n" + 423 | " mavenCentral()\n" + 424 | "}\n" + 425 | "\n" + 426 | "android {\n" + 427 | " compileSdkVersion 23\n" + 428 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 429 | " \n" + 430 | " defaultConfig {\n" + 431 | " minSdkVersion 15\n" + 432 | " targetSdkVersion 24\n" + 433 | " testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n" + 434 | " }\n" + 435 | "}\n" + 436 | "\n" + 437 | "dependencies {\n" + 438 | " androidTestCompile 'com.android.support.test:runner:0.4'\n" + 439 | " androidTestCompile 'com.android.support.test:rules:0.4'\n" + 440 | "}"); 441 | 442 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 443 | 444 | writeFile(manifestFile, 445 | //language="XML" 446 | "\n" + 448 | " \n" + 449 | ""); 450 | 451 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 452 | 453 | writeFile(javaFile, "import java.util.concurrent.Callable;\n" + 454 | "\n" + 455 | "public class Main {\n" + 456 | " public static Callable f() {\n" + 457 | " return () -> \"Hello, Lambda Test!\";\n" + 458 | " }\n" + 459 | "}"); 460 | 461 | File testJavaFile = new File(rootDir, "src/androidTest/java/Test.java"); 462 | 463 | writeFile(testJavaFile, "import org.junit.Assert;\n" + 464 | "import org.junit.runner.RunWith;\n" + 465 | "import android.support.test.runner.AndroidJUnit4;\n" + 466 | "\n" + 467 | "import java.util.concurrent.Callable;\n" + 468 | "\n" + 469 | "@RunWith(AndroidJUnit4.class)\n" + 470 | "public class Test {\n" + 471 | " @org.junit.Test\n" + 472 | " public void test() throws Exception {\n" + 473 | " Runnable lambda = () -> Assert.assertTrue(true);\n" + 474 | " lambda.run();\n" + 475 | " Assert.assertEquals(\"Hello, Lambda Test!\", Main.f().call());\n" + 476 | " }\n" + 477 | "}"); 478 | 479 | StringWriter errorOutput = new StringWriter(); 480 | BuildResult result = GradleRunner.create() 481 | .withGradleVersion(gradleVersion) 482 | .withProjectDir(rootDir) 483 | .withArguments("connectedCheck", "--stacktrace", "-Pandroid.enableAapt2=false") 484 | .forwardStdError(errorOutput) 485 | .build(); 486 | 487 | assertThat(result.task(":connectedCheck").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 488 | } 489 | 490 | @Test 491 | public void withKotlin() throws Exception { 492 | writeFile(buildFile, 493 | //language="Groovy" 494 | "buildscript {\n" + 495 | " repositories {\n" + 496 | " maven { url 'https://maven.google.com' }\n" + 497 | " jcenter()\n" + 498 | " }\n" + 499 | " \n" + 500 | " dependencies {\n" + 501 | " classpath files(" + getPluginClasspath() + ")\n" + 502 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 503 | " classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:" + kotlinVersion + "'" + 504 | " }\n" + 505 | "}\n" + 506 | "\n" + 507 | "apply plugin: 'com.android.application'\n" + 508 | "apply plugin: 'me.tatarka.retrolambda'\n" + 509 | "apply plugin: 'kotlin-android'\n" + 510 | "\n" + 511 | "repositories {\n" + 512 | " maven { url 'https://maven.google.com' }\n" + 513 | " mavenCentral()\n" + 514 | "}\n" + 515 | "\n" + 516 | "android {\n" + 517 | " compileSdkVersion 24\n" + 518 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 519 | " \n" + 520 | " defaultConfig {\n" + 521 | " minSdkVersion 15\n" + 522 | " targetSdkVersion 24\n" + 523 | " }\n" + 524 | "}\n" + 525 | "dependencies {\n" + 526 | " compile 'org.jetbrains.kotlin:kotlin-stdlib:1.1.0'\n" + 527 | "}"); 528 | 529 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 530 | 531 | writeFile(manifestFile, 532 | //language="XML" 533 | "\n" + 535 | " \n" + 536 | ""); 537 | 538 | File javaFile1 = new File(rootDir, "src/main/java/test/MainActivity.java"); 539 | File javaFile2 = new File(rootDir, "src/main/java/test/JavaFile.java"); 540 | 541 | File kotlinFile = new File(rootDir, "src/main/kotlin/test/KotlinFile.kt"); 542 | 543 | writeFile(javaFile1, "package test;" + 544 | "import android.app.Activity;" + 545 | "import android.os.Bundle;" + 546 | "import android.util.Log;" + 547 | "public class MainActivity extends Activity {\n" + 548 | " public void onCreate(Bundle savedInstanceState) {\n" + 549 | " Runnable lambda = () -> Log.d(\"MainActivity\", \"Hello, Lambda!\");\n" + 550 | " lambda.run();\n" + 551 | " new KotlinFile().doThis();" + 552 | " }\n" + 553 | "}"); 554 | 555 | writeFile(javaFile2, "package test;" + 556 | "public class JavaFile {\n" + 557 | " public void doThat() {\n" + 558 | " System.out.println(\"That\");" + 559 | " }" + 560 | "}"); 561 | 562 | writeFile(kotlinFile, "package test\n" + 563 | "import kotlin.io.println\n" + 564 | "class KotlinFile {\n" + 565 | "public fun doThis() {\n" + 566 | " println(\"This\")\n" + 567 | " JavaFile().doThat()\n" + 568 | "}\n" + 569 | "}"); 570 | 571 | StringWriter errorOutput = new StringWriter(); 572 | BuildResult result = GradleRunner.create() 573 | .withGradleVersion(gradleVersion) 574 | .withProjectDir(rootDir) 575 | .withArguments("assembleDebug", "--stacktrace", "-Pandroid.enableAapt2=false") 576 | .forwardStdError(errorOutput) 577 | .build(); 578 | 579 | assertThat(result.task(":assembleDebug").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 580 | 581 | File mainClassFile = findFile(rootDir, "MainActivity.class"); 582 | File lambdaClassFile = findFile(rootDir, "MainActivity$$Lambda$1.class"); 583 | 584 | assertThat(mainClassFile).exists(); 585 | assertThat(lambdaClassFile).exists(); 586 | } 587 | } 588 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/test/java/me/tatarka/AndroidFeaturePluginTest.java: -------------------------------------------------------------------------------- 1 | package me.tatarka; 2 | 3 | 4 | import org.gradle.testkit.runner.BuildResult; 5 | import org.gradle.testkit.runner.GradleRunner; 6 | import org.gradle.testkit.runner.TaskOutcome; 7 | import org.junit.Before; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.rules.TemporaryFolder; 11 | import org.junit.runner.RunWith; 12 | import org.junit.runners.Parameterized; 13 | 14 | import java.io.File; 15 | import java.io.StringWriter; 16 | import java.util.Arrays; 17 | import java.util.Collection; 18 | 19 | import static me.tatarka.TestHelpers.*; 20 | import static org.assertj.core.api.Assertions.assertThat; 21 | 22 | @RunWith(Parameterized.class) 23 | public class AndroidFeaturePluginTest { 24 | 25 | @Parameterized.Parameters(name = "{0}") 26 | public static Collection data() { 27 | return Arrays.asList(new Object[][]{ 28 | oldestSupportedAndroidFeaturePluginVersion(), 29 | newestSupportedAndroidPluginVersion() 30 | }); 31 | } 32 | 33 | @Rule 34 | public final TemporaryFolder testProjectDir = new TemporaryFolder(); 35 | private final String androidVersion; 36 | private final String gradleVersion; 37 | private final String buildToolsVersion; 38 | private final String compileSdkVersion; 39 | private File rootDir; 40 | private File buildFile; 41 | 42 | public AndroidFeaturePluginTest(String androidVersion, String gradleVersion, String buildToolsVersion, String kotlinVersion) { 43 | this.androidVersion = androidVersion; 44 | this.gradleVersion = gradleVersion; 45 | this.buildToolsVersion = buildToolsVersion; 46 | this.compileSdkVersion = buildToolsVersion.substring(0, buildToolsVersion.indexOf('.')); 47 | } 48 | 49 | @Before 50 | public void setup() throws Exception { 51 | rootDir = testProjectDir.getRoot(); 52 | buildFile = testProjectDir.newFile("build.gradle"); 53 | copyLocalPropertiesIfExists(rootDir); 54 | } 55 | 56 | @Test 57 | public void assembleDebug() throws Exception { 58 | writeFile(buildFile, 59 | //language="Groovy" 60 | "buildscript {\n" + 61 | " repositories {\n" + 62 | " maven { url 'https://maven.google.com' }\n" + 63 | " jcenter()\n" + 64 | " }\n" + 65 | " \n" + 66 | " dependencies {\n" + 67 | " classpath files(" + getPluginClasspath() + ")\n" + 68 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 69 | " }\n" + 70 | "}\n" + 71 | "\n" + 72 | "apply plugin: 'com.android.feature'\n" + 73 | "apply plugin: 'me.tatarka.retrolambda'\n" + 74 | "\n" + 75 | "repositories {\n" + 76 | " maven { url 'https://maven.google.com' }\n" + 77 | " mavenCentral()\n" + 78 | " jcenter()\n" + 79 | "}\n" + 80 | "\n" + 81 | "android {\n" + 82 | " compileSdkVersion " + compileSdkVersion + "\n" + 83 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 84 | " \n" + 85 | " defaultConfig {\n" + 86 | " minSdkVersion 15\n" + 87 | " targetSdkVersion 24\n" + 88 | " }\n" + 89 | "}"); 90 | 91 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 92 | 93 | writeFile(manifestFile, 94 | //language="XML" 95 | "\n" + 97 | " \n" + 98 | ""); 99 | 100 | File javaFile = new File(rootDir, "src/main/java/MainActivity.java"); 101 | 102 | writeFile(javaFile, "package test;" + 103 | "import android.app.Activity;" + 104 | "import android.os.Bundle;" + 105 | "import android.util.Log;" + 106 | "public class MainActivity extends Activity {\n" + 107 | " public void onCreate(Bundle savedInstanceState) {\n" + 108 | " Runnable lambda = () -> Log.d(\"MainActivity\", \"Hello, Lambda!\");\n" + 109 | " lambda.run();\n" + 110 | " }\n" + 111 | "}"); 112 | 113 | StringWriter errorOutput = new StringWriter(); 114 | BuildResult result = GradleRunner.create() 115 | .withGradleVersion(gradleVersion) 116 | .withProjectDir(rootDir) 117 | .withArguments("assembleDebug", "--stacktrace") 118 | .forwardStdError(errorOutput) 119 | .build(); 120 | 121 | assertThat(result.task(":assembleDebug").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 122 | 123 | File mainClassFile = findFile(rootDir, "MainActivity.class"); 124 | File lambdaClassFile = findFile(rootDir, "MainActivity$$Lambda$1.class"); 125 | 126 | assertThat(mainClassFile).exists(); 127 | assertThat(lambdaClassFile).exists(); 128 | } 129 | 130 | @Test 131 | public void unitTest() throws Exception { 132 | writeFile(buildFile, 133 | //language="Groovy" 134 | "buildscript {\n" + 135 | " repositories {\n" + 136 | " maven { url 'https://maven.google.com' }\n" + 137 | " jcenter()\n" + 138 | " }\n" + 139 | " \n" + 140 | " dependencies {\n" + 141 | " classpath files(" + getPluginClasspath() + ")\n" + 142 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 143 | " }\n" + 144 | "}\n" + 145 | "\n" + 146 | "apply plugin: 'com.android.feature'\n" + 147 | "apply plugin: 'me.tatarka.retrolambda'\n" + 148 | "\n" + 149 | "repositories {\n" + 150 | " maven { url 'https://maven.google.com' }\n" + 151 | " mavenCentral()\n" + 152 | " jcenter()\n" + 153 | "}\n" + 154 | "\n" + 155 | "android {\n" + 156 | " compileSdkVersion " + compileSdkVersion + "\n" + 157 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 158 | " \n" + 159 | " defaultConfig {\n" + 160 | " minSdkVersion 15\n" + 161 | " targetSdkVersion 24\n" + 162 | " }\n" + 163 | "}\n" + 164 | "\n" + 165 | "dependencies {\n" + 166 | " testCompile 'junit:junit:4.12'\n" + 167 | "}"); 168 | 169 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 170 | 171 | writeFile(manifestFile, 172 | //language="XML" 173 | "\n" + 175 | " \n" + 176 | ""); 177 | 178 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 179 | 180 | writeFile(javaFile, "import java.util.concurrent.Callable;\n" + 181 | "\n" + 182 | "public class Main {\n" + 183 | " public static Callable f() {\n" + 184 | " return () -> \"Hello, Lambda Test!\";\n" + 185 | " }\n" + 186 | "}"); 187 | 188 | File testJavaFile = new File(rootDir, "src/test/java/Test.java"); 189 | 190 | writeFile(testJavaFile, "import org.junit.Assert;\n" + 191 | "import org.junit.runner.RunWith;\n" + 192 | "import org.junit.runners.JUnit4;\n" + 193 | "\n" + 194 | "import java.util.concurrent.Callable;\n" + 195 | "\n" + 196 | "@RunWith(JUnit4.class)\n" + 197 | "public class Test {\n" + 198 | " @org.junit.Test\n" + 199 | " public void test() throws Exception {\n" + 200 | " Runnable lambda = () -> Assert.assertTrue(true);\n" + 201 | " lambda.run();\n" + 202 | " Assert.assertEquals(\"Hello, Lambda Test!\", Main.f().call());\n" + 203 | " }\n" + 204 | "}"); 205 | 206 | StringWriter errorOutput = new StringWriter(); 207 | BuildResult result = GradleRunner.create() 208 | .withGradleVersion(gradleVersion) 209 | .withProjectDir(rootDir) 210 | .withArguments("test", "--stacktrace") 211 | .forwardStdError(errorOutput) 212 | .build(); 213 | 214 | assertThat(result.task(":test").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 215 | } 216 | 217 | @Test 218 | public void androidTest() throws Exception { 219 | writeFile(buildFile, 220 | //language="Groovy" 221 | "buildscript {\n" + 222 | " repositories {\n" + 223 | " maven { url 'https://maven.google.com' }\n" + 224 | " jcenter()\n" + 225 | " }\n" + 226 | " \n" + 227 | " dependencies {\n" + 228 | " classpath files(" + getPluginClasspath() + ")\n" + 229 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 230 | " }\n" + 231 | "}\n" + 232 | "\n" + 233 | "apply plugin: 'com.android.feature'\n" + 234 | "apply plugin: 'me.tatarka.retrolambda'\n" + 235 | "\n" + 236 | "repositories {\n" + 237 | " maven { url 'https://maven.google.com' }\n" + 238 | " mavenCentral()\n" + 239 | " jcenter()\n" + 240 | "}\n" + 241 | "\n" + 242 | "android {\n" + 243 | " compileSdkVersion " + compileSdkVersion + "\n" + 244 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 245 | " \n" + 246 | " defaultConfig {\n" + 247 | " minSdkVersion 15\n" + 248 | " targetSdkVersion 24\n" + 249 | " testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n" + 250 | " }\n" + 251 | "}\n" + 252 | "\n" + 253 | "dependencies {\n" + 254 | " androidTestCompile 'com.android.support.test:runner:0.5'\n" + 255 | " androidTestCompile 'com.android.support.test:rules:0.5'\n" + 256 | "}"); 257 | 258 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 259 | 260 | writeFile(manifestFile, 261 | //language="XML" 262 | "\n" + 264 | " \n" + 265 | ""); 266 | 267 | File javaFile = new File(rootDir, "src/main/java/test/Main.java"); 268 | 269 | writeFile(javaFile, "package test;\nimport java.util.concurrent.Callable;\n" + 270 | "\n" + 271 | "public class Main {\n" + 272 | " public static Callable f() {\n" + 273 | " return () -> \"Hello, Lambda Test!\";\n" + 274 | " }\n" + 275 | "}"); 276 | 277 | File testJavaFile = new File(rootDir, "src/androidTest/java/test/Test.java"); 278 | 279 | writeFile(testJavaFile, "package test;\nimport org.junit.Assert;\n" + 280 | "import org.junit.runner.RunWith;\n" + 281 | "import android.support.test.runner.AndroidJUnit4;\n" + 282 | "\n" + 283 | "import java.util.concurrent.Callable;\n" + 284 | "\n" + 285 | "@RunWith(AndroidJUnit4.class)\n" + 286 | "public class Test {\n" + 287 | " @org.junit.Test\n" + 288 | " public void test() throws Exception {\n" + 289 | " Runnable lambda = () -> Assert.assertTrue(true);\n" + 290 | " lambda.run();\n" + 291 | " Assert.assertEquals(\"Hello, Lambda Test!\", Main.f().call());\n" + 292 | " }\n" + 293 | "}"); 294 | 295 | StringWriter errorOutput = new StringWriter(); 296 | BuildResult result = GradleRunner.create() 297 | .withGradleVersion(gradleVersion) 298 | .withProjectDir(rootDir) 299 | .withArguments("connectedCheck", "--stacktrace") 300 | .forwardStdError(errorOutput) 301 | .build(); 302 | 303 | assertThat(result.task(":connectedCheck").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 304 | } 305 | } 306 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/test/java/me/tatarka/AndroidLibPluginTest.java: -------------------------------------------------------------------------------- 1 | package me.tatarka; 2 | 3 | 4 | import org.gradle.testkit.runner.BuildResult; 5 | import org.gradle.testkit.runner.GradleRunner; 6 | import org.gradle.testkit.runner.TaskOutcome; 7 | import org.junit.Before; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.rules.TemporaryFolder; 11 | import org.junit.runner.RunWith; 12 | import org.junit.runners.Parameterized; 13 | 14 | import java.io.File; 15 | import java.io.StringWriter; 16 | import java.util.Arrays; 17 | import java.util.Collection; 18 | 19 | import static me.tatarka.TestHelpers.*; 20 | import static org.assertj.core.api.Assertions.assertThat; 21 | 22 | @RunWith(Parameterized.class) 23 | public class AndroidLibPluginTest { 24 | 25 | @Parameterized.Parameters(name = "{0}") 26 | public static Collection data() { 27 | return Arrays.asList(new Object[][]{ 28 | oldestSupportedAndroidPluginVersion(), 29 | newestSupportedAndroidPluginVersion() 30 | }); 31 | } 32 | 33 | @Rule 34 | public final TemporaryFolder testProjectDir = new TemporaryFolder(); 35 | private final String androidVersion; 36 | private final String gradleVersion; 37 | private final String buildToolsVersion; 38 | private final String compileSdkVersion; 39 | private File rootDir; 40 | private File buildFile; 41 | 42 | public AndroidLibPluginTest(String androidVersion, String gradleVersion, String buildToolsVersion, String kotlinVersion) { 43 | this.androidVersion = androidVersion; 44 | this.gradleVersion = gradleVersion; 45 | this.buildToolsVersion = buildToolsVersion; 46 | this.compileSdkVersion = buildToolsVersion.substring(0, buildToolsVersion.indexOf('.')); 47 | } 48 | 49 | @Before 50 | public void setup() throws Exception { 51 | rootDir = testProjectDir.getRoot(); 52 | buildFile = testProjectDir.newFile("build.gradle"); 53 | copyLocalPropertiesIfExists(rootDir); 54 | } 55 | 56 | @Test 57 | public void assembleDebug() throws Exception { 58 | writeFile(buildFile, 59 | //language="Groovy" 60 | "buildscript {\n" + 61 | " repositories {\n" + 62 | " maven { url 'https://maven.google.com' }\n" + 63 | " jcenter()\n" + 64 | " }\n" + 65 | " \n" + 66 | " dependencies {\n" + 67 | " classpath files(" + getPluginClasspath() + ")\n" + 68 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 69 | " }\n" + 70 | "}\n" + 71 | "\n" + 72 | "apply plugin: 'com.android.library'\n" + 73 | "apply plugin: 'me.tatarka.retrolambda'\n" + 74 | "\n" + 75 | "repositories {\n" + 76 | " maven { url 'https://maven.google.com' }\n" + 77 | " mavenCentral()\n" + 78 | " jcenter()\n" + 79 | "}\n" + 80 | "\n" + 81 | "android {\n" + 82 | " compileSdkVersion " + compileSdkVersion + "\n" + 83 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 84 | " \n" + 85 | " defaultConfig {\n" + 86 | " minSdkVersion 15\n" + 87 | " targetSdkVersion 24\n" + 88 | " }\n" + 89 | "}"); 90 | 91 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 92 | 93 | writeFile(manifestFile, 94 | //language="XML" 95 | "\n" + 97 | " \n" + 98 | ""); 99 | 100 | File javaFile = new File(rootDir, "src/main/java/MainActivity.java"); 101 | 102 | writeFile(javaFile, "package test;" + 103 | "import android.app.Activity;" + 104 | "import android.os.Bundle;" + 105 | "import android.util.Log;" + 106 | "public class MainActivity extends Activity {\n" + 107 | " public void onCreate(Bundle savedInstanceState) {\n" + 108 | " Runnable lambda = () -> Log.d(\"MainActivity\", \"Hello, Lambda!\");\n" + 109 | " lambda.run();\n" + 110 | " }\n" + 111 | "}"); 112 | 113 | StringWriter errorOutput = new StringWriter(); 114 | BuildResult result = GradleRunner.create() 115 | .withGradleVersion(gradleVersion) 116 | .withProjectDir(rootDir) 117 | .withArguments("assembleDebug", "--stacktrace") 118 | .forwardStdError(errorOutput) 119 | .build(); 120 | 121 | assertThat(result.task(":assembleDebug").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 122 | 123 | File mainClassFile = findFile(rootDir, "MainActivity.class"); 124 | File lambdaClassFile = findFile(rootDir, "MainActivity$$Lambda$1.class"); 125 | 126 | assertThat(mainClassFile).exists(); 127 | assertThat(lambdaClassFile).exists(); 128 | } 129 | 130 | @Test 131 | public void unitTest() throws Exception { 132 | writeFile(buildFile, 133 | //language="Groovy" 134 | "buildscript {\n" + 135 | " repositories {\n" + 136 | " maven { url 'https://maven.google.com' }\n" + 137 | " jcenter()\n" + 138 | " }\n" + 139 | " \n" + 140 | " dependencies {\n" + 141 | " classpath files(" + getPluginClasspath() + ")\n" + 142 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 143 | " }\n" + 144 | "}\n" + 145 | "\n" + 146 | "apply plugin: 'com.android.library'\n" + 147 | "apply plugin: 'me.tatarka.retrolambda'\n" + 148 | "\n" + 149 | "repositories {\n" + 150 | " maven { url 'https://maven.google.com' }\n" + 151 | " mavenCentral()\n" + 152 | "}\n" + 153 | "\n" + 154 | "android {\n" + 155 | " compileSdkVersion " + compileSdkVersion + "\n" + 156 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 157 | " \n" + 158 | " defaultConfig {\n" + 159 | " minSdkVersion 15\n" + 160 | " targetSdkVersion 24\n" + 161 | " }\n" + 162 | "}\n" + 163 | "\n" + 164 | "dependencies {\n" + 165 | " testCompile 'junit:junit:4.12'\n" + 166 | "}"); 167 | 168 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 169 | 170 | writeFile(manifestFile, 171 | //language="XML" 172 | "\n" + 174 | " \n" + 175 | ""); 176 | 177 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 178 | 179 | writeFile(javaFile, "import java.util.concurrent.Callable;\n" + 180 | "\n" + 181 | "public class Main {\n" + 182 | " public static Callable f() {\n" + 183 | " return () -> \"Hello, Lambda Test!\";\n" + 184 | " }\n" + 185 | "}"); 186 | 187 | File testJavaFile = new File(rootDir, "src/test/java/Test.java"); 188 | 189 | writeFile(testJavaFile, "import org.junit.Assert;\n" + 190 | "import org.junit.runner.RunWith;\n" + 191 | "import org.junit.runners.JUnit4;\n" + 192 | "\n" + 193 | "import java.util.concurrent.Callable;\n" + 194 | "\n" + 195 | "@RunWith(JUnit4.class)\n" + 196 | "public class Test {\n" + 197 | " @org.junit.Test\n" + 198 | " public void test() throws Exception {\n" + 199 | " Runnable lambda = () -> Assert.assertTrue(true);\n" + 200 | " lambda.run();\n" + 201 | " Assert.assertEquals(\"Hello, Lambda Test!\", Main.f().call());\n" + 202 | " }\n" + 203 | "}"); 204 | 205 | StringWriter errorOutput = new StringWriter(); 206 | BuildResult result = GradleRunner.create() 207 | .withGradleVersion(gradleVersion) 208 | .withProjectDir(rootDir) 209 | .withArguments("test", "--stacktrace") 210 | .forwardStdError(errorOutput) 211 | .build(); 212 | 213 | assertThat(result.task(":test").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 214 | } 215 | 216 | @Test 217 | public void androidTest() throws Exception { 218 | writeFile(buildFile, 219 | //language="Groovy" 220 | "buildscript {\n" + 221 | " repositories {\n" + 222 | " maven { url 'https://maven.google.com' }\n" + 223 | " jcenter()\n" + 224 | " }\n" + 225 | " \n" + 226 | " dependencies {\n" + 227 | " classpath files(" + getPluginClasspath() + ")\n" + 228 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 229 | " }\n" + 230 | "}\n" + 231 | "\n" + 232 | "apply plugin: 'com.android.library'\n" + 233 | "apply plugin: 'me.tatarka.retrolambda'\n" + 234 | "\n" + 235 | "repositories {\n" + 236 | " maven { url 'https://maven.google.com' }\n" + 237 | " mavenCentral()\n" + 238 | "}\n" + 239 | "\n" + 240 | "android {\n" + 241 | " compileSdkVersion " + compileSdkVersion + "\n" + 242 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 243 | " \n" + 244 | " defaultConfig {\n" + 245 | " minSdkVersion 15\n" + 246 | " targetSdkVersion 24\n" + 247 | " testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n" + 248 | " }\n" + 249 | "}\n" + 250 | "\n" + 251 | "dependencies {\n" + 252 | " androidTestCompile 'com.android.support.test:runner:0.5'\n" + 253 | " androidTestCompile 'com.android.support.test:rules:0.5'\n" + 254 | "}"); 255 | 256 | File manifestFile = new File(rootDir, "src/main/AndroidManifest.xml"); 257 | 258 | writeFile(manifestFile, 259 | //language="XML" 260 | "\n" + 262 | " \n" + 263 | ""); 264 | 265 | File javaFile = new File(rootDir, "src/main/java/test/Main.java"); 266 | 267 | writeFile(javaFile, "package test;\nimport java.util.concurrent.Callable;\n" + 268 | "\n" + 269 | "public class Main {\n" + 270 | " public static Callable f() {\n" + 271 | " return () -> \"Hello, Lambda Test!\";\n" + 272 | " }\n" + 273 | "}"); 274 | 275 | File testJavaFile = new File(rootDir, "src/androidTest/java/test/Test.java"); 276 | 277 | writeFile(testJavaFile, "package test;\nimport org.junit.Assert;\n" + 278 | "import org.junit.runner.RunWith;\n" + 279 | "import android.support.test.runner.AndroidJUnit4;\n" + 280 | "\n" + 281 | "import java.util.concurrent.Callable;\n" + 282 | "\n" + 283 | "@RunWith(AndroidJUnit4.class)\n" + 284 | "public class Test {\n" + 285 | " @org.junit.Test\n" + 286 | " public void test() throws Exception {\n" + 287 | " Runnable lambda = () -> Assert.assertTrue(true);\n" + 288 | " lambda.run();\n" + 289 | " Assert.assertEquals(\"Hello, Lambda Test!\", Main.f().call());\n" + 290 | " }\n" + 291 | "}"); 292 | 293 | StringWriter errorOutput = new StringWriter(); 294 | BuildResult result = GradleRunner.create() 295 | .withGradleVersion(gradleVersion) 296 | .withProjectDir(rootDir) 297 | .withArguments("connectedCheck", "--stacktrace") 298 | .forwardStdError(errorOutput) 299 | .build(); 300 | 301 | assertThat(result.task(":connectedCheck").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/test/java/me/tatarka/AndroidTestPluginTest.java: -------------------------------------------------------------------------------- 1 | package me.tatarka; 2 | 3 | 4 | import org.gradle.testkit.runner.BuildResult; 5 | import org.gradle.testkit.runner.GradleRunner; 6 | import org.gradle.testkit.runner.TaskOutcome; 7 | import org.junit.Before; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.rules.TemporaryFolder; 11 | import org.junit.runner.RunWith; 12 | import org.junit.runners.Parameterized; 13 | 14 | import java.io.File; 15 | import java.io.StringWriter; 16 | import java.util.Arrays; 17 | import java.util.Collection; 18 | 19 | import static me.tatarka.TestHelpers.*; 20 | import static org.assertj.core.api.Assertions.assertThat; 21 | 22 | @RunWith(Parameterized.class) 23 | public class AndroidTestPluginTest { 24 | 25 | @Parameterized.Parameters(name = "{0}") 26 | public static Collection data() { 27 | return Arrays.asList(new Object[][]{ 28 | //oldestSupportedAndroidPluginVersion(), 29 | newestSupportedAndroidPluginVersion() 30 | }); 31 | } 32 | 33 | @Rule 34 | public final TemporaryFolder testProjectDir = new TemporaryFolder(); 35 | private final String androidVersion; 36 | private final String gradleVersion; 37 | private final String buildToolsVersion; 38 | private File rootDir; 39 | 40 | public AndroidTestPluginTest(String androidVersion, String gradleVersion, String buildToolsVersion, String kotlinVersion) { 41 | this.androidVersion = androidVersion; 42 | this.gradleVersion = gradleVersion; 43 | this.buildToolsVersion = buildToolsVersion; 44 | } 45 | 46 | @Before 47 | public void setup() throws Exception { 48 | rootDir = testProjectDir.getRoot(); 49 | testProjectDir.newFile("build.gradle"); 50 | copyLocalPropertiesIfExists(rootDir); 51 | } 52 | 53 | @Test 54 | public void test() throws Exception { 55 | File settingsFile = testProjectDir.newFile("settings.gradle"); 56 | writeFile(settingsFile, 57 | //language="Groovy" 58 | "include \":app\", \":test\""); 59 | 60 | File appRootDir = testProjectDir.newFolder("app"); 61 | writeFile(new File(appRootDir, "build.gradle"), 62 | //language="Groovy" 63 | "buildscript {\n" + 64 | " System.properties['com.android.build.gradle.overrideVersionCheck'] = 'true'\n" + 65 | " \n" + 66 | " repositories {\n" + 67 | " maven { url 'https://maven.google.com' }\n" + 68 | " jcenter()\n" + 69 | " }\n" + 70 | " \n" + 71 | " dependencies {\n" + 72 | " classpath files(" + getPluginClasspath() + ")\n" + 73 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 74 | " }\n" + 75 | "}\n" + 76 | "\n" + 77 | "apply plugin: 'com.android.application'\n" + 78 | "apply plugin: 'me.tatarka.retrolambda'\n" + 79 | "\n" + 80 | "repositories {\n" + 81 | " maven { url 'https://maven.google.com' }\n" + 82 | " mavenCentral()\n" + 83 | "}\n" + 84 | "\n" + 85 | "android {\n" + 86 | " compileSdkVersion 24\n" + 87 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 88 | " \n" + 89 | " defaultConfig {\n" + 90 | " applicationId \"test.app\"\n" + 91 | " minSdkVersion 15\n" + 92 | " targetSdkVersion 24\n" + 93 | " }\n" + 94 | " \n" + 95 | " publishNonDefault true\n" + 96 | "}"); 97 | 98 | File appManifestFile = new File(appRootDir, "src/main/AndroidManifest.xml"); 99 | 100 | writeFile(appManifestFile, 101 | //language="XML" 102 | "\n" + 104 | " \n" + 105 | ""); 106 | 107 | File javaFile = new File(appRootDir, "src/main/java/Main.java"); 108 | 109 | writeFile(javaFile, "import java.util.concurrent.Callable;\n" + 110 | "\n" + 111 | "public class Main {\n" + 112 | " public static Callable f() {\n" + 113 | " return () -> \"Hello, Lambda Test!\";\n" + 114 | " }\n" + 115 | "}"); 116 | 117 | File testRootDir = testProjectDir.newFolder("test"); 118 | writeFile(new File(testRootDir, "build.gradle"), 119 | //language="Groovy" 120 | "buildscript {\n" + 121 | " repositories {\n" + 122 | " maven { url 'https://maven.google.com' }\n" + 123 | " jcenter()\n" + 124 | " }\n" + 125 | " \n" + 126 | " dependencies {\n" + 127 | " classpath files(" + getPluginClasspath() + ")\n" + 128 | " classpath 'com.android.tools.build:gradle:" + androidVersion + "'\n" + 129 | " }\n" + 130 | "}\n" + 131 | "\n" + 132 | "apply plugin: 'com.android.test'\n" + 133 | "apply plugin: 'me.tatarka.retrolambda'\n" + 134 | "\n" + 135 | "repositories {\n" + 136 | " maven { url 'https://maven.google.com' }\n" + 137 | " mavenCentral()\n" + 138 | "}\n" + 139 | "\n" + 140 | "android {\n" + 141 | " compileSdkVersion 23\n" + 142 | " buildToolsVersion '" + buildToolsVersion + "'\n" + 143 | " \n" + 144 | " targetProjectPath ':app'\n" + 145 | " targetVariant 'debug'\n" + 146 | " \n" + 147 | " defaultConfig {\n" + 148 | " minSdkVersion 15\n" + 149 | " targetSdkVersion 24\n" + 150 | " testInstrumentationRunner \"android.support.test.runner.AndroidJUnitRunner\"\n" + 151 | " }\n" + 152 | "}\n" + 153 | "\n" + 154 | "dependencies {\n" + 155 | " compile 'com.android.support.test:runner:0.4'\n" + 156 | " compile 'com.android.support.test:rules:0.4'\n" + 157 | "}"); 158 | 159 | File testManifestFile = new File(testRootDir, "src/main/AndroidManifest.xml"); 160 | 161 | writeFile(testManifestFile, 162 | //language="XML" 163 | "\n" + 165 | " \n" + 166 | ""); 167 | 168 | File testJavaFile = new File(testRootDir, "src/main/java/Test.java"); 169 | 170 | writeFile(testJavaFile, "import org.junit.Assert;\n" + 171 | "import org.junit.runner.RunWith;\n" + 172 | "import android.support.test.runner.AndroidJUnit4;\n" + 173 | "\n" + 174 | "import java.util.concurrent.Callable;\n" + 175 | "\n" + 176 | "@RunWith(AndroidJUnit4.class)\n" + 177 | "public class Test {\n" + 178 | " @org.junit.Test\n" + 179 | " public void test() throws Exception {\n" + 180 | " Runnable lambda = () -> Assert.assertTrue(true);\n" + 181 | " lambda.run();\n" + 182 | " Assert.assertEquals(\"Hello, Lambda Test!\", Main.f().call());\n" + 183 | " }\n" + 184 | "}"); 185 | 186 | StringWriter errorOutput = new StringWriter(); 187 | BuildResult result = GradleRunner.create() 188 | .withGradleVersion(gradleVersion) 189 | .withProjectDir(rootDir) 190 | .withArguments("connectedCheck", "--stacktrace") 191 | .forwardStdError(errorOutput) 192 | .build(); 193 | 194 | assertThat(result.task(":test:connectedCheck").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/test/java/me/tatarka/GroovyPluginTest.java: -------------------------------------------------------------------------------- 1 | package me.tatarka; 2 | 3 | 4 | import org.gradle.testkit.runner.BuildResult; 5 | import org.gradle.testkit.runner.GradleRunner; 6 | import org.gradle.testkit.runner.TaskOutcome; 7 | import org.junit.Before; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.rules.TemporaryFolder; 11 | import org.junit.runner.RunWith; 12 | import org.junit.runners.JUnit4; 13 | import org.junit.runners.Parameterized; 14 | 15 | import java.io.File; 16 | import java.io.StringWriter; 17 | import java.util.Arrays; 18 | import java.util.Collection; 19 | 20 | import static me.tatarka.TestHelpers.findFile; 21 | import static me.tatarka.TestHelpers.getPluginClasspath; 22 | import static me.tatarka.TestHelpers.newestSupportedGradleVersion; 23 | import static me.tatarka.TestHelpers.oldestSupportedGradleVersion; 24 | import static me.tatarka.TestHelpers.writeFile; 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | @RunWith(Parameterized.class) 28 | public class GroovyPluginTest { 29 | 30 | @Parameterized.Parameters(name = "{0}") 31 | public static Collection data() { 32 | return Arrays.asList(new Object[][]{ 33 | oldestSupportedGradleVersion(), 34 | newestSupportedGradleVersion() 35 | }); 36 | } 37 | 38 | @Rule 39 | public final TemporaryFolder testProjectDir = new TemporaryFolder(); 40 | private final String gradleVersion; 41 | private File rootDir; 42 | private File buildFile; 43 | 44 | public GroovyPluginTest(String gradleVersion) { 45 | this.gradleVersion = gradleVersion; 46 | } 47 | 48 | @Before 49 | public void setup() throws Exception { 50 | rootDir = testProjectDir.getRoot(); 51 | buildFile = testProjectDir.newFile("build.gradle"); 52 | } 53 | 54 | @Test 55 | public void assemble() throws Exception { 56 | writeFile(buildFile, "buildscript {\n" + 57 | " dependencies {\n" + 58 | " classpath files(" + getPluginClasspath() + ")\n" + 59 | " }\n" + 60 | "}\n" + 61 | "\n" + 62 | "apply plugin: 'groovy'\n" + 63 | "apply plugin: 'me.tatarka.retrolambda'\n" + 64 | "\n" + 65 | "repositories {\n" + 66 | " mavenCentral()\n" + 67 | "}\n" + 68 | "\n" + 69 | "dependencies {\n" + 70 | " compile 'org.codehaus.groovy:groovy-all:2.4.7'\n" + 71 | "}"); 72 | 73 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 74 | 75 | writeFile(javaFile, "public class Main {\n" + 76 | " public static void main(String[] args) {\n" + 77 | " Runnable lambda = () -> System.out.println(\"Hello, Lambda!\");\n" + 78 | " lambda.run();\n" + 79 | " }\n" + 80 | "}"); 81 | 82 | StringWriter errorOutput = new StringWriter(); 83 | BuildResult result = GradleRunner.create() 84 | .withGradleVersion(gradleVersion) 85 | .withProjectDir(rootDir) 86 | .withArguments("assemble", "--stacktrace") 87 | .forwardStdError(errorOutput) 88 | .build(); 89 | 90 | assertThat(result.task(":assemble").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 91 | 92 | File mainClassFile = findFile(rootDir, "Main.class"); 93 | File lambdaClassFile = findFile(rootDir, "Main$$Lambda$1.class"); 94 | 95 | assertThat(mainClassFile).exists(); 96 | assertThat(lambdaClassFile).exists(); 97 | } 98 | 99 | @Test 100 | public void test() throws Exception { 101 | writeFile(buildFile, "buildscript {\n" + 102 | " dependencies {\n" + 103 | " classpath files(" + getPluginClasspath() + ")\n" + 104 | " }\n" + 105 | "}\n" + 106 | "\n" + 107 | "apply plugin: 'groovy'\n" + 108 | "apply plugin: 'me.tatarka.retrolambda'\n" + 109 | "\n" + 110 | "repositories {\n" + 111 | " mavenCentral()\n" + 112 | "}\n" + 113 | "\n" + 114 | "dependencies {\n" + 115 | " compile 'org.codehaus.groovy:groovy-all:2.4.7'\n" + 116 | " testCompile 'junit:junit:4.12'\n" + 117 | "}\n" + 118 | "\n" + 119 | "test {\n" + 120 | " testLogging { events \"failed\" }\n" + 121 | "}"); 122 | 123 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 124 | 125 | writeFile(javaFile, "import java.util.concurrent.Callable;\n" + 126 | "\n" + 127 | "public class Main {\n" + 128 | " public static Callable f() {\n" + 129 | " return () -> \"Hello, Lambda Test!\";\n" + 130 | " }\n" + 131 | "}"); 132 | 133 | File testJavaFile = new File(rootDir, "src/test/java/Test.java"); 134 | 135 | writeFile(testJavaFile, "import org.junit.Assert;\n" + 136 | "import org.junit.runner.RunWith;\n" + 137 | "import org.junit.runners.JUnit4;\n" + 138 | "\n" + 139 | "import java.util.concurrent.Callable;\n" + 140 | "\n" + 141 | "@RunWith(JUnit4.class)\n" + 142 | "public class Test {\n" + 143 | " @org.junit.Test\n" + 144 | " public void test() throws Exception {\n" + 145 | " Runnable lambda = () -> Assert.assertTrue(true);\n" + 146 | " lambda.run();\n" + 147 | " Assert.assertEquals(\"Hello, Lambda Test!\", Main.f().call());\n" + 148 | " }\n" + 149 | "}"); 150 | 151 | StringWriter errorOutput = new StringWriter(); 152 | BuildResult result = GradleRunner.create() 153 | .withGradleVersion(gradleVersion) 154 | .withProjectDir(rootDir) 155 | .withArguments("test", "--stacktrace") 156 | .forwardStdError(errorOutput) 157 | .build(); 158 | 159 | assertThat(result.task(":test").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 160 | } 161 | 162 | @Test 163 | public void run() throws Exception { 164 | writeFile(buildFile, "buildscript {\n" + 165 | " dependencies {\n" + 166 | " classpath files(" + getPluginClasspath() + ")\n" + 167 | " }\n" + 168 | "}\n" + 169 | "\n" + 170 | "apply plugin: 'groovy'\n" + 171 | "apply plugin: 'application'\n" + 172 | "apply plugin: 'me.tatarka.retrolambda'\n" + 173 | "\n" + 174 | "repositories {\n" + 175 | " mavenCentral()\n" + 176 | "}\n" + 177 | "\n" + 178 | "dependencies {\n" + 179 | " compile 'org.codehaus.groovy:groovy-all:2.4.7'\n" + 180 | "}\n" + 181 | "\n" + 182 | "mainClassName = \"Main\"\n" + 183 | "\n" + 184 | "jar {\n" + 185 | " manifest {\n" + 186 | " attributes 'Main-Class': mainClassName\n" + 187 | " }\n" + 188 | "}"); 189 | 190 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 191 | 192 | writeFile(javaFile, "public class Main {\n" + 193 | " public static void main(String[] args) {\n" + 194 | " Runnable lambda = () -> System.out.println(\"Hello, Lambda Run!\");\n" + 195 | " lambda.run();\n" + 196 | " }\n" + 197 | "}"); 198 | 199 | StringWriter errorOutput = new StringWriter(); 200 | BuildResult result = GradleRunner.create() 201 | .withGradleVersion(gradleVersion) 202 | .withProjectDir(rootDir) 203 | .withArguments("run") 204 | .forwardStdError(errorOutput) 205 | .build(); 206 | 207 | assertThat(result.task(":run").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 208 | assertThat(result.getOutput()).contains("Hello, Lambda Run!"); 209 | } 210 | } 211 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/test/java/me/tatarka/JavaPluginTest.java: -------------------------------------------------------------------------------- 1 | package me.tatarka; 2 | 3 | 4 | import org.gradle.testkit.runner.BuildResult; 5 | import org.gradle.testkit.runner.GradleRunner; 6 | import org.gradle.testkit.runner.TaskOutcome; 7 | import org.junit.Before; 8 | import org.junit.Rule; 9 | import org.junit.Test; 10 | import org.junit.rules.TemporaryFolder; 11 | import org.junit.runner.RunWith; 12 | import org.junit.runners.JUnit4; 13 | import org.junit.runners.Parameterized; 14 | 15 | import java.io.File; 16 | import java.io.StringWriter; 17 | import java.util.Arrays; 18 | import java.util.Collection; 19 | 20 | import static me.tatarka.TestHelpers.findFile; 21 | import static me.tatarka.TestHelpers.getPluginClasspath; 22 | import static me.tatarka.TestHelpers.newestSupportedGradleVersion; 23 | import static me.tatarka.TestHelpers.oldestSupportedGradleVersion; 24 | import static me.tatarka.TestHelpers.writeFile; 25 | import static org.assertj.core.api.Assertions.assertThat; 26 | 27 | @RunWith(Parameterized.class) 28 | public class JavaPluginTest { 29 | 30 | @Parameterized.Parameters(name = "{0}") 31 | public static Collection data() { 32 | return Arrays.asList(new Object[][]{ 33 | oldestSupportedGradleVersion(), 34 | newestSupportedGradleVersion() 35 | }); 36 | } 37 | 38 | @Rule 39 | public final TemporaryFolder testProjectDir = new TemporaryFolder(); 40 | private final String gradleVersion; 41 | 42 | private File rootDir; 43 | private File buildFile; 44 | 45 | public JavaPluginTest(String gradleVersion) { 46 | this.gradleVersion = gradleVersion; 47 | } 48 | 49 | @Before 50 | public void setup() throws Exception { 51 | rootDir = testProjectDir.getRoot(); 52 | buildFile = testProjectDir.newFile("build.gradle"); 53 | } 54 | 55 | @Test 56 | public void assemble() throws Exception { 57 | writeFile(buildFile, "buildscript {\n" + 58 | " dependencies {\n" + 59 | " classpath files(" + getPluginClasspath() + ")\n" + 60 | " }\n" + 61 | "}\n" + 62 | "\n" + 63 | "apply plugin: 'java'\n" + 64 | "apply plugin: 'me.tatarka.retrolambda'\n" + 65 | "\n" + 66 | "repositories {\n" + 67 | " mavenCentral()\n" + 68 | "}"); 69 | 70 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 71 | 72 | writeFile(javaFile, "public class Main {\n" + 73 | " public static void main(String[] args) {\n" + 74 | " Runnable lambda = () -> System.out.println(\"Hello, Lambda!\");\n" + 75 | " lambda.run();\n" + 76 | " }\n" + 77 | "}"); 78 | 79 | StringWriter errorOutput = new StringWriter(); 80 | BuildResult result = GradleRunner.create() 81 | .withGradleVersion(gradleVersion) 82 | .withProjectDir(rootDir) 83 | .withArguments("assemble", "--stacktrace") 84 | .forwardStdError(errorOutput) 85 | .build(); 86 | 87 | assertThat(result.task(":assemble").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 88 | 89 | File mainClassFile = findFile(rootDir, "Main.class"); 90 | File lambdaClassFile = findFile(rootDir, "Main$$Lambda$1.class"); 91 | 92 | assertThat(mainClassFile).exists(); 93 | assertThat(lambdaClassFile).exists(); 94 | } 95 | 96 | @Test 97 | public void test() throws Exception { 98 | writeFile(buildFile, "buildscript {\n" + 99 | " dependencies {\n" + 100 | " classpath files(" + getPluginClasspath() + ")\n" + 101 | " }\n" + 102 | "}\n" + 103 | "\n" + 104 | "apply plugin: 'java'\n" + 105 | "apply plugin: 'me.tatarka.retrolambda'\n" + 106 | "\n" + 107 | "repositories {\n" + 108 | " mavenCentral()\n" + 109 | "}\n" + 110 | "\n" + 111 | "dependencies {\n" + 112 | " testCompile 'junit:junit:4.12'\n" + 113 | "}\n" + 114 | "\n" + 115 | "test {\n" + 116 | " testLogging { events \"failed\" }\n" + 117 | "}"); 118 | 119 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 120 | 121 | writeFile(javaFile, "import java.util.concurrent.Callable;\n" + 122 | "\n" + 123 | "public class Main {\n" + 124 | " public static Callable f() {\n" + 125 | " return () -> \"Hello, Lambda Test!\";\n" + 126 | " }\n" + 127 | "}"); 128 | 129 | File testJavaFile = new File(rootDir, "src/test/java/Test.java"); 130 | 131 | writeFile(testJavaFile, "import org.junit.Assert;\n" + 132 | "import org.junit.runner.RunWith;\n" + 133 | "import org.junit.runners.JUnit4;\n" + 134 | "\n" + 135 | "import java.util.concurrent.Callable;\n" + 136 | "\n" + 137 | "@RunWith(JUnit4.class)\n" + 138 | "public class Test {\n" + 139 | " @org.junit.Test\n" + 140 | " public void test() throws Exception {\n" + 141 | " Runnable lambda = () -> Assert.assertTrue(true);\n" + 142 | " lambda.run();\n" + 143 | " Assert.assertEquals(\"Hello, Lambda Test!\", Main.f().call());\n" + 144 | " }\n" + 145 | "}"); 146 | 147 | StringWriter errorOutput = new StringWriter(); 148 | BuildResult result = GradleRunner.create() 149 | .withGradleVersion(gradleVersion) 150 | .withProjectDir(rootDir) 151 | .withArguments("test", "--stacktrace") 152 | .forwardStdError(errorOutput) 153 | .build(); 154 | 155 | assertThat(result.task(":test").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 156 | } 157 | 158 | @Test 159 | public void run() throws Exception { 160 | writeFile(buildFile, "buildscript {\n" + 161 | " dependencies {\n" + 162 | " classpath files(" + getPluginClasspath() + ")\n" + 163 | " }\n" + 164 | "}\n" + 165 | "\n" + 166 | "apply plugin: 'java'\n" + 167 | "apply plugin: 'application'\n" + 168 | "apply plugin: 'me.tatarka.retrolambda'\n" + 169 | "\n" + 170 | "repositories {\n" + 171 | " mavenCentral()\n" + 172 | "}\n" + 173 | "\n" + 174 | "mainClassName = \"Main\"\n" + 175 | "\n" + 176 | "jar {\n" + 177 | " manifest {\n" + 178 | " attributes 'Main-Class': mainClassName\n" + 179 | " }\n" + 180 | "}"); 181 | 182 | File javaFile = new File(rootDir, "src/main/java/Main.java"); 183 | 184 | writeFile(javaFile, "public class Main {\n" + 185 | " public static void main(String[] args) {\n" + 186 | " Runnable lambda = () -> System.out.println(\"Hello, Lambda Run!\");\n" + 187 | " lambda.run();\n" + 188 | " }\n" + 189 | "}"); 190 | 191 | StringWriter errorOutput = new StringWriter(); 192 | BuildResult result = GradleRunner.create() 193 | .withGradleVersion(gradleVersion) 194 | .withProjectDir(rootDir) 195 | .withArguments("run") 196 | .forwardStdError(errorOutput) 197 | .build(); 198 | 199 | assertThat(result.task(":run").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); 200 | assertThat(result.getOutput()).contains("Hello, Lambda Run!"); 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /gradle-retrolambda/src/test/java/me/tatarka/TestHelpers.java: -------------------------------------------------------------------------------- 1 | package me.tatarka; 2 | 3 | import org.apache.commons.io.FileUtils; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.BufferedWriter; 7 | import java.io.File; 8 | import java.io.FileInputStream; 9 | import java.io.FileWriter; 10 | import java.io.IOException; 11 | import java.io.InputStream; 12 | import java.io.InputStreamReader; 13 | import java.nio.file.FileVisitResult; 14 | import java.nio.file.Files; 15 | import java.nio.file.Path; 16 | import java.nio.file.SimpleFileVisitor; 17 | import java.nio.file.attribute.BasicFileAttributes; 18 | import java.util.Properties; 19 | 20 | public class TestHelpers { 21 | 22 | /** 23 | * Taken from https://docs.gradle.org/current/userguide/test_kit.html and modified for java. 24 | */ 25 | public static String getPluginClasspath() throws IOException { 26 | InputStream pluginClasspathResource = TestHelpers.class.getClassLoader().getResourceAsStream("plugin-classpath.txt"); 27 | StringBuilder classpath = new StringBuilder(); 28 | BufferedReader reader = new BufferedReader(new InputStreamReader(pluginClasspathResource)); 29 | try { 30 | for (String line; (line = reader.readLine()) != null; ) { 31 | if (classpath.length() != 0) classpath.append(", "); 32 | line = line.replace("\\", "\\\\"); // escape backslashes in Windows paths 33 | classpath.append("'").append(line).append("'"); 34 | } 35 | } finally { 36 | reader.close(); 37 | } 38 | return classpath.toString(); 39 | } 40 | 41 | public static void writeFile(File file, String content) throws IOException { 42 | //noinspection ResultOfMethodCallIgnored 43 | file.getParentFile().mkdirs(); 44 | BufferedWriter writer = new BufferedWriter(new FileWriter(file)); 45 | try { 46 | writer.write(content); 47 | } finally { 48 | writer.close(); 49 | } 50 | } 51 | 52 | public static String[] oldestSupportedGradleVersion() { 53 | return new String[]{"2.6"}; 54 | } 55 | 56 | public static String[] newestSupportedGradleVersion() { 57 | return new String[]{"5.1.1"}; 58 | } 59 | 60 | public static String[] oldestSupportedAndroidPluginVersion() { 61 | return new String[]{ 62 | /*androidPluginVersion=*/"1.5.0", 63 | /*gradleVersion=*/"2.6", 64 | /*buildToolsVersion=*/"24.0.3", 65 | /*kotlinVersion=*/"1.1.0", 66 | }; 67 | } 68 | 69 | public static String[] oldestSupportedAndroidFeaturePluginVersion() { 70 | return new String[]{ 71 | /*androidPluginVersion=*/"3.1.0", 72 | /*gradleVersion=*/"4.4", 73 | /*buildToolsVersion=*/"26.0.2", 74 | /*kotlinVersion=*/"1.1.0", 75 | }; 76 | } 77 | 78 | public static String[] newestSupportedAndroidPluginVersion() { 79 | return new String[]{ 80 | /*androidPluginVersion=*/currentAndroidPluginVersion(), 81 | /*gradleVersion=*/"5.4", 82 | /*buildToolsVersion=*/"28.0.3", 83 | /*kotlinVersion=*/"1.3.10", 84 | }; 85 | } 86 | 87 | private static String currentAndroidPluginVersion() { 88 | try { 89 | Properties properties = new Properties(); 90 | properties.load(new FileInputStream("../gradle.properties")); 91 | return properties.getProperty("androidPluginVersion"); 92 | } catch (IOException e) { 93 | throw new RuntimeException(e); 94 | } 95 | } 96 | 97 | public static File findFile(File dir, final String name) throws IOException { 98 | final File[] result = new File[1]; 99 | Files.walkFileTree(dir.toPath(), new SimpleFileVisitor() { 100 | @Override 101 | public FileVisitResult visitFile(Path path, BasicFileAttributes basicFileAttributes) throws IOException { 102 | if (path.endsWith(name)) { 103 | result[0] = path.toFile(); 104 | return FileVisitResult.TERMINATE; 105 | } else { 106 | return FileVisitResult.CONTINUE; 107 | } 108 | } 109 | }); 110 | return result[0]; 111 | } 112 | 113 | public static void copyLocalPropertiesIfExists(File destinationDir) throws IOException { 114 | File localProperties = new File("../local.properties"); 115 | if (localProperties.exists()) { 116 | FileUtils.copyFile(localProperties, new File(destinationDir, "local.properties")); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | group = me.tatarka 2 | version = 3.7.1 3 | androidPluginVersion = 3.4.0 4 | useAlpha = true 5 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evant/gradle-retrolambda/e286096796ddc39f1b24c9c00834978536247656/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Apr 21 14:21:17 EDT 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4-all.zip 7 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | # 4 | # Copyright 2015 the original author or authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | ## 21 | ## Gradle start up script for UN*X 22 | ## 23 | ############################################################################## 24 | 25 | # Attempt to set APP_HOME 26 | # Resolve links: $0 may be a link 27 | PRG="$0" 28 | # Need this for relative symlinks. 29 | while [ -h "$PRG" ] ; do 30 | ls=`ls -ld "$PRG"` 31 | link=`expr "$ls" : '.*-> \(.*\)$'` 32 | if expr "$link" : '/.*' > /dev/null; then 33 | PRG="$link" 34 | else 35 | PRG=`dirname "$PRG"`"/$link" 36 | fi 37 | done 38 | SAVED="`pwd`" 39 | cd "`dirname \"$PRG\"`/" >/dev/null 40 | APP_HOME="`pwd -P`" 41 | cd "$SAVED" >/dev/null 42 | 43 | APP_NAME="Gradle" 44 | APP_BASE_NAME=`basename "$0"` 45 | 46 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 47 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 48 | 49 | # Use the maximum available, or set MAX_FD != -1 to use that value. 50 | MAX_FD="maximum" 51 | 52 | warn () { 53 | echo "$*" 54 | } 55 | 56 | die () { 57 | echo 58 | echo "$*" 59 | echo 60 | exit 1 61 | } 62 | 63 | # OS specific support (must be 'true' or 'false'). 64 | cygwin=false 65 | msys=false 66 | darwin=false 67 | nonstop=false 68 | case "`uname`" in 69 | CYGWIN* ) 70 | cygwin=true 71 | ;; 72 | Darwin* ) 73 | darwin=true 74 | ;; 75 | MINGW* ) 76 | msys=true 77 | ;; 78 | NONSTOP* ) 79 | nonstop=true 80 | ;; 81 | esac 82 | 83 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 84 | 85 | # Determine the Java command to use to start the JVM. 86 | if [ -n "$JAVA_HOME" ] ; then 87 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 88 | # IBM's JDK on AIX uses strange locations for the executables 89 | JAVACMD="$JAVA_HOME/jre/sh/java" 90 | else 91 | JAVACMD="$JAVA_HOME/bin/java" 92 | fi 93 | if [ ! -x "$JAVACMD" ] ; then 94 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 95 | 96 | Please set the JAVA_HOME variable in your environment to match the 97 | location of your Java installation." 98 | fi 99 | else 100 | JAVACMD="java" 101 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 102 | 103 | Please set the JAVA_HOME variable in your environment to match the 104 | location of your Java installation." 105 | fi 106 | 107 | # Increase the maximum file descriptors if we can. 108 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then 109 | MAX_FD_LIMIT=`ulimit -H -n` 110 | if [ $? -eq 0 ] ; then 111 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 112 | MAX_FD="$MAX_FD_LIMIT" 113 | fi 114 | ulimit -n $MAX_FD 115 | if [ $? -ne 0 ] ; then 116 | warn "Could not set maximum file descriptor limit: $MAX_FD" 117 | fi 118 | else 119 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 120 | fi 121 | fi 122 | 123 | # For Darwin, add options to specify how the application appears in the dock 124 | if $darwin; then 125 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 126 | fi 127 | 128 | # For Cygwin, switch paths to Windows format before running java 129 | if $cygwin ; then 130 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 131 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 132 | JAVACMD=`cygpath --unix "$JAVACMD"` 133 | 134 | # We build the pattern for arguments to be converted via cygpath 135 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 136 | SEP="" 137 | for dir in $ROOTDIRSRAW ; do 138 | ROOTDIRS="$ROOTDIRS$SEP$dir" 139 | SEP="|" 140 | done 141 | OURCYGPATTERN="(^($ROOTDIRS))" 142 | # Add a user-defined pattern to the cygpath arguments 143 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 144 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 145 | fi 146 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 147 | i=0 148 | for arg in "$@" ; do 149 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 150 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 151 | 152 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 153 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 154 | else 155 | eval `echo args$i`="\"$arg\"" 156 | fi 157 | i=$((i+1)) 158 | done 159 | case $i in 160 | (0) set -- ;; 161 | (1) set -- "$args0" ;; 162 | (2) set -- "$args0" "$args1" ;; 163 | (3) set -- "$args0" "$args1" "$args2" ;; 164 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 165 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 166 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 167 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 168 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 169 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 170 | esac 171 | fi 172 | 173 | # Escape application args 174 | save () { 175 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done 176 | echo " " 177 | } 178 | APP_ARGS=$(save "$@") 179 | 180 | # Collect all arguments for the java command, following the shell quoting and substitution rules 181 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" 182 | 183 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong 184 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then 185 | cd "$(dirname "$0")" 186 | fi 187 | 188 | exec "$JAVACMD" "$@" 189 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem http://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 33 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 34 | 35 | @rem Find java.exe 36 | if defined JAVA_HOME goto findJavaFromJavaHome 37 | 38 | set JAVA_EXE=java.exe 39 | %JAVA_EXE% -version >NUL 2>&1 40 | if "%ERRORLEVEL%" == "0" goto init 41 | 42 | echo. 43 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 44 | echo. 45 | echo Please set the JAVA_HOME variable in your environment to match the 46 | echo location of your Java installation. 47 | 48 | goto fail 49 | 50 | :findJavaFromJavaHome 51 | set JAVA_HOME=%JAVA_HOME:"=% 52 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 53 | 54 | if exist "%JAVA_EXE%" goto init 55 | 56 | echo. 57 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 58 | echo. 59 | echo Please set the JAVA_HOME variable in your environment to match the 60 | echo location of your Java installation. 61 | 62 | goto fail 63 | 64 | :init 65 | @rem Get command-line arguments, handling Windows variants 66 | 67 | if not "%OS%" == "Windows_NT" goto win9xME_args 68 | 69 | :win9xME_args 70 | @rem Slurp the command line arguments. 71 | set CMD_LINE_ARGS= 72 | set _SKIP=2 73 | 74 | :win9xME_args_slurp 75 | if "x%~1" == "x" goto execute 76 | 77 | set CMD_LINE_ARGS=%* 78 | 79 | :execute 80 | @rem Setup the command line 81 | 82 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 83 | 84 | @rem Execute Gradle 85 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 86 | 87 | :end 88 | @rem End local scope for the variables with windows NT shell 89 | if "%ERRORLEVEL%"=="0" goto mainEnd 90 | 91 | :fail 92 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 93 | rem the _cmd.exe /c_ return code! 94 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 95 | exit /b 1 96 | 97 | :mainEnd 98 | if "%OS%"=="Windows_NT" endlocal 99 | 100 | :omega 101 | -------------------------------------------------------------------------------- /sample-android-app/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url 'https://maven.google.com' } 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath "com.android.tools.build:gradle:$androidPluginVersion" 9 | classpath "me.tatarka:gradle-retrolambda:$version" 10 | } 11 | } 12 | 13 | apply plugin: 'com.android.application' 14 | apply plugin: 'me.tatarka.retrolambda' 15 | 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | 21 | dependencies { 22 | implementation project(':sample-android-lib') 23 | implementation project(':sample-android-feature') 24 | 25 | implementation 'com.google.dagger:dagger:2.6' 26 | annotationProcessor "com.google.dagger:dagger-compiler:2.6" 27 | compileOnly 'javax.annotation:jsr250-api:1.0' 28 | 29 | api 'com.android.support:appcompat-v7:26.0.0' 30 | 31 | androidTestImplementation 'com.android.support:support-annotations:26.0.0' 32 | androidTestImplementation 'com.android.support.test:runner:1.0.2' 33 | androidTestImplementation 'com.android.support.test:rules:1.0.2' 34 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' 35 | androidTestImplementation 'org.assertj:assertj-core:2.5.0' 36 | 37 | testImplementation 'junit:junit:4.12' 38 | testImplementation 'org.assertj:assertj-core:2.5.0' 39 | testImplementation 'org.mockito:mockito-core:2.0.23-beta' 40 | } 41 | 42 | android { 43 | compileSdkVersion 26 44 | 45 | defaultConfig { 46 | applicationId "me.tatarka.retrolambda.sample.app" 47 | minSdkVersion 15 48 | targetSdkVersion 26 49 | versionCode 1 50 | versionName "1.0" 51 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 52 | } 53 | 54 | buildTypes { 55 | debug { 56 | testCoverageEnabled true 57 | } 58 | release { 59 | minifyEnabled true 60 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 61 | } 62 | } 63 | 64 | compileOptions { 65 | sourceCompatibility JavaVersion.VERSION_1_8 66 | targetCompatibility JavaVersion.VERSION_1_8 67 | } 68 | 69 | packagingOptions { 70 | exclude 'LICENSE' 71 | exclude 'LICENSE.txt' 72 | } 73 | 74 | flavorDimensions "price" 75 | 76 | productFlavors { 77 | free { 78 | dimension "price" 79 | } 80 | paid { 81 | dimension "price" 82 | } 83 | } 84 | } 85 | 86 | retrolambda { 87 | javaVersion JavaVersion.VERSION_1_7 88 | } 89 | -------------------------------------------------------------------------------- /sample-android-app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -dontwarn java.lang.invoke.* 2 | -dontwarn **$$Lambda$* 3 | -------------------------------------------------------------------------------- /sample-android-app/src/androidTest/java/me/tatarka/sample/app/test/MainActivityInstrumentationTest.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.sample.app.test; 2 | 3 | import android.support.test.espresso.ViewAssertion; 4 | import android.support.test.espresso.assertion.ViewAssertions; 5 | import android.support.test.rule.ActivityTestRule; 6 | import android.support.test.runner.AndroidJUnit4; 7 | import android.widget.TextView; 8 | 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | 13 | import me.tatarka.retrolambda.sample.app.MainActivity; 14 | import me.tatarka.retrolambda.sample.app.R; 15 | import me.tatarka.retrolambda.sample.app.ResFunction; 16 | 17 | import static android.support.test.espresso.Espresso.onView; 18 | import static android.support.test.espresso.assertion.ViewAssertions.matches; 19 | import static android.support.test.espresso.matcher.ViewMatchers.withId; 20 | import static android.support.test.espresso.matcher.ViewMatchers.withText; 21 | import static org.assertj.core.api.Java6Assertions.assertThat; 22 | 23 | @RunWith(AndroidJUnit4.class) 24 | public class MainActivityInstrumentationTest { 25 | 26 | @Rule 27 | public ActivityTestRule activityRule = new ActivityTestRule<>(MainActivity.class); 28 | 29 | @Test 30 | public void testHelloRetrolambda() { 31 | TextView text = (TextView) activityRule.getActivity().findViewById(R.id.text); 32 | assertThat(text.getText().toString()).isEqualTo("Hello, Retrolambda!"); 33 | } 34 | 35 | @Test 36 | public void testHelloRetrolambdaLib() { 37 | TextView textLib = (TextView) activityRule.getActivity().findViewById(R.id.text_lib); 38 | assertThat(textLib.getText().toString()).isEqualTo("Hello, Retrolambda (from lib, mode a)!"); 39 | } 40 | 41 | @Test 42 | public void testLambdaInTest() { 43 | ResFunction lambda = (res) -> "test"; 44 | assertThat(lambda.run(activityRule.getActivity().getResources())).isEqualTo("test"); 45 | } 46 | 47 | @Test 48 | public void testWithEspresso() { 49 | onView(withId(R.id.text)).check((view, ex) -> matches(withText("Hello, Retrolambda!"))); 50 | onView(withId(R.id.text_lib)).check(matches(withText("Hello, Retrolambda (from lib, mode a)!"))); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /sample-android-app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /sample-android-app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evant/gradle-retrolambda/e286096796ddc39f1b24c9c00834978536247656/sample-android-app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /sample-android-app/src/main/java/me/tatarka/retrolambda/sample/app/MainActivity.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.app; 2 | 3 | import android.os.Bundle; 4 | import android.support.v7.app.AppCompatActivity; 5 | import android.widget.TextView; 6 | import android.widget.Toast; 7 | 8 | import javax.inject.Inject; 9 | 10 | public class MainActivity extends AppCompatActivity { 11 | @Inject 12 | ResFunction hello; 13 | 14 | @Inject 15 | me.tatarka.retrolambda.sample.lib.Function libHello; 16 | 17 | @Inject 18 | me.tatarka.retrolambda.sample.feature.Function libFeature; 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | 24 | DaggerMyComponent.builder() 25 | .myModule(new MyModule()) 26 | .build() 27 | .inject(this); 28 | 29 | setContentView(R.layout.activity_main); 30 | 31 | TextView text = (TextView) findViewById(R.id.text); 32 | text.setText(hello.run(getResources())); 33 | 34 | TextView textLib = (TextView) findViewById(R.id.text_lib); 35 | textLib.setText(libHello.run()); 36 | 37 | TextView textFeature = (TextView) findViewById(R.id.text_feature); 38 | textFeature.setText(libFeature.run()); 39 | 40 | ResFunction lambda = (res) -> "Foo2"; 41 | 42 | Toast.makeText(this, lambda.run(null), Toast.LENGTH_SHORT).show(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sample-android-app/src/main/java/me/tatarka/retrolambda/sample/app/MyComponent.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.app; 2 | 3 | import dagger.Component; 4 | 5 | @Component(modules = MyModule.class) 6 | public interface MyComponent { 7 | void inject(MainActivity activity); 8 | } 9 | -------------------------------------------------------------------------------- /sample-android-app/src/main/java/me/tatarka/retrolambda/sample/app/MyModule.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.app; 2 | 3 | import android.content.res.Resources; 4 | 5 | import dagger.Module; 6 | import dagger.Provides; 7 | import me.tatarka.retrolambda.sample.feature.Feature; 8 | import me.tatarka.retrolambda.sample.lib.Lib; 9 | 10 | @Module 11 | public class MyModule { 12 | @Provides 13 | public ResFunction provideHello() { 14 | return this::getHello; 15 | } 16 | 17 | private String getHello(Resources resources) { 18 | ResFunction f = (res) -> { 19 | return res.getString(R.string.hello); 20 | }; 21 | return f.run(resources); 22 | } 23 | 24 | @Provides 25 | public me.tatarka.retrolambda.sample.lib.Function provideLibHello() { 26 | return Lib.getHello(Lib.MODE_A); 27 | } 28 | 29 | @Provides 30 | public me.tatarka.retrolambda.sample.feature.Function provideFeatureHello() { 31 | return Feature.getHello(Lib.MODE_A); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sample-android-app/src/main/java/me/tatarka/retrolambda/sample/app/ResFunction.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.app; 2 | 3 | import android.content.res.Resources; 4 | 5 | /** 6 | * Created by evan on 3/29/15. 7 | */ 8 | public interface ResFunction { 9 | String run(Resources resources); 10 | } 11 | -------------------------------------------------------------------------------- /sample-android-app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 14 | 15 | 21 | 22 | 28 | 29 | -------------------------------------------------------------------------------- /sample-android-app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evant/gradle-retrolambda/e286096796ddc39f1b24c9c00834978536247656/sample-android-app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample-android-app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evant/gradle-retrolambda/e286096796ddc39f1b24c9c00834978536247656/sample-android-app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample-android-app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evant/gradle-retrolambda/e286096796ddc39f1b24c9c00834978536247656/sample-android-app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample-android-app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evant/gradle-retrolambda/e286096796ddc39f1b24c9c00834978536247656/sample-android-app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample-android-app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/evant/gradle-retrolambda/e286096796ddc39f1b24c9c00834978536247656/sample-android-app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample-android-app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Hello, Retrolambda! 4 | -------------------------------------------------------------------------------- /sample-android-app/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /sample-android-app/src/test/java/me/tatarka/retrolambda/sample/app/test/FunctionTest.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.app.test; 2 | 3 | import android.content.res.Resources; 4 | 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.junit.runners.JUnit4; 8 | 9 | import me.tatarka.retrolambda.sample.app.R; 10 | import me.tatarka.retrolambda.sample.app.ResFunction; 11 | import me.tatarka.retrolambda.sample.app.MyModule; 12 | 13 | import static org.assertj.core.api.Assertions.assertThat; 14 | import static org.mockito.Mockito.mock; 15 | import static org.mockito.Mockito.when; 16 | 17 | /** 18 | * Created by evan on 3/29/15. 19 | */ 20 | @RunWith(JUnit4.class) 21 | public class FunctionTest { 22 | MyModule module = new MyModule(); 23 | 24 | @Test 25 | public void testGetHello() { 26 | Resources res = mock(Resources.class); 27 | when(res.getString(R.string.hello)).thenReturn("Hello, Retrolambda!"); 28 | assertThat(module.provideHello().run(res)).isEqualTo("Hello, Retrolambda!"); 29 | } 30 | 31 | @Test 32 | public void testGetHelloLib() { 33 | assertThat(module.provideLibHello().run()).isEqualTo("Hello, Retrolambda (from lib, mode a)!"); 34 | } 35 | 36 | @Test 37 | public void testLambdaInTest() { 38 | ResFunction lambda = (res) -> "test"; 39 | Resources res = mock(Resources.class); 40 | assertThat(lambda.run(res)).isEqualTo("test"); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /sample-android-feature/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url 'https://maven.google.com' } 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath "com.android.tools.build:gradle:$androidPluginVersion" 9 | classpath "me.tatarka:gradle-retrolambda:$version" 10 | } 11 | } 12 | 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | 18 | apply plugin: 'com.android.feature' 19 | apply plugin: 'me.tatarka.retrolambda' 20 | 21 | android { 22 | compileSdkVersion 26 23 | 24 | defaultConfig { 25 | minSdkVersion 15 26 | targetSdkVersion 26 27 | versionCode 1 28 | versionName "1.0" 29 | } 30 | 31 | buildTypes { 32 | release { 33 | minifyEnabled false 34 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 35 | } 36 | } 37 | 38 | compileOptions { 39 | sourceCompatibility JavaVersion.VERSION_1_8 40 | targetCompatibility JavaVersion.VERSION_1_8 41 | } 42 | } 43 | 44 | dependencies { 45 | implementation 'com.android.support:support-annotations:26.0.0' 46 | } 47 | -------------------------------------------------------------------------------- /sample-android-feature/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sample-android-feature/src/main/java/me/tatarka/retrolambda/sample/feature/Feature.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.feature; 2 | 3 | import android.support.annotation.IntDef; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | 7 | /** 8 | * Created by evan on 3/29/15. 9 | */ 10 | public class Feature { 11 | 12 | @Retention(RetentionPolicy.SOURCE) 13 | @IntDef({MODE_A, MODE_B}) 14 | public @interface Mode {} 15 | 16 | public static final int MODE_A = 1; 17 | public static final int MODE_B = 2; 18 | 19 | 20 | public static Function getHello(@Mode int mode) { 21 | if (mode == MODE_A) { 22 | return () -> "Hello, Retrolambda (from feature, mode a)!"; 23 | } else { 24 | return () -> "Hello, Retrolambda (from feature, mode b)!"; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /sample-android-feature/src/main/java/me/tatarka/retrolambda/sample/feature/Function.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.feature; 2 | 3 | import android.support.annotation.Nullable; 4 | 5 | public interface Function { 6 | @Nullable 7 | String run(); 8 | } 9 | -------------------------------------------------------------------------------- /sample-android-lib/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url 'https://maven.google.com' } 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath "com.android.tools.build:gradle:$androidPluginVersion" 9 | classpath "me.tatarka:gradle-retrolambda:$version" 10 | } 11 | } 12 | 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | 18 | apply plugin: 'com.android.library' 19 | apply plugin: 'me.tatarka.retrolambda' 20 | 21 | android { 22 | compileSdkVersion 26 23 | 24 | defaultConfig { 25 | minSdkVersion 15 26 | targetSdkVersion 26 27 | versionCode 1 28 | versionName "1.0" 29 | } 30 | 31 | buildTypes { 32 | release { 33 | minifyEnabled false 34 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 35 | } 36 | } 37 | 38 | compileOptions { 39 | sourceCompatibility JavaVersion.VERSION_1_8 40 | targetCompatibility JavaVersion.VERSION_1_8 41 | } 42 | } 43 | 44 | dependencies { 45 | implementation 'com.android.support:support-annotations:26.0.0' 46 | } 47 | -------------------------------------------------------------------------------- /sample-android-lib/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /sample-android-lib/src/main/java/me/tatarka/retrolambda/sample/lib/Function.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.lib; 2 | 3 | import android.support.annotation.Nullable; 4 | 5 | public interface Function { 6 | @Nullable 7 | String run(); 8 | } 9 | -------------------------------------------------------------------------------- /sample-android-lib/src/main/java/me/tatarka/retrolambda/sample/lib/Lib.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.lib; 2 | 3 | import android.support.annotation.IntDef; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | 7 | /** 8 | * Created by evan on 3/29/15. 9 | */ 10 | public class Lib { 11 | 12 | @Retention(RetentionPolicy.SOURCE) 13 | @IntDef({MODE_A, MODE_B}) 14 | public @interface Mode {} 15 | 16 | public static final int MODE_A = 1; 17 | public static final int MODE_B = 2; 18 | 19 | 20 | public static Function getHello(@Mode int mode) { 21 | if (mode == MODE_A) { 22 | return () -> "Hello, Retrolambda (from lib, mode a)!"; 23 | } else { 24 | return () -> "Hello, Retrolambda (from lib, mode b)!"; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /sample-android-test/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | maven { url 'https://maven.google.com' } 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath "com.android.tools.build:gradle:$androidPluginVersion" 9 | classpath "me.tatarka:gradle-retrolambda:$version" 10 | } 11 | } 12 | 13 | repositories { 14 | jcenter() 15 | } 16 | 17 | apply plugin: 'com.android.test' 18 | apply plugin: 'me.tatarka.retrolambda' 19 | 20 | android { 21 | compileSdkVersion 26 22 | 23 | defaultConfig { 24 | minSdkVersion 15 25 | targetSdkVersion 26 26 | 27 | testApplicationId 'me.tatarka.retrolambda.sample.test' 28 | testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner' 29 | } 30 | 31 | targetProjectPath ':sample-android-app' 32 | 33 | compileOptions { 34 | sourceCompatibility JavaVersion.VERSION_1_8 35 | targetCompatibility JavaVersion.VERSION_1_8 36 | } 37 | 38 | lintOptions { 39 | abortOnError false 40 | } 41 | 42 | flavorDimensions "price" 43 | 44 | productFlavors { 45 | free { 46 | dimension "price" 47 | } 48 | paid { 49 | dimension "price" 50 | } 51 | } 52 | } 53 | 54 | dependencies { 55 | implementation 'com.android.support:support-annotations:26.0.0' 56 | implementation 'com.android.support.test:runner:1.0.2' 57 | implementation 'com.android.support.test:rules:1.0.2' 58 | implementation 'com.android.support.test.espresso:espresso-core:3.0.2' 59 | implementation 'org.assertj:assertj-core:2.5.0' 60 | } 61 | -------------------------------------------------------------------------------- /sample-android-test/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 8 | -------------------------------------------------------------------------------- /sample-android-test/src/main/java/me/tatarka/retrolamba/sample/test/MainActivityInstrumentationTest.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolamba.sample.test; 2 | 3 | import android.support.test.rule.ActivityTestRule; 4 | import android.support.test.runner.AndroidJUnit4; 5 | import android.widget.TextView; 6 | import me.tatarka.retrolambda.sample.app.MainActivity; 7 | import me.tatarka.retrolambda.sample.app.R; 8 | import me.tatarka.retrolambda.sample.app.ResFunction; 9 | import org.junit.Rule; 10 | import org.junit.Test; 11 | import org.junit.runner.RunWith; 12 | 13 | import static android.support.test.espresso.Espresso.onView; 14 | import static android.support.test.espresso.assertion.ViewAssertions.matches; 15 | import static android.support.test.espresso.matcher.ViewMatchers.withId; 16 | import static android.support.test.espresso.matcher.ViewMatchers.withText; 17 | import static org.assertj.core.api.Java6Assertions.assertThat; 18 | 19 | @RunWith(AndroidJUnit4.class) 20 | public class MainActivityInstrumentationTest { 21 | 22 | @Rule 23 | public ActivityTestRule activityRule = new ActivityTestRule<>(MainActivity.class); 24 | 25 | @Test 26 | public void testHelloRetrolambda() { 27 | TextView text = (TextView) activityRule.getActivity().findViewById(R.id.text); 28 | assertThat(text.getText().toString()).isEqualTo("Hello, Retrolambda!"); 29 | } 30 | 31 | @Test 32 | public void testHelloRetrolambdaLib() { 33 | TextView textLib = (TextView) activityRule.getActivity().findViewById(R.id.text_lib); 34 | assertThat(textLib.getText().toString()).isEqualTo("Hello, Retrolambda (from lib, mode a)!"); 35 | } 36 | 37 | @Test 38 | public void testLambdaInTest() { 39 | ResFunction lambda = (res) -> "test"; 40 | assertThat(lambda.run(activityRule.getActivity().getResources())).isEqualTo("test"); 41 | } 42 | 43 | @Test 44 | public void testWithEspresso() { 45 | onView(withId(R.id.text)).check((view, ex) -> matches(withText("Hello, Retrolambda!"))); 46 | onView(withId(R.id.text_lib)).check(matches(withText("Hello, Retrolambda (from lib, mode a)!"))); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /sample-java-default-methods/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenLocal() 4 | mavenCentral() 5 | } 6 | 7 | dependencies { 8 | classpath "me.tatarka:gradle-retrolambda:${rootProject.version}" 9 | } 10 | } 11 | 12 | apply plugin: 'java' 13 | apply plugin: 'application' 14 | apply plugin: 'me.tatarka.retrolambda' 15 | 16 | repositories { 17 | mavenCentral() 18 | } 19 | 20 | dependencies { 21 | testCompile 'junit:junit:4.12' 22 | testCompile 'org.assertj:assertj-core:2.0.0' 23 | } 24 | 25 | mainClassName = "me.tatarka.retrolambda.sample.Main" 26 | 27 | jar { 28 | manifest { 29 | attributes 'Main-Class': mainClassName 30 | } 31 | } 32 | 33 | retrolambda { 34 | javaVersion JavaVersion.VERSION_1_7 35 | defaultMethods true 36 | } 37 | -------------------------------------------------------------------------------- /sample-java-default-methods/src/main/java/me/tatarka/retrolambda/sample/Interface.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample; 2 | 3 | /** 4 | * Created by evan on 3/29/15. 5 | */ 6 | public interface Interface { 7 | static String staticMethod() { 8 | return "Hello, retrolambda (from static method in interface)!"; 9 | } 10 | 11 | default String defaultMethod() { 12 | return "Hello, retrolambda (from default method in interface)!"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /sample-java-default-methods/src/main/java/me/tatarka/retrolambda/sample/Main.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample; 2 | 3 | /** 4 | * Created by evan on 3/29/15. 5 | */ 6 | public class Main { 7 | public static void main(String[] args) { 8 | System.out.println(Interface.staticMethod()); 9 | Impl impl = new Impl(); 10 | System.out.println(impl.defaultMethod()); 11 | } 12 | 13 | private static class Impl implements Interface { 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /sample-java/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | mavenCentral() 4 | } 5 | 6 | dependencies { 7 | classpath "me.tatarka:gradle-retrolambda:${rootProject.version}" 8 | } 9 | } 10 | 11 | apply plugin: 'java' 12 | apply plugin: 'application' 13 | apply plugin: 'me.tatarka.retrolambda' 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | testCompile 'junit:junit:4.12' 21 | } 22 | 23 | mainClassName = "me.tatarka.retrolambda.sample.Main" 24 | 25 | jar { 26 | manifest { 27 | attributes 'Main-Class': mainClassName 28 | } 29 | } 30 | 31 | retrolambda { 32 | javaVersion JavaVersion.VERSION_1_6 33 | } 34 | -------------------------------------------------------------------------------- /sample-java/src/main/java/me/tatarka/retrolambda/sample/Function.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample; 2 | 3 | /** 4 | * Created by evan on 3/29/15. 5 | */ 6 | @FunctionalInterface 7 | public interface Function { 8 | String run(); 9 | } 10 | -------------------------------------------------------------------------------- /sample-java/src/main/java/me/tatarka/retrolambda/sample/Main.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample; 2 | 3 | /** 4 | * Created by evan on 3/29/15. 5 | */ 6 | public class Main { 7 | public static void main(String[] args) { 8 | System.out.println(getHello().run()); 9 | } 10 | 11 | public static Function getHello() { 12 | return () -> "Hello, retrolambda!"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /sample-java/src/test/java/me/tatarka/retrolambda/sample/test/Test.java: -------------------------------------------------------------------------------- 1 | package me.tatarka.retrolambda.sample.test; 2 | 3 | import org.junit.Assert; 4 | import org.junit.runner.RunWith; 5 | import org.junit.runners.JUnit4; 6 | 7 | import me.tatarka.retrolambda.sample.Main; 8 | 9 | /** 10 | * Created by evan on 3/29/15. 11 | */ 12 | @RunWith(JUnit4.class) 13 | public class Test { 14 | @org.junit.Test 15 | public void testGetHello() { 16 | Assert.assertEquals("Hello, retrolambda!", Main.getHello().run()); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'gradle-retrolambda-project' 2 | 3 | include ':sample-java', 4 | ':sample-java-default-methods', 5 | ':sample-android-app', 6 | ':sample-android-lib', 7 | ':sample-android-feature', 8 | ':sample-android-test' 9 | 10 | includeBuild './gradle-retrolambda' 11 | -------------------------------------------------------------------------------- /test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # A simple script to run tests both under java 7 and java 8. 3 | # JAVA7_HOME and JAVA8_HOME environment variables must be set. 4 | 5 | cd ./gradle-retrolambda 6 | echo JAVA_HOME=$JAVA8_HOME 7 | JAVA_HOME=$JAVA8_HOME ../gradlew test 8 | echo JAVA_HOME=$JAVA7_HOME 9 | JAVA_HOME=$JAVA7_HOME ../gradlew test 10 | --------------------------------------------------------------------------------