Skip to content

Commit e812b19

Browse files
committed
feat: Add Kotlin autolinker for React Native 0.63.x+
Issue: #7821
1 parent efee2bd commit e812b19

File tree

4 files changed

+93
-41
lines changed

4 files changed

+93
-41
lines changed

autolink/postlink/activityLinker.js

+40-25
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,20 @@ class ActivityLinker {
5454
}
5555

5656
_removeGetMainComponentName(contents) {
57-
var match = /\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*@Override\s*protected\s*String\s*getMainComponentName\s*\(\)\s*{\s*return.+\s*\}/.exec(
58-
contents
59-
);
60-
if (match) {
61-
debugn(' Removing getMainComponentName function');
62-
return contents.replace(
63-
/\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*@Override\s*protected\s*String\s*getMainComponentName\s*\(\)\s*{\s*return.+\s*\}/,
64-
''
65-
);
57+
var javaRegex = /\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*@Override\s*protected\s*String\s*getMainComponentName\s*\(\)\s*{\s*return.+\s*\}/;
58+
var javaMatch = javaRegex.exec(contents);
59+
if (javaMatch) {
60+
debugn(' [Java] Removing getMainComponentName function');
61+
return contents.replace(javaRegex, '');
62+
}
63+
64+
var kotlinRegex = /\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*override\sfun\sgetMainComponentName\(\):\sString\s=\s.+/;
65+
var kotlinMatch = kotlinRegex.exec(contents);
66+
if (kotlinMatch) {
67+
debugn(' [Kotlin] Removing getMainComponentName function');
68+
return contents.replace(kotlinRegex, '');
6669
}
70+
6771
warnn(' getMainComponentName function was not found.');
6872
return contents;
6973
}
@@ -78,13 +82,20 @@ class ActivityLinker {
7882
debugn(' Extending NavigationActivity');
7983
return activityContent
8084
.replace(/extends\s+ReactActivity\s*/, 'extends NavigationActivity ')
85+
.replace(/ReactActivity\(\)/, 'NavigationActivity()')
8186
.replace(
8287
/public\s+MainActivityDelegate\s*\(\s*ReactActivity\s+activity,\s*String\s+mainComponentName\s*\)/,
8388
'public MainActivityDelegate(NavigationActivity activity, String mainComponentName)'
8489
)
8590
.replace(
91+
// Java
8692
'import com.facebook.react.ReactActivity;',
8793
'import com.reactnativenavigation.NavigationActivity;'
94+
)
95+
.replace(
96+
// Kotlin
97+
/import\scom\.facebook\.react\.ReactActivity\n/,
98+
'import com.reactnativenavigation.NavigationActivity\n'
8899
);
89100
}
90101

@@ -94,30 +105,34 @@ class ActivityLinker {
94105
}
95106

96107
_doesActivityExtendReactActivity(activityContent) {
97-
return /public\s+class\s+MainActivity\s+extends\s+ReactActivity\s*/.test(activityContent);
108+
return (
109+
/public\s+class\s+MainActivity\s+extends\s+ReactActivity\s*/.test(activityContent) ||
110+
/class\sMainActivity\s?:\s?ReactActivity\(\)/.test(activityContent)
111+
);
98112
}
99113

100114
_hasAlreadyExtendNavigationActivity(activityContent) {
101-
return /public\s+class\s+MainActivity\s+extends\s+NavigationActivity\s*/.test(activityContent);
115+
return (
116+
/public\s+class\s+MainActivity\s+extends\s+NavigationActivity\s*/.test(activityContent) ||
117+
/class\sMainActivity\s:\sNavigationActivity\(\)\s\{/.test(activityContent)
118+
);
102119
}
103120

104121
_removeCreateReactActivityDelegate(activityContent) {
105-
if (this._hasCreateReactActivityDelegate(activityContent)) {
106-
debugn(' Removing createReactActivityDelegate function');
107-
return activityContent.replace(
108-
/\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*@Override\s*protected\s*ReactActivityDelegate\s*createReactActivityDelegate\s*\(\)\s*{\s*return((.|\r|\s)*?)}/,
109-
''
110-
);
111-
} else {
112-
warnn(' createReactActivityDelegate is already not defined in MainActivity');
113-
return activityContent;
122+
var javaRegex = /\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*@Override\s*protected\s*ReactActivityDelegate\s*createReactActivityDelegate\s*\(\)\s*{\s*return((.|\r|\s)*?)}/;
123+
if (javaRegex.test(activityContent)) {
124+
debugn(' [Java] Removing createReactActivityDelegate function');
125+
return activityContent.replace(javaRegex, '');
114126
}
115-
}
116127

117-
_hasCreateReactActivityDelegate(activityContent) {
118-
return /\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*@Override\s*protected\s*ReactActivityDelegate\s*createReactActivityDelegate\s*\(\)\s*{\s*return((.|\r|\s)*?)}/.test(
119-
activityContent
120-
);
128+
var kotlinRegex = /\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*override\sfun\screateReactActivityDelegate\(\):\sReactActivityDelegate\s=\s+DefaultReactActivityDelegate\(this,\smainComponentName,\sfabricEnabled\)/;
129+
if (kotlinRegex.test(activityContent)) {
130+
debugn(' [Kotlin] Removing createReactActivityDelegate function');
131+
return activityContent.replace(kotlinRegex, '');
132+
}
133+
134+
warnn(' createReactActivityDelegate is already not defined in MainActivity');
135+
return activityContent;
121136
}
122137
}
123138

autolink/postlink/applicationLinker.js

+46-11
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,16 @@ class ApplicationLinker {
7171
/extends\s+Application\s+implements\s+ReactApplication/gi,
7272
'extends NavigationApplication'
7373
)
74+
.replace(/:\sApplication\(\),\sReactApplication/, ': NavigationApplication()')
7475
.replace(
76+
// Java
7577
'import com.facebook.react.ReactApplication;',
7678
'import com.reactnativenavigation.NavigationApplication;'
79+
)
80+
.replace(
81+
// Kotlin
82+
'import com.facebook.react.ReactApplication',
83+
'import com.reactnativenavigation.NavigationApplication'
7784
);
7885
}
7986

@@ -88,13 +95,18 @@ class ApplicationLinker {
8895
}
8996

9097
_doesExtendApplication(applicationContent) {
91-
return /\s+MainApplication\s+extends\s+Application\s+implements\s+ReactApplication\s+/.test(
92-
applicationContent
98+
return (
99+
/\s+MainApplication\s+extends\s+Application\s+implements\s+ReactApplication\s+/.test(
100+
applicationContent
101+
) || /class\sMainApplication\s:\sApplication\(\),\sReactApplication/.test(applicationContent)
93102
);
94103
}
95104

96105
_hasAlreadyLinkedApplication(applicationContent) {
97-
return /\s+extends\s+NavigationApplication\s+/.test(applicationContent);
106+
return (
107+
/\s+extends\s+NavigationApplication\s+/.test(applicationContent) ||
108+
/class\sMainApplication\s:\sNavigationApplication\(\)/.test(applicationContent)
109+
);
98110
}
99111

100112
_extendNavigationHost(applicationContent) {
@@ -114,10 +126,17 @@ class ApplicationLinker {
114126
} else if (this._doesExtendDefaultReactNativeHost(applicationContent)) {
115127
debugn(' Changing host implementation to NavigationReactNativeHost');
116128
return applicationContent
117-
.replace('new DefaultReactNativeHost(this)', 'new NavigationReactNativeHost(this)')
129+
.replace('new DefaultReactNativeHost(this)', 'new NavigationReactNativeHost(this)') // Java
130+
.replace('DefaultReactNativeHost(this)', 'NavigationReactNativeHost(this)') // Kotlin
118131
.replace(
132+
// Java
119133
'import com.facebook.react.defaults.DefaultReactNativeHost;',
120134
'import com.facebook.react.defaults.DefaultReactNativeHost;\nimport com.reactnativenavigation.react.NavigationReactNativeHost;'
135+
)
136+
.replace(
137+
// Kotlin
138+
/import\scom\.facebook\.react\.defaults\.DefaultReactNativeHost\n/,
139+
'import com.facebook.react.defaults.DefaultReactNativeHost\nimport com.reactnativenavigation.react.NavigationReactNativeHost\n'
121140
);
122141
}
123142

@@ -129,27 +148,43 @@ class ApplicationLinker {
129148
}
130149

131150
_doesExtendDefaultReactNativeHost(applicationContent) {
132-
return /\s*new DefaultReactNativeHost\(this\)\s*/.test(applicationContent);
151+
return (
152+
/\s*new DefaultReactNativeHost\(this\)\s*/.test(applicationContent) ||
153+
/DefaultReactNativeHost\(this\)/.test(applicationContent)
154+
);
133155
}
134156

135157
_hasAlreadyLinkedNavigationHost(applicationContent) {
136-
return /\s*new NavigationReactNativeHost\(this\)\s*/.test(applicationContent);
158+
return (
159+
/\s*new NavigationReactNativeHost\(this\)\s*/.test(applicationContent) ||
160+
/NavigationReactNativeHost\(this\)/.test(applicationContent)
161+
);
137162
}
138163

139164
_removeSOLoaderInit(applicationContent) {
140165
if (this._isSOLoaderInitCalled(applicationContent)) {
141166
debugn(' Removing call to SOLoader.init()');
142-
return applicationContent.replace(
143-
/SoLoader.init\(\s*this\s*,\s*[/* native exopackage */]*\s*false\s*\);/,
144-
''
145-
);
167+
return applicationContent
168+
.replace(
169+
// Java
170+
/SoLoader.init\(\s*this\s*,\s*[/* native exopackage */]*\s*false\s*\);/,
171+
''
172+
)
173+
.replace(
174+
// Kotlin
175+
/SoLoader\.init\(this,\sfalse\)/,
176+
''
177+
);
146178
}
147179
warnn(' SOLoader.init() is not called, skipping.');
148180
return applicationContent;
149181
}
150182

151183
_isSOLoaderInitCalled(applicationContent) {
152-
return /SoLoader.init\(this,\s*[/* native exopackage */]*\s*false\);/.test(applicationContent);
184+
return (
185+
/SoLoader.init\(this,\s*[/* native exopackage */]*\s*false\);/.test(applicationContent) ||
186+
/SoLoader\.init\(this,\sfalse\)/.test(applicationContent)
187+
);
153188
}
154189
}
155190

autolink/postlink/gradleLinker.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ class GradleLinker {
173173
* @param {string} contents
174174
*/
175175
_isKotlinPluginDeclared(contents) {
176-
return /org.jetbrains.kotlin:kotlin-gradle-plugin:/.test(contents);
176+
return /org\.jetbrains\.kotlin:kotlin-gradle-plugin:?/.test(contents);
177177
}
178178
}
179179

autolink/postlink/path.js

+6-4
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ var ignoreFolders = {
33
ignore: ['node_modules/**', '**/build/**', '**/Build/**', '**/DerivedData/**', '**/*-tvOS*/**'],
44
};
55

6-
exports.mainActivityJava = glob.sync('**/MainActivity.java', ignoreFolders)[0];
7-
exports.mainActivityKotlin = glob.sync('**/MainActivity.kt', ignoreFolders)[0];
8-
var mainApplicationJava = glob.sync('**/MainApplication.java', ignoreFolders)[0];
6+
exports.mainActivityJava = glob.sync('**/MainActivity.{java,kt}', ignoreFolders)[0];
7+
var mainApplicationJava = glob.sync('**/MainApplication.{java,kt}', ignoreFolders)[0];
98
exports.mainApplicationJava = mainApplicationJava;
10-
exports.rootGradle = mainApplicationJava.replace(/android\/app\/.*\.java/, 'android/build.gradle');
9+
exports.rootGradle = mainApplicationJava.replace(
10+
/android\/app\/.*\.(java|kt)/,
11+
'android/build.gradle'
12+
);
1113

1214
var reactNativeVersion = require('../../../react-native/package.json').version;
1315
exports.appDelegate = glob.sync(

0 commit comments

Comments
 (0)