public async Task <PapyrusAssemblyObject> Parse(string file)
 {
     return(await Task.Run(() =>
     {
         PapyrusAssemblyObject obj = null;
         var ext = Path.GetExtension(file);
         if (!string.IsNullOrEmpty(ext))
         {
             // StatusCallback.WriteLine("... " + Path.GetFileNameWithoutExtension(file));
             obj = ext.ToLower().EndsWith("pas")
                 ? PapyrusAssemblyParser.ParseAssembly(file)
                 : PapyrusScriptParser.ParseScript(file);
         }
         filesParsed++;
         StatusCallback.Title = "PapyrusDotNet - Parsing Papyrus: " + filesParsed + "/" + totalFilesToParse;
         return obj;
     }));
 }
Example #2
0
        public PapyrusAssemblyObject ParseScript(string file)
        {
            var obj = new PapyrusAssemblyObject();

            var scriptObject = Parse(file);

            var objName = scriptObject.Name;

            obj.Name = objName;

            foreach (var s in scriptObject.StateFunctions)
            {
                var state = new PapyrusAssemblyState();
                state.Name = s.Name;
                foreach (var f in s.Functions)
                {
                    var sourceFunction = f;

                    if (!string.IsNullOrEmpty(sourceFunction.StateName) && string.IsNullOrEmpty(state.Name))
                    {
                        state.Name = sourceFunction.StateName;
                    }

                    var function = new PapyrusAssemblyFunction();
                    function.Name        = functionNameResolver.Resolve(sourceFunction.Name);
                    function.ReturnType  = sourceFunction.ReturnType.VarType;
                    function.ReturnArray = sourceFunction.ReturnType.IsArray;
                    var inputNameIndex = 0;
                    foreach (var p in sourceFunction.Parameters)
                    {
                        function.Params.Add(new PapyrusAssemblyVariable(p.Name, p.VarType));

                        inputNameIndex++;
                    }

                    function.IsStatic = sourceFunction.IsGlobal;
                    function.IsNative = sourceFunction.IsNative;
                    function.IsEvent  = sourceFunction.IsEvent;
                    // Since we are only generating "dummy" classes,
                    // the function scope is not necessary at this point.
                    // var fs = sourceFunction.FunctionScope;

                    state.Functions.Add(function);
                }

                obj.States.Add(state);
            }

            // Ignore Non Overridable Functions for now.
            // We will need to handle these later to make sure that a user
            // does not override them. GetState, SetState are both common.
            //var nof = scriptObject.kNonOverridableFunctions;
            //var instanceVars = scriptObject.kInstanceVariables;
            //var propertyVars = scriptObject.kProperties;

            // If the script is extended by another script
            // The script will have a parent.
            if (scriptObject.Extends != null)
            {
                obj.ExtendsName = scriptObject.Extends;
            }

            foreach (var prop in scriptObject.Properties)
            {
                obj.PropertyTable.Add(new PapyrusAssemblyVariable(prop.Name, prop.VarType));
            }

            foreach (var field in scriptObject.InstanceVariables)
            {
                // Most likely an auto- property
                // And we have already added them above.
                if (field.Name.StartsWith("::"))
                {
                    continue;
                }
            }

            //      throw new NotImplementedException("Parsing from .psc/ Skyrim Papyrus Scripts are not yet supported.");

            //	TypeDefinition def = new TypeDefinition("","", TypeAttributes.);


            return(obj);
        }
        public TypeDefinition Resolve(ModuleDefinition mainModule, PapyrusAssemblyObject input)
        {
            var newType = new TypeDefinition(assemblyNameResolver.BaseNamespace, input.Name, TypeAttributes.Class)
            {
                IsPublic = true
            };


            // newType.DeclaringType = newType;
            if (!string.IsNullOrEmpty(input.ExtendsName))
            {
                newType.BaseType = new TypeReference(assemblyNameResolver.BaseNamespace, input.ExtendsName, mainModule,
                                                     mainModule);
                // newType.DeclaringType = MainModule.Types.FirstOrDefault(t => t.FullName == newType.BaseType.FullName);
                newType.Scope = mainModule;
            }
            else
            {
                newType.BaseType = mainModule.TypeSystem.Object;
                newType.Scope    = mainModule;
            }

            statusCallback.WriteLine("Generating Type '" + assemblyNameResolver.BaseNamespace + "." + input.Name +
                                     "'...");

            foreach (var prop in input.PropertyTable)
            {
                var typeRef = referenceResolver.Resolve(mainModule, null, prop.Type);
                var pro     = new PropertyDefinition(prop.Name, PropertyAttributes.HasDefault, typeRef);
                newType.Properties.Add(pro);
            }

            // newType.AddDefaultConstructor();

            builder.AddEmptyConstructor(newType);

            builder.AddVirtualOnInit(newType);

            foreach (var papyrusAsmState in input.States)
            {
                foreach (var papyrusAsmFunction in papyrusAsmState.Functions)
                {
                    var typeReference = referenceResolver.Resolve(mainModule, null, papyrusAsmFunction.ReturnType);
                    // var typeRef = MainModule.TypeSystem.Void;

                    var function = new MethodDefinition(papyrusAsmFunction.Name, MethodAttributes.Public, typeReference)
                    {
                        IsStatic = papyrusAsmFunction.IsStatic
                    };

                    if (function.IsStatic)
                    {
                        function.HasThis = false;
                    }
                    if (!function.IsStatic && papyrusAsmFunction.Name.StartsWith("On") || papyrusAsmFunction.IsEvent)
                    {
                        function.IsVirtual = true;
                    }
                    else
                    {
                        function.IsVirtual = false;
                    }

                    builder.CreateEmptyFunctionBody(ref function);

                    foreach (var par in papyrusAsmFunction.Params)
                    {
                        var resolvedTypeReference = referenceResolver.Resolve(mainModule, null, par.Type);
                        // var typeRefp = MainModule.TypeSystem.Object;

                        var nPar = new ParameterDefinition(par.Name, ParameterAttributes.None, resolvedTypeReference);
                        function.Parameters.Add(nPar);
                    }
                    var skipAdd = false;
                    foreach (var m in newType.Methods)
                    {
                        if (m.Name == function.Name)
                        {
                            if (m.Parameters.Count == function.Parameters.Count)
                            {
                                skipAdd = true;
                                for (var pi = 0; pi < m.Parameters.Count; pi++)
                                {
                                    if (m.Parameters[pi].ParameterType.FullName !=
                                        function.Parameters[pi].ParameterType.FullName)
                                    {
                                        skipAdd = false;
                                    }
                                }
                                break;
                            }
                        }
                    }
                    if (!skipAdd)
                    {
                        newType.Methods.Add(function);
                    }
                }
            }
            return(newType);
        }