Skip to content

Commit

Permalink
Merge pull request #29 from NativeScript/trifonov/improve-generation
Browse files Browse the repository at this point in the history
Trifonov/improve generation
  • Loading branch information
vtrifonov authored Jul 16, 2018
2 parents 3ba56dc + f08d410 commit cce79ed
Show file tree
Hide file tree
Showing 35 changed files with 1,243 additions and 230 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
.DS_Store
/build
/captures
.idea

/out
/output
/newApp
/dts_gen_app
testparams.txt
testparams.txt
/jars
66 changes: 66 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
android-platform-17:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-17/android.jar
mv out/android.d.ts out/android-platform-17.d.ts

android-platform-18:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-18/android.jar
mv out/android.d.ts out/android-platform-18.d.ts

android-platform-19:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-19/android.jar
mv out/android.d.ts out/android-platform-19.d.ts

android-platform-20:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-20/android.jar
mv out/android.d.ts out/android-platform-20.d.ts

android-platform-21:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-21/android.jar
mv out/android.d.ts out/android-platform-21.d.ts

android-platform-22:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-22/android.jar
mv out/android.d.ts out/android-platform-22.d.ts

android-platform-23:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-23/android.jar
mv out/android.d.ts out/android-platform-23.d.ts

android-platform-24:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-24/android.jar
mv out/android.d.ts out/android-platform-24.d.ts

android-platform-25:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-25/android.jar
mv out/android.d.ts out/android-platform-25.d.ts

android-platform-26:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-26/android.jar
mv out/android.d.ts out/android-platform-26.d.ts

android-platform-27:
java -jar dts-generator/build/libs/dts-generator.jar -input ~/Library/Android/sdk/platforms/android-27/android.jar
mv out/android.d.ts out/android-platform-27.d.ts

android-platform-all: android-platform-17 android-platform-18 android-platform-19 android-platform-20 android-platform-21 \
android-platform-22 android-platform-23 android-platform-24 android-platform-25 android-platform-26 android-platform-27

android-support-17:
java -jar dts-generator/build/libs/dts-generator.jar \
-input libs/android-support/27.0.1 -input-generics libs/generics.txt \
-super /Users/trifonov/Library/Android/sdk/platforms/android-17/android.jar -skip-declarations
mv out/android.d.ts out/android-support-17.d.ts

android-support-23:
java -jar dts-generator/build/libs/dts-generator.jar \
-input libs/android-support/27.0.1 -input-generics libs/generics.txt \
-super /Users/trifonov/Library/Android/sdk/platforms/android-23/android.jar -skip-declarations
mv out/android.d.ts out/android-support-23.d.ts

android-support-26:
java -jar dts-generator/build/libs/dts-generator.jar \
-input libs/android-support/27.0.1 -input-generics libs/generics.txt \
-super /Users/trifonov/Library/Android/sdk/platforms/android-26/android.jar -skip-declarations
mv out/android.d.ts out/android-support-26.d.ts

android-support-all: android-support-17 android-support-23 android-support-26
75 changes: 67 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,21 @@ Generate definitions following any of the approaches described below. Once you h
## Generate definitons for Android SDK
```shell
cd dts-generator
gradlew jar
./gradlew jar
java -jar build\libs\dts-generator.jar -input %ANDROID_HOME%\platforms\android-<Platform Level (21/22/23/24)>\android.jar
```

## Generate definitions for any Jar
```shell
cd dts-generator
gradlew jar
./gradlew jar
java -jar build\libs\dts-generator.jar -input <Path to your Jar>
```

## Pass multiple jars to generator
```shell
cd dts-generator
gradlew jar
./gradlew jar
java -jar build\libs\dts-generator.jar -input <jar1> <jar2> <jar3>
```

Expand All @@ -48,8 +48,67 @@ Rename classes.jar if necessary
java -jar build\libs\dts-generator.jar -input classes.jar dependency-of-classes-jar.jar
```

## Support libraries
In the [lib](lib) folder there are android support libraries jars which are get from the following git repos:
* [android-support-v4](https://github.com/dandar3/android-support-v4/tree/master/libs)
* [android-support-v7-appcompat](https://github.com/dandar3/android-support-v7-appcompat/tree/master/libs)
* [android-support-design](https://github.com/dandar3/android-support-design/tree/master/libs)
## Complex typings generation
Generating the typings corresponding to the android and android-support jar files is a bit tricky operation, so here's a detailed explanation how to do it.
There are different andoid support versions and they depend on main android classes it is a little bit complicated to generate those typings. One option is to generate a big **d.ts** file with all the libraries inside. The downside of this approach is that you have to generate a big file for every API level and if the android support version is changed all those **d.ts** files need to be regenerated.
To avoid this there's some functionality in the tool for passing dependencies when generating typings.
There are two type of dependencies that can be passed:

1. Super class jars - this is needed when the current jar has classes which are extending classes from another jar file, but we don't want to have all that jar files' typings in a single output file. To achieve this we can provide the super class jar with the **super** argument(which works the same way as **input** for multiple files).
For instance if we want to generate typings for **android.support.v4.view.ViewPager** and we don't pass the super classes jar the generated typings won't extend any class as there's no information in the jar that contains the ViewPager. However this class extends **android.view.ViewGroup** class which is a part of the android jar file(any of the API levels). So if we pass one of the android.jar files as a super class jar file the generated typing will contain `extends android.view.ViewGroup`.
2. Input generics - When trying to get the type of a parameter which is a generic class we cannot really get the generic types of that class, so we cannot generate working typings. To fix this we are adding information about the generics of each package at the end of the file with comments starting with `//Generics information:`.
So to fix this we need to provide a file with all the generic information for the packages the current jar relies on. You need to create a file and copy all the generic informations of the related packages and provide it in the **input-generics** argument. This will make all the generic classes referenced without passing types to pass **any** so that the ouput will be valid.

## Adding all implements for generic types
There is an option **all-generic-implements** which is disabled by default which controls whether to add implements for all interfaces (if they are more than one) to generic type declarations. The problem is that in most of the cases one of those interfaces is actually an extend, so it should be manual reviewed and fixed after generation.

## Finding package dependencies
If you want to generate typings of a package but you are not sure how you can get all the needed dependencies you can follow the steps bellow:

1. Open [dts-generator/build.gradle](dts-generator/build.gradle) file and locate `dependencies` part.
2. Add as a `testCompileOnly` dependency the one that you want to generate typings for:

```groovy
dependencies {
compile 'org.apache.bcel:bcel:6.2'
compile 'commons-io:commons-io:2.6'
compile 'com.google.code.findbugs:findbugs:3.0.1'
// add your dependency bellow
testCompileOnly "com.android.support:support-v4:27.0.1"
}
```
3. Open the [dts-generator](dts-generator) folder in your terminal
4. Run the following command:
```
./gradlew extractAllJars
```
5. The command above will get the needed jar files for your dependency and will output them in the [dts-generator/jar-files](dts-generator/jar-files) folder (or you can optionaly pass another output folder `-PjarsOutput=another-folder`)
6. You can run the following command to check what are the dependencies between the packages:
```
./gradlew dependencies --configuration testCompileOnly
```
7. Run the dts-generator tool passing as **input** arguments the path to the output jars folder
## Android support specifics
To get all the jar files for android support follow the steps above. You can find the **jar** files for android support 27.0.1 in [the current repository](libs/android-support/27.0.1)
As the android support needs the base android jar file to create its typings you need to pass the android.jar file as a **super** parameter to the generator. To avoid having typings for every different API level you can reuse typings built with API level 17 for all API levels until 23. It's quite easy to test this:
1. Run the typings generator for android support passing **android-17/android.jar** as a supper jar
2. Add `/// <reference path="android-17.d.ts"/>` at the top of the generated typings file where android-17.d.ts is the typings file of the android API level 17
3. Run `tsc` passing the generated typings file and there shouldn't be errors
4. Now start replacing the reference file with the files from other API level while the `tsc` execution completes with no error
5. If there's an error this means that you need to generate the android support typings with the same android API level super jar
By repeating the steps above we've found that:
- Android support 17 typings(built with supper jar from android API 17) can be reused until android API 22
- Android support 23 typings(built with supper jar from android API 23) can be reused until android API 25
- Android support 26 typings(built with supper jar from android API 26) can be reused for API 26 and 27
The corresponding typings files can be found in the [tns-platform-declarations](https://github.com/NativeScript/NativeScript/tree/master/tns-platform-declarations) package. The repo's [Makefile](Makefile) can be used as a reference for creating these typings files
1 change: 0 additions & 1 deletion dts-generator/.idea/.name

This file was deleted.

22 changes: 0 additions & 22 deletions dts-generator/.idea/compiler.xml

This file was deleted.

3 changes: 0 additions & 3 deletions dts-generator/.idea/copyright/profiles_settings.xml

This file was deleted.

6 changes: 0 additions & 6 deletions dts-generator/.idea/encodings.xml

This file was deleted.

17 changes: 0 additions & 17 deletions dts-generator/.idea/gradle.xml

This file was deleted.

9 changes: 0 additions & 9 deletions dts-generator/.idea/modules.xml

This file was deleted.

79 changes: 77 additions & 2 deletions dts-generator/build.gradle
Original file line number Diff line number Diff line change
@@ -1,7 +1,32 @@
apply plugin: 'java'
apply plugin: 'java-library'

def version = "2.0.0"

project.ext.extractedDependenciesDir = "jar-files"
if(project.hasProperty("jarsOutput")) {
project.ext.extractedDependenciesDir = project.ext.jarsOutput
}

repositories {
google()
jcenter()
}

allprojects {
gradle.projectsEvaluated {
tasks.withType(JavaCompile) {
options.compilerArgs << "-Xlint:all" << "-Werror"
}
}
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'org.apache.bcel:bcel:6.2'
compile 'commons-io:commons-io:2.6'
compile 'com.google.code.findbugs:findbugs:3.0.1'

// add your dependency here as the example bellow, make sure you are using testCompileOnly
// testCompileOnly "com.android.support:support-v4:27.0.1"
}

jar {
Expand All @@ -11,6 +36,8 @@ jar {
//set main class for the jar
manifest {
attributes 'Main-Class': 'com.telerik.Main'
attributes 'Specification-Version': version
attributes 'Manifest-Version': version
}
}

Expand All @@ -20,3 +47,51 @@ task copyJarToBuildTools (type: Copy) {
}

jar.finalizedBy(copyJarToBuildTools)

task extractAllJars {

outputs.dir extractedDependenciesDir

doLast {
def iter = configurations.testCompileOnly.resolvedConfiguration.resolvedArtifacts.iterator()
def dependencyCounter = 0
while (iter.hasNext()) {
//declaring variable as specific class for getting code completion in Android Studio
org.gradle.api.internal.artifacts.DefaultResolvedArtifact nextDependency = iter.next()

def outputDir = java.nio.file.Paths.get(extractedDependenciesDir, nextDependency.toString()).normalize().toString()
explodeAar(nextDependency.file, outputDir)
dependencyCounter++
}
}
}

def explodeAar(File compileDependency, String outputDir) {
if (compileDependency.name.endsWith(".aar")) {
java.util.jar.JarFile jar = new java.util.jar.JarFile(compileDependency)
Enumeration enumEntries = jar.entries()
while (enumEntries.hasMoreElements()) {
java.util.jar.JarEntry file = (java.util.jar.JarEntry) enumEntries.nextElement()
if (file.name.endsWith(".jar")) {
def f = new File(outputDir, file.name)
new File(f.parent).mkdirs()
InputStream is = jar.getInputStream(file)
FileOutputStream fos = new FileOutputStream(f)
while (is.available() > 0) {
fos.write(is.read())
}
fos.close()
is.close()
}
if (file.isDirectory()) {
continue
}
}
jar.close()
} else if (compileDependency.name.endsWith(".jar")) {
copy {
from compileDependency.absolutePath
into outputDir
}
}
}
Binary file removed dts-generator/libs/bcel-5.2.jar
Binary file not shown.
Binary file removed dts-generator/libs/commons-io-2.4.jar
Binary file not shown.
Loading

0 comments on commit cce79ed

Please sign in to comment.