I'm working with ast-grep and trying to modify Java code by adding a new line at the end of a constructor. Despite several attempts, I haven't been able to figure out the correct approach.
Here's what I'm trying to achieve:
Original constructor:
public RiskHandler() {
EnvironmentInitializer.initAppConfig();
final RiskApplicationComponent riskApplicationComponent = DaggerRiskApplicationComponent.create();
processor = riskApplicationComponent.riskProcessor();
}
Desired output:
public RiskHandler() {
EnvironmentInitializer.initAppConfig();
final RiskApplicationComponent riskApplicationComponent = DaggerRiskApplicationComponent.create();
processor = riskApplicationComponent.riskProcessor();
testObj = new TestClassProvider().provideTestObj(true);
}
I need to add the line testObj = new TestClassProvider().provideTestObj(true);
as the last line inside the constructor.
I've tried using this YAML configuration, but it's not working:
id: add_agent_declaration
language: java
rule:
kind: constructor_declaration
pattern: |
public $CLASS_NAME() {
$$$BODY
}
fix: |-
public $CLASS_NAME() {
$$$BODY
testObj = new TestClassProvider().provideTestObj(true);
}
I've been looking through the ast-grep documentation but haven't found a clear way to achieve this.
Could someone please help me with how to add a specific new line at the end of the constructor body.
Any help or guidance would be greatly appreciated!
It almost works when you match against the constructor_body
instead of the constructor_declaration
. Strangely, however, you need to provide the opening {
but the closing }
becomes part of $$$BODY
, which means you cannot put any additional lines before the }
.
Pattern:
language: java
rule:
kind: constructor_body
pattern: |
{$$$BODY
fix: |-
{
$$$BODY
testObj = new TestClassProvider().provideTestObj(true);
}
Result:
public RiskHandler() {
EnvironmentInitializer.initAppConfig();
final RiskApplicationComponent riskApplicationComponent = DaggerRiskApplicationComponent.create();
processor = riskApplicationComponent.riskProcessor();
}
testObj = new TestClassProvider().provideTestObj(true);
}
This does not happen when you match the individual lines, which indeed gives the desired result:
language: java
rule:
kind: constructor_body
pattern: |
{$BODY_A
$BODY_B
$BODY_C
fix: |-
{
$BODY_A
$BODY_B
$BODY_C
testObj = new TestClassProvider().provideTestObj(true);
}
However, of course you may not know how many lines there are and in any case it is not a very clean solution.
To match all lines at once and still add the extra line at the right position you can use a workaround: take the full constructor body as a single node $BODY
and strip the final two characters (the }
and the character before, which I'm not fully sure what it is but it messes up the layout if you don't remove it).
id: add_agent_declaration
language: java
rule:
kind: constructor_body
pattern: $BODY
transform:
NEWBODY:
substring:
source: $BODY
startChar: 0
endChar: -2
fix:
$NEWBODY
testObj = new TestClassProvider().provideTestObj(true);
}
This generates the correct code with the additional line within the braces.