/// <summary> /// Recursively inlines all methods invoked within the <paramref name="methodBody" /> for which the /// <paramref name="predicate" /> returns <c>true</c>. /// </summary> /// <param name="methodBody">The method body which should have all invoked methods inlined.</param> /// <param name="predicate">The predicate that indicates whether an invoked method should be inlined.</param> internal static MethodBodyMetadata Inline(MethodBodyMetadata methodBody, Func<MethodMetadata, bool> predicate) { Requires.NotNull(methodBody, () => methodBody); var inliner = new MethodInliner(predicate); inliner._nameScope.AddRange(methodBody.Parameters.Select(parameter => parameter.Name)); var body = inliner._variableReplacer.Visit(inliner.Inline(methodBody)); return new MethodBodyMetadata(methodBody.Parameters, inliner._localVariables, (BlockStatement)body); }
public void Visit(MethodBodyMetadata metadata) { _writer.AppendBlockStatement(() => { foreach (var variable in metadata.LocalVariables) { string defaultValue = null; if (variable.Type == typeof(int)) defaultValue = "0"; if (variable.Type == typeof(double)) defaultValue = "0.0"; if (variable.Type == typeof(bool)) defaultValue = "false"; if (variable.Type.IsEnum) { defaultValue = String.Format("{0}.{1}", variable.Type.Name, Enum.GetValues(variable.Type).Cast<object>().First()); Enums.Add(variable.Type); } _writer.AppendLine("{0} {1} = {2};", GetTypeName(variable.Type), variable.Name, defaultValue); } foreach (var s in metadata.Body.Statements) Visit(s); }); }
/// <summary> /// Recursively inlines all methods invoked within <paramref name="methodBody" />'s body. /// </summary> /// <param name="methodBody">The method which should have all invoked methods inlined.</param> private BoundNode Inline(MethodBodyMetadata methodBody) { foreach (var variable in methodBody.LocalVariables) ReplaceWithNewLocalVariable(variable); return Visit(methodBody.Body); }