[ 
https://issues.apache.org/jira/browse/GROOVY-7764?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16170630#comment-16170630
 ] 

Jochen Theodorou commented on GROOVY-7764:
------------------------------------------

ResolveVisitor will fail compilation if a class cannot be resolved. 
ResolveVisitor is the first thing being done in Semantic Analysis. For stub 
compilation we do this actually a little bit different. We first start 
resolving in an no-error mode, which means all the errors found by 
ResolveVisitor will not be reported. And we do this already in the step 
Conversion. So in theory a transform could run in Conversion already. 

There are problems with this though:
* Not all classes will be resolved, the transform would require special handling
* ResolveVisitor is one of the most expensive steps during compilation, doing 
it twice will make compilation take almost twice as long
* This early resolving step introduces unstable semantics.

With unstable semantics I mean... 

Assume you have import a.* and b.* and there is a class a.Foo and b.Foo and you 
use the vanilla Foo. Then this is supposed to fail compilation, because it is 
unclear if you did mean a.Foo or b.Foo. But with early resolving and one of the 
Foo classes being written in Java, it is possible that the compilation will 
succeed, because the compiler sees only one Foo and there is nothing unclear 
for the compiler what Foo you mean. But if both are Groovy or Java, it would 
fail. And in an incremental compilation step based on files this could also 
work one time and one time not. 

Another example would be the vanilla name Script and import a.*, with an 
a.Script written in Java. Because default imports are shadowed by explicit 
imports this now does not fail compilation if the compiler does see a.Script. 
But the problem is that the vanilla name Script will be compiled to 
groovy.lang.Script if a.Script is not known at this point. Obviously you get 
this problem in stub generation today already. But it can be fixed by an 
explicit import. Here the compiler knows then the full name, without having to 
resolve the class.

Of course other information of the resolve step could be also very important. 
static imports, variables scopes, resolving inner classes, knowing if something 
that might be a class or variable is actually a variable and so on. I am 
ignoring this here, but they are potentially important too.

This can be all fixed by throwing away all the resolving information from the 
early resolve and resolve again of course, but that will probably about double 
compilation time.

Then there is of course the minimal variant... we try to resolve only the 
annotations, to see if they are actually describing transforms and then 
applying the transforms. This basically has the same shadowing problems, they 
are just happening in a smaller scope, with less possibility for collisions, 
thus will not happen so often. We would still not get a correct compilation 
from this of course. And conversion means what conversion means, which is that 
there is only the raw AST. 

Then what transforms would work in this mode?
could work: 
* ToString
* EqualsAndHashCode
* TupleConstructor
* Canonical
* IndexedProperty
* Lazy
* Sortable
* Buildere
* Memoized
* Singleton
* Log
* Synchronized
* WithReadLock
* WithWriteLock
* AutoClone
* AutoExternalize
* Field
* PackageScope
* CompileDynamic
* Bindable
* ListenerList
* Vetoable
* NotYetImplemented
* ASTTest
* Grab and related, but it will not actually provide anything

cannot work reliably: 
* InheritConstructors
* Category
* Newify
* Delegate
* Immutable
* Mixin
* ThreadInterrupt, TimedInterrupt, ConditionalInterrupt
* TypeChecked

Yes, the list is pretty long

> Joint compilation does not work with AST-transformed Groovy
> -----------------------------------------------------------
>
>                 Key: GROOVY-7764
>                 URL: https://issues.apache.org/jira/browse/GROOVY-7764
>             Project: Groovy
>          Issue Type: Bug
>          Components: Stub generator / Joint compiler
>    Affects Versions: 2.4.6
>            Reporter: O. Reißig
>         Attachments: foo.zip
>
>
> When using AST transformations together with joint compilation the generated 
> stubs don't mind the transformations, which may yield invalid classes, that 
> javac will fail to compile.
> Example:
> {code}
> [...]
> class GroovyTest implements Callable {
>     @Delegate
>     private final Callable c = { println "Hello World" }
> }
> {code}
> will get compiled into the following stub:
> {code}
> [...]
> public class GroovyTest
>   extends java.lang.Object  implements
>     java.util.concurrent.Callable,    groovy.lang.GroovyObject {
> ;
> public  groovy.lang.MetaClass getMetaClass() { return 
> (groovy.lang.MetaClass)null;}
> public  void setMetaClass(groovy.lang.MetaClass mc) { }
> public  java.lang.Object invokeMethod(java.lang.String method, 
> java.lang.Object arguments) { return null;}
> public  java.lang.Object getProperty(java.lang.String property) { return 
> null;}
> public  void setProperty(java.lang.String property, java.lang.Object value) { 
> }
> }
> {code}
> which claims to implement {{Callable}}, but lacks a {{call}} method.
> I don't know if this is specific to {{@Delegate}}, but noticed similar 
> behaviour with {{@InheritConstructors}}.



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)

Reply via email to