private static bool AddArrayInitializer(Exprent first, Exprent second) { if (first.type == Exprent.Exprent_Assignment) { AssignmentExprent @as = (AssignmentExprent)first; if (@as.GetRight().type == Exprent.Exprent_New && @as.GetLeft().type == Exprent.Exprent_Var) { NewExprent newExpr = (NewExprent)@as.GetRight(); if (!(newExpr.GetLstArrayElements().Count == 0)) { VarExprent arrVar = (VarExprent)@as.GetLeft(); if (second.type == Exprent.Exprent_Assignment) { AssignmentExprent aas = (AssignmentExprent)second; if (aas.GetLeft().type == Exprent.Exprent_Array) { ArrayExprent arrExpr = (ArrayExprent)aas.GetLeft(); if (arrExpr.GetArray().type == Exprent.Exprent_Var && arrVar.Equals(arrExpr.GetArray ()) && arrExpr.GetIndex().type == Exprent.Exprent_Const) { int constValue = ((ConstExprent)arrExpr.GetIndex()).GetIntValue(); if (constValue < newExpr.GetLstArrayElements().Count) { Exprent init = newExpr.GetLstArrayElements()[constValue]; if (init.type == Exprent.Exprent_Const) { ConstExprent cinit = (ConstExprent)init; VarType arrType = newExpr.GetNewType().DecreaseArrayDim(); ConstExprent defaultVal = ExprProcessor.GetDefaultArrayValue(arrType); if (cinit.Equals(defaultVal)) { Exprent tempExpr = aas.GetRight(); if (!tempExpr.ContainsExprent(arrVar)) { newExpr.GetLstArrayElements()[constValue] = tempExpr; if (tempExpr.type == Exprent.Exprent_New) { NewExprent tempNewExpr = (NewExprent)tempExpr; int dims = newExpr.GetNewType().arrayDim; if (dims > 1 && !(tempNewExpr.GetLstArrayElements().Count == 0)) { tempNewExpr.SetDirectArrayInit(true); } } return(true); } } } } } } } } } } return(false); }
private static int IsArrayInitializer(List <Exprent> list, int index) { Exprent current = list[index]; if (current.type == Exprent.Exprent_Assignment) { AssignmentExprent @as = (AssignmentExprent)current; if (@as.GetRight().type == Exprent.Exprent_New && @as.GetLeft().type == Exprent.Exprent_Var) { NewExprent newExpr = (NewExprent)@as.GetRight(); if (newExpr.GetExprType().arrayDim > 0 && newExpr.GetLstDims().Count == 1 && (newExpr .GetLstArrayElements().Count == 0) && newExpr.GetLstDims()[0].type == Exprent.Exprent_Const) { int size = (int)((ConstExprent)newExpr.GetLstDims()[0]).GetValue(); if (size == 0) { return(0); } VarExprent arrVar = (VarExprent)@as.GetLeft(); Dictionary <int, Exprent> mapInit = new Dictionary <int, Exprent>(); int i = 1; while (index + i < list.Count && i <= size) { bool found = false; Exprent expr = list[index + i]; if (expr.type == Exprent.Exprent_Assignment) { AssignmentExprent aas = (AssignmentExprent)expr; if (aas.GetLeft().type == Exprent.Exprent_Array) { ArrayExprent arrExpr = (ArrayExprent)aas.GetLeft(); if (arrExpr.GetArray().type == Exprent.Exprent_Var && arrVar.Equals(arrExpr.GetArray ()) && arrExpr.GetIndex().type == Exprent.Exprent_Const) { // TODO: check for a number type. Failure extremely improbable, but nevertheless... int constValue = ((ConstExprent)arrExpr.GetIndex()).GetIntValue(); if (constValue < size && !mapInit.ContainsKey(constValue)) { if (!aas.GetRight().ContainsExprent(arrVar)) { Sharpen.Collections.Put(mapInit, constValue, aas.GetRight()); found = true; } } } } } if (!found) { break; } i++; } double fraction = ((double)mapInit.Count) / size; if ((arrVar.IsStack() && fraction > 0) || (size <= 7 && fraction >= 0.3) || (size > 7 && fraction >= 0.7)) { List <Exprent> lstRet = new List <Exprent>(); VarType arrayType = newExpr.GetNewType().DecreaseArrayDim(); ConstExprent defaultVal = ExprProcessor.GetDefaultArrayValue(arrayType); for (int j = 0; j < size; j++) { lstRet.Add(defaultVal.Copy()); } int dims = newExpr.GetNewType().arrayDim; foreach (KeyValuePair <int, Exprent> ent in mapInit) { Exprent tempExpr = ent.Value; lstRet[ent.Key] = tempExpr; if (tempExpr.type == Exprent.Exprent_New) { NewExprent tempNewExpr = (NewExprent)tempExpr; if (dims > 1 && !(tempNewExpr.GetLstArrayElements().Count == 0)) { tempNewExpr.SetDirectArrayInit(true); } } } newExpr.SetLstArrayElements(lstRet); return(mapInit.Count); } } } } return(0); }
public static void Simplify(SwitchStatement switchStatement) { SwitchExprent switchExprent = (SwitchExprent)switchStatement.GetHeadexprent(); Exprent value = switchExprent.GetValue(); if (IsEnumArray(value)) { List <List <Exprent> > caseValues = switchStatement.GetCaseValues(); Dictionary <Exprent, Exprent> mapping = new Dictionary <Exprent, Exprent>(caseValues .Count); ArrayExprent array = (ArrayExprent)value; FieldExprent arrayField = (FieldExprent)array.GetArray(); ClassesProcessor.ClassNode classNode = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(arrayField.GetClassname()); if (classNode != null) { MethodWrapper wrapper = classNode.GetWrapper().GetMethodWrapper(ICodeConstants.Clinit_Name , "()V"); if (wrapper != null && wrapper.root != null) { wrapper.GetOrBuildGraph().IterateExprents((Exprent exprent) => { if (exprent is AssignmentExprent) { AssignmentExprent assignment = (AssignmentExprent)exprent; Exprent left = assignment.GetLeft(); if (left.type == Exprent.Exprent_Array && ((ArrayExprent)left).GetArray().Equals( arrayField)) { Sharpen.Collections.Put(mapping, assignment.GetRight(), ((InvocationExprent)((ArrayExprent )left).GetIndex()).GetInstance()); } } return(0); } ); } } List <List <Exprent> > realCaseValues = new List <List <Exprent> >(caseValues.Count); foreach (List <Exprent> caseValue in caseValues) { List <Exprent> values = new List <Exprent>(caseValue.Count); realCaseValues.Add(values); foreach (Exprent exprent in caseValue) { if (exprent == null) { values.Add(null); } else { Exprent realConst = mapping.GetOrNull(exprent); if (realConst == null) { DecompilerContext.GetLogger().WriteMessage("Unable to simplify switch on enum: " + exprent + " not found, available: " + mapping, IFernflowerLogger.Severity.Error ); return; } values.Add(realConst.Copy()); } } } caseValues.Clear(); Sharpen.Collections.AddAll(caseValues, realCaseValues); switchExprent.ReplaceExprent(value, ((InvocationExprent)array.GetIndex()).GetInstance ().Copy()); } }