react-native link support for native Android modules developed in Kotlin
Summary: Currently React Native cli does not support linking native Android modules written in Kotlin. This PR aims to add support to it and closes #14561 - New unit tests added to verify the added functionality, they can be found inside: `local-cli/core/__tests__/android/findPackageClassName.spec.js` - Existing unit tests passed. Closes https://github.com/facebook/react-native/pull/14660 Differential Revision: D5316981 Pulled By: shergin fbshipit-source-id: 98354ba1e1ce1080a9a4b9958ef39893472038a1
This commit is contained in:
parent
0797dae500
commit
d666f30665
|
@ -4,7 +4,8 @@ const path = require('path');
|
|||
const manifest = fs.readFileSync(path.join(__dirname, './files/AndroidManifest.xml'));
|
||||
const mainJavaClass = fs.readFileSync(path.join(__dirname, './files/Main.java'));
|
||||
|
||||
exports.valid = {
|
||||
function generateValidFileStructure(classFileName) {
|
||||
return {
|
||||
src: {
|
||||
'AndroidManifest.xml': manifest,
|
||||
main: {
|
||||
|
@ -12,13 +13,18 @@ exports.valid = {
|
|||
some: {
|
||||
example: {
|
||||
'Main.java': mainJavaClass,
|
||||
'ReactPackage.java': fs.readFileSync(path.join(__dirname, './files/ReactPackage.java')),
|
||||
[classFileName]: fs.readFileSync(path.join(__dirname, `./files/${classFileName}`)),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
exports.valid = generateValidFileStructure('ReactPackage.java');
|
||||
|
||||
exports.validKotlin = generateValidFileStructure('ReactPackage.kt');
|
||||
|
||||
exports.userConfigManifest = {
|
||||
src: {
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class SomeExamplePackage implements ReactPackage {
|
||||
public class SomeExampleJavaPackage implements ReactPackage {
|
||||
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
package com.some.example;
|
||||
|
||||
import android.view.View
|
||||
import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.bridge.NativeModule
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.uimanager.ReactShadowNode
|
||||
import com.facebook.react.uimanager.ViewManager
|
||||
import java.util.*
|
||||
|
||||
class SomeExampleKotlinPackage : ReactPackage {
|
||||
|
||||
override fun createNativeModules(reactContext: ReactApplicationContext): MutableList<NativeModule>
|
||||
= mutableListOf(MaterialPaletteModule(reactContext))
|
||||
|
||||
override fun createViewManagers(reactContext: ReactApplicationContext?):
|
||||
MutableList<ViewManager<View, ReactShadowNode>> = Collections.emptyList()
|
||||
|
||||
}
|
|
@ -19,14 +19,25 @@ describe('android::findPackageClassName', () => {
|
|||
beforeAll(() => {
|
||||
mockFS({
|
||||
empty: {},
|
||||
flat: {
|
||||
flatJava: {
|
||||
android: mocks.valid,
|
||||
},
|
||||
flatKotlin: {
|
||||
android: mocks.validKotlin,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('returns manifest content if file exists in the folder', () => {
|
||||
expect(typeof findPackageClassName('flat')).toBe('string');
|
||||
expect(typeof findPackageClassName('flatJava')).toBe('string');
|
||||
});
|
||||
|
||||
it('returns the name of the java class implementing ReactPackage', () => {
|
||||
expect(findPackageClassName('flatJava')).toBe('SomeExampleJavaPackage');
|
||||
});
|
||||
|
||||
it('returns the name of the kotlin class implementing ReactPackage', () => {
|
||||
expect(findPackageClassName('flatKotlin')).toBe('SomeExampleKotlinPackage');
|
||||
});
|
||||
|
||||
it('returns `null` if there are no matches', () => {
|
||||
|
|
|
@ -14,16 +14,16 @@ const path = require('path');
|
|||
|
||||
/**
|
||||
* Gets package's class name (class that implements ReactPackage)
|
||||
* by searching for its declaration in all Java files present in the folder
|
||||
* by searching for its declaration in all Java/Kotlin files present in the folder
|
||||
*
|
||||
* @param {String} folder Folder to find java files
|
||||
* @param {String} folder Folder to find java/kt files
|
||||
*/
|
||||
module.exports = function getPackageClassName(folder) {
|
||||
const files = glob.sync('**/*.java', { cwd: folder });
|
||||
const files = glob.sync('**/+(*.java|*.kt)', { cwd: folder });
|
||||
|
||||
const packages = files
|
||||
.map(filePath => fs.readFileSync(path.join(folder, filePath), 'utf8'))
|
||||
.map(file => file.match(/class (.*) implements ReactPackage/))
|
||||
.map(file => file.match(/class (.*) +(implements|:) ReactPackage/))
|
||||
.filter(match => match);
|
||||
|
||||
return packages.length ? packages[0][1] : null;
|
||||
|
|
Loading…
Reference in New Issue