private PapyrusTypeDefinition GetTypeFromLocation(object variableNameOrTypeName,
                                                          PapyrusTypeDefinition defaultType)
        {
            // If the input is a VariableReference, we may have the typename already.
            var targetTypeNameOrVariable = variableNameOrTypeName.ToString();
            var vref = variableNameOrTypeName as PapyrusVariableReference;

            if (!string.IsNullOrEmpty(vref?.TypeName?.Value))
            {
                return(GetTypeDefinition(vref.TypeName.Value, defaultType));
            }
            // if no type was found, we try to take the name
            if (!string.IsNullOrEmpty(vref?.Name?.Value))
            {
                targetTypeNameOrVariable = vref?.Name?.Value;
            }
            // if no name was found, we try and take the value.
            if (!string.IsNullOrEmpty(vref?.Value?.ToString()))
            {
                targetTypeNameOrVariable = vref?.Value?.ToString();
            }


            // if we are accessing a variable to call a method from we will need to get the type of the variable.
            var possibleType = GetTypeOfVariable(targetTypeNameOrVariable);

            if (possibleType != null)
            {
                return(GetTypeDefinition(possibleType, defaultType));
            }

            // if it is a static call, we will have the target type name from the input string
            return(GetTypeDefinition(targetTypeNameOrVariable, defaultType));
        }
Ejemplo n.º 2
0
        private void ReadStates(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef)
        {
            var stateCount = pexReader.ReadInt16();

            for (var i = 0; i < stateCount; i++)
            {
                var state = new PapyrusStateDefinition(typeDef);
                state.Name = pexReader.ReadStringRef();
                var methodCount = pexReader.ReadInt16();
                for (var k = 0; k < methodCount; k++)
                {
                    var name   = pexReader.ReadString();
                    var method = ReadMethod(asm);

                    method.DeclaringState = state;
                    method.Name           = new PapyrusStringRef(asm, name);
                    if (method.Name.Value.ToLower().StartsWith("on"))
                    {
                        // For now, lets assume that all functions with the name starting with "On" is an event.
                        method.IsEvent = true;
                    }
                    state.Methods.Add(method);
                }
                // typeDef.States.Add(state);
            }

            UpdateOperands(typeDef.States);
        }
Ejemplo n.º 3
0
        private PapyrusFieldDefinition ReadDocumentedField(PapyrusAssemblyDefinition asm,
                                                           PapyrusTypeDefinition declaringType)
        {
            var sfd = ReadFieldDefinition(asm, declaringType);

            sfd.Documentation = pexReader.ReadString();
            return(sfd);
        }
Ejemplo n.º 4
0
 public IEnumerable <PapyrusInstruction> ProcessInstructions(PapyrusAssemblyDefinition targetPapyrusAssembly,
                                                             PapyrusTypeDefinition targetPapyrusType,
                                                             PapyrusMethodDefinition targetPapyrusMethod, MethodDefinition method, MethodBody body,
                                                             Collection <Instruction> instructions,
                                                             PapyrusCompilerOptions options)
 {
     throw new NotImplementedException();
 }
Ejemplo n.º 5
0
        private void ReadFields(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef)
        {
            var fieldCount = pexReader.ReadInt16();

            for (var i = 0; i < fieldCount; i++)
            {
                typeDef.Fields.Add(ReadFieldDefinition(asm, typeDef));
            }
        }
Ejemplo n.º 6
0
 private void ReadTypeInfo(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef)
 {
     typeDef.Name          = pexReader.ReadStringRef();
     typeDef.Size          = pexReader.ReadInt32();
     typeDef.BaseTypeName  = pexReader.ReadStringRef();
     typeDef.Documentation = pexReader.ReadStringRef();
     typeDef.Flags         = pexReader.ReadByte();
     typeDef.UserFlags     = pexReader.ReadInt32();
     typeDef.AutoStateName = pexReader.ReadStringRef();
 }
Ejemplo n.º 7
0
        private void WriteFields(PapyrusTypeDefinition papyrusTypeDefinition)
        {
            var fields = papyrusTypeDefinition.Fields;

            pexWriter.Write((short)fields.Count);
            foreach (var field in fields)
            {
                WriteFieldDefinition(field);
            }
        }
Ejemplo n.º 8
0
        private void WriteProperties(PapyrusTypeDefinition papyrusTypeDefinition)
        {
            var props = papyrusTypeDefinition.Properties;

            pexWriter.Write((short)props.Count);
            foreach (var prop in props)
            {
                WritePropertyDefinition(prop);
            }
        }
Ejemplo n.º 9
0
        private void WriteStates(PapyrusTypeDefinition papyrusTypeDefinition)
        {
            var states = papyrusTypeDefinition.States;

            pexWriter.Write((short)states.Count);
            foreach (var state in states)
            {
                WriteState(state);
            }
        }
        private PapyrusTypeDefinition GetTypeDefinition(string typeName, PapyrusTypeDefinition defaultType)
        {
            var targetAsm =
                loadedAssemblies.FirstOrDefault(t => t.Types.Any(o => o.Name.Value.ToLower() == typeName.ToLower()));

            if (targetAsm != null)
            {
                return(targetAsm.Types.First());
            }
            return(defaultType);
        }
Ejemplo n.º 11
0
        private PapyrusTypeDefinition CreateType(PapyrusAssemblyDefinition pex, TypeDefinition type,
                                                 PapyrusCompilerOptions options, bool isStruct = false)
        {
            var papyrusType = new PapyrusTypeDefinition(pex, isStruct);


            if (isStruct)
            {
                papyrusType.IsStruct = true;
                papyrusType.IsClass  = false;
            }

            papyrusType.Name          = type.Name.Ref(pex);
            papyrusType.AutoStateName = "".Ref(pex);
            papyrusType.Documentation = "".Ref(pex);
            papyrusType.BaseTypeName  = type.BaseType != null
                ? Utility.GetPapyrusBaseType(type.BaseType).Ref(pex)
                : "".Ref(pex);

            UpdateUserFlags(type, pex);

            // Create Fields
            CreateFields(type, pex).ForEach(papyrusType.Fields.Add);

            // Create Properties
            CreateProperties(papyrusAssemblies, type, papyrusType, pex).ForEach(papyrusType.Properties.Add);

            // Create Structs
            foreach (var nestedType in type.NestedTypes)
            {
                // Make sure we don't add any delegate classes, as those are not supported as is
                if (delegatePairDefinition.DelegateTypeDefinitions.Contains(nestedType))
                {
                    continue;
                }
                // We do not want to include any Enums either :-)
                if (EnumDefinitions.Contains(nestedType))
                {
                    continue;
                }
                papyrusType.NestedTypes.Add(CreateStruct(nestedType, pex, options));
            }

            if (!isStruct)
            {
                var autoState = new PapyrusStateDefinition(papyrusType)
                {
                    Name = "".Ref(pex)
                };
                // -- Do not create the methods until all types has been parsed. excluding getters and setters
                // CreateMethods(type, papyrusType, pex, options).ForEach(autoState.Methods.Add);
            }
            return(papyrusType);
        }
Ejemplo n.º 12
0
 private void WriteTypeInfo(PapyrusTypeDefinition def)
 {
     pexWriter.Write(def.Name);
     pexWriter.Write(def.Size);
     pexWriter.Write(def.BaseTypeName);
     pexWriter.Write(def.Documentation);
     if (Assembly.VersionTarget == PapyrusVersionTargets.Fallout4)
     {
         pexWriter.Write(def.Flags);
     }
     pexWriter.Write(def.UserFlags);
     pexWriter.Write(def.AutoStateName);
 }
Ejemplo n.º 13
0
 public void AddResult(PapyrusTypeDefinition type, PapyrusStateDefinition state, PapyrusMethodDefinition method,
                       PapyrusInstruction instruction, string search, string resultRepresentation)
 {
     SearchText = search;
     usageRepresentaitons.Add(new FindResultData
     {
         Type        = type,
         State       = state,
         Method      = method,
         Instruction = instruction,
         Text        = resultRepresentation,
         SearchText  = search
     });
 }
Ejemplo n.º 14
0
 public PapyrusReferenceValueViewModel(List <PapyrusAssemblyDefinition> loadedAssemblies,
                                       PapyrusTypeDefinition currentType, PapyrusMethodDefinition currentMethod, OpCodeArgumentDescription desc)
 {
     this.loadedAssemblies = loadedAssemblies;
     this.currentType      = currentType;
     this.currentMethod    = currentMethod;
     this.desc             = desc;
     if (currentMethod != null)
     {
         ReferenceCollection = new ObservableCollection <PapyrusMemberReference>(currentMethod.GetVariables());
     }
     ComboBoxItems             = new ObservableCollection <FrameworkElement>(CreateComboBoxItems());
     SelectedReferenceType     = ComboBoxItems.First() as ComboBoxItem;
     ReferenceSelectionVisible = Visibility.Visible;
 }
Ejemplo n.º 15
0
        private void WriteStructs(PapyrusTypeDefinition papyrusTypeDefinition)
        {
            var structs = papyrusTypeDefinition.NestedTypes;

            pexWriter.Write((short)structs.Count);
            foreach (var structDef in structs)
            {
                pexWriter.Write(structDef.Name);
                pexWriter.Write((short)structDef.Fields.Count);
                foreach (var field in structDef.Fields)
                {
                    WriteDocumentedField(field);
                }
            }
        }
 private PapyrusTypeDefinition GetTargetType(PapyrusTypeDefinition defaultType)
 {
     if (desc.OpCode == PapyrusOpCodes.Callstatic)
     {
         return(GetTypeFromLocation(Arguments[0], defaultType));
     }
     if (desc.OpCode == PapyrusOpCodes.Callmethod)
     {
         return(GetTypeFromLocation(Arguments[1], defaultType));
     }
     if (desc.OpCode == PapyrusOpCodes.Callparent) // Call Base
     {
         return(GetTypeFromLocation(defaultType.BaseTypeName.Value, defaultType));
     }
     return(defaultType);
 }
Ejemplo n.º 17
0
        private PapyrusFieldDefinition ReadFieldDefinition(PapyrusAssemblyDefinition asm,
                                                           PapyrusTypeDefinition declaringType)
        {
            var fd = new PapyrusFieldDefinition(asm, declaringType);

            // Field Definition

            fd.Name      = pexReader.ReadStringRef();
            fd.TypeName  = pexReader.ReadString();
            fd.UserFlags = pexReader.ReadInt32();
            {
                // Type Reference
                fd.DefaultValue = ReadValueReference(asm, fd.TypeName);
            }
            fd.Flags = pexReader.ReadByte(); //== 1;
            return(fd);
        }
Ejemplo n.º 18
0
        private void ReadStructs(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef)
        {
            var structCount = pexReader.ReadInt16();

            for (var i = 0; i < structCount; i++)
            {
                var structDef = new PapyrusTypeDefinition(asm, true);
                structDef.IsStruct = true;
                structDef.Name     = pexReader.ReadStringRef();

                var variableCount = pexReader.ReadInt16();
                for (var l = 0; l < variableCount; l++)
                {
                    structDef.Fields.Add(ReadDocumentedField(asm, typeDef));
                }
                typeDef.NestedTypes.Add(structDef);
            }
        }
Ejemplo n.º 19
0
        public PapyrusReferenceAndConstantValueViewModel(List <PapyrusAssemblyDefinition> loadedAssemblies,
                                                         PapyrusTypeDefinition currentType,
                                                         PapyrusMethodDefinition currentMethod, OpCodeArgumentDescription desc, PapyrusPrimitiveType[] argumentTypes)
        {
            this.loadedAssemblies = loadedAssemblies;
            this.currentType      = currentType;
            this.currentMethod    = currentMethod;
            this.desc             = desc;
            this.argumentTypes    = argumentTypes;

            if (argumentTypes == null)
            {
                argumentTypes = new PapyrusPrimitiveType[0];
            }

            // Update the type constraints so we are only able to assign
            // values of the correct types.
            if (desc != null && argumentTypes.Length > 0)
            {
                UpdateTypeConstraints(argumentTypes);
            }

            if (currentMethod != null)
            {
                var references = new List <PapyrusMemberReference>();
                references.AddRange(currentMethod.Parameters);
                references.AddRange(currentMethod.GetVariables());
                if (currentType != null)
                {
                    references.AddRange(currentType.Fields);
                }

                ReferenceCollection = new ObservableCollection <PapyrusMemberReference>(references);

                HideValueInputs();

                ReferenceValueVisibility = Visibility.Visible;

                //SelectedValueType = ReferenceCollection.LastOrDefault();
            }
            ComboBoxItems     = new ObservableCollection <FrameworkElement>(CreateComboBoxItems());
            SelectedValueType = ComboBoxItems.First() as ComboBoxItem;
        }
Ejemplo n.º 20
0
        public Collection <PapyrusTypeDefinition> ReadTypeDefinitions(PapyrusAssemblyDefinition asm)
        {
            var types = new Collection <PapyrusTypeDefinition>();

            var classCount = pexReader.ReadInt16();

            for (var j = 0; j < classCount; j++)
            {
                var typeDef = new PapyrusTypeDefinition(asm);
                typeDef.IsClass = true;

                if (asm.VersionTarget == PapyrusVersionTargets.Fallout4)
                {
                    ReadTypeInfo(asm, typeDef);

                    ReadStructs(asm, typeDef);

                    ReadFields(asm, typeDef);

                    ReadProperties(asm, typeDef);

                    ReadStates(asm, typeDef);
                }
                else
                {
                    typeDef.Name = pexReader.ReadStringRef();
                    typeDef.Size = pexReader.ReadInt32();
                    // pexReader.DEBUGGING = true
                    typeDef.BaseTypeName  = pexReader.ReadStringRef();
                    typeDef.Documentation = pexReader.ReadStringRef();
                    typeDef.UserFlags     = pexReader.ReadInt32();
                    typeDef.AutoStateName = pexReader.ReadStringRef();

                    ReadFields(asm, typeDef);

                    ReadProperties(asm, typeDef);

                    ReadStates(asm, typeDef);
                }
                types.Add(typeDef);
            }
            return(types);
        }
Ejemplo n.º 21
0
        private List <PapyrusMethodDefinition> CreateMethods(
            ICollection <PapyrusAssemblyDefinition> papyrusAssemblyCollection, TypeDefinition type,
            PapyrusTypeDefinition papyrusType, PapyrusAssemblyDefinition pex, PapyrusCompilerOptions options)
        {
            var methods = delegatePairDefinition.DelegateMethodDefinitions.Select(method
                                                                                  => CreatePapyrusMethodDefinition(papyrusAssemblyCollection, pex, papyrusType, method, delegatePairDefinition, options)).ToList();

            foreach (var method in type.Methods.OrderByDescending(m => m.IsConstructor))
            {
                if (propertyMethods.Contains(method))
                {
                    continue;
                }

                methods.Add(CreatePapyrusMethodDefinition(papyrusAssemblyCollection, pex, papyrusType, method,
                                                          delegatePairDefinition, options));
            }
            return(methods);
        }
Ejemplo n.º 22
0
        public PapyrusMethodSelectorViewModel(List <PapyrusAssemblyDefinition> loadedAssemblies,
                                              PapyrusTypeDefinition currentType, OpCodeArgumentDescription opCodeArgumentDescription)
        {
            this.loadedAssemblies = loadedAssemblies;

            if (currentType != null)
            {
                Methods =
                    new ObservableCollection <PapyrusViewModel>(
                        currentType.States.SelectMany(s => s.Methods)
                        .OrderBy(m => m.Name?.Value)
                        .Select(j => new PapyrusViewModel
                {
                    Text = j.Name.Value + GetParameterString(j.Parameters) + " : " + j.ReturnTypeName.Value,
                    Item = j
                }));
            }

            SelectedMethodCommand = new RelayCommand <PapyrusViewModel>(SelectMethod);
        }
Ejemplo n.º 23
0
        private void ProcessInstructions(IEnumerable <PapyrusAssemblyDefinition> papyrusAssemblyCollection,
                                         IDelegatePairDefinition delegatePairDef, MethodDefinition method, PapyrusAssemblyDefinition asm,
                                         PapyrusTypeDefinition papyrusType, PapyrusMethodDefinition m, PapyrusCompilerOptions options)
        {
            var papyrusInstructions =
                instructionProcessor.ProcessInstructions(papyrusAssemblyCollection, delegatePairDef, asm, papyrusType, m,
                                                         method, method.Body, method.Body.Instructions, options);

            if (method.Name.ToLower() == "oninit")
            {
                List <PapyrusInstruction> structGets;
                var ip = instructionProcessor as ClrInstructionProcessor;
                // TODO: Going against solid here just because im to damn tired, which I ended up breaking in lots of places.
                m.Body.Instructions.Insert(0,
                                           ip.CallProcessor.CreatePapyrusCallInstruction(instructionProcessor, PapyrusOpCodes.Callmethod, constructor,
                                                                                         "self",
                                                                                         "::nonevar", new List <object>(), out structGets));
            }

            m.Body.Instructions.AddRange(papyrusInstructions);
        }
Ejemplo n.º 24
0
        private void ReadProperties(PapyrusAssemblyDefinition asm, PapyrusTypeDefinition typeDef)
        {
            var propDefs      = new Collection <PapyrusPropertyDefinition>();
            var propertyCount = pexReader.ReadInt16();

            for (var i = 0; i < propertyCount; i++)
            {
                var prop = new PapyrusPropertyDefinition(asm);
                prop.Name          = pexReader.ReadStringRef();
                prop.TypeName      = pexReader.ReadStringRef();
                prop.Documentation = pexReader.ReadStringRef();
                prop.Userflags     = pexReader.ReadInt32();
                prop.Flags         = pexReader.ReadByte();
                if (prop.IsAuto)
                {
                    prop.AutoName = pexReader.ReadString();
                }
                else
                {
                    if (prop.HasGetter)
                    {
                        prop.GetMethod          = ReadMethod(asm);
                        prop.GetMethod.IsGetter = true;
                        prop.GetMethod.PropName = prop.Name.Value;
                    }
                    if (prop.HasSetter)
                    {
                        prop.SetMethod          = ReadMethod(asm);
                        prop.SetMethod.IsSetter = true;
                        prop.SetMethod.PropName = prop.Name.Value;
                    }
                }
                propDefs.Add(prop);
            }
            typeDef.Properties = propDefs;
        }
Ejemplo n.º 25
0
 private void AddTypeDefinition(TypeDefinition owningType, PapyrusStringRef name, PapyrusTypeDefinition type,
                                bool isNested)
 {
     AddTypeDefinition(owningType, name.Value, type, isNested);
 }
Ejemplo n.º 26
0
        private void AddTypeDefinition(TypeDefinition owningType, string name, PapyrusTypeDefinition type, bool isNested)
        {
            if (mainModule.Types.Any(t => t.Name.ToLower() == name.ToLower()))
            {
                // Type already exists? Don't do anything.
                return;
            }

            var newType = new TypeDefinition(NamespaceResolver.Resolve(name), name,
                                             isNested
                    ? TypeAttributes.NestedPublic | TypeAttributes.SequentialLayout | TypeAttributes.BeforeFieldInit |
                                             TypeAttributes.Sealed
                    : TypeAttributes.Public | TypeAttributes.Class);

            if (isNested)
            {
                newType.IsClass  = false;
                newType.BaseType = mainModule.Import(typeof(ValueType));

                if (owningType.NestedTypes.Any(t => t.Name.ToLower() == name.ToLower()))
                {
                    // Structure already exists? Don't do anything.
                    return;
                }
                owningType.NestedTypes.Add(newType);
            }
            else
            {
                mainModule.Types.Add(newType);
            }

            AddEmptyConstructor(newType);

            if (!isNested)
            {
                if (!string.IsNullOrEmpty(type.BaseTypeName?.Value))
                {
                    var baseType = ResolveTypeReference(null, type.BaseTypeName.Value);
                    newType.BaseType = baseType ?? objectType;
                }
                else
                {
                    newType.BaseType = objectType;
                }
            }

            foreach (var field in type.Fields)
            {
                var fieldType = field.DefaultValue;
                var typeName  = fieldType.Name;
                var typeRef   = ResolveTypeReference(null, typeName);

                var attributes = FieldAttributes.Public;

                if (field.Name.Value.ToLower().EndsWith("_var"))
                {
                    if (type.Properties.Any(
                            n => field.Name.Value.Contains('_') && n.Name.Value == field.Name.Value.Split('_')[0] ||
                            n.AutoName == field.Name.Value))
                    {
                        attributes = FieldAttributes.Private;
                    }
                }

                //if (field.IsConst)
                //{
                //    attributes |= FieldAttributes.InitOnly;
                //}

                var fieldDef = new FieldDefinition(field.Name.Value.Replace("::", ""), attributes, typeRef);
                newType.Fields.Add(fieldDef);
            }

            foreach (var prop in type.Properties)
            {
                FieldDefinition targetField = null;
                foreach (var field in newType.Fields)
                {
                    if (!string.IsNullOrEmpty(prop.AutoName))
                    {
                        if (prop.AutoName.Contains(field.Name))
                        {
                            targetField = field;
                            break;
                        }
                    }
                    if (field.Name.ToLower().Contains(prop.Name.Value.ToLower() + "_var"))
                    {
                        targetField = field;
                        break;
                    }
                }

                var typeRef = ResolveTypeReference(null, prop.TypeName);

                newType.AddProperty(nameConventionResolver.Resolve(prop.Name.Value), typeRef, targetField);
            }


            foreach (var structure in type.NestedTypes)
            {
                AddTypeDefinition(newType, structure.Name, structure, true);
            }

            foreach (var state in type.States)
            {
                foreach (var method in state.Methods)
                {
                    method.Name.Value = nameConventionResolver.Resolve(method.Name.Value);

                    var typeRef    = ResolveTypeReference(null, method.ReturnTypeName);
                    var attributes = MethodAttributes.Public;

                    if (method.IsGlobal /* || method.IsNative */)
                    {
                        attributes |= MethodAttributes.Static;
                    }
                    else if (method.IsEvent)
                    {
                        attributes |= MethodAttributes.Virtual;
                        attributes |= MethodAttributes.NewSlot;
                    }


                    var methodDef = new MethodDefinition(method.Name.Value, attributes, typeRef);

                    // methodDef.IsNative = method.IsNative;
                    foreach (var param in method.Parameters)
                    {
                        var paramTypeRef = ResolveTypeReference(null, param.TypeName);
                        var paramDef     = new ParameterDefinition(param.Name.Value, ParameterAttributes.None, paramTypeRef);
                        methodDef.Parameters.Add(paramDef);
                    }

                    var existingMethod =
                        newType.Methods.Any(m => m.Name == methodDef.Name &&
                                            methodDef.ReturnType == typeRef &&
                                            methodDef.Parameters.Count == m.Parameters.Count
                                            );

                    if (!existingMethod)
                    {
                        CreateEmptyFunctionBody(ref methodDef);
                        newType.Methods.Add(methodDef);
                    }
                }
            }
            // return newType;
        }
        private void BuildType(TypeBuilder definedType, PapyrusTypeDefinition type)
        {
            //definedType.BaseType = DefinedTypes[0].DeclaringType


            var myCtorBuilder = definedType.DefineConstructor(
                MethodAttributes.Public,
                CallingConventions.HasThis, Type.EmptyTypes);

            BuildConstructor(myCtorBuilder.GetILGenerator());


            foreach (var f in type.Fields)
            {
                //    Type[] paramTypes = GetParameterTypes(m.Parameters);
                //    Type returnType = GetReturnType(m.ReturnTypeName.Value);
                //    MethodAttributes accessAttributes = GetMethodAttributes(m);

                //    var method = definedType.DefineMethod(m.Name.Value, accessAttributes, CallingConventions.Standard, returnType, paramTypes);
                //    CreateEmptyBody(method.GetILGenerator(), returnType);
            }

            foreach (var p in type.Properties)
            {
                //    Type[] paramTypes = GetParameterTypes(m.Parameters);
                //    Type returnType = GetReturnType(m.ReturnTypeName.Value);
                //    MethodAttributes accessAttributes = GetMethodAttributes(m);

                //    var method = definedType.DefineMethod(m.Name.Value, accessAttributes, CallingConventions.Standard, returnType, paramTypes);
                //    CreateEmptyBody(method.GetILGenerator(), returnType);
            }

            // Structs
            foreach (var t in type.NestedTypes)
            {
            }

            foreach (var state in type.States)
            {
                foreach (var m in state.Methods)
                {
                    var paramTypes = GetParameterTypes(m.Parameters);
                    var returnType = GetType(m.ReturnTypeName.Value);

                    var callingConvention = CallingConventions.Standard;
                    if (m.IsGlobal || m.IsNative)
                    {
                        callingConvention = CallingConventions.HasThis;
                    }

                    var method = definedType.DefineMethod(m.Name.Value, MethodAttributes.Public, callingConvention,
                                                          returnType, paramTypes);

                    //var pi = 1;
                    //foreach (var p in m.Parameters)
                    //{
                    //    method.DefineParameter(pi++, ParameterAttributes.None, p.Name.Value);
                    //}

                    if (callingConvention == CallingConventions.HasThis)
                    {
                        method.GetILGenerator().Emit(OpCodes.Ldarg_0);
                    }

                    CreateEmptyBody(method.GetILGenerator(), returnType);
                }
            }
        }
Ejemplo n.º 28
0
        private PapyrusMethodDefinition CreatePapyrusMethodDefinition(
            IEnumerable <PapyrusAssemblyDefinition> papyrusAssemblyCollection, PapyrusAssemblyDefinition asm,
            PapyrusTypeDefinition papyrusType,
            MethodDefinition method, IDelegatePairDefinition delegatePairDef, PapyrusCompilerOptions options)
        {
            if (method.IsConstructor)
            {
                // Replace: .ctor with __ctor
                method.Name = method.Name.Replace(".", "__");
                constructor = method;
            }

            var m = new PapyrusMethodDefinition(asm);

            m.Documentation = "".Ref(asm);
            m.UserFlags     = attributeReader.ReadPapyrusAttributes(method).UserFlagsValue;
            m.IsGlobal      = method.IsStatic;
            m.IsNative      = method.CustomAttributes.Any(i => i.AttributeType.Name.Equals("NativeAttribute"));
            m.Name          = method.Name.Ref(asm);
            var papyrusReturnType = Utility.GetPapyrusReturnType(method.ReturnType, activeClrType);

            if (EnumDefinitions.Any(m2 => m2.FullName == method.ReturnType.FullName))
            {
                papyrusReturnType = "Int";
            }

            m.ReturnTypeName = papyrusReturnType.Ref(asm); // method.ReturnType.Name
            m.Parameters     = new List <PapyrusParameterDefinition>();
            foreach (var p in method.Parameters)
            {
                // TODO: Add support for delegate as parameter

                var paramTypeName = Utility.GetPapyrusReturnType(p.ParameterType, activeClrType, true);

                // Replace enum types into Integer
                if (EnumDefinitions.Any(i => i.FullName == p.ParameterType.FullName))
                {
                    paramTypeName = "Int";
                }

                m.Parameters.Add(new PapyrusParameterDefinition
                {
                    Name     = p.Name.Ref(asm),
                    TypeName = paramTypeName.Ref(asm)
                });
            }

            var clrVariables = method.Body.Variables;

            var varNum = 0;

            foreach (var clrVar in clrVariables)
            {
                var delegateVars =
                    delegatePairDef.DelegateMethodLocalPair.Where(d => d.Key == method).SelectMany(d => d.Value);

                if (delegateVars.Any(d => "V_" + d.Index == "V_" + clrVar.Index))
                {
                    // This local variable is pointing to a delegate
                    // and since we are removing all Delegate types, this wont work. So we have to change the type into something else.
                    // in this case, we are changing it into a Int

                    if (!clrVar.Name.Contains("$<>"))
                    // if we are reading symbols, delegate variables contains unwanted characters in their names.
                    // And since those are not going to be used. We can just skip these.
                    {
                        var varName = (!string.IsNullOrEmpty(clrVar.Name) ? clrVar.Name : clrVar.ToString()).Ref(asm);

                        var delegateInvokeRef = delegateFinder.FindDelegateInvokeReference(delegatePairDefinition, m);

                        m.Body.Variables.Add(new PapyrusVariableReference(varName, "Int".Ref(asm))
                        {
                            IsDelegateReference     = true,
                            DelegateInvokeReference = delegateInvokeRef,
                            Value = varName.Value,
                            Type  = PapyrusPrimitiveType.Reference
                        });
                    }
                }
                else
                {
                    var varName          = (!string.IsNullOrEmpty(clrVar.Name) ? clrVar.Name : clrVar.ToString()).Ref(asm);
                    var variableTypeName = Utility.GetPapyrusReturnType(clrVar.VariableType.FullName);

                    // If its an enum, we want to change the type into a Int
                    if (EnumDefinitions.Any(i => i.FullName == clrVar.VariableType.FullName))
                    {
                        variableTypeName = "Int";
                    }

                    m.Body.Variables.Add(new PapyrusVariableReference(varName, variableTypeName.Ref(asm))
                    {
                        Value = varName.Value,
                        Type  = PapyrusPrimitiveType.Reference
                    });
                }
                varNum++;
            }

            if (method.HasBody)
            {
                ProcessInstructions(papyrusAssemblyCollection, delegatePairDef, method, asm, papyrusType, m, options);

                if (papyrusReturnType == "None")
                {
                    if (m.Body.Variables.All(n => n.Name.Value.ToLower() != "::nonevar"))
                    {
                        var nonevar = "::NoneVar".Ref(asm);
                        m.Body.Variables.Add(new PapyrusVariableReference(nonevar, "None".Ref(asm))
                        {
                            Value = nonevar.Value,
                            Type  = PapyrusPrimitiveType.Reference
                        });
                    }
                }
                m.Body.Instructions.RecalculateOffsets();
            }

            return(m);
        }
Ejemplo n.º 29
0
        private List <PapyrusPropertyDefinition> CreateProperties(
            IEnumerable <PapyrusAssemblyDefinition> papyrusAssemblyCollection, TypeDefinition type,
            PapyrusTypeDefinition papyrusType, PapyrusAssemblyDefinition pex)
        {
            var propList = new List <PapyrusPropertyDefinition>();

            foreach (var prop in type.Properties)
            {
                var properties       = attributeReader.ReadPapyrusAttributes(prop);
                var propertyTypeName = Utility.GetPapyrusReturnType(prop.PropertyType);

                if (EnumDefinitions.Any(i => i.FullName == prop.PropertyType.FullName))
                {
                    propertyTypeName = "Int";
                }

                var papyrusPropertyDefinition = new PapyrusPropertyDefinition(pex, prop.Name,
                                                                              propertyTypeName)
                {
                    Documentation = "".Ref(pex),
                    Userflags     = properties.UserFlagsValue
                };

                var result = propertyAnalyzer.Analyze(prop);

                if (result.IsAutoVar)
                {
                    papyrusPropertyDefinition.IsAuto   = true;
                    papyrusPropertyDefinition.AutoName = result.AutoVarName;
                }
                else
                {
                    if (prop.SetMethod != null)
                    {
                        papyrusPropertyDefinition.HasSetter = true;
                        papyrusPropertyDefinition.SetMethod = CreatePapyrusMethodDefinition(papyrusAssemblyCollection,
                                                                                            pex, papyrusType, prop.SetMethod,
                                                                                            delegatePairDefinition,
                                                                                            processorOptions);
                        propertyMethods.Add(prop.SetMethod);
                    }

                    if (prop.GetMethod != null)
                    {
                        papyrusPropertyDefinition.HasGetter = true;
                        papyrusPropertyDefinition.GetMethod = CreatePapyrusMethodDefinition(papyrusAssemblyCollection,
                                                                                            pex, papyrusType, prop.GetMethod,
                                                                                            delegatePairDefinition,
                                                                                            processorOptions);
                        propertyMethods.Add(prop.GetMethod);
                    }

                    if (prop.SetMethod == null && prop.GetMethod == null)
                    {
                        papyrusPropertyDefinition.IsAuto   = true;
                        papyrusPropertyDefinition.AutoName =
                            papyrusType.Fields.FirstOrDefault(
                                f =>
                                f.Name.Value.Contains("_" + prop.Name + "_") &&
                                f.Name.Value.EndsWith("_BackingField")).Name.Value;
                    }
                }
                propList.Add(papyrusPropertyDefinition);
            }
            return(propList);
        }
Ejemplo n.º 30
0
        private void CreateDebugInfo(PapyrusAssemblyDefinition pex, PapyrusTypeDefinition papyrusType,
                                     TypeDefinition type)
        {
            var debug = pex.DebugInfo;

            debug.DebugTime = UnixTimeConverterUtility.Convert(DateTime.Now);

            if (pex.VersionTarget == PapyrusVersionTargets.Fallout4)
            {
                foreach (var t in papyrusType.NestedTypes)
                {
                    var structInfo = new PapyrusStructDescription();
                    structInfo.Name = papyrusType.Name;
                    structInfo.DeclaringTypeName = type.Name.Ref(pex);

                    foreach (var f in t.Fields)
                    {
                        structInfo.FieldNames.Add(f.Name);
                    }

                    debug.StructDescriptions.Add(structInfo);
                }
            }

            foreach (var s in papyrusType.States)
            {
                foreach (var method in s.Methods)
                {
                    var m = new PapyrusMethodDecription();
                    m.Name = method.Name;
                    m.DeclaringTypeName = type.Name.Ref(pex);
                    m.StateName         = "".Ref(pex);

                    if (method.Name.Value.ToLower().StartsWith("get_"))
                    {
                        m.MethodType = PapyrusMethodTypes.Getter;
                    }
                    else if (method.Name.Value.ToLower().StartsWith("set_"))
                    {
                        m.MethodType = PapyrusMethodTypes.Setter;
                    }
                    else
                    {
                        m.MethodType = PapyrusMethodTypes.Method;
                    }
                    var lastStart = 0;
                    method.Body.Instructions.ForEach(i =>
                    {
                        if (i.SequencePoint != null)
                        {
                            lastStart = i.SequencePoint.StartLine;
                            m.BodyLineNumbers.Add((short)i.SequencePoint.StartLine);
                        }
                        else
                        {
                            m.BodyLineNumbers.Add((short)lastStart);
                        }
                    });

                    debug.MethodDescriptions.Add(m);
                }
            }

            var stateProperties = new PapyrusStatePropertyDescriptions();

            stateProperties.GroupDocumentation = "".Ref(pex);
            stateProperties.GroupName          = "".Ref(pex);
            stateProperties.ObjectName         = type.Name.Ref(pex);

            foreach (var prop in type.Properties)
            {
                // TODO: This
                stateProperties.PropertyNames.Add(prop.Name.Ref(pex));
            }
            debug.PropertyDescriptions.Add(stateProperties);
        }