diff --git a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs index b6d8b33bb..71db95751 100644 --- a/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs +++ b/ICSharpCode.Decompiler/Ast/Transforms/PatternStatementTransform.cs @@ -716,7 +716,7 @@ namespace ICSharpCode.Decompiler.Ast.Transforms return null; } FieldReference cachedDictField = m.Get("cachedDict").Single().Annotation(); - if (cachedDictField == null || !cachedDictField.DeclaringType.Name.StartsWith("", StringComparison.Ordinal)) + if (cachedDictField == null) return null; List dictCreation = m.Get("dictCreation").Single().Statements.ToList(); List> dict = BuildDictionary(dictCreation); @@ -764,22 +764,73 @@ namespace ICSharpCode.Decompiler.Ast.Transforms } List> BuildDictionary(List dictCreation) - { - List> dict = new List>(); - 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; - PrimitiveExpression arg1 = ie.Arguments.ElementAtOrDefault(0) as PrimitiveExpression; - PrimitiveExpression arg2 = ie.Arguments.ElementAtOrDefault(1) as PrimitiveExpression; - if (arg1 != null && arg2 != null && arg1.Value is string && arg2.Value is int) - dict.Add(new KeyValuePair((string)arg1.Value, (int)arg2.Value)); - } - return dict; - } + { + 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> BuildDictionaryFromInitializer(Statement statement) + { + List> dict = new List>(); + Match m = assignInitializedDictionary.Match(statement); + if (!m.Success) + return dict; + + foreach (ArrayInitializerExpression initializer in m.Get("dictJumpTable").ToArray()) { + KeyValuePair pair; + if (TryGetPairFrom(initializer.Elements, out pair)) + dict.Add(pair); + } + + return dict; + } + + private static List> BuildDictionaryFromAddMethodCalls(List dictCreation) + { + List> dict = new List>(); + 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 pair; + if (TryGetPairFrom(ie.Arguments, out pair)) + dict.Add(pair); + } + return dict; + } + + private static bool TryGetPairFrom(AstNodeCollection expressions, out KeyValuePair 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)arg1.Value, (int)arg2.Value); + return true; + } + + pair = default(KeyValuePair); + return false; + } + #endregion #region Automatic Properties