Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Mixin context action
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using ActiveMesa.R2P.ContextActions;
using ActiveMesa.R2P.Infrastructure;
using JetBrains.Application;
using JetBrains.Application.Progress;
using JetBrains.ProjectModel;
using JetBrains.ReSharper.Feature.Services.Bulbs;
using JetBrains.ReSharper.Feature.Services.CSharp.Bulbs;
using JetBrains.ReSharper.Intentions.Extensibility;
using JetBrains.ReSharper.Psi.CSharp;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using JetBrains.ReSharper.Psi.ExtensionsAPI.Tree;
using JetBrains.ReSharper.Psi.Impl.CodeStyle;
using JetBrains.ReSharper.Psi.Tree;
using JetBrains.TextControl;
using JetBrains.Util;
namespace ActiveMesa.R2P.Mixin
[ContextAction(Description="Injects a mixin", Group=ContextActionGroups.CSharp, Name = "Inject mixin")]
public class ApplyMixinAction : ContextActionBase
private readonly ICSharpContextActionDataProvider provider;
private IAttribute mixinAttribute;
public ApplyMixinAction(ICSharpContextActionDataProvider provider)
this.provider = provider;
protected override Action<ITextControl> ExecutePsiTransaction(ISolution solution, IProgressIndicator progress)
// get the argument, if it exists
string argument = this.With(x => mixinAttribute)
.If(x => x.Arguments.Count == 1)
.With(x => x.Arguments[0])
.With(x => x.Expression)
.With(x => x as ICSharpLiteralExpression)
.With(x => x.ConstantValue)
.If(x => x.IsString())
.With(x => x.Value as string);
if (argument != null)
var sb = new StringBuilder();
sb.AppendLine("using System;")
.AppendLine("using System.Collections.Generic;")
.AppendLine("using System.Linq;")
.AppendLine("public class Mixin {")
.AppendLine("public IEnumerable<string> Invoke() {")
var inpc = new CSharpInProcessCompiler();
var t = inpc.CompileAndInstantiate(sb.ToString());
var lines = (IEnumerable<string>) t.GetType().GetMethod("Invoke").Invoke(t, EmptyArray<object>.Instance);
string allLines = Environment.NewLine + lines.Join(Environment.NewLine) + Environment.NewLine;
var owner = mixinAttribute.GetContainingTypeDeclaration() as IClassLikeDeclaration;
if (owner != null)
return tc =>
tc.Document.InsertText(owner.RBrace.GetDocumentRange().TextRange.StartOffset, allLines);
return null;
public override string Text
get { return "Apply mixin"; }
public override bool IsAvailable(IUserDataHolder cache)
mixinAttribute = provider.GetSelectedElement<IAttribute>(true, true);
return mixinAttribute != null && mixinAttribute.Name.ShortName.Equals("Mixin");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment