Top Description Methods
groovy.lang

public @Interface Newify

extends Annotation
Annotations
@Documented
@Retention:SOURCE
@Target:CONSTRUCTOR, METHOD, TYPE, FIELD, LOCAL_VARIABLE
@GroovyASTTransformationClass:NewifyASTTransformation
Imports
org.codehaus.groovy.transform.GroovyASTTransformationClass, java.lang.annotation.ElementType, .Retention, .RetentionPolicy, .Target

Annotation that supports writing constructor call expressions without the 'new' keyword. Instead they can be written "Ruby-style" as a method call to a 'new' method or "Python-style" by just omitting the 'new' keyword.

Warning

For the Python style with class-name-matching pattern, the pattern should be chosen as to avoid matching method names if possible. If following Java/Groovy naming conventions, class names (contrary to method names) start with an uppercase letter. In this case pattern="[A-Z].*" (see java.util.regex.Pattern for supported Java pattern syntax) is the recommended pattern to allow all classes to be created without requiring a new keyword. Using a pattern that also matches method names (e.g. ".+", ".*" or "[a-zA-Z].*") might negatively impact build performance, since the Groovy compiler will have to match every class in context against any potential constructor call.

@Newify allows you to write code snippets like this ("Python-style"):

@Newify([Tree,Leaf]) class MyTreeProcessor {
    def myTree = Tree(Tree(Leaf("A"), Leaf("B")), Leaf("C"))
    def process() { ... }
}
// Any class whose name matches pattern can be created without new
@Newify(pattern="[A-Z].*") class MyTreeProcessor {
    final myTree = Tree(Tree(Leaf("A"), Leaf("B")), Leaf("C"))
    final sb = StringBuilder("...")
    def dir = File('.')
    def root = XmlSlurper().parseText(File(dir, sb.toString()).text)
}
or this ("Ruby-style"):
@Newify class MyTreeProcessor {
    def myTree = Tree.new(Tree.new(Leaf.new("A"), Leaf.new("B")), Leaf.new("C"))
    def process() { ... }
}
After the AST transformation, the following code is passed on for further compilation:
class MyTreeProcessor {
    def myTree = new Tree(new Tree(new Leaf("A"), new Leaf("B")), new Leaf("C"))
    def process() { ... }
}
The annotation can be used on a whole class as shown above or selectively on a particular method, constructor or field.

The "Ruby-style" new conversions occur automatically unless the 'auto=false' flag is given when using the annotation. You might do this if you create a new method using meta programming.

For the "Python-style" conversions you can either specify each class name on which you want them to apply, or supply a pattern to match class names against. The transformation then works by matching the basename of the provided classes to any similarly named instance method calls not specifically bound to an object, i.e. associated with the 'this' object. In other words Leaf("A") would be transformed to new Leaf("A") but x.Leaf("A") would not be touched.

An example showing how to use the annotation at different levels:

@Newify(auto=false, value=Foo)
class Main {
    @Newify // turn auto on for field
    def field1 = java.math.BigInteger.new(42)
    def field2, field3, field4

    @Newify(pattern="[A-z][A-Za-z0-9_]*") // Any class name that starts with an uppercase letter
    def process() {
        field2 = A(Bb(Ccc("my bar")))
    }

    @Newify(Baz)
    Main() {
        field3 = Foo("my foo")
        field4 = Baz("my baz")
    }
}
The annotation is intended to be used sparingly; perhaps in DSL scenarios or when using deeply nested structural types. In particular, there is no support for using the facility with two similarly named classes from different packages at the same time. Though it is OK to have different packages in different contexts. Also, there is no support for turning "Ruby-style" conversions off at the method, constructor or field level if already turned on at the class level.

Method Summary

Modifier and TypeMethod and Description
public boolean

Returns:

if automatic conversion of "Ruby-style" new method calls should occur
auto
()

public String

Returns:

a regex pattern for class names where "Python-style" constructor notation will be supported
pattern
()

public Class<?>[]

Returns:

one or more classes where "Python-style" constructor notation will be supported
value
()

Inherited from java.lang.annotation.Annotation:
annotationTypeequalshashCodetoString

Method Detail

autoback to summary
public boolean auto()
Returns:boolean

if automatic conversion of "Ruby-style" new method calls should occur

patternback to summary
public String pattern()
Returns:String

a regex pattern for class names where "Python-style" constructor notation will be supported

Since
2.5.0
valueback to summary
public Class<?>[] value()
Returns:Class<?>[]

one or more classes where "Python-style" constructor notation will be supported