/// <summary> /// The currently highlighted word has changed. Update the adornments to reflect this change /// </summary> private void Update_Word_Adornments() { try { DateTime time1 = DateTime.Now; if (this.NewWord.Length > 0) { ITextSnapshot s = this.RequestedPoint.Snapshot; SnapshotSpan sp = this.NewWordSpan.Value; // Find the new spans FindData findData; Rn reg = RegisterTools.ParseRn(this.NewWord); if (reg != Rn.NOREG) { AsmDudeToolsStatic.Output_INFO(string.Format(AsmDudeToolsStatic.CultureUI, "{0}:Update_Word_Adornments. Register={1}", this.ToString(), this.NewWord)); string t = RegisterTools.GetRelatedRegister(reg); findData = new FindData(t, s) { FindOptions = FindOptions.WholeWord | FindOptions.SingleLine | FindOptions.UseRegularExpressions, }; } else { (bool valid, ulong value, int nBits) = AsmSourceTools.Parse_Constant(this.NewWord); if (valid) { AsmDudeToolsStatic.Output_INFO(string.Format(AsmDudeToolsStatic.CultureUI, "{0}:Update_Word_Adornments. Contant={1}", this.ToString(), this.NewWord)); string t = AsmSourceTools.Get_Related_Constant(this.NewWord, value, nBits); findData = new FindData(t, s) { FindOptions = FindOptions.WholeWord | FindOptions.SingleLine | FindOptions.UseRegularExpressions, }; } else { AsmDudeToolsStatic.Output_INFO(string.Format(AsmDudeToolsStatic.CultureUI, "{0}:Update_Word_Adornments. Keyword={1}", this.ToString(), this.NewWord)); //We have to replace all occurrences of special characters with escaped versions of that char since we cannot use verbatim strings. string t = this.NewWord.Replace(".", "\\.").Replace("$", "\\$").Replace("?", "\\?").Replace("/", "\\/"); findData = new FindData(t, s) { FindOptions = FindOptions.WholeWord | FindOptions.SingleLine | FindOptions.UseRegularExpressions, }; } } List <SnapshotSpan> wordSpans = new List <SnapshotSpan>(); try { wordSpans.AddRange(this.textSearchService_.FindAll(findData)); } catch (Exception e2) { AsmDudeToolsStatic.Output_WARNING(string.Format(AsmDudeToolsStatic.CultureUI, "could not highlight string \"{0}\"; e={1}", findData.SearchString, e2.InnerException.Message)); } this.SynchronousUpdate(this.RequestedPoint, new NormalizedSnapshotSpanCollection(wordSpans), this.NewWord, sp); } else { // If we couldn't find a word, just clear out the existing markers this.SynchronousUpdate(this.RequestedPoint, new NormalizedSnapshotSpanCollection(), null, null); } AsmDudeToolsStatic.Print_Speed_Warning(time1, "HighlightWordTagger"); } catch (Exception e) { AsmDudeToolsStatic.Output_ERROR(string.Format(AsmDudeToolsStatic.CultureUI, "{0}:UpdateWordAdornments; e={1}", this.ToString(), e.ToString())); } }
public IEnumerable <ITagSpan <AsmTokenTag> > GetTags_NEW(NormalizedSnapshotSpanCollection spans) { DateTime time1 = DateTime.Now; if (spans.Count == 0) { //there is no content in the buffer yield break; } foreach (SnapshotSpan curSpan in spans) { ITextSnapshotLine containingLine = curSpan.Start.GetContainingLine(); string line = containingLine.GetText().ToUpper(); int offset = containingLine.Start.Position; IEnumerator <(int BeginPos, int Length, bool IsLabel)> enumerator = AsmSourceTools.SplitIntoKeywordPos(line).GetEnumerator(); bool needToAdvance = false; bool hasNext = enumerator.MoveNext(); if (!hasNext) { break; } (int BeginPos, int Length, bool IsLabel)prev = (0, 0, false); (int BeginPos, int Length, bool IsLabel)current = enumerator.Current; while (hasNext) { string asmToken = NasmIntelTokenTagger.Keyword(current, line); // keyword starts with a remark char if (AsmSourceTools.IsRemarkChar(asmToken[0])) { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._remark)); continue; } // keyword k is a label definition if (current.IsLabel) { SnapshotSpan labelDefSpan = NasmIntelTokenTagger.New_Span(current, offset, curSpan); //AsmDudeToolsStatic.Output_INFO("MasmTokenTagger:GetTags: found label " + asmToken +" at line "+containingLine.LineNumber); if (asmToken.Equals("@@")) { // TODO: special MASM label, for the moment, ignore it, later: check whether it is used etc. } else { yield return(new TagSpan <AsmTokenTag>(labelDefSpan, this.Make_AsmTokenTag_LabelDef(containingLine.LineNumber))); } continue; } AsmTokenType keywordType = this._asmDudeTools.Get_Token_Type_Intel(asmToken); switch (keywordType) { case AsmTokenType.Jump: { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._jump)); { // go to the next word if (needToAdvance) { hasNext = enumerator.MoveNext(); prev = current; current = enumerator.Current; } needToAdvance = true; } string asmToken2 = NasmIntelTokenTagger.Keyword(current, line); switch (asmToken2) { case "$": case "@B": case "@F": { // TODO: special MASM label, for the moment, ignore it, later: check whether it is used etc. break; } case "WORD": case "DWORD": case "QWORD": case "SHORT": case "NEAR": { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._misc)); { // go to the next word if (needToAdvance) { hasNext = enumerator.MoveNext(); prev = current; current = enumerator.Current; } needToAdvance = true; } switch (NasmIntelTokenTagger.Keyword(current, line)) { case "$": case "@B": case "@F": { // TODO: special MASM label, for the moment, ignore it, later: check whether it is used etc. break; } case "PTR": { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._misc)); break; } default: { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.Make_AsmTokenTag_Label(containingLine.LineNumber))); break; } } break; } default: { if (RegisterTools.IsRegister(asmToken2)) { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._register)); } else { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.Make_AsmTokenTag_Label(containingLine.LineNumber))); } break; } } break; } case AsmTokenType.UNKNOWN: // asmToken is not a known keyword, check if it is numerical { //if (AsmTools.AsmSourceTools.Evaluate_Constant(asmToken, true).Valid) if (AsmSourceTools.Parse_Constant(asmToken, true).Valid) { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._constant)); } else if (asmToken.StartsWith("\"") && asmToken.EndsWith("\"")) { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._constant)); } else { // do one word look back; see whether we can understand the current unknown word string previousKeyword = NasmIntelTokenTagger.Keyword(prev, line); switch (previousKeyword) { case "ALIAS": { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._labelDef)); break; } default: { break; } } // do one word lookahead; see whether we can understand the current unknown word // go to the next word needToAdvance = false; if (enumerator.MoveNext()) { prev = current; current = enumerator.Current; string nextKeyword = NasmIntelTokenTagger.Keyword(current, line); switch (nextKeyword) { case "PROC": case "EQU": case "LABEL": { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(prev, offset, curSpan), this._labelDef)); yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._directive)); break; } case "PROTO": { // a proto is considered a label definition but it should not clash with other label definitions yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(prev, offset, curSpan), this._labelDef_PROTO)); yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._directive)); break; } default: break; } } else { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._UNKNOWN)); } } break; } case AsmTokenType.Directive: { AssemblerEnum assember = this._asmDudeTools.Get_Assembler(asmToken); if (assember.HasFlag(AssemblerEnum.MASM)) // this MASM token-tagger only tags MASM directives { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this._directive)); if (asmToken.Equals("INVOKE")) { { // go to the next word if (needToAdvance) { hasNext = enumerator.MoveNext(); prev = current; current = enumerator.Current; } needToAdvance = true; } //string asmToken2 = NasmTokenTagger.Keyword(current, line); yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), this.Make_AsmTokenTag_Label(containingLine.LineNumber))); } } break; } default: { yield return(new TagSpan <AsmTokenTag>(NasmIntelTokenTagger.New_Span(current, offset, curSpan), new AsmTokenTag(keywordType))); break; } } { // go to the next word if (needToAdvance) { hasNext = enumerator.MoveNext(); prev = current; current = enumerator.Current; } needToAdvance = true; } } } AsmDudeToolsStatic.Print_Speed_Warning(time1, "MasmTokenTagger"); }