mcpiroman
05/25/2022, 8:41 AMinternal
symbols from other modules using `@Suppress("INVISIBLE_MEMBER")`or "INVISIBLE_REFERENCE"
. However that does not work for internal setter on a property. How can I suppress Cannot assign to ...: the setter is internal in ...
?Didier Villevalois
05/28/2022, 10:34 AMIrGenerationExtension
but at the level of the FIR (i.e. after semantic resolution but before the lowerings). I know that FIR is still in active development but maybe there are already something that I can use.
Thanks a lot to you all for any help you can provide me.Jack Darlington
05/29/2022, 6:00 PMmbonnin
05/30/2022, 12:26 PMclass Foo {
object bar {}
companion object {
val bar = "companion bar"
}
}
// I can read the companion bar
println(Foo.bar) // companion bar
// How do I access the object bar?
println(Foo.??)
Alexander Maryanovsky
05/31/2022, 9:34 AMAlexander Maryanovsky
06/01/2022, 5:33 PMval evenCount = listOf(1, 2, 3).sumOf { if (it % 2 == 0) 1 else 0 }
says sumOf
is ambiguous (can’t decide between a version that returns Int and one that returns Long), but this compiles fine:
val evenCount = listOf(1, 2, 3).sumOf { 0 + if (it % 2 == 0) 1 else 0 }
Youssef Shoaib [MOD]
06/04/2022, 11:57 AMjava.lang.IllegalArgumentException: No argument for parameter VALUE_PARAMETER name:_context_receiver_1 index:1
. The printed IR shows that the function I'm calling has a dispatch receiver, 2 context receivers, and a normal parameter, but the IR calls it just by providing the dispatch receiver and the parameter:
CALL 'public abstract fun display <T1, SubT1> (_context_receiver_0: <root>.Kind<T1 of <root>.Display.display, SubT1 of <root>.Display.display>, _context_receiver_1: <root>.Display<SubT1 of <root>.Display.display, SubT1 of <root>.Display.display>, t1: T1 of <root>.Display.display): kotlin.String declared in <root>.Display' type=kotlin.String origin=null
<T1>: SubT1 of <root>.ListDisplay.display$lambda-0
<SubT1>: SubT1 of <root>.ListDisplay.display$lambda-0
$this: GET_FIELD 'FIELD FIELD_FOR_CAPTURED_VALUE name:$_context_receiver_1 type:<root>.Display<SubT1 of <root>.ListDisplay.display$lambda-0, SubT1 of <root>.ListDisplay.display$lambda-0> visibility:public/*package*/ [final]' type=<root>.Display<SubT1 of <root>.ListDisplay.display$lambda-0, SubT1 of <root>.ListDisplay.display$lambda-0> origin=null
receiver: GET_VAR '<this>: <root>.ListDisplay.display$lambda-0.<no name provided> declared in <root>.ListDisplay.display$lambda-0.<no name provided>.invoke' type=<root>.ListDisplay.display$lambda-0.<no name provided> origin=null
_context_receiver_0: TYPE_OP type=SubT1 of <root>.ListDisplay.display$lambda-0 origin=CAST typeOperand=SubT1 of <root>.ListDisplay.display$lambda-0
GET_VAR 'it: kotlin.Any? declared in <root>.ListDisplay.display$lambda-0.<no name provided>.invoke' type=kotlin.Any? origin=null
Is this even worth reporting? Because it seems like FIR obviously doesn't support the basic functionality of context receivers. Is there anywhere I can see the progress of FIR at least? any specific youtrack issues I should be on the lookout for?alp
06/06/2022, 2:17 AM"org.jetbrains.kotlin:kotlin-compiler-embeddable:1.5.32"
, the project targets JVM only(android), and I create a simple gradle plugin to analyze some kotlin source files.
I create a KotlinCoreEnvironment
and pass there all the paths to analyze. I add them to the config like:
configuration.addKotlinSourceRoots(kotlinFiles)
configuration.addJvmClasspathRoots(classpath)
Then I create the binding context like:
analyzer.analyzeAndReport(files) {
TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
environment.project,
files,
NoScopeRecordCliBindingTrace(),
environment.configuration,
environment::createPackagePartProvider,
::FileBasedDeclarationProviderFactory
)
}
return analyzer.analysisResult.bindingContext // I use this bindingContext
I have the binding context and start analyzing the file. The goal is to get some types and classes for methods from the expressions like:
Foo()
.bar() // returns Bar object
.baz() // returns Baz object
where Foo
, Bar
and Baz
are 3 different classes in different kt files.I want to understand all the types by parsing such piece of code but not able to. I searched this channel for BindingContext
, BindingTrace
and other keywords but nothing worked for me. I tried calling getResolvedCall
and getCall
on above expressions, everything returns null, same for trying to get Type
or anything that I think may help me to resolve the target file that contains the functions from the code snippet above. Also, played with BindingUtils
with no luck.
I’m just learning how compiler works but the information is relatively limited so I mostly use some existing projects to understand the internals. Please let me know how if what I’m indenting to do is achievable.
Thanks in advanceQuantum64
06/06/2022, 9:30 PMOliver.O
06/07/2022, 6:24 PMcompileCommonMainKotlinMetadata
?
Second question in 🧵.zsqw123
06/08/2022, 8:40 AMPsiElementFinder
to make the elements in it correctly recognized by the IDE, but I encountered the error Kotlin light classes should not be found by JavaPsiFacade
, I would like to know what is the replacement for the PsiElementFinder
extension point of the java idea plugin in kotlin?alaershov
06/09/2022, 7:00 AMYoussef Shoaib [MOD]
06/09/2022, 9:45 PMBindingContext
, using context receivers and based on the utility functions that are peppered around kotlin-compiler-embeddable
. Hopefully, this will find some use, at least before FIR takes overYoussef Shoaib [MOD]
06/10/2022, 3:00 PMserver
06/11/2022, 6:55 AMBig Chungus
06/12/2022, 11:13 AMsam
06/21/2022, 9:22 AM-entry
I can see the function looks ok using dump, but I get an error saying it cannot be found. If I create the function manually, then it looks identical to my generated output. Is there something special that needs to be done for the native task to pick up the entry point ?Tyler Rockwood
06/21/2022, 7:18 PM-Xreport-perf
flag to the compiler run.
info: PERF: <redacted_module_name>, 1 files (23 lines)
info: PERF: INIT: Compiler initialized in 1758 ms
info: PERF: ANALYZE 4307 ms 5.340 loc/s
info: PERF: IR TRANSLATION 289 ms 79.585 loc/s
info: PERF: IR LOWERING 494 ms 46.559 loc/s
info: PERF: IR GENERATION 348 ms 66.092 loc/s
info: PERF: GENERATE 842 ms 27.316 loc/s
info: PERF: GC time for G1 Young Generation is 47 ms, 2 collections
info: PERF: GC time for G1 Old Generation is 0 ms, 0 collections
info: PERF: JIT time is 22892 ms
info: PERF: Find Java class performed 11 times, total time 234 ms
info: PERF: Type info performed 39 times, total time 2214 ms
info: PERF: Call resolve performed 38 times, total time 2116 ms
info: PERF: Binary class from Kotlin file performed 210 times, total time 226 ms
We've tried to turn on -Xbackend-threads
but that fails due to https://youtrack.jetbrains.com/issue/KT-52824. In general we don't have any compiler plugin ourselves, although Bazel uses jvm-abi-gen
for better compilation avoidance. Are we just hopeless until K2? I've ran across issues like https://youtrack.jetbrains.com/issue/KT-38101 that performance issues (at least in the analyze phase) are being fixed in K2 (which we can't try in alpha yet because of the missing support for plugins). In the release notes for Kotlin 1.7 there was a section that posted performance numbers and there are current packages getting 1-2K loc/s with the current compiler. Even our largest modules (assuming there is some constant overhead that is making the above example so bad) maxes out at about 100 loc/s (5.8k lines in 5 files taking around 57 seconds).
Are the Bazel kotlin rules invoking the compiler incorrectly to lead to such bad performance? I'm happy to talk though the threading model and how the Bazel rules invoke the compiler with someone if that turns out to be the issue.turansky
06/22/2022, 12:54 AMis
and as
expressions?
Is there DeclarationChecker
analog for such checks?David Bieregger
06/22/2022, 4:02 PMtry {
throw Error("Oh no!")
} catch {
console.log("Something bad happened, but don't know what")
}
This saves you to write the unneccessary term: (e: Exception)
or (_: Throwable)
2. Elvis operator for exceptions maybe with a excalmation mark !:
?
var result = methodThatMightThrowAnError() !: return null
If you like it or not it's a very common pattern in libraries to use exceptions as method result. Even though the exception doesn't tell you any thing important it's essential to caputure those exceptions to know that the method didn't succeed.
A realworld example would be:
inline fun <reified T> validateSignedToken(token: String) =
try {
Json.decodeFromString<T>(jwtVerifier.verify(token).getClaim("payload").asString())
} catch (e: Exception) {
null
}
It can be reduced to:
inline fun <reified T> validateSignedToken(token: String) =
Json.decodeFromString<T>(jwtVerifier.verify(token).getClaim("payload").asString()) !: null
And yes it a bit a code golf, but I think this is Kotlin a lot about. Making thinks things very short and concise. When you don't need the Exception why spend writing the type for every try catch block?
I can imagine it beeing used in a Unit Testing project as follows:
fun insertTokenTest() {
assertNoException {
val person = fetchToken() !: "12345678" //This might cause an exception, but when it is not available we just don't mind an use an default value
Database.insertToken(person)
}
}
fun assertNoException(block: () -> Unit) =
block() !: throw Error("No exception is expected")
I think I have seen this operator already somewhere, but don't know where. Does this already have a name? Otherwise does somebody know a famous person with such a hairdo? ;)Zac Sweers
06/22/2022, 4:04 PM(_: Throwable)
. And intentionally ignoring an exception seems like a code smell. Definitely think this would encourage far more problems than it solvesNick
06/22/2022, 7:16 PMturansky
06/23/2022, 9:48 PMvalue class Age(value: Int)
val age = Age(42)
println(age) // AUTOBOX DISABLING REQUIRED
In IrElementTransformer
I can receive age
as IrGetValue
. Which processing required after?Christian Maus
06/28/2022, 5:49 PMprogram
, which is a contextual function can not be evaluated when the context parameter is brought into scope.
Should I file a bug report? 🤔
fun interface Context1 {
fun c1(): Int
}
fun interface Context2 {
fun c2(v: Int): String
}
context(Context1)
fun useC1(): context(Context2) (Int) -> String {
val x = c1()
return { c2(it + x) }
}
fun main(args: Array<String>) {
val program: context(Context2) (Int) -> String = with(Context1 { 42 }) {
useC1()
}
//this works
val result = program(Context2 { "the value is $it" }, 2)
//but this doesn't work
with(Context2 { "the value is $it" }) {
program(2)
}
}
Javier
06/29/2022, 11:01 AM"-Xallow-kotlin-package"
Vitali Plagov
06/29/2022, 12:35 PM1.7.0 release video▾
-Xbackend-threads=4
. But it doesn’t affect the compilation time regardless of number of threads I specify. Am I doing something wrong or missing?
compileKotlin {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11
freeCompilerArgs = ["-Xuse-k2", "-Xbackend-threads=4"]
}
}
Jake Woods
06/30/2022, 4:01 AM_η_−1
means as part of the definition of ϕ
in the kotlin spec least upper bound algorithm? Everything else seems to be defined somewhere in the document but I can’t figure out what the substitution would be for ``_η_−1({out LUB(x_out, y_out), in GLB(x_in, y_in)}`. 🙏reactormonk
07/04/2022, 7:26 AMsuspend fun <ReaderType, ReturnType> registerCallback(listener: (((ReaderType) -> Unit)?) -> Unit, func: (ReaderType) -> ReturnType): ReturnType {
return suspendCoroutine<ReturnType> { block ->
listener { btr ->
block.resume(func(btr))
listener(null)
}
}
}
val reader = registerCallback(acsBluetoothReaderManager::setOnReaderDetectionListener) { reader ->
[...]
reader
}
gives me
java.lang.ClassCastException: org.reactormonk.debugapplication.BluetoothSupportKt$registerCallback$2$1 cannot be cast to com.acs.bluetooth.BluetoothReaderManager$OnReaderDetectionListener
at org.reactormonk.debugapplication.BluetoothNFCActivity$onCreate$1$reader$1.invoke(BluetoothNFC.kt:72)
Compiles fine though.
This is the interface:
public void setOnReaderDetectionListener(BluetoothReaderManager.OnReaderDetectionListener listener) {
this.b = listener;
}
public interface OnReaderDetectionListener {
void onReaderDetection(BluetoothReader var1);
}
fwcd
07/06/2022, 11:31 AMdmitriy.novozhilov
07/06/2022, 2:04 PMdmitriy.novozhilov
07/06/2022, 2:04 PMYoussef Shoaib [MOD]
07/06/2022, 2:07 PMdoAnalysis
-style hook that just allows a plugin to go wild and resolve an expression from the start however it wants?dmitriy.novozhilov
07/06/2022, 2:09 PMfun <K> materialize(): K = null!!
fun <T> id(x: T): T = x
fun takeInt(x: Int) {}
fun test() {
takeInt(id(materialize()))
}
In this example materialize
and id
will be completed only during completion of call takeInt
So if you change candidate (and, potentially, return type) of inner call (materialize
) then it require to reanalyze all calls in chain, because with new type of argument some other functions for outer calls can be applicablecould we have a hook intoThis is also is a bad idea, because call resolution is already extremely complicated (did you read that part of specification?), and providing custom rules to it from plugins will blow everybody minds (compiler devs, plugin devs and regular users)to provide our ownFirCallResolver
Candidate
FirDeclarationGenerationExtension
, why it's not enough for you?Or, how about aWith this approach Kotlin with such plugin won't be Kotlin anymore, because there are no guarantees that plugin will do everything according to specification-style hook that just allows a plugin to go wild and resolve an expression from the start however it wants?doAnalysis
Youssef Shoaib [MOD]
07/06/2022, 2:55 PMaddNewImplicitReceivers
exists, and in fact that's what arrow-inject uses, but I wanted something that wouldn't require the user to explicitly say what receivers they want)
From my observations, when there's multiple candidates that can work, except that both have some missing context receiver, I got a ConeAmbiguityError
so already there isn't one candidate that can work, and so my plugin just helps choose one of them, while if there's only one candidate that can work (but is missing a context receiver), I got an InapplicableCandidateError
, and so my plugin then doesn't change the candidate to a different function, but simply allows the candidate to be considered applicable because a new context receiver gets added into the tower data.
In the case of the `materialize`example (which is actually quite apt because it is similar to a function I've already tested) the return type of materialize would either be determined by explicit type arguments, by the type that id expects, or if there's no other type hints at all, then by the context receiver it is missing (i.e. if materialize had a context(MyWrapper<K>)
and there's only one `MyWrapper`that the plugin knows about with some concrete type). The return type of materialize then changes in 2 cases:
• If it had no type hints, then now it has a return type, which I think is considered okay
• If it knows what type it needed to be, then materialize's return type is either that required type or some subtype of it, but if it is a subtype then I'd and takeInt should still be satisfied (keep in mind that if takeInt
had 2 overloads with one of them taking a subtype of the other then already it would be trying to choose which overload wins based on the argument)
I hope that this makes some sense, hopefully. I'm on mobile rn so it's kinda difficult to provide actual code. Thank you, by the way, because this has helped open my eyes to some incorrect assumptions that I had about the compiler.raulraja
07/06/2022, 5:19 PMYoussef Shoaib [MOD]
07/06/2022, 5:35 PMcontext<Foo<Int>>()
for instance (i.e. I want the context to be available without the user explicitly writing out the type so that e.g. in your polymorphic provider test I could call a function that expects a Foo<Int>
in its context and that would be resolved without requiring a context<Foo<Int>>()
right before the call). The reason behind this is that I want to extensively use contexts with generics without having to type out what generic type it needs (e.g. if I have functions that take `Foo<String> Foo<Int>`or even a Foo<Foo<Foo<List<Any>>>>
I would like all of those function calls to be resolved without any explicit types).raulraja
07/06/2022, 5:38 PMwith
. We have replicated more or less what the ResolutionStageRunner does in the compiler to have the ability to resolve a fake call given a set of candidates.with
Youssef Shoaib [MOD]
07/06/2022, 5:50 PM@Provider internal fun intProvider(): Int = 42
@Provider internal fun stringProvider(): String = "hello world"
data class Foo<A>(val n: A)
context(A)
@Provider internal fun <A> fooProvider(): Foo<A> = Foo(this@A)
context(Foo<Int>) fun needsInt() = TODO()
context(Foo<String>) fun needsString() = TODO()
fun box(): String {
needsInt() //in FIR, it'll have a call to fooProvider as its first contextReceiverArgument, and in turn that call to fooProvider has a call to intProvider as its first contextReceiverArgument (or could be done in IR, doesn't matter)
needsString() // should have first CR argument as call to fooProvider, which has first CR argument as call to stringProvider
}
I want that to compile with no errors, and on the two needsX
calls, the context receiver should basically be a new Foo instance with the Int/String inside of it (which is what to be expected from the providers). With arrow-inject right now I'd need to add the apt calls of arrow's context<>()
function, but that feels redundant to me.raulraja
07/06/2022, 6:42 PMcontextual
but also the error expression types resulting from addNewImplicitReceivers
when the fir call has errors. https://github.com/arrow-kt/arrow-inject/blob/e5a7be736eb01e5eab014d9b36eef2e61cf2[…]/fir/resolution/contexts/ContextProvidersResolutionExtension.ktcontextOf
function but could just look at the error types in resolution to look up the providers.Youssef Shoaib [MOD]
07/06/2022, 7:03 PMcontext(Int) fun foo() = TODO()
context(String) fun foo() = TODO()
@Provider internal fun intProvider(): Int = 42
fun main() {
foo() // should run the one expecting Int
}
Suppressing the errors in this case won't make resolution run correctly here, and if there's no way to alter the callee reference (at least no officially supported API) then such a case won't be possible. I think that an API to support something like that should exist therefore.raulraja
07/06/2022, 7:25 PMoverride fun addNewImplicitReceivers(functionCall: FirFunctionCall): List<ConeKotlinType>
? I'm speculating that when you add the expected types there then the function call should resolve fine because that is added prior to resolving calls.Youssef Shoaib [MOD]
07/06/2022, 7:32 PMaddNewImplicitReceivers
is actually called after the call is completely resolved. Obviously that doesn't matter for arrow's case, but in my case I basically get the BodyResolveComponents
using a hack (I register a custom FirSessionComponent
like this to get access to all the Body Resolve Components then I filter for the one I want) and then inside addNewImplicitReceivers
I figure out the missing context receiver types, find the right providers for them, add them to the towerDataContext, call the expressions transformer (which can be accessed thru BodyResolveComponents), and then remove them from towerDataContext. Finally I use replaceContextReceiverArguments to make them function calls instead (but I could use the arrow approach in IR instead, doesn't matter too much).
And so, I need BodyResolveComponents inside addNewImplicitReceivers
so that I can access the transformer (or alternatively, I could use the callResolver and callCompleter, but both of which are still inside BodyResolveComponents).
I could create my own BodyResolveComponents, but they'll be missing all the surrounding receivers for instance since I won't have access to the real towerDataContext.dmitriy.novozhilov
07/07/2022, 7:34 AMraulraja
07/07/2022, 11:51 AMdmitriy.novozhilov
07/07/2022, 12:48 PM