Exemple #1
0
        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 bool ChangeExprentType(Exprent exprent, VarType newType, int minMax)
        {
            bool res = true;

            switch (exprent.type)
            {
            case Exprent.Exprent_Const:
            {
                ConstExprent constExpr = (ConstExprent)exprent;
                VarType      constType = constExpr.GetConstType();
                if (newType.typeFamily > ICodeConstants.Type_Family_Integer || constType.typeFamily
                    > ICodeConstants.Type_Family_Integer)
                {
                    return(true);
                }
                else if (newType.typeFamily == ICodeConstants.Type_Family_Integer)
                {
                    VarType minInteger = new ConstExprent((int)constExpr.GetValue(), false, null).GetConstType
                                             ();
                    if (minInteger.IsStrictSuperset(newType))
                    {
                        newType = minInteger;
                    }
                }
                goto case Exprent.Exprent_Var;
            }

            case Exprent.Exprent_Var:
            {
                VarVersionPair pair = null;
                if (exprent.type == Exprent.Exprent_Const)
                {
                    pair = new VarVersionPair(((ConstExprent)exprent).id, -1);
                }
                else if (exprent.type == Exprent.Exprent_Var)
                {
                    pair = new VarVersionPair((VarExprent)exprent);
                }
                if (minMax == 0)
                {
                    // min
                    VarType currentMinType = mapExprentMinTypes.GetOrNull(pair);
                    VarType newMinType;
                    if (currentMinType == null || newType.typeFamily > currentMinType.typeFamily)
                    {
                        newMinType = newType;
                    }
                    else if (newType.typeFamily < currentMinType.typeFamily)
                    {
                        return(true);
                    }
                    else
                    {
                        newMinType = VarType.GetCommonSupertype(currentMinType, newType);
                    }
                    Sharpen.Collections.Put(mapExprentMinTypes, pair, newMinType);
                    if (exprent.type == Exprent.Exprent_Const)
                    {
                        ((ConstExprent)exprent).SetConstType(newMinType);
                    }
                    if (currentMinType != null && (newMinType.typeFamily > currentMinType.typeFamily ||
                                                   newMinType.IsStrictSuperset(currentMinType)))
                    {
                        return(false);
                    }
                }
                else
                {
                    // max
                    VarType currentMaxType = mapExprentMaxTypes.GetOrNull(pair);
                    VarType newMaxType;
                    if (currentMaxType == null || newType.typeFamily < currentMaxType.typeFamily)
                    {
                        newMaxType = newType;
                    }
                    else if (newType.typeFamily > currentMaxType.typeFamily)
                    {
                        return(true);
                    }
                    else
                    {
                        newMaxType = VarType.GetCommonMinType(currentMaxType, newType);
                    }
                    Sharpen.Collections.Put(mapExprentMaxTypes, pair, newMaxType);
                }
                break;
            }

            case Exprent.Exprent_Assignment:
            {
                return(ChangeExprentType(((AssignmentExprent)exprent).GetRight(), newType, minMax
                                         ));
            }

            case Exprent.Exprent_Function:
            {
                FunctionExprent func = (FunctionExprent)exprent;
                switch (func.GetFuncType())
                {
                case FunctionExprent.Function_Iif:
                {
                    // FIXME:
                    res = ChangeExprentType(func.GetLstOperands()[1], newType, minMax) & ChangeExprentType
                              (func.GetLstOperands()[2], newType, minMax);
                    break;
                }

                case FunctionExprent.Function_And:
                case FunctionExprent.Function_Or:
                case FunctionExprent.Function_Xor:
                {
                    res = ChangeExprentType(func.GetLstOperands()[0], newType, minMax) & ChangeExprentType
                              (func.GetLstOperands()[1], newType, minMax);
                    break;
                }
                }
                break;
            }
            }
            return(res);
        }