Browse Source

Remove old switch-on-string code from PatternStatementTransform

pull/887/head
Siegfried Pammer 8 years ago
parent
commit
8ee222b373
  1. 8
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 172
      ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

8
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -201,8 +201,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -201,8 +201,8 @@ namespace ICSharpCode.Decompiler.CSharp
if (settings.AsyncAwait && AsyncAwaitDecompiler.IsCompilerGeneratedStateMachine(type))
return true;
} else if (type.IsCompilerGenerated()) {
// if (type.Name.StartsWith("<PrivateImplementationDetails>", StringComparison.Ordinal))
// return true;
if (type.Name.StartsWith("<PrivateImplementationDetails>", StringComparison.Ordinal))
return true;
if (settings.AnonymousTypes && type.IsAnonymousType())
return true;
}
@ -215,8 +215,8 @@ namespace ICSharpCode.Decompiler.CSharp @@ -215,8 +215,8 @@ namespace ICSharpCode.Decompiler.CSharp
return true;
if (settings.AutomaticProperties && IsAutomaticPropertyBackingField(field))
return true;
// if (settings.SwitchStatementOnString && IsSwitchOnStringCache(field))
// return true;
if (settings.SwitchStatementOnString && IsSwitchOnStringCache(field))
return true;
}
// event-fields are not [CompilerGenerated]
if (settings.AutomaticEvents && field.DeclaringType.Events.Any(ev => ev.Name == field.Name))

172
ICSharpCode.Decompiler/CSharp/Transforms/PatternStatementTransform.cs

@ -96,11 +96,6 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -96,11 +96,6 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
public override AstNode VisitIfElseStatement(IfElseStatement ifElseStatement)
{
if (context.Settings.SwitchStatementOnString) {
AstNode result = TransformSwitchOnString(ifElseStatement);
if (result != null)
return result;
}
AstNode simplifiedIfElse = SimplifyCascadingIfElseStatements(ifElseStatement);
if (simplifiedIfElse != null)
return simplifiedIfElse;
@ -256,174 +251,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms @@ -256,174 +251,7 @@ namespace ICSharpCode.Decompiler.CSharp.Transforms
return null;
}
#endregion
#region switch on strings
static readonly IfElseStatement switchOnStringPattern = new IfElseStatement {
Condition = new BinaryOperatorExpression {
Left = new AnyNode("switchExpr"),
Operator = BinaryOperatorType.InEquality,
Right = new NullReferenceExpression()
},
TrueStatement = new BlockStatement {
new IfElseStatement {
Condition = new BinaryOperatorExpression {
Left = new AnyNode("cachedDict"),
Operator = BinaryOperatorType.Equality,
Right = new NullReferenceExpression()
},
TrueStatement = new AnyNode("dictCreation")
},
new IfElseStatement {
Condition = new InvocationExpression(new MemberReferenceExpression(new Backreference("cachedDict").ToExpression(), "TryGetValue"),
new NamedNode("switchVar", new IdentifierExpression(Pattern.AnyString)),
new DirectionExpression {
FieldDirection = FieldDirection.Out,
Expression = new IdentifierExpression(Pattern.AnyString).WithName("intVar")
}),
TrueStatement = new BlockStatement {
Statements = {
new NamedNode(
"switch", new SwitchStatement {
Expression = new IdentifierExpressionBackreference("intVar"),
SwitchSections = { new Repeat(new AnyNode()) }
})
}
}
},
new Repeat(new AnyNode("nonNullDefaultStmt")).ToStatement()
},
FalseStatement = new OptionalNode("nullStmt", new BlockStatement { Statements = { new Repeat(new AnyNode()) } })
};
public SwitchStatement TransformSwitchOnString(IfElseStatement node)
{
Match m = switchOnStringPattern.Match(node);
if (!m.Success)
return null;
// 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().IsMatch(m.Get("switchExpr").Single())) {
AssignmentExpression assign = m.Get("switchExpr").Single() as AssignmentExpression;
if (!(assign != null && m.Get("switchVar").Single().IsMatch(assign.Left)))
return null;
}
FieldReference cachedDictField = m.Get<AstNode>("cachedDict").Single().Annotation<FieldReference>();
if (cachedDictField == null)
return null;
List<Statement> dictCreation = m.Get<BlockStatement>("dictCreation").Single().Statements.ToList();
List<KeyValuePair<string, int>> dict = BuildDictionary(dictCreation);
SwitchStatement sw = m.Get<SwitchStatement>("switch").Single();
sw.Expression = m.Get<Expression>("switchExpr").Single().Detach();
foreach (SwitchSection section in sw.SwitchSections) {
List<CaseLabel> labels = section.CaseLabels.ToList();
section.CaseLabels.Clear();
foreach (CaseLabel label in labels) {
PrimitiveExpression expr = label.Expression as PrimitiveExpression;
if (expr == null || !(expr.Value is int))
continue;
int val = (int)expr.Value;
foreach (var pair in dict) {
if (pair.Value == val)
section.CaseLabels.Add(new CaseLabel { Expression = new PrimitiveExpression(pair.Key) });
}
}
}
if (m.Has("nullStmt")) {
SwitchSection section = new SwitchSection();
section.CaseLabels.Add(new CaseLabel { Expression = new NullReferenceExpression() });
BlockStatement block = m.Get<BlockStatement>("nullStmt").Single();
block.Statements.Add(new BreakStatement());
section.Statements.Add(block.Detach());
sw.SwitchSections.Add(section);
} else if (m.Has("nonNullDefaultStmt")) {
sw.SwitchSections.Add(
new SwitchSection {
CaseLabels = { new CaseLabel { Expression = new NullReferenceExpression() } },
Statements = { new BlockStatement { new BreakStatement() } }
});
}
if (m.Has("nonNullDefaultStmt")) {
SwitchSection section = new SwitchSection();
section.CaseLabels.Add(new CaseLabel());
BlockStatement block = new BlockStatement();
block.Statements.AddRange(m.Get<Statement>("nonNullDefaultStmt").Select(s => s.Detach()));
block.Add(new BreakStatement());
section.Statements.Add(block);
sw.SwitchSections.Add(section);
}
node.ReplaceWith(sw);
return sw;
}
List<KeyValuePair<string, int>> BuildDictionary(List<Statement> dictCreation)
{
if (context.Settings.ObjectOrCollectionInitializers && dictCreation.Count == 1)
return BuildDictionaryFromInitializer(dictCreation[0]);
return BuildDictionaryFromAddMethodCalls(dictCreation);
}
static readonly Statement assignInitializedDictionary = new ExpressionStatement {
Expression = new AssignmentExpression {
Left = new AnyNode().ToExpression(),
Right = new ObjectCreateExpression {
Type = new AnyNode(),
Arguments = { new Repeat(new AnyNode()) },
Initializer = new ArrayInitializerExpression {
Elements = { new Repeat(new AnyNode("dictJumpTable")) }
}
},
},
};
private List<KeyValuePair<string, int>> BuildDictionaryFromInitializer(Statement statement)
{
List<KeyValuePair<string, int>> dict = new List<KeyValuePair<string, int>>();
Match m = assignInitializedDictionary.Match(statement);
if (!m.Success)
return dict;
foreach (ArrayInitializerExpression initializer in m.Get<ArrayInitializerExpression>("dictJumpTable")) {
KeyValuePair<string, int> pair;
if (TryGetPairFrom(initializer.Elements, out pair))
dict.Add(pair);
}
return dict;
}
private static List<KeyValuePair<string, int>> BuildDictionaryFromAddMethodCalls(List<Statement> dictCreation)
{
List<KeyValuePair<string, int>> dict = new List<KeyValuePair<string, int>>();
for (int i = 0; i < dictCreation.Count; i++) {
ExpressionStatement es = dictCreation[i] as ExpressionStatement;
if (es == null)
continue;
InvocationExpression ie = es.Expression as InvocationExpression;
if (ie == null)
continue;
KeyValuePair<string, int> pair;
if (TryGetPairFrom(ie.Arguments, out pair))
dict.Add(pair);
}
return dict;
}
private static bool TryGetPairFrom(AstNodeCollection<Expression> expressions, out KeyValuePair<string, int> pair)
{
PrimitiveExpression arg1 = expressions.ElementAtOrDefault(0) as PrimitiveExpression;
PrimitiveExpression arg2 = expressions.ElementAtOrDefault(1) as PrimitiveExpression;
if (arg1 != null && arg2 != null && arg1.Value is string && arg2.Value is int) {
pair = new KeyValuePair<string, int>((string)arg1.Value, (int)arg2.Value);
return true;
}
pair = default(KeyValuePair<string, int>);
return false;
}
#endregion
#region Automatic Properties
static readonly PropertyDeclaration automaticPropertyPattern = new PropertyDeclaration {
Attributes = { new Repeat(new AnyNode()) },

Loading…
Cancel
Save