Пример #1
0
        /// <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()));
            }
        }
Пример #2
0
        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");
        }