* Copyright (c) 2024-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { generatorConfiguration, ModuleConfiguration } from "../config"
import * as idl from "../idl"
const stdlibModule: ModuleConfiguration = {
name: "__stdlib",
packages: [""],
useFoldersLayout: false,
external: true,
tsLikePackage: "__stdlib"
}
const modulesCache = new Map<string, ModuleConfiguration>()
* Is source submodule of target.
* Every source is submodule if target is empty string
* @example `isSubmodule("a.b.c", "a") === true`
* @example `isSubmodule("a", "a.b.c") === false`
* @example `isSubmodule("a.b.cd", "a.b.c") === false`
*/
export function isSubmodule(source:string, target:string): boolean {
return source === target
|| target === ""
|| source.startsWith(target + '.')
}
export function isInModule(node: idl.IDLNode, module: ModuleConfiguration): boolean
export function isInModule(packageName: string, module: ModuleConfiguration): boolean
export function isInModule(nodeOrPackage: idl.IDLNode | string, module: ModuleConfiguration): boolean {
if (typeof nodeOrPackage === 'object')
return isInModule(idl.getPackageName(nodeOrPackage), module)
return module.packages.some(modulePackage => isSubmodule(nodeOrPackage, modulePackage))
}
export function isInExternalModule(node: idl.IDLNode): boolean {
return getModuleFor(node).external ?? false
}
export function getModuleFor(node: idl.IDLNode): ModuleConfiguration
export function getModuleFor(packageName: string): ModuleConfiguration
export function getModuleFor(nodeOrPackage: idl.IDLNode | string): ModuleConfiguration {
if (typeof nodeOrPackage === "object")
return getModuleFor(idl.getPackageName(nodeOrPackage))
const packageName = nodeOrPackage
let module = modulesCache.get(packageName)
if (module) return module
module = getApplicableModuleFor(packageName)
modulesCache.set(packageName, module)
return module
}
function getApplicableModuleFor(packageName: string): ModuleConfiguration {
const config = generatorConfiguration()
const applicableModules = [...config.modules.values()].filter(module => isInModule(packageName, module))
if (applicableModules.length === 0) {
if (packageName === '') {
console.error("WARNING: use current module for empty package")
return stdlibModule
}
if (packageName.startsWith(`idlize.stdlib`)) {
return stdlibModule
}
if (packageName.startsWith(`idlize.`)) {
return currentModule()
}
if (packageName === `synthetic`)
return currentModule()
const modules = [...config.modules.keys()].map(it => `"${it}"`).join(", ")
throw new Error(`Package "${packageName}" is not listed in any module.`
+ ` Add the "${packageName}" to the existed list of modules [${modules}] or new one in the configuration file`)
}
if (applicableModules.length > 1)
throw new Error(`Package ${packageName} listed in ${applicableModules.length} packages: ${applicableModules.map(it => it.name).join(", ")}`)
return applicableModules[0]
}
export function currentModule(): ModuleConfiguration {
const conf = generatorConfiguration()
const result = conf.modules.get(conf.moduleName)
if (!result)
throw new Error(`Can not determine current module configuration ${conf.moduleName}`)
return result
}
export function isInCurrentModule(node: idl.IDLNode): boolean
export function isInCurrentModule(packageName: string): boolean
export function isInCurrentModule(nodeOrPackage: idl.IDLNode | string): boolean {
const module = typeof nodeOrPackage === 'string'
? getModuleFor(nodeOrPackage)
: getModuleFor(nodeOrPackage)
return generatorConfiguration().moduleName == module.name
}
export function isInStdlibModule(node: idl.IDLNode): boolean
export function isInStdlibModule(packageName: string): boolean
export function isInStdlibModule(nodeOrPackage: idl.IDLNode | string): boolean {
const module = typeof nodeOrPackage === 'string'
? getModuleFor(nodeOrPackage)
: getModuleFor(nodeOrPackage)
return stdlibModule.name == module.name
}