public static CodeMemberField AddField(this CodeTypeDeclaration type, string fieldName, CodeTypeReference fieldType, CodeExpression init = null) { var field = Declare.Field(fieldName, fieldType); if (init != null) { field.InitExpression = init; } return(type.AddMember(field)); }
static void AddToStringHelper(CodeTypeDeclaration type, CodeDomProvider provider) { var helperClass = Declare.Class("ToStringInstanceHelper") .AsNestedPublic() .WithReference(out var helperClassType); helperClass.AddField <IFormatProvider> ("formatProvider", TypeReference <System.Globalization.CultureInfo> .Global.Property("InvariantCulture")) .WithReference(out var formatProvider); helperClass.AddProperty <IFormatProvider> ("FormatProvider") .WithGet(formatProvider) .WithSetIgnoresNull(formatProvider); helperClass.AddMethod("ToStringWithCulture") .Returns <string> () .WithParameter <object> ("objectToConvert", out var objectToConvert) .WithStatements( objectToConvert.ThrowIfNull(), Declare.Variable <Type> ("type", objectToConvert.InvokeMethod("GetType"), out var objType), Declare.Variable <Type> ("iConvertibleType", Expression.TypeOf <IConvertible> (), out var iConvertibleType), Statement.If(iConvertibleType.InvokeMethod("IsAssignableFrom", objType), Then: Statement.Return(objectToConvert.Cast <IConvertible> ().InvokeMethod("ToString", formatProvider))), Declare.Variable <System.Reflection.MethodInfo> ("methInfo", objType.InvokeMethod("GetMethod", Expression.Primitive("ToString"), Expression.Array <Type> (iConvertibleType)), out var methInfoLocalRef), Statement.If(methInfoLocalRef.IsNotNull(), Then: Statement.Return(Expression.Cast <string> ( methInfoLocalRef.InvokeMethod("Invoke", objectToConvert, Expression.Array <object> (formatProvider))))), Statement.Return(objectToConvert.InvokeMethod("ToString")) ); var helperFieldName = provider.CreateValidIdentifier("_toStringHelper"); type.AddPropertyGetOnly("ToStringHelper", type.AddField(helperFieldName, helperClassType, Expression.New(helperClassType))); type.AddMember(helperClass); }
public static CodeMemberMethod AddMethod(this CodeTypeDeclaration type, string methodName) => type.AddMember(Declare.Method(methodName));
public static CodeMemberProperty AddProperty(this CodeTypeDeclaration type, string propertyName, CodeTypeReference propertyType) => type.AddMember(Declare.Property(propertyName, propertyType));
public static CodeSnippetTypeMember AddSnippetMember(this CodeTypeDeclaration type, string value, CodeLinePragma location = null) => type.AddMember(IndentHelpers.CreateSnippetMember(value, location));
// END SYNCED SECTION public static T AddTo <T> (this T member, CodeTypeDeclaration type) where T : CodeTypeMember => type.AddMember(member);
static void GenerateTransformMethod(CodeTypeDeclaration templateType, TemplateSettings settings, ParsedTemplate pt, string templateFile, bool isOverride) { string baseDirectory = Path.GetDirectoryName(templateFile); var transformMeth = Declare.Method("TransformText").Returns <string> ().AsVirtual(); if (isOverride) { transformMeth.AsOverride(); } transformMeth.WithStatements(Expression.This.SetProperty("GenerationEnvironment", Expression.Null)); CodeExpression toStringHelper = settings.IsPreprocessed ? Expression.This.Property("ToStringHelper") : TypeReference.Global(typeof(ToStringHelper)).AsExpression(); //method references that will need to be used multiple times var writeMeth = Expression.This.Method("Write"); var toStringMeth = toStringHelper.Method("ToStringWithCulture"); bool helperMode = false; //build the code from the segments foreach (TemplateSegment seg in pt.Content) { CodeStatement st = null; CodeLinePragma location = null; if (!settings.NoLinePragmas) { var f = seg.StartLocation.FileName ?? templateFile; if (!string.IsNullOrEmpty(f)) { // FIXME: we need to know where the output file will be to make this work properly if (settings.RelativeLinePragmas) { f = FileUtil.AbsoluteToRelativePath(baseDirectory, f); } else { f = Path.GetFullPath(f); } } location = new CodeLinePragma(f, seg.StartLocation.Line); } switch (seg.Type) { case SegmentType.Block: if (helperMode) { //TODO: are blocks permitted after helpers? pt.LogError("Blocks are not permitted after helpers", seg.TagStartLocation); } st = Statement.Snippet(seg.Text); break; case SegmentType.Expression: st = writeMeth.Invoke(toStringMeth.Invoke(Expression.Snippet(seg.Text))).AsStatement(); break; case SegmentType.Content: st = writeMeth.Invoke(Expression.Primitive(seg.Text)).AsStatement(); break; case SegmentType.Helper: if (!string.IsNullOrEmpty(seg.Text)) { templateType.AddSnippetMember(seg.Text, location); } helperMode = true; break; default: throw new InvalidOperationException(); } if (st != null) { if (helperMode) { //convert the statement into a snippet member and attach it to the top level type //TODO: is there a way to do this for languages that use indentation for blocks, e.g. python? using (var writer = new StringWriter()) { settings.Provider.GenerateCodeFromStatement(st, writer, null); var text = writer.ToString(); if (!string.IsNullOrEmpty(text)) { templateType.AddSnippetMember(text, location); } } } else { st.LinePragma = location; transformMeth.Statements.Add(st); continue; } } } transformMeth.WithStatements(Statement.Return(Expression.This.Property("GenerationEnvironment").InvokeMethod("ToString"))); templateType.AddMember(transformMeth); }