public
Created

Mixin context action

  • Download Gist
MixinContextAction
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
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() {")
.AppendLine(argument)
.AppendLine("}")
.AppendLine("}");
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");
}
}
}

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.