Created
March 2, 2011 12:55
-
-
Save aaronpowell/850881 to your computer and use it in GitHub Desktop.
A macro to convert a field to a property, also adds c#-esq naming
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Boo.Lang.Extensions | |
import Boo.Lang.Compiler | |
import Boo.Lang.Compiler.Ast | |
macro field: | |
case [| field $name as $type |]: | |
backingField = ReferenceExpression("_$name") | |
fn = "$name"[0].ToString().ToUpper() + "$name".Substring(1) | |
yield [| | |
private $backingField as $type | |
|] | |
yield [| | |
public $fn as $type: | |
get: return $backingField | |
set: $backingField = value | |
|] | |
yield [| | |
public $name as $type: | |
get: return $backingField | |
set: $backingField = value | |
|] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class FieldMacro : AbstractAstMacro | |
{ | |
public override Statement Expand(MacroStatement macro) | |
{ | |
if (macro.Arguments.Count == 1) | |
{ | |
var tryCastExpression = (TryCastExpression)macro.Arguments.First; | |
var referenceExpression = (ReferenceExpression)tryCastExpression.Target; | |
var property = new Property(referenceExpression.Name) | |
{ | |
LexicalInfo = macro.LexicalInfo, | |
Getter = new Method(), | |
Setter = new Method() | |
}; | |
var field = new Field( | |
tryCastExpression.Type.LexicalInfo | |
) | |
{ | |
Name = "_" + referenceExpression.Name, | |
Modifiers = TypeMemberModifiers.Private, | |
Type = tryCastExpression.Type | |
}; | |
property.Getter.Body.Add( | |
new ReturnStatement(LexicalInfo.Empty) | |
{ | |
Expression = Expression.Lift(field) | |
} | |
); | |
property.Setter.Body.Add( | |
new BinaryExpression(LexicalInfo.Empty) | |
{ | |
Operator = BinaryOperatorType.Assign, | |
Left = Expression.Lift(field), | |
Right = new ReferenceExpression(LexicalInfo.Empty) { Name = "value" } | |
} | |
); | |
var clazz = (ClassDefinition)macro.GetAncestor(NodeType.ClassDefinition); | |
clazz.Members.Add(field); | |
clazz.Members.Add(property); | |
return null; | |
} | |
CompilerErrorFactory.CustomError(macro.LexicalInfo, | |
string.Format("{0} must be used like: '{0} foo as type'", | |
macro.Name)); | |
return null; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
field Title as string | |
field Body as Html | |
field HeroImage as Uri |
Defining types in boo that i want to push into ravendb. You don't need to do the camel-casing, I just wanted it for better .NET API
yeah makes sense. Note: think you should also provide example code (i.e. in the comments) of how you would use this in anger.
i.e. does it look like?:
class MyType:
field intField as int
field stringField as string
Yep that's basically it
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yeah that's very nice, but when would you use this beast?