Esempio n. 1
0
 private static void FixStructs(AinFile ainFile)
 {
     foreach (var structInfo in ainFile.Structs)
     {
         structInfo.NumberOfMembers = structInfo.Members.Count;
         var constructor = ainFile.GetFunction(structInfo.Name + "@0");
         var destructor  = ainFile.GetFunction(structInfo.Name + "@1");
         if (constructor != null)
         {
             structInfo.Constructor = constructor.Index;
         }
         if (destructor != null)
         {
             structInfo.Destructor = destructor.Index;
         }
     }
 }
Esempio n. 2
0
        public void projectWriter_BeforeWritingInstruction(object sender, InstructionInfoEventArgs e)
        {
            var instructionInfo = e.InstructionInfo;

            if (instructionInfo.instruction == Instruction.MSG)
            {
                string messageText = e.Text;
                //string messageText = ainFile.Messages[instructionInfo.word1];
                messageText = CombineRemainingText(messageText);
                e.Text      = messageText;
                HandleMessage(e, messageText);
            }
            else if (instructionInfo.instruction == Instruction.CALLFUNC)
            {
                var    function     = ainFile.GetFunction(instructionInfo.word1);
                string functionName = null;
                if (function != null)
                {
                    functionName = function.Name;
                }
                if (functionName == NextLineFunctionName)
                {
                    if (remainingText != "")
                    {
                        e.Handled = true;
                    }
                    else
                    {
                        NextLine(e);
                    }
                }
                else if (functionName == NextMessageFunctionName)
                {
                    if (remainingText != "")
                    {
                        while (remainingText != "")
                        {
                            e.Handled = true;
                            HandleMessage(e, remainingText);
                        }

                        GenerateNextMessage(e);
                    }
                    else
                    {
                        NextMessage();
                    }
                }
                else if (ReduceMarginFunctionNames.Contains(functionName))
                {
                    this.maxCharactersPerLine = this.MaxCharactersPerLineReduced;
                }
            }
        }
        public Variable[] GetVariables(AinFile ainFile)
        {
            List <Variable> list = new List <Variable>();

            foreach (var variableName in VariableNames)
            {
                int dotPosition = variableName.IndexOf('.');
                if (dotPosition == -1)
                {
                    dotPosition = variableName.Length;
                }
                if (dotPosition > 0)
                {
                    string functionName  = variableName.Substring(0, dotPosition);
                    string parameterName = "";
                    if (dotPosition + 1 <= variableName.Length)
                    {
                        parameterName = variableName.Substring(dotPosition + 1);
                    }

                    var function = ainFile.GetFunction(functionName);
                    if (function != null)
                    {
                        Variable variable = null;
                        for (int i = 0; i < function.ParameterCount; i++)
                        {
                            if (function.Parameters[i].Name == parameterName)
                            {
                                variable = function.Parameters[i];
                                break;
                            }
                        }
                        if (variable == null)
                        {
                            int variableIndex = 0;
                            if (!int.TryParse(parameterName, out variableIndex))
                            {
                                variableIndex = 0;
                            }
                            variable = function.GetNonVoidFunctionParameter(variableIndex) as Variable;
                        }

                        if (variable != null)
                        {
                            list.Add((Variable)variable);
                        }
                    }
                }
            }
            return(list.ToArray());
        }
        //private static bool MatchFunction(AinFile ainFile, WordWrapOptions2 wordWrapOptions, int maxCharactersPerLineNormal, int maxCharactersPerLineReduced, string functionName, params DataType[] dataTypes)
        //{
        //    var function = ainFile.GetFunction(functionName);
        //    if (function != null && function.ParameterCount == dataTypes.Length && function.Parameters.Take(function.ParameterCount).Select(a => a.DataType).SequenceEqual(dataTypes))
        //    {
        //        //if we specified values for the max lengths, set them
        //        if (maxCharactersPerLineNormal > 0)
        //        {
        //            wordWrapOptions.MaxCharactersPerLineNormal = maxCharactersPerLineNormal;
        //        }
        //        if (maxCharactersPerLineReduced > 0)
        //        {
        //            wordWrapOptions.MaxCharactersPerLineReduced = maxCharactersPerLineReduced;
        //        }

        //        //set the function name
        //        wordWrapOptions.ReduceMarginFunctionName = functionName;

        //        //indicate success
        //        return true;
        //    }
        //    return false;
        //}

        private static bool ContainsFunction(AinFile ainFile, string functionName, params object[] dataTypesAndParamaterNames)
        {
            var func = ainFile.GetFunction(functionName);

            if (func == null)
            {
                return(false);
            }
            if ((dataTypesAndParamaterNames.Length & 1) != 0)
            {
                throw new ArgumentException("Number of parameter for dataTypesAndParameterNames must be even");
            }

            if (func.ParameterCount == 0 && dataTypesAndParamaterNames.Length == 0)
            {
                return(true);
            }

            for (int i = 0; i + 1 < dataTypesAndParamaterNames.Length; i += 2)
            {
                DataType?dataType      = dataTypesAndParamaterNames[i] as DataType?;
                string   parameterName = dataTypesAndParamaterNames[i + 1] as string;

                if (dataType == null || parameterName == null)
                {
                    throw new ArgumentException("Wrong type for data type or parameter name");
                }

                var arg = func.GetNonVoidFunctionParameter(i / 2);
                if (arg == null)
                {
                    return(false);
                }

                if (dataType == arg.DataType && parameterName == arg.Name)
                {
                }
                else
                {
                    return(false);
                }
            }
            return(true);
        }
        /// <summary>
        /// Checks if a variable object is a reference to a variable registered in the AinFile, and returns the original variable from the AinFile if it exists, otherwise returns null.
        /// </summary>
        /// <param name="variable">The variable to find</param>
        /// <param name="ainFile">The AinFile to find the variable in.</param>
        /// <returns>returns the original variable from the AinFile if it exists, otherwise returns null</returns>
        public static IVariable Canonicalize(this IVariable variable, AinFile ainFile)
        {
            int index       = variable.Index;
            int parentIndex = -1;

            if (variable == null || ainFile == null)
            {
                return(null);
            }
            var root = variable.Root;

            var parent = variable.Parent;

            if (parent != null)
            {
                parentIndex = parent.Index;
            }

            if (root == ainFile || root == null)
            {
                if (parent is Function)
                {
                    if (parent.Name.StartsWith("system."))
                    {
                        return(AinFile.GetSystemCallParameter(parentIndex, index));
                    }
                    return(ainFile.GetFunctionParameter(parentIndex, index));
                }
                if (parent is Struct)
                {
                    return(ainFile.GetStructMember(parentIndex, index));
                }
                if (variable is Global)
                {
                    return(ainFile.GetGlobal(index));
                }
                if (parent is FunctionType)
                {
                    return(ainFile.GetFuncTypeParameter(parentIndex, index));
                }
                if (parent is HllFunction)
                {
                    if (parent.Parent != null)
                    {
                        return(ainFile.GetLibraryFunctionParameter(parent.Parent.Index, parentIndex, index));
                    }
                    else
                    {
                        return(null);
                    }
                }
                if (variable is Function)
                {
                    if (variable.Name.StartsWith("system."))
                    {
                        return(AinFile.GetSystemCall(index));
                    }
                    return(ainFile.GetFunction(index));
                }
                if (variable is Struct)
                {
                    return(ainFile.GetStruct(index));
                }
                if (variable is HllFunction)
                {
                    return(ainFile.GetLibraryFunction(parentIndex, index));
                }
                if (variable is FunctionType)
                {
                    return(ainFile.GetFuncType(index));
                }
            }
            else
            {
                if (parent is Function)
                {
                    if (parent.Name.StartsWith("system."))
                    {
                        return(AinFile.GetSystemCallParameter(parentIndex, index));
                    }
                    return(ainFile.GetFunctionParameter(parent.Name, variable.Name));
                }
                if (variable is Global)
                {
                    return(ainFile.GetGlobal(variable.Name));
                }
                if (parent is Struct)
                {
                    return(ainFile.GetStructMember(parent.Name, variable.Name));
                }
                if (parent is FunctionType)
                {
                    return(ainFile.GetFuncTypeParameter(parent.Name, variable.Index));
                }
                if (parent is HllFunction)
                {
                    if (parent.Parent != null)
                    {
                        return(ainFile.GetLibraryFunctionParameter(parent.Parent.Name, parent.Name, index));
                    }
                    else
                    {
                        return(null);
                    }
                }
                if (variable is Function)
                {
                    if (variable.Name.StartsWith("system."))
                    {
                        return(AinFile.GetSystemCall(index));
                    }
                    return(ainFile.GetFunction(variable.Name));
                }
                if (variable is Struct)
                {
                    return(ainFile.GetStruct(variable.Name));
                }
                if (variable is HllFunction)
                {
                    return(ainFile.GetLibraryFunction(parent.Name, variable.Name));
                }
                if (variable is FunctionType)
                {
                    return(ainFile.GetFuncType(variable.Name));
                }
            }
            return(null);
        }
        public static void DoRance01(AinFile ainFile, TextImportExport exportImport)
        {
            //TEMPORARY CODE FOR RANCE 01 NAME EXTRACTION
            var dic = new Dictionary <string, string>();

            dic["*"]          = "*";
            dic["*/B"]        = "*";
            dic["**"]         = "**";
            dic["**/B"]       = "**";
            dic["***"]        = "***";
            dic["TADA"]       = "TADA";
            dic["アイ"]         = "Ai";
            dic["アキ"]         = "Aki";
            dic["アリス"]        = "Alice";
            dic["イェリコ"]       = "Yeriko";
            dic["ウィリス"]       = "Willis";
            dic["ウェンズディング"]   = "Wendsding";
            dic["ウェンズディング/B"] = "Wendsding/B";
            dic["エンエン"]       = "Enen";
            dic["カルピス"]       = "Calpis";
            dic["キース"]        = "Keith";
            dic["クリン"]        = "Kurin";
            dic["シィル"]        = "Sill";
            dic["ジャン"]        = "Jean";
            dic["スアマ"]        = "Suama";
            dic["ニウ"]         = "Niu";
            dic["ネカイ"]        = "Nekai";
            dic["ハイジ"]        = "Heidi";
            dic["パティ"]        = "Pattie";
            dic["パルプテンクス"]    = "Pulptenks";
            dic["ヒカリ"]        = "Hikari";
            dic["ブリティシュ"]     = "British";
            dic["ボブザ"]        = "Bobza";
            dic["マリス"]        = "Maris";
            dic["ミ"]          = "Mi";
            dic["ミリー"]        = "Milly";
            dic["ムララ"]        = "Murara";
            dic["メナド"]        = "Menad";
            dic["ユキ"]         = "Yuki";
            dic["ユラン"]        = "Yulang";
            dic["ライハルト"]      = "Reichardt";
            dic["ラベンダー"]      = "Lavender";
            dic["ランス"]        = "Rance";
            dic["リア"]         = "Lia";
            dic["ルイス"]        = "Luis";
            dic["魚介"]         = "Gyokai";
            dic["奈美"]         = "Nami";
            dic["忍者"]         = "Ninja";
            dic["美樹"]         = "Miki";
            dic["変態ネズミ"]      = "Pervert Mouse";
            dic["諭吉"]         = "Yukichi";
            dic["葉月"]         = "Hazuki";

            dic["DJC++"]         = "DJC++";
            dic["TADA/1"]        = "TADA";
            dic["TADA/2"]        = "TADA";
            dic["TADA/3"]        = "TADA";
            dic["TADA/ウィリス"]     = "Willis";
            dic["TADA/ハイジ"]      = "Heidi";
            dic["TADA/パティ"]      = "Pattie";
            dic["TADA/パルプテンクス"]  = "Pulptenks";
            dic["TADA/ラベンダー"]    = "Lavender";
            dic["TADA/葉月"]       = "Hazuki";
            dic["ふみゃ"]           = "Fumya";
            dic["アイ/基本"]         = "Ai";
            dic["アキ/基本"]         = "Aki";
            dic["アリスマン/基本"]      = "Alice man";
            dic["イェリコ/基本"]       = "Yeriko";
            dic["イェリコ/通せんぼ"]     = "Yeriko";
            dic["ウィリス/基本"]       = "Willis";
            dic["キース/基本/遠距離"]    = "Keith";
            dic["クリン/基本"]        = "Kurin";
            dic["シィル/学生服"]       = "Sill";
            dic["シィル/基本"]        = "Sill";
            dic["ジャン/基本"]        = "Jean";
            dic["ネカイ/基本"]        = "Nekai";
            dic["ハイジ/基本"]        = "Heidi";
            dic["ハイジ/基本/盗む"]     = "Heidi";
            dic["パティ/基本"]        = "Pattie";
            dic["パルプテンクス/基本"]    = "Pulptenks";
            dic["パルプテンクス/救出前"]   = "Pulptenks";
            dic["ヒカリ/基本"]        = "Hikari";
            dic["ブリティシュ/基本"]     = "British";
            dic["ブリティシュ/基本/泣く"]  = "British";
            dic["ボブザ/基本"]        = "Bobza";
            dic["マリス/学生服"]       = "Maris";
            dic["マリス/基本"]        = "Maris";
            dic["ミ/基本"]          = "Mi";
            dic["ミリー/眼鏡"]        = "Milly";
            dic["ミリー/眼帯"]        = "Milly";
            dic["ミリー/基本"]        = "Milly";
            dic["ムララ/基本"]        = "Murara";
            dic["メナド/基本"]        = "Menad";
            dic["ユキ/基本"]         = "Yuki";
            dic["ユラン/基本"]        = "Yulang";
            dic["ユラン/私服"]        = "Yulang";
            dic["ユラン/私服/レイプ後"]   = "Yulang";
            dic["ラベンダー/基本"]      = "Lavender";
            dic["ラベンダー/基本/泣く"]   = "Lavender";
            dic["リア/基本"]         = "Lia";
            dic["ルイス/基本"]        = "Luis";
            dic["魚介"]            = "Gyokai";
            dic["都市守備隊/基本"]      = "City defense corps";
            dic["都市守備隊/基本/B"]    = "City defense corps";
            dic["盗賊団/基本"]        = "Band of thieves";
            dic["盗賊団/基本/B"]      = "Band of thieves";
            dic["奈美/基本"]         = "Nami";
            dic["忍者/学生服"]        = "Ninja";
            dic["忍者/学生服/驚く"]     = "Ninja";
            dic["忍者/学生服/笑う"]     = "Ninja";
            dic["忍者/基本"]         = "Ninja";
            dic["汎用女生徒/基本"]      = "Generic schoolgirl";
            dic["汎用女生徒/基本/B"]    = "Generic schoolgirl";
            dic["美樹/基本"]         = "Miki";
            dic["変態ネズミ/基本"]      = "Pervert Mouse";
            dic["葉月/ボディペイント"]    = "Hazuki";
            dic["葉月/ボディペイント/笑う"] = "Hazuki";
            dic["葉月/基本"]         = "Hazuki";
            dic["葉月/基本/笑う"]      = "Hazuki";
            dic["葉月/脱ぐ04"]       = "Hazuki";
            dic["葉月/脱ぐ04/笑う"]    = "Hazuki";
            dic["葉月/脱ぐ06"]       = "Hazuki";
            dic["葉月/脱ぐ06/笑う"]    = "Hazuki";
            dic["葉月/脱ぐ07"]       = "Hazuki";
            dic["葉月/脱ぐ07/笑う"]    = "Hazuki";
            dic["葉月/脱ぐ08"]       = "Hazuki";
            dic["葉月/脱ぐ08/笑う"]    = "Hazuki";

            var func      = ainFile.GetFunction("●名札");
            var parameter = func.Parameters[0];

            var func2      = ainFile.GetFunction("●立ち絵");
            var parameter2 = func2.Parameters[0];

            exportImport.AnnotateParameterWithStrings(dic, parameter, parameter2);
        }
        internal void ExportFiles(string destinationPath)
        {
            ainFile.FindFunctionTypes();
            stopwatch.Start();

            var encoding   = Extensions.BinaryEncoding;
            var enumerator = new FunctionEnumerator(this.ainFile);
            var results    = enumerator.GetFilesAndFunctions();
            HashSet <Struct> UnvisitedStructs = new HashSet <Struct>(ainFile.Structs);
            HashSet <int>    VisitedFunctions = new HashSet <int>();
            int functionsVisited = 0;
            int totalFunctions   = ainFile.Functions.Count;

            codeDisplayOptions.DisplayDefaultValuesForMethods = false;
            var displayer = new ExpressionDisplayer(ainFile, codeDisplayOptions);

            StringBuilder mainIncludeFile = new StringBuilder();

            mainIncludeFile.AppendLine("Source = {");
            mainIncludeFile.AppendLine("\t\"constants.jaf\",");
            mainIncludeFile.AppendLine("\t\"classes.jaf\",");
            mainIncludeFile.AppendLine("\t\"globals.jaf\",");

            this.SeenFilenames.Add("classes.jaf");
            this.SeenFilenames.Add("globals.jaf");
            this.SeenFilenames.Add("constants.jaf");
            this.SeenFilenames.Add("HLL\\hll.inc");

            if (ainFile.Libraries.Count > 0)
            {
                mainIncludeFile.AppendLine("\t\"HLL\\hll.inc\",");
            }

            foreach (var fileNode in results)
            {
                string fileName = fileNode.name.Replace("\r", "\\r").Replace("\n", "\\n");  //fix filenames that went through bad tools
                if (fileNode.children.Count > 0)
                {
                    using (FileStream fs = CreateFileUnique(ref fileName, destinationPath))
                    {
                        mainIncludeFile.AppendLine("\t\"" + fileName + "\",");

                        using (var streamWriter = new StreamWriter(fs, encoding))
                        {
                            foreach (var functionNode in fileNode.children)
                            {
                                if (backgroundWorker != null)
                                {
                                    if (backgroundWorker.CancellationPending == true)
                                    {
                                        //abort
                                        return;
                                    }
                                }

                                int functionNumber = functionNode.id;
                                var function       = ainFile.GetFunction(functionNumber);

                                if (function.ToString().Contains("SP_SET_CG_REAL"))
                                {
                                    Console.WriteLine("SP_SET_CG_REAL");
                                }

                                if (!VisitedFunctions.Contains(functionNumber))
                                {
                                    VisitedFunctions.Add(functionNumber);
                                    if (this.backgroundWorker != null && stopwatch.ElapsedTime >= 250)
                                    {
                                        stopwatch.Start();
                                        backgroundWorker.ReportProgress(100 * functionsVisited / totalFunctions,
                                                                        "Function " + functionNumber.ToString() + " of " + totalFunctions.ToString() +
                                                                        ", currently decompiling" + Environment.NewLine + function.Name);
                                    }

                                    if (function.Name == "0" || function.Name.EndsWith("@2"))
                                    {
                                        //exclude global array initializer and struct array initializer functions
                                    }
                                    else
                                    {
                                        //var structInfo = function.GetClass();
                                        //if (structInfo != null)
                                        //{
                                        //    if (UnvisitedStructs.Contains(structInfo))
                                        //    {
                                        //        UnvisitedStructs.Remove(structInfo);
                                        //        string classDeclaration = displayer.GetClassDeclaration(structInfo);
                                        //        streamWriter.Write(classDeclaration);
                                        //    }
                                        //}
                                        if (Debugger.IsAttached)
                                        {
                                            //no exception handling when debugging - we want to see the exceptions
                                            try
                                            {
                                                var    expression = decompiler.DecompileFunction(function);
                                                string text       = displayer.PrintExpression2(expression, true);
                                                streamWriter.WriteLine(text);
                                            }
                                            finally
                                            {
                                            }
                                        }
                                        else
                                        {
                                            try
                                            {
                                                var    expression = decompiler.DecompileFunction(function);
                                                string text       = displayer.PrintExpression2(expression, true);
                                                streamWriter.WriteLine(text);
                                            }
                                            catch (Exception ex)
                                            {
                                                string errorMessage = "Function " + functionNode.name + " failed to decompile.";
                                                RaiseError(errorMessage, ex);
                                            }
                                            finally
                                            {
                                            }
                                        }
                                    }
                                    functionsVisited++;
                                }
                            }
                            streamWriter.Flush();
                            streamWriter.Close();
                        }
                    }
                }
            }
            mainIncludeFile.AppendLine("}");

            if (UnvisitedStructs.Count > 0)
            {
                var remainingStructs = UnvisitedStructs.OrderByIndex().ToArray();

                if (this.backgroundWorker != null)
                {
                    backgroundWorker.ReportProgress(100, "Generating class declarations...");
                }
                using (var fs = CreateFile("classes.jaf", destinationPath))
                {
                    using (var sw = new StreamWriter(fs, encoding))
                    {
                        foreach (var structInfo in remainingStructs)
                        {
                            string classDeclaration = displayer.GetClassDeclaration(structInfo);
                            sw.Write(classDeclaration);
                            sw.WriteLine();
                        }

                        foreach (var funcType in ainFile.FunctionTypes)
                        {
                            string funcTypeDeclaration = displayer.GetFunctypeDeclaration(funcType);
                            sw.WriteLine(funcTypeDeclaration);
                        }

                        foreach (var delg in ainFile.Delegates)
                        {
                            string delegateDeclaration = displayer.GetDelegateDeclaration(delg);
                            sw.WriteLine(delegateDeclaration);
                        }
                        sw.Flush();
                        sw.Close();
                    }
                }
            }

            Dictionary <Global, Expression> globalInitializers = GetGlobalInitializers();

            if (this.backgroundWorker != null)
            {
                backgroundWorker.ReportProgress(100, "Listing global variables...");
            }

            using (var fs = CreateFile("globals.jaf", destinationPath))
            {
                string lastGlobalGroupName = null;
                using (var sw = new MyIndentedTextWriter(new StreamWriter(fs, encoding)))
                {
                    Dictionary <int, GlobalInitialValue> initialValues = new Dictionary <int, GlobalInitialValue>();
                    foreach (var globalInitialValue in ainFile.GlobalInitialValues)
                    {
                        initialValues[globalInitialValue.GlobalIndex] = globalInitialValue;
                    }


                    foreach (var global in ainFile.Globals)
                    {
                        if (global.DataType != DataType.Void)
                        {
                            string globalGroupName = global.GroupName;
                            if (globalGroupName != lastGlobalGroupName)
                            {
                                if (lastGlobalGroupName != null)
                                {
                                    sw.Indent--;
                                    sw.WriteLine("}");
                                }
                                if (globalGroupName != null)
                                {
                                    sw.WriteLine("globalgroup " + globalGroupName);
                                    sw.WriteLine("{");
                                    sw.Indent++;
                                }
                            }
                            lastGlobalGroupName = globalGroupName;

                            sw.Write(global.GetDataTypeName());
                            sw.Write(" ");
                            sw.Write(global.Name);

                            if (global.DataType.IsArray())
                            {
                                if (globalInitializers.ContainsKey(global))
                                {
                                    var expr = globalInitializers[global];

                                    foreach (var e in expr.Args)
                                    {
                                        if (e.ExpressionType == Instruction.PUSH)
                                        {
                                            sw.Write("[" + e.Value.ToString() + "]");
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (initialValues.ContainsKey(global.Index))
                                {
                                    sw.Write(" = ");
                                    var initialValue = initialValues[global.Index];
                                    sw.Write(initialValue.GetValueQuoted());
                                }
                            }
                            sw.WriteLine(";");
                        }
                    }
                    if (lastGlobalGroupName != null)
                    {
                        sw.Indent--;
                        sw.WriteLine("}");
                    }
                    sw.Flush();
                    sw.Close();
                }
            }

            using (var fs = CreateFile("constants.jaf", destinationPath))
            {
                using (StreamWriter sw = new StreamWriter(fs, encoding))
                {
                    sw.WriteLine("const int true = 1;");
                    sw.WriteLine("const int false = 0;");
                    sw.WriteLine();
                    if (ainFile.MetadataFile != null)
                    {
                        foreach (var pair in ainFile.MetadataFile.EnumerationTypes)
                        {
                            var enumerationType = pair.Value;
                            sw.WriteLine("//" + enumerationType.Name);
                            foreach (var pair2 in enumerationType)
                            {
                                sw.WriteLine("const int " + pair2.Value + " = " + pair2.Key.ToString() + ";");
                            }
                            sw.WriteLine();
                        }
                    }

                    sw.Flush();
                    fs.Flush();
                    sw.Close();
                    fs.Close();
                }
            }

            if (this.backgroundWorker != null)
            {
                backgroundWorker.ReportProgress(100, "Creating project file...");
            }

            if (ainFile.Libraries.Count > 0)
            {
                StringBuilder libraryIncludeFile = new StringBuilder();
                libraryIncludeFile.AppendLine("SystemSource = {");

                string hllDirectory = Path.Combine(destinationPath, "HLL");
                foreach (var library in ainFile.Libraries)
                {
                    string hllFileName = library.LibraryName + ".hll";

                    using (var fs = CreateFileUnique(ref hllFileName, hllDirectory))
                    {
                        libraryIncludeFile.AppendLine("\t\"" + hllFileName + "\",\t\"" + library.LibraryName + "\",");
                        using (var sw = new StreamWriter(fs, encoding))
                        {
                            foreach (var func in library.Functions)
                            {
                                string declaration = func.GetDeclaration() + ";";
                                sw.WriteLine(declaration);
                            }
                            sw.Flush();
                            sw.Close();
                        }
                    }
                }
                libraryIncludeFile.AppendLine("}");
                string includeFileContents = libraryIncludeFile.ToString();

                using (var fs = CreateFile("hll.inc", hllDirectory))
                {
                    using (var sw = new StreamWriter(fs, encoding))
                    {
                        sw.Write(includeFileContents);
                    }
                }
            }

            File.WriteAllText(Path.Combine(destinationPath, "main.inc"), mainIncludeFile.ToString(), encoding);

            //build a PJE file
            {
                StringBuilder pje = new StringBuilder();
                pje.AppendLine("// Project Environment File");
                pje.AppendLine("ProjectName = \"" + Path.GetFileNameWithoutExtension(this.ainFile.OriginalFilename) + "\"");
                pje.AppendLine();
                pje.AppendLine("CodeName = \"" + Path.GetFileNameWithoutExtension(this.ainFile.OriginalFilename) + ".ain\"");
                pje.AppendLine();
                pje.AppendLine("#define _AINVERSION " + ainFile.Version.ToString());
                pje.AppendLine("#define _KEYCODE 0x" + ainFile.KeyCode.ToString("X8"));
                pje.AppendLine("#define _ISAI2FILE " + (ainFile.IsAi2File ? "true" : "false"));
                if (ainFile.Version >= 6)
                {
                    pje.AppendLine("#define _USESMSG1 " + (ainFile.UsesMsg1 ? "true" : "false"));
                }
                pje.AppendLine("#define _TARGETVM " + ainFile.TargetVMVersion.ToString());
                pje.AppendLine();
                pje.AppendLine("GameVersion = " + ainFile.GameVersion.ToString());
                pje.AppendLine();
                pje.AppendLine("// Settings for each directory");
                pje.AppendLine("SourceDir = \".\"");
                pje.AppendLine("HLLDir = \"HLL\"");
                pje.AppendLine("ObjDir = \"OBJ\"");
                pje.AppendLine("OutputDir = \"Run\"");
                pje.AppendLine();
                pje.AppendLine("Source = {");
                pje.AppendLine("    \"main.inc\",");
                pje.AppendLine("}");

                string pjeFileName = Path.Combine(destinationPath, Path.GetFileNameWithoutExtension(this.ainFile.OriginalFilename) + ".pje");

                File.WriteAllText(pjeFileName, pje.ToString(), encoding);
            }
        }
            private void ReadReplacementFile(TextReaderWrapper tr, string textFileName)
            {
                textFileName = Path.GetFullPath(textFileName);
                if (IncludedFiles.Contains(textFileName.ToUpperInvariant()))
                {
                    return;
                }
                IncludedFiles.Set(textFileName.ToUpperInvariant());

                string line;

                while (true)
                {
                    line = tr.ReadLine();
                    if (line == null)
                    {
                        break;
                    }

                    //remove initial whitespace
                    line = line.TrimStart();

                    //check for "#include"
                    if (line.StartsWith("#include "))
                    {
                        string filenameToInclude = line.Substring("#include ".Length);
                        //check for quotes?
                        if (filenameToInclude.StartsWith("\"") && filenameToInclude.EndsWith("\""))
                        {
                            filenameToInclude = filenameToInclude.Substring(1, filenameToInclude.Length - 2);
                        }
                        string basePath = tr.DirectoryName;
                        filenameToInclude = Path.Combine(basePath, filenameToInclude);
                        if (!File.Exists(filenameToInclude))
                        {
                            throw new FileNotFoundException("Cannot find file: " + filenameToInclude, filenameToInclude);
                        }

                        if (File.Exists(filenameToInclude) && !IncludedFiles.Contains(filenameToInclude.ToUpperInvariant()))
                        {
                            IncludedFiles.Add(filenameToInclude.ToUpperInvariant());
                            var encoding = EncodingDetector.DetectEncoding(filenameToInclude);
                            tr.IncludeTextReader(new StreamReader(filenameToInclude, encoding));
                        }
                        continue;
                    }


                    //remove commented text
                    int indexOfComment = line.IndexOf('#');
                    if (indexOfComment >= 0)
                    {
                        line = line.Substring(0, indexOfComment);
                    }

                    //reading one of these lines:
                    //CODE
                    //function x functionName  (or func, f)
                    //string x text (or str, s)
                    //message x text (or msg, m)
                    //id x text (or i)
                    //x text (same as id x text)

                    string lineTrim = line.Trim();

                    if (lineTrim.Equals("CODE", StringComparison.OrdinalIgnoreCase) || lineTrim.Equals("CODE2", StringComparison.OrdinalIgnoreCase))
                    {
                        bool          isCode2  = lineTrim.Equals("CODE2", StringComparison.OrdinalIgnoreCase);
                        StringBuilder codeText = new StringBuilder();
                        while (true)
                        {
                            line     = tr.ReadLine();
                            lineTrim = line.Trim();
                            if (lineTrim.StartsWith("#include"))
                            {
                                string filenameToInclude = lineTrim.Substring("#include ".Length);
                                //check for quotes?
                                if (filenameToInclude.StartsWith("\"") && filenameToInclude.EndsWith("\""))
                                {
                                    filenameToInclude = filenameToInclude.Substring(1, filenameToInclude.Length - 2);
                                }
                                string basePath = tr.DirectoryName;
                                if (!Path.IsPathRooted(filenameToInclude))
                                {
                                    filenameToInclude = Path.Combine(basePath, filenameToInclude);
                                }
                                filenameToInclude = Path.GetFullPath(filenameToInclude);

                                if (!File.Exists(filenameToInclude))
                                {
                                    throw new FileNotFoundException("Cannot find file: " + filenameToInclude, filenameToInclude);
                                }

                                if (File.Exists(filenameToInclude) && !IncludedFiles.Contains(filenameToInclude.ToUpperInvariant()))
                                {
                                    IncludedFiles.Add(filenameToInclude.ToUpperInvariant());

                                    if (isCode2)
                                    {
                                        //replace with #include <fullpath>, let the compiler handle the actual include
                                        codeText.AppendLine("#include " + AssemblerProjectWriter.EscapeAndQuoteString(filenameToInclude));
                                    }
                                    else
                                    {
                                        var encoding = EncodingDetector.DetectEncoding(filenameToInclude);
                                        tr.IncludeTextReader(new StreamReader(filenameToInclude, encoding));
                                    }
                                }
                                continue;
                            }

                            if (lineTrim.ToUpperInvariant() == "ENDCODE")
                            {
                                if (isCode2)
                                {
                                    CodePatches2.AppendLine(codeText.ToString());
                                }
                                else
                                {
                                    CodePatches.Set(currentFunctionName, codeText.ToString());
                                }
                                break;
                            }
                            else
                            {
                                codeText.AppendLine(line);
                            }
                        }
                        continue;
                    }

                    //find first space
                    int spaceIndex = line.IndexOf(' ');
                    if (spaceIndex == -1)
                    {
                        continue;
                    }
                    string tagName = line.Substring(0, spaceIndex);
                    line = line.Substring(spaceIndex + 1);
                    int number;
                    //if it starts with a number, it's a legacy text replacement
                    if (IntUtil.TryParse(tagName, out number) == true)
                    {
                        tagName = "id";
                    }
                    else
                    {
                        bool   isFunction   = false;
                        string tagNameLower = tagName.ToLowerInvariant();
                        if (tagNameLower == "f" || tagNameLower == "func" || tagNameLower == "function")
                        {
                            isFunction = true;
                        }

                        line       = line.TrimStart();
                        spaceIndex = line.IndexOf(' ');
                        if (spaceIndex == -1)
                        {
                            if (isFunction)
                            {
                                number = -1;
                            }
                            else
                            {
                                continue;
                            }
                        }
                        else
                        {
                            string numberString = line.Substring(0, spaceIndex);
                            line = line.Substring(spaceIndex + 1);

                            if (IntUtil.TryParse(numberString, out number) == false)
                            {
                                if (isFunction)
                                {
                                    line   = numberString + " " + line;
                                    number = -1;
                                }
                                else
                                {
                                    continue;
                                }
                            }
                        }
                    }

                    line = StringExportImport.UnescapeText(line);

                    switch (tagName.ToLowerInvariant())
                    {
                    case "f":
                    case "func":
                    case "function":
                        string nextFunctionName = line.Trim();
                        var    function         = ainFile.GetFunction(number);
                        if (function == null)
                        {
                            function = ainFile.GetFunction(nextFunctionName);
                            if (function == null)
                            {
                                continue;
                            }
                        }
                        currentFunctionName = function.Name;
                        stringDictionary    = stringEntries.GetOrAddNew(currentFunctionName);
                        messageDictionary   = messageEntries.GetOrAddNew(currentFunctionName);
                        break;

                    case "string":
                    case "str":
                    case "s":
                        stringDictionary.Set(number, line);
                        break;

                    case "msg":
                    case "message":
                    case "m":
                        messageDictionary.Set(number, line);
                        break;

                    case "i":
                    case "id":
                        numberedStrings.Set(number, line);
                        break;
                    }
                }
            }
        private List <string> GetTextFromFunction(Function function)
        {
            int numberOfNonCommentedLines = 0;
            int numberOfStrings           = 0;
            int numberOfMessages          = 0;

            //Expression expression = null;
            //int expressionLastAddress = function.Address;

            useStringsToMatch = StringsToMatch != null && StringsToMatch.Count > 0;
            //List<string> strings = new List<string>();
            //List<string> messages = new List<string>();
            List <string> functionLines      = new List <string>();
            string        functionLineString = "FUNCTION " + /*function.Index.ToString() + " " + */ AssemblerProjectWriter.SanitizeVariableName(function.Name);

            functionLines.Add(functionLineString);
            functionLines.Add("#x strings, x messages");  //this line gets changed later (it's index 1)
            int    address  = function.Address;
            string lastName = null;

            while (address < ainFile.Code.Length)
            {
                var instructionInfo = ainFile.Peek(address);
                if (instructionInfo.instruction == Instruction.ENDFUNC || instructionInfo.instruction == Instruction.FUNC)
                {
                    break;
                }
                if (this.AnnotateEnumerationType != null && instructionInfo.instruction == Instruction.CALLFUNC)
                {
                    var func = ainFile.GetFunction(instructionInfo.word1);
                    if (VariablesUsingEnumerationType.Contains(func))
                    {
                        var parameters = GetParametersThatUsesEnumerationType(func);
                        if (parameters.FirstOrDefault() != null)
                        {
                            foreach (var parameter in parameters)
                            {
                                int i    = parameter.Index;
                                int addr = instructionInfo.CurrentAddress - (func.ParameterCount) * 6 + i * 6;
                                var ins2 = ainFile.Peek(addr);
                                if (ins2.instruction == Instruction.PUSH)
                                {
                                    string enumerationValue = this.AnnotateEnumerationType.GetOrDefault(ins2.word1, "");
                                    if (!String.IsNullOrEmpty(enumerationValue))
                                    {
                                        functionLines.Add("");
                                        functionLines.Add("#" + enumerationValue);
                                    }
                                }
                                else if (ins2.instruction == Instruction.S_PUSH)
                                {
                                    string str = ainFile.GetString(ins2.word1);
                                    if (!String.IsNullOrEmpty(str))
                                    {
                                        if (this.replacementStringsForAnnotations != null && this.replacementStringsForAnnotations.ContainsKey(str))
                                        {
                                            string nextStr = this.replacementStringsForAnnotations[str];
                                            if (!nextStr.StartsWith("*"))
                                            {
                                                str = nextStr;
                                            }
                                            else
                                            {
                                                str = lastName;
                                            }
                                        }
                                        else
                                        {
                                        }
                                        if (lastName != str)
                                        {
                                            lastName = str;
                                            functionLines.Add("");
                                            functionLines.Add("#" + str);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                if (instructionInfo.instruction == Instruction.MSG)
                {
                    //if (this.AnnotateEnumerationType != null)
                    //{
                    //    if (expression == null)
                    //    {
                    //        expression = ainFile.DecompiledCodeCache.GetDecompiledCode(function);
                    //    }
                    //    CatchUpToAddress(ref expression, functionLines, address);
                    //}
                    int    messageNumber = instructionInfo.word1;
                    string message       = ainFile.GetMessage(messageNumber);
                    if (message != null)
                    {
                        if (useStringsToMatch == false || StringsToMatch.Contains(message))
                        {
                            string messageLine = "m " + numberOfMessages.ToString("000") + " " + StringExportImport.EscapeText(message);
                            functionLines.Add(messageLine);
                        }
                        numberOfMessages++;
                        numberOfNonCommentedLines++;
                    }
                }
                else if (instructionInfo.instruction == Instruction.STRSWITCH)
                {
                    int switchBlockNumber = instructionInfo.word1;
                    var switchBlock       = ainFile.Switches.GetOrNull(switchBlockNumber);
                    if (switchBlock != null)
                    {
                        foreach (var switchCase in switchBlock.SwitchCases)
                        {
                            int    stringNumber = switchCase.Value;
                            string str          = ainFile.GetString(stringNumber);
                            if (str != null)
                            {
                                AddString(ref numberOfNonCommentedLines, ref numberOfStrings, functionLines, stringNumber, str);
                            }
                        }
                    }
                }
                else
                {
                    int indexOfStringArgument = instructionInfo.instruction.IndexOfStringArgument();
                    if (indexOfStringArgument != -1)
                    {
                        int    stringNumber = instructionInfo.words[indexOfStringArgument];
                        string str          = ainFile.GetString(stringNumber);
                        if (str != null)
                        {
                            AddString(ref numberOfNonCommentedLines, ref numberOfStrings, functionLines, stringNumber, str);
                        }
                    }
                }
                address = instructionInfo.nextAddress;
            }
            functionLines[1] = "#" + numberOfStrings.ToString() + " strings, " + numberOfMessages.ToString() + " messages";
            if (numberOfNonCommentedLines == 0)
            {
                functionLines.Clear();
            }
            return(functionLines);
        }
Esempio n. 10
0
        public void GetExclusionList()
        {
            this.exclusionFlags = (this.ExcludeFunctionNames ? (int)StringExclusionReason.IsFunctionName : 0) |
                                  (this.ExcludeSystemFunctions ? (int)StringExclusionReason.IsInsideSystemFunction : 0) |
                                  (this.ExcludeTestFunctions ? (int)StringExclusionReason.IsInsideTestFunction : 0) |
                                  (this.ExcludeUnusedStrings ? (int)StringExclusionReason.IsUnused : 0) |
                                  (this.ExcludeAsserts ? (int)StringExclusionReason.IsAssert : 0) |
                                  (this.ExcludeEventFlags ? (int)StringExclusionReason.IsEvent : 0);

            if (alreadyBuilt)
            {
                return;
            }
            alreadyBuilt = true;

            //if (currentExclusionFlags == newExclusionFlags)
            //{
            //    return;
            //}

            //currentExclusionFlags = newExclusionFlags;
            stringsToExclude.Clear();

            //build list of "System" functions
            var functionEnumerator = new FunctionEnumerator(ainFile);
            var filesAndFunctions  = functionEnumerator.GetFilesAndFunctions();
            var systemFiles        = filesAndFunctions.Where(f => f.name.StartsWith("System\\", StringComparison.OrdinalIgnoreCase));
            var systemFunctions    = new HashSet <int>(systemFiles.SelectMany(f => f.children).Select(res => res.id));

            Dictionary <int, HashSet <int> > assertStringNumberToFunctionIndex = GetStringsUsedInAsserts();

            HashSet <Function> functionsThatCallEv = new HashSet <Function>();
            //get functions that call "EV()"
            var evFunction = ainFile.GetFunction("EV");

            if (evFunction != null)
            {
                functionsThatCallEv = ainFile.CodeSearchCache.FunctionsCache.GetUsedBy(evFunction);
            }

            //Is it used as part of a function call to EV?
            foreach (var function in functionsThatCallEv)
            {
                int address          = function.Address;
                int codeLength       = ainFile.Code.Length;
                int evFunctionIndex  = evFunction.Index;
                int evFunctionArgs   = evFunction.ParameterCount;
                int evFunctionOffset = evFunctionArgs * 6;
                while (address < codeLength)
                {
                    var instructionInfo = Decompiler.Peek(ainFile.Code, address);
                    if (instructionInfo.instruction == Instruction.CALLFUNC && instructionInfo.word1 == evFunctionIndex)
                    {
                        var ins1 = Decompiler.Peek(ainFile.Code, instructionInfo.CurrentAddress - evFunctionOffset);
                        if (ins1.instruction == Instruction.S_PUSH)
                        {
                            stringsToExclude.SetBit(ins1.word1, StringExclusionReason.IsEvent);
                        }
                    }
                    else if (instructionInfo.instruction == Instruction.FUNC || instructionInfo.instruction == Instruction.ENDFUNC)
                    {
                        break;
                    }
                    address = instructionInfo.nextAddress;
                }

                //var expression = ainFile.DecompiledCodeCache.GetDecompiledCode(function);
                //var childExpressions = expression.GetChildExpressions();
                //var evCalls = childExpressions.Where(e => e.ExpressionType == Instruction.CALLFUNC && e.Variable == evFunction);
                //var stringNumbers = evCalls.SelectMany(evCall => evCall.GetChildExpressions())
                //    .Where(e => e.ExpressionType == Instruction.S_PUSH)
                //    .Select(e => e.Value);
                //foreach (var stringNumber in stringNumbers)
                //{
                //    stringsToExclude.SetBit(stringNumber, ExclusionReason.IsEvent);
                //}
            }

            for (int i = 0; i < ainFile.Strings.Count; i++)
            {
                string str = ainFile.Strings[i];
                if (String.IsNullOrEmpty(str))
                {
                    continue;
                }
                //Is it a function name?
                if (ainFile.FunctionNameToIndex.ContainsKey(str))
                {
                    stringsToExclude.SetBit(i, StringExclusionReason.IsFunctionName);
                }
                var usedBy = ainFile.CodeSearchCache.StringsCache.GetUsedBy(str);
                //Is it used only by a function containing TEST or DEBUG in its name?
                if (usedBy.All(f => f.Name.Contains("テスト") || f.Name.Contains("デバッグ"))) //TEST or DEBUG
                {
                    stringsToExclude.SetBit(i, StringExclusionReason.IsInsideTestFunction);
                }
                //Is it used only by a system function?
                if (usedBy.All(f => systemFunctions.Contains(f.Index)))
                {
                    stringsToExclude.SetBit(i, StringExclusionReason.IsInsideSystemFunction);
                }
                //Is it never used?
                if (usedBy.Count == 0)
                {
                    stringsToExclude.SetBit(i, StringExclusionReason.IsUnused);
                }
                //Is it used only in an assert?
                if (assertStringNumberToFunctionIndex.ContainsKey(i))
                {
                    var assertFunctionIndexes = assertStringNumberToFunctionIndex[i];
                    var usedByFunctionIndexes = usedBy.Select(f => f.Index);
                    if (assertFunctionIndexes.SetEquals(usedByFunctionIndexes))
                    {
                        stringsToExclude.SetBit(i, StringExclusionReason.IsAssert);
                    }
                }
            }

            if (stringsToExclude.ContainsKey(0))
            {
                stringsToExclude.Remove(0);
            }



            ////part 1: function names
            //if (ExcludeFunctionNames)
            //{
            //    for (int i = 0; i < ainFile.Strings.Count; i++)
            //    {
            //        string str = ainFile.Strings[i];
            //        if (ainFile.FunctionNameToIndex.ContainsKey(str))
            //        {
            //            stringsToExclude.SetBit(i, ExclusionReason.IsFunctionName);
            //        }
            //    }
            //}

            ////part 2: Test functions
            //if (ExcludeTestFunctions)
            //{
            //    for (int i = 0; i < ainFile.Strings.Count; i++)
            //    {
            //        string str = ainFile.Strings[i];
            //        var usedBy = ainFile.CodeSearchCache.StringsCache.GetUsedBy(str);
            //        if (usedBy.All(f => f.Name.Contains("テスト") || f.Name.Contains("デバッグ"))) //TEST or DEBUG
            //        {
            //            stringsToExclude.SetBit(i, ExclusionReason.IsInsideTestFunction);
            //        }
            //    }
            //}

            ////part 3: System functions
            //if (ExcludeSystemFunctions)
            //{
            //    for (int i = 0; i < ainFile.Strings.Count; i++)
            //    {
            //        string str = ainFile.Strings[i];
            //        var usedBy = ainFile.CodeSearchCache.StringsCache.GetUsedBy(str);
            //        if (usedBy.All(f => systemFunctions.Contains(f.Index)))
            //        {
            //            stringsToExclude.SetBit(i, ExclusionReason.IsInsideSystemFunction);
            //        }
            //    }
            //}

            ////part 4: Unused strings
            //if (ExcludeUnusedStrings)
            //{
            //    for (int i = 0; i < ainFile.Strings.Count; i++)
            //    {
            //        string str = ainFile.Strings[i];
            //        var usedBy = ainFile.CodeSearchCache.StringsCache.GetUsedBy(str);
            //        if (usedBy.Count == 0)
            //        {
            //            stringsToExclude.SetBit(i, ExclusionReason.IsUnused);
            //        }
            //    }
            //}
        }
Esempio n. 11
0
        public void LoadFile(string fileName)
        {
            var text        = File.ReadAllText(fileName);
            var document    = XDocument.Parse(text);
            var rootElement = document.Element(XNamespace.None + "root");

            if (rootElement == null)
            {
                return;
            }

            foreach (var element in rootElement.Elements())
            {
                if (element.IsNamed("variable"))
                {
                    var metaData = TryReadMetadata(element);

                    string name = element.GetAttribute("name");
                    if (name != null && metaData != null)
                    {
                        IVariable variable           = null;
                        string    parentFunctionName = element.GetAttribute("function");
                        string    parentStructName   = element.GetAttribute("struct");

                        var parentFunction = ainFile.GetFunction(parentFunctionName);
                        var parentStruct   = ainFile.GetStruct(parentStructName);
                        var function       = ainFile.GetFunction(name);
                        var structInfo     = ainFile.GetStruct(name);
                        var global         = ainFile.GetGlobal(name);

                        if (parentFunction != null)
                        {
                            int index;
                            if (!int.TryParse(name, out index))
                            {
                                variable = ainFile.GetFunctionParameter(parentFunction, name);
                            }
                            else
                            {
                                variable = ainFile.GetFunctionParameter(parentFunction, index);
                            }
                        }
                        else if (parentStruct != null)
                        {
                            variable = ainFile.GetStructMember(parentStruct, name);
                        }
                        else if (function != null)
                        {
                            variable = function;
                        }
                        else if (structInfo != null)
                        {
                            variable = structInfo;
                        }
                        else if (global != null)
                        {
                            variable = global;
                        }

                        if (variable != null)
                        {
                            Metadata[variable] = metaData;
                        }
                    }
                }
                else if (element.IsNamed("enumeration"))
                {
                    string name = element.GetAttribute("name");
                    if (name != null)
                    {
                        var enumeration = this.EnumerationTypes.GetOrAddNew(name);
                        enumeration.Name = name;
                        foreach (var enumerationElement in element.Elements())
                        {
                            if (enumerationElement.IsNamed("item"))
                            {
                                string itemName        = enumerationElement.GetAttribute("name");
                                string itemValueString = enumerationElement.GetAttribute("value");
                                if (itemName != null && itemValueString != null)
                                {
                                    int itemValue;
                                    if (int.TryParse(itemValueString, out itemValue))
                                    {
                                        enumeration.Add(itemValue, itemName);
                                    }
                                }
                            }
                        }
                    }
                }
                else if (element.IsNamed("globalgroup"))
                {
                    string indexString = element.GetAttribute("index");
                    int    index;
                    if (IntUtil.TryParse(indexString, out index))
                    {
                        var metaData = TryReadMetadata(element);
                        if (metaData != null)
                        {
                            this.GlobalGroupMetadata.Set(index, metaData);
                        }
                    }
                }
            }
        }
        private bool FindFunctionTypeForVariable(IVariable variable, Expression code, bool MakeNewStuffUp)
        {
            bool variableIsFunction = variable as Function != null;
            bool variableIsFuncType = variable.DataType.IsFuncType();
            bool variableIsDelegate = variable.DataType.IsDelegate();

            foreach (var e in code.GetChildExpressions())
            {
                Expression otherExpression = null;
                IVariable  expVariable     = null;
                if (e.ExpressionType == Instruction.CALLFUNC2 && variableIsFuncType)
                {
                    bool isVoid = e.IsVoidContext();
                    if (!isVoid)
                    {
                        otherExpression = e.GetOtherSideOfBinaryExpression();
                    }
                    IVariable otherExpressionVariable = null;
                    if (otherExpression != null)
                    {
                        otherExpressionVariable = otherExpression.Variable;
                    }

                    DataType otherExpressionDataType   = DataType.Void;
                    int      otherExpressionStructType = -1;
                    if (otherExpressionVariable != null)
                    {
                        otherExpressionDataType   = otherExpressionVariable.DataType;
                        otherExpressionStructType = otherExpressionVariable.StructType;
                    }
                    else
                    {
                        if (isVoid)
                        {
                            otherExpressionDataType = DataType.Void;
                        }
                        else
                        {
                            otherExpressionDataType = DataType.AnyNonVoidType;
                        }
                    }

                    var argExpressions    = (e.Arg3 ?? Expression.Empty).FlattenContainerExpression(Instruction.Comma).ToArray();
                    var variables         = GetVariablesFromExpressions(argExpressions);
                    var matchingFuncTypes = ainFile.MatchingFunctionTypes(otherExpressionDataType, otherExpressionStructType, variables, variables.Length).Distinct().ToArray();

                    var firstMatchingFuncType = matchingFuncTypes.FirstOrDefault();
                    if (firstMatchingFuncType != null)
                    {
                        if (MakeNewStuffUp || matchingFuncTypes.Skip(1).FirstOrDefault() == null)
                        {
                            variable.StructType = firstMatchingFuncType.Index;
                        }
                    }
                }
                if (variableIsFunction && e.ExpressionType == Instruction.RETURN)
                {
                    otherExpression = e.Arg1;
                    expVariable     = variable;
                }
                else
                {
                    expVariable = e.Variable;
                    if (variable == expVariable)
                    {
                        otherExpression = e.GetOtherSideOfBinaryExpression();
                    }
                }

                if (otherExpression != null)
                {
                    Function otherFunction = null;
                    if (otherExpression.ExpressionType == Instruction.PUSH)
                    {
                        otherFunction = ainFile.GetFunction(otherExpression.Value);
                    }
                    else if (otherExpression.ExpressionType == Instruction.S_PUSH)
                    {
                        otherFunction = ainFile.GetFunction(ainFile.GetString(otherExpression.Value));
                    }
                    else
                    {
                        var otherVariable = otherExpression.Variable;
                        if (otherVariable != null && !variableIsDelegate && otherVariable.DataType.IsFuncType() && otherVariable.StructType != -1)
                        {
                            variable.StructType = otherVariable.StructType;
                            return(true);
                        }
                        if (otherVariable != null && variableIsDelegate && otherVariable.DataType.IsDelegate() && otherVariable.StructType != -1)
                        {
                            variable.StructType = otherVariable.StructType;
                            return(true);
                        }
                    }
                    if (otherFunction != null)
                    {
                        FunctionType matchingFuncType = null;
                        if (!variableIsDelegate)
                        {
                            if (!MakeNewStuffUp)
                            {
                                matchingFuncType = ainFile.GetFuncTypeUnique(otherFunction);
                            }
                            else
                            {
                                matchingFuncType = ainFile.GetFuncType(otherFunction);
                            }
                            if (matchingFuncType != null)
                            {
                                variable.StructType = matchingFuncType.Index;
                                return(true);
                            }
                        }
                        else
                        {
                            if (!MakeNewStuffUp)
                            {
                                matchingFuncType = ainFile.GetDelegateUnique(otherFunction);
                            }
                            else
                            {
                                matchingFuncType = ainFile.GetDelegateType(otherFunction);
                            }
                            if (matchingFuncType != null)
                            {
                                variable.StructType = matchingFuncType.Index;
                                return(true);
                            }
                        }
                    }
                }
                else
                {
                    var functionParameter = e.GetFunctionCallParameter();
                    if (functionParameter != null)
                    {
                        if (functionParameter != null && !variableIsDelegate && functionParameter.DataType.IsFuncType() && functionParameter.StructType != -1)
                        {
                            variable.StructType = functionParameter.StructType;
                            return(true);
                        }
                        if (functionParameter != null && variableIsDelegate && functionParameter.DataType.IsDelegate() && functionParameter.StructType != -1)
                        {
                            variable.StructType = functionParameter.StructType;
                            return(true);
                        }
                    }
                    else if (variable.DataType.IsArray())
                    {
                        var parent = e.Parent;
                        if (parent != null && (parent.ExpressionType == Instruction.A_PUSHBACK || parent.ExpressionType == Instruction.A_INSERT))
                        {
                            var       arg2 = parent.Arg2;
                            IVariable var2 = null;
                            if (arg2 != null)
                            {
                                var2 = arg2.Variable;
                            }
                            if (var2 != null)
                            {
                                if (!variableIsDelegate && var2.DataType.IsFuncType() && var2.StructType != -1)
                                {
                                    variable.StructType = var2.StructType;
                                    return(true);
                                }
                                if (variableIsDelegate && var2.DataType.IsDelegate() && var2.StructType != -1)
                                {
                                    variable.StructType = var2.StructType;
                                    return(true);
                                }
                            }
                        }
                    }
                    else if (e.ExpressionType == Instruction.CALLFUNC2)
                    {
                    }
                }
            }
            return(false);
        }