/// <summary> /// </summary> /// <param name="statusCallback"></param> /// <param name="wordDictionaryFile"></param> public DictionaryPapyrusNameResolver(IStatusCallbackService statusCallback, string wordDictionaryFile = null) { statusCallbackService = statusCallback; // "wordlist.txt" if (string.IsNullOrEmpty(wordDictionaryFile)) { return; } if (File.Exists(wordDictionaryFile)) { statusCallbackService.WriteLine("Loading wordlist... This may take a few seconds."); WordList = File.ReadAllLines(wordDictionaryFile); } else { statusCallbackService.WriteLine("Wordlist was not found, skipping..."); WordList = new string[0]; } }
/// <summary> /// Builds a .NET Assembly using the input Papyrus Source /// </summary> /// <param name="inputSourceFiles"></param> public async void BuildAssembly(string[] inputSourceFiles) { // @"C:\The Elder Scrolls V Skyrim\Data\scripts\Source" var files = inputSourceFiles; var resolvedAssemblyName = AssemblyNameResolver.Resolve(null); CoreAssembly = AssemblyDefinition.CreateAssembly( resolvedAssemblyName, resolvedAssemblyName.Name, ModuleKind.Dll); MainModule = CoreAssembly.MainModule; var papyrusObjects = new List <PapyrusAssemblyObject>(); StatusCallback.WriteLine("Parsing Papyrus... This usually takes about 30 seconds."); totalFilesToParse = files.Length; var asyncParse = files.Select(Parse); papyrusObjects.AddRange(await Task.WhenAll(asyncParse.ToArray())); StatusCallback.Title = "PapyrusDotNet"; StatusCallback.WriteLine("Adding object references... This usually takes about a minute."); foreach (var pasObj in papyrusObjects) { AddedTypeReferences.Add(TypeReferenceResolver.Resolve(MainModule, null, pasObj.Name)); } foreach (var pas in papyrusObjects) { MainModule.Types.Add(TypeDefinitionResolver.Resolve(MainModule, pas)); } StatusCallback.WriteLine("Resolving object references... This usually takes about 30 seconds."); foreach (var t in MainModule.Types) { foreach (var f in t.Methods) { var typeDefinition = MainModule.Types.FirstOrDefault(ty => ty.FullName == f.ReturnType.FullName); f.ReturnType = TypeReferenceResolver.Resolve(MainModule, typeDefinition, f.ReturnType.FullName); foreach (var p in f.Parameters) { var td = MainModule.Types.FirstOrDefault(ty => ty.FullName == p.ParameterType.FullName); if (td != null) { /* // Most likely a System object. * p.ParameterType = GetTypeReference(null, p.ParameterType.FullName); * else */ p.ParameterType = TypeReferenceResolver.Resolve(MainModule, typeDefinition, td.FullName); } } } } StatusCallback.WriteLine("Importing Papyrus specific attributes..."); var allAttributesToInclude = Assembly.GetExecutingAssembly().GetTypes().Where( t => t.Name.ToLower().EndsWith("attribute") //TODO: we should include the PapyrusDotNet.System here as well. ); foreach (var attr in allAttributesToInclude) { ImportType(MainModule, attr); } CoreAssembly.Write(AssemblyNameResolver.OutputLibraryFilename); StatusCallback.ForegroundColor = ConsoleColor.Green; StatusCallback.WriteLine(AssemblyNameResolver.OutputLibraryFilename + " successefully generated."); StatusCallback.ResetColor(); }
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); }