Skip to content

Conversation

@Foso
Copy link
Contributor

@Foso Foso commented Oct 20, 2019

This PR will added the option to add a list of ComponentRegistrars to the compiler.

@tschuchortdev
Copy link
Owner

Looks nice. Arrow-meta was announced to the public at lambda world conf this Friday, so it's good if we have more ergonomic support for compiler plugins soon when more people will write their own.

Is this ready to be merged or more like a WIP? I will do a closer review tomorrow.

The stupid CI failed again but I think it's unrelated to these changes.

@Foso
Copy link
Contributor Author

Foso commented Oct 21, 2019

Hi, i heard about arrow-meta and i'm excited to try it out :)

This is ready to be merged, i wanted to add this feature, before i will add the support of the JSCompiler

var pluginClasspaths: List<File> = emptyList()

/**
* Compiler plugins that should be added the compilation
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

Comment on lines 412 to 421
if(annotationProcessors.isEmpty()) {
log("No services were given. Not running kapt steps.")
return ExitCode.OK
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why was this removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this because it was not possible to execute the compiler plugins without also adding an annotation processor.
The problem was that the pluginClasspaths were set after this check.

I restored this and made changes. Inside stubsAndApt, only the annotation processors are added to threadLocalParameters. Then inside compileKotlin, only the compiler plugins are set, so the processors aren't getting executed twice.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't this change the behaviour so that additional compiler plugins are only registered in the compileKotlin step? The current behaviour of #23. Is that additional plugins are executed in both steps. I don't know which way is actually right though,

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you are right, we could also do it this way:

if(annotationProcessors.isEmpty() && compilerPlugins.isEmpty()) {
			log("No services were given. Not running kapt steps.")
			return ExitCode.OK
}

I remove the changes in stubsAndApt and compileKotlin and just add the additional check for the compilerPlugins. Then the behaviour stays the same and it's possible to add compilerPlugins without also adding annotation processors.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be best to always add compiler plugins in the stubsAndApt step but cancel it if there are no annotation processors, like we did previously.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if i understand it correctly, in stubsAndApt we'll add the compiler plugins and cancel if there is no annotation processor. And then in compileKotlin we'll add the plugins again?

Otherwise i can't see how it's possible to add a compiler plugin without also having to add a annotation processor.


override fun registerProjectComponents(project: MockProject, configuration: CompilerConfiguration) {
val parameters = threadLocalParameters.get()
KaptComponentRegistrar(parameters.processors,parameters.kaptOptions).registerProjectComponents(project,configuration)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I read a few days ago in the Kotlin slack that the order of registering compiler plugins matters. Right now we are registering Kapt first. Could there be a problem here? For example if a compiler plugin like arrow-meta introduces some new syntax/type checking that isn't legal in vanilla Kotlin the respective plugin would have to be run before Kapt or Kapt wouldn't know how to deal with that. Any thoughts on this @raulraja?

@raulraja
Copy link

raulraja commented Oct 26, 2019 via email

@tschuchortdev
Copy link
Owner

@raulraja That's not really what I meant. Let's assume you have some plugin that replaces every method named foo with a method bar. If the Kapt plugin is registered first, I assume that apt will see a foo method in the stub files. If Kapt is registered last, then I assume apt will see a bar method in the stub files. This could be problematic.

@raulraja
Copy link

raulraja commented Oct 27, 2019 via email

Comment on lines 526 to 541

/**
* Here the list of compiler plugins is set
*
* To avoid that the annotation processors are executed twice,
* the list is set to empty
*/
MainComponentRegistrar.threadLocalParameters.set(
MainComponentRegistrar.Parameters(
listOf(),
KaptOptions.Builder(),
compilerPlugins
)
)


Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why did you remove this again? I think we always need to add the compiler plugins to the compileKotlin step, even if they already ran in the stubsAndApt step.

Copy link
Contributor Author

@Foso Foso Nov 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @tschuchortdev , i removed it because i wanted to change a less as possible, because i couldn't guarantee that it would break any behaviour of any other compiler plugins that runs in any of the compiler phases. All i can say is, that i could test my MpApt Plugin with these changes and it didn't break any of the existing tests and Kapt was also working. I don't know much about when which compiler phase is running, because my plugin is only running in one phase.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you creating new source files with your plugin or simply adding to the AST?

Copy link
Contributor Author

@Foso Foso Nov 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My plugin just detects the annotations, it doesn't provide code generation

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we still need to run the plugins in the compileKotlin step then, because all the changes done to the AST during stubsAndApt will be discarded, so a compiler plugin that changes the AST would have no effect.

But I think we also need to run the plugins in the stubsAndApt step as well, before kapt plugin is run.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think that we should add it to both. I could restore my deleted version.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I restored it, and changed the check in stubsAndApt to "annotationProcessors.isEmpty()" again, because without, all added plugins were executed in both phases. In the future we need an option where you can set in which phases you want to execute the plugins, but for now i would keep it that way. If you think otherwise, just add " && compilerPlugins.isEmpty()" to the if statement again.

@tschuchortdev
Copy link
Owner

@Foso Can you check what the correct behaviour is when KApt interacts with compiler plugins? If you just modify your MpApt plugin to add some dummy method to all classes and then run it together with a regular annotation processor, you should be able to see the method (or not) in the AP and we can be sure. I'm not so familiar with compiler plugins unfortunately or I would do it myself.

If not, I say we just register first-party plugins before KApt in the MainComponentRegistrar and merge it. If someone complains we can always fix it later.

@tschuchortdev tschuchortdev self-requested a review October 29, 2019 20:23
Foso added 3 commits November 6, 2019 19:22
…ile-testing into tschuchortdev#15-betterSupportForCompilerPlugins

� Conflicts:
�	src/test/kotlin/com/tschuchort/compiletesting/KotlinCompilationTests.kt
Copy link
Owner

@tschuchortdev tschuchortdev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The arrow-meta people will be happy to have this. I will merge it manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants