Skip to content

Instantly share code, notes, and snippets.

@nesteruk
Created August 23, 2012 11:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nesteruk/3435846 to your computer and use it in GitHub Desktop.
Save nesteruk/3435846 to your computer and use it in GitHub Desktop.
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() {")
.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");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment