when compiling Test.groovy, the compiler should recognize, that there is a class foo.Constants and enqueue it for compiling. But in the end that is not even important. The compiler should recognize the static import and see that PI is imported that way. In theory the compiler could, without compiling Constants, issue the needed bytecode for this. The Groovy compiler does normally not inline, so that would be a PropertyExpression with foo.Constants as ClassExpression in the object part and PI as property string. There is one problem though with this. from the static import alone and without looking at the class the compiler cannot easily know if we import a method or an constant/static property. Also the problem is on what to do should the name PI reappear in the class... which is not the case here, but it is a potential problem.
Maybe we should make our lifes here more easy than we did in the past. Maybe we should simply say that if you static import, that you cannot declare a property or method of that name and that if you use the name as property or method, that then we will do the redirection.
@Alexander, that radical influence was surely not intended and was by accident. Actually it is not easy to write test cases for this kind of thing.