public override CheckTypesResult CheckExprTypeBounds() { CheckTypesResult result = new CheckTypesResult(); result.AddMinTypeExprent(value, VarType.Vartype_Bytechar); result.AddMaxTypeExprent(value, VarType.Vartype_Int); VarType valType = value.GetExprType(); foreach (List <Exprent> lst in caseValues) { foreach (Exprent expr in lst) { if (expr != null) { VarType caseType = expr.GetExprType(); if (!caseType.Equals(valType)) { valType = VarType.GetCommonSupertype(caseType, valType); result.AddMinTypeExprent(value, valType); } } } } return(result); }
public override bool Equals(object obj) { PointerVarType v2 = (obj as PointerVarType); if (v2 == null) { return(false); } return(pointedToType.Equals(v2.pointedToType)); }
public override bool Equals(object obj) { ArrayVarType v2 = (obj as ArrayVarType); if (v2 == null) { return(false); } return(baseType.Equals(v2.baseType) && this.arrayDimensions.SequenceEqual(v2.arrayDimensions)); }
public virtual void AdjustConstType(VarType expectedType) { // BYTECHAR and SHORTCHAR => CHAR in the CHAR context if ((expectedType.Equals(VarType.Vartype_Char) || expectedType.Equals(VarType.Vartype_Character )) && (constType.Equals(VarType.Vartype_Bytechar) || constType.Equals(VarType.Vartype_Shortchar ))) { int intValue = GetIntValue(); if (IsPrintableAscii(intValue) || Char_Escapes.ContainsKey(intValue)) { SetConstType(VarType.Vartype_Char); } } else if ((expectedType.Equals(VarType.Vartype_Int) || expectedType.Equals(VarType .Vartype_Integer)) && constType.typeFamily == ICodeConstants.Type_Family_Integer) { // BYTE, BYTECHAR, SHORTCHAR, SHORT, CHAR => INT in the INT context SetConstType(VarType.Vartype_Int); } }
private static bool IsAppendConcat(InvocationExprent expr, VarType cltype) { if ("append".Equals(expr.GetName())) { MethodDescriptor md = expr.GetDescriptor(); if (md.ret.Equals(cltype) && [email protected] == 1) { VarType param = md.@params[0]; switch (param.type) { case ICodeConstants.Type_Object: { if (!param.Equals(VarType.Vartype_String) && !param.Equals(VarType.Vartype_Object )) { break; } goto case ICodeConstants.Type_Boolean; } case ICodeConstants.Type_Boolean: case ICodeConstants.Type_Char: case ICodeConstants.Type_Double: case ICodeConstants.Type_Float: case ICodeConstants.Type_Int: case ICodeConstants.Type_Long: { return(true); } default: { break; } } } } return(false); }
public override VarType GetExprType() { VarType exprType = array.GetExprType(); if (exprType.Equals(VarType.Vartype_Null)) { return(hardType.Copy()); } else { return(exprType.DecreaseArrayDim()); } }
private static Exprent RemoveStringValueOf(Exprent exprent) { if (exprent.type == Exprent.Exprent_Invocation) { InvocationExprent iex = (InvocationExprent)exprent; if ("valueOf".Equals(iex.GetName()) && stringClass.Equals(iex.GetClassname())) { MethodDescriptor md = iex.GetDescriptor(); if ([email protected] == 1) { VarType param = md.@params[0]; switch (param.type) { case ICodeConstants.Type_Object: { if (!param.Equals(VarType.Vartype_Object)) { break; } goto case ICodeConstants.Type_Boolean; } case ICodeConstants.Type_Boolean: case ICodeConstants.Type_Char: case ICodeConstants.Type_Double: case ICodeConstants.Type_Float: case ICodeConstants.Type_Int: case ICodeConstants.Type_Long: { return(iex.GetLstParameters()[0]); } } } } } return(exprent); }
private static InvocationExprent IsAssertionError(Statement stat) { if (stat == null || stat.GetExprents() == null || stat.GetExprents().Count != 1) { return(null); } Exprent expr = stat.GetExprents()[0]; if (expr.type == Exprent.Exprent_Exit) { ExitExprent exexpr = (ExitExprent)expr; if (exexpr.GetExitType() == ExitExprent.Exit_Throw && exexpr.GetValue().type == Exprent .Exprent_New) { NewExprent nexpr = (NewExprent)exexpr.GetValue(); if (Class_Assertion_Error.Equals(nexpr.GetNewType()) && nexpr.GetConstructor() != null) { return(nexpr.GetConstructor()); } } } return(null); }
private Exprent ProcessExprentRecursive(Exprent exprent) { bool replaced = true; while (replaced) { replaced = false; foreach (Exprent expr in exprent.GetAllExprents()) { Exprent retexpr = ProcessExprentRecursive(expr); if (retexpr != null) { exprent.ReplaceExprent(expr, retexpr); replaced = true; exprentReplaced = true; break; } } } if (exprent.type == Exprent.Exprent_Assignment) { AssignmentExprent @as = (AssignmentExprent)exprent; if (@as.GetRight().type == Exprent.Exprent_Function) { FunctionExprent func = (FunctionExprent)@as.GetRight(); VarType midlayer = null; if (func.GetFuncType() >= FunctionExprent.Function_I2l && func.GetFuncType() <= FunctionExprent .Function_I2s) { midlayer = func.GetSimpleCastType(); if (func.GetLstOperands()[0].type == Exprent.Exprent_Function) { func = (FunctionExprent)func.GetLstOperands()[0]; } else { return(null); } } if (func.GetFuncType() == FunctionExprent.Function_Add || func.GetFuncType() == FunctionExprent .Function_Sub) { Exprent econd = func.GetLstOperands()[0]; Exprent econst = func.GetLstOperands()[1]; if (econst.type != Exprent.Exprent_Const && econd.type == Exprent.Exprent_Const && func.GetFuncType() == FunctionExprent.Function_Add) { econd = econst; econst = func.GetLstOperands()[0]; } if (econst.type == Exprent.Exprent_Const && ((ConstExprent)econst).HasValueOne()) { Exprent left = @as.GetLeft(); VarType condtype = econd.GetExprType(); if (left.Equals(econd) && (midlayer == null || midlayer.Equals(condtype))) { FunctionExprent ret = new FunctionExprent(func.GetFuncType() == FunctionExprent.Function_Add ? FunctionExprent.Function_Ppi : FunctionExprent.Function_Mmi, econd, func.bytecode ); ret.SetImplicitType(condtype); exprentReplaced = true; return(ret); } } } } } return(null); }
private void SetNewVarIndices(VarTypeProcessor typeProcessor, DirectGraph graph, VarVersionsProcessor previousVersionsProcessor) { Dictionary <VarVersionPair, VarType> mapExprentMaxTypes = typeProcessor.GetMapExprentMaxTypes (); Dictionary <VarVersionPair, VarType> mapExprentMinTypes = typeProcessor.GetMapExprentMinTypes (); Dictionary <VarVersionPair, int> mapFinalVars = typeProcessor.GetMapFinalVars(); CounterContainer counters = DecompilerContext.GetCounterContainer(); Dictionary <VarVersionPair, int> mapVarPaar = new Dictionary <VarVersionPair, int> (); Dictionary <int, int> mapOriginalVarIndices = new Dictionary <int, int>(); // map var-version pairs on new var indexes foreach (VarVersionPair pair in new List <VarVersionPair>(mapExprentMinTypes.Keys)) { if (pair.version >= 0) { int newIndex = pair.version == 1 ? pair.var : counters.GetCounterAndIncrement(CounterContainer .Var_Counter); VarVersionPair newVar = new VarVersionPair(newIndex, 0); Sharpen.Collections.Put(mapExprentMinTypes, newVar, mapExprentMinTypes.GetOrNull( pair)); Sharpen.Collections.Put(mapExprentMaxTypes, newVar, mapExprentMaxTypes.GetOrNull( pair)); if (mapFinalVars.ContainsKey(pair)) { Sharpen.Collections.Put(mapFinalVars, newVar, Sharpen.Collections.Remove(mapFinalVars , pair)); } Sharpen.Collections.Put(mapVarPaar, pair, newIndex); Sharpen.Collections.Put(mapOriginalVarIndices, newIndex, pair.var); } } // set new vars graph.IterateExprents((Exprent exprent) => { List <Exprent> lst = exprent.GetAllExprents(true); lst.Add(exprent); foreach (Exprent expr in lst) { if (expr.type == Exprent.Exprent_Var) { VarExprent newVar = (VarExprent)expr; int?newVarIndex = mapVarPaar.GetOrNullable(new VarVersionPair(newVar)); if (newVarIndex != null) { newVar.SetIndex(newVarIndex.Value); newVar.SetVersion(0); } } else if (expr.type == Exprent.Exprent_Const) { VarType maxType = mapExprentMaxTypes.GetOrNull(new VarVersionPair(expr.id, -1)); if (maxType != null && maxType.Equals(VarType.Vartype_Char)) { ((ConstExprent)expr).SetConstType(maxType); } } } return(0); } ); if (previousVersionsProcessor != null) { Dictionary <int, int> oldIndices = previousVersionsProcessor.GetMapOriginalVarIndices (); this.mapOriginalVarIndices = new Dictionary <int, int>(mapOriginalVarIndices.Count ); foreach (KeyValuePair <int, int> entry in mapOriginalVarIndices) { int value = entry.Value; int?oldValue = oldIndices.GetOrNullable(value); value = oldValue != null ? oldValue.Value : value; Sharpen.Collections.Put(this.mapOriginalVarIndices, entry.Key, value); } } else { this.mapOriginalVarIndices = mapOriginalVarIndices; } }
private static void SimpleMerge(VarTypeProcessor typeProcessor, DirectGraph graph , StructMethod mt) { Dictionary <VarVersionPair, VarType> mapExprentMaxTypes = typeProcessor.GetMapExprentMaxTypes (); Dictionary <VarVersionPair, VarType> mapExprentMinTypes = typeProcessor.GetMapExprentMinTypes (); Dictionary <int, HashSet <int> > mapVarVersions = new Dictionary <int, HashSet <int> > (); foreach (VarVersionPair pair in mapExprentMinTypes.Keys) { if (pair.version >= 0) { // don't merge constants mapVarVersions.ComputeIfAbsent(pair.var, (int k) => new HashSet <int>()).Add(pair. version); } } bool is_method_static = mt.HasModifier(ICodeConstants.Acc_Static); Dictionary <VarVersionPair, int> mapMergedVersions = new Dictionary <VarVersionPair , int>(); foreach (KeyValuePair <int, HashSet <int> > ent in mapVarVersions) { if (ent.Value.Count > 1) { List <int> lstVersions = new List <int>(ent.Value); lstVersions.Sort(); for (int i = 0; i < lstVersions.Count; i++) { VarVersionPair firstPair = new VarVersionPair(ent.Key, lstVersions[i]); VarType firstType = mapExprentMinTypes.GetOrNull(firstPair); if (firstPair.var == 0 && firstPair.version == 1 && !is_method_static) { continue; } // don't merge 'this' variable for (int j = i + 1; j < lstVersions.Count; j++) { VarVersionPair secondPair = new VarVersionPair(ent.Key, lstVersions[j]); VarType secondType = mapExprentMinTypes.GetOrNull(secondPair); if (firstType.Equals(secondType) || (firstType.Equals(VarType.Vartype_Null) && secondType .type == ICodeConstants.Type_Object) || (secondType.Equals(VarType.Vartype_Null) && firstType.type == ICodeConstants.Type_Object)) { VarType firstMaxType = mapExprentMaxTypes.GetOrNull(firstPair); VarType secondMaxType = mapExprentMaxTypes.GetOrNull(secondPair); VarType type = firstMaxType == null ? secondMaxType : secondMaxType == null ? firstMaxType : VarType.GetCommonMinType(firstMaxType, secondMaxType); Sharpen.Collections.Put(mapExprentMaxTypes, firstPair, type); Sharpen.Collections.Put(mapMergedVersions, secondPair, firstPair.version); Sharpen.Collections.Remove(mapExprentMaxTypes, secondPair); Sharpen.Collections.Remove(mapExprentMinTypes, secondPair); if (firstType.Equals(VarType.Vartype_Null)) { Sharpen.Collections.Put(mapExprentMinTypes, firstPair, secondType); firstType = secondType; } Sharpen.Collections.Put(typeProcessor.GetMapFinalVars(), firstPair, VarTypeProcessor .Var_Non_Final); lstVersions.RemoveAtReturningValue(j); //noinspection AssignmentToForLoopParameter j--; } } } } } if (!(mapMergedVersions.Count == 0)) { UpdateVersions(graph, mapMergedVersions); } }
private static Exprent IdentifySecondaryFunctions(Exprent exprent, bool statement_level , VarProcessor varProc) { if (exprent.type == Exprent.Exprent_Function) { FunctionExprent fexpr = (FunctionExprent)exprent; switch (fexpr.GetFuncType()) { case FunctionExprent.Function_Bool_Not: { Exprent retparam = PropagateBoolNot(fexpr); if (retparam != null) { return(retparam); } break; } case FunctionExprent.Function_Eq: case FunctionExprent.Function_Ne: case FunctionExprent.Function_Gt: case FunctionExprent.Function_Ge: case FunctionExprent.Function_Lt: case FunctionExprent.Function_Le: { Exprent expr1 = fexpr.GetLstOperands()[0]; Exprent expr2 = fexpr.GetLstOperands()[1]; if (expr1.type == Exprent.Exprent_Const) { expr2 = expr1; expr1 = fexpr.GetLstOperands()[1]; } if (expr1.type == Exprent.Exprent_Function && expr2.type == Exprent.Exprent_Const) { FunctionExprent funcexpr = (FunctionExprent)expr1; ConstExprent cexpr = (ConstExprent)expr2; int functype = funcexpr.GetFuncType(); if (functype == FunctionExprent.Function_Lcmp || functype == FunctionExprent.Function_Fcmpg || functype == FunctionExprent.Function_Fcmpl || functype == FunctionExprent.Function_Dcmpg || functype == FunctionExprent.Function_Dcmpl) { int desttype = -1; int?[] destcons = mapNumComparisons.GetOrNull(fexpr.GetFuncType()); if (destcons != null) { int index = cexpr.GetIntValue() + 1; if (index >= 0 && index <= 2) { int?destcon = destcons[index]; if (destcon != null) { desttype = destcon.Value; } } } if (desttype >= 0) { return(new FunctionExprent(desttype, funcexpr.GetLstOperands(), funcexpr.bytecode )); } } } break; } } } bool replaced = true; while (replaced) { replaced = false; foreach (Exprent expr in exprent.GetAllExprents()) { Exprent retexpr = IdentifySecondaryFunctions(expr, false, varProc); if (retexpr != null) { exprent.ReplaceExprent(expr, retexpr); replaced = true; break; } } } switch (exprent.type) { case Exprent.Exprent_Function: { FunctionExprent fexpr_1 = (FunctionExprent)exprent; List <Exprent> lstOperands = fexpr_1.GetLstOperands(); switch (fexpr_1.GetFuncType()) { case FunctionExprent.Function_Xor: { for (int i = 0; i < 2; i++) { Exprent operand = lstOperands[i]; VarType operandtype = operand.GetExprType(); if (operand.type == Exprent.Exprent_Const && operandtype.type != ICodeConstants.Type_Boolean) { ConstExprent cexpr = (ConstExprent)operand; long val; if (operandtype.type == ICodeConstants.Type_Long) { val = (long)cexpr.GetValue(); } else { val = (int)cexpr.GetValue(); } if (val == -1) { List <Exprent> lstBitNotOperand = new List <Exprent>(); lstBitNotOperand.Add(lstOperands[1 - i]); return(new FunctionExprent(FunctionExprent.Function_Bit_Not, lstBitNotOperand, fexpr_1 .bytecode)); } } } break; } case FunctionExprent.Function_Eq: case FunctionExprent.Function_Ne: { if (lstOperands[0].GetExprType().type == ICodeConstants.Type_Boolean && lstOperands [1].GetExprType().type == ICodeConstants.Type_Boolean) { for (int i = 0; i < 2; i++) { if (lstOperands[i].type == Exprent.Exprent_Const) { ConstExprent cexpr = (ConstExprent)lstOperands[i]; int val = (int)cexpr.GetValue(); if ((fexpr_1.GetFuncType() == FunctionExprent.Function_Eq && val == 1) || (fexpr_1 .GetFuncType() == FunctionExprent.Function_Ne && val == 0)) { return(lstOperands[1 - i]); } else { List <Exprent> lstNotOperand = new List <Exprent>(); lstNotOperand.Add(lstOperands[1 - i]); return(new FunctionExprent(FunctionExprent.Function_Bool_Not, lstNotOperand, fexpr_1 .bytecode)); } } } } break; } case FunctionExprent.Function_Bool_Not: { if (lstOperands[0].type == Exprent.Exprent_Const) { int val = ((ConstExprent)lstOperands[0]).GetIntValue(); if (val == 0) { return(new ConstExprent(VarType.Vartype_Boolean, 1, fexpr_1.bytecode)); } else { return(new ConstExprent(VarType.Vartype_Boolean, 0, fexpr_1.bytecode)); } } break; } case FunctionExprent.Function_Iif: { Exprent expr1_1 = lstOperands[1]; Exprent expr2_1 = lstOperands[2]; if (expr1_1.type == Exprent.Exprent_Const && expr2_1.type == Exprent.Exprent_Const) { ConstExprent cexpr1 = (ConstExprent)expr1_1; ConstExprent cexpr2 = (ConstExprent)expr2_1; if (cexpr1.GetExprType().type == ICodeConstants.Type_Boolean && cexpr2.GetExprType ().type == ICodeConstants.Type_Boolean) { if (cexpr1.GetIntValue() == 0 && cexpr2.GetIntValue() != 0) { return(new FunctionExprent(FunctionExprent.Function_Bool_Not, lstOperands[0], fexpr_1 .bytecode)); } else if (cexpr1.GetIntValue() != 0 && cexpr2.GetIntValue() == 0) { return(lstOperands[0]); } } } break; } case FunctionExprent.Function_Lcmp: case FunctionExprent.Function_Fcmpl: case FunctionExprent.Function_Fcmpg: case FunctionExprent.Function_Dcmpl: case FunctionExprent.Function_Dcmpg: { int var = DecompilerContext.GetCounterContainer().GetCounterAndIncrement(CounterContainer .Var_Counter); VarType type = lstOperands[0].GetExprType(); FunctionExprent iff = new FunctionExprent(FunctionExprent.Function_Iif, Sharpen.Arrays.AsList <Exprent> (new FunctionExprent(FunctionExprent.Function_Lt, Sharpen.Arrays.AsList <Exprent>(new VarExprent (var, type, varProc), ConstExprent.GetZeroConstant(type.type)), null), new ConstExprent (VarType.Vartype_Int, -1, null), new ConstExprent(VarType.Vartype_Int, 1, null)) , null); FunctionExprent head = new FunctionExprent(FunctionExprent.Function_Eq, Sharpen.Arrays.AsList <Exprent> (new AssignmentExprent(new VarExprent(var, type, varProc), new FunctionExprent(FunctionExprent .Function_Sub, Sharpen.Arrays.AsList(lstOperands[0], lstOperands[1]), null), null ), ConstExprent.GetZeroConstant(type.type)), null); varProc.SetVarType(new VarVersionPair(var, 0), type); return(new FunctionExprent(FunctionExprent.Function_Iif, Sharpen.Arrays.AsList <Exprent>(head , new ConstExprent(VarType.Vartype_Int, 0, null), iff), fexpr_1.bytecode)); } } break; } case Exprent.Exprent_Assignment: { // check for conditional assignment AssignmentExprent asexpr = (AssignmentExprent)exprent; Exprent right = asexpr.GetRight(); Exprent left = asexpr.GetLeft(); if (right.type == Exprent.Exprent_Function) { FunctionExprent func = (FunctionExprent)right; VarType midlayer = null; if (func.GetFuncType() >= FunctionExprent.Function_I2l && func.GetFuncType() <= FunctionExprent .Function_I2s) { right = func.GetLstOperands()[0]; midlayer = func.GetSimpleCastType(); if (right.type == Exprent.Exprent_Function) { func = (FunctionExprent)right; } else { return(null); } } List <Exprent> lstFuncOperands = func.GetLstOperands(); Exprent cond = null; switch (func.GetFuncType()) { case FunctionExprent.Function_Add: case FunctionExprent.Function_And: case FunctionExprent.Function_Or: case FunctionExprent.Function_Xor: { if (left.Equals(lstFuncOperands[1])) { cond = lstFuncOperands[0]; break; } goto case FunctionExprent.Function_Sub; } case FunctionExprent.Function_Sub: case FunctionExprent.Function_Mul: case FunctionExprent.Function_Div: case FunctionExprent.Function_Rem: case FunctionExprent.Function_Shl: case FunctionExprent.Function_Shr: case FunctionExprent.Function_Ushr: { if (left.Equals(lstFuncOperands[0])) { cond = lstFuncOperands[1]; } break; } } if (cond != null && (midlayer == null || midlayer.Equals(cond.GetExprType()))) { asexpr.SetRight(cond); asexpr.SetCondType(func.GetFuncType()); } } break; } case Exprent.Exprent_Invocation: { if (!statement_level) { // simplify if exprent is a real expression. The opposite case is pretty absurd, can still happen however (and happened at least once). Exprent retexpr = ConcatenationHelper.ContractStringConcat(exprent); if (!exprent.Equals(retexpr)) { return(retexpr); } } break; } } return(null); }
public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer) { VarType leftType = left.GetExprType(); VarType rightType = right.GetExprType(); bool fieldInClassInit = false; bool hiddenField = false; if (left.type == Exprent.Exprent_Field) { // first assignment to a final field. Field name without "this" in front of it FieldExprent field = (FieldExprent)left; ClassesProcessor.ClassNode node = ((ClassesProcessor.ClassNode)DecompilerContext. GetProperty(DecompilerContext.Current_Class_Node)); if (node != null) { StructField fd = node.classStruct.GetField(field.GetName(), field.GetDescriptor() .descriptorString); if (fd != null) { if (field.IsStatic() && fd.HasModifier(ICodeConstants.Acc_Final)) { fieldInClassInit = true; } if (node.GetWrapper() != null && node.GetWrapper().GetHiddenMembers().Contains(InterpreterUtil .MakeUniqueKey(fd.GetName(), fd.GetDescriptor()))) { hiddenField = true; } } } } if (hiddenField) { return(new TextBuffer()); } TextBuffer buffer = new TextBuffer(); if (fieldInClassInit) { buffer.Append(((FieldExprent)left).GetName()); } else { buffer.Append(left.ToJava(indent, tracer)); } if (right.type == Exprent_Const) { ((ConstExprent)right).AdjustConstType(leftType); } TextBuffer res = right.ToJava(indent, tracer); if (condType == Condition_None && !leftType.IsSuperset(rightType) && (rightType.Equals (VarType.Vartype_Object) || leftType.type != ICodeConstants.Type_Object)) { if (right.GetPrecedence() >= FunctionExprent.GetPrecedence(FunctionExprent.Function_Cast )) { res.Enclose("(", ")"); } res.Prepend("(" + ExprProcessor.GetCastTypeName(leftType) + ")"); } buffer.Append(condType == Condition_None ? " = " : Operators[condType]).Append(res ); tracer.AddMapping(bytecode); return(buffer); }
public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer) { bool literal = DecompilerContext.GetOption(IFernflowerPreferences.Literals_As_Is ); bool ascii = DecompilerContext.GetOption(IFernflowerPreferences.Ascii_String_Characters ); tracer.AddMapping(bytecode); if (constType.type != ICodeConstants.Type_Null && value == null) { return(new TextBuffer(ExprProcessor.GetCastTypeName(constType))); } switch (constType.type) { case ICodeConstants.Type_Boolean: { return(new TextBuffer(((int)value != 0).ToString())); } case ICodeConstants.Type_Char: { int val = (int)value; string ret = Char_Escapes.GetOrNull(val); if (ret == null) { char c = (char)val; if (IsPrintableAscii(c) || !ascii && TextUtil.IsPrintableUnicode(c)) { ret = c.ToString(); } else { ret = TextUtil.CharToUnicodeLiteral(c); } } return(new TextBuffer(ret).Enclose("'", "'")); } case ICodeConstants.Type_Byte: case ICodeConstants.Type_Bytechar: case ICodeConstants.Type_Short: case ICodeConstants.Type_Shortchar: case ICodeConstants.Type_Int: { int intVal = (int)value; if (!literal) { if (intVal == int.MaxValue) { return(new FieldExprent("MAX_VALUE", "java/lang/Integer", true, null, FieldDescriptor .Integer_Descriptor, bytecode).ToJava(0, tracer)); } else if (intVal == int.MinValue) { return(new FieldExprent("MIN_VALUE", "java/lang/Integer", true, null, FieldDescriptor .Integer_Descriptor, bytecode).ToJava(0, tracer)); } } return(new TextBuffer(value.ToString())); } case ICodeConstants.Type_Long: { long longVal = (long)value; if (!literal) { if (longVal == long.MaxValue) { return(new FieldExprent("MAX_VALUE", "java/lang/Long", true, null, FieldDescriptor .Long_Descriptor, bytecode).ToJava(0, tracer)); } else if (longVal == long.MinValue) { return(new FieldExprent("MIN_VALUE", "java/lang/Long", true, null, FieldDescriptor .Long_Descriptor, bytecode).ToJava(0, tracer)); } } return(new TextBuffer(value.ToString()).Append('L')); } case ICodeConstants.Type_Float: { float floatVal = (float)value; if (!literal) { if (float.IsNaN(floatVal)) { return(new FieldExprent("NaN", "java/lang/Float", true, null, FieldDescriptor.Float_Descriptor , bytecode).ToJava(0, tracer)); } else if (floatVal == float.PositiveInfinity) { return(new FieldExprent("POSITIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor .Float_Descriptor, bytecode).ToJava(0, tracer)); } else if (floatVal == float.NegativeInfinity) { return(new FieldExprent("NEGATIVE_INFINITY", "java/lang/Float", true, null, FieldDescriptor .Float_Descriptor, bytecode).ToJava(0, tracer)); } else if (floatVal == float.MaxValue) { return(new FieldExprent("MAX_VALUE", "java/lang/Float", true, null, FieldDescriptor .Float_Descriptor, bytecode).ToJava(0, tracer)); } else if (floatVal == float.MinValue) { return(new FieldExprent("MIN_VALUE", "java/lang/Float", true, null, FieldDescriptor .Float_Descriptor, bytecode).ToJava(0, tracer)); } } else if (float.IsNaN(floatVal)) { return(new TextBuffer("0.0F / 0.0")); } else if (floatVal == float.PositiveInfinity) { return(new TextBuffer("1.0F / 0.0")); } else if (floatVal == float.NegativeInfinity) { return(new TextBuffer("-1.0F / 0.0")); } return(new TextBuffer(value.ToString()).Append('F')); } case ICodeConstants.Type_Double: { double doubleVal = (double)value; if (!literal) { if (double.IsNaN(doubleVal)) { return(new FieldExprent("NaN", "java/lang/Double", true, null, FieldDescriptor.Double_Descriptor , bytecode).ToJava(0, tracer)); } else if (doubleVal == double.PositiveInfinity) { return(new FieldExprent("POSITIVE_INFINITY", "java/lang/Double", true, null, FieldDescriptor .Double_Descriptor, bytecode).ToJava(0, tracer)); } else if (doubleVal == double.NegativeInfinity) { return(new FieldExprent("NEGATIVE_INFINITY", "java/lang/Double", true, null, FieldDescriptor .Double_Descriptor, bytecode).ToJava(0, tracer)); } else if (doubleVal == double.MaxValue) { return(new FieldExprent("MAX_VALUE", "java/lang/Double", true, null, FieldDescriptor .Double_Descriptor, bytecode).ToJava(0, tracer)); } else if (doubleVal == double.MinValue) { return(new FieldExprent("MIN_VALUE", "java/lang/Double", true, null, FieldDescriptor .Double_Descriptor, bytecode).ToJava(0, tracer)); } } else if (double.IsNaN(doubleVal)) { return(new TextBuffer("0.0D / 0.0")); } else if (doubleVal == double.PositiveInfinity) { return(new TextBuffer("1.0D / 0.0")); } else if (doubleVal == double.NegativeInfinity) { return(new TextBuffer("-1.0D / 0.0")); } return(new TextBuffer(value.ToString()).Append('D')); } case ICodeConstants.Type_Null: { return(new TextBuffer("null")); } case ICodeConstants.Type_Object: { if (constType.Equals(VarType.Vartype_String)) { return(new TextBuffer(ConvertStringToJava(value.ToString(), ascii)).Enclose("\"", "\"")); } else if (constType.Equals(VarType.Vartype_Class)) { string stringVal = value.ToString(); VarType type = new VarType(stringVal, !stringVal.StartsWith("[")); return(new TextBuffer(ExprProcessor.GetCastTypeName(type)).Append(".class")); } break; } } throw new Exception("invalid constant type: " + constType); }
private BitSet GetAmbiguousParameters() { StructClass cl = DecompilerContext.GetStructContext().GetClass(classname); if (cl == null) { return(Empty_Bit_Set); } // check number of matches List <MethodDescriptor> matches = new List <MethodDescriptor>(); foreach (StructMethod mt in cl.GetMethods()) { if (name.Equals(mt.GetName())) { MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt.GetDescriptor()); if ([email protected] == [email protected]) { for (int i = 0; i < [email protected]; i++) { if (md.@params[i].typeFamily != descriptor.@params[i].typeFamily) { goto nextMethod_continue; } } matches.Add(md); } } } nextMethod_break :; nextMethod_continue : if (matches.Count == 1) { return(Empty_Bit_Set); } // check if a call is unambiguous StructMethod mt_1 = cl.GetMethod(InterpreterUtil.MakeUniqueKey(name, stringDescriptor )); if (mt_1 != null) { MethodDescriptor md = MethodDescriptor.ParseDescriptor(mt_1.GetDescriptor()); if ([email protected] == lstParameters.Count) { bool exact = true; for (int i = 0; i < [email protected]; i++) { if (!md.@params[i].Equals(lstParameters[i].GetExprType())) { exact = false; break; } } if (exact) { return(Empty_Bit_Set); } } } // mark parameters BitSet ambiguous = new BitSet([email protected]); for (int i = 0; i < [email protected]; i++) { VarType paramType = descriptor.@params[i]; foreach (MethodDescriptor md in matches) { if (!paramType.Equals(md.@params[i])) { ambiguous.Set(i); break; } } } return(ambiguous); }
public override TextBuffer ToJava(int indent, BytecodeMappingTracer tracer) { TextBuffer buf = new TextBuffer(); string super_qualifier = null; bool isInstanceThis = false; tracer.AddMapping(bytecode); if (instance is InvocationExprent) { ((InvocationExprent)instance).MarkUsingBoxingResult(); } if (isStatic__) { if (IsBoxingCall() && canIgnoreBoxing) { // process general "boxing" calls, e.g. 'Object[] data = { true }' or 'Byte b = 123' // here 'byte' and 'short' values do not need an explicit narrowing type cast ExprProcessor.GetCastedExprent(lstParameters[0], descriptor.@params[0], buf, indent , false, false, false, false, tracer); return(buf); } ClassesProcessor.ClassNode node = (ClassesProcessor.ClassNode)DecompilerContext.GetProperty (DecompilerContext.Current_Class_Node); if (node == null || !classname.Equals(node.classStruct.qualifiedName)) { buf.Append(DecompilerContext.GetImportCollector().GetShortNameInClassContext(ExprProcessor .BuildJavaClassName(classname))); } } else { if (instance != null && instance.type == Exprent.Exprent_Var) { VarExprent instVar = (VarExprent)instance; VarVersionPair varPair = new VarVersionPair(instVar); VarProcessor varProc = instVar.GetProcessor(); if (varProc == null) { MethodWrapper currentMethod = (MethodWrapper)DecompilerContext.GetProperty(DecompilerContext .Current_Method_Wrapper); if (currentMethod != null) { varProc = currentMethod.varproc; } } string this_classname = null; if (varProc != null) { this_classname = varProc.GetThisVars().GetOrNull(varPair); } if (this_classname != null) { isInstanceThis = true; if (invocationTyp == Invoke_Special) { if (!classname.Equals(this_classname)) { // TODO: direct comparison to the super class? StructClass cl = DecompilerContext.GetStructContext().GetClass(classname); bool isInterface = cl != null && cl.HasModifier(ICodeConstants.Acc_Interface); super_qualifier = !isInterface ? this_classname : classname; } } } } if (functype == Typ_General) { if (super_qualifier != null) { TextUtil.WriteQualifiedSuper(buf, super_qualifier); } else if (instance != null) { TextBuffer res = instance.ToJava(indent, tracer); if (IsUnboxingCall()) { // we don't print the unboxing call - no need to bother with the instance wrapping / casting buf.Append(res); return(buf); } VarType rightType = instance.GetExprType(); VarType leftType = new VarType(ICodeConstants.Type_Object, 0, classname); if (rightType.Equals(VarType.Vartype_Object) && !leftType.Equals(rightType)) { buf.Append("((").Append(ExprProcessor.GetCastTypeName(leftType)).Append(")"); if (instance.GetPrecedence() >= FunctionExprent.GetPrecedence(FunctionExprent.Function_Cast )) { res.Enclose("(", ")"); } buf.Append(res).Append(")"); } else if (instance.GetPrecedence() > GetPrecedence()) { buf.Append("(").Append(res).Append(")"); } else { buf.Append(res); } } } } switch (functype) { case Typ_General: { if (VarExprent.Var_Nameless_Enclosure.Equals(buf.ToString())) { buf = new TextBuffer(); } if (buf.Length() > 0) { buf.Append("."); } buf.Append(name); if (invocationTyp == Invoke_Dynamic) { buf.Append("<invokedynamic>"); } buf.Append("("); break; } case Typ_Clinit: { throw new Exception("Explicit invocation of " + ICodeConstants.Clinit_Name); } case Typ_Init: { if (super_qualifier != null) { buf.Append("super("); } else if (isInstanceThis) { buf.Append("this("); } else if (instance != null) { buf.Append(instance.ToJava(indent, tracer)).Append(".<init>("); } else { throw new Exception("Unrecognized invocation of " + ICodeConstants.Init_Name); } break; } } List <VarVersionPair> mask = null; bool isEnum = false; if (functype == Typ_Init) { ClassesProcessor.ClassNode newNode = DecompilerContext.GetClassProcessor().GetMapRootClasses ().GetOrNull(classname); if (newNode != null) { mask = ExprUtil.GetSyntheticParametersMask(newNode, stringDescriptor, lstParameters .Count); isEnum = newNode.classStruct.HasModifier(ICodeConstants.Acc_Enum) && DecompilerContext .GetOption(IFernflowerPreferences.Decompile_Enum); } } BitSet setAmbiguousParameters = GetAmbiguousParameters(); // omit 'new Type[] {}' for the last parameter of a vararg method call if (lstParameters.Count == [email protected] && IsVarArgCall()) { Exprent lastParam = lstParameters[lstParameters.Count - 1]; if (lastParam.type == Exprent_New && lastParam.GetExprType().arrayDim >= 1) { ((NewExprent)lastParam).SetVarArgParam(true); } } bool firstParameter = true; int start = isEnum ? 2 : 0; for (int i = start; i < lstParameters.Count; i++) { if (mask == null || mask[i] == null) { TextBuffer buff = new TextBuffer(); bool ambiguous = setAmbiguousParameters.Get(i); // 'byte' and 'short' literals need an explicit narrowing type cast when used as a parameter ExprProcessor.GetCastedExprent(lstParameters[i], descriptor.@params[i], buff, indent , true, ambiguous, true, true, tracer); // the last "new Object[0]" in the vararg call is not printed if (buff.Length() > 0) { if (!firstParameter) { buf.Append(", "); } buf.Append(buff); } firstParameter = false; } } buf.Append(')'); return(buf); }