diff --git a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs index b10772645..33786fcc2 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs @@ -385,7 +385,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms #region switch on strings static readonly IfElseStatement switchOnStringPattern = new IfElseStatement { Condition = new BinaryOperatorExpression { - Left = new NamedNode("switchVar", new IdentifierExpression()), + Left = new AnyNode("switchExpr"), Operator = BinaryOperatorType.InEquality, Right = new NullReferenceExpression() }, @@ -405,7 +405,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms new IfElseStatement { Condition = new Backreference("cachedDict").ToExpression().Invoke( "TryGetValue", - new Backreference("switchVar"), + new NamedNode("switchVar", new IdentifierExpression()), new DirectionExpression { FieldDirection = FieldDirection.Out, Expression = new IdentifierExpressionBackreference("intVar") @@ -433,13 +433,19 @@ namespace ICSharpCode.Decompiler.Ast.Transforms continue; if (m.Has("nonNullDefaultStmt") && !m.Has("nullStmt")) continue; + // switchVar must be the same as switchExpr; or switchExpr must be an assignment and switchVar the left side of that assignment + if (m.Get("switchVar").Single().Match(m.Get("switchExpr").Single()) == null) { + AssignmentExpression assign = m.Get("switchExpr").Single() as AssignmentExpression; + if (m.Get("switchVar").Single().Match(assign.Left) == null) + continue; + } FieldReference cachedDictField = m.Get("cachedDict").Single().Annotation(); if (cachedDictField == null || !cachedDictField.DeclaringType.Name.StartsWith("", StringComparison.Ordinal)) continue; List dictCreation = m.Get("dictCreation").Single().Statements.ToList(); List> dict = BuildDictionary(dictCreation); SwitchStatement sw = m.Get("switch").Single(); - sw.Expression = m.Get("switchVar").Single().Detach(); + sw.Expression = m.Get("switchExpr").Single().Detach(); foreach (SwitchSection section in sw.SwitchSections) { List labels = section.CaseLabels.ToList(); section.CaseLabels.Clear(); diff --git a/ICSharpCode.Decompiler/ILAst/ILInlining.cs b/ICSharpCode.Decompiler/ILAst/ILInlining.cs index 4a078f8fb..26e26c6ae 100644 --- a/ICSharpCode.Decompiler/ILAst/ILInlining.cs +++ b/ICSharpCode.Decompiler/ILAst/ILInlining.cs @@ -147,6 +147,12 @@ namespace ICSharpCode.Decompiler.ILAst // ensure the variable is accessed only a single time if (!(numStloc.GetOrDefault(v) == 1 && numLdloc.GetOrDefault(v) == 1 && numLdloca.GetOrDefault(v) == 0)) return false; + + if (next is ILCondition) + next = ((ILCondition)next).Condition; + else if (next is ILWhileLoop) + next = ((ILWhileLoop)next).Condition; + ILExpression parent; int pos; if (FindLoadInNext(next as ILExpression, v, inlinedExpression, out parent, out pos) == true) { @@ -335,7 +341,7 @@ namespace ICSharpCode.Decompiler.ILAst case ILCode.Ldsflda: // All address-loading instructions always return the same value for a given operand/argument combination, // so they can be safely copied. - return true; + return true; case ILCode.Ldarg: // arguments can be copied only if they aren't assigned to (directly or indirectly via ldarga) ParameterDefinition pd = (ParameterDefinition)ldArg.Operand;