[warning][g/c]
This commit is contained in:
@@ -141,6 +141,12 @@ kotlinNativeInterop {
|
||||
}
|
||||
}
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
allWarningsAsErrors=true
|
||||
}
|
||||
}
|
||||
|
||||
tasks.matching { it.name == 'linkClangstubsSharedLibrary' }.all {
|
||||
it.dependsOn libclangextTask
|
||||
it.inputs.dir libclangextDir
|
||||
|
||||
+1
-1
@@ -178,7 +178,7 @@ private fun reparseWithCodeSnippets(library: CompilationWithPCH,
|
||||
}
|
||||
|
||||
assert(codeSnippetLines.size == CODE_SNIPPET_LINES_NUMBER)
|
||||
codeSnippetLines.forEach { writer.appendln(it) }
|
||||
codeSnippetLines.forEach { writer.appendLine(it) }
|
||||
}
|
||||
}
|
||||
clang_reparseTranslationUnit(translationUnit, 0, null, 0)
|
||||
|
||||
+2
-2
@@ -233,7 +233,7 @@ val Compilation.preambleLines: List<String>
|
||||
|
||||
internal fun Appendable.appendPreamble(compilation: Compilation) = this.apply {
|
||||
compilation.preambleLines.forEach {
|
||||
this.appendln(it)
|
||||
this.appendLine(it)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -340,7 +340,7 @@ fun List<List<String>>.mapFragmentIsCompilable(originalLibrary: CompilationWithP
|
||||
fragmentsToCheck.forEach {
|
||||
it.value.forEach {
|
||||
assert(!it.contains('\n'))
|
||||
writer.appendln(it)
|
||||
writer.appendLine(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +75,9 @@ sourceSets.main.kotlin.srcDirs += "src/jvm/kotlin"
|
||||
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = ['-Xopt-in=kotlin.ExperimentalUnsignedTypes', '-Xinline-classes']
|
||||
freeCompilerArgs = ['-Xuse-experimental=kotlin.ExperimentalUnsignedTypes', '-Xuse-experimental=kotlin.Experimental',
|
||||
'-Xopt-in=kotlin.RequiresOptIn', "-XXLanguage:+InlineClasses"]
|
||||
allWarningsAsErrors=true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,5 +47,6 @@ dependencies {
|
||||
compileKotlin {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = ['-Xopt-in=kotlin.ExperimentalUnsignedTypes', '-Xskip-metadata-version-check']
|
||||
allWarningsAsErrors=true
|
||||
}
|
||||
}
|
||||
|
||||
+40
-40
@@ -71,7 +71,7 @@ class StubIrBridgeBuilder(
|
||||
|
||||
private val bridgeGeneratingVisitor = object : StubIrVisitor<StubContainer?, Unit> {
|
||||
|
||||
override fun visitClass(element: ClassStub, owner: StubContainer?) {
|
||||
override fun visitClass(element: ClassStub, data: StubContainer?) {
|
||||
element.annotations.filterIsInstance<AnnotationStub.ObjC.ExternalClass>().firstOrNull()?.let {
|
||||
val origin = element.origin
|
||||
if (it.protocolGetter.isNotEmpty() && origin is StubOrigin.ObjCProtocol && !origin.isMeta) {
|
||||
@@ -85,16 +85,16 @@ class StubIrBridgeBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitTypealias(element: TypealiasStub, owner: StubContainer?) {
|
||||
override fun visitTypealias(element: TypealiasStub, data: StubContainer?) {
|
||||
}
|
||||
|
||||
override fun visitFunction(element: FunctionStub, owner: StubContainer?) {
|
||||
override fun visitFunction(element: FunctionStub, data: StubContainer?) {
|
||||
try {
|
||||
when {
|
||||
element.external -> tryProcessCCallAnnotation(element)
|
||||
element.isOptionalObjCMethod() -> { }
|
||||
element.origin is StubOrigin.Synthetic.EnumByValue -> { }
|
||||
owner != null && owner.isInterface -> { }
|
||||
data != null && data.isInterface -> { }
|
||||
else -> generateBridgeBody(element)
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
@@ -112,17 +112,17 @@ class StubIrBridgeBuilder(
|
||||
simpleBridgeGenerator.insertNativeBridge(function, emptyList(), wrapper.lines)
|
||||
}
|
||||
|
||||
override fun visitProperty(element: PropertyStub, owner: StubContainer?) {
|
||||
override fun visitProperty(element: PropertyStub, data: StubContainer?) {
|
||||
try {
|
||||
when (val kind = element.kind) {
|
||||
is PropertyStub.Kind.Constant -> {
|
||||
}
|
||||
is PropertyStub.Kind.Val -> {
|
||||
visitPropertyAccessor(kind.getter, owner)
|
||||
visitPropertyAccessor(kind.getter, data)
|
||||
}
|
||||
is PropertyStub.Kind.Var -> {
|
||||
visitPropertyAccessor(kind.getter, owner)
|
||||
visitPropertyAccessor(kind.setter, owner)
|
||||
visitPropertyAccessor(kind.getter, data)
|
||||
visitPropertyAccessor(kind.setter, data)
|
||||
}
|
||||
}
|
||||
} catch (e: Throwable) {
|
||||
@@ -131,49 +131,49 @@ class StubIrBridgeBuilder(
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitConstructor(constructorStub: ConstructorStub, owner: StubContainer?) {
|
||||
override fun visitConstructor(constructorStub: ConstructorStub, data: StubContainer?) {
|
||||
}
|
||||
|
||||
override fun visitPropertyAccessor(accessor: PropertyAccessor, owner: StubContainer?) {
|
||||
when (accessor) {
|
||||
override fun visitPropertyAccessor(propertyAccessor: PropertyAccessor, data: StubContainer?) {
|
||||
when (propertyAccessor) {
|
||||
is PropertyAccessor.Getter.SimpleGetter -> {
|
||||
when (accessor) {
|
||||
when (propertyAccessor) {
|
||||
in builderResult.bridgeGenerationComponents.getterToBridgeInfo -> {
|
||||
val extra = builderResult.bridgeGenerationComponents.getterToBridgeInfo.getValue(accessor)
|
||||
val extra = builderResult.bridgeGenerationComponents.getterToBridgeInfo.getValue(propertyAccessor)
|
||||
val typeInfo = extra.typeInfo
|
||||
propertyAccessorBridgeBodies[accessor] = typeInfo.argFromBridged(simpleBridgeGenerator.kotlinToNative(
|
||||
nativeBacked = accessor,
|
||||
propertyAccessorBridgeBodies[propertyAccessor] = typeInfo.argFromBridged(simpleBridgeGenerator.kotlinToNative(
|
||||
nativeBacked = propertyAccessor,
|
||||
returnType = typeInfo.bridgedType,
|
||||
kotlinValues = emptyList(),
|
||||
independent = false
|
||||
) {
|
||||
typeInfo.cToBridged(expr = extra.cGlobalName)
|
||||
}, kotlinFile, nativeBacked = accessor)
|
||||
}, kotlinFile, nativeBacked = propertyAccessor)
|
||||
}
|
||||
in builderResult.bridgeGenerationComponents.arrayGetterInfo -> {
|
||||
val extra = builderResult.bridgeGenerationComponents.arrayGetterInfo.getValue(accessor)
|
||||
val extra = builderResult.bridgeGenerationComponents.arrayGetterInfo.getValue(propertyAccessor)
|
||||
val typeInfo = extra.typeInfo
|
||||
val getAddressExpression = getGlobalAddressExpression(extra.cGlobalName, accessor)
|
||||
propertyAccessorBridgeBodies[accessor] = typeInfo.argFromBridged(getAddressExpression, kotlinFile, nativeBacked = accessor) + "!!"
|
||||
val getAddressExpression = getGlobalAddressExpression(extra.cGlobalName, propertyAccessor)
|
||||
propertyAccessorBridgeBodies[propertyAccessor] = typeInfo.argFromBridged(getAddressExpression, kotlinFile, nativeBacked = propertyAccessor) + "!!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is PropertyAccessor.Getter.ReadBits -> {
|
||||
val extra = builderResult.bridgeGenerationComponents.getterToBridgeInfo.getValue(accessor)
|
||||
val extra = builderResult.bridgeGenerationComponents.getterToBridgeInfo.getValue(propertyAccessor)
|
||||
val rawType = extra.typeInfo.bridgedType
|
||||
val readBits = "readBits(this.rawPtr, ${accessor.offset}, ${accessor.size}, ${accessor.signed}).${rawType.convertor!!}()"
|
||||
val readBits = "readBits(this.rawPtr, ${propertyAccessor.offset}, ${propertyAccessor.size}, ${propertyAccessor.signed}).${rawType.convertor!!}()"
|
||||
val getExpr = extra.typeInfo.argFromBridged(readBits, kotlinFile, object : NativeBacked {})
|
||||
propertyAccessorBridgeBodies[accessor] = getExpr
|
||||
propertyAccessorBridgeBodies[propertyAccessor] = getExpr
|
||||
}
|
||||
|
||||
is PropertyAccessor.Setter.SimpleSetter -> when (accessor) {
|
||||
is PropertyAccessor.Setter.SimpleSetter -> when (propertyAccessor) {
|
||||
in builderResult.bridgeGenerationComponents.setterToBridgeInfo -> {
|
||||
val extra = builderResult.bridgeGenerationComponents.setterToBridgeInfo.getValue(accessor)
|
||||
val extra = builderResult.bridgeGenerationComponents.setterToBridgeInfo.getValue(propertyAccessor)
|
||||
val typeInfo = extra.typeInfo
|
||||
val bridgedValue = BridgeTypedKotlinValue(typeInfo.bridgedType, typeInfo.argToBridged("value"))
|
||||
val setter = simpleBridgeGenerator.kotlinToNative(
|
||||
nativeBacked = accessor,
|
||||
nativeBacked = propertyAccessor,
|
||||
returnType = BridgedType.VOID,
|
||||
kotlinValues = listOf(bridgedValue),
|
||||
independent = false
|
||||
@@ -181,52 +181,52 @@ class StubIrBridgeBuilder(
|
||||
out("${extra.cGlobalName} = ${typeInfo.cFromBridged(
|
||||
nativeValues.single(),
|
||||
scope,
|
||||
nativeBacked = accessor
|
||||
nativeBacked = propertyAccessor
|
||||
)};")
|
||||
""
|
||||
}
|
||||
propertyAccessorBridgeBodies[accessor] = setter
|
||||
propertyAccessorBridgeBodies[propertyAccessor] = setter
|
||||
}
|
||||
}
|
||||
|
||||
is PropertyAccessor.Setter.WriteBits -> {
|
||||
val extra = builderResult.bridgeGenerationComponents.setterToBridgeInfo.getValue(accessor)
|
||||
val extra = builderResult.bridgeGenerationComponents.setterToBridgeInfo.getValue(propertyAccessor)
|
||||
val rawValue = extra.typeInfo.argToBridged("value")
|
||||
propertyAccessorBridgeBodies[accessor] = "writeBits(this.rawPtr, ${accessor.offset}, ${accessor.size}, $rawValue.toLong())"
|
||||
propertyAccessorBridgeBodies[propertyAccessor] = "writeBits(this.rawPtr, ${propertyAccessor.offset}, ${propertyAccessor.size}, $rawValue.toLong())"
|
||||
}
|
||||
|
||||
is PropertyAccessor.Getter.InterpretPointed -> {
|
||||
val getAddressExpression = getGlobalAddressExpression(accessor.cGlobalName, accessor)
|
||||
propertyAccessorBridgeBodies[accessor] = getAddressExpression
|
||||
val getAddressExpression = getGlobalAddressExpression(propertyAccessor.cGlobalName, propertyAccessor)
|
||||
propertyAccessorBridgeBodies[propertyAccessor] = getAddressExpression
|
||||
}
|
||||
|
||||
is PropertyAccessor.Getter.ExternalGetter -> {
|
||||
if (accessor in builderResult.wrapperGenerationComponents.getterToWrapperInfo) {
|
||||
val extra = builderResult.wrapperGenerationComponents.getterToWrapperInfo.getValue(accessor)
|
||||
val cCallAnnotation = accessor.annotations.firstIsInstanceOrNull<AnnotationStub.CCall.Symbol>()
|
||||
if (propertyAccessor in builderResult.wrapperGenerationComponents.getterToWrapperInfo) {
|
||||
val extra = builderResult.wrapperGenerationComponents.getterToWrapperInfo.getValue(propertyAccessor)
|
||||
val cCallAnnotation = propertyAccessor.annotations.firstIsInstanceOrNull<AnnotationStub.CCall.Symbol>()
|
||||
?: error("external getter for ${extra.global.name} wasn't marked with @CCall")
|
||||
val wrapper = if (extra.passViaPointer) {
|
||||
wrapperGenerator.generateCGlobalByPointerGetter(extra.global, cCallAnnotation.symbolName)
|
||||
} else {
|
||||
wrapperGenerator.generateCGlobalGetter(extra.global, cCallAnnotation.symbolName)
|
||||
}
|
||||
simpleBridgeGenerator.insertNativeBridge(accessor, emptyList(), wrapper.lines)
|
||||
simpleBridgeGenerator.insertNativeBridge(propertyAccessor, emptyList(), wrapper.lines)
|
||||
}
|
||||
}
|
||||
|
||||
is PropertyAccessor.Setter.ExternalSetter -> {
|
||||
if (accessor in builderResult.wrapperGenerationComponents.setterToWrapperInfo) {
|
||||
val extra = builderResult.wrapperGenerationComponents.setterToWrapperInfo.getValue(accessor)
|
||||
val cCallAnnotation = accessor.annotations.firstIsInstanceOrNull<AnnotationStub.CCall.Symbol>()
|
||||
if (propertyAccessor in builderResult.wrapperGenerationComponents.setterToWrapperInfo) {
|
||||
val extra = builderResult.wrapperGenerationComponents.setterToWrapperInfo.getValue(propertyAccessor)
|
||||
val cCallAnnotation = propertyAccessor.annotations.firstIsInstanceOrNull<AnnotationStub.CCall.Symbol>()
|
||||
?: error("external setter for ${extra.global.name} wasn't marked with @CCall")
|
||||
val wrapper = wrapperGenerator.generateCGlobalSetter(extra.global, cCallAnnotation.symbolName)
|
||||
simpleBridgeGenerator.insertNativeBridge(accessor, emptyList(), wrapper.lines)
|
||||
simpleBridgeGenerator.insertNativeBridge(propertyAccessor, emptyList(), wrapper.lines)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitSimpleStubContainer(simpleStubContainer: SimpleStubContainer, owner: StubContainer?) {
|
||||
override fun visitSimpleStubContainer(simpleStubContainer: SimpleStubContainer, data: StubContainer?) {
|
||||
simpleStubContainer.classes.forEach {
|
||||
it.accept(this, simpleStubContainer)
|
||||
}
|
||||
|
||||
+1
-1
@@ -147,7 +147,7 @@ class StubIrDriver(
|
||||
) = Result.Metadata(StubIrMetadataEmitter(context, builderResult, moduleName, bridgeBuilderResult).emit())
|
||||
|
||||
private fun emitCFile(context: StubIrContext, cFile: Appendable, entryPoint: String?, nativeBridges: NativeBridges) {
|
||||
val out = { it: String -> cFile.appendln(it) }
|
||||
val out = { it: String -> cFile.appendLine(it) }
|
||||
|
||||
context.libraryForCStubs.preambleLines.forEach {
|
||||
out(it)
|
||||
|
||||
+11
-11
@@ -57,7 +57,7 @@ class StubIrTextEmitter(
|
||||
}
|
||||
|
||||
private fun <R> withOutput(appendable: Appendable, action: () -> R): R {
|
||||
return withOutput({ appendable.appendln(it) }, action)
|
||||
return withOutput({ appendable.appendLine(it) }, action)
|
||||
}
|
||||
|
||||
private fun generateLinesBy(action: () -> Unit): List<String> {
|
||||
@@ -148,7 +148,7 @@ class StubIrTextEmitter(
|
||||
}
|
||||
private val printer = object : StubIrVisitor<StubContainer?, Unit> {
|
||||
|
||||
override fun visitClass(element: ClassStub, owner: StubContainer?) {
|
||||
override fun visitClass(element: ClassStub, data: StubContainer?) {
|
||||
element.annotations.forEach {
|
||||
out(renderAnnotation(it))
|
||||
}
|
||||
@@ -173,13 +173,13 @@ class StubIrTextEmitter(
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitTypealias(element: TypealiasStub, owner: StubContainer?) {
|
||||
override fun visitTypealias(element: TypealiasStub, data: StubContainer?) {
|
||||
val alias = renderClassifierDeclaration(element.alias)
|
||||
val aliasee = renderStubType(element.aliasee)
|
||||
out("typealias $alias = $aliasee")
|
||||
}
|
||||
|
||||
override fun visitFunction(element: FunctionStub, owner: StubContainer?) {
|
||||
override fun visitFunction(element: FunctionStub, data: StubContainer?) {
|
||||
if (element in bridgeBuilderResult.excludedStubs) return
|
||||
|
||||
val header = run {
|
||||
@@ -187,7 +187,7 @@ class StubIrTextEmitter(
|
||||
val receiver = element.receiver?.let { renderFunctionReceiver(it) + "." } ?: ""
|
||||
val typeParameters = renderTypeParameters(element.typeParameters)
|
||||
val override = if (element.isOverride) "override " else ""
|
||||
val modality = renderMemberModality(element.modality, owner)
|
||||
val modality = renderMemberModality(element.modality, data)
|
||||
"$override${modality}fun$typeParameters $receiver${element.name.asSimpleName()}$parameters: ${renderStubType(element.returnType)}"
|
||||
}
|
||||
if (!nativeBridges.isSupported(element)) {
|
||||
@@ -205,17 +205,17 @@ class StubIrTextEmitter(
|
||||
element.isOptionalObjCMethod() -> out("$header = optional()")
|
||||
element.origin is StubOrigin.Synthetic.EnumByValue ->
|
||||
out("$header = values().find { it.value == value }!!")
|
||||
owner != null && owner.isInterface -> out(header)
|
||||
data != null && data.isInterface -> out(header)
|
||||
else -> block(header) {
|
||||
functionBridgeBodies.getValue(element).forEach(out)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitProperty(element: PropertyStub, owner: StubContainer?) =
|
||||
emitProperty(element, owner)
|
||||
override fun visitProperty(element: PropertyStub, data: StubContainer?) =
|
||||
emitProperty(element, data)
|
||||
|
||||
override fun visitConstructor(constructorStub: ConstructorStub, owner: StubContainer?) {
|
||||
override fun visitConstructor(constructorStub: ConstructorStub, data: StubContainer?) {
|
||||
constructorStub.annotations.forEach {
|
||||
out(renderAnnotation(it))
|
||||
}
|
||||
@@ -223,11 +223,11 @@ class StubIrTextEmitter(
|
||||
out("${visibility}constructor(${constructorStub.parameters.joinToString { renderFunctionParameter(it) }}) {}")
|
||||
}
|
||||
|
||||
override fun visitPropertyAccessor(propertyAccessor: PropertyAccessor, owner: StubContainer?) {
|
||||
override fun visitPropertyAccessor(propertyAccessor: PropertyAccessor, data: StubContainer?) {
|
||||
|
||||
}
|
||||
|
||||
override fun visitSimpleStubContainer(simpleStubContainer: SimpleStubContainer, owner: StubContainer?) {
|
||||
override fun visitSimpleStubContainer(simpleStubContainer: SimpleStubContainer, data: StubContainer?) {
|
||||
if (simpleStubContainer.meta.textAtStart.isNotEmpty()) {
|
||||
out(simpleStubContainer.meta.textAtStart)
|
||||
}
|
||||
|
||||
+2
-3
@@ -7,7 +7,6 @@ import org.jetbrains.kotlin.native.interop.gen.jvm.prepareTool
|
||||
import org.jetbrains.kotlin.native.interop.indexer.NativeLibraryHeaders
|
||||
import org.jetbrains.kotlin.native.interop.indexer.getHeaderPaths
|
||||
import org.jetbrains.kotlin.native.interop.tool.CInteropArguments
|
||||
import kotlinx.cli.ArgParser
|
||||
import java.io.File
|
||||
|
||||
fun defFileDependencies(args: Array<String>) {
|
||||
@@ -40,7 +39,7 @@ private fun makeDependencyAssigner(targets: List<String>, defFiles: List<File>)
|
||||
private fun makeDependencyAssignerForTarget(target: String, defFiles: List<File>): SingleTargetDependencyAssigner {
|
||||
val tool = prepareTool(target, KotlinPlatform.NATIVE)
|
||||
val cinteropArguments = CInteropArguments()
|
||||
cinteropArguments.argParser.parse(arrayOf<String>())
|
||||
cinteropArguments.argParser.parse(arrayOf())
|
||||
val libraries = defFiles.associateWith {
|
||||
buildNativeLibrary(
|
||||
tool,
|
||||
@@ -73,7 +72,7 @@ private fun patchDepends(file: File, newDepends: List<String>) {
|
||||
val newDefFileLines = listOf(dependsLine) + defFileLines.filter { !it.startsWith("depends =") }
|
||||
|
||||
file.bufferedWriter().use { writer ->
|
||||
newDefFileLines.forEach { writer.appendln(it) }
|
||||
newDefFileLines.forEach { writer.appendLine(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -54,8 +54,8 @@ fun createInteropLibrary(
|
||||
nopack = nopack,
|
||||
shortName = shortName
|
||||
).apply {
|
||||
val metadata = metadata.write(ChunkingWriteStrategy())
|
||||
addMetadata(SerializedMetadata(metadata.header, metadata.fragments, metadata.fragmentNames))
|
||||
val serializedMetadata = metadata.write(ChunkingWriteStrategy())
|
||||
addMetadata(SerializedMetadata(serializedMetadata.header, serializedMetadata.fragments, serializedMetadata.fragmentNames))
|
||||
nativeBitcodeFiles.forEach(this::addNativeBitcode)
|
||||
addManifestAddend(manifest)
|
||||
addLinkDependencies(dependencies)
|
||||
|
||||
@@ -56,7 +56,8 @@ compileCompilerKotlin {
|
||||
// but not for Kotlin.
|
||||
dependsOn('generateCompilerProto')
|
||||
kotlinOptions.jvmTarget = "1.8"
|
||||
kotlinOptions.freeCompilerArgs += "-Xopt-in=org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI"
|
||||
kotlinOptions.allWarningsAsErrors=true
|
||||
kotlinOptions.freeCompilerArgs += ['-Xopt-in=kotlin.RequiresOptIn', '-Xopt-in=org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI']
|
||||
}
|
||||
|
||||
compileCompilerJava {
|
||||
@@ -200,7 +201,9 @@ final List<File> stdLibSrc = [
|
||||
targetList.each { target ->
|
||||
def konanJvmArgs = [*HostManager.regularJvmArgs]
|
||||
|
||||
def defaultArgs = ['-nopack', '-nostdlib', '-no-default-libs', '-no-endorsed-libs']
|
||||
def defaultArgs = ['-nopack', '-nostdlib', '-no-default-libs', '-no-endorsed-libs',
|
||||
//Uncomment this '-Werror' when common stdlib will be ready
|
||||
]
|
||||
if (target != "wasm32") defaultArgs += '-g'
|
||||
def konanArgs = [*defaultArgs,
|
||||
'-target', target,
|
||||
|
||||
+27
-8
@@ -19,10 +19,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
@@ -113,7 +110,7 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
||||
|
||||
val builtFunctionNClasses get() =
|
||||
builtClassesMap.values
|
||||
.filter { (it.descriptor as FunctionClassDescriptor).functionKind == FunctionClassDescriptor.Kind.Function }
|
||||
.filter { it -> (it.descriptor as FunctionClassDescriptor).functionKind == FunctionClassDescriptor.Kind.Function }
|
||||
.map { FunctionalInterface(it, (it.descriptor as FunctionClassDescriptor).arity) }
|
||||
|
||||
private fun createTypeParameter(descriptor: TypeParameterDescriptor) =
|
||||
@@ -122,8 +119,14 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
||||
descriptor
|
||||
)
|
||||
?: IrTypeParameterImpl(
|
||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET, DECLARATION_ORIGIN_FUNCTION_CLASS,
|
||||
descriptor
|
||||
SYNTHETIC_OFFSET,
|
||||
SYNTHETIC_OFFSET,
|
||||
DECLARATION_ORIGIN_FUNCTION_CLASS,
|
||||
IrTypeParameterSymbolImpl(descriptor),
|
||||
descriptor.name,
|
||||
descriptor.index,
|
||||
descriptor.isReified,
|
||||
descriptor.variance
|
||||
)
|
||||
|
||||
private fun createSimpleFunction(
|
||||
@@ -301,7 +304,23 @@ internal class BuiltInFictitiousFunctionIrClassFactory(
|
||||
|
||||
fun createFakeOverrideProperty(descriptor: PropertyDescriptor): IrProperty {
|
||||
val propertyDeclare = { s: IrPropertySymbol ->
|
||||
IrPropertyImpl(offset, offset, memberOrigin, descriptor, s, descriptor.name)
|
||||
@Suppress("DEPRECATION")
|
||||
/* TODO: [PropertyDescriptor::isDelegated] is deprecated. */
|
||||
IrPropertyImpl(
|
||||
startOffset = offset,
|
||||
endOffset = offset,
|
||||
origin = memberOrigin,
|
||||
symbol = s,
|
||||
name = descriptor.name,
|
||||
visibility = descriptor.visibility,
|
||||
modality = descriptor.modality,
|
||||
isVar = descriptor.isVar,
|
||||
isConst = descriptor.isConst,
|
||||
isLateinit = descriptor.isLateInit,
|
||||
isDelegated = descriptor.isDelegated,
|
||||
isExternal = descriptor.isExternal,
|
||||
isExpect = descriptor.isExpect,
|
||||
isFakeOverride = memberOrigin == IrDeclarationOrigin.FAKE_OVERRIDE)
|
||||
}
|
||||
val property = symbolTable?.declareProperty(offset, offset, memberOrigin, descriptor, propertyFactory = propertyDeclare)
|
||||
?: propertyDeclare(IrPropertySymbolImpl(descriptor))
|
||||
|
||||
+15
-8
@@ -46,9 +46,11 @@ import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager
|
||||
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
|
||||
import org.jetbrains.kotlin.library.SerializedIrModule
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
|
||||
/**
|
||||
* Offset for synthetic elements created by lowerings and not attributable to other places in the source code.
|
||||
@@ -56,7 +58,7 @@ import org.jetbrains.kotlin.library.SerializedIrModule
|
||||
|
||||
internal class SpecialDeclarationsFactory(val context: Context) {
|
||||
private val enumSpecialDeclarationsFactory by lazy { EnumSpecialDeclarationsFactory(context) }
|
||||
private val outerThisFields = mutableMapOf<ClassDescriptor, IrField>()
|
||||
private val outerThisFields = mutableMapOf<IrClass, IrField>()
|
||||
private val bridgesDescriptors = mutableMapOf<Pair<IrSimpleFunction, BridgeDirections>, IrSimpleFunction>()
|
||||
private val loweredEnums = mutableMapOf<IrClass, LoweredEnum>()
|
||||
private val ordinals = mutableMapOf<ClassDescriptor, Map<ClassDescriptor, Int>>()
|
||||
@@ -67,8 +69,8 @@ internal class SpecialDeclarationsFactory(val context: Context) {
|
||||
IrDeclarationOriginImpl("FIELD_FOR_OUTER_THIS")
|
||||
|
||||
fun getOuterThisField(innerClass: IrClass): IrField =
|
||||
if (!innerClass.descriptor.isInner) throw AssertionError("Class is not inner: ${innerClass.descriptor}")
|
||||
else outerThisFields.getOrPut(innerClass.descriptor) {
|
||||
if (!innerClass.isInner) throw AssertionError("Class is not inner: ${innerClass.descriptor}")
|
||||
else outerThisFields.getOrPut(innerClass) {
|
||||
val outerClass = innerClass.parent as? IrClass
|
||||
?: throw AssertionError("No containing class for inner class ${innerClass.descriptor}")
|
||||
|
||||
@@ -87,11 +89,16 @@ internal class SpecialDeclarationsFactory(val context: Context) {
|
||||
}
|
||||
|
||||
IrFieldImpl(
|
||||
innerClass.startOffset,
|
||||
innerClass.endOffset,
|
||||
DECLARATION_ORIGIN_FIELD_FOR_OUTER_THIS,
|
||||
descriptor,
|
||||
outerClass.defaultType
|
||||
startOffset = innerClass.startOffset,
|
||||
endOffset = innerClass.endOffset,
|
||||
origin = DECLARATION_ORIGIN_FIELD_FOR_OUTER_THIS,
|
||||
symbol = IrFieldSymbolImpl(descriptor),
|
||||
name = descriptor.name,
|
||||
type = outerClass.defaultType,
|
||||
visibility = descriptor.visibility,
|
||||
isFinal = !descriptor.isVar,
|
||||
isExternal = descriptor.isEffectivelyExternal(),
|
||||
isStatic = descriptor.dispatchReceiverParameter == null
|
||||
).apply {
|
||||
parent = innerClass
|
||||
}
|
||||
|
||||
+8
-6
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.library.SearchPathResolver
|
||||
import org.jetbrains.kotlin.library.isInterop
|
||||
import org.jetbrains.kotlin.library.toUnresolvedLibraries
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
internal fun Context.getExportedDependencies(): List<ModuleDescriptor> = getDescriptorsFromLibraries((config.resolve.exportedLibraries + config.resolve.includedLibraries).toSet())
|
||||
internal fun Context.getIncludedLibraryDescriptors(): List<ModuleDescriptor> = getDescriptorsFromLibraries(config.resolve.includedLibraries.toSet())
|
||||
@@ -93,11 +94,11 @@ private sealed class FeaturedLibrariesReporter {
|
||||
|
||||
override fun reportNotIncludedLibraries(includedLibraries: List<KonanLibrary>, remainingFeaturedLibraries: Set<File>) {
|
||||
val message = buildString {
|
||||
appendln(notIncludedLibraryMessageTitle())
|
||||
remainingFeaturedLibraries.forEach { appendln(it) }
|
||||
appendln()
|
||||
appendln("Included libraries:")
|
||||
includedLibraries.forEach { appendln(it.libraryFile) }
|
||||
appendLine(notIncludedLibraryMessageTitle())
|
||||
remainingFeaturedLibraries.forEach { appendLine(it) }
|
||||
appendLine()
|
||||
appendLine("Included libraries:")
|
||||
includedLibraries.forEach { appendLine(it.libraryFile) }
|
||||
}
|
||||
|
||||
configuration.report(CompilerMessageSeverity.STRONG_WARNING, message)
|
||||
@@ -163,7 +164,8 @@ private fun getFeaturedLibraries(
|
||||
) : List<KonanLibrary> {
|
||||
val remainingFeaturedLibraries = featuredLibraryFiles.toMutableSet()
|
||||
val result = mutableListOf<KonanLibrary>()
|
||||
val libraries = resolvedLibraries.getFullList(null) as List<KonanLibrary>
|
||||
//TODO: please add type checks before cast.
|
||||
val libraries = resolvedLibraries.getFullList(null).cast<List<KonanLibrary>>()
|
||||
|
||||
for (library in libraries) {
|
||||
val libraryFile = library.libraryFile
|
||||
|
||||
+5
-5
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.konan.target.*
|
||||
import org.jetbrains.kotlin.konan.util.KonanHomeProvider
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
class KonanConfig(val project: Project, val configuration: CompilerConfiguration) {
|
||||
|
||||
@@ -32,7 +33,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
||||
configuration.get(KonanConfigKeys.RUNTIME_FILE)
|
||||
)
|
||||
|
||||
internal val platformManager = PlatformManager(distribution)
|
||||
private val platformManager = PlatformManager(distribution)
|
||||
internal val targetManager = platformManager.targetManager(configuration.get(KonanConfigKeys.TARGET))
|
||||
internal val target = targetManager.target
|
||||
internal val phaseConfig = configuration.get(CLIConfigurationKeys.PHASE_CONFIG)!!
|
||||
@@ -78,7 +79,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
||||
|
||||
internal val resolvedLibraries get() = resolve.resolvedLibraries
|
||||
|
||||
internal val cacheSupport = CacheSupport(configuration, resolvedLibraries, target, produce)
|
||||
private val cacheSupport = CacheSupport(configuration, resolvedLibraries, target, produce)
|
||||
|
||||
internal val cachedLibraries: CachedLibraries
|
||||
get() = cacheSupport.cachedLibraries
|
||||
@@ -106,12 +107,11 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
|
||||
|
||||
fun librariesWithDependencies(moduleDescriptor: ModuleDescriptor?): List<KonanLibrary> {
|
||||
if (moduleDescriptor == null) error("purgeUnneeded() only works correctly after resolve is over, and we have successfully marked package files as needed or not needed.")
|
||||
|
||||
return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder) as List<KonanLibrary>
|
||||
return resolvedLibraries.filterRoots { (!it.isDefault && !this.purgeUserLibs) || it.isNeededForLink }.getFullList(TopologicalLibraryOrder).cast()
|
||||
}
|
||||
|
||||
val shouldCoverSources = configuration.getBoolean(KonanConfigKeys.COVERAGE)
|
||||
val shouldCoverLibraries = !configuration.getList(KonanConfigKeys.LIBRARIES_TO_COVER).isNullOrEmpty()
|
||||
private val shouldCoverLibraries = !configuration.getList(KonanConfigKeys.LIBRARIES_TO_COVER).isNullOrEmpty()
|
||||
|
||||
internal val runtimeNativeLibraries: List<String> = mutableListOf<String>().apply {
|
||||
add(if (debug) "debug.bc" else "release.bc")
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.konan
|
||||
import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase
|
||||
import org.jetbrains.kotlin.backend.common.phaser.invokeToplevel
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironment) {
|
||||
|
||||
@@ -25,7 +26,7 @@ fun runTopLevelPhases(konanConfig: KonanConfig, environment: KotlinCoreEnvironme
|
||||
if (konanConfig.infoArgsOnly) return
|
||||
|
||||
try {
|
||||
(toplevelPhase as CompilerPhase<Context, Unit, Unit>).invokeToplevel(context.phaseConfig, context, Unit)
|
||||
toplevelPhase.cast<CompilerPhase<Context, Unit, Unit>>().invokeToplevel(context.phaseConfig, context, Unit)
|
||||
} finally {
|
||||
context.disposeLlvm()
|
||||
}
|
||||
|
||||
-6
@@ -39,7 +39,6 @@ private val objCConstructorFqName = FqName("kotlinx.cinterop.ObjCConstructor")
|
||||
private val objCFactoryFqName = interopPackageName.child(Name.identifier("ObjCFactory"))
|
||||
private val objcnamesForwardDeclarationsPackageName = Name.identifier("objcnames")
|
||||
|
||||
@Deprecated("Use IR version rather than descriptor version")
|
||||
fun ClassDescriptor.isObjCClass(): Boolean =
|
||||
this.getAllSuperClassifiers().any { it.fqNameSafe == objCObjectFqName } && // TODO: this is not cheap. Cache me!
|
||||
this.containingDeclaration.fqNameSafe != interopPackageName
|
||||
@@ -53,7 +52,6 @@ private fun IrClass.getAllSuperClassifiers(): List<IrClass> =
|
||||
internal fun IrClass.isObjCClass() = this.getAllSuperClassifiers().any { it.fqNameForIrSerialization == objCObjectFqName } &&
|
||||
this.parent.fqNameForIrSerialization != interopPackageName
|
||||
|
||||
@Deprecated("Use IR version rather than descriptor version")
|
||||
fun ClassDescriptor.isExternalObjCClass(): Boolean = this.isObjCClass() &&
|
||||
this.parentsWithSelf.filterIsInstance<ClassDescriptor>().any {
|
||||
it.annotations.findAnnotation(externalObjCClassFqName) != null
|
||||
@@ -86,7 +84,6 @@ fun FunctionDescriptor.isObjCClassMethod() =
|
||||
fun IrFunction.isObjCClassMethod() =
|
||||
this.parent.let { it is IrClass && it.isObjCClass() }
|
||||
|
||||
@Deprecated("Use IR version rather than descriptor version")
|
||||
fun FunctionDescriptor.isExternalObjCClassMethod() =
|
||||
this.containingDeclaration.let { it is ClassDescriptor && it.isExternalObjCClass() }
|
||||
|
||||
@@ -94,14 +91,12 @@ internal fun IrFunction.isExternalObjCClassMethod() =
|
||||
this.parent.let {it is IrClass && it.isExternalObjCClass()}
|
||||
|
||||
// Special case: methods from Kotlin Objective-C classes can be called virtually from bridges.
|
||||
@Deprecated("Use IR version rather than descriptor version")
|
||||
fun FunctionDescriptor.canObjCClassMethodBeCalledVirtually(overriddenDescriptor: FunctionDescriptor) =
|
||||
overriddenDescriptor.isOverridable && this.kind.isReal && !this.isExternalObjCClassMethod()
|
||||
|
||||
internal fun IrFunction.canObjCClassMethodBeCalledVirtually(overridden: IrFunction) =
|
||||
overridden.isOverridable && this.origin != IrDeclarationOrigin.FAKE_OVERRIDE && !this.isExternalObjCClassMethod()
|
||||
|
||||
@Deprecated("Use IR version rather than descriptor version")
|
||||
fun ClassDescriptor.isKotlinObjCClass(): Boolean = this.isObjCClass() && !this.isExternalObjCClass()
|
||||
|
||||
fun IrClass.isKotlinObjCClass(): Boolean = this.isObjCClass() && !this.isExternalObjCClass()
|
||||
@@ -249,7 +244,6 @@ fun IrConstructor.objCConstructorIsDesignated(): Boolean =
|
||||
this.getAnnotationArgumentValue<Boolean>(objCConstructorFqName, "designated")
|
||||
?: error("Could not find 'designated' argument")
|
||||
|
||||
@Deprecated("Use IR version rather than descriptor version")
|
||||
fun ConstructorDescriptor.objCConstructorIsDesignated(): Boolean {
|
||||
val annotation = this.annotations.findAnnotation(objCConstructorFqName)!!
|
||||
val value = annotation.allValueArguments[Name.identifier("designated")]!!
|
||||
|
||||
+2
-2
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrTryImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
|
||||
import org.jetbrains.kotlin.ir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
@@ -103,7 +103,7 @@ private fun createKotlinBridge(
|
||||
isExternal: Boolean
|
||||
): IrFunctionImpl {
|
||||
val bridgeDescriptor = WrappedSimpleFunctionDescriptor()
|
||||
val bridge = IrFunctionImpl(
|
||||
@Suppress("DEPRECATION") val bridge = IrFunctionImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
|
||||
+1
-1
@@ -120,7 +120,7 @@ internal class GlobalHierarchyAnalysis(val context: Context, val irModule: IrMod
|
||||
* else binary_search(0, -size)
|
||||
*/
|
||||
val interfaceColors = assignColorsToInterfaces()
|
||||
val maxColor = interfaceColors.values.max() ?: 0
|
||||
val maxColor = interfaceColors.values.maxOrNull() ?: 0
|
||||
var bitsPerColor = 0
|
||||
var x = maxColor
|
||||
while (x > 0) {
|
||||
|
||||
+6
-9
@@ -6,12 +6,8 @@
|
||||
package org.jetbrains.kotlin.backend.konan.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||
import org.jetbrains.kotlin.backend.konan.KonanFqNames
|
||||
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
||||
import org.jetbrains.kotlin.backend.konan.binaryTypeIsReference
|
||||
import org.jetbrains.kotlin.backend.konan.ir.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.backend.konan.ir.getSuperInterfaces
|
||||
import org.jetbrains.kotlin.backend.konan.isInlinedNative
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.longName
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
@@ -27,6 +23,7 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.resolve.annotations.argumentValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
/**
|
||||
@@ -214,11 +211,11 @@ internal val IrClass.isFrozen: Boolean
|
||||
// RTTI is used for non-reference type box:
|
||||
!this.defaultType.binaryTypeIsReference()
|
||||
|
||||
fun IrConstructorCall.getAnnotationStringValue() = (getValueArgument(0) as? IrConst<String>)?.value
|
||||
fun IrConstructorCall.getAnnotationStringValue() = getValueArgument(0).safeAs<IrConst<String>>()?.value
|
||||
|
||||
fun IrConstructorCall.getAnnotationStringValue(name: String): String {
|
||||
val parameter = symbol.owner.valueParameters.single { it.name.asString() == name }
|
||||
return (getValueArgument(parameter.index) as IrConst<String>).value
|
||||
return getValueArgument(parameter.index).cast<IrConst<String>>().value
|
||||
}
|
||||
|
||||
fun AnnotationDescriptor.getAnnotationStringValue(name: String): String {
|
||||
@@ -227,7 +224,7 @@ fun AnnotationDescriptor.getAnnotationStringValue(name: String): String {
|
||||
|
||||
fun <T> IrConstructorCall.getAnnotationValueOrNull(name: String): T? {
|
||||
val parameter = symbol.owner.valueParameters.atMostOne { it.name.asString() == name }
|
||||
return parameter?.let { getValueArgument(it.index)?.let { (it as IrConst<T>).value } }
|
||||
return parameter?.let { getValueArgument(it.index)?.let { (it.cast<IrConst<T>>()).value } }
|
||||
}
|
||||
|
||||
fun IrFunction.externalSymbolOrThrow(): String? {
|
||||
|
||||
+2
-5
@@ -7,20 +7,17 @@ package org.jetbrains.kotlin.backend.konan.descriptors
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
|
||||
import org.jetbrains.kotlin.library.metadata.KlibMetadataProtoBuf
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
|
||||
@@ -119,7 +116,7 @@ fun AnnotationDescriptor.getStringValueOrNull(name: String): String? {
|
||||
return constantValue?.value as String?
|
||||
}
|
||||
|
||||
fun <T> AnnotationDescriptor.getArgumentValueOrNull(name: String): T? {
|
||||
inline fun <reified T> AnnotationDescriptor.getArgumentValueOrNull(name: String): T? {
|
||||
val constantValue = this.allValueArguments.entries.atMostOne {
|
||||
it.key.asString() == name
|
||||
}?.value
|
||||
|
||||
+3
-2
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.ir.types.isMarkedNullable
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
val IrField.fqNameForIrSerialization: FqName get() = this.parent.fqNameForIrSerialization.child(this.name)
|
||||
|
||||
@@ -67,12 +68,12 @@ val IrClass.isFinalClass: Boolean
|
||||
|
||||
fun IrClass.isSpecialClassWithNoSupertypes() = this.isAny() || this.isNothing()
|
||||
|
||||
fun <T> IrDeclaration.getAnnotationArgumentValue(fqName: FqName, argumentName: String): T? {
|
||||
inline fun <reified T> IrDeclaration.getAnnotationArgumentValue(fqName: FqName, argumentName: String): T? {
|
||||
val annotation = this.annotations.findAnnotation(fqName) ?: return null
|
||||
for (index in 0 until annotation.valueArgumentsCount) {
|
||||
val parameter = annotation.symbol.owner.valueParameters[index]
|
||||
if (parameter.name == Name.identifier(argumentName)) {
|
||||
val actual = annotation.getValueArgument(index) as? IrConst<T>
|
||||
val actual = annotation.getValueArgument(index).safeAs<IrConst<T>>()
|
||||
return actual?.value
|
||||
}
|
||||
}
|
||||
|
||||
+4
-2
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
|
||||
import org.jetbrains.kotlin.ir.types.impl.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperInterfaces
|
||||
@@ -79,12 +79,14 @@ internal interface DescriptorToIrTranslationMixin {
|
||||
is PropertyDescriptor -> createProperty(it)
|
||||
is FunctionDescriptor -> createFunction(it, IrDeclarationOrigin.FAKE_OVERRIDE)
|
||||
else -> error("Unexpected fake override descriptor: $it")
|
||||
} as IrDeclaration // Assistance for type inference.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createConstructor(constructorDescriptor: ClassConstructorDescriptor): IrConstructor {
|
||||
val irConstructor = symbolTable.declareConstructor(constructorDescriptor) {
|
||||
// TODO: [IrUninitializedType] is deprecated.
|
||||
@Suppress("DEPRECATION")
|
||||
IrConstructorImpl(
|
||||
SYNTHETIC_OFFSET, SYNTHETIC_OFFSET,
|
||||
IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB,
|
||||
|
||||
+1
-1
@@ -133,7 +133,7 @@ internal fun RuntimeAware.getLlvmFunctionType(function: IrFunction): LLVMTypeRef
|
||||
paramTypes.add(kObjHeaderPtr) // Suspend functions have implicit parameter of type Continuation<>.
|
||||
if (isObjectType(returnType)) paramTypes.add(kObjHeaderPtrPtr)
|
||||
|
||||
return functionType(returnType, isVarArg = false, paramTypes = *paramTypes.toTypedArray())
|
||||
return functionType(returnType, isVarArg = false, paramTypes = paramTypes.toTypedArray())
|
||||
}
|
||||
|
||||
internal val IrClass.typeInfoHasVtableAttached: Boolean
|
||||
|
||||
+2
-1
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.*
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
internal val contextLLVMSetupPhase = makeKonanModuleOpPhase(
|
||||
name = "ContextLLVMSetup",
|
||||
@@ -45,7 +46,7 @@ internal val contextLLVMSetupPhase = makeKonanModuleOpPhase(
|
||||
producer = DWARF.producer,
|
||||
isOptimized = 0,
|
||||
flags = "",
|
||||
rv = DWARF.runtimeVersion(context.config)) as DIScopeOpaqueRef?
|
||||
rv = DWARF.runtimeVersion(context.config)).cast()
|
||||
else null
|
||||
}
|
||||
)
|
||||
|
||||
+9
-9
@@ -5,9 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.llvm
|
||||
|
||||
import kotlinx.cinterop.*
|
||||
import kotlinx.cinterop.allocArray
|
||||
import kotlinx.cinterop.get
|
||||
import kotlinx.cinterop.memScoped
|
||||
import kotlinx.cinterop.toKString
|
||||
import llvm.*
|
||||
import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.backend.konan.hash.GlobalHash
|
||||
import org.jetbrains.kotlin.backend.konan.ir.llvmSymbolOrigin
|
||||
@@ -15,18 +17,16 @@ import org.jetbrains.kotlin.descriptors.konan.CompiledKlibModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.CurrentKlibModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.util.file
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.isReal
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.library.uniqueName
|
||||
import org.jetbrains.kotlin.library.unresolvedDependencies
|
||||
import org.jetbrains.kotlin.library.resolver.TopologicalLibraryOrder
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import kotlin.properties.ReadOnlyProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
@@ -208,7 +208,7 @@ internal interface ContextUtils : RuntimeAware {
|
||||
*/
|
||||
fun GlobalHash.getBytes(): ByteArray {
|
||||
val size = GlobalHash.size
|
||||
assert(size.toLong() == LLVMStoreSizeOfType(llvmTargetData, runtime.globalHashType))
|
||||
assert(size == LLVMStoreSizeOfType(llvmTargetData, runtime.globalHashType))
|
||||
|
||||
return this.bits.getBytes(size)
|
||||
}
|
||||
@@ -394,7 +394,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
.filter {
|
||||
require(it is KonanLibrary)
|
||||
(!it.isDefault && !context.config.purgeUserLibs) || imports.nativeDependenciesAreUsed(it)
|
||||
} as List<KonanLibrary>
|
||||
}.cast<List<KonanLibrary>>()
|
||||
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
}
|
||||
|
||||
val bitcodeToLink: List<KonanLibrary> by lazy {
|
||||
(context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder) as List<KonanLibrary>)
|
||||
(context.config.resolvedLibraries.getFullList(TopologicalLibraryOrder).cast<List<KonanLibrary>>())
|
||||
.filter { shouldContainBitcode(it) }
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.konan.CURRENT
|
||||
import org.jetbrains.kotlin.konan.CompilerVersion
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
internal object DWARF {
|
||||
val producer = "konanc ${CompilerVersion.CURRENT} / kotlin-compiler: ${KotlinVersion.CURRENT}"
|
||||
@@ -173,7 +174,7 @@ internal fun generateDebugInfoHeader(context: Context) {
|
||||
derivedFrom = null,
|
||||
elements = null,
|
||||
elementsCount = 0,
|
||||
refPlace = null)!! as DITypeOpaqueRef
|
||||
refPlace = null).cast<DITypeOpaqueRef>()
|
||||
context.debugInfo.objHeaderPointerType = dwarfPointerType(context, objHeaderType)
|
||||
}
|
||||
}
|
||||
@@ -181,7 +182,7 @@ internal fun generateDebugInfoHeader(context: Context) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
internal fun IrType.dwarfType(context: Context, targetData: LLVMTargetDataRef): DITypeOpaqueRef {
|
||||
when {
|
||||
this.computePrimitiveBinaryTypeOrNull() != null -> return debugInfoBaseType(context, targetData, this.render(), llvmType(context), encoding(context).value.toInt())
|
||||
this.computePrimitiveBinaryTypeOrNull() != null -> return debugInfoBaseType(context, targetData, this.render(), llvmType(context), encoding().value.toInt())
|
||||
else -> {
|
||||
return when {
|
||||
classOrNull != null || this.isTypeParameter() -> context.debugInfo.objHeaderPointerType!!
|
||||
@@ -225,7 +226,7 @@ internal fun IrType.llvmType(context:Context): LLVMTypeRef = context.debugInfo.l
|
||||
}
|
||||
}
|
||||
|
||||
internal fun IrType.encoding(context: Context): DwarfTypeKind = when(computePrimitiveBinaryTypeOrNull()) {
|
||||
internal fun IrType.encoding(): DwarfTypeKind = when(computePrimitiveBinaryTypeOrNull()) {
|
||||
PrimitiveBinaryType.FLOAT -> DwarfTypeKind.DW_ATE_float
|
||||
PrimitiveBinaryType.DOUBLE -> DwarfTypeKind.DW_ATE_float
|
||||
PrimitiveBinaryType.BOOLEAN -> DwarfTypeKind.DW_ATE_boolean
|
||||
|
||||
+6
-32
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.coverage.LLVMCoverageInstrumentation
|
||||
import org.jetbrains.kotlin.backend.konan.optimizations.DataFlowIR
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
@@ -424,7 +423,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
}
|
||||
context.llvm.fileInitializers
|
||||
.forEach { irField ->
|
||||
val expression = irField.initializer?.expression
|
||||
if (irField.initializer != null && irField.storageKind == FieldStorageKind.THREAD_LOCAL) {
|
||||
val initialization = evaluateExpression(irField.initializer!!.expression)
|
||||
val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress(
|
||||
@@ -713,15 +711,15 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
declaration.location(start = false)) {
|
||||
using(FunctionScope(declaration, it)) {
|
||||
val parameterScope = ParameterScope(declaration, functionGenerationContext)
|
||||
using(parameterScope) {
|
||||
using(VariableScope()) {
|
||||
using(parameterScope) usingParameterScope@{
|
||||
using(VariableScope()) usingVariableScope@{
|
||||
recordCoverage(body)
|
||||
if (declaration.isReifiedInline) {
|
||||
callDirect(context.ir.symbols.throwIllegalStateExceptionWithMessage.owner,
|
||||
listOf(context.llvm.staticData.kotlinStringLiteral(
|
||||
"unsupported call of reified inlined function `${declaration.fqNameForIrSerialization}`").llvm),
|
||||
Lifetime.IRRELEVANT)
|
||||
return@using
|
||||
return@usingVariableScope
|
||||
}
|
||||
when (body) {
|
||||
is IrBlockBody -> body.statements.forEach { generateStatement(it) }
|
||||
@@ -1669,7 +1667,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
var bbExit : LLVMBasicBlockRef? = null
|
||||
var resultPhi : LLVMValueRef? = null
|
||||
private val functionScope by lazy { returnableBlock.inlineFunctionSymbol?.owner?.scope() }
|
||||
private val outerScope = currentCodeContext.scope()
|
||||
|
||||
private fun getExit(): LLVMBasicBlockRef {
|
||||
val location = returnableBlock.inlineFunctionSymbol?.let {
|
||||
@@ -1709,7 +1706,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
override fun location(offset: Int): LocationInfo? {
|
||||
return if (returnableBlock.inlineFunctionSymbol != null) {
|
||||
val diScope = functionScope ?: return null
|
||||
val outerFileEntry = outerFileEntry()
|
||||
val inlinedAt = outerContext.location(returnableBlock.startOffset)
|
||||
?: error("no location for inlinedAt:\n" +
|
||||
"${returnableBlock.startOffset} ${returnableBlock.endOffset}\n" +
|
||||
@@ -1720,11 +1716,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
}
|
||||
}
|
||||
|
||||
private fun outerFileEntry() =
|
||||
(outerContext.fileScope() as? FileScope)?.file?.fileEntry
|
||||
?: error("returnable block should be inlined at some file")
|
||||
|
||||
|
||||
/**
|
||||
* Note: DILexicalBlocks aren't nested, they should be scoped with the parent function.
|
||||
*/
|
||||
@@ -1932,10 +1923,10 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
context.debugInfo.subprograms.getOrPut(functionLlvmValue) {
|
||||
memScoped {
|
||||
val subroutineType = subroutineType(context, codegen.llvmTargetData)
|
||||
val functionLlvmValue = codegen.llvmFunction(this@scope)
|
||||
diFunctionScope(name.asString(), functionLlvmValue.name!!, startLine, subroutineType).also {
|
||||
val llvmFunnction = codegen.llvmFunction(this@scope)
|
||||
diFunctionScope(name.asString(), llvmFunnction.name!!, startLine, subroutineType).also {
|
||||
if (!this@scope.isInline)
|
||||
DIFunctionAddSubprogram(functionLlvmValue, it)
|
||||
DIFunctionAddSubprogram(llvmFunnction, it)
|
||||
}
|
||||
}
|
||||
} as DIScopeOpaqueRef
|
||||
@@ -2301,21 +2292,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
private fun call(symbol: DataFlowIR.FunctionSymbol, function: LLVMValueRef, args: List<LLVMValueRef>,
|
||||
resultLifetime: Lifetime): LLVMValueRef {
|
||||
val result = call(function, args, resultLifetime)
|
||||
if (symbol.returnsNothing) {
|
||||
functionGenerationContext.unreachable()
|
||||
}
|
||||
|
||||
if (LLVMGetReturnType(getFunctionType(function)) == voidType) {
|
||||
return codegen.theUnitInstanceRef.llvm
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
private fun call(function: LLVMValueRef, args: List<LLVMValueRef>,
|
||||
resultLifetime: Lifetime = Lifetime.IRRELEVANT,
|
||||
exceptionHandler: ExceptionHandler = currentCodeContext.exceptionHandler): LLVMValueRef {
|
||||
@@ -2513,8 +2489,6 @@ private fun Name.debugNameConversion(): Name = when(this) {
|
||||
else -> this
|
||||
}
|
||||
|
||||
class NoContextFound : Throwable()
|
||||
|
||||
internal class LocationInfo(val scope: DIScopeOpaqueRef,
|
||||
val line: Int,
|
||||
val column: Int,
|
||||
|
||||
+2
-2
@@ -87,8 +87,8 @@ class FunctionRegions(
|
||||
val structuralHash: Long = 0
|
||||
|
||||
override fun toString(): String = buildString {
|
||||
appendln("${function.symbolName} regions:")
|
||||
regions.forEach { (irElem, region) -> appendln("${ir2string(irElem)} -> ($region)") }
|
||||
appendLine("${function.symbolName} regions:")
|
||||
regions.forEach { (irElem, region) -> appendLine("${ir2string(irElem)} -> ($region)") }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -622,7 +622,7 @@ private fun ObjCExportBlockCodeGenerator.emitBlockToKotlinFunctionConverters() {
|
||||
val functionClassesByArity =
|
||||
context.ir.symbols.functionIrClassFactory.builtFunctionNClasses.associateBy { it.arity }
|
||||
|
||||
var count = ((functionClassesByArity.keys.max() ?: -1) + 1)
|
||||
var count = ((functionClassesByArity.keys.maxOrNull() ?: -1) + 1)
|
||||
// TODO: ugly hack to avoid huge unneeded adaptors linked into every binary, needs rework.
|
||||
if (context.config.produce.isCache) {
|
||||
count = count.coerceAtMost(maxConvertorsInCache)
|
||||
|
||||
+2
-2
@@ -279,8 +279,8 @@ internal class CallableReferenceLowering(val context: Context): FileLoweringPass
|
||||
isKSuspendFunction -> kSuspendFunctionImplConstructorSymbol.owner
|
||||
else -> irBuiltIns.anyClass.owner.constructors.single()
|
||||
}
|
||||
+irDelegatingConstructorCall(superConstructor).apply {
|
||||
if (!isKFunction && !isKSuspendFunction) return@apply
|
||||
+irDelegatingConstructorCall(superConstructor).apply applyIrDelegationConstructorCall@ {
|
||||
if (!isKFunction && !isKSuspendFunction) return@applyIrDelegationConstructorCall
|
||||
// TODO: Remove as soon as IR declarations have their originalDescriptor.
|
||||
val name = (referencedFunction.descriptor as? WrappedSimpleFunctionDescriptor)?.originalDescriptor?.name
|
||||
?: referencedFunction.name
|
||||
|
||||
+1
@@ -253,6 +253,7 @@ internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
|
||||
createValuesPropertyInitializer(enumEntries)
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
return IrPropertyImpl(startOffset, endOffset, DECLARATION_ORIGIN_ENUM,
|
||||
false, loweredEnum.valuesField.descriptor, irField, getter, null).apply {
|
||||
parent = implObject
|
||||
|
||||
+7
-7
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
|
||||
/**
|
||||
* Check given function is a getter or setter
|
||||
@@ -230,8 +231,7 @@ private fun InteropCallContext.writePointerToMemory(
|
||||
|
||||
private fun InteropCallContext.writeObjCReferenceToMemory(
|
||||
nativePtr: IrExpression,
|
||||
value: IrExpression,
|
||||
pointerType: IrType
|
||||
value: IrExpression
|
||||
): IrExpression {
|
||||
val valueToWrite = builder.irCall(symbols.interopObjCObjectRawValueGetter).also {
|
||||
it.extensionReceiver = value
|
||||
@@ -316,7 +316,7 @@ private fun InteropCallContext.generateEnumVarValueAccess(callSite: IrCall): IrE
|
||||
private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpression {
|
||||
val accessor = callSite.symbol.owner
|
||||
val memberAt = accessor.getAnnotation(RuntimeNames.cStructMemberAt)!!
|
||||
val offset = (memberAt.getValueArgument(0) as IrConst<Long>).value
|
||||
val offset = memberAt.getValueArgument(0).cast<IrConst<Long>>().value
|
||||
val fieldPointer = calculateFieldPointer(callSite.dispatchReceiver!!, offset)
|
||||
return when {
|
||||
accessor.isGetter -> {
|
||||
@@ -337,7 +337,7 @@ private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpre
|
||||
type.isCEnumType() -> writeEnumValueToMemory(fieldPointer, value, type)
|
||||
type.isStoredInMemoryDirectly() -> writeValueToMemory(fieldPointer, value, type)
|
||||
type.isCPointer() -> writePointerToMemory(fieldPointer, value, type)
|
||||
type.isSupportedReference() -> writeObjCReferenceToMemory(fieldPointer, value, type)
|
||||
type.isSupportedReference() -> writeObjCReferenceToMemory(fieldPointer, value)
|
||||
else -> failCompilation("Unsupported struct field type: ${type.getClass()?.name}")
|
||||
}
|
||||
}
|
||||
@@ -348,7 +348,7 @@ private fun InteropCallContext.generateMemberAtAccess(callSite: IrCall): IrExpre
|
||||
private fun InteropCallContext.generateArrayMemberAtAccess(callSite: IrCall): IrExpression {
|
||||
val accessor = callSite.symbol.owner
|
||||
val memberAt = accessor.getAnnotation(RuntimeNames.cStructArrayMemberAt)!!
|
||||
val offset = (memberAt.getValueArgument(0) as IrConst<Long>).value
|
||||
val offset = memberAt.getValueArgument(0).cast<IrConst<Long>>().value
|
||||
val fieldPointer = calculateFieldPointer(callSite.dispatchReceiver!!, offset)
|
||||
return builder.irCall(symbols.interopInterpretCPointer).also {
|
||||
it.putValueArgument(0, fieldPointer)
|
||||
@@ -407,8 +407,8 @@ private fun InteropCallContext.readBits(
|
||||
private fun InteropCallContext.generateBitFieldAccess(callSite: IrCall): IrExpression {
|
||||
val accessor = callSite.symbol.owner
|
||||
val bitField = accessor.getAnnotation(RuntimeNames.cStructBitField)!!
|
||||
val offset = (bitField.getValueArgument(0) as IrConst<Long>).value
|
||||
val size = (bitField.getValueArgument(1) as IrConst<Int>).value
|
||||
val offset = bitField.getValueArgument(0).cast<IrConst<Long>>().value
|
||||
val size = bitField.getValueArgument(1).cast<IrConst<Int>>().value
|
||||
val base = builder.irCall(symbols.interopNativePointedRawPtrGetter).also {
|
||||
it.dispatchReceiver = callSite.dispatchReceiver!!
|
||||
}
|
||||
|
||||
+1
-1
@@ -313,6 +313,6 @@ internal class ObjCExport(val context: Context, symbolTable: SymbolTable) {
|
||||
return allPackages.map { it.fqName }.distinct()
|
||||
.filter { candidate -> nonEmptyPackages.all { it.isSubpackageOf(candidate) } }
|
||||
// Now there are all common ancestors of non-empty packages. Longest of them is the least common accessor:
|
||||
.maxBy { it.asString().length }!!
|
||||
.maxByOrNull { it.asString().length }!!
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -201,7 +201,7 @@ internal class ObjCExportTranslatorImpl(
|
||||
|
||||
return translateClassOrInterfaceName(descriptor).also {
|
||||
val objcName = forwardDeclarationObjcClassName(objcGenerics, descriptor, namer)
|
||||
generator?.referenceClass(objcName, descriptor)
|
||||
generator?.referenceClass(objcName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,7 +211,7 @@ internal class ObjCExportTranslatorImpl(
|
||||
generator?.requireClassOrInterface(descriptor)
|
||||
|
||||
return translateClassOrInterfaceName(descriptor).also {
|
||||
generator?.referenceProtocol(it.objCName, descriptor)
|
||||
generator?.referenceProtocol(it.objCName)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1137,11 +1137,11 @@ abstract class ObjCExportHeaderGenerator internal constructor(
|
||||
}
|
||||
}
|
||||
|
||||
internal fun referenceClass(objCName: String, descriptor: ClassDescriptor? = null) {
|
||||
internal fun referenceClass(objCName: String) {
|
||||
classForwardDeclarations += objCName
|
||||
}
|
||||
|
||||
internal fun referenceProtocol(objCName: String, descriptor: ClassDescriptor? = null) {
|
||||
internal fun referenceProtocol(objCName: String) {
|
||||
protocolForwardDeclarations += objCName
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -97,7 +97,7 @@ private fun ObjCExportMapper.isHiddenByDeprecation(descriptor: CallableMemberDes
|
||||
}
|
||||
|
||||
internal fun ObjCExportMapper.getDeprecation(descriptor: DeclarationDescriptor): Deprecation? {
|
||||
deprecationResolver?.getDeprecations(descriptor).orEmpty().maxBy {
|
||||
deprecationResolver?.getDeprecations(descriptor).orEmpty().maxByOrNull {
|
||||
when (it.deprecationLevel) {
|
||||
DeprecationLevelValue.WARNING -> 1
|
||||
DeprecationLevelValue.ERROR -> 2
|
||||
|
||||
+1
-1
@@ -229,7 +229,7 @@ internal class CallGraphBuilder(val context: Context,
|
||||
}
|
||||
val body = function.body
|
||||
body.forEachCallSite { call ->
|
||||
val devirtualizedCallSite = (call as? DataFlowIR.Node.VirtualCall)?.let { devirtualizedCallSites?.get(it) }
|
||||
val devirtualizedCallSite = (call as? DataFlowIR.Node.VirtualCall)?.let { devirtualizedCallSites.get(it) }
|
||||
if (devirtualizedCallSite == null) {
|
||||
val callee = call.callee.resolved()
|
||||
if (moduleDFG.functions.containsKey(callee))
|
||||
|
||||
+1
-3
@@ -133,8 +133,7 @@ private class ExpressionValuesExtractor(val context: Context,
|
||||
else { // Propagate cast to sub-values.
|
||||
forEachValue(expression.argument) { value ->
|
||||
with(expression) {
|
||||
block(IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, typeOperand,
|
||||
typeOperand.classifierOrFail, value))
|
||||
block(IrTypeOperatorCallImpl(startOffset, endOffset, type, operator, typeOperand, value))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,7 +403,6 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag
|
||||
.filterIsInstance<IrSimpleFunction>().single { it.name.asString() == "invokeSuspend" }.symbol
|
||||
|
||||
private val getContinuationSymbol = symbols.getContinuation
|
||||
private val continuationType = getContinuationSymbol.owner.returnType
|
||||
|
||||
private val arrayGetSymbols = symbols.arrayGet.values
|
||||
private val arraySetSymbols = symbols.arraySet.values
|
||||
|
||||
+110
-115
@@ -5,17 +5,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan.optimizations
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ir.ir2stringWhole
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isBuiltInOperator
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.target
|
||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.allParameters
|
||||
import org.jetbrains.kotlin.backend.konan.ir.isOverridableOrOverrides
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.functionName
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.isExported
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.localHash
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.symbolName
|
||||
import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD
|
||||
import org.jetbrains.kotlin.backend.konan.lower.bridgeTarget
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -29,7 +32,6 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isBuiltInOperator
|
||||
|
||||
internal object DataFlowIR {
|
||||
|
||||
@@ -305,137 +307,137 @@ internal object DataFlowIR {
|
||||
" FUNCTION REFERENCE ${node.symbol}\n"
|
||||
|
||||
is Node.StaticCall -> {
|
||||
val result = StringBuilder()
|
||||
result.appendln(" STATIC CALL ${node.callee}. Return type = ${node.returnType}")
|
||||
node.arguments.forEach {
|
||||
result.append(" ARG #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${it.castToType}")
|
||||
buildString {
|
||||
appendLine(" STATIC CALL ${node.callee}. Return type = ${node.returnType}")
|
||||
node.arguments.forEach {
|
||||
append(" ARG #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${it.castToType}")
|
||||
}
|
||||
}
|
||||
result.toString()
|
||||
}
|
||||
|
||||
is Node.VtableCall -> {
|
||||
val result = StringBuilder()
|
||||
result.appendln(" VIRTUAL CALL ${node.callee}. Return type = ${node.returnType}")
|
||||
result.appendln(" RECEIVER: ${node.receiverType}")
|
||||
result.appendln(" VTABLE INDEX: ${node.calleeVtableIndex}")
|
||||
node.arguments.forEach {
|
||||
result.append(" ARG #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${it.castToType}")
|
||||
buildString {
|
||||
appendLine(" VIRTUAL CALL ${node.callee}. Return type = ${node.returnType}")
|
||||
appendLine(" RECEIVER: ${node.receiverType}")
|
||||
appendLine(" VTABLE INDEX: ${node.calleeVtableIndex}")
|
||||
node.arguments.forEach {
|
||||
append(" ARG #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${it.castToType}")
|
||||
}
|
||||
}
|
||||
result.toString()
|
||||
}
|
||||
|
||||
is Node.ItableCall -> {
|
||||
val result = StringBuilder()
|
||||
result.appendln(" INTERFACE CALL ${node.callee}. Return type = ${node.returnType}")
|
||||
result.appendln(" RECEIVER: ${node.receiverType}")
|
||||
result.appendln(" METHOD HASH: ${node.calleeHash}")
|
||||
node.arguments.forEach {
|
||||
result.append(" ARG #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${it.castToType}")
|
||||
buildString {
|
||||
appendLine(" INTERFACE CALL ${node.callee}. Return type = ${node.returnType}")
|
||||
appendLine(" RECEIVER: ${node.receiverType}")
|
||||
appendLine(" METHOD HASH: ${node.calleeHash}")
|
||||
node.arguments.forEach {
|
||||
append(" ARG #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${it.castToType}")
|
||||
}
|
||||
}
|
||||
result.toString()
|
||||
}
|
||||
|
||||
is Node.NewObject -> {
|
||||
val result = StringBuilder()
|
||||
result.appendln(" NEW OBJECT ${node.callee}")
|
||||
result.appendln(" CONSTRUCTED TYPE ${node.constructedType}")
|
||||
node.arguments.forEach {
|
||||
result.append(" ARG #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${it.castToType}")
|
||||
buildString {
|
||||
appendLine(" NEW OBJECT ${node.callee}")
|
||||
appendLine(" CONSTRUCTED TYPE ${node.constructedType}")
|
||||
node.arguments.forEach {
|
||||
append(" ARG #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${it.castToType}")
|
||||
}
|
||||
}
|
||||
result.toString()
|
||||
}
|
||||
|
||||
is Node.FieldRead -> {
|
||||
val result = StringBuilder()
|
||||
result.appendln(" FIELD READ ${node.field}")
|
||||
result.append(" RECEIVER #${node.receiver?.node?.let { ids[it]!! } ?: "null"}")
|
||||
if (node.receiver?.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${node.receiver.castToType}")
|
||||
result.toString()
|
||||
buildString {
|
||||
appendLine(" FIELD READ ${node.field}")
|
||||
append(" RECEIVER #${node.receiver?.node?.let { ids[it]!! } ?: "null"}")
|
||||
if (node.receiver?.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${node.receiver.castToType}")
|
||||
}
|
||||
}
|
||||
|
||||
is Node.FieldWrite -> {
|
||||
val result = StringBuilder()
|
||||
result.appendln(" FIELD WRITE ${node.field}")
|
||||
result.append(" RECEIVER #${node.receiver?.node?.let { ids[it]!! } ?: "null"}")
|
||||
if (node.receiver?.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${node.receiver.castToType}")
|
||||
print(" VALUE #${ids[node.value.node]!!}")
|
||||
if (node.value.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${node.value.castToType}")
|
||||
result.toString()
|
||||
buildString {
|
||||
appendLine(" FIELD WRITE ${node.field}")
|
||||
append(" RECEIVER #${node.receiver?.node?.let { ids[it]!! } ?: "null"}")
|
||||
if (node.receiver?.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${node.receiver.castToType}")
|
||||
print(" VALUE #${ids[node.value.node]!!}")
|
||||
if (node.value.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${node.value.castToType}")
|
||||
}
|
||||
}
|
||||
|
||||
is Node.ArrayRead -> {
|
||||
val result = StringBuilder()
|
||||
result.appendln(" ARRAY READ")
|
||||
result.append(" ARRAY #${ids[node.array.node]}")
|
||||
if (node.array.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${node.array.castToType}")
|
||||
result.append(" INDEX #${ids[node.index.node]!!}")
|
||||
if (node.index.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${node.index.castToType}")
|
||||
result.toString()
|
||||
buildString {
|
||||
appendLine(" ARRAY READ")
|
||||
append(" ARRAY #${ids[node.array.node]}")
|
||||
if (node.array.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${node.array.castToType}")
|
||||
append(" INDEX #${ids[node.index.node]!!}")
|
||||
if (node.index.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${node.index.castToType}")
|
||||
}
|
||||
}
|
||||
|
||||
is Node.ArrayWrite -> {
|
||||
val result = StringBuilder()
|
||||
result.appendln(" ARRAY WRITE")
|
||||
result.append(" ARRAY #${ids[node.array.node]}")
|
||||
if (node.array.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${node.array.castToType}")
|
||||
result.append(" INDEX #${ids[node.index.node]!!}")
|
||||
if (node.index.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${node.index.castToType}")
|
||||
print(" VALUE #${ids[node.value.node]!!}")
|
||||
if (node.value.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${node.value.castToType}")
|
||||
result.toString()
|
||||
buildString {
|
||||
appendLine(" ARRAY WRITE")
|
||||
append(" ARRAY #${ids[node.array.node]}")
|
||||
if (node.array.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${node.array.castToType}")
|
||||
append(" INDEX #${ids[node.index.node]!!}")
|
||||
if (node.index.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${node.index.castToType}")
|
||||
print(" VALUE #${ids[node.value.node]!!}")
|
||||
if (node.value.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${node.value.castToType}")
|
||||
}
|
||||
}
|
||||
|
||||
is Node.Variable -> {
|
||||
val result = StringBuilder()
|
||||
result.appendln(" ${node.kind}")
|
||||
node.values.forEach {
|
||||
result.append(" VAL #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
result.appendln()
|
||||
else
|
||||
result.appendln(" CASTED TO ${it.castToType}")
|
||||
buildString {
|
||||
appendLine(" ${node.kind}")
|
||||
node.values.forEach {
|
||||
append(" VAL #${ids[it.node]!!}")
|
||||
if (it.castToType == null)
|
||||
appendLine()
|
||||
else
|
||||
appendLine(" CASTED TO ${it.castToType}")
|
||||
}
|
||||
}
|
||||
result.toString()
|
||||
}
|
||||
|
||||
else -> {
|
||||
@@ -463,13 +465,6 @@ internal object DataFlowIR {
|
||||
private val FQ_NAME_POINTS_TO = FQ_NAME_KONAN.child(NAME_POINTS_TO)
|
||||
|
||||
private val konanPackage = context.builtIns.builtInsModule.getPackage(FQ_NAME_KONAN).memberScope
|
||||
private val escapesAnnotationDescriptor = konanPackage.getContributedClassifier(
|
||||
NAME_ESCAPES, NoLookupLocation.FROM_BACKEND) as org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
private val escapesWhoDescriptor = escapesAnnotationDescriptor.unsubstitutedPrimaryConstructor!!.valueParameters.single()
|
||||
private val pointsToAnnotationDescriptor = konanPackage.getContributedClassifier(
|
||||
NAME_POINTS_TO, NoLookupLocation.FROM_BACKEND) as org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
private val pointsToOnWhomDescriptor = pointsToAnnotationDescriptor.unsubstitutedPrimaryConstructor!!.valueParameters.single()
|
||||
|
||||
private val getContinuationSymbol = context.ir.symbols.getContinuation
|
||||
private val continuationType = getContinuationSymbol.owner.returnType
|
||||
|
||||
@@ -613,7 +608,7 @@ internal object DataFlowIR {
|
||||
val pointsToBitMask = (pointsToAnnotation?.getValueArgument(0) as? IrVararg)?.elements?.map { (it as IrConst<Int>).value }
|
||||
FunctionSymbol.External(name.localHash.value, attributes, it, takeName { name }, it.isExported()).apply {
|
||||
escapes = escapesBitMask
|
||||
pointsTo = pointsToBitMask?.let { it.toIntArray() }
|
||||
pointsTo = pointsToBitMask?.toIntArray()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-21
@@ -132,24 +132,6 @@ internal object Devirtualization {
|
||||
|
||||
private val symbolTable = moduleDFG.symbolTable
|
||||
|
||||
// TODO: Make custom hashtable.
|
||||
class IntHashSet : Iterable<Int> {
|
||||
private val hashSet = HashSet<Int>()
|
||||
val size get() = hashSet.size
|
||||
fun isEmpty() = size == 0
|
||||
fun add(x: Int) = hashSet.add(x)
|
||||
|
||||
override operator fun iterator(): Iterator<Int> = Itr()
|
||||
|
||||
private inner class Itr : Iterator<Int> {
|
||||
private val itr = hashSet.iterator()
|
||||
override fun hasNext() = itr.hasNext()
|
||||
|
||||
override fun next() = itr.next()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
sealed class Node(val id: Int) {
|
||||
var directCastEdges: MutableList<CastEdge>? = null
|
||||
var reversedCastEdges: MutableList<CastEdge>? = null
|
||||
@@ -818,8 +800,8 @@ internal object Devirtualization {
|
||||
return true
|
||||
}
|
||||
|
||||
private fun makePrime(x: Int): Int {
|
||||
var x = x
|
||||
private fun makePrime(p: Int): Int {
|
||||
var x = p
|
||||
while (true) {
|
||||
if (isPrime(x)) return x
|
||||
++x
|
||||
@@ -832,6 +814,7 @@ internal object Devirtualization {
|
||||
val directEdgesCount = IntArrayList()
|
||||
val reversedEdgesCount = IntArrayList()
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
private fun addEdge(from: Node, to: Node) {
|
||||
val fromId = from.id
|
||||
val toId = to.id
|
||||
@@ -1600,7 +1583,7 @@ internal object Devirtualization {
|
||||
expression
|
||||
else with (cast) {
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, operator,
|
||||
typeOperand, typeOperandClassifier, expression)
|
||||
typeOperand, expression)
|
||||
}
|
||||
with (coercion) {
|
||||
return IrCallImpl(startOffset, endOffset, type, symbol, typeArgumentsCount, origin).apply {
|
||||
|
||||
@@ -61,7 +61,7 @@ kotlin {
|
||||
|
||||
jvm().compilations.all {
|
||||
kotlinOptions {
|
||||
freeCompilerArgs = ["-Xopt-in=kotlinx.cli.ExperimentalCli"]
|
||||
freeCompilerArgs = ["-Xopt-in=kotlinx.cli.ExperimentalCli", "-Xopt-in=kotlin.RequiresOptIn"]
|
||||
suppressWarnings = true
|
||||
}
|
||||
}
|
||||
@@ -100,7 +100,7 @@ targetList.each { target ->
|
||||
'-produce', 'library', '-module-name', moduleName, '-XXLanguage:+AllowContractsForCustomFunctions',
|
||||
'-Xmulti-platform', '-Xopt-in=kotlinx.cli.ExperimentalCli',
|
||||
'-Xopt-in=kotlin.ExperimentalMultiplatform',
|
||||
'-Xallow-result-return-type',
|
||||
'-Xallow-result-return-type', '-Werror', '-Xopt-in=kotlin.RequiresOptIn',
|
||||
commonSrc.absolutePath,
|
||||
"-Xcommon-sources=${commonSrc.absolutePath}",
|
||||
nativeSrc]
|
||||
|
||||
@@ -471,18 +471,18 @@ open class ArgParser(
|
||||
// Form with several short forms as one string.
|
||||
val otherBooleanOptions = option.substring(1)
|
||||
saveOptionWithoutParameter(firstOption)
|
||||
for (option in otherBooleanOptions) {
|
||||
shortNames["$option"]?.let {
|
||||
for (opt in otherBooleanOptions) {
|
||||
shortNames["$opt"]?.let {
|
||||
if (it.descriptor.type.hasParameter) {
|
||||
printError(
|
||||
"Option $optionShortFromPrefix$option can't be used in option combination $candidate, " +
|
||||
"Option $optionShortFromPrefix$opt can't be used in option combination $candidate, " +
|
||||
"because parameter value of type ${it.descriptor.type.description} should be " +
|
||||
"provided for current option."
|
||||
)
|
||||
}
|
||||
}?: printError("Unknown option $optionShortFromPrefix$option in option combination $candidate.")
|
||||
}?: printError("Unknown option $optionShortFromPrefix$opt in option combination $candidate.")
|
||||
|
||||
saveOptionWithoutParameter(shortNames["$option"]!!)
|
||||
saveOptionWithoutParameter(shortNames["$opt"]!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ class MultipleArgument<T : Any, DefaultRequired: DefaultRequiredType> internal c
|
||||
fun <T : Any, TResult, DefaultRequired: DefaultRequiredType>
|
||||
AbstractSingleArgument<T, TResult, DefaultRequired>.multiple(number: Int): MultipleArgument<T, DefaultRequired> {
|
||||
require(number >= 2) { "multiple() modifier with value less than 2 is unavailable. It's already set to 1." }
|
||||
val newArgument = with((delegate as ParsingValue<T, T>).descriptor as ArgDescriptor) {
|
||||
val newArgument = with(delegate.cast<ParsingValue<T, T>>().descriptor as ArgDescriptor) {
|
||||
MultipleArgument<T, DefaultRequired>(ArgDescriptor(type, fullName, number, description, listOfNotNull(defaultValue),
|
||||
required, deprecatedWarning), owner)
|
||||
}
|
||||
@@ -172,7 +172,7 @@ fun <T : Any, TResult, DefaultRequired: DefaultRequiredType>
|
||||
*/
|
||||
fun <T : Any, TResult, DefaultRequired: DefaultRequiredType> AbstractSingleArgument<T, TResult, DefaultRequired>.vararg():
|
||||
MultipleArgument<T, DefaultRequired> {
|
||||
val newArgument = with((delegate as ParsingValue<T, T>).descriptor as ArgDescriptor) {
|
||||
val newArgument = with(delegate.cast<ParsingValue<T, T>>().descriptor as ArgDescriptor) {
|
||||
MultipleArgument<T, DefaultRequired>(ArgDescriptor(type, fullName, null, description, listOfNotNull(defaultValue),
|
||||
required, deprecatedWarning), owner)
|
||||
}
|
||||
@@ -189,7 +189,7 @@ fun <T : Any, TResult, DefaultRequired: DefaultRequiredType> AbstractSingleArgum
|
||||
* @param value the default value.
|
||||
*/
|
||||
fun <T: Any> SingleNullableArgument<T>.default(value: T): SingleArgument<T, DefaultRequiredType.Default> {
|
||||
val newArgument = with((delegate as ParsingValue<T, T>).descriptor as ArgDescriptor) {
|
||||
val newArgument = with(delegate.cast<ParsingValue<T, T>>().descriptor as ArgDescriptor) {
|
||||
SingleArgument<T, DefaultRequiredType.Default>(ArgDescriptor(type, fullName, number, description, value,
|
||||
false, deprecatedWarning), owner)
|
||||
}
|
||||
@@ -208,7 +208,7 @@ fun <T: Any> SingleNullableArgument<T>.default(value: T): SingleArgument<T, Defa
|
||||
fun <T: Any> MultipleArgument<T, DefaultRequiredType.None>.default(value: Collection<T>):
|
||||
MultipleArgument<T, DefaultRequiredType.Default> {
|
||||
require (value.isNotEmpty()) { "Default value for argument can't be empty collection." }
|
||||
val newArgument = with((delegate as ParsingValue<T, List<T>>).descriptor as ArgDescriptor) {
|
||||
val newArgument = with(delegate.cast<ParsingValue<T, List<T>>>().descriptor as ArgDescriptor) {
|
||||
MultipleArgument<T, DefaultRequiredType.Default>(ArgDescriptor(type, fullName, number, description, value.toList(),
|
||||
required, deprecatedWarning), owner)
|
||||
}
|
||||
@@ -224,7 +224,7 @@ fun <T: Any> MultipleArgument<T, DefaultRequiredType.None>.default(value: Collec
|
||||
* Note that only trailing arguments can be optional, i.e. no required arguments can follow optional ones.
|
||||
*/
|
||||
fun <T: Any> SingleArgument<T, DefaultRequiredType.Required>.optional(): SingleNullableArgument<T> {
|
||||
val newArgument = with((delegate as ParsingValue<T, T>).descriptor as ArgDescriptor) {
|
||||
val newArgument = with(delegate.cast<ParsingValue<T, T>>().descriptor as ArgDescriptor) {
|
||||
SingleNullableArgument(ArgDescriptor(type, fullName, number, description, defaultValue,
|
||||
false, deprecatedWarning), owner)
|
||||
}
|
||||
@@ -240,7 +240,7 @@ fun <T: Any> SingleArgument<T, DefaultRequiredType.Required>.optional(): SingleN
|
||||
* Note that only trailing arguments can be optional: no required arguments can follow the optional ones.
|
||||
*/
|
||||
fun <T: Any> MultipleArgument<T, DefaultRequiredType.Required>.optional(): MultipleArgument<T, DefaultRequiredType.None> {
|
||||
val newArgument = with((delegate as ParsingValue<T, List<T>>).descriptor as ArgDescriptor) {
|
||||
val newArgument = with(delegate.cast<ParsingValue<T, List<T>>>().descriptor as ArgDescriptor) {
|
||||
MultipleArgument<T, DefaultRequiredType.None>(ArgDescriptor(type, fullName, number, description,
|
||||
defaultValue?.toList() ?: listOf(), false, deprecatedWarning), owner)
|
||||
}
|
||||
@@ -248,4 +248,6 @@ fun <T: Any> MultipleArgument<T, DefaultRequiredType.Required>.optional(): Multi
|
||||
return newArgument
|
||||
}
|
||||
|
||||
internal fun failAssertion(message: String): Nothing = throw AssertionError(message)
|
||||
internal fun failAssertion(message: String): Nothing = throw AssertionError(message)
|
||||
|
||||
internal inline fun <reified T : Any> Any?.cast(): T = this as T
|
||||
@@ -17,7 +17,7 @@ import kotlin.annotation.AnnotationTarget.*
|
||||
* annotating that usage with the [UseExperimental] annotation, e.g. `@UseExperimental(ExperimentalCli::class)`,
|
||||
* or by using the compiler argument `-Xuse-experimental=kotlinx.cli.ExperimentalCli`.
|
||||
*/
|
||||
@RequiresOptIn("This API is experimental. It may be changed in the future without notice.", RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn("This API is experimental. It may be changed in the future without notice.", level = RequiresOptIn.Level.WARNING)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@Target(
|
||||
CLASS,
|
||||
|
||||
@@ -103,7 +103,7 @@ class MultipleOption<T : Any, OptionType : MultipleOptionType, DefaultType: Defa
|
||||
*/
|
||||
fun <T : Any, TResult, DefaultType: DefaultRequiredType> AbstractSingleOption<T, TResult, DefaultType>.multiple():
|
||||
MultipleOption<T, MultipleOptionType.Repeated, DefaultType> {
|
||||
val newOption = with((delegate as ParsingValue<T, T>).descriptor as OptionDescriptor) {
|
||||
val newOption = with(delegate.cast<ParsingValue<T, T>>().descriptor as OptionDescriptor) {
|
||||
MultipleOption<T, MultipleOptionType.Repeated, DefaultType>(
|
||||
OptionDescriptor(
|
||||
optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName,
|
||||
@@ -122,7 +122,7 @@ fun <T : Any, TResult, DefaultType: DefaultRequiredType> AbstractSingleOption<T,
|
||||
*/
|
||||
fun <T : Any, DefaultType: DefaultRequiredType> MultipleOption<T, MultipleOptionType.Delimited, DefaultType>.multiple():
|
||||
MultipleOption<T, MultipleOptionType.RepeatedDelimited, DefaultRequiredType> {
|
||||
val newOption = with((delegate as ParsingValue<T, List<T>>).descriptor as OptionDescriptor) {
|
||||
val newOption = with(delegate.cast<ParsingValue<T, List<T>>>().descriptor as OptionDescriptor) {
|
||||
if (multiple) {
|
||||
error("Try to use modifier multiple() twice on option ${fullName ?: ""}")
|
||||
}
|
||||
@@ -145,7 +145,7 @@ fun <T : Any, DefaultType: DefaultRequiredType> MultipleOption<T, MultipleOption
|
||||
* @param value the default value.
|
||||
*/
|
||||
fun <T : Any> SingleNullableOption<T>.default(value: T): SingleOption<T, DefaultRequiredType.Default> {
|
||||
val newOption = with((delegate as ParsingValue<T, T>).descriptor as OptionDescriptor) {
|
||||
val newOption = with(delegate.cast<ParsingValue<T, T>>().descriptor as OptionDescriptor) {
|
||||
SingleOption<T, DefaultRequiredType.Default>(
|
||||
OptionDescriptor(
|
||||
optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName,
|
||||
@@ -167,7 +167,7 @@ fun <T : Any> SingleNullableOption<T>.default(value: T): SingleOption<T, Default
|
||||
fun <T : Any, OptionType : MultipleOptionType>
|
||||
MultipleOption<T, OptionType, DefaultRequiredType.None>.default(value: Collection<T>):
|
||||
MultipleOption<T, OptionType, DefaultRequiredType.Default> {
|
||||
val newOption = with((delegate as ParsingValue<T, List<T>>).descriptor as OptionDescriptor) {
|
||||
val newOption = with(delegate.cast<ParsingValue<T, List<T>>>().descriptor as OptionDescriptor) {
|
||||
require(value.isNotEmpty()) { "Default value for option can't be empty collection." }
|
||||
MultipleOption<T, OptionType, DefaultRequiredType.Default>(
|
||||
OptionDescriptor(
|
||||
@@ -185,7 +185,7 @@ fun <T : Any, OptionType : MultipleOptionType>
|
||||
* Requires the option to be always provided in command line.
|
||||
*/
|
||||
fun <T : Any> SingleNullableOption<T>.required(): SingleOption<T, DefaultRequiredType.Required> {
|
||||
val newOption = with((delegate as ParsingValue<T, T>).descriptor as OptionDescriptor) {
|
||||
val newOption = with(delegate.cast<ParsingValue<T, T>>().descriptor as OptionDescriptor) {
|
||||
SingleOption<T, DefaultRequiredType.Required>(
|
||||
OptionDescriptor(
|
||||
optionFullFormPrefix, optionShortFromPrefix, type, fullName,
|
||||
@@ -204,7 +204,7 @@ fun <T : Any> SingleNullableOption<T>.required(): SingleOption<T, DefaultRequire
|
||||
fun <T : Any, OptionType : MultipleOptionType>
|
||||
MultipleOption<T, OptionType, DefaultRequiredType.None>.required():
|
||||
MultipleOption<T, OptionType, DefaultRequiredType.Required> {
|
||||
val newOption = with((delegate as ParsingValue<T, List<T>>).descriptor as OptionDescriptor) {
|
||||
val newOption = with(delegate.cast<ParsingValue<T, List<T>>>().descriptor as OptionDescriptor) {
|
||||
MultipleOption<T, OptionType, DefaultRequiredType.Required>(
|
||||
OptionDescriptor(
|
||||
optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName,
|
||||
@@ -228,7 +228,7 @@ fun <T : Any, OptionType : MultipleOptionType>
|
||||
fun <T : Any, DefaultRequired: DefaultRequiredType> AbstractSingleOption<T, *, DefaultRequired>.delimiter(
|
||||
delimiterValue: String):
|
||||
MultipleOption<T, MultipleOptionType.Delimited, DefaultRequired> {
|
||||
val newOption = with((delegate as ParsingValue<T, T>).descriptor as OptionDescriptor) {
|
||||
val newOption = with(delegate.cast<ParsingValue<T, T>>().descriptor as OptionDescriptor) {
|
||||
MultipleOption<T, MultipleOptionType.Delimited, DefaultRequired>(
|
||||
OptionDescriptor(
|
||||
optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName,
|
||||
@@ -252,7 +252,7 @@ fun <T : Any, DefaultRequired: DefaultRequiredType> AbstractSingleOption<T, *, D
|
||||
fun <T : Any, DefaultRequired: DefaultRequiredType> MultipleOption<T, MultipleOptionType.Repeated, DefaultRequired>.delimiter(
|
||||
delimiterValue: String):
|
||||
MultipleOption<T, MultipleOptionType.RepeatedDelimited, DefaultRequired> {
|
||||
val newOption = with((delegate as ParsingValue<T, List<T>>).descriptor as OptionDescriptor) {
|
||||
val newOption = with(delegate.cast<ParsingValue<T, List<T>>>().descriptor as OptionDescriptor) {
|
||||
MultipleOption<T, MultipleOptionType.RepeatedDelimited, DefaultRequired>(
|
||||
OptionDescriptor(
|
||||
optionFullFormPrefix, optionShortFromPrefix, type, fullName, shortName,
|
||||
|
||||
Reference in New Issue
Block a user