diff --git a/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/singleton/SingletonTransformationSupport.kt b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/singleton/SingletonTransformationSupport.kt
new file mode 100644
index 000000000000..6f2dda9e6b9a
--- /dev/null
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/singleton/SingletonTransformationSupport.kt
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.groovy.transformations.singleton
+
+import com.intellij.util.text.nullize
+import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifierFlags.*
+import org.jetbrains.plugins.groovy.lang.psi.impl.booleanValue
+import org.jetbrains.plugins.groovy.lang.psi.impl.findDeclaredDetachedValue
+import org.jetbrains.plugins.groovy.lang.psi.impl.stringValue
+import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightField
+import org.jetbrains.plugins.groovy.transformations.AstTransformationSupport
+import org.jetbrains.plugins.groovy.transformations.TransformationContext
+import org.jetbrains.plugins.groovy.transformations.plusAssign
+
+class SingletonTransformationSupport : AstTransformationSupport {
+
+ override fun applyTransformation(context: TransformationContext) {
+ val annotation = context.getAnnotation(singletonFqn) ?: return
+ val name = annotation.findDeclaredDetachedValue("property").stringValue().nullize(true) ?: "instance"
+ val lazy = annotation.findDeclaredDetachedValue("lazy").booleanValue() ?: false
+
+ context += GrLightField(context.codeClass, name, context.classType, annotation).apply {
+ val modifiers = STATIC_MASK or if (lazy) PRIVATE_MASK else PUBLIC_MASK or FINAL_MASK
+ modifierList.setModifiers(modifiers)
+ navigationElement = annotation
+ originInfo = singletonOriginInfo
+ }
+
+ context += context.memberBuilder.constructor {
+ setModifiers(PRIVATE_MASK)
+ originInfo = singletonOriginInfo
+ }
+
+ context += context.memberBuilder.method("get${name.capitalize()}") {
+ setModifiers(PUBLIC_MASK or STATIC_MASK)
+ returnType = context.classType
+ navigationElement = annotation
+ originInfo = singletonOriginInfo
+ }
+ }
+}
\ No newline at end of file
diff --git a/plugins/groovy/groovy-psi/resources/standardDsls/singletonTransform.gdsl b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/singleton/impl.kt
similarity index 64%
rename from plugins/groovy/groovy-psi/resources/standardDsls/singletonTransform.gdsl
rename to plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/singleton/impl.kt
index d4e2ad6aba45..2d68c7d443e8 100644
--- a/plugins/groovy/groovy-psi/resources/standardDsls/singletonTransform.gdsl
+++ b/plugins/groovy/groovy-psi/src/org/jetbrains/plugins/groovy/transformations/singleton/impl.kt
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,12 +13,9 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package standardDsls
+package org.jetbrains.plugins.groovy.transformations.singleton
-contributor(ctype:hasAnnotation("groovy.lang.Singleton")) {
- if (psiClass?.hasAnnotation("groovy.lang.Singleton")) {
- property name: "instance",
- type: psiClass?.getQualifiedName() ?: "java.lang.Object",
- isStatic: true
- }
-}
+import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames
+
+internal val singletonFqn = GroovyCommonClassNames.GROOVY_LANG_SINGLETON
+internal val singletonOriginInfo = "by @Singleton"
\ No newline at end of file
diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml
index 46c173d67909..1580a5d9dfba 100644
--- a/plugins/groovy/src/META-INF/plugin.xml
+++ b/plugins/groovy/src/META-INF/plugin.xml
@@ -145,6 +145,8 @@
+
+
setInstance(null)
+Simple simple
+simple = Simple.getInstance()
+simple = Simple.instance
+simple = new Simple()
+
+CustomName.setCoolInstance(null)
+CustomName customName
+customName = CustomName.getCoolInstance()
+customName = CustomName.coolInstance
+customName = new CustomName()
+
+DefaultConstructor.setInstance(null)
+DefaultConstructor defaultConstructor
+defaultConstructor = DefaultConstructor.getInstance()
+defaultConstructor = DefaultConstructor.instance
+defaultConstructor = new DefaultConstructor()
+
+CustomConstructor customConstructor
+customConstructor = CustomConstructor.getInstance()
+customConstructor = CustomConstructor.instance
+customConstructor = new CustomConstructor()
+customConstructor = new CustomConstructor(1, "")
+
+Lazy lazy
+lazy = Lazy.getInstance()
+lazy = Lazy.instance
+lazy = new Lazy()
+
+LazyDefaultConstructor lazyDefaultConstructor
+lazyDefaultConstructor = LazyDefaultConstructor.getInstance()
+lazyDefaultConstructor = LazyDefaultConstructor.instance
+lazyDefaultConstructor = new LazyDefaultConstructor()
+'''
+ enableInspections(GrUnresolvedAccessInspection)
+ checkHighlighting()
+
+ configureByText 'Main.java', '''\
+public class Main {
+ public static void main(String[] args) {
+ Simple simple;
+ simple = Simple.getInstance();
+ simple = Simple.instance;
+ simple = new Simple();
+
+ CustomName customName;
+ customName = CustomName.getCoolInstance();
+ customName = CustomName.coolInstance;
+ customName = new CustomName();
+
+ DefaultConstructor defaultConstructor;
+ defaultConstructor = DefaultConstructor.getInstance();
+ defaultConstructor = DefaultConstructor.instance;
+ defaultConstructor = new DefaultConstructor();
+
+ CustomConstructor customConstructor;
+ customConstructor = CustomConstructor.getInstance();
+ customConstructor = CustomConstructor.instance;
+ customConstructor = new CustomConstructor();
+ customConstructor = new CustomConstructor(1, "");
+
+ Lazy lazy;
+ lazy = Lazy.getInstance();
+ lazy = Lazy.instance;
+ lazy = new Lazy();
+
+ LazyDefaultConstructor lazyDefaultConstructor;
+ lazyDefaultConstructor = LazyDefaultConstructor.getInstance();
+ lazyDefaultConstructor = LazyDefaultConstructor.instance;
+ lazyDefaultConstructor = new LazyDefaultConstructor();
+ }
+}
+'''
+ checkHighlighting()
+ assert !file.contentsLoaded
+ }
+ }
+}
diff --git a/plugins/groovy/testdata/groovy/dsl/transform/SingletonTransform.groovy b/plugins/groovy/testdata/groovy/dsl/transform/SingletonTransform.groovy
deleted file mode 100644
index ba22e17752a4..000000000000
--- a/plugins/groovy/testdata/groovy/dsl/transform/SingletonTransform.groovy
+++ /dev/null
@@ -1,3 +0,0 @@
-@Singleton class T {}
-
-T.inst
\ No newline at end of file
diff --git a/plugins/groovy/testdata/groovy/dsl/transform/SingletonTransform_after.groovy b/plugins/groovy/testdata/groovy/dsl/transform/SingletonTransform_after.groovy
deleted file mode 100644
index 97ee38e0af32..000000000000
--- a/plugins/groovy/testdata/groovy/dsl/transform/SingletonTransform_after.groovy
+++ /dev/null
@@ -1,3 +0,0 @@
-@Singleton class T {}
-
-T.instance
\ No newline at end of file