Q:

PowerShell AST Modification and Extents

I am currently trying to use the AST functionality introduced in PowerShell 3.0 to modify a ScriptBlock. My requirement is that all the parameters in the parameter block of the ScriptBlock get a [Parameter(Mandatory)] attribute.
Basically the code should modify this:
Param([string]$x)

Write-Host $x

to this:
Param([Parameter(Mandatory)][string]$x)

Write-Host $x

However, I ran into a problem when adding that new attribute, since it expects an IScriptExtent and I am not sure how I should create a new IScriptExtent.
How can I create a new script extent? What values can I use for the position? Do I have to change the position of all following extents?
I tried just reusing the extent of each parameter I am modifying, but unfortunately this does not seem to yield the results it should (e.g. when I am calling ToString on the modified ScriptBlock I don't see any changes).
My implementation so far is based on the ICustomAstVisitor found here.
The most important method looks like this:
public object VisitParameter(ParameterAst parameterAst)
{
   var newName = VisitElement(parameterAst.Name);

   var extent = // What to do here?

   var mandatoryArg = new AttributeAst(extent, new ReflectionTypeName(typeof (ParameterAttribute)),
        new ExpressionAst[0],
        new[] {new NamedAttributeArgumentAst(extent, "Mandatory", new ConstantExpressionAst(extent, true), true)});

   var newAttributes = new[] {mandatoryArg}.Concat(VisitElements(parameterAst.Attributes));
   var newDefaultValue = VisitElement(parameterAst.DefaultValue);
      return new ParameterAst(parameterAst.Extent, newName, newAttributes, newDefaultValue);
}

A:

Names that begin with I are typically Interfaces. They are not classes that you create an instance of, they are contracts of sorts that specify that a particular class implements a certain known set of functionality.
For example, a [hashtable] implements IEnumerable. That means that anything that knows how to work with an IEnumerable interface and operate on that class; you could create your own class that implements the interface, and code that never could have known about your class or what it does can still interact with it in the way that IEnumerable defines (which in this case is a way to iterate over it).
So, when a function declares a parameter with an interface type, it's not looking for any one specific class, it's looking for any class that implements that interface.
The next step then is to find which types implement that interface. Here's some PowerShell code I used to find those:
[System.AppDomain]::CurrentDomain.GetAssemblies().GetTypes() | Where-Object { 
    [System.Management.Automation.Language.IScriptExtent].IsAssignableFrom($_) 
}

From this, we can see the following:

IsPublic IsSerial Name                                     BaseType                                                    
-------- -------- ----                                     --------                                                    
True     False    IScriptExtent                                                                                        
False    False    InternalScriptExtent                     System.Object                                               
False    False    EmptyScriptExtent                        System.Object                                               
True     False    ScriptExtent                             System.Object                                               

The first listing is the interface itself. Of the other three, two of them are not public, so that just leaves ScriptExtent.
You can create one of these with New-Object but you need to supply the start and end positions as [ScriptPosition] objects. I'm not entirely sure what those should be without seeing more of your code.

A:

The script extent is used primarily for error reporting, but is also used for debugging (for example, setting a line breakpoint.)
In general, the options for synthesized script (like your example) are:

reuse an existing ast, presumably near/related to the ast you're adding
use an empty ast (basically create instances of ScriptExtent and ScriptPosition with no file, empty line)
create a synthetic extent that aids in debugging somehow, maybe with some special content

In your example, any of the above are suitable. The second option is the simplest. The third option is just a variant of the second, but you would set the content to something useful, e.g.
<#Generated: [Parameter(Mandatory)] #>

