Git Product home page Git Product logo

mpapt's Introduction

Hi there ๐Ÿ™‹โ€โ™‚๏ธ ๐Ÿ™‹โ€, I am Jens

I'm a software engineer and passionate about Open Source. I like experimenting with Kotlin, in particular multiplatform projects. Here are some of my projects. If you like my work and you want to stay updated, please follow me on:

Kotlin Multiplatform

HTTP client / Kotlin Symbol Processor for Kotlin Multiplatform (Js, Jvm, Android, Native, iOS) using KSP and Ktor clients inspired by Retrofit

Showdown is a selfhosted open source web app/server, you can use for remote planning pokerยฎ with scrum teams. Try at http://showdown.fly.dev/#/

This an Android App that helps you share/manage your files on your Android Device through a WebInterface in the Browser - Built with Ktor and Kotlin-React

A ReactNative App written with Kotlin JS

Android

Community-driven collection of Jetpack Compose example code and tutorials https://foso.github.io/compose

Kotlin

Intellij-based Plugin that can convert HTML to Compose for Web code.

A Interpreter/Transpiler for the Folders esoteric programming language, a language with no code and just folders, written in Kotlin

Kotlin Compiler

This is an example project that shows how to create a Kotlin Compiler Plugin.The plugin will print "Hello from" and the name of the file that is being compiled, as a compiler warning to the terminal log.

  • MpApt (Kotlin JVM/JS/Native)

Kotlin Native/JS/JVM Annotation Processor library for Kotlin compiler plugins

Method call logging for Kotlin Multiplatform

mpapt's People

Contributors

chippmann avatar foso avatar jensklingenbergedeka avatar ronntor avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

mpapt's Issues

[Question/Help Wanted] Running apt in the same sourceset while compiling it

Hi!

I've faced problem implementing APT with your library. Looks like it's normal behavior of kotlin's compiler, I dunno.

Project: mpp with common/frontend/backend source sets.

What I need? I have classes in backend source set, that should be weaved by my APT plugin.
And here is an egg-chicken trouble :) Kotlin code I generate with APT should be included in compiler on the current run...

On the first run APT works well, but rendered classes not includes in compiler and it fails with "Reference not resolved" error.
On the second run everything compiles fine, as compiler knows about rendered files already.

Any way this behavior could be achieved? :)

Support warning/error messages

A java annotation processor can report warnings/errors with javax.annotation.processing.Messager which can include a message as well as what element that message is on. Would be nice to have a similar api available. You seem to have a log() method on AbstractProcessor() but it seems pretty limited.

GradlePlugin -> KotlinCompilerPlugin fails

Hi,

I have tried following the steps but get the following error:

> Task :compileKotlinJs FAILED
e: java.lang.NoClassDefFoundError: de/jensklingenberg/mpapt/model/AbstractProcessor
	at java.base/java.lang.ClassLoader.defineClass1(Native Method)
	at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
	at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
	at java.base/java.net.URLClassLoader.defineClass(URLClassLoader.java:514)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:422)
	at java.base/java.net.URLClassLoader$1.run(URLClassLoader.java:416)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:691)
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:415)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	at com.fab1an.myplugin.MyPluginComponentRegistrar.registerProjectComponents(MyPluginComponentRegistrar.kt:18)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment$Companion.registerExtensionsFromPlugins$cli(KotlinCoreEnvironment.kt:584)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment$ProjectEnvironment.registerExtensionsFromPlugins(KotlinCoreEnvironment.kt:132)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment.<init>(KotlinCoreEnvironment.kt:172)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment.<init>(KotlinCoreEnvironment.kt)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment$Companion.createForProduction(KotlinCoreEnvironment.kt:426)
	at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment.createForProduction(KotlinCoreEnvironment.kt)
	at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:207)
	at org.jetbrains.kotlin.cli.js.K2JSCompiler.doExecute(K2JSCompiler.java:74)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:88)
	at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:44)
	at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:98)
	at org.jetbrains.kotlin.incremental.IncrementalJsCompilerRunner.runCompiler(IncrementalJsCompilerRunner.kt:178)
	at org.jetbrains.kotlin.incremental.IncrementalJsCompilerRunner.runCompiler(IncrementalJsCompilerRunner.kt:75)
	at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileIncrementally(IncrementalCompilerRunner.kt:286)
	at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl$rebuild(IncrementalCompilerRunner.kt:99)
	at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileImpl(IncrementalCompilerRunner.kt:114)
	at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:74)
	at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile$default(IncrementalCompilerRunner.kt:65)
	at org.jetbrains.kotlin.daemon.CompileServiceImplBase.execJsIncrementalCompiler(CompileServiceImpl.kt:550)
	at org.jetbrains.kotlin.daemon.CompileServiceImplBase.access$execJsIncrementalCompiler(CompileServiceImpl.kt:96)
	at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1747)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:564)
	at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
	at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:691)
	at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
	at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
	at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.ClassNotFoundException: de.jensklingenberg.mpapt.model.AbstractProcessor
	at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:435)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:589)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
	... 49 more

Help wanted

Hi there are some things i need help with:

  1. I need a better way to detect when the last class of a module/platform was read and the processing is finished, right now i'm relying on fact that the classes NativeIrGenerationExtension, DebugLogClassGenerationInterceptor and JsSyntheticTranslateExtensionExt are called after the SyntheticResolveExtensionImpl class. I would like to find to have solution that doesn't need these extra classes.

  2. I would like to have a solution where you don't have to manually register every extension classes and just pass the instance of MpAptProject in only one class and this class will register all needed extension classes.

Maybe something like this:

val processor = MpAptTestProcessor(configuration)
val mpapt = MpAptProject(processor)
Mpapt.init(mpapt)

My problem is that i need the project file for the "Register"-classes (I don't know what's the correct name for this classes "IrGenerationExtension.registerExtension()" ) and the kotlin-compiler is using com.intellij.mock.MockProject but the kotlin-compiler-embeddable is using org.jetbrains.kotlin.com.intellij.mock.MockProject and they both have the "Register"-classes with the same name but they need the different project objects. Right now i'm using only the kotlin-compiler-embeddable as dependency in MpApt

  1. Testing
    I don't know what's the best way to write tests for this library

[Question/Help wanted] Resolving dependencies between the different Gradle modules

KUDOS for all the work you've put into this project. Great effort and result.

I am trying to integrate it in a simple framework I've been trying to develop for Kotlin MPP. However, I have run into an issue and can't seem to find a way around it so far.

I have the following project structure:

root
    - demo - Kotlin MPP project
       * dependency implementation project(":annotations")
       * dependency implementation project(":core)
       * applies 'gradle-plugin'
    - annotations - Kotlin MPP projects, contains annotations that have to be processed at build time
    - compiler-plugin-common - Koltin JVM project, the annotation processor implementation
       * dependency implementation "com.something:annotations-jvm:0.0.1"
    - compiler-plugin-jvm-js - Plugging in the processor for JVM/JS
    - compiler-plugin-native - Pluggin in the processor for Kotlin / Native
    - core - Kotlin MPP project, the framework implementation
    - gradle-plugin - Gradle compiler plugin, resolved dependencies to the per platform annotation processing logic

When I try and run a gradle build on demo, it fails to resolve the transitive dependency on com.something:annotations-jvm:0.0.1 with :

org.gradle.internal.component.AmbiguousConfigurationSelectionException: Cannot choose between the following variants of com.something:annotations-jvm.0.0.1:

Problem guessing build folder when deploying to Heroku

I've created the compiler plugin and it works fine when the build process is run locally. But when I try to deploy my application to Heroku the build process fails, because the guessingBuildFolder() function is not able to correctly identify build directory. It returns something like this:

/tmp/build_e07308a302dcea2bb1f4d06d3a3f73ab/src/commonMain/kotlin/com/example/Service.ktbuild

I will the change the checking for supported target platforms

I will add a function to the Abstractprocessor where you get the active target platform and can return true if you want to enable the processor or false if you don't. The default is every target will be enabled

fun isTargetPlatformSupported(platform: TargetPlatform) : Boolean

Help Wanted: Only one Expression Annotation is detected

I would appreciated some help with the following:

When I create two annotated expressions like

fun t1() = @ExprAnn "test"
fun t2() = @ExprAnn "test"

roundEnvironment.getElementsAnnotatedWith(annotationName) only reports one of them.

override fun getSupportedAnnotationTypes(): Set<String> {
    return setOf(annotationName)
}
override fun process(roundEnvironment: RoundEnvironment) {
    roundEnvironment.getElementsAnnotatedWith(annotationName).forEach { element ->
        messageCollector().report(WARNING, "in Loop")
        when (element) {
            is Element.ExpressionElement -> expressions.add(element.ktExpression)
        }
    }
}
override fun processingOver() {
    messageCollector().report(WARNING, "Over")
}

Did I get something wrong here?

ComponentRegistrar is not being called

Hi
I have done all setup, but while building the project there is no activity in compiler module
I have annotated ComponentRegistrar class with @autoservice and published to local maven (and it exists) but it doesn't work
KotlinGradleSubplugin is alive and it is working however
Thanks in advance

[Question/Help Wanted] Annotation Processor get's called to late in the process?

I'm actually not quite sure what problem I'm facing.
But to me it seems that the annotation processor gets called to late on a native target.

A bit of context:
I collect all classes, functions, and properties annotated in the processors process function (like in the examples).
In the annotation processors processingOver function i generate code (like in the examples).
This generated code is put into a subfolder of the build folder of the project. This subfolder is added as a src directory.
But on a clean build this generated code is not compiled into the final binary.
But if i don't clean the project first and build again (so the generated code is still in that subdir) it gets compiled into the final binary.

So my assumption is that my code gets compiled first, then the annotation processing happens, then the linking and so on.

I think i'm just misconfiguring something so that the annotation processing happens too late.
What am I doing wrong?
Also i don't really know what source code snippets you maybe need to help with my problem.

annotation processor
native component registrar
subplugin

Just discovered the DeclarationChecker Class

I just discovered that the class "org.jetbrains.kotlin.resolve.checkers.DeclarationChecker" can also be used to get the classes, functions,properties. It gets called on Jvm/JS/Native. Looks likes it's simpler to use than SyntheticResolveExtension

You can register it inside the registerModuleComponents() of a StorageComponentContainerContributor.

override fun registerModuleComponents(container: StorageComponentContainer, platform: TargetPlatform, moduleDescriptor: ModuleDescriptor) {
        container.useInstance(DeclarationCheckerImpl())
    }
class DeclarationCheckerImpl() : DeclarationChecker{
    override fun check(declaration: KtDeclaration, descriptor: DeclarationDescriptor, context: DeclarationCheckerContext) {

        when(descriptor){
            is SimpleFunctionDescriptor->{
                println("SimpleFunctionDescriptor  "+descriptor.name)
            }
            is ClassConstructorDescriptor->{
                println("ClassConstructorDescriptor  "+descriptor.name)
            }
            is ClassDescriptor ->{
                println("ClassDescriptor  "+descriptor.name)
            }
            is PropertyDescriptor->{
                println("PropertyDescriptor  "+descriptor.name)

            }
            is PropertyGetterDescriptor->{
                println("PropertyGetterDescriptor  "+descriptor.name)
            }
            is PropertySetterDescriptor->{
                println("PropertySetterDescriptor  "+descriptor.name)
            }

            is LocalVariableDescriptor->{
                println("LocalVariableDescriptor  "+descriptor.name)

            }
        }
    }

}

I will use this class to detect the annotations.

Compilation faillure on classes without properties

If you have an annotation on a class or constructor of a class that doesn't have any properties declared inside it's body, method SyntheticResolveExtensionImpl.generateSyntheticProperties fails on this line, because getProperties returns an empty collection:
val isLastProperty = ((thisDescriptor.source as KotlinSourceElement).psi as KtClass).getProperties().last().equals(name)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.