kevin.cianfarini
03/19/2022, 12:25 AMRepresents a compiled regular expressionWhen we say it's compiled, does that mean the regex is transformed into a state machine? I recently read this article and thought it was very interesting. https://swtch.com/~rsc/regexp/regexp1.html
dalexander
03/22/2022, 3:23 PMgalex
03/23/2022, 3:07 PMAnalysisHandlerExtension
fit this use case? Any examples?eygraber
03/25/2022, 3:05 PMuseFir = true
and I'm getting some errors. What's the best way to report these?kralli
03/25/2022, 5:27 PMval a: List<String>= listOf()
, where there is no whitespace in between the type parameter and the assignment.
Am I right when I conclude, that the PsiBuilder
does not allow for splitting tokens but only for remapping? So is it really not (trivially) possible to convert a GTEQ into a GT and an EQ?eygraber
03/27/2022, 4:48 AMKtLambdaArgument
that is the last value in Call.valueArguments
what is the best way to determine if it is a trailing lambda or not?Peter Mandeljc
03/31/2022, 7:59 AM// A
fun example() = "banana"
// B
companion object {
const val X = "banana"
}
fun example() = X
I guess benefit is storing variable to heap. But on the other hand, I think that adding single-use constants impacts code readability. Any thoughts?vineethraj49
04/01/2022, 2:52 PMZac Sweers
04/03/2022, 4:29 AMhfhbd
04/04/2022, 2:43 PMVladimir Tagakov
04/07/2022, 1:33 AMprivate typealias FixesCompilation = (Unit, Unit) -> Unit
private typealias AlsoFixesCompilation = Unit.(action: Unit) -> Unit
val d: Unit.(action: Unit) -> Unit
If any of lines above is presented everything compiles fine, typealias is not used anywhere. But when I remove it I’m getting the ISE
with: IrSimpleFunctionPublicSymbolImpl for kotlin/Function2.invoke|3397681596704175240[0] is already bound: FUN IR_EXTERNAL_DECLARATION_STUB name:invoke
Kotlin version is: 1.6.10
full stacktrace in the threadpakoito
04/08/2022, 9:15 AMAny
in fun <T> assertEquals(expected: T, result: T): Unit
when expected and result don’t have a shared ancestor?Asq
04/09/2022, 1:06 PMTom Dyas
04/10/2022, 2:58 AMorg.jetbrains.kotlin.cli.jvm.K2JVMCompiler
) Must it be a jar from under KOTLIN_HOME
or are plugin jars available on Maven Central for resolution with Coursier?martmists
04/19/2022, 12:18 PMneworldlt
04/19/2022, 3:55 PMinternal
modifiers in the compiler process. Like kotlin-allopen
plugin. The idea is to keep a way of having internal
abuse in kotlin generated code. However, after deep-diving I hit a wall. No extension is running because Square's Anvil
(and probably KSP) is generating code that does not compile due to publicly exposed internal
stuff. The only exception is DeclarationAttributeAltererExtension
, which runs during the resolve phase. However, DeclarationAttributeAltererExtension
is able to modify only Modality
.
Is there any other way to plugin during resolve
phase in order to fix compilation errors?martmists
04/20/2022, 11:16 AMMuhammad Sufyian
04/23/2022, 10:43 AMhow kotlin compiler works
and looking for some document or may be any other way that can help me in understand the execution from syntax tree generation to target code .
Can anyone point me in the right direction ?
Thank youPeter Mandeljc
05/03/2022, 4:07 PMopen fun x() = Unit
B. open fun x() { }
galex
05/05/2022, 9:59 AMAnalysisHandlerExtension
is the right place for things like returning errors if the class name is not valid (as a simple use case).
To do so I've implemented something like this:
class CGAnalysisHandlerExtension : AnalysisHandlerExtension {
override fun doAnalysis(
project: Project,
module: ModuleDescriptor,
projectContext: ProjectContext,
files: Collection<KtFile>,
bindingTrace: BindingTrace,
componentProvider: ComponentProvider
): AnalysisResult? {
files.forEach { file ->
val fileName = file.name.replace(".kt", "")
file.children.forEach {
when (it) {
is KtClass -> {
if (it.name != fileName) {
bindingTrace.report(UNDERSCORE_IS_RESERVED.on(it))
return AnalysisResult.compilationError(bindingTrace.bindingContext)
}
}
}
}
}
return super.doAnalysis(project, module, projectContext, files, bindingTrace, componentProvider)
}
}
Doing so I thought I'd see the IDE underline the className in red with its error but the IDE doesn't react to this report, only when compiling and in the Build Output (see screenshot).
So my question is the following: What is the missing piece here to have the IDE show the report/error as any other errors, and can't I have this check actually happen when the class is in the "Analyzing..." phase of the IDE?
Thanks in advance!doubov
05/05/2022, 10:24 PMcontext(CoroutineExecutorScope<Msg, State, Label>)
works fine, but
context(CoroutineExecutorScope<Msg, *, *>)
throws a compilation error.Quantum64
05/09/2022, 9:00 AMaballano
05/09/2022, 11:35 AMfun <T> something(f: () -> T): T
and I would like for the compiler to fail if I try to do this:
val unit: Unit = something {
1
}
The problem with this is that if we would have something like a Flow inside or any other complex type that we forgot to execute/unwrap/whatever, this would be a bug in the codebase, for example:
val unit: Unit = something {
flowOf(1)
}
If this would fail as I would expect it to, I would notice that I forgot to collect my flow, but instead is accepting a Flow or any type as Unit, is there a way to enforce this somehow?Alexander Maryanovsky
05/17/2022, 7:43 AMtypealias ComposableFunction = @Composable (value: Int) -> Unit
but this doesn’t:
typealias ComposableFunction = @Composable(value: Int) -> Unit
martmists
05/19/2022, 1:07 PMorg.jetbrains.kotlin.backend.common.BackendException: Backend Internal error: Exception during psi2ir
File being compiled: (26,9) in /home/mart/git/sites/martmists/src/backendMain/kotlin/com/martmists/backend/data/GithubProject.kt
The root cause java.util.NoSuchElementException was thrown at: org.jetbrains.kotlin.psi2ir.generators.ArgumentsGenerationUtilsKt$generateReceiver$1.load(ArgumentsGenerationUtils.kt:873)
Collection contains no element matching the predicate.: KtCallExpression:
div("project project-github") {
...
Jesper Åman
05/22/2022, 10:48 AMIrGenerationExtension
that generates some classes and methods, in some of the method bodies I need to include a super call, however, it's not entirely clear to me how to achieve this through the IR-apis. With this code, which is meant to just call super.onCreate()
in a subclass of `android.app.Application`:
override fun visitFunctionNew(declaration: IrFunction): IrStatement {
if (declaration.name.asString() == "onCreate"
&& declaration.parentAsClass.hasAnnotation(pluginContext.externalConfigApplicationAnnotation)
) {
...
// If body does not already exist
declaration.body = pluginContext.irBlockBody(declaration.symbol) {
+irCall(declaration, superQualifierSymbol = pluginContext.applicationClass).apply {
dispatchReceiver = irGet(declaration.dispatchReceiverParameter!!)
}
...
}
...
}
return super.onVisitFunctionNew(declaration)
}
I'm getting the following error:
Caused by: java.lang.AssertionError: SyntheticAccessorLowering should not attempt to modify other files!
While lowering this file: FILE fqName:c.z.a.e.sample fileName:/.../MainActivity.kt
Trying to add this accessor: FUN SYNTHETIC_ACCESSOR name:access$onCreate$s-1072845520 visibility:public modality:FINAL <> ($this:android.app.Application) returnType:kotlin.Unit
Seems like rather than just invoking super, it tries to generate a synthetic accessor. Any ideas as to why this is not working?
I do have a workaround currently that involves just injecting the java byte code further down the chain via a ClassBuilderInterceptorExtension
, but would very much like to avoid this if possible.
I'm seeing that there are ways to achieve this easily when dealing with constructors, e.g. +irDelegatingConstructorCall(...)
, is there something similar available for functions generally?Alexander Maryanovsky
05/22/2022, 3:38 PMQuantum64
05/24/2022, 4:00 AMrrva
05/24/2022, 5:53 AMAlexander Maryanovsky
05/24/2022, 3:58 PMAlexander Maryanovsky
05/24/2022, 3:58 PMFleshgrinder
05/24/2022, 4:20 PMAlexander Maryanovsky
05/24/2022, 4:58 PMnschulzke
05/24/2022, 5:09 PMMemento
class that has internal
and private
functions?Alexander Maryanovsky
05/24/2022, 5:10 PMnschulzke
05/24/2022, 5:11 PMAlexander Maryanovsky
05/24/2022, 5:11 PMnschulzke
05/24/2022, 5:12 PMAlexander Maryanovsky
05/24/2022, 5:15 PMFleshgrinder
05/24/2022, 6:01 PMephemient
05/25/2022, 1:40 AMpublic sealed interface Foo {
internal class Impl : Foo
}
internal fun Foo.asImpl(): Foo.Impl = when (this) {
is Impl -> this
}
over open-coding as Impl
everywhereAlexander Maryanovsky
05/25/2022, 4:39 AMFleshgrinder
05/25/2022, 6:41 AMpublic class Foo internal constructor() {
internal val state: Any? = TODO()
internal fun doSomething() = Unit
}
And if Java is a concern we can tack on @JvmSynthetic
on all the `internal`s. Regardless, having a public as Private
is less work then anything else and it's very clear. Having a dedicated auto-casting for it, however, seems unsafe and going against Kotlin's idea of being explicit about type changes.
That said, all of these are workarounds for the absence of more fine grained access modifiers and I totally agree that there should be more:
• Friend classes
• Package private where the package(s) the symbol is visible in can be chosen with wildcard support.
• Module private where the module(s) the symbol is visible in can be chosen with wildcard support.
• …
I think the Java module system is a way to get there and I'm curious how it might evolve beyond what we have today (which is too narrow in functionality by focusing on the needs of the JDK itself, which is totally fine as a starting point).Alexander Maryanovsky
05/25/2022, 9:30 AMFleshgrinder
05/25/2022, 11:06 AMval private: Private = public
or val private = public as Private
because without having the type anywhere it's impossible for the compiler to know that one didn't want Public
. Now continue this to f(public)
where f
is fun f(private: Private)
. In the current compilation where the sealed class only has one member this is legal, in the next one it is not legal anymore since the concrete type is only known at runtime. This may lead to a codebase being broken all over (imagine 100+ f
calls). This is where I see the unsafety.
Btw. @ephemient doesn't suffer from this problem, because the conversion is confined into a dedicated function that makes usage search and global fixing easy.interface Into<T> {
fun into(): T
}
How cool would it be to have this but with multiple inheritance like Rust has it. Kotlin special cased this for Comparable<T>
with operator
support. Of course, generic support would be nice, but it would break Java compatibility. However, the Into<T>
trait would be doable.
public sealed interface Public {
internal class Private : Public
}
internal operator fun Public.into(): Private = this as Private
For Java we generate:
public static Private toPrivate(Public public) {}
The whole thing would work exactly as it does in Rust with turbofish to help the compiler if it's confused.
f(public.into())
😎
class A {
operator fun into(): B = TODO()
operator fun into(): C = TODO()
}
fun g(a: A) {
val b: B = a.into()
val c = a.into<C>()
}
// Java
void g(A a) {
B b = a.toB();
C c = a.toC();
}
Alexander Maryanovsky
05/25/2022, 12:57 PMwhen
is exhaustive, and tomorrow, when another type is added, it’s not, and doesn’t compile.Fleshgrinder
05/25/2022, 1:02 PMAlexander Maryanovsky
05/25/2022, 1:04 PMT?
to T
as soon as the compiler can infer that the value is not null
, I think the auto-casting for a single sealed type is natural.Public
is Private
, as it doesn’t give a warning when you cast it manually.Fleshgrinder
05/25/2022, 1:11 PMBut it’s possible there are other use-cases, although I can’t think of any at the moment.Absolutely, that's what I wrote in my very first message: maybe I'm missing something. Handling of
T?
to T
is a very special case that complicates the language, but its applicability is universal so that it's warranted. Here we talk about an edge case that only very few are going to encounter. Complicating the language for such things is never a good idea. It's better to abstract the actual underlying issue and address it with a solution that solves a whole bunch of issues in a generic way. This is always hard for language designers to convey to users, since each user has a particular unique pain point, but that's what language designers have to do. There's also always the danger of introducing a particular solution to a particular problem and then other things break or get harder, but taking the feature back is close to impossible. Another situation that needs to be avoided by all means. Sealed types is a proven thing, but auto-casting if a sealed type has a single implementation is not. What if that single subtype has additional subtypes? Is the cast still safe in that situation? What does it mean for this and that? Lots of ground to cover. From the ad-hoc analysis done by some of us in this thread it already seems not worthwhile to go further for the reasons explained.
The special casing of T?
and T
is on its own a problem and a fully fledged union/intersection system that works for all types (built-in or user) like Ceylon has it would be that general, universal solution. Everybody wants it, but it's hard. 🤞 we'll get it at some point.Alexander Maryanovsky
05/25/2022, 1:20 PMsealed interface Base{
}
class Sub1: Base{
val n = 5
}
class Sub2: Base{
val k = 6
}
fun foo (b: Base){
println(
(b as Sub2).k
)
}
Fleshgrinder
05/25/2022, 1:22 PMsealed interface I {
private class C : I
private class D : I
}
fun f(i: I) {
val c = i as C
}
Nor does it warn here:
import java.util.UUID
fun f(x: UUID) {
val y = x as String
}
Alexander Maryanovsky
05/25/2022, 1:22 PMFleshgrinder
05/25/2022, 1:22 PMAlexander Maryanovsky
05/25/2022, 1:23 PMas
to be as!
as!!
Fleshgrinder
05/25/2022, 1:25 PMas
(a cast) is by definition a forced operation, adding more symbols to it does not change that fact. Sure, the JVM (and other systems) have runtime protections to avoid totally silly casts, but they don't have to. In Rust silly casts are possible with unsafe {}
and in C any cast is always possible. It's just 0s and 1s after all we are dealing with and how we interpret them is up to us.
import java.util.UUID
fun f(x: UUID) {
val y = x as? String
}
This is possible to avoid the runtime exception.ephemient
05/25/2022, 1:28 PMList<String>
to a List<Int>
can appear to succeed even though it'll cause problems later. but UUID as String
is immediateFleshgrinder
05/25/2022, 1:31 PMList as List
cast due to type erasure.Alexander Maryanovsky
05/25/2022, 1:32 PMas!!
would more clearly mark an unsafe operation.Fleshgrinder
05/25/2022, 1:34 PM!
is used to mark types where nullability is unknown and !!
is used to throw a NPE if something shall never be null. Very different things.Alexander Maryanovsky
05/25/2022, 1:35 PM?
is used in more than one place to mark “operation or null if operation can’t succeed”Fleshgrinder
05/25/2022, 1:37 PM?
is consistently used together with null
. It either marks a type as nullable or an expression to short circuit if the previous expression is null.
There are many languages out there that use symbols in different contexts for totally different things, and that can be fine, or you end up with Perl. 🤷 It's all about trade offs.