To generate code, I used to use templates like the following (contrived example):

```smalltalk

template := 'method1

^ {returnValue}'.

template format: { #returnValue -> 2 } asDictionary

```

This is *okay* for simple cases, but can get unwieldy, and doesn't benefit from e.g. (early) compiler warnings. It is also lacking when one wants to offer the behavior as a method and also as a script with no dependencies (maybe for CI).

To overcome some of these limitations, I started saving the code template as an actual method and transforming the AST, e.g.:

```smalltalk

"Convert baseline##: method"

methodTree := (self methodNamed: selector) parseTree.

methodTree selector: #baseline:.

methodTree pragmas at: 1 put: (RBPragmaNode selector: #baseline arguments: #()).

commonBlockBody := methodTree statements first arguments last body.

commonBlockBody statements

detect: [ :e | e selector = #repository: ]

ifFound: [ :repoSetter | commonBlockBody removeNode: repoSetter ].

"Compile baseline method"

baseline compile: methodTree newSource classified: 'baseline'

```

When I started doing this, I noticed two things:

1. There were idioms that were repeated over and over.

2. It still isn't super easy to turn a method into a script with no dependencies (e.g. self sends)

So, I did a spike to wrap a few common idioms for this use case. It works like this. Say you have a method like this:

```

SmallRemoteGitRepository>>#addRemote: urlString as: nameString

"Assumes repo is loaded"

| repo remote |

repo := IceRepository registry detect: [ :e | e name = self projectName ].

remote := IceGitRemote name: nameString url: urlString.

repo addRemote: remote.

remote fetch

```

And you want to also provide it as source code for a script with no dependencies. You can do:

```

SmallRemoteGitRepository >>#scriptToAddRemote: urlString as: nameString

| method transformer |

method := SmallRemoteGitRepository methodNamed: #addRemote:as:.

transformer := method peAST_Transformer

beScript;

addStatementFirst: #projectName , ' := ' , self projectName printString;

addStatementFirst: #nameString , ' := ' , nameString printString;

addStatementFirst: #urlString , ' := ' , urlString printString;

replaceNodeDetect: [ :e | e isMessage and: [ e selector = #projectName ] ]

withNode: (RBVariableNode named: #projectName).

^ transformer newSource

```

which would generate (for example, for a particular instance):

```

| repo remote projectName |

urlString := 'git@github.com:magritte-metamodel/magritte.git'.

nameString := 'upstream'.

projectName := 'Magritte'.

repo := IceRepository registry detect: [ :e | e name = projectName ].

remote := IceGitRemote name: nameString url: urlString.

repo addRemote: remote.

remote fetch

```

So my questions are:

- Does something like this already exist?

- Are there better ways to solve this problem?

- Does this solution look promising/generally-helpful?