Skip to content

Commit a1c0357

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

File tree

3 files changed

+70
-39
lines changed

3 files changed

+70
-39
lines changed

autolink/postlink/activityLinker.js

Lines changed: 34 additions & 25 deletions
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,6 +82,7 @@ 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)'
@@ -94,30 +99,34 @@ class ActivityLinker {
9499
}
95100

96101
_doesActivityExtendReactActivity(activityContent) {
97-
return /public\s+class\s+MainActivity\s+extends\s+ReactActivity\s*/.test(activityContent);
102+
return (
103+
/public\s+class\s+MainActivity\s+extends\s+ReactActivity\s*/.test(activityContent) ||
104+
/class\sMainActivity\s?:\s?ReactActivity\(\)/.test(activityContent)
105+
);
98106
}
99107

100108
_hasAlreadyExtendNavigationActivity(activityContent) {
101-
return /public\s+class\s+MainActivity\s+extends\s+NavigationActivity\s*/.test(activityContent);
109+
return (
110+
/public\s+class\s+MainActivity\s+extends\s+NavigationActivity\s*/.test(activityContent) ||
111+
/class\sMainActivity\s:\sNavigationActivity\(\)\s\{/.test(activityContent)
112+
);
102113
}
103114

104115
_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;
116+
var javaRegex = /\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*@Override\s*protected\s*ReactActivityDelegate\s*createReactActivityDelegate\s*\(\)\s*{\s*return((.|\r|\s)*?)}/;
117+
if (javaRegex.test(activityContent)) {
118+
debugn(' [Java] Removing createReactActivityDelegate function');
119+
return activityContent.replace(javaRegex, '');
114120
}
115-
}
116121

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-
);
122+
var kotlinRegex = /\/\*\*\s*\n([^\*]|(\*(?!\/)))*\*\/\s*override\sfun\screateReactActivityDelegate\(\):\sReactActivityDelegate\s=\s+DefaultReactActivityDelegate\(this,\smainComponentName,\sfabricEnabled\)/;
123+
if (kotlinRegex.test(activityContent)) {
124+
debugn(' [Kotlin] Removing createReactActivityDelegate function');
125+
return activityContent.replace(kotlinRegex, '');
126+
}
127+
128+
warnn(' createReactActivityDelegate is already not defined in MainActivity');
129+
return activityContent;
121130
}
122131
}
123132

autolink/postlink/applicationLinker.js

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ class ApplicationLinker {
7171
/extends\s+Application\s+implements\s+ReactApplication/gi,
7272
'extends NavigationApplication'
7373
)
74+
.replace(/:\sApplication\(\),\sReactApplication/, ': NavigationApplication()')
7475
.replace(
7576
'import com.facebook.react.ReactApplication;',
7677
'import com.reactnativenavigation.NavigationApplication;'
@@ -88,13 +89,18 @@ class ApplicationLinker {
8889
}
8990

9091
_doesExtendApplication(applicationContent) {
91-
return /\s+MainApplication\s+extends\s+Application\s+implements\s+ReactApplication\s+/.test(
92-
applicationContent
92+
return (
93+
/\s+MainApplication\s+extends\s+Application\s+implements\s+ReactApplication\s+/.test(
94+
applicationContent
95+
) || /class\sMainApplication\s:\sNavigationApplication\(\)/.test(applicationContent)
9396
);
9497
}
9598

9699
_hasAlreadyLinkedApplication(applicationContent) {
97-
return /\s+extends\s+NavigationApplication\s+/.test(applicationContent);
100+
return (
101+
/\s+extends\s+NavigationApplication\s+/.test(applicationContent) ||
102+
/class\sMainApplication\s:\sNavigationApplication\(\)/.test(applicationContent)
103+
);
98104
}
99105

100106
_extendNavigationHost(applicationContent) {
@@ -114,7 +120,8 @@ class ApplicationLinker {
114120
} else if (this._doesExtendDefaultReactNativeHost(applicationContent)) {
115121
debugn(' Changing host implementation to NavigationReactNativeHost');
116122
return applicationContent
117-
.replace('new DefaultReactNativeHost(this)', 'new NavigationReactNativeHost(this)')
123+
.replace('new DefaultReactNativeHost(this)', 'new NavigationReactNativeHost(this)') // Java
124+
.replace('DefaultReactNativeHost(this)', 'NavigationReactNativeHost(this)') // Kotlin
118125
.replace(
119126
'import com.facebook.react.defaults.DefaultReactNativeHost;',
120127
'import com.facebook.react.defaults.DefaultReactNativeHost;\nimport com.reactnativenavigation.react.NavigationReactNativeHost;'
@@ -129,27 +136,43 @@ class ApplicationLinker {
129136
}
130137

131138
_doesExtendDefaultReactNativeHost(applicationContent) {
132-
return /\s*new DefaultReactNativeHost\(this\)\s*/.test(applicationContent);
139+
return (
140+
/\s*new DefaultReactNativeHost\(this\)\s*/.test(applicationContent) ||
141+
/DefaultReactNativeHost\(this\)/.test(applicationContent)
142+
);
133143
}
134144

135145
_hasAlreadyLinkedNavigationHost(applicationContent) {
136-
return /\s*new NavigationReactNativeHost\(this\)\s*/.test(applicationContent);
146+
return (
147+
/\s*new NavigationReactNativeHost\(this\)\s*/.test(applicationContent) ||
148+
/NavigationReactNativeHost\(this\)/.test(applicationContent)
149+
);
137150
}
138151

139152
_removeSOLoaderInit(applicationContent) {
140153
if (this._isSOLoaderInitCalled(applicationContent)) {
141154
debugn(' Removing call to SOLoader.init()');
142-
return applicationContent.replace(
143-
/SoLoader.init\(\s*this\s*,\s*[/* native exopackage */]*\s*false\s*\);/,
144-
''
145-
);
155+
return applicationContent
156+
.replace(
157+
// Java
158+
/SoLoader.init\(\s*this\s*,\s*[/* native exopackage */]*\s*false\s*\);/,
159+
''
160+
)
161+
.replace(
162+
// Kotlin
163+
/SoLoader\.init\(this,\sfalse\)/,
164+
''
165+
);
146166
}
147167
warnn(' SOLoader.init() is not called, skipping.');
148168
return applicationContent;
149169
}
150170

151171
_isSOLoaderInitCalled(applicationContent) {
152-
return /SoLoader.init\(this,\s*[/* native exopackage */]*\s*false\);/.test(applicationContent);
172+
return (
173+
/SoLoader.init\(this,\s*[/* native exopackage */]*\s*false\);/.test(applicationContent) ||
174+
/SoLoader\.init\(this,\sfalse\)/.test(applicationContent)
175+
);
153176
}
154177
}
155178

autolink/postlink/path.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ 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;
109
exports.rootGradle = mainApplicationJava.replace(/android\/app\/.*\.java/, 'android/build.gradle');
1110

0 commit comments

Comments
 (0)