public void TestReplaceBaseType() { var context = TestRefactoringContext.Create(@" public class $Foo : System.IDisposable { }"); using (var script = context.StartScript()) { var type = context.GetNode <TypeDeclaration>(); script.ChangeBaseTypes(type, new AstType[] { AstType.Create("System.Test") }); } Assert.AreEqual(@" public class Foo : System.Test { }", context.Text); }
/// <summary> /// Decompile the specified expression, given the network, process, method, and statement /// </summary> /// <param name="network">The top-level network.</param> /// <param name="proc">The process where the method is located.</param> /// <param name="method">The method where the statement is found.</param> /// <param name="statement">The statement where the expression is found.</param> /// <param name="expression">The expression to decompile</param> protected Expression Decompile(NetworkState network, ProcessState proc, MethodState method, Statement statement, ICSharpCode.Decompiler.CSharp.Syntax.Expression expression) { if (expression is ICSharpCode.Decompiler.CSharp.Syntax.AssignmentExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.AssignmentExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.IdentifierExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression) { var mr = expression as ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression; if (mr.ToString() == "base.ShouldContinue") { return new PrimitiveExpression(true, method.SourceMethod.Module.ImportReference(typeof(bool))) { SourceExpression = mr, Parent = statement, } } ; return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.PrimitiveExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.BinaryOperatorExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.IndexerExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.IndexerExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.CastExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.CastExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.ConditionalExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.ConditionalExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.InvocationExpression) { var si = expression as ICSharpCode.Decompiler.CSharp.Syntax.InvocationExpression; var mt = si.Target as ICSharpCode.Decompiler.CSharp.Syntax.MemberReferenceExpression; if (mt.ToString() == "base.PrintDebug" || mt.ToString() == "base.SimulationOnly") { return new EmptyExpression() { SourceExpression = si, Parent = statement } } ; if (mt.ToString() == "Console.WriteLine" || mt.ToString() == "Console.Write") { return new EmptyExpression() { SourceExpression = si, Parent = statement } } ; // Catch common translations if (mt != null && (expression as ICSharpCode.Decompiler.CSharp.Syntax.InvocationExpression).Arguments.Count == 1) { if (mt.MemberName == "op_Implicit" || mt.MemberName == "op_Explicit") { var mtm = Decompile(network, proc, method, statement, mt); return(Decompile(network, proc, method, statement, new ICSharpCode.Decompiler.CSharp.Syntax.CastExpression(AstType.Create(mtm.SourceResultType.FullName), si.Arguments.First().Clone()))); } else if (mt.MemberName == "op_Increment") { return(Decompile(network, proc, method, statement, new ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression(UnaryOperatorType.Increment, si.Arguments.First().Clone()))); } else if (mt.MemberName == "op_Decrement") { return(Decompile(network, proc, method, statement, new ICSharpCode.Decompiler.CSharp.Syntax.UnaryOperatorExpression(UnaryOperatorType.Decrement, si.Arguments.First().Clone()))); } } return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.InvocationExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.ParenthesizedExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.ParenthesizedExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.NullReferenceExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.NullReferenceExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.ArrayCreateExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.ArrayCreateExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.CheckedExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.CheckedExpression)); } else if (expression is ICSharpCode.Decompiler.CSharp.Syntax.UncheckedExpression) { return(Decompile(network, proc, method, statement, expression as ICSharpCode.Decompiler.CSharp.Syntax.UncheckedExpression)); } else if (expression == ICSharpCode.Decompiler.CSharp.Syntax.Expression.Null) { return new EmptyExpression() { SourceExpression = expression } } ; else { throw new Exception(string.Format("Unsupported expression: {0} ({1})", expression, expression.GetType().FullName)); } }
void Fix(Script script, MethodDeclaration methodDeclaration, TypeDeclaration typeDeclaration) { var newTypeDeclaration = (TypeDeclaration)typeDeclaration.Clone(); var resolver = ctx.GetResolverStateAfter(typeDeclaration.LBraceToken); var typeResolve = resolver.ResolveSimpleName("IDisposable", new List <IType>()) as TypeResolveResult; bool canShortenIDisposable = typeResolve != null && typeResolve.Type.FullName == "System.IDisposable"; string interfaceName = (canShortenIDisposable ? string.Empty : "System.") + "IDisposable"; newTypeDeclaration.BaseTypes.Add(new SimpleType(interfaceName)); foreach (var method in DisposeMethods(newTypeDeclaration).ToList()) { if (typeDeclaration.ClassType == ClassType.Interface) { method.Remove(); } else { method.Modifiers &= ~Modifiers.Private; method.Modifiers &= ~Modifiers.Protected; method.Modifiers &= ~Modifiers.Internal; method.Modifiers |= Modifiers.Public; } } if (typeDeclaration.ClassType == ClassType.Interface) { var disposeMember = ((MemberResolveResult)ctx.Resolve(methodDeclaration)).Member; script.DoGlobalOperationOn(new List <IEntity>() { disposeMember }, (nCtx, nScript, nodes) => { List <Tuple <AstType, AstType> > pendingChanges = new List <Tuple <AstType, AstType> >(); foreach (var node in nodes) { var method = node as MethodDeclaration; if (method != null && !method.PrivateImplementationType.IsNull) { var nResolver = ctx.GetResolverStateAfter(typeDeclaration.LBraceToken); var nTypeResolve = nResolver.ResolveSimpleName("IDisposable", new List <IType>()) as TypeResolveResult; bool nCanShortenIDisposable = nTypeResolve != null && nTypeResolve.Type.FullName == "System.IDisposable"; string nInterfaceName = (nCanShortenIDisposable ? string.Empty : "System.") + "IDisposable"; pendingChanges.Add(Tuple.Create(method.PrivateImplementationType, AstType.Create(nInterfaceName))); } } foreach (var change in pendingChanges) { nScript.Replace(change.Item1, change.Item2); } }, "Fix explicitly implemented members"); } script.Replace(typeDeclaration, newTypeDeclaration); }
public IsExpression IsType(Type type) { return(new IsExpression { Type = AstType.Create(type), Expression = this }); }
public AsExpression CastAs(Type type) { return(new AsExpression { Type = AstType.Create(type), Expression = this }); }
public CastExpression CastTo(Type type) { return(new CastExpression { Type = AstType.Create(type), Expression = this }); }
public override void VisitMethodDeclaration(MethodDeclaration methodDeclaration) { if (!methodDeclaration.Body.IsNull) { base.VisitMethodDeclaration(methodDeclaration); return; } if (methodDeclaration.Name == "ToString" && methodDeclaration.Parameters.Count == 0) { methodDeclaration.Modifiers |= Modifiers.Override; } methodDeclaration.Modifiers |= Modifiers.Public; methodDeclaration.Body = new BlockStatement { BindMethodBody(methodDeclaration) }; base.VisitMethodDeclaration(methodDeclaration); if (IsIgnored(methodDeclaration)) { methodDeclaration.Remove(); } RemoveAttributes(methodDeclaration.Attributes); var typeDeclaration = methodDeclaration.GetParent <TypeDeclaration> (); if (typeDeclaration == null || !CurrentTypeData.IsReadOnlyList || methodDeclaration.Name != "Item") { return; } var indexerDeclaration = new IndexerDeclaration { Modifiers = Modifiers.Public, ReturnType = methodDeclaration.ReturnType.Clone(), Getter = new Accessor { Body = (BlockStatement)methodDeclaration.Body.Clone() } }; foreach (var param in methodDeclaration.Parameters) { indexerDeclaration.Parameters.Add(param.Clone()); } methodDeclaration.ReplaceWith(indexerDeclaration); typeDeclaration.BaseTypes.Add( new SimpleType("IReadOnlyList", methodDeclaration.ReturnType.Clone()) ); var forStatement = new ForStatement { Initializers = { new VariableDeclarationStatement( indexerDeclaration.Parameters.First().Type.Clone(), "i", new PrimitiveExpression(0) ), new ExpressionStatement( new AssignmentExpression( new IdentifierExpression("n"), new IdentifierExpression("Count") ) ) }, Condition = new BinaryOperatorExpression( new IdentifierExpression("i"), BinaryOperatorType.LessThan, new IdentifierExpression("n") ), Iterators = { new ExpressionStatement( new UnaryOperatorExpression( UnaryOperatorType.PostIncrement, new IdentifierExpression("i") ) ) }, EmbeddedStatement = new YieldReturnStatement { Expression = new IndexerExpression( new ThisReferenceExpression(), new IdentifierExpression("i") ) }, }; typeDeclaration.Members.Add(new MethodDeclaration { Modifiers = Modifiers.Public, Name = "GetEnumerator", ReturnType = new SimpleType("IEnumerator", methodDeclaration.ReturnType.Clone()), Body = new BlockStatement { forStatement } }); typeDeclaration.Members.Add(new MethodDeclaration { Name = "IEnumerable.GetEnumerator", ReturnType = AstType.Create("IEnumerator"), Body = new BlockStatement { new ReturnStatement( new IdentifierExpression("GetEnumerator").Invoke() ) } }); }