public static void DoWork(string targetFile)
 {
     // ensure we have a ParseAttribute for this file
     //if (!ParseStatus.ContainsKey(targetFile))
     //{
     //    ParseStatus.Add(targetFile, new ParseAttribute());
     //}
     //ParseStatusController.EnsureExists(targetFile);
     //bool IsReparsing = false;
     //lock(_synchronizationParseStatus) {
     //    IsReparsing = ParseStatus[targetFile].IsReparsing;
     //}
     if (ParseStatusController.IsReparsing(targetFile))
     {
         // TODO what is this for? does it help with threading? (probably not)
         Thread.Sleep(50);
     }
     else
     {
         lock (_synchronizationParseStatus)
         {
             ParseStatus[targetFile].IsReparsing = true;
         }
         VerilogGlobals.ReparseWork(threadbuffer, threadFile);
         // TODO once reparsing is done in a thread, we need to tell the viewport to redraww the screen
         Thread.Sleep(10);
     }
 }
        /// <summary>
        ///   LineParse
        /// </summary>
        /// <param name="theLine"></param>
        private static void LineParse(string theLine, int theLineNumber)
        {
            // first, parse the words and tokens
            string thisTokenString = "";
            int    LinePosition    = 0;

            tokens = VerilogGlobals.VerilogKeywordSplit(theLine, priorToken);
            Boolean IsContinuedLineComment = false;                      // new lines never have a continued line comment; comments with "//" are only effective for the current line, but /* can span multiple lines

            foreach (VerilogGlobals.VerilogToken VerilogToken in tokens) // this group of tokens in in a single line
            {
                // by the time we get here, we might have a tag with adjacent comments:
                //     assign//
                //     //assign
                //     assign//comment
                //     /*assign*/
                //     assign/*comment*/
                thisTokenString = VerilogToken.Part;
                CommentHelper.CommentHelper commentHelper = new CommentHelper.CommentHelper(thisTokenString,
                                                                                            IsContinuedLineComment,
                                                                                            VerilogGlobals.IsContinuedBlockComment);
                VerilogGlobals.IsContinuedBlockComment = commentHelper.HasBlockStartComment;
                IsContinuedLineComment = commentHelper.HasOpenLineComment; // we'll use this when processing the VerilogToken item in the commentHelper, above
                foreach (CommentHelper.CommentHelper.CommentItem Item in commentHelper.CommentItems)
                {
                    // TODO - are we actually doing anything with TestComment, or is this just for testing VerilogGlobals.TextIsComment() ??
                    bool TestComment = VerilogGlobals.TextIsComment(theLineNumber, LinePosition);
                    LinePosition += Item.ItemText.Length;

                    // is this item a comment? If so, color as appropriate. comments take highest priority: no other condition will change color of a comment
                    if (Item.IsComment)
                    {
                        // nothing
                    }

                    // otherwise when not a comment, check to see if it is a keyword
                    else
                    {
                        // first check to see if any new variables are being defined;

                        double duration10 = (DateTime.Now - ProfileStart).TotalMilliseconds;
                        VerilogGlobals.BuildHoverItems(Item.ItemText);
                        double duration11 = (DateTime.Now - ProfileStart).TotalMilliseconds;
                    }
                }
            }
        }
Beispiel #3
0
            public static void DoWork(string targetFile)
            {
                // ensure we have a ParseAttribute for this file
                //if (!ParseStatus.ContainsKey(targetFile))
                //{
                //    ParseStatus.Add(targetFile, new ParseAttribute());
                //}
                //ParseStatusController.EnsureExists(targetFile);
                //bool IsReparsing = false;
                //lock(_synchronizationParseStatus) {
                //    IsReparsing = ParseStatus[targetFile].IsReparsing;
                //}
                if (ParseStatusController.IsReparsing(targetFile))
                {
                    // TODO what is this for? does it help with threading? (probably not)
                    System.Diagnostics.Debug.WriteLine("DoWork called while IsReparsing...");

                    Thread.Sleep(50);
                }
                else
                {
                    lock (_synchronizationParseStatus)
                    {
                        ParseStatus[targetFile].IsReparsing = true;
                    }
                    //if ( 1==1 || (DateTime.Now - LastRefresh).TotalSeconds > 10)
                    //{
                    //    System.Diagnostics.Debug.WriteLine("BufferAttributes calling ReparseWork");
                    VerilogGlobals.ReparseWork(threadbuffer, threadFile);
                    //    LastRefresh = DateTime.Now;
                    //}


                    // TODO once reparsing is done in a thread, we need to tell the viewport to redraww the screen
                    // does this redraw?
                    // TheView.Selection.TextView.ViewScroller.ScrollViewportVerticallyByPixels(0);

                    Thread.Sleep(10);
                }
            }
Beispiel #4
0
        /// <summary>
        /// Determine which pieces of Quickinfo content should be displayed
        /// </summary>
        public void AugmentQuickInfoSession(IQuickInfoSession session, IList <object> quickInfoContent, out ITrackingSpan applicableToSpan)
        {
            applicableToSpan = null;

            if (_disposed)
            {
                throw new ObjectDisposedException("TestQuickInfoSource");
            }

            var triggerPoint = (SnapshotPoint)session.GetTriggerPoint(_buffer.CurrentSnapshot);

            if (triggerPoint == null)
            {
                return;
            }


            foreach (IMappingTagSpan <VerilogToken.VerilogTokenTag> curTag in _aggregator.GetTags(new SnapshotSpan(triggerPoint, triggerPoint)))
            {
                // here we add hover text at runtime
                if (_VerilogKeywordHoverText.Keys.Contains(curTag.Tag.type))
                {
                    var tagSpan = curTag.Span.GetSpans(_buffer).First();
                    applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive);
                    quickInfoContent.Add(_VerilogKeywordHoverText[curTag.Tag.type]);
                }
                else
                {                                            //
                    var    thisTag      = curTag.ToString(); //TODO is this where to add verilog variables?
                    var    tagSpan      = curTag.Span.GetSpans(_buffer).First();
                    string thisHoverKey = tagSpan.GetText();

                    // 510 = tagSpan.Snapshot.GetLineFromPosition(tagSpan.Start.Position).Extent.Start.Position
                    // 523 = ((Microsoft.VisualStudio.Text.Utilities.MappingPointSnapshot)curTag.Span.Start)._anchor.Position                                                   // by the time we get here, we've lost the scope of which module we are in, so a helper function is needed

                    int thisLine     = tagSpan.Snapshot.GetLineFromPosition(tagSpan.Start.Position).LineNumber;
                    int thisPosition = tagSpan.Start.Position
                                       - tagSpan.Snapshot.GetLineFromPosition(tagSpan.Start.Position).Extent.Start.Position;
                    // tagSpan.Snapshot.GetLineFromPosition(tagSpan.Start.Position).End.Position;
                    string thisScopeName = VerilogGlobals.TextModuleName(thisLine,
                                                                         thisPosition);  // TODO get proper values!
                    if (VerilogGlobals.VerilogVariableHoverText[thisScopeName].Keys.Contains(thisHoverKey))
                    {
                        applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive);
                        quickInfoContent.Add(VerilogGlobals.VerilogVariableHoverText[thisScopeName][thisHoverKey]);
                    }
                }

                //if (curTag.Tag.type == VerilogTokenTypes.Verilog_always)
                //{
                //    var tagSpan = curTag.Span.GetSpans(_buffer).First();
                //    applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive);
                //    quickInfoContent.Add(_VerilogKeywordHoverText[VerilogTokenTypes.Verilog_always]);
                //}
                //else if (curTag.Tag.type == VerilogTokenTypes.Verilog_begin)
                //{
                //    var tagSpan = curTag.Span.GetSpans(_buffer).First();
                //    applicableToSpan = _buffer.CurrentSnapshot.CreateTrackingSpan(tagSpan, SpanTrackingMode.EdgeExclusive);
                //    quickInfoContent.Add("Question Begin?");
                //}
            }
        }
        public static void ReparseWork(ITextBuffer buffer, string targetFile)
        {
            int thisBufferVersion = 0;

            System.Diagnostics.Debug.WriteLine("Starting ReparseWork...");

            // ensure our ParseStatus dictionary of ParseAttribute items has an item for our current file
            //if (!ParseStatus.ContainsKey(targetFile))
            //{
            //    ParseStatus.Add(targetFile,  new ParseAttribute());
            //}
            lock (_synchronizationParseStatus)
            {
                VerilogGlobals.ParseStatusController.EnsureExists(targetFile);
                ParseStatus[targetFile].IsReparsing = true;
                //IsReparsing = true;

                if (buffer == null)
                {
                    ParseStatus[targetFile].IsReparsing = false;
                    // IsReparsing = false;
                    return;
                }

                if (buffer.EditInProgress)
                {
                    ParseStatus[targetFile].IsReparsing = false;
                    // IsReparsing = false;
                    return;
                }

                try
                {
                    thisBufferVersion = buffer.CurrentSnapshot.Version.VersionNumber;
                }
                catch
                {
                    thisBufferVersion = 0;
                }

                // if we could not determine a version ( = 0), or if the last time we reparsed was for this same buffer, then exit
                if ((thisBufferVersion == 0) || (ParseStatus[targetFile].LastReparseVersion == thisBufferVersion))
                {
                    ParseStatus[targetFile].IsReparsing = false;
                    // IsReparsing = false;
                    return;
                }
            }


            //if ((DateTime.Now - ProfileStart).TotalMilliseconds < 1000)
            //{
            //    ProfileStart = DateTime.Now;
            //    return; // never reparse more than once a second
            //}
            ProfileStart = DateTime.Now;
            ITextSnapshot newSnapshot          = buffer.CurrentSnapshot;
            string        thisChar             = "";
            string        lastChar             = "";
            string        thisLine             = "";
            bool          IsActiveLineComment  = false;
            bool          IsActiveBlockComment = false;

            int    thisLineNumber = 0;
            double duration2;
            double duration3;

            editingBufferAttributes = new List <BufferAttribute>(); // re-initialize the global editingBufferAttributes used for editing
            // TODO lock on private object, see _synchronizationParseStatus

            lock (editingBufferAttributes)
            {
                BufferAttribute bufferAttribute = new BufferAttribute();
                //
                // Reparse AppendBufferAttribute
                //
                void AppendBufferAttribute()
                {
                    duration2 = (DateTime.Now - ProfileStart).TotalMilliseconds;
                    bufferAttribute.LineNumber = thisLineNumber;

                    // TODO move this to separate function
                    if (thisModuleName != "")
                    {
                        if (!ModuleNames.ContainsValue(thisModuleName))
                        {
                            byte thisNewKey;
                            if (ModuleNames.Count < 256)
                            {
                                thisNewKey = (byte)ModuleNames.Count;
                            }
                            else
                            {
                                // TODO this is actually an error! do something here (popup warning?)
                                thisNewKey = 0; // we'll (incorrectly) assume global space if there are more than 255 modules
                            }
                            ModuleNames.Add(thisNewKey, thisModuleName);
                            ModuleKeys.Add(thisModuleName, thisNewKey); // build two dictionaries for runtime performance

                            // create placeholder for variables
                            if (!VerilogVariables.ContainsKey(thisModuleName))
                            {
                                VerilogVariables.Add(thisModuleName, new Dictionary <string, VerilogTokenTypes> {
                                });
                            }

                            // ensure VerilogVariableHoverText has a dictionary for [thisModuleName]
                            if (!VerilogVariableHoverText.ContainsKey(thisModuleName))
                            {
                                VerilogVariableHoverText.Add(thisModuleName, new Dictionary <string, string> {
                                });
                            }
                        }
                        bufferAttribute.ModuleNameKey = ModuleKeys[thisModuleName]; // ModuleNames.FirstOrDefault(x => x.Value == thisModuleName).Key; // thanks stackoverflow https://stackoverflow.com/questions/2444033/get-dictionary-key-by-value
                    }

                    editingBufferAttributes.Add(bufferAttribute);
                    bufferAttribute = new BufferAttribute();

                    // set rollover params
                    bufferAttribute.RoundBracketDepth    = editingBufferAttributes[editingBufferAttributes.Count - 1].RoundBracketDepth;
                    bufferAttribute.SquareBracketDepth   = editingBufferAttributes[editingBufferAttributes.Count - 1].SquareBracketDepth;
                    bufferAttribute.SquigglyBracketDepth = editingBufferAttributes[editingBufferAttributes.Count - 1].SquigglyBracketDepth;
                    bufferAttribute.IsComment            = IsActiveBlockComment;
                    bufferAttribute.IsEmpty = true; // although we may have carried over some values, at this point it is still "empty"
                    duration3 = (DateTime.Now - ProfileStart).TotalMilliseconds;
                }

                void CharParse()
                {
                    for (int i = 0; i < thisLine.Length; i++)
                    {
                        thisChar = thisLine.Substring(i, 1);
                        switch (thisChar)
                        {
                        case "[":
                            if (IsActiveLineComment || IsActiveBlockComment)
                            {
                                // AttributesChanged = false; // if there's an active line comment - nothing changes!
                            }
                            else
                            {
                                bufferAttribute.SquareBracketDepth++;
                                bufferAttribute.LineStart = i;     // brackets are only 1 char long, starting
                                bufferAttribute.LineEnd   = i;     // and ending at the same positions
                                AppendBufferAttribute();
                            }
                            break;

                        case "]":
                            if (IsActiveLineComment || IsActiveBlockComment)
                            {
                                // AttributesChanged = false; // if there's an active line comment - nothing changes!
                            }
                            else
                            {
                                bufferAttribute.LineStart = i;     // brackets are only 1 char long, starting
                                bufferAttribute.LineEnd   = i;     // and ending at the same positions
                                AppendBufferAttribute();
                                bufferAttribute.SquareBracketDepth = (bufferAttribute.SquareBracketDepth > 0) ? (--bufferAttribute.SquareBracketDepth) : 0;
                            }
                            break;

                        case "(":
                            if (IsActiveLineComment || IsActiveBlockComment)
                            {
                                // AttributesChanged = false; // if there's an active line comment - nothing changes!
                            }
                            else
                            {
                                bufferAttribute.RoundBracketDepth++;
                                bufferAttribute.LineStart = i;     // brackets are only 1 char long, starting
                                bufferAttribute.LineEnd   = i;     // and ending at the same positions
                                AppendBufferAttribute();
                            }
                            break;

                        case ")":
                            if (IsActiveLineComment || IsActiveBlockComment)
                            {
                                // AttributesChanged = false; // if there's an active line comment - nothing changes!
                            }
                            else
                            {
                                bufferAttribute.LineStart = i;     // brackets are only 1 char long, starting
                                bufferAttribute.LineEnd   = i;     // and ending at the same positions
                                AppendBufferAttribute();
                                bufferAttribute.RoundBracketDepth = (bufferAttribute.RoundBracketDepth > 0) ? (--bufferAttribute.RoundBracketDepth) : 0;
                            }
                            break;

                        case "{":
                            if (IsActiveLineComment || IsActiveBlockComment)
                            {
                                // AttributesChanged = false; // if there's an active line comment - nothing changes!
                            }
                            else
                            {
                                bufferAttribute.SquigglyBracketDepth++;
                                bufferAttribute.LineStart = i;     // brackets are only 1 char long, starting
                                bufferAttribute.LineEnd   = i;     // and ending at the same positions
                                AppendBufferAttribute();
                            }
                            break;

                        case "}":
                            if (IsActiveLineComment || IsActiveBlockComment)
                            {
                                // AttributesChanged = false; // if there's an active line comment - nothing changes!
                            }
                            else
                            {
                                bufferAttribute.LineStart = i;     // brackets are only 1 char long, starting
                                bufferAttribute.LineEnd   = i;     // and ending at the same positions
                                AppendBufferAttribute();
                                bufferAttribute.SquigglyBracketDepth = (bufferAttribute.SquigglyBracketDepth > 0) ? (--bufferAttribute.SquigglyBracketDepth) : 0;
                            }
                            break;

                        case "*":
                            // encountered "/*"
                            if (lastChar == "/")
                            {
                                if (IsActiveLineComment || IsActiveBlockComment)
                                {
                                    // AttributesChanged = false; // if there's an active line comment - nothing changes!
                                }
                                else
                                {
                                    bufferAttribute.LineStart = i - 1;     // started on prior char
                                                                           // bufferAttribute.LineEnd TBD
                                    IsActiveBlockComment      = true;
                                    bufferAttribute.IsComment = true;
                                    AppendBufferAttribute();
                                }
                            }
                            else
                            {
                                // AttributesChanged = false;
                            }
                            break;

                        case "/":
                            // check for block comment end "*/"
                            if (lastChar == "*")
                            {
                                if (!IsActiveLineComment)
                                {
                                    IsActiveBlockComment      = false;
                                    bufferAttribute.LineEnd   = i;   //
                                    bufferAttribute.IsComment = false;
                                    AppendBufferAttribute();
                                }
                                else
                                {
                                    // AttributesChanged = false;
                                }
                            }
                            else
                            {
                                // detect line comments "//"
                                if (lastChar == "/" && !IsActiveLineComment)     // encountered first "//" on a line, can only be ended by new line
                                {
                                    IsActiveLineComment       = true;
                                    bufferAttribute.IsComment = true;
                                    bufferAttribute.LineStart = i - 1; // comment actually starts on prior char
                                    bufferAttribute.LineEnd   = -1;    // a value of -1 means the entire line, regardless of actual length.
                                                                       // AttributesChanged = (i > 1); // the attribute of the line will not change if the first char starts a comment
                                    AppendBufferAttribute();
                                }
                                else
                                {
                                    // AttributesChanged = false;
                                }
                            }
                            break;

                        default:
                            // we'll keep track of ending string segment that may need to be added below; note if something interesting is found, we'll overwrite these bufferAttribute values, above
                            if (bufferAttribute.LineStart < 0)
                            {
                                bufferAttribute.LineStart = i; // the first time we end up here, is the start of the string that does not match one of the above special cases
                            }
                            bufferAttribute.LineEnd = i;       // keep track of the end.
                            break;
                        }
                        lastChar = thisChar;
                    } // end of for loop looking at each char in line
                }

                VerilogGlobals.InitHoverBuilder();

                double duration4 = (DateTime.Now - ProfileStart).TotalMilliseconds;
                // reminder bufferAttribute is pointing to the contents of the last item in editingBufferAttributes
                foreach (var line in newSnapshot.Lines)
                {
                    //Thread.Sleep(10);
                    thisLine       = line.GetText();
                    thisLineNumber = line.LineNumber; // zero-based line numbers

                    // parse the entire line for tokens
                    double duration6 = (DateTime.Now - ProfileStart).TotalMilliseconds;
                    LineParse(thisLine, thisLineNumber);
                    double duration7 = (DateTime.Now - ProfileStart).TotalMilliseconds;

                    // some things, like bracket depth, require us to look at each character...
                    // we'll build a helper table to be able to lookup bracket depth at
                    // arbitrary points
                    CharParse();
                    double duration8 = (DateTime.Now - ProfileStart).TotalMilliseconds;
                    lastChar = "";  // the lastChar is irrelevant when spanning multiple lines, as we are only using it for comment detection
                    if (!bufferAttribute.IsEmpty)
                    {
                        AppendBufferAttribute();
                    }

                    if (editingBufferAttributes.Count > 0)
                    {
                        // when we reach the end of the line, we reach the end of the line comment!
                        IsActiveLineComment = false;
                    }
                    double duration9 = (DateTime.Now - ProfileStart).TotalMilliseconds;
                    if (!BufferFirstParseComplete)
                    {
                        // TODO - this was supposed to help intial file load of large files, but does not seem to help.
                        BufferAttributes = editingBufferAttributes;
                    }
                } // foreach line
            }     // lock editingBufferAttributes

            double duration5 = (DateTime.Now - ProfileStart).TotalMilliseconds;

            // TODO - do we need a final, end-of-file bufferAttribute (probably not)

            lock (_synchronizationParseStatus)
            {
                // in case we got here from someplace that set NeedReparse to true - reset to indicate completion:
                VerilogGlobals.ParseStatus[targetFile].NeedReparse = true;
                //VerilogGlobals.NeedReparse = false;
                VerilogGlobals.ParseStatus[targetFile].LastParseTime = DateTime.Now;
                //VerilogGlobals.LastParseTime = DateTime.Now;
                VerilogGlobals.ParseStatus[targetFile].LastReparseVersion = thisBufferVersion;
            }
            double duration = (DateTime.Now - ProfileStart).TotalMilliseconds;

            BufferAttributes         = editingBufferAttributes;
            BufferFirstParseComplete = true;
            lock (_synchronizationParseStatus)
            {
                ParseStatus[targetFile].IsReparsing = false;
            }
        } // Reparse