Search code examples
javaintellij-ideagetter-setter

Custom Intellij template setter to do simple fieldname subString


I am trying to write a custom setter using intellij template's which needs to do simple subString on fieldName if it starts with specific prefix, for example "i_"

I have a class as follows:

public class Summary {
    public long i_duration;
}

Using the default Setter generation in intellij outputs:

public class Summary {
    public long i_duration;

    public long getI_duration() {
        return i_duration;
    }
}

Am trying to achieve

public class Summary {
    public long i_duration;

    public long getDuration() {
        return i_duration;
    }
}

What I have tried so far is copying Intelij's Template and using combination of StringUtil.startsWith() and StringUtil.substringAfter() to strip the "i_" from field name before using as part of method name. However I'm leaking a space somewhere and getting an error while I'm using the template below.

Incorrect method 'long get Duration() { return i_duration; }'

As we can see there appears to be a space inserted between 'get' and 'Duration'. Below is my custom template for Setter Generation

#if($field.modifierStatic)
static ##
#end
$field.type ##
#set($fieldName = $field.name)
#set($rejectPrefix = "i_")
#if ($StringUtil.startsWith(${fieldName}, ${rejectPrefix}))
    #set($fieldName = $StringUtil.substringAfter(${fieldName}, ${rejectPrefix}))
#end    
#if($field.recordComponent)
    ${fieldName}##
#else
    #set($name = $StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier(${fieldName})))
    #if ($field.boolean && $field.primitive)
    is##
    #else
    get##
    #end
    ${name}##
#end
() {
return $field.name;
}

Default Intelij Default Template for Setter Generation

#if($field.modifierStatic)
static ##
#end
$field.type ##
#if($field.recordComponent)
  ${field.name}##
#else
#set($name = $StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project))))
#if ($field.boolean && $field.primitive)
  is##
#else
  get##
#end
${name}##
#end
() {
  return $field.name;
}

There's not lot of documentation around writing custom getter template on intellij but have seen this Generate custom code

Also seen: Source code for intellij's StringUtil and FieldElement class


Solution

  • Got this working, sharing for everyone below. Still don't understand why did it work this way, someone from intellij community could explain us better

    #if($field.modifierStatic)
    static ##
    #end
    $field.type ##
    #set($fieldName = $field.name)
    #set($rejectPrefix = "m_")
    #if ($StringUtil.startsWith(${fieldName}, ${rejectPrefix}))
        #set($fieldName = $StringUtil.substringAfter(${fieldName}, ${rejectPrefix}))
    #end    
    #if($field.recordComponent)
        ${fieldName}##
    #else
        #set($name = $StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier(${fieldName})))
        #if ($field.boolean && $field.primitive)
        is${name}##
        #else
        get${name}##
        #end
    #end
    () {
    return $field.name;
    }
    

    I assumed each usage of ## could be leaking space or auto-inserting them, so merged if-else block on is## and get## with single ${name}## in end to if-else block on is${name}## and get${name}##