diff --git a/jest.config.js b/jest.config.js index f5de6fad3e71530dd29dd00f270370f7b80e5acc..1f301d966d0f0989c06a795d5504df982fabd7f2 100644 --- a/jest.config.js +++ b/jest.config.js @@ -10,6 +10,8 @@ module.exports = { __GLOBAL__: false, __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false, + // source-map + __PLATFORM_WEB__: false, }, coverageDirectory: 'coverage', coverageReporters: ['html', 'lcov', 'text'], diff --git a/packages/uni-components/dist/components.js b/packages/uni-components/dist/components.js index 929df59cbfa274b6348982349df4fd0ed3611b05..01cee8279a6d16fada58842d2e9cf94b8824b574 100644 --- a/packages/uni-components/dist/components.js +++ b/packages/uni-components/dist/components.js @@ -3272,7 +3272,8 @@ const Switch = defineComponent({ return () => { const { color, - type + type, + disabled } = props2; return createVNode("div", { "ref": rootRef @@ -3280,7 +3281,8 @@ const Switch = defineComponent({ dataUncType: "uni-switch" }, listeners, { checked: switchChecked.value, - color + color, + disabled }, { "style": DCSwitchSize }), null) : null, type === SwitchType.checkbox ? createVNode(resolveComponent("checkbox"), mergeProps({ diff --git a/packages/uni-stacktracey/__tests__/__snapshots__/codeFrame.spec.ts.snap b/packages/uni-stacktracey/__tests__/__snapshots__/codeFrame.spec.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..0aa2322837ce0cf1b8bd15e7e11b1a80d0e176a4 --- /dev/null +++ b/packages/uni-stacktracey/__tests__/__snapshots__/codeFrame.spec.ts.snap @@ -0,0 +1,353 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`code-frame generateCodeFrame 1`] = ` +Object { + "column": 33, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 38, + "message": "'DATA: String' is deprecated. Deprecated in Java +36 | */ +37 | const MEDIA_PROJECTIONS_API_16 = arrayOf( +38 | MediaStore.Images.ImageColumns.DATA, + | ^ +39 | MediaStore.Images.ImageColumns.DATE_TAKEN, +40 | MediaStore.Images.ImageColumns.WIDTH,", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 2`] = ` +Object { + "column": 6, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 78, + "message": "Unnecessary non-null assertion (!!) on a non-null receiver of type onImageCatchOptions +76 | } +77 | lastFileObserverTime = System.currentTimeMillis() +78 | listenOption!.onImageCatchChange(newPath) + | ^ +79 | } +80 | }", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 3`] = ` +Object { + "column": 8, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 126, + "message": "Condition 'cursor == null' is always 'false' +124| +125| +126| if (cursor == null) { + | ^ +127| return +128| }", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 4`] = ` +Object { + "column": 73, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 135, + "message": "'DATA: String' is deprecated. Deprecated in Java +133| +134| // 获取各列的索引 +135| let dataIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA) + | ^ +136| let dateTakenIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_TAKEN) +137| let widthIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.WIDTH)", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 5`] = ` +Object { + "column": 17, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 143, + "message": "Variable 'width' initializer is redundant +141| let data = cursor.getString(dataIndex) +142| let dateTaken = cursor.getLong(dateTakenIndex) +143| let width = 0; + | ^ +144| let height = 0; +145| if (widthIndex >= 0 && heightIndex >= 0) {", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 6`] = ` +Object { + "column": 18, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 144, + "message": "Variable 'height' initializer is redundant +142| let dateTaken = cursor.getLong(dateTakenIndex) +143| let width = 0; +144| let height = 0; + | ^ +145| if (widthIndex >= 0 && heightIndex >= 0) { +146| width = cursor.getInt(widthIndex)", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 7`] = ` +Object { + "column": 6, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 182, + "message": "Unnecessary non-null assertion (!!) on a non-null receiver of type onImageCatchOptions +180| if (checkScreenShot(data, dateTaken, width, height)) { +181| if (!checkCallback(data)) { +182| listenOption!.onImageCatchChange(data) + | ^ +183| } +184| } else {", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 8`] = ` +Object { + "column": 39, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 250, + "message": "'getter for defaultDisplay: Display!' is deprecated. Deprecated in Java +248| try { +249| let windowManager = getUniActivity()!.getSystemService(Context.WINDOW_SERVICE) as WindowManager +250| let defaultDisplay = windowManager.defaultDisplay + | ^ +251| defaultDisplay.getRealSize(screenSize) +252| } catch (e) {", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 9`] = ` +Object { + "column": 19, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 251, + "message": "'getRealSize(Point!): Unit' is deprecated. Deprecated in Java +249| let windowManager = getUniActivity()!.getSystemService(Context.WINDOW_SERVICE) as WindowManager +250| let defaultDisplay = windowManager.defaultDisplay +251| defaultDisplay.getRealSize(screenSize) + | ^ +252| } catch (e) { +253| e.printStackTrace()", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 10`] = ` +Object { + "column": 46, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 310, + "message": "'getExternalStorageDirectory(): File!' is deprecated. Deprecated in Java +308| var directory_screenshot: File; +309| +310| var directory_pictures = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_PICTURES); + | ^ +311| var directory_dcim = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM); +312| ", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrame 11`] = ` +Object { + "column": 42, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 311, + "message": "'getExternalStorageDirectory(): File!' is deprecated. Deprecated in Java +309| +310| var directory_pictures = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_PICTURES); +311| var directory_dcim = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM); + | ^ +312| +313| if (Build.MANUFACTURER.equals(\\"Xiaomi\\", true)) {", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 1`] = ` +Object { + "column": 33, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 38, + "message": "'DATA: String' is deprecated. Deprecated in Java +36 | */ +37 | const MEDIA_PROJECTIONS_API_16 = arrayOf( +38 | MediaStore.Images.ImageColumns.DATA, + | ^ +39 | MediaStore.Images.ImageColumns.DATE_TAKEN, +40 | MediaStore.Images.ImageColumns.WIDTH,", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 2`] = ` +Object { + "column": 6, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 78, + "message": "Unnecessary non-null assertion (!!) on a non-null receiver of type onImageCatchOptions +76 | } +77 | lastFileObserverTime = System.currentTimeMillis() +78 | listenOption!.onImageCatchChange(newPath) + | ^ +79 | } +80 | }", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 3`] = ` +Object { + "column": 8, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 126, + "message": "Condition 'cursor == null' is always 'false' +124| +125| +126| if (cursor == null) { + | ^ +127| return +128| }", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 4`] = ` +Object { + "column": 73, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 135, + "message": "'DATA: String' is deprecated. Deprecated in Java +133| +134| // 获取各列的索引 +135| let dataIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA) + | ^ +136| let dateTakenIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_TAKEN) +137| let widthIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.WIDTH)", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 5`] = ` +Object { + "column": 17, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 143, + "message": "Variable 'width' initializer is redundant +141| let data = cursor.getString(dataIndex) +142| let dateTaken = cursor.getLong(dateTakenIndex) +143| let width = 0; + | ^ +144| let height = 0; +145| if (widthIndex >= 0 && heightIndex >= 0) {", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 6`] = ` +Object { + "column": 18, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 144, + "message": "Variable 'height' initializer is redundant +142| let dateTaken = cursor.getLong(dateTakenIndex) +143| let width = 0; +144| let height = 0; + | ^ +145| if (widthIndex >= 0 && heightIndex >= 0) { +146| width = cursor.getInt(widthIndex)", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 7`] = ` +Object { + "column": 6, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 182, + "message": "Unnecessary non-null assertion (!!) on a non-null receiver of type onImageCatchOptions +180| if (checkScreenShot(data, dateTaken, width, height)) { +181| if (!checkCallback(data)) { +182| listenOption!.onImageCatchChange(data) + | ^ +183| } +184| } else {", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 8`] = ` +Object { + "column": 39, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 250, + "message": "'getter for defaultDisplay: Display!' is deprecated. Deprecated in Java +248| try { +249| let windowManager = getUniActivity()!.getSystemService(Context.WINDOW_SERVICE) as WindowManager +250| let defaultDisplay = windowManager.defaultDisplay + | ^ +251| defaultDisplay.getRealSize(screenSize) +252| } catch (e) {", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 9`] = ` +Object { + "column": 19, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 251, + "message": "'getRealSize(Point!): Unit' is deprecated. Deprecated in Java +249| let windowManager = getUniActivity()!.getSystemService(Context.WINDOW_SERVICE) as WindowManager +250| let defaultDisplay = windowManager.defaultDisplay +251| defaultDisplay.getRealSize(screenSize) + | ^ +252| } catch (e) { +253| e.printStackTrace()", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 10`] = ` +Object { + "column": 46, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 310, + "message": "'getExternalStorageDirectory(): File!' is deprecated. Deprecated in Java +308| var directory_screenshot: File; +309| +310| var directory_pictures = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_PICTURES); + | ^ +311| var directory_dcim = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM); +312| ", + "type": "warning", +} +`; + +exports[`code-frame generateCodeFrameWithSourceMapPath 11`] = ` +Object { + "column": 42, + "file": "/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts", + "line": 311, + "message": "'getExternalStorageDirectory(): File!' is deprecated. Deprecated in Java +309| +310| var directory_pictures = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_PICTURES); +311| var directory_dcim = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM); + | ^ +312| +313| if (Build.MANUFACTURER.equals(\\"Xiaomi\\", true)) {", + "type": "warning", +} +`; diff --git a/packages/uni-stacktracey/__tests__/codeFrame.spec.ts b/packages/uni-stacktracey/__tests__/codeFrame.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..c6e320c7a7c8897b2239d0fad791145af076a7a9 --- /dev/null +++ b/packages/uni-stacktracey/__tests__/codeFrame.spec.ts @@ -0,0 +1,127 @@ +import fs from 'fs' +import path from 'path' + +const { + SourceMapConsumer, + generateCodeFrameSourceMapConsumer, + generateCodeFrameWithSourceMapPath, +} = require('../dist/uni-stacktracey.cjs.js') +import type { + BasicSourceMapConsumer, + IndexedSourceMapConsumer, +} from '../lib/source-map' + +const warnings = [ + { + type: 'warning', + message: "'DATA: String' is deprecated. Deprecated in Java", + file: 'index.kt', + line: 27, + column: 71, + }, + { + type: 'warning', + message: + 'Unnecessary non-null assertion (!!) on a non-null receiver of type onImageCatchOptions', + file: 'index.kt', + line: 41, + column: 25, + }, + { + type: 'warning', + message: "Condition 'cursor == null' is always 'false'", + file: 'index.kt', + line: 61, + column: 13, + }, + { + type: 'warning', + message: "'DATA: String' is deprecated. Deprecated in Java", + file: 'index.kt', + line: 63, + column: 78, + }, + { + type: 'warning', + message: "Variable 'width' initializer is redundant", + file: 'index.kt', + line: 69, + column: 21, + }, + { + type: 'warning', + message: "Variable 'height' initializer is redundant", + file: 'index.kt', + line: 70, + column: 22, + }, + { + type: 'warning', + message: + 'Unnecessary non-null assertion (!!) on a non-null receiver of type onImageCatchOptions', + file: 'index.kt', + line: 97, + column: 47, + }, + { + type: 'warning', + message: + "'getter for defaultDisplay: Display!' is deprecated. Deprecated in Java", + file: 'index.kt', + line: 122, + column: 44, + }, + { + type: 'warning', + message: "'getRealSize(Point!): Unit' is deprecated. Deprecated in Java", + file: 'index.kt', + line: 123, + column: 24, + }, + { + type: 'warning', + message: + "'getExternalStorageDirectory(): File!' is deprecated. Deprecated in Java", + file: 'index.kt', + line: 152, + column: 51, + }, + { + type: 'warning', + message: + "'getExternalStorageDirectory(): File!' is deprecated. Deprecated in Java", + file: 'index.kt', + line: 153, + column: 47, + }, +] + +const filename = path.resolve(__dirname, 'index.kt.map') + +describe('code-frame', () => { + let consumer: BasicSourceMapConsumer | IndexedSourceMapConsumer + async function initConsumer() { + if (!consumer) { + consumer = await new SourceMapConsumer(fs.readFileSync(filename, 'utf8')) + } + return consumer + } + + test('generateCodeFrame', async () => { + const consumer = await initConsumer() + warnings.forEach((w) => { + expect(generateCodeFrameSourceMapConsumer(consumer, w)).toMatchSnapshot() + }) + }) + + test('generateCodeFrameWithSourceMapPath', async () => { + ;( + await generateCodeFrameWithSourceMapPath( + filename, + JSON.stringify(warnings) + ) + ).forEach((m: unknown) => { + expect(m).toMatchSnapshot() + }) + }) +}) diff --git a/packages/uni-stacktracey/__tests__/index.kt.map b/packages/uni-stacktracey/__tests__/index.kt.map new file mode 100644 index 0000000000000000000000000000000000000000..440b7a9c3f4244ae3a736c0e8acec95baf2ea365 --- /dev/null +++ b/packages/uni-stacktracey/__tests__/index.kt.map @@ -0,0 +1 @@ +{"version":3,"sourceRoot":"/Users/fxy/Projects/Gitcode/hello-uts","sources":["/Users/fxy/Projects/Gitcode/hello-uts/uni_modules/uts-screenshot-listener/utssdk/app-android/index.uts"],"sourcesContent":["\n\nimport {\n onAppActivityDestroy,\n onAppActivityPause,\n onAppActivityResume,\n onAppActivityBack,\n getUniActivity,\n getAppContext\n} from \"io.dcloud.uts.android\";\n\n\nimport ActivityCompat from \"androidx.core.app.ActivityCompat\";\nimport Manifest from \"android.Manifest\";\nimport PackageManager from \"android.content.pm.PackageManager\";\nimport Context from \"android.content.Context\";\nimport Point from \"android.graphics.Point\";\nimport Build from \"android.os.Build\";\nimport Handler from \"android.os.Handler\";\nimport MediaStore from \"android.provider.MediaStore\";\nimport Looper from \"android.os.Looper\";\nimport Cursor from \"android.database.Cursor\";\nimport ContentObserver from \"android.database.ContentObserver\";\nimport Uri from \"android.net.Uri\";\nimport BitmapFactory from \"android.graphics.BitmapFactory\";\nimport Display from \"android.view.Display\";\nimport Locale from \"java.util.Locale\";\nimport WindowManager from \"android.view.WindowManager\";\nimport FileObserver from \"android.os.FileObserver\";\nimport File from \"java.io.File\";\nimport RequiresApi from \"androidx.annotation.RequiresApi\";\nimport Environment from \"android.os.Environment\";\n\n/**\n * 读取媒体数据库时需要读取的列,其中 width、height 字段在 API 16 之后才有\n */\nconst MEDIA_PROJECTIONS_API_16 = arrayOf(\n MediaStore.Images.ImageColumns.DATA,\n MediaStore.Images.ImageColumns.DATE_TAKEN,\n MediaStore.Images.ImageColumns.WIDTH,\n MediaStore.Images.ImageColumns.HEIGHT\n)\n\n/**\n * 截屏路径判断的关键字\n */\nconst KEYWORDS = arrayOf(\n \"screenshot\", \"screen_shot\", \"screen-shot\", \"screen shot\",\n \"screencapture\", \"screen_capture\", \"screen-capture\", \"screen capture\",\n \"screencap\", \"screen_cap\", \"screen-cap\", \"screen cap\"\n)\n\n\n\n/**\n * android 10版本以上通过文件监听实现\n */\n@RequiresApi(Build.VERSION_CODES.Q)\nclass ScreenFileObserver extends FileObserver {\n\n allScreen: File;\n\n constructor(screenFile: File) {\n super(screenFile)\n this.allScreen = screenFile;\n }\n\n override onEvent(event: Int, path?: String): void {\n if (event == FileObserver.CREATE) {\n var newPath: string = new File(allScreen, path).path;\n let currentTime = System.currentTimeMillis();\n\n if ((currentTime - lastFileObserverTime) < 1000) {\n // 本地截屏行为比上一次超过1000ms,才认为是一个有效的时间\n return;\n }\n lastFileObserverTime = System.currentTimeMillis()\n listenOption!.onImageCatchChange(newPath)\n }\n }\n}\n\n\n/**\n * 屏幕尺寸\n */\nlet mScreenRealSize: Point | null = getRealScreenSize();\nlet mHasCallbackPaths: ArrayList = new ArrayList()\nlet mStartListenTime: number = 0;\nlet mUiHandler: Handler = Handler(Looper.getMainLooper())\n/**\n * 内部媒体文件监听器\n */\nlet mInternalObserver: MediaContentObserver | null = null;\n/**\n * 外部媒体文件监听器\n */\nlet mExternalObserver: MediaContentObserver | null = null;\n/**\n * android 10 版本使用的文件监听器\n */\nlet screenOB: ScreenFileObserver | null = null;\n\ntype onImageCatchOptions = {\n onImageCatchChange: (res: string) => void;\n};\n\nlet listenOption: onImageCatchOptions = new onImageCatchOptions();\n\nlet lastFileObserverTime: number = 0;\n\n/**\n * 处理媒体数据库的内容改变\n */\nfunction handleMediaContentChange(contentUri: Uri) {\n let cursor: Cursor | null = null;\n try {\n cursor = getUniActivity()!.contentResolver.query(\n contentUri,\n MEDIA_PROJECTIONS_API_16,\n null, null,\n MediaStore.Images.ImageColumns.DATE_ADDED + \" desc limit 1\"\n )!\n\n\n if (cursor == null) {\n return\n }\n\n if (!cursor.moveToFirst()) {\n return\n }\n\n // 获取各列的索引\n let dataIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA)\n let dateTakenIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATE_TAKEN)\n let widthIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.WIDTH)\n let heightIndex = cursor.getColumnIndex(MediaStore.Images.ImageColumns.HEIGHT)\n\n // 获取行数据\n let data = cursor.getString(dataIndex)\n let dateTaken = cursor.getLong(dateTakenIndex)\n let width = 0;\n let height = 0;\n if (widthIndex >= 0 && heightIndex >= 0) {\n width = cursor.getInt(widthIndex)\n height = cursor.getInt(heightIndex)\n } else {\n let size = getImageSize(data)\n width = size.x\n height = size.y\n }\n\n // 处理获取到的第一行数据\n handleMediaRowData(data, dateTaken, width, height)\n } catch (e) {\n e.printStackTrace()\n } finally {\n if (cursor != null && !cursor.isClosed) {\n cursor.close()\n }\n }\n}\n\n/**\n * 获取媒体库内置图像的大小\n */\nfunction getImageSize(imagePath: string): Point {\n let options = BitmapFactory.Options()\n options.inJustDecodeBounds = true\n BitmapFactory.decodeFile(imagePath, options)\n return Point(options.outWidth, options.outHeight)\n}\n\n/**\n * 处理获取到的一行数据\n */\nfunction handleMediaRowData(data: String, dateTaken: Long, width: Int, height: Int) {\n\n if (checkScreenShot(data, dateTaken, width, height)) {\n if (!checkCallback(data)) {\n listenOption!.onImageCatchChange(data)\n }\n } else {\n // 如果在观察区间媒体数据库有数据改变,又不符合截屏规则\n }\n}\n\n/**\n * 判断指定的数据行是否符合截屏条件\n */\nfunction checkScreenShot(data?: string, dateTaken: Long, width: Int, height: Int): boolean {\n // 判断依据一: 时间判断\n // 如果加入数据库的时间在开始监听之前, 或者与当前时间相差大于10秒, 则认为当前没有截屏\n if (dateTaken < mStartListenTime || System.currentTimeMillis() - dateTaken > 10 * 1000) {\n return false\n }\n\n // 判断依据二: 尺寸判断\n if (mScreenRealSize != null) {\n // 如果图片尺寸超出屏幕, 则认为当前没有截屏\n if (!(width <= mScreenRealSize!.x && height <= mScreenRealSize!.y)\n || (height <= mScreenRealSize!.x && width <= mScreenRealSize!.y)\n ) {\n return false\n }\n }\n\n // 判断依据三: 路径判断\n if (data == null) {\n return false\n }\n\n let lowerData = data.lowercase(Locale.getDefault())\n // 判断图片路径是否含有指定的关键字之一, 如果有, 则认为当前截屏了\n for (keyWork in KEYWORDS) {\n if (lowerData.contains(keyWork)) {\n return true\n }\n }\n return false\n}\n\n/**\n * 判断是否已回调过, 某些手机ROM截屏一次会发出多次内容改变的通知;

\n * 删除一个图片也会发通知, 同时防止删除图片时误将上一张符合截屏规则的图片当做是当前截屏.\n */\nfunction checkCallback(imagePath: String): boolean {\n\n if (mHasCallbackPaths.contains(imagePath)) {\n return true\n }\n // 大概缓存15~20条记录便可\n if (mHasCallbackPaths.size >= 20) {\n // for (i of 4) {\n // \tmHasCallbackPaths.removeAt(0)\n // }\n }\n mHasCallbackPaths.add(imagePath)\n return false\n}\n\n/**\n * 获取屏幕分辨率\n */\nfunction getRealScreenSize(): Point | null {\n let screenSize: Point = Point();\n try {\n let windowManager = getUniActivity()!.getSystemService(Context.WINDOW_SERVICE) as WindowManager\n let defaultDisplay = windowManager.defaultDisplay\n defaultDisplay.getRealSize(screenSize)\n } catch (e) {\n e.printStackTrace()\n }\n\n return screenSize\n}\n\n\n\n/**\n * 媒体内容观察者\n */\nclass MediaContentObserver extends ContentObserver {\n\n contentUri: Uri;\n handler: Handler;\n\n constructor(contentUri: Uri, handler: Handler) {\n super(handler)\n this.contentUri = contentUri\n this.handler = handler\n }\n\n override onChange(selfChange: Boolean) {\n super.onChange(selfChange)\n handleMediaContentChange(contentUri)\n }\n}\n\n\n\n/**\n * 请求权限\n */\nexport function requestPremission() {\n\n // 注册一个请求回调\n // 发起权限申请\n if (ActivityCompat.checkSelfPermission(getUniActivity()!, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {\n ActivityCompat.requestPermissions(getUniActivity()!, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), 1001)\n }\n\n // 请求权限\n return { name: \"requestPremission\" };\n}\n\n\n\n/**\n * 开启截图监听\n */\nexport function onUserCaptureScreen(success: (res: string) => void) {\n listenOption.onImageCatchChange = success;\n\n if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n // android 10 以上版本,使用监听文件的方式,更加可靠\n var directory_screenshot: File;\n\n var directory_pictures = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_PICTURES);\n var directory_dcim = File(Environment.getExternalStorageDirectory(), Environment.DIRECTORY_DCIM);\n\n if (Build.MANUFACTURER.equals(\"Xiaomi\", true)) {\n directory_screenshot = File(directory_dcim, \"Screenshots\");\n } else {\n directory_screenshot = File(directory_pictures, \"Screenshots\");\n }\n if (screenOB != null) {\n screenOB!.stopWatching()\n }\n screenOB = new ScreenFileObserver(directory_screenshot)\n screenOB!.startWatching()\n } else {\n // android 10 以下版本,采用监听系统媒体库的方式\n mStartListenTime = System.currentTimeMillis()\n\n // 创建内容观察者\n mInternalObserver =\n new MediaContentObserver(MediaStore.Images.Media.INTERNAL_CONTENT_URI, mUiHandler)\n mExternalObserver =\n new MediaContentObserver(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, mUiHandler)\n\n // 注册内容观察者\n getUniActivity()!.getContentResolver()!.registerContentObserver(\n MediaStore.Images.Media.INTERNAL_CONTENT_URI,\n false,\n mInternalObserver!\n )\n getUniActivity()!.getContentResolver()!.registerContentObserver(\n MediaStore.Images.Media.EXTERNAL_CONTENT_URI,\n false,\n mExternalObserver!\n )\n }\n\n}\n\n/**\n * 关闭截屏监听\n */\nexport function offUserCaptureScreen(success: (res: string) => void) {\n if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {\n // android 10以上,关闭监听通过移除文件监听器实现\n if (screenOB != null) {\n screenOB!.stopWatching()\n screenOB = null\n }\n lastFileObserverTime = 0;\n } else {\n // android 10以下,注销内容观察者\n if (mInternalObserver != null) {\n try {\n getUniActivity()!.contentResolver.unregisterContentObserver(mInternalObserver!)\n } catch (e) {\n e.printStackTrace()\n }\n mInternalObserver = null\n }\n if (mExternalObserver != null) {\n try {\n getUniActivity()!.contentResolver.unregisterContentObserver(mExternalObserver!)\n } catch (e) {\n e.printStackTrace()\n }\n mExternalObserver = null\n }\n\n // 清空数据\n mStartListenTime = 0\n }\n success(\"\");\n}\n\n\n\n\n\n\n\n\n\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/packages/uni-stacktracey/dist/uni-stacktracey.cjs.js b/packages/uni-stacktracey/dist/uni-stacktracey.cjs.js index b11c0f0f36b194df1a44c45e3d6ba8fddd28fb84..e1fe650cdf4dbfe906d85373a83951fb85c9bf81 100644 --- a/packages/uni-stacktracey/dist/uni-stacktracey.cjs.js +++ b/packages/uni-stacktracey/dist/uni-stacktracey.cjs.js @@ -2,13 +2,15 @@ Object.defineProperty(exports, '__esModule', { value: true }); -var require$$0$2 = require('fs'); +var fs = require('fs'); var path = require('path'); +var os = require('os'); function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } -var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$2); +var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); var path__default = /*#__PURE__*/_interopDefaultLegacy(path); +var os__default = /*#__PURE__*/_interopDefaultLegacy(os); /* ------------------------------------------------------------------------ */ const O = Object, isBrowser = @@ -1662,7 +1664,7 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { var readWasm$1 = createCommonjsModule(function (module) { { // Node version of reading a wasm file into an array buffer. - const fs = require$$0__default["default"]; + const fs = fs__default["default"]; const path = path__default["default"]; module.exports = function readWasm() { @@ -3597,6 +3599,116 @@ var SourceMapConsumer = require$$1.SourceMapConsumer; require$$2.SourceNode; +const splitRE = /\r?\n/; +const range = 2; +function posToNumber(source, pos) { + if (typeof pos === 'number') + return pos; + const lines = source.split(splitRE); + const { line, column } = pos; + let start = 0; + for (let i = 0; i < line - 1; i++) { + start += lines[i].length + 1; + } + return start + column; +} +function generateCodeFrame(source, start = 0, end) { + start = posToNumber(source, start); + end = end || start; + const lines = source.split(splitRE); + let count = 0; + const res = []; + for (let i = 0; i < lines.length; i++) { + count += lines[i].length + 1; + if (count >= start) { + for (let j = i - range; j <= i + range || end > count; j++) { + if (j < 0 || j >= lines.length) + continue; + const line = j + 1; + res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); + const lineLength = lines[j].length; + if (j === i) { + // push underline + const pad = start - (count - lineLength) + 1; + const length = Math.max(1, end > count ? lineLength - pad : end - start); + res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)); + } + else if (j > i) { + if (end > count) { + const length = Math.max(Math.min(end - count, lineLength), 1); + res.push(` | ` + '^'.repeat(length)); + } + count += lineLength + 1; + } + } + break; + } + } + return res.join('\n'); +} +const isWindows = os__default["default"].platform() === 'win32'; +function normalizePath(id) { + return isWindows ? id.replace(/\\/g, '/') : id; +} +function generateCodeFrameSourceMapConsumer(consumer, m, options = {}) { + if (m.file) { + const res = consumer.originalPositionFor({ + line: m.line, + column: m.column, + }); + if (res.source != null && res.line != null && res.column != null) { + const code = consumer.sourceContentFor(res.source, true); + if (code) { + return { + type: m.type, + file: options.sourceRoot + ? normalizePath(path__default["default"].relative(options.sourceRoot, res.source)) + : res.source, + line: res.line, + column: res.column, + message: `${m.message} +${generateCodeFrame(code, { line: res.line, column: res.column })}`, + }; + } + } + } +} +function initConsumer(filename) { + if (fs__default["default"].existsSync(filename)) { + return new SourceMapConsumer(fs__default["default"].readFileSync(filename, 'utf8')); + } + return Promise.resolve(undefined); +} +function generateCodeFrameWithSourceMapPath(filename, messages, options = {}) { + if (typeof messages === 'string') { + try { + messages = JSON.parse(messages); + } + catch (e) { } + } + if (Array.isArray(messages) && messages.length) { + return new Promise((resolve) => { + initConsumer(filename).then((consumer) => { + resolve(messages + .map((m) => { + if (m.file && consumer) { + const message = generateCodeFrameSourceMapConsumer(consumer, m, options); + if (message) { + return message; + } + } + if (!m.file) { + m.file = ''; + } + return m; + }) + .filter(Boolean)); + }); + }); + } + return Promise.resolve([]); +} + const nixSlashes = (x) => x.replace(/\\/g, '/'); const sourcemapCatch = {}; function stacktracey(stacktrace, opts) { @@ -3727,7 +3839,7 @@ function getSourceMapContent(sourcemapUrl) { }); } else { - sourcemapCatch[sourcemapUrl] = require$$0__default["default"].readFileSync(sourcemapUrl, 'utf-8'); + sourcemapCatch[sourcemapUrl] = fs__default["default"].readFileSync(sourcemapUrl, 'utf-8'); resolve(sourcemapCatch[sourcemapUrl]); } } @@ -3919,6 +4031,10 @@ ${_stack.errMsg}`; }; } +exports.SourceMapConsumer = SourceMapConsumer; +exports.generateCodeFrame = generateCodeFrame; +exports.generateCodeFrameSourceMapConsumer = generateCodeFrameSourceMapConsumer; +exports.generateCodeFrameWithSourceMapPath = generateCodeFrameWithSourceMapPath; exports.stacktracey = stacktracey; exports.uniStracktraceyPreset = uniStracktraceyPreset; exports.utsStracktraceyPreset = utsStracktraceyPreset; diff --git a/packages/uni-stacktracey/dist/uni-stacktracey.es.js b/packages/uni-stacktracey/dist/uni-stacktracey.es.js index 68ccbf76c4c608ea84e016d699a5943250a64e22..cc5648e8ee70fa7910c4a7565a6dfaf521348a42 100644 --- a/packages/uni-stacktracey/dist/uni-stacktracey.es.js +++ b/packages/uni-stacktracey/dist/uni-stacktracey.es.js @@ -1,5 +1,6 @@ -import require$$0$2 from 'fs'; +import fs from 'fs'; import path from 'path'; +import os from 'os'; /* ------------------------------------------------------------------------ */ const O = Object, isBrowser = @@ -3581,6 +3582,116 @@ var SourceMapConsumer = require$$1.SourceMapConsumer; require$$2.SourceNode; +const splitRE = /\r?\n/; +const range = 2; +function posToNumber(source, pos) { + if (typeof pos === 'number') + return pos; + const lines = source.split(splitRE); + const { line, column } = pos; + let start = 0; + for (let i = 0; i < line - 1; i++) { + start += lines[i].length + 1; + } + return start + column; +} +function generateCodeFrame(source, start = 0, end) { + start = posToNumber(source, start); + end = end || start; + const lines = source.split(splitRE); + let count = 0; + const res = []; + for (let i = 0; i < lines.length; i++) { + count += lines[i].length + 1; + if (count >= start) { + for (let j = i - range; j <= i + range || end > count; j++) { + if (j < 0 || j >= lines.length) + continue; + const line = j + 1; + res.push(`${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${lines[j]}`); + const lineLength = lines[j].length; + if (j === i) { + // push underline + const pad = start - (count - lineLength) + 1; + const length = Math.max(1, end > count ? lineLength - pad : end - start); + res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)); + } + else if (j > i) { + if (end > count) { + const length = Math.max(Math.min(end - count, lineLength), 1); + res.push(` | ` + '^'.repeat(length)); + } + count += lineLength + 1; + } + } + break; + } + } + return res.join('\n'); +} +const isWindows = os.platform() === 'win32'; +function normalizePath(id) { + return isWindows ? id.replace(/\\/g, '/') : id; +} +function generateCodeFrameSourceMapConsumer(consumer, m, options = {}) { + if (m.file) { + const res = consumer.originalPositionFor({ + line: m.line, + column: m.column, + }); + if (res.source != null && res.line != null && res.column != null) { + const code = consumer.sourceContentFor(res.source, true); + if (code) { + return { + type: m.type, + file: options.sourceRoot + ? normalizePath(path.relative(options.sourceRoot, res.source)) + : res.source, + line: res.line, + column: res.column, + message: `${m.message} +${generateCodeFrame(code, { line: res.line, column: res.column })}`, + }; + } + } + } +} +function initConsumer(filename) { + if (fs.existsSync(filename)) { + return new SourceMapConsumer(fs.readFileSync(filename, 'utf8')); + } + return Promise.resolve(undefined); +} +function generateCodeFrameWithSourceMapPath(filename, messages, options = {}) { + if (typeof messages === 'string') { + try { + messages = JSON.parse(messages); + } + catch (e) { } + } + if (Array.isArray(messages) && messages.length) { + return new Promise((resolve) => { + initConsumer(filename).then((consumer) => { + resolve(messages + .map((m) => { + if (m.file && consumer) { + const message = generateCodeFrameSourceMapConsumer(consumer, m, options); + if (message) { + return message; + } + } + if (!m.file) { + m.file = ''; + } + return m; + }) + .filter(Boolean)); + }); + }); + } + return Promise.resolve([]); +} + // @ts-ignore { // @ts-ignore @@ -3721,7 +3832,7 @@ function getSourceMapContent(sourcemapUrl) { }); } else { - sourcemapCatch[sourcemapUrl] = require$$0$2.readFileSync(sourcemapUrl, 'utf-8'); + sourcemapCatch[sourcemapUrl] = fs.readFileSync(sourcemapUrl, 'utf-8'); resolve(sourcemapCatch[sourcemapUrl]); } } @@ -3913,4 +4024,4 @@ ${_stack.errMsg}`; }; } -export { stacktracey, uniStracktraceyPreset, utsStracktraceyPreset }; +export { SourceMapConsumer, generateCodeFrame, generateCodeFrameSourceMapConsumer, generateCodeFrameWithSourceMapPath, stacktracey, uniStracktraceyPreset, utsStracktraceyPreset }; diff --git a/packages/uni-stacktracey/src/index.ts b/packages/uni-stacktracey/src/index.ts index 7faedc110fc83910fe78cd3198ecb94336e56536..d881be87b0c65458e650dd71d63710d0093f35eb 100644 --- a/packages/uni-stacktracey/src/index.ts +++ b/packages/uni-stacktracey/src/index.ts @@ -8,6 +8,13 @@ import { } from '../lib/source-map/source-map' import path from 'path' +export { SourceMapConsumer } from '../lib/source-map/source-map' + +export { + generateCodeFrame, + generateCodeFrameSourceMapConsumer, + generateCodeFrameWithSourceMapPath, +} from './utils' // @ts-ignore if (__PLATFORM_WEB__) { // @ts-ignore diff --git a/packages/uni-stacktracey/src/utils.ts b/packages/uni-stacktracey/src/utils.ts new file mode 100644 index 0000000000000000000000000000000000000000..3bf0864400138e07142ba5c539d26a2364d1bb1d --- /dev/null +++ b/packages/uni-stacktracey/src/utils.ts @@ -0,0 +1,159 @@ +import fs from 'fs' +import os from 'os' +import path from 'path' +import { + BasicSourceMapConsumer, + IndexedSourceMapConsumer, + SourceMapConsumer, +} from '../lib/source-map/source-map' + +const splitRE = /\r?\n/ + +const range: number = 2 + +function posToNumber( + source: string, + pos: number | { line: number; column: number } +): number { + if (typeof pos === 'number') return pos + const lines = source.split(splitRE) + const { line, column } = pos + let start = 0 + for (let i = 0; i < line - 1; i++) { + start += lines[i].length + 1 + } + return start + column +} + +export function generateCodeFrame( + source: string, + start: number | { line: number; column: number } = 0, + end?: number +): string { + start = posToNumber(source, start) + end = end || start + const lines = source.split(splitRE) + let count = 0 + const res: string[] = [] + for (let i = 0; i < lines.length; i++) { + count += lines[i].length + 1 + if (count >= start) { + for (let j = i - range; j <= i + range || end > count; j++) { + if (j < 0 || j >= lines.length) continue + const line = j + 1 + res.push( + `${line}${' '.repeat(Math.max(3 - String(line).length, 0))}| ${ + lines[j] + }` + ) + const lineLength = lines[j].length + if (j === i) { + // push underline + const pad = start - (count - lineLength) + 1 + const length = Math.max( + 1, + end > count ? lineLength - pad : end - start + ) + res.push(` | ` + ' '.repeat(pad) + '^'.repeat(length)) + } else if (j > i) { + if (end > count) { + const length = Math.max(Math.min(end - count, lineLength), 1) + res.push(` | ` + '^'.repeat(length)) + } + count += lineLength + 1 + } + } + break + } + } + return res.join('\n') +} + +interface MessageSourceLocation { + type: 'exception' | 'error' | 'warning' | 'info' | 'logging' | 'output' + message: string + file?: string + line: number + column: number +} +interface GenerateCodeFrameOptions { + sourceRoot?: string +} +const isWindows = os.platform() === 'win32' +function normalizePath(id: string): string { + return isWindows ? id.replace(/\\/g, '/') : id +} + +export function generateCodeFrameSourceMapConsumer( + consumer: BasicSourceMapConsumer | IndexedSourceMapConsumer, + m: MessageSourceLocation, + options: GenerateCodeFrameOptions = {} +): Required | undefined { + if (m.file) { + const res = consumer.originalPositionFor({ + line: m.line, + column: m.column, + }) + if (res.source != null && res.line != null && res.column != null) { + const code = consumer.sourceContentFor(res.source, true) + if (code) { + return { + type: m.type, + file: options.sourceRoot + ? normalizePath(path.relative(options.sourceRoot, res.source)) + : res.source, + line: res.line, + column: res.column, + message: `${m.message} +${generateCodeFrame(code, { line: res.line, column: res.column })}`, + } + } + } + } +} + +function initConsumer(filename: string) { + if (fs.existsSync(filename)) { + return new SourceMapConsumer(fs.readFileSync(filename, 'utf8')) + } + return Promise.resolve(undefined) +} + +export function generateCodeFrameWithSourceMapPath( + filename: string, + messages: MessageSourceLocation[] | string, + options: GenerateCodeFrameOptions = {} +): Promise[]> { + if (typeof messages === 'string') { + try { + messages = JSON.parse(messages) + } catch (e) {} + } + if (Array.isArray(messages) && messages.length) { + return new Promise((resolve) => { + initConsumer(filename).then((consumer) => { + resolve( + (messages as MessageSourceLocation[]) + .map((m) => { + if (m.file && consumer) { + const message = generateCodeFrameSourceMapConsumer( + consumer, + m, + options + ) + if (message) { + return message + } + } + if (!m.file) { + m.file = '' + } + return m as Required + }) + .filter(Boolean) + ) + }) + }) + } + return Promise.resolve([]) +} diff --git a/packages/uni-uts-vite/src/utils/compiler/kotlin.ts b/packages/uni-uts-vite/src/utils/compiler/kotlin.ts index 40748ceb7b40f70418ce26696fbd537498aa2b93..3fd32641f3c6c74ddbb41e61e271cb87ee127f5d 100644 --- a/packages/uni-uts-vite/src/utils/compiler/kotlin.ts +++ b/packages/uni-uts-vite/src/utils/compiler/kotlin.ts @@ -78,6 +78,11 @@ export async function runKotlinDev(filename: string) { getDefaultJar().concat(resolveLibs(filename)) ), d8: resolveD8Args(jarFile), + sourceRoot: process.env.UNI_INPUT_DIR, + sourceMapPath: resolveSourceMapFile( + process.env.UNI_OUTPUT_DIR, + kotlinFile + ), } const res = await compile(options, process.env.UNI_INPUT_DIR) // console.log('dex compile time: ' + (Date.now() - time) + 'ms') @@ -95,6 +100,13 @@ export async function runKotlinDev(filename: string) { } } +function resolveSourceMapFile(outputDir: string, kotlinFile: string) { + return ( + path.resolve(resolveSourceMapPath(), path.relative(outputDir, kotlinFile)) + + '.map' + ) +} + async function compile(filename: string) { if (!process.env.UNI_HBUILDERX_PLUGINS) { return