4b9b75a4405429c6073e155f743ddb44715b5d93
[idea/community.git] / plugins / groovy / src / org / jetbrains / plugins / groovy / dsl / GroovyDslExecutor.groovy
1 package org.jetbrains.plugins.groovy.dsl
2
3 import com.intellij.openapi.util.Pair
4 import com.intellij.psi.PsiElement
5 import com.intellij.util.ProcessingContext
6 import org.jetbrains.plugins.groovy.dsl.psi.PsiEnhancerCategory
7 import org.jetbrains.plugins.groovy.dsl.toplevel.CompositeContextFilter
8 import org.jetbrains.plugins.groovy.dsl.toplevel.ContextFilter
9 import org.jetbrains.plugins.groovy.dsl.toplevel.GdslMetaClassProperties
10
11 /**
12  * @author ilyas
13  */
14
15 public class GroovyDslExecutor {
16   static final def cats = PsiEnhancerCategory.EP_NAME.extensions.collect { it.class }
17   final List<Pair<ContextFilter, Closure>> enhancers = []
18   private final String myFileName;
19
20   public GroovyDslExecutor(String text, String fileName) {
21     myFileName = fileName
22
23     def shell = new GroovyShell()
24     def script = shell.parse(text, fileName)
25
26     def mc = new ExpandoMetaClass(script.class, false)
27     def enhancer = new GdslMetaClassProperties(this)
28
29     // Fill script with necessary properties
30     def properties = enhancer.metaClass.properties
31     for (MetaProperty p in properties) {
32       if (p.getType() == Closure.class) {
33         mc."$p.name" = p.getProperty(enhancer)
34       }
35     }
36
37     mc.initialize()
38     script.metaClass = mc
39     script.run()
40   }
41
42   def addClassEnhancer(List<ContextFilter> cts, Closure toDo) {
43     enhancers << Pair.create(CompositeContextFilter.compose(cts, false), toDo)
44   }
45
46   def processVariants(GroovyClassDescriptor descriptor, consumer, ProcessingContext ctx) {
47     for (pair in enhancers) {
48       if (pair.first.isApplicable(descriptor, ctx)) {
49         Closure f = pair.second.clone()
50         f.delegate = consumer
51         f.resolveStrategy = Closure.DELEGATE_FIRST
52
53         use(cats) {
54           f.call()
55         }
56       }
57     }
58   }
59
60   def String toString() {
61     return "${super.toString()}; file = $myFileName";
62   }
63
64 }