public IEnumerable <PapyrusInstruction> ProcessInstructions(PapyrusAssemblyDefinition targetPapyrusAssembly, PapyrusTypeDefinition targetPapyrusType, PapyrusMethodDefinition targetPapyrusMethod, MethodDefinition method, MethodBody body, Collection <Instruction> instructions, PapyrusCompilerOptions options) { throw new NotImplementedException(); }
/// <summary> /// Initializes a new instance of the <see cref="Clr2PapyrusConverter" /> class. /// </summary> /// <param name="userInterface"></param> /// <param name="instructionProcessor">The instruction processor.</param> /// <param name="processorOptions"></param> public Clr2PapyrusConverter( IUserInterface userInterface, IClrInstructionProcessor instructionProcessor, PapyrusCompilerOptions processorOptions) { attributeReader = new PapyrusAttributeReader(new PapyrusValueTypeConverter()); this.userInterface = userInterface; this.instructionProcessor = instructionProcessor; this.processorOptions = processorOptions; delegateFinder = new DelegateFinder(); }
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); }
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); }
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); }
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); }
private PapyrusTypeDefinition CreateStruct(TypeDefinition structType, PapyrusAssemblyDefinition asm, PapyrusCompilerOptions options) { return(CreateType(asm, structType, options, true)); }