提交 bb88d93d 编写于 作者: fxy060608's avatar fxy060608

wip(uts): compiler

上级 9bd88e4b
import FrameLayout from 'android.widget.FrameLayout'
import Log from 'android.util.Log'
import FrameLayout from 'android.widget.FrameLayout'
import { IUser } from './interface.uts'
import { login } from './login.uts'
import logo from '../static/logo.png'
......
......@@ -3,6 +3,7 @@ import kotlinx.coroutines.*;
import io.dcloud.uts.runtime.*;
import io.dcloud.uts.android.getResourcePath;
import android.util.Log;
import android.widget.FrameLayout;
interface IUser {
fun register(name: String): Unit;
}
......
{"version":3,"sources":["/Users/fxy/Projects/GitHub/uni-app/uni-app-next/packages/playground/uts/uni_modules/test-uniplugin/static/logo.png","/Users/fxy/Projects/GitHub/uni-app/uni-app-next/packages/playground/uts/uni_modules/test-uniplugin/app-android/index.uts","/Users/fxy/Projects/GitHub/uni-app/uni-app-next/packages/playground/uts/uni_modules/test-uniplugin/app-android/interface.uts","/Users/fxy/Projects/GitHub/uni-app/uni-app-next/packages/playground/uts/uni_modules/test-uniplugin/app-android/login.uts"],"sourcesContent":["import { getResourcePath } from 'io.dcloud.uts.android'\nexport default getResourcePath('uni_modules/test-uniplugin/static/logo.png')\n ","import FrameLayout from 'android.widget.FrameLayout'\nimport Log from 'android.util.Log'\nimport { IUser } from './interface.uts'\nimport { login } from './login.uts'\nimport logo from '../static/logo.png'\nexport class User implements IUser {\n async login(name: string, pwd: string) {\n setTimeout(() => {\n console.log('timeout')\n }, 1000)\n login(name, pwd)\n Log.info('123')\n Log.info(logo)\n }\n register(name: string, callback: () => void) {\n Log.info(logo as FrameLayout)\n }\n}\nfunction login(name: string, callback: () => void) {}\nexport function register(name: string, callback: () => void) {}\n","export interface IUser {\n register(name: string): void\n}\n","export function login(name: string, pwd: string) {\n console.log('login')\n return { name, pwd }\n}\n"],"names":[],"mappings":";;;AAAA;ACCA,OAAgB,gBAAkB,CAAA;UCDjB,KAAK;QACpB,QAAQ,CAAC,IAAY,EAAN,MAAM,GAAG,IAAI;;ACDvB,IAAS,KAAK,CAAC,IAAY,EAAN,MAAM,EAAE,GAAW,EAAN,MAAM,iBAAE;IAC/C,OAAO,CAAC,GAAG,CAAC,OAAO,0DAAC;IACpB,OAAO;QAAE,IAAA,IAAI,GAAJ,IAAI;QAAE,IAAA,GAAG,GAAH,GAAG;KAAE,CAAA;AACtB;gBHFe,eAAe,CAAC,4CAA4C,CAAC;ACIrE,WAAM,IAAI,GAAY,KAAK;qBAC1B,KAAK,CAAC,IAAY,EAAN,MAAM,EAAE,GAAW,EAAN,MAAM,8CAAE;QACrC,UAAU,CAAC,KAAM;YACf,OAAO,CAAC,GAAG,CAAC,SAAS,0DAAC;QACxB;QAAC,EAAE,IAAI,CAAC;QACR,MAAM,IAAI,EAAE,GAAG,CAAC;QAChB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;QACf,GAAG,CAAC,IAAI,WAAM;IAChB;iBACA,QAAQ,CAAC,IAAY,EAAN,MAAM,EAAE,QAAoB,aAAA,EAAE;QAC3C,GAAG,CAAC,IAAI,cAAS,WAAW,CAAC;IAC/B;CACD;AACD,UAAe,IAAY,EAAN,MAAM,EAAE,QAAoB,QAAJ,IAAI,EAAE,CAAC,CAAC;AAC9C,IAAS,QAAQ,CAAC,IAAY,EAAN,MAAM,EAAE,QAAoB,aAAA,EAAE,CAAC,CAAC"}
\ No newline at end of file
{"version":3,"sources":["/Users/fxy/Projects/GitHub/uni-app/uni-app-next/packages/playground/uts/uni_modules/test-uniplugin/static/logo.png","/Users/fxy/Projects/GitHub/uni-app/uni-app-next/packages/playground/uts/uni_modules/test-uniplugin/app-android/index.uts","/Users/fxy/Projects/GitHub/uni-app/uni-app-next/packages/playground/uts/uni_modules/test-uniplugin/app-android/interface.uts","/Users/fxy/Projects/GitHub/uni-app/uni-app-next/packages/playground/uts/uni_modules/test-uniplugin/app-android/login.uts"],"sourcesContent":["import { getResourcePath } from 'io.dcloud.uts.android'\nexport default getResourcePath('uni_modules/test-uniplugin/static/logo.png')\n ","import Log from 'android.util.Log'\nimport FrameLayout from 'android.widget.FrameLayout'\nimport { IUser } from './interface.uts'\nimport { login } from './login.uts'\nimport logo from '../static/logo.png'\nexport class User implements IUser {\n async login(name: string, pwd: string) {\n setTimeout(() => {\n console.log('timeout')\n }, 1000)\n login(name, pwd)\n Log.info('123')\n Log.info(logo)\n }\n register(name: string, callback: () => void) {\n Log.info(logo as FrameLayout)\n }\n}\nfunction login(name: string, callback: () => void) {}\nexport function register(name: string, callback: () => void) {}\n","export interface IUser {\n register(name: string): void\n}\n","export function login(name: string, pwd: string) {\n console.log('login')\n return { name, pwd }\n}\n"],"names":[],"mappings":";;;AAAA;ACAA,OAAgB,gBAAkB,CAAA;AAClC,OAAwB,0BAA4B,CAAA;UCDnC,KAAK;QACpB,QAAQ,CAAC,IAAY,EAAN,MAAM,GAAG,IAAI;;ACDvB,IAAS,KAAK,CAAC,IAAY,EAAN,MAAM,EAAE,GAAW,EAAN,MAAM,iBAAE;IAC/C,OAAO,CAAC,GAAG,CAAC,OAAO,0DAAC;IACpB,OAAO;QAAE,IAAA,IAAI,GAAJ,IAAI;QAAE,IAAA,GAAG,GAAH,GAAG;KAAE,CAAA;AACtB;gBHFe,eAAe,CAAC,4CAA4C,CAAC;ACIrE,WAAM,IAAI,GAAY,KAAK;qBAC1B,KAAK,CAAC,IAAY,EAAN,MAAM,EAAE,GAAW,EAAN,MAAM,8CAAE;QACrC,UAAU,CAAC,KAAM;YACf,OAAO,CAAC,GAAG,CAAC,SAAS,0DAAC;QACxB;QAAC,EAAE,IAAI,CAAC;QACR,MAAM,IAAI,EAAE,GAAG,CAAC;QAChB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC;QACf,GAAG,CAAC,IAAI,WAAM;IAChB;iBACA,QAAQ,CAAC,IAAY,EAAN,MAAM,EAAE,QAAoB,aAAA,EAAE;QAC3C,GAAG,CAAC,IAAI,cAAS,WAAW,CAAC;IAC/B;CACD;AACD,UAAe,IAAY,EAAN,MAAM,EAAE,QAAoB,QAAJ,IAAI,EAAE,CAAC,CAAC;AAC9C,IAAS,QAAQ,CAAC,IAAY,EAAN,MAAM,EAAE,QAAoB,aAAA,EAAE,CAAC,CAAC"}
\ No newline at end of file
......@@ -19,17 +19,6 @@ function resolveWithSymlinks(id: string, basedir: string): string {
extensions,
// necessary to work with pnpm
preserveSymlinks: true,
pathFilter(pkg, filepath, relativePath) {
if (pkg.uni_modules && (pkg.uni_modules as any).type === 'uts') {
const file = process.env.UNI_UTS_PLATFORM + '/index.uts'
if (
fs.existsSync(path.join(filepath.replace(relativePath, ''), file))
) {
return file
}
}
return relativePath
},
})
}
......@@ -130,3 +119,51 @@ export function resolveComponentsLibPath() {
}
return componentsLibPath
}
// 仅限 root/uni_modules/test-plugin | root/utssdk/test-plugin 格式
export function resolveUtsModule(
id: string,
importer: string,
platform: typeof process.env.UNI_UTS_PLATFORM
) {
id = path.resolve(importer, id)
if (id.includes('utssdk') || id.includes('uni_modules')) {
const parts = normalizePath(id).split('/')
const parentDir = parts[parts.length - 2]
if (parentDir === 'uni_modules' || parentDir === 'utssdk') {
const index = path.resolve(id, 'index.uts')
if (fs.existsSync(index)) {
return index
}
if (
parentDir === 'uni_modules' &&
!fs.existsSync(path.join(id, 'utssdk'))
) {
// uni_modules/test-plugin/utssdk不存在
return
}
const platformDir = path.resolve(
id,
parentDir === 'uni_modules' ? 'utssdk' : '',
platform
)
// App平台仅支持 uts
if (platform === 'app-android' || platform === 'app-ios') {
return resolveUtsFile(platformDir, ['.uts'])
}
return resolveUtsFile(platformDir)
}
}
}
function resolveUtsFile(
dir: string,
extensions: string[] = ['.uts', '.ts', '.js']
) {
for (let i = 0; i < extensions.length; i++) {
const indexFile = path.join(dir, 'index' + extensions[i])
if (fs.existsSync(indexFile)) {
return indexFile
}
}
}
......@@ -2,9 +2,8 @@ import type { Plugin } from 'vite'
import path from 'path'
import {
isInHBuilderX,
normalizePath,
parseVueRequest,
requireResolve,
resolveUtsModule,
} from '@dcloudio/uni-cli-shared'
import {
ClassDeclaration,
......@@ -30,12 +29,11 @@ export function uniUtsV1Plugin(): Plugin {
apply: 'build',
enforce: 'pre',
resolveId(id, importer) {
if (isUtsModuleRoot(id)) {
return requireResolve(
id,
(importer && path.dirname(importer)) || process.env.UNI_INPUT_DIR
)
}
return resolveUtsModule(
id,
importer ? path.dirname(importer) : process.env.UNI_INPUT_DIR,
process.env.UNI_UTS_PLATFORM
)
},
async transform(code, id, opts) {
if (opts && opts.ssr) {
......@@ -80,15 +78,6 @@ ${genProxyCode(ast)}
}
}
// 仅限 uni_modules/test-plugin 格式
function isUtsModuleRoot(id: string) {
const parts = normalizePath(id).split('/')
if (parts[parts.length - 2] === 'uni_modules') {
return true
}
return false
}
function genProxyFunctionCode(
method: string,
async: boolean,
......
......@@ -54,36 +54,39 @@ export async function compile(filename: string) {
},
})
// console.log('uts compile time: ' + (Date.now() - time) + 'ms')
const kotlinFile = resolveKotlinFile(filename, inputDir, outputDir)
if (process.env.NODE_ENV === 'production') {
const androidInputDir = resolveAndroidDir(filename)
const androidOutputDir = resolveAndroidDir(kotlinFile)
// 生产模式下,需要将 kt 文件转移到 src 下
fs.copyFileSync(
path.resolve(filename, '../../package.json'),
path.resolve(kotlinFile, '../../package.json')
)
fs.mkdirSync(path.resolve(kotlinFile, '../src'))
const cfgJson = path.resolve(androidInputDir, 'config.json')
if (fs.existsSync(cfgJson)) {
fs.copyFileSync(cfgJson, path.resolve(androidOutputDir, 'config.json'))
}
fs.mkdirSync(path.resolve(androidOutputDir, 'src'))
if (fs.existsSync(kotlinFile)) {
fs.moveSync(kotlinFile, path.resolve(kotlinFile, '../src/index.kt'))
fs.moveSync(kotlinFile, path.resolve(androidOutputDir, 'src/index.kt'))
}
const kotlinMapFile = kotlinFile + '.map'
if (fs.existsSync(kotlinMapFile)) {
fs.moveSync(
kotlinMapFile,
path.resolve(kotlinFile, '../src/index.map.kt')
path.resolve(androidOutputDir, 'src/index.map.kt')
)
}
const copies = ['assets', 'libs', 'res']
const moduleDir = path.dirname(filename)
const outputModuleDir = path.dirname(kotlinFile)
fs.readdirSync(moduleDir).forEach((file) => {
if (copies.includes(file)) {
fs.copySync(
path.join(moduleDir, file),
path.join(outputModuleDir, file)
)
}
})
if (fs.existsSync(androidInputDir)) {
fs.readdirSync(androidInputDir).forEach((file) => {
if (copies.includes(file)) {
fs.copySync(
path.join(androidInputDir, file),
path.join(androidOutputDir, file)
)
}
})
}
} else if (process.env.NODE_ENV === 'development') {
// 开发模式下,需要生成 dex
if (fs.existsSync(kotlinFile)) {
......@@ -143,7 +146,7 @@ function resolveD8Args(filename: string) {
}
function resolveLibs(filename: string) {
const libsPath = path.resolve(path.dirname(filename), 'libs')
const libsPath = path.resolve(resolveAndroidDir(filename), 'libs')
const libs: string[] = []
if (fs.existsSync(libsPath)) {
libs.push(...sync('*.jar', { cwd: libsPath, absolute: true }))
......@@ -179,14 +182,42 @@ function resolveDexFile(jarFile: string) {
return normalizePath(path.resolve(path.dirname(jarFile), 'classes.dex'))
}
function resolveAndroidDir(filename: string) {
const maybeAndroidDir = path.dirname(filename)
// 如果是根目录的index.uts编译出来的index.kt,则移动到app-android下
const isRootIndex = path.basename(maybeAndroidDir) !== 'app-android'
if (isRootIndex) {
if (maybeAndroidDir.includes('uni_modules')) {
return path.join(maybeAndroidDir, 'utssdk/app-android')
}
return path.join(maybeAndroidDir, 'app-android')
}
return maybeAndroidDir
}
function resolveKotlinFile(
filename: string,
inputDir: string,
outputDir: string
) {
return path
let ktFile = path
.resolve(outputDir, path.relative(inputDir, filename))
.replace(path.extname(filename), '.kt')
const maybeModuleDir = path.dirname(filename)
// 如果是根目录的index.uts编译出来的index.kt,则移动到app-android下
const isRootIndex = path.basename(maybeModuleDir) !== 'app-android'
if (isRootIndex) {
if (fs.existsSync(ktFile)) {
const newKtFile = path.resolve(
path.dirname(ktFile),
(maybeModuleDir.includes('uni_modules') ? 'utssdk/' : '') +
'app-android/index.kt'
)
fs.moveSync(ktFile, newKtFile)
ktFile = newKtFile
}
}
return ktFile
}
function resolveDexPath(filename: string) {
......@@ -226,9 +257,15 @@ const getCompilerServer = ():
export function parsePackage(filepath: string) {
const parts = normalizePath(filepath).split('/')
const index = parts.findIndex((part) => part === 'uni_modules')
const isUniModules = parts.includes('uni_modules')
const index = isUniModules
? parts.findIndex((part) => part === 'uni_modules')
: parts.findIndex((part) => part === 'utssdk')
if (index > -1) {
return 'uts.modules.' + camelize(parts[index + 1])
return (
'uts.sdk.' + (isUniModules ? 'modules.' : '') + camelize(parts[index + 1])
)
}
return ''
}
......@@ -187,6 +187,9 @@ function initUtsPlatform(options: CliOptions) {
options.platform = 'app'
}
}
if (options.platform === 'app' && !process.env.UNI_UTS_PLATFORM) {
process.env.UNI_UTS_PLATFORM = 'app-android'
}
}
function initAutomator({ autoHost, autoPort }: CliOptions) {
......
......@@ -5,10 +5,19 @@ import {
extensions,
normalizePath,
requireResolve,
resolveUtsModule,
} from '@dcloudio/uni-cli-shared'
import { VitePluginUniResolvedOptions } from '..'
export const customResolver: ResolverFunction = (updatedId, importer) => {
const utsModuleFile = resolveUtsModule(
updatedId,
importer ? path.dirname(importer) : process.env.UNI_INPUT_DIR,
process.env.UNI_UTS_PLATFORM
)
if (utsModuleFile) {
return isWindows ? normalizePath(utsModuleFile) : utsModuleFile
}
if (isWindows) {
return normalizePath(
requireResolve(updatedId, importer || process.env.UNI_INPUT_DIR)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册