-
Notifications
You must be signed in to change notification settings - Fork 935
perf(autolinking)!: prioritise files with *Package.java|*Package.kt in getPackageClassName
#2384
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| /** | ||
| * Copyright (c) Facebook, Inc. and its affiliates. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE file in the root directory of this source tree. | ||
| */ | ||
|
|
||
| package com.some.example; | ||
|
|
||
| import com.facebook.react.ReactPackage; | ||
| import com.facebook.react.bridge.NativeModule; | ||
| import com.facebook.react.bridge.ReactApplicationContext; | ||
| import com.facebook.react.uimanager.ViewManager; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.Arrays; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
|
|
||
| public class SomeExampleJavaPackage implements ReactPackage { | ||
|
|
||
| @Override | ||
| public List<NativeModule> createNativeModules( | ||
| ReactApplicationContext reactContext) { | ||
| List<NativeModule> modules = new ArrayList<>(); | ||
| modules.add(new SomeExampleModule(reactContext)); | ||
| return modules; | ||
| } | ||
|
|
||
| @Override | ||
| public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) { | ||
| return Collections.emptyList(); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /** | ||
| * Copyright (c) Facebook, Inc. and its affiliates. | ||
| * | ||
| * This source code is licensed under the MIT license found in the | ||
| * LICENSE file in the root directory of this source tree. | ||
| */ | ||
|
|
||
| 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() | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,22 +11,43 @@ import glob from 'fast-glob'; | |
| import path from 'path'; | ||
| import {unixifyPaths} from '@react-native-community/cli-tools'; | ||
|
|
||
| export function getMainActivityFiles(folder: string) { | ||
| return glob.sync('**/+(*.java|*.kt)', {cwd: unixifyPaths(folder)}); | ||
| export function getMainActivityFiles( | ||
| folder: string, | ||
| includePackage: boolean = true, | ||
| ) { | ||
| let patternArray = []; | ||
|
|
||
| if (includePackage) { | ||
| patternArray.push('*Package.java', '*Package.kt'); | ||
| } else { | ||
| patternArray.push('*.java', '*.kt'); | ||
| } | ||
|
|
||
| return glob.sync(`**/+(${patternArray.join('|')})`, { | ||
| cwd: unixifyPaths(folder), | ||
| }); | ||
| } | ||
|
|
||
| export default function getPackageClassName(folder: string) { | ||
| const files = getMainActivityFiles(folder); | ||
| let files = getMainActivityFiles(folder); | ||
| let packages = getClassNameMatches(files, folder); | ||
|
|
||
| const packages = files | ||
| .map((filePath) => fs.readFileSync(path.join(folder, filePath), 'utf8')) | ||
| .map(matchClassName) | ||
| .filter((match) => match); | ||
| if (!packages.length) { | ||
| files = getMainActivityFiles(folder, false); | ||
|
Comment on lines
+32
to
+36
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A bit late to the game but I wonder if globbing for
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @szymonrybczak keen to measure it and sending a followup if that helps with perf? :)
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hm, I gave it a shot but the improvement won't be big because after my checks the amount of libraries that needs to fallback are very small. Now: With executing glob once and filtering in-memory: |
||
| packages = getClassNameMatches(files, folder); | ||
| } | ||
|
|
||
| // @ts-ignore | ||
| return packages.length ? packages[0][1] : null; | ||
| } | ||
|
|
||
| function getClassNameMatches(files: string[], folder: string) { | ||
| return files | ||
| .map((filePath) => fs.readFileSync(path.join(folder, filePath), 'utf8')) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder if streaming is faster than reading the whole file every time: https://tangledeveloper.medium.com/how-to-read-file-line-by-line-efficiently-in-node-js-8125fe5bd185
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. worth to measure definitely, these declarations are usually somewhere at the top of the file so it hints some potential
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replacing |
||
| .map(matchClassName) | ||
| .filter((match) => match); | ||
| } | ||
|
|
||
| export function matchClassName(file: string) { | ||
| const nativeModuleMatch = file.match( | ||
| /class\s+(\w+[^(\s]*)[\s\w():]*(\s+implements\s+|:)[\s\w():,]*[^{]*ReactPackage/, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| import {getMainActivityFiles} from './findPackageClassName'; | ||
|
|
||
| export default function isProjectUsingKotlin(sourceDir: string): boolean { | ||
| const mainActivityFiles = getMainActivityFiles(sourceDir); | ||
| const mainActivityFiles = getMainActivityFiles(sourceDir, false); | ||
|
|
||
| return mainActivityFiles.some((file) => file.endsWith('.kt')); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe there's scope to exclude previously matched files from this list not to read same files twice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice! good catch