Exemplo n.º 1
0
        /// <summary>
        /// Search the given span for any instances of classified tags
        /// </summary>
        public IEnumerable <ITagSpan <ClassificationTag> > GetTags(NormalizedSnapshotSpanCollection spans)
        {
            if (Settings.Default.SyntaxHighlighting_On)
            {
                if (spans.Count == 0)
                {  //there is no content in the buffer
                    yield break;
                }
                DateTime time1 = DateTime.Now;
                foreach (IMappingTagSpan <AsmTokenTag> tagSpan in _aggregator.GetTags(spans))
                {
                    NormalizedSnapshotSpanCollection tagSpans = tagSpan.Span.GetSpans(spans[0].Snapshot);
                    switch (tagSpan.Tag.type)
                    {
                    case AsmTokenType.Mnemonic: yield return(new TagSpan <ClassificationTag>(tagSpans[0], _mnemonic)); break;

                    case AsmTokenType.Register: yield return(new TagSpan <ClassificationTag>(tagSpans[0], _register)); break;

                    case AsmTokenType.Remark: yield return(new TagSpan <ClassificationTag>(tagSpans[0], _remark)); break;

                    case AsmTokenType.Directive: yield return(new TagSpan <ClassificationTag>(tagSpans[0], _directive)); break;

                    case AsmTokenType.Constant: yield return(new TagSpan <ClassificationTag>(tagSpans[0], _constant)); break;

                    case AsmTokenType.Jump: yield return(new TagSpan <ClassificationTag>(tagSpans[0], _jump)); break;

                    case AsmTokenType.Label: yield return(new TagSpan <ClassificationTag>(tagSpans[0], _label)); break;

                    case AsmTokenType.LabelDef: yield return(new TagSpan <ClassificationTag>(tagSpans[0], _labelDef)); break;

                    case AsmTokenType.Misc: yield return(new TagSpan <ClassificationTag>(tagSpans[0], _misc)); break;

                    default:
                        break;
                    }
                }
                AsmDudeToolsStatic.printSpeedWarning(time1, "Asm Classifier");
            }
        }
Exemplo n.º 2
0
        public IEnumerable <ITagSpan <AsmTokenTag> > GetTags(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();
                IList <Tuple <int, int, bool> > pos = AsmSourceTools.splitIntoKeywordPos(line);

                int offset    = containingLine.Start.Position;
                int nKeywords = pos.Count;

                for (int k = 0; k < nKeywords; k++)
                {
                    if (pos[k].Item3)
                    {
                        SnapshotSpan label       = newSpan(pos[k], offset, curSpan);
                        string       labelString = label.GetText();
                        //AsmDudeToolsStatic.Output(string.Format("INFO: found label {0}", labelString));
                        if (labelString.StartsWith("."))
                        {
                            // TODO: special NASM local labels, for the moment, ignore them.
                        }
                        else
                        {
                            yield return(new TagSpan <AsmTokenTag>(label, this._labelDef));
                        }
                        continue;
                    }

                    string asmToken = keyword(pos[k], line);
                    if (AsmSourceTools.isRemarkChar(asmToken[0]))
                    {
                        yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._remark));

                        continue;
                    }

                    AsmTokenType keywordType = this._asmDudeTools.getTokenType(asmToken);
                    switch (keywordType)
                    {
                    case AsmTokenType.Jump:
                        #region Jump
                        yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._jump));

                        k++;
                        if (k == nKeywords)
                        {
                            break;
                        }

                        string asmToken2 = keyword(pos[k], line);
                        if (!asmToken2[0].Equals('.'))
                        {
                            switch (asmToken2)
                            {
                            case "WORD":
                            case "DWORD":
                            case "QWORD":
                            case "SHORT":
                            case "NEAR":
                                yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._misc));

                                k++;
                                if (k == nKeywords)
                                {
                                    break;
                                }
                                string asmToken3 = keyword(pos[k], line);
                                if (!asmToken3[0].Equals('.'))
                                {
                                    switch (asmToken3)
                                    {
                                    case "PTR":
                                        yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._misc));

                                        break;

                                    default:
                                        yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._label));

                                        break;
                                    }
                                }
                                break;

                            default:
                                if (RegisterTools.isRegister(asmToken2))
                                {
                                    yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._register));
                                }
                                else
                                {
                                    yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._label));
                                }
                                break;
                            }
                        }
                        break;

                        #endregion Jump
                    case AsmTokenType.UNKNOWN:     // asmToken is not a known keyword, check if it is numerical
                        #region UNKNOWN
                        if (AsmTools.AsmSourceTools.isConstant(asmToken))
                        {
                            yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._constant));
                        }
                        else if (asmToken.StartsWith("\"") && asmToken.EndsWith("\""))
                        {
                            yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._constant));
                        }
                        else
                        {
                            bool isUnknown = true;

                            // do one word lookahead; see whether we can understand the current unknown word
                            if ((k + 1) < nKeywords)
                            {
                                k++;
                                string nextKeyword = keyword(pos[k], line);

                                switch (nextKeyword)
                                {
                                case "LABEL":
                                    yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k - 1], offset, curSpan), this._labelDef));

                                    yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._directive));

                                    isUnknown = false;
                                    break;

                                default:
                                    k--;
                                    break;
                                }
                            }

                            // do one word look back; see whether we can understand the current unknown word
                            if (k > 0)
                            {
                                string previousKeyword = keyword(pos[k - 1], line);
                                switch (previousKeyword)
                                {
                                case "ALIAS":
                                    yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._labelDef));

                                    isUnknown = false;
                                    break;

                                default:
                                    break;
                                }
                            }

                            if (isUnknown)
                            {
                                yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._UNKNOWN));
                            }
                        }
                        break;

                        #endregion UNKNOWN
                    case AsmTokenType.Directive:
                        #region Directive
                        switch (this._asmDudeTools.getAssembler(asmToken))
                        {
                        case AssemblerEnum.NASM:
                        case AssemblerEnum.UNKNOWN:
                            yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), this._directive));

                            break;

                        default:
                            break;
                        }
                        break;

                        #endregion Directive
                    default:
                        yield return(new TagSpan <AsmTokenTag>(newSpan(pos[k], offset, curSpan), new AsmTokenTag(keywordType)));

                        break;
                    }
                }
            }
            AsmDudeToolsStatic.printSpeedWarning(time1, "NasmTokenTagger");
        }
Exemplo n.º 3
0
        public void AugmentCompletionSession(ICompletionSession session, IList <CompletionSet> completionSets)
        {
            //AsmDudeToolsStatic.Output(string.Format("INFO: {0}:AugmentCompletionSession", this.ToString()));

            if (_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.isAllUpper(partialKeyword);

                SortedSet <Completion> completions = null;

                string   lineStr  = line.GetText();
                var      t        = AsmSourceTools.parseLine(lineStr);
                Mnemonic mnemonic = t.Item2;

                if (mnemonic == Mnemonic.UNKNOWN)
                {
                    ISet <AsmTokenType> selected = new HashSet <AsmTokenType> {
                        AsmTokenType.Directive, AsmTokenType.Jump, AsmTokenType.Misc, AsmTokenType.Mnemonic                                                       /*, AsmTokenType.Register */
                    };
                    completions = this.selectedCompletions(useCapitals, selected);
                }
                else     // the current line contains a mnemonic
                {
                    string previousKeyword = AsmDudeToolsStatic.getPreviousKeyword(line.Start, start);
                    //AsmDudeToolsStatic.Output("INFO: AsmCompletionSource:AugmentCompletionSession; mnemonic=" + mnemonic+ "; previousKeyword="+ previousKeyword);

                    if (AsmSourceTools.isJump(AsmSourceTools.parseMnemonic(previousKeyword)))
                    {
                        //AsmDudeToolsStatic.Output("INFO: AsmCompletionSource:AugmentCompletionSession; previous keyword is a jump mnemonic");
                        // previous keyword is jump (or call) mnemonic. Suggest "SHORT" or a label
                        completions = this.labelCompletions();
                        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"))
                    {
                        // previous keyword is SHORT. Suggest a label
                        completions = this.labelCompletions();
                    }
                    else
                    {
                        IList <Operand>         operands = AsmSourceTools.makeOperands(t.Item3);
                        ISet <AsmSignatureEnum> allowed  = new HashSet <AsmSignatureEnum>();
                        int commaCount = AsmSignature.countCommas(lineStr);
                        IList <AsmSignatureElement> allSignatures = this._asmDudeTools.mnemonicStore.getSignatures(mnemonic);

                        ISet <Arch> selectedArchitectures = AsmDudeToolsStatic.getArchSwithedOn();
                        foreach (AsmSignatureElement se in AsmSignatureHelpSource.constrainSignatures(allSignatures, operands, selectedArchitectures))
                        {
                            if (commaCount < se.operands.Count)
                            {
                                foreach (AsmSignatureEnum s in se.operands[commaCount])
                                {
                                    allowed.Add(s);
                                }
                            }
                        }
                        completions = this.mnemonicOperandCompletions(useCapitals, allowed);
                    }
                }
                //AsmDudeToolsStatic.Output("INFO: AsmCompletionSource:AugmentCompletionSession; nCompletions=" + completions.Count);
                #endregion

                completionSets.Add(new CompletionSet("Tokens", "Tokens", applicableTo, completions, Enumerable.Empty <Completion>()));

                AsmDudeToolsStatic.printSpeedWarning(time1, "Code Completion");
            } catch (Exception e) {
                AsmDudeToolsStatic.Output(string.Format("ERROR: {0}:AugmentCompletionSession; e={1}", this.ToString(), e.ToString()));
            }
        }