private void Load() { ThreadHelper.ThrowIfNotOnUIThread(); if (Filename != null && File.Exists(Filename)) { try { string jsonString = File.ReadAllText(Filename); Settings = JsonConvert.DeserializeObject <SolutionSettings>(jsonString); } catch (Exception e) { OutputLog.Error(e.Message); } } }
private void FixOverlaps(LayoutNode node) { ThreadHelper.ThrowIfNotOnUIThread(); if (node.Type.Length > 0 && node.Type.StartsWith("union")) { node.Category = LayoutNode.LayoutCategory.Union; node.Extra = node.Children; node.Children = new List <LayoutNode>(); } if (node.Category != LayoutNode.LayoutCategory.Union) { for (int i = 1; i < node.Children.Count;) { var thisNode = node.Children[i]; var prevNode = node.Children[i - 1]; if (thisNode.Offset == prevNode.Offset) { if (prevNode.IsBaseCategory() && prevNode.Size == 1) { //Empty base optimization node.Extra.Add(prevNode); node.Children.RemoveAt(i - 1); } else { //Found unknown overlap OutputLog.Log("Found type overlap without known explanation"); ++i; } } else { ++i; } } } //continue recursion foreach (LayoutNode child in node.Children) { FixOverlaps(child); } }
public override ProjectProperties GetProjectData() { ThreadHelper.ThrowIfNotOnUIThread(); OutputLog.Log("Capturing configuration from CMake..."); Document document = EditorUtils.GetActiveDocument(); if (document == null) { return(null); } var evaluator = new MacroEvaluatorCMake(); var customSettings = SettingsManager.Instance.Settings; string commandsFile = customSettings == null ? null : customSettings.CMakeCommandsFile; commandsFile = commandsFile == null ? null : evaluator.Evaluate(commandsFile); if (commandsFile == null || commandsFile.Length == 0) { var activeConfig = GetActiveConfiguration(); if (activeConfig != null) { var cmakeArgsEvaluator = new MacroEvaluatorCMakeArgs(); commandsFile = cmakeArgsEvaluator.Evaluate(activeConfig.buildRoot); if (commandsFile.Length > 0) { char lastchar = commandsFile[commandsFile.Length - 1]; if (lastchar != '\\' && lastchar != '/') { commandsFile += '\\'; } commandsFile += "compile_commands.json"; } } } var ret = CaptureCMakeCommands(commandsFile, document.FullName); AddCustomSettings(ret, evaluator); return(ret); }
protected override void ProcessPostProjectData(ProjectProperties projProperties) { ThreadHelper.ThrowIfNotOnUIThread(); for (int i = 0; i < projProperties.ForceIncludes.Count; ++i) { string pchFile = projProperties.ForceIncludes[i] + ".pch"; if (File.Exists(pchFile)) { OutputLog.Log("Found incompatible pch file, generating alias for: " + pchFile); string originalName = projProperties.ForceIncludes[i]; string newName = Path.GetDirectoryName(originalName) + @"\SL_" + Path.GetFileName(originalName); projProperties.ForceIncludes[i] = newName; File.Copy(originalName, newName, true); } } }
public void Save() { ThreadHelper.ThrowIfNotOnUIThread(); TryRefreshFilename(); if (Filename != null && Settings != null) { try { string jsonString = JsonConvert.SerializeObject(Settings, Formatting.Indented); File.WriteAllText(Filename, jsonString); } catch (Exception e) { OutputLog.Error(e.Message); } } }
private CMakeConfiguration GetActiveConfiguration() { ThreadHelper.ThrowIfNotOnUIThread(); string solutionPath = EditorUtils.GetSolutionPath(); if (solutionPath == null || solutionPath.Length == 0) { return(null); } string settingsFilename = solutionPath + "CMakeSettings.json"; if (File.Exists(settingsFilename)) { CMakeSettings settings = null; try { string jsonString = File.ReadAllText(settingsFilename); settings = JsonConvert.DeserializeObject <CMakeSettings>(jsonString); } catch (Exception e) { OutputLog.Error(e.Message); } string activeConfigName = GetActiveConfigurationName(); if (activeConfigName != null && activeConfigName.Length > 0 && settings != null && settings.configurations != null) { foreach (CMakeConfiguration config in settings.configurations) { if (config.name == activeConfigName) { return(config); } } } } return(null); }
/// <summary> /// Initialization of the package; this method is called right after the package is sited, so this is the place /// where you can put all the initialization code that rely on services provided by VisualStudio. /// </summary> /// <param name="cancellationToken">A cancellation token to monitor for initialization cancellation, which can occur when VS is shutting down.</param> /// <param name="progress">A provider for progress updates.</param> /// <returns>A task representing the async work of package initialization, or an already completed task if there is none. Do not return null from this method.</returns> protected override async Task InitializeAsync(CancellationToken cancellationToken, IProgress <ServiceProgressData> progress) { // When initialized asynchronously, the current thread may be a background thread at this point. // Do any initialization that requires the UI thread after switching to the UI thread. await this.JoinableTaskFactory.SwitchToMainThreadAsync(cancellationToken); OutputLog.Initialize(this); LayoutParser.SetupParser(); SettingsManager.Instance.Initialize(this); EditorUtils.Initialize(this); await LayoutWindowCommand.InitializeAsync(this); await ParseCommand.InitializeAsync(this); await Editor.SettingsCommand.InitializeAsync(this); await Editor.DocumentationCommand.InitializeAsync(this); await Editor.ReportIssueCommand.InitializeAsync(this); await Editor.AboutCommand.InitializeAsync(this); }
private XmlNode SearchInProjectFile(Project project, string modulePath) { ThreadHelper.ThrowIfNotOnUIThread(); //Get Relative path to modulePath from projectPath string projectPath = Path.GetDirectoryName(project.FullName) + '\\'; string relativePath = MakeRelativePath(projectPath, modulePath); if (relativePath == null) { return(null); } relativePath += "\\"; XmlDocument doc = new XmlDocument(); doc.Load(project.FullName); if (doc == null) { return(null); } XmlNodeList compileUnits = doc.GetElementsByTagName("ClCompile"); foreach (XmlNode tu in compileUnits) { XmlNode fileName = tu.Attributes.GetNamedItem("Include"); if (fileName != null && fileName.InnerText.StartsWith(relativePath)) { string fileRelativeToModule = fileName.InnerText.Substring(relativePath.Length); OutputLog.Log("Found compilation unit in same module: " + fileRelativeToModule); return(tu); } } OutputLog.Log("Could not find any compilation unit in the same Unreal module."); return(null); }
private ProjectProperties CaptureCMakeCommands(string commandsFile, string documentName) { ThreadHelper.ThrowIfNotOnUIThread(); var ret = new ProjectProperties(); if (commandsFile == null || commandsFile.Length == 0) { OutputLog.Log("Unable to retrieve a CMake commands file.\nMake sure the cmake flag -DCMAKE_EXPORT_COMPILE_COMMANDS=1 is set and the options are pointing to the proper file."); } else { if (File.Exists(commandsFile)) { OutputLog.Log("Capturing commands from CMake commands file: " + commandsFile); List <CMakeCommandEntry> allCommands = null; try { string jsonString = File.ReadAllText(commandsFile); allCommands = JsonConvert.DeserializeObject <List <CMakeCommandEntry> >(jsonString); } catch (Exception e) { OutputLog.Error(e.Message); } ExtractCMakeProjectProperties(ret, FindBestCMakeEntry(allCommands, documentName)); } else { OutputLog.Log("Unable to find CMake commands file at " + commandsFile + ".\nMake sure the cmake flag -DCMAKE_EXPORT_COMPILE_COMMANDS=1 is set and the options are pointing to the proper file."); } } return(ret); }
public override ProjectProperties GetProjectData() { ThreadHelper.ThrowIfNotOnUIThread(); OutputLog.Log("Using manual configuration..."); var ret = new ProjectProperties(); Project project = EditorUtils.GetActiveProject(); VCProject prj = project == null ? null : project.Object as VCProject; VCConfiguration config = prj == null ? null : prj.ActiveConfiguration; VCPlatform platform = config == null ? null : config.Platform; if (platform != null) { AddCustomSettings(ret, new MacroEvaluatorVisualPlatform(platform)); } else { AddCustomSettings(ret, new MacroEvaluatorCMake()); } return(ret); }
private void ExtractCMakeProjectProperties(ProjectProperties inout, CMakeCommandEntry command) { ThreadHelper.ThrowIfNotOnUIThread(); if (command == null) { return; } OutputLog.Log("Extracting commands from Translation Unit: " + command.file); inout.WorkingDirectory = command.directory; List <string> commands = ParseCommands(command.command); for (int i = 0; i < commands.Count; ++i) { string com = commands[i]; if (com.Length > 2 && com[0] == '-' || com[0] == '/') { if (com[1] == 'D') { inout.PrepocessorDefinitions.Add(com.Substring(2, com.Length - 2)); } else if (com[1] == 'I') { inout.IncludeDirectories.Add(com.Substring(2, com.Length - 2)); } else if (com == "-m32") { inout.Target = ProjectProperties.TargetType.x86; } else if (com == "-m64") { inout.Target = ProjectProperties.TargetType.x64; } else if (com.StartsWith("-std")) { string standard = com.Substring(5, com.Length - 5); if (standard == "c++98") { inout.Standard = ProjectProperties.StandardVersion.Cpp98; } else if (standard == "c++03") { inout.Standard = ProjectProperties.StandardVersion.Cpp03; } else if (standard == "c++14") { inout.Standard = ProjectProperties.StandardVersion.Cpp14; } else if (standard == "c++17") { inout.Standard = ProjectProperties.StandardVersion.Cpp17; } else if (standard == "c++20") { inout.Standard = ProjectProperties.StandardVersion.Cpp20; } else if (standard == "gnu++98") { inout.Standard = ProjectProperties.StandardVersion.Gnu98; } else if (standard == "gnu++03") { inout.Standard = ProjectProperties.StandardVersion.Gnu03; } else if (standard == "gnu++14") { inout.Standard = ProjectProperties.StandardVersion.Gnu14; } else if (standard == "gnu++17") { inout.Standard = ProjectProperties.StandardVersion.Gnu17; } else if (standard == "gnu++20") { inout.Standard = ProjectProperties.StandardVersion.Gnu20; } else { inout.Standard = ProjectProperties.StandardVersion.Latest; } } else if (com.StartsWith("-include")) { inout.IncludeDirectories.Add(com.Substring(8, com.Length - 8)); } } } }
public async Task <ParseResult> ParseAsync(ProjectProperties projProperties, DocumentLocation location) { await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync(); ParseResult ret = new ParseResult(); if (location.Filename == null || location.Filename.Length == 0) { OutputLog.Error("No file provided for parsing"); ret.Status = ParseResult.StatusCode.InvalidInput; return(ret); } AdjustPaths(projProperties.IncludeDirectories); AdjustPaths(projProperties.ForceIncludes); string includes = GenerateCommandStr("-I", projProperties.IncludeDirectories); string forceInc = GenerateCommandStr("-include", projProperties.ForceIncludes); string defines = GenerateCommandStr("-D", projProperties.PrepocessorDefinitions); string workDir = projProperties.WorkingDirectory.Length == 0 ? "" : " -working-directory=" + AdjustPath(projProperties.WorkingDirectory); string flags = projProperties.ShowWarnings? "" : " -w"; string extra = projProperties.ExtraArguments.Length == 0? "" : " " + projProperties.ExtraArguments; string standard = GetStandardFlag(projProperties.Standard); string archStr = projProperties != null && projProperties.Target == ProjectProperties.TargetType.x86 ? "-m32" : "-m64"; string toolCmd = AdjustPath(location.Filename) + " -- -x c++ " + archStr + standard + flags + defines + includes + forceInc + workDir + extra; OutputLog.Focus(); OutputLog.Log("Looking for structures at " + location.Filename + ":" + location.Line + ":" + location.Column + "..."); if (PrintCommandLine) { OutputLog.Log("COMMAND LINE: " + toolCmd); } Log = ""; var watch = System.Diagnostics.Stopwatch.StartNew(); var valid = false; valid = await System.Threading.Tasks.Task.Run(() => LayoutParser_ParseLocation(toolCmd, location.Filename, location.Line, location.Column)); watch.Stop(); const long TicksPerMicrosecond = (TimeSpan.TicksPerMillisecond / 1000); string timeStr = " (" + GetTimeStr((ulong)(watch.ElapsedTicks / TicksPerMicrosecond)) + ")"; if (Log.Length > 0) { OutputLog.Log("Execution Log:\n" + Log); ret.ParserLog = Log; Log = ""; } if (valid) { //capture data uint size = 0; IntPtr result = LayoutParser_GetData(ref size); if (size > 0) { byte[] managedArray = new byte[size]; Marshal.Copy(result, managedArray, 0, (int)size); using (BinaryReader reader = new BinaryReader(new MemoryStream(managedArray))) { ret.Layout = ReadNode(reader); FinalizeNode(ret.Layout); } OutputLog.Log("Found structure " + ret.Layout.Type + "." + timeStr); ret.Status = ParseResult.StatusCode.Found; } else { OutputLog.Log("No structure found at the given location." + timeStr); ret.Status = ParseResult.StatusCode.NotFound; } } else { OutputLog.Error("Unable to scan the given location." + timeStr); ret.Status = ParseResult.StatusCode.ParseFailed; } LayoutParser_Clear(); return(ret); }
public override ProjectProperties GetProjectData() { ThreadHelper.ThrowIfNotOnUIThread(); OutputLog.Log("Capturing configuration from VS projects..."); Project project = EditorUtils.GetActiveProject(); VCProject prj = project.Object as VCProject; if (prj == null) { return(null); } VCConfiguration config = prj.ActiveConfiguration; if (config == null) { return(null); } VCPlatform platform = config.Platform; if (platform == null) { return(null); } var vctools = config.Tools as IVCCollection; if (vctools == null) { return(null); } var midl = vctools.Item("VCMidlTool") as VCMidlTool; var evaluator = new MacroEvaluatorVisualPlatform(platform); ProjectProperties ret = new ProjectProperties(); ret.Target = midl != null && midl.TargetEnvironment == midlTargetEnvironment.midlTargetWin32 ? ProjectProperties.TargetType.x86 : ProjectProperties.TargetType.x64; ret.Standard = GetStandardVersion(config); //Working directory (always local to processed file) ret.WorkingDirectory = Path.GetDirectoryName(project.FullName); //Include dirs / files and preprocessor AppendMSBuildStringToList(ret.IncludeDirectories, evaluator.Evaluate(platform.IncludeDirectories)); AppendProjectProperties(ret, vctools.Item("VCCLCompilerTool") as VCCLCompilerTool, vctools.Item("VCNMakeTool") as VCNMakeTool, evaluator); //Get settings from the single file (this might fail badly if there are no settings to catpure) var applicationObject = EditorUtils.ServiceProvider.GetService(typeof(DTE)) as EnvDTE80.DTE2; Assumes.Present(applicationObject); ProjectItem item = applicationObject.ActiveDocument.ProjectItem; VCFile vcfile = item != null ? item.Object as VCFile : null; IVCCollection fileCfgs = vcfile != null ? (IVCCollection)vcfile.FileConfigurations : null; VCFileConfiguration fileConfig = fileCfgs != null?fileCfgs.Item(config.Name) as VCFileConfiguration : null; VCCLCompilerTool fileToolCL = null; VCNMakeTool fileToolNMake = null; try { fileToolCL = fileConfig.Tool as VCCLCompilerTool; fileToolNMake = fileConfig.Tool as VCNMakeTool; } catch (Exception e) { //If we really need this data we can always parse the vcxproj as an xml OutputLog.Log("File specific properties not found, only project properties used (" + e.Message + ")"); } AppendProjectProperties(ret, fileToolCL, fileToolNMake, evaluator); CaptureExtraProperties(ret, evaluator); AddCustomSettings(ret, evaluator); RemoveMSBuildStringFromList(ret.IncludeDirectories, evaluator.Evaluate(platform.ExcludeDirectories)); //Exclude directories ProcessPostProjectData(ret); return(ret); }