public void Test_AsmSourceTools_parseMnemonic() { foreach (Mnemonic x in Enum.GetValues(typeof(Mnemonic))) { Assert.AreEqual(AsmSourceTools.ParseMnemonic(x.ToString(), true), x, "Parsing string " + x.ToString() + " does not yield the same enumeration."); } }
public void AddData(MicroArch microArch, string filename) { AsmDudeToolsStatic.Output_INFO("PerformanceStore:AddData: microArch=" + microArch + "; filename=" + filename); try { System.IO.StreamReader file = new System.IO.StreamReader(filename); string line; while ((line = file.ReadLine()) != null) { if ((line.Trim().Length > 0) && (!line.StartsWith(";"))) { string[] columns = line.Split('\t'); if (columns.Length == 5) { { // handle instruction foreach (string mnemonicStr in columns[0].Split(' ')) { if (mnemonicStr.Length > 0) { Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(mnemonicStr); if (mnemonic == Mnemonic.UNKNOWN) { AsmDudeToolsStatic.Output_WARNING("PerformanceStore:LoadData: microArch=" + microArch + ": unknown mnemonic " + mnemonicStr + " in line: " + line); } else { PerformanceItem item = new PerformanceItem(); item._microArch = microArch; item._instr = mnemonic; item._args = columns[1]; item._latency = columns[2]; item._throughput = columns[3]; item._remark = columns[4]; this._data.Add(item); } } } } } else { AsmDudeToolsStatic.Output_WARNING("PerformanceStore:AddData: found " + columns.Length + " columns; funky line" + line); } } } file.Close(); } catch (FileNotFoundException) { AsmDudeToolsStatic.Output_ERROR("PerformanceStore:LoadData: could not find file \"" + filename + "\"."); } catch (Exception e) { AsmDudeToolsStatic.Output_ERROR("PerformanceStore:LoadData: error while reading file \"" + filename + "\"." + e); } }
private IDictionary <string, IList <Mnemonic> > Load_Instruction_Translation(string filename) { IDictionary <string, IList <Mnemonic> > translations = new Dictionary <string, IList <Mnemonic> >(); try { StreamReader file = new StreamReader(filename); string line; while ((line = file.ReadLine()) != null) { if ((line.Trim().Length > 0) && (!line.StartsWith(";"))) { string[] columns = line.Split('\t'); if (columns.Length == 2) { string key = columns[0].Trim(); IList <Mnemonic> values = new List <Mnemonic>(); foreach (string mnemonicStr in columns[1].Trim().Split(' ')) { Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(mnemonicStr); if (mnemonic == Mnemonic.NONE) { AsmDudeToolsStatic.Output_WARNING("PerformanceStore:Load_Instruction_Translation: key=" + columns[0] + ": unknown mnemonic " + mnemonicStr + " in line: " + line); } else { values.Add(mnemonic); } } //AsmDudeToolsStatic.Output_INFO("PerformanceStore:Load_Instruction_Translation: key=" + key + " = " + String.Join(",", values)); if (translations.ContainsKey(key)) { AsmDudeToolsStatic.Output_WARNING("PerformanceStore:Load_Instruction_Translation: key=" + key + " in line: " + line + " already used"); } else { translations.Add(key, values); } } } } file.Close(); } catch (FileNotFoundException) { AsmDudeToolsStatic.Output_ERROR("PerformanceStore:Load_Instruction_Translation: could not find file \"" + filename + "\"."); } catch (Exception e) { AsmDudeToolsStatic.Output_ERROR("PerformanceStore:Load_Instruction_Translation: error while reading file \"" + filename + "\"." + e); } return(translations); }
static Tuple <Mnemonic, List <IformRegister>, int, bool, float, float> ParseLine(string line) { var x = line.Split(','); if (x.Length != 5) { Console.WriteLine("ERROR: could not parse " + line); } var y = x[0].Split('_'); Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(y[0], true); List <IformRegister> args = new List <IformRegister>(); for (int i = 1; i < y.Length; ++i) { var z = ParseIformRegister(y[i], false); if (z == IformRegister.UNKNOWN) { //Console.WriteLine("WARNING: could not parse " + line); } else if (z == IformRegister.IGNORE) { } else { args.Add(z); } } int n_bits = -1; Int32.TryParse(x[1], out n_bits); bool use_mask = (x[2] == "yes"); float throughput = -1; float.TryParse(x[3], out throughput); float latency = -1; float.TryParse(x[4], out latency); return(Tuple.Create(mnemonic, args, n_bits, use_mask, throughput, latency)); }
/// <summary> /// get url for the provided keyword. Returns empty string if the keyword does not exist or the keyword does not have an url. /// </summary> public string Get_Url(string keyword) { // no need to pre-process this information. try { string keywordUpper = keyword.ToUpper(); Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(keyword); if (mnemonic != Mnemonic.UNKNOWN) { string url = this.Mnemonic_Store.GetHtmlRef(mnemonic); //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:getUrl: keyword {1}; url {2}.", this.ToString(), keyword, url)); return(url); } return(""); } catch (Exception e) { AsmDudeToolsStatic.Output(string.Format("ERROR: {0}:getUrl: exception {1}.", ToString(), e.ToString())); return(""); } }
public AsmTokenType Get_Token_Type(string keyword) { Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(keyword); if (mnemonic != Mnemonic.UNKNOWN) { if (AsmSourceTools.IsJump(mnemonic)) { return(AsmTokenType.Jump); } return(AsmTokenType.Mnemonic); } if (this._type.TryGetValue(keyword.ToUpper(), out var tokenType)) { return(tokenType); } return(AsmTokenType.UNKNOWN); }
public AsmTokenType Get_Token_Type_Intel(string keyword) { Debug.Assert(keyword == keyword.ToUpper()); Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(keyword, true); if (mnemonic != Mnemonic.NONE) { return((this.MnemonicSwitchedOn(mnemonic)) ? AsmSourceTools.IsJump(mnemonic) ? AsmTokenType.Jump : AsmTokenType.Mnemonic : AsmSourceTools.IsJump(mnemonic) ? AsmTokenType.Jump : AsmTokenType.MnemonicOff); } Rn reg = RegisterTools.ParseRn(keyword, true); if (reg != Rn.NOREG) { return((this.RegisterSwitchedOn(reg)) ? AsmTokenType.Register : AsmTokenType.Register); //TODO } return(this._type.TryGetValue(keyword, out AsmTokenType tokenType) ? tokenType : AsmTokenType.UNKNOWN); }
private void ToolTipLegacy(SnapshotPoint triggerPoint, System.Windows.Point p) { var span = Get_Keyword_Span_At_Point(triggerPoint); ITrackingSpan applicableTo = this._textView.TextSnapshot.CreateTrackingSpan(span, SpanTrackingMode.EdgeInclusive); // check if a tooltip window is already visible for the applicable span if ((this._legacySpan != null) && this._legacySpan.OverlapsWith(span)) { //AsmDudeToolsStatic.Output_INFO("AsmQuickInfoController:ToolTipLegacy: tooltip is already visible. span = " + this._legacySpan.ToString() + ", content =" + applicableTo.GetText(this._textView.TextSnapshot)); return; } string keyword = applicableTo.GetText(this._textView.TextSnapshot); Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(keyword, false); if (mnemonic != Mnemonic.NONE) { var instructionTooltipWindow = new InstructionTooltipWindow(AsmDudeToolsStatic.Get_Font_Color()) { Owner = this // set the owner of this windows such that we can manually close this window }; instructionTooltipWindow.SetDescription(mnemonic, AsmDudeTools.Instance); instructionTooltipWindow.SetPerformanceInfo(mnemonic, AsmDudeTools.Instance); instructionTooltipWindow.Margin = new Thickness(7.0); var border = new Border() { BorderBrush = System.Windows.Media.Brushes.LightGray, BorderThickness = new Thickness(1.0), CornerRadius = new CornerRadius(2.0), Background = AsmDudeToolsStatic.Get_Background_Color(), Child = instructionTooltipWindow }; // cleanup old window remnants if (this._legacyTooltipWindow != null) { AsmDudeToolsStatic.Output_INFO("AsmQuickInfoController:ToolTipLegacy: going to cleanup old window remnants."); if (this._legacyTooltipWindow.IsLoaded) { this._legacyTooltipWindow = null; } else { this._legacyTooltipWindow?.Close(); } } this._legacyTooltipWindow = new Window { WindowStyle = WindowStyle.None, ResizeMode = ResizeMode.NoResize, SizeToContent = SizeToContent.WidthAndHeight, Left = p.X, Top = p.Y, Content = border }; this._legacyTooltipWindow.LostKeyboardFocus += (o, i) => { //AsmDudeToolsStatic.Output_INFO("AsmQuickInfoController:LostKeyboardFocus: going to close the tooltip window."); try { (o as Window).Close(); } catch (Exception e) { AsmDudeToolsStatic.Output_WARNING("AsmQuickInfoController:LostKeyboardFocus: e=" + e.Message); } }; this._legacySpan = span; this._legacyTooltipWindow.Show(); this._legacyTooltipWindow.Focus(); //give the tooltip window focus, such that we can use the lostKeyboardFocus event to close this window; } }
private void LoadHandcraftedData(string filename) { //AsmDudeToolsStatic.Output_INFO("MnemonicStore:load_data_intel: filename=" + filename); try { StreamReader file = new StreamReader(filename); string line; while ((line = file.ReadLine()) != null) { if ((line.Length > 0) && (!line.StartsWith(";", StringComparison.Ordinal))) { string[] columns = line.Split('\t'); if (columns.Length == 4) { // general description #region Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(columns[1], false); if (mnemonic == Mnemonic.NONE) { AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadHandcraftedData: unknown mnemonic in line" + line); } else { if (this.description_.ContainsKey(mnemonic)) { this.description_.Remove(mnemonic); } this.description_.Add(mnemonic, columns[2]); if (this.htmlRef_.ContainsKey(mnemonic)) { this.htmlRef_.Remove(mnemonic); } this.htmlRef_.Add(mnemonic, columns[3]); } #endregion } else if ((columns.Length == 5) || (columns.Length == 6)) { // signature description, ignore an old sixth column #region Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(columns[0], false); if (mnemonic == Mnemonic.NONE) { AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadHandcraftedData: unknown mnemonic in line" + line); } else { AsmSignatureElement se = new AsmSignatureElement(mnemonic, columns[1], columns[2], columns[3], columns[4]); this.Add(se); } #endregion } else { AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadHandcraftedData: s.Length=" + columns.Length + "; funky line" + line); } } } file.Close(); #region Fill Arch foreach (KeyValuePair <Mnemonic, IList <AsmSignatureElement> > pair in this.data_) { ISet <Arch> archs = new HashSet <Arch>(); foreach (AsmSignatureElement signatureElement in pair.Value) { foreach (Arch arch in signatureElement.Arch) { archs.Add(arch); } } IList <Arch> list = new List <Arch>(); foreach (Arch a in archs) { list.Add(a); } this.arch_[pair.Key] = list; } #endregion } catch (FileNotFoundException) { AsmDudeToolsStatic.Output_ERROR("MnemonicStore:LoadHandcraftedData: could not find file \"" + filename + "\"."); } catch (Exception e) { AsmDudeToolsStatic.Output_ERROR("MnemonicStore:LoadHandcraftedData: error while reading file \"" + filename + "\"." + e); } }
private void LoadRegularData(string filename) { //AsmDudeToolsStatic.Output_INFO("MnemonicStore:loadRegularData: filename=" + filename); try { StreamReader file = new StreamReader(filename); string line; while ((line = file.ReadLine()) != null) { if ((line.Length > 0) && (!line.StartsWith(";", StringComparison.Ordinal))) { string[] columns = line.Split('\t'); if (columns.Length == 4) { // general description #region Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(columns[1], false); if (mnemonic == Mnemonic.NONE) { // ignore the unknown mnemonic //AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadRegularData: unknown mnemonic in line: " + line); } else { if (!this.description_.ContainsKey(mnemonic)) { this.description_.Add(mnemonic, columns[2]); } else { // this happens when the mnemonic is defined in multiple files, using the data from the first file //AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadRegularData: mnemonic " + mnemonic + " already has a description"); } if (!this.htmlRef_.ContainsKey(mnemonic)) { this.htmlRef_.Add(mnemonic, columns[3]); } else { // this happens when the mnemonic is defined in multiple files, using the data from the first file //AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadRegularData: mnemonic " + mnemonic + " already has a html ref"); } } #endregion } else if ((columns.Length == 5) || (columns.Length == 6)) { // signature description, ignore an old sixth column #region Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(columns[0], false); if (mnemonic == Mnemonic.NONE) { AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadRegularData: unknown mnemonic in line: " + line); } else { AsmSignatureElement se = new AsmSignatureElement(mnemonic, columns[1], columns[2], columns[3], columns[4]); if (this.Add(se)) { AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadRegularData: signature already exists" + se.ToString()); } } #endregion } else { AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadRegularData: s.Length=" + columns.Length + "; funky line" + line); } } } file.Close(); #region Fill Arch foreach (KeyValuePair <Mnemonic, IList <AsmSignatureElement> > pair in this.data_) { ISet <Arch> archs = new HashSet <Arch>(); foreach (AsmSignatureElement signatureElement in pair.Value) { foreach (Arch arch in signatureElement.Arch) { if (arch == Arch.ARCH_NONE) { AsmDudeToolsStatic.Output_WARNING("MnemonicStore:loadRegularData: found ARCH NONE."); } else { archs.Add(arch); } } } IList <Arch> list = new List <Arch>(); foreach (Arch a in archs) { list.Add(a); } this.arch_[pair.Key] = list; } #endregion } catch (FileNotFoundException) { AsmDudeToolsStatic.Output_ERROR("MnemonicStore:loadRegularData: could not find file \"" + filename + "\"."); } catch (Exception e) { AsmDudeToolsStatic.Output_ERROR("MnemonicStore:loadRegularData: error while reading file \"" + filename + "\"." + e); } }
public void AugmentCompletionSession(ICompletionSession session, IList <CompletionSet> completionSets) { Contract.Requires(session != null); Contract.Requires(completionSets != null); try { //AsmDudeToolsStatic.Output_INFO(string.Format(AsmDudeToolsStatic.CultureUI, "{0}:AugmentCompletionSession", this.ToString())); if (!Settings.Default.CodeCompletion_On) { return; } DateTime time1 = DateTime.Now; ITextSnapshot snapshot = this.buffer_.CurrentSnapshot; SnapshotPoint triggerPoint = (SnapshotPoint)session.GetTriggerPoint(snapshot); if (triggerPoint == null) { return; } ITextSnapshotLine line = triggerPoint.GetContainingLine(); //1] check if current position is in a remark; if we are in a remark, no code completion #region if (triggerPoint.Position > 1) { char currentTypedChar = (triggerPoint - 1).GetChar(); //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession: current char = "+ currentTypedChar); if (!currentTypedChar.Equals('#')) { //TODO UGLY since the user can configure this starting character int pos = triggerPoint.Position - line.Start; if (AsmSourceTools.IsInRemark(pos, line.GetText())) { //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession: currently in a remark section"); return; } else { // AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession: not in a remark section"); } } } #endregion //2] find the start of the current keyword #region SnapshotPoint start = triggerPoint; while ((start > line.Start) && !AsmSourceTools.IsSeparatorChar((start - 1).GetChar())) { start -= 1; } #endregion //3] get the word that is currently being typed #region ITrackingSpan applicableTo = snapshot.CreateTrackingSpan(new SnapshotSpan(start, triggerPoint), SpanTrackingMode.EdgeInclusive); string partialKeyword = applicableTo.GetText(snapshot); bool useCapitals = AsmDudeToolsStatic.Is_All_upcase(partialKeyword); string lineStr = line.GetText(); (string label, Mnemonic mnemonic, string[] args, string remark)t = AsmSourceTools.ParseLine(lineStr); Mnemonic mnemonic = t.mnemonic; string previousKeyword_upcase = AsmDudeToolsStatic.Get_Previous_Keyword(line.Start, start).ToUpperInvariant(); //AsmDudeToolsStatic.Output_INFO(string.Format(AsmDudeToolsStatic.CultureUI, "{0}:AugmentCompletionSession. lineStr=\"{1}\"; previousKeyword=\"{2}\"", this.ToString(), lineStr, previousKeyword)); if (mnemonic == Mnemonic.NONE) { if (previousKeyword_upcase.Equals("INVOKE", StringComparison.Ordinal)) //TODO INVOKE is a MASM keyword not a NASM one... { // Suggest a label IEnumerable <Completion> completions = this.Label_Completions(useCapitals, false); if (completions.Any()) { completionSets.Add(new CompletionSet("Labels", "Labels", applicableTo, completions, Enumerable.Empty <Completion>())); } } else { { ISet <AsmTokenType> selected1 = new HashSet <AsmTokenType> { AsmTokenType.Directive, AsmTokenType.Jump, AsmTokenType.Misc, AsmTokenType.Mnemonic }; IEnumerable <Completion> completions1 = this.Selected_Completions(useCapitals, selected1, true); if (completions1.Any()) { completionSets.Add(new CompletionSet("All", "All", applicableTo, completions1, Enumerable.Empty <Completion>())); } } if (false) { ISet <AsmTokenType> selected2 = new HashSet <AsmTokenType> { AsmTokenType.Jump, AsmTokenType.Mnemonic }; IEnumerable <Completion> completions2 = this.Selected_Completions(useCapitals, selected2, false); if (completions2.Any()) { completionSets.Add(new CompletionSet("Instr", "Instr", applicableTo, completions2, Enumerable.Empty <Completion>())); } } if (false) { ISet <AsmTokenType> selected3 = new HashSet <AsmTokenType> { AsmTokenType.Directive, AsmTokenType.Misc }; IEnumerable <Completion> completions3 = this.Selected_Completions(useCapitals, selected3, true); if (completions3.Any()) { completionSets.Add(new CompletionSet("Directive", "Directive", applicableTo, completions3, Enumerable.Empty <Completion>())); } } } } else { // the current line contains a mnemonic //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession; mnemonic=" + mnemonic+ "; previousKeyword="+ previousKeyword); if (AsmSourceTools.IsJump(AsmSourceTools.ParseMnemonic(previousKeyword_upcase, true))) { //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession; previous keyword is a jump mnemonic"); // previous keyword is jump (or call) mnemonic. Suggest "SHORT" or a label IEnumerable <Completion> completions = this.Label_Completions(useCapitals, true); if (completions.Any()) { completionSets.Add(new CompletionSet("Labels", "Labels", applicableTo, completions, Enumerable.Empty <Completion>())); } } else if (previousKeyword_upcase.Equals("SHORT", StringComparison.Ordinal) || previousKeyword_upcase.Equals("NEAR", StringComparison.Ordinal)) { // Suggest a label IEnumerable <Completion> completions = this.Label_Completions(useCapitals, false); if (completions.Any()) { completionSets.Add(new CompletionSet("Labels", "Labels", applicableTo, completions, Enumerable.Empty <Completion>())); } } else { IList <Operand> operands = AsmSourceTools.MakeOperands(t.args); ISet <AsmSignatureEnum> allowed = new HashSet <AsmSignatureEnum>(); int commaCount = AsmSignature.Count_Commas(lineStr); IEnumerable <AsmSignatureElement> allSignatures = this.asmDudeTools_.Mnemonic_Store.GetSignatures(mnemonic); ISet <Arch> selectedArchitectures = AsmDudeToolsStatic.Get_Arch_Swithed_On(); foreach (AsmSignatureElement se in AsmSignatureHelpSource.Constrain_Signatures(allSignatures, operands, selectedArchitectures)) { if (commaCount < se.Operands.Count) { foreach (AsmSignatureEnum s in se.Operands[commaCount]) { allowed.Add(s); } } } IEnumerable <Completion> completions = this.Mnemonic_Operand_Completions(useCapitals, allowed, line.LineNumber); if (completions.Any()) { completionSets.Add(new CompletionSet("All", "All", applicableTo, completions, Enumerable.Empty <Completion>())); } } } #endregion AsmDudeToolsStatic.Print_Speed_Warning(time1, "Code Completion"); } catch (Exception e) { AsmDudeToolsStatic.Output_ERROR(string.Format(AsmDudeToolsStatic.CultureUI, "{0}:AugmentCompletionSession; e={1}", this.ToString(), e.ToString())); } }
private void AddData(MicroArch microArch, string filename, IDictionary <string, IList <Mnemonic> > translations) { //AsmDudeToolsStatic.Output_INFO("PerformanceStore:AddData_New: microArch=" + microArch + "; filename=" + filename); try { StreamReader file = new StreamReader(filename); string line; int lineNumber = 0; while ((line = file.ReadLine()) != null) { if ((line.Trim().Length > 0) && (!line.StartsWith(";"))) { string[] columns = line.Split('\t'); if (columns.Length == 8) { { // handle instruction string mnemonicKey = columns[0].Trim(); if (!translations.TryGetValue(mnemonicKey, out IList <Mnemonic> mnemonics)) { mnemonics = new List <Mnemonic>(); foreach (string mnemonicStr in mnemonicKey.Split(' ')) { Mnemonic mnemonic = AsmSourceTools.ParseMnemonic(mnemonicStr); if (mnemonic == Mnemonic.NONE) { // check if the mnemonicStr can be translated to a list of mnemonics if (translations.TryGetValue(mnemonicStr, out IList <Mnemonic> mnemonics2)) { foreach (Mnemonic m in mnemonics2) { mnemonics.Add(m); } } else { AsmDudeToolsStatic.Output_WARNING("PerformanceStore:AddData: microArch=" + microArch + ": unknown mnemonic " + mnemonicStr + " in line " + lineNumber + " with content \"" + line + "\"."); } } else { mnemonics.Add(mnemonic); } } } foreach (Mnemonic m in mnemonics) { this._data.Add(new PerformanceItem() { _microArch = microArch, _instr = m, _args = columns[1], _mu_Ops_Fused = columns[2], _mu_Ops_Merged = columns[3], _mu_Ops_Port = columns[4], _latency = columns[5], _throughput = columns[6], _remark = columns[7] }); } } } else { AsmDudeToolsStatic.Output_WARNING("PerformanceStore:AddData: found " + columns.Length + " columns; funky line" + line); } } lineNumber++; } file.Close(); } catch (FileNotFoundException) { AsmDudeToolsStatic.Output_ERROR("PerformanceStore:LoadData: could not find file \"" + filename + "\"."); } catch (Exception e) { AsmDudeToolsStatic.Output_ERROR("PerformanceStore:LoadData: error while reading file \"" + filename + "\"." + e); } }
/// <summary> /// get url for the provided keyword. Returns empty string if the keyword does not exist or the keyword does not have an url. /// </summary> public string Get_Url(string keyword) { return(this.Mnemonic_Store.GetHtmlRef(AsmSourceTools.ParseMnemonic(keyword))); }
/// <summary> /// Determine which pieces of Quickinfo content should be displayed /// </summary> public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan) { //AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession"); applicableToSpan = null; try { DateTime time1 = DateTime.Now; ITextSnapshot snapshot = this._sourceBuffer.CurrentSnapshot; var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(snapshot); if (triggerPoint == null) { AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession: trigger point is null"); return; } string keyword = ""; IEnumerable <IMappingTagSpan <AsmTokenTag> > enumerator = this._aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint)); //AsmDudeToolsStatic.Output("INFO: AsmQuickInfoSource:AugmentQuickInfoSession: enumerator.Count="+ enumerator.Count()); if (enumerator.Count() > 0) { if (false) { // TODO: multiple tags at the provided triggerPoint is most likely the result of a bug in AsmTokenTagger, but it seems harmless... if (enumerator.Count() > 1) { foreach (IMappingTagSpan <AsmTokenTag> v in enumerator) { AsmDudeToolsStatic.Output(string.Format("WARNING: {0}:AugmentQuickInfoSession. more than one tag! \"{1}\"", ToString(), v.Span.GetSpans(this._sourceBuffer).First().GetText())); } } } IMappingTagSpan <AsmTokenTag> asmTokenTag = enumerator.First(); SnapshotSpan tagSpan = asmTokenTag.Span.GetSpans(this._sourceBuffer).First(); keyword = tagSpan.GetText(); int lineNumber = tagSpan.Snapshot.GetLineNumberFromPosition(tagSpan.Start); //AsmDudeToolsStatic.Output("INFO: AsmQuickInfoSource:AugmentQuickInfoSession: keyword=\""+ keyword + "\"; type=" + asmTokenTag.Tag.type +"; file="+AsmDudeToolsStatic.GetFileName(session.TextView.TextBuffer)); string keywordUpper = keyword.ToUpper(); applicableToSpan = snapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive); TextBlock description = null; switch (asmTokenTag.Tag.Type) { case AsmTokenType.Misc: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Keyword ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Misc)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.Directive: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Directive ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Directive)))); string descr = this._asmDudeTools.Get_Description(keywordUpper); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.Register: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Register ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Register)))); string register_Descr = this._asmDudeTools.Get_Description(keywordUpper); if (register_Descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + register_Descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } if (this._asmSimulator.Is_Enabled) { IState_R state = this._asmSimulator.GetState(lineNumber, true); string msg = this._asmSimulator.GetRegisterValue(RegisterTools.ParseRn(keyword), state); if (msg.Length == 0) { msg = "Calculating register content"; } description.Inlines.Add(new Run(AsmSourceTools.Linewrap("\n" + msg, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.Mnemonic: case AsmTokenType.Jump: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Mnemonic ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Opcode)))); Mnemonic mmemonic = AsmSourceTools.ParseMnemonic(keywordUpper); { string archStr = ":" + ArchTools.ToString(this._asmDudeTools.Mnemonic_Store.GetArch(mmemonic)) + " "; string descr = this._asmDudeTools.Mnemonic_Store.GetDescription(mmemonic); description.Inlines.Add(new Run(AsmSourceTools.Linewrap(archStr + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } { // show performance information MicroArch selectedMicroarchitures = AsmDudeToolsStatic.Get_MicroArch_Switched_On(); IReadOnlyList <PerformanceItem> performanceData = this._asmDudeTools.Performance_Store.GetPerformance(mmemonic, selectedMicroarchitures); if (performanceData.Count > 0) { FontFamily family = new FontFamily("Consolas"); IList <Run> list = new List <Run>(); description.Inlines.Add(new Run(string.Format("\n\n{0,-15}{1,-24}{2,-10}{3,-10}\n", "Architecture", "Instruction", "Latency", "Throughput")) { FontFamily = family, FontStyle = FontStyles.Italic, FontWeight = FontWeights.Bold, Foreground = this._foreground }); foreach (PerformanceItem item in performanceData) { description.Inlines.Add(new Run(string.Format("{0,-15}{1,-24}{2,-10}{3,-10}{4,-10}\n", item._microArch, item._instr + " " + item._args, item._latency, item._throughput, item._remark)) { FontFamily = family, Foreground = this._foreground }); } } } break; } case AsmTokenType.Label: { string label = keyword; string labelPrefix = asmTokenTag.Tag.Misc; string full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(labelPrefix, label, AsmDudeToolsStatic.Used_Assembler); description = new TextBlock(); description.Inlines.Add(Make_Run1("Label ", this._foreground)); description.Inlines.Add(Make_Run2(full_Qualified_Label, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Label)))); string descr = Get_Label_Description(full_Qualified_Label); if (descr.Length == 0) { descr = Get_Label_Description(label); } if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.LabelDef: { string label = keyword; string extra_Tag_Info = asmTokenTag.Tag.Misc; string full_Qualified_Label; if ((extra_Tag_Info != null) && extra_Tag_Info.Equals(AsmTokenTag.MISC_KEYWORD_PROTO)) { full_Qualified_Label = label; } else { full_Qualified_Label = AsmDudeToolsStatic.Make_Full_Qualified_Label(extra_Tag_Info, label, AsmDudeToolsStatic.Used_Assembler); } AsmDudeToolsStatic.Output_INFO("AsmQuickInfoSource:AugmentQuickInfoSession: found label def " + full_Qualified_Label); description = new TextBlock(); description.Inlines.Add(Make_Run1("Label ", this._foreground)); description.Inlines.Add(Make_Run2(full_Qualified_Label, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Label)))); string descr = Get_Label_Def_Description(full_Qualified_Label, label); if (descr.Length > 0) { description.Inlines.Add(new Run(AsmSourceTools.Linewrap(": " + descr, AsmDudePackage.maxNumberOfCharsInToolTips)) { Foreground = this._foreground }); } break; } case AsmTokenType.Constant: { description = new TextBlock(); description.Inlines.Add(Make_Run1("Constant ", this._foreground)); description.Inlines.Add(Make_Run2(keyword, new SolidColorBrush(AsmDudeToolsStatic.ConvertColor(Settings.Default.SyntaxHighlighting_Constant)))); break; } default: //description = new TextBlock(); //description.Inlines.Add(makeRun1("Unused tagType " + asmTokenTag.Tag.type)); break; } if (description != null) { description.FontSize = AsmDudeToolsStatic.Get_Font_Size() + 2; description.FontFamily = AsmDudeToolsStatic.Get_Font_Type(); //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:AugmentQuickInfoSession; setting description fontSize={1}; fontFamily={2}", this.ToString(), description.FontSize, description.FontFamily)); quickInfoContent.Add(description); } } //AsmDudeToolsStatic.Output("INFO: AsmQuickInfoSource:AugmentQuickInfoSession: applicableToSpan=\"" + applicableToSpan + "\"; quickInfoContent,Count=" + quickInfoContent.Count); AsmDudeToolsStatic.Print_Speed_Warning(time1, "QuickInfo"); } catch (Exception e) { AsmDudeToolsStatic.Output(string.Format("ERROR: {0}:AugmentQuickInfoSession; e={1}", ToString(), e.ToString())); } }
public void AugmentCompletionSession(ICompletionSession session, IList <CompletionSet> completionSets) { //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:AugmentCompletionSession", this.ToString())); if (this._disposed) { return; } if (!Settings.Default.CodeCompletion_On) { return; } try { DateTime time1 = DateTime.Now; ITextSnapshot snapshot = this._buffer.CurrentSnapshot; SnapshotPoint triggerPoint = (SnapshotPoint)session.GetTriggerPoint(snapshot); if (triggerPoint == null) { return; } ITextSnapshotLine line = triggerPoint.GetContainingLine(); //1] check if current position is in a remark; if we are in a remark, no code completion #region if (triggerPoint.Position > 1) { char currentTypedChar = (triggerPoint - 1).GetChar(); //AsmDudeToolsStatic.Output("INFO: CodeCompletionSource:AugmentCompletionSession: current char = "+ currentTypedChar); if (!currentTypedChar.Equals('#')) { //TODO UGLY since the user can configure this starting character int pos = triggerPoint.Position - line.Start; if (AsmSourceTools.IsInRemark(pos, line.GetText())) { //AsmDudeToolsStatic.Output("INFO: CodeCompletionSource:AugmentCompletionSession: currently in a remark section"); return; } else { // AsmDudeToolsStatic.Output("INFO: CodeCompletionSource:AugmentCompletionSession: not in a remark section"); } } } #endregion //2] find the start of the current keyword #region SnapshotPoint start = triggerPoint; while ((start > line.Start) && !AsmTools.AsmSourceTools.IsSeparatorChar((start - 1).GetChar())) { start -= 1; } #endregion //3] get the word that is currently being typed #region ITrackingSpan applicableTo = snapshot.CreateTrackingSpan(new SnapshotSpan(start, triggerPoint), SpanTrackingMode.EdgeInclusive); string partialKeyword = applicableTo.GetText(snapshot); bool useCapitals = AsmDudeToolsStatic.Is_All_Upper(partialKeyword); SortedSet <Completion> completions = null; string lineStr = line.GetText(); var t = AsmSourceTools.ParseLine(lineStr); Mnemonic mnemonic = t.Item2; //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession; lineStr="+ lineStr+ "; t.Item1="+t.Item1); string previousKeyword = AsmDudeToolsStatic.Get_Previous_Keyword(line.Start, start).ToUpper(); if (mnemonic == Mnemonic.UNKNOWN) { //AsmDudeToolsStatic.Output_INFO("CodeCompletionSource:AugmentCompletionSession; lineStr=" + lineStr + "; previousKeyword=" + previousKeyword); if (previousKeyword.Equals("INVOKE")) //TODO INVOKE is a MASM keyword not a NASM one... { // Suggest a label completions = Label_Completions(); } else { ISet <AsmTokenType> selected = new HashSet <AsmTokenType> { AsmTokenType.Directive, AsmTokenType.Jump, AsmTokenType.Misc, AsmTokenType.Mnemonic }; completions = Selected_Completions(useCapitals, selected); } } else { // the current line contains a mnemonic //AsmDudeToolsStatic.Output("INFO: CodeCompletionSource:AugmentCompletionSession; mnemonic=" + mnemonic+ "; previousKeyword="+ previousKeyword); if (AsmSourceTools.IsJump(AsmSourceTools.ParseMnemonic(previousKeyword))) { //AsmDudeToolsStatic.Output("INFO: CodeCompletionSource:AugmentCompletionSession; previous keyword is a jump mnemonic"); // previous keyword is jump (or call) mnemonic. Suggest "SHORT" or a label completions = Label_Completions(); completions.Add(new Completion("SHORT", (useCapitals) ? "SHORT" : "short", null, this._icons[AsmTokenType.Misc], "")); completions.Add(new Completion("NEAR", (useCapitals) ? "NEAR" : "near", null, this._icons[AsmTokenType.Misc], "")); } else if (previousKeyword.Equals("SHORT") || previousKeyword.Equals("NEAR")) { // Suggest a label completions = Label_Completions(); } else { IList <Operand> operands = AsmSourceTools.MakeOperands(t.Item3); ISet <AsmSignatureEnum> allowed = new HashSet <AsmSignatureEnum>(); int commaCount = AsmSignature.Count_Commas(lineStr); IList <AsmSignatureElement> allSignatures = this._asmDudeTools.Mnemonic_Store.GetSignatures(mnemonic); ISet <Arch> selectedArchitectures = AsmDudeToolsStatic.Get_Arch_Swithed_On(); foreach (AsmSignatureElement se in AsmSignatureHelpSource.Constrain_Signatures(allSignatures, operands, selectedArchitectures)) { if (commaCount < se.Operands.Count) { foreach (AsmSignatureEnum s in se.Operands[commaCount]) { allowed.Add(s); } } } completions = Mnemonic_Operand_Completions(useCapitals, allowed); } } //AsmDudeToolsStatic.Output("INFO: CodeCompletionSource:AugmentCompletionSession; nCompletions=" + completions.Count); #endregion completionSets.Add(new CompletionSet("Tokens", "Tokens", applicableTo, completions, Enumerable.Empty <Completion>())); AsmDudeToolsStatic.Print_Speed_Warning(time1, "Code Completion"); } catch (Exception e) { AsmDudeToolsStatic.Output_ERROR(string.Format("{0}:AugmentCompletionSession; e={1}", ToString(), e.ToString())); } }