Esempio n. 1
0
        private void BuildModelDoWork(object sender, DoWorkEventArgs e)
        {
            if (disableEntityParsing)
            {
                return;
            }
            System.Diagnostics.Trace.WriteLine("-->> XSharpClassifier.BuildModelDoWork()");
            // Note this runs in the background
            // parse for positional keywords that change the colors
            // and get a reference to the tokenstream
            // do we need to create a new tree
            // this happens the first time in the buffer only
            var          snapshot = _buffer.CurrentSnapshot;
            ITokenStream tokens   = null;
            ParseResult  info;

            {
                Debug("Starting parse at {0}, version {1}", DateTime.Now, snapshot.Version.ToString());
                var lines = new List <String>();
                foreach (var line in snapshot.Lines)
                {
                    lines.Add(line.GetText());
                }

                info = _sourceWalker.Parse(lines, false);
                lock (gate)
                {
                    _info = info;
                }
                Debug("Ending parse at {0}, version {1}", DateTime.Now, snapshot.Version.ToString());
            }
            tokens = _tokens;
            if (info != null && tokens != null)
            {
                Debug("Starting model build  at {0}, version {1}", DateTime.Now, snapshot.Version.ToString());
                _sourceWalker.BuildModel(info);
                var regionTags = BuildRegionTags(info, snapshot, xsharpRegionStart, xsharpRegionStop);
                lock (gate)
                {
                    _parserRegions = regionTags.ToArray();
                }
                DoRepaintRegions();
                Debug("Ending model build  at {0}, version {1}", DateTime.Now, snapshot.Version.ToString());
            }
            System.Diagnostics.Trace.WriteLine("<<-- XSharpClassifier.BuildModelDoWork()");
        }
Esempio n. 2
0
        public IList <ClassificationSpan> BuildRegionTags(XSharpModel.ParseResult info, ITextSnapshot snapshot, IClassificationType start, IClassificationType stop)
        {
            if (disableRegions)
            {
                return(new List <ClassificationSpan>());
            }
            System.Diagnostics.Trace.WriteLine("-->> XSharpClassifier.BuildRegionTags()");
            var regions      = new List <ClassificationSpan>();
            var classList    = new List <EntityObject>();
            var propertyList = new List <EntityObject>();

            if (info != null && snapshot != null)
            {
                // walk list of entities
                foreach (var oElement in info.Entities)
                {
                    if (oElement.eType.NeedsEndKeyword())
                    {
                        classList.Add(oElement);
                    }
                    if (oElement.eType == EntityType._Property)
                    {
                        if (oElement.oParent?.eType != EntityType._Interface)
                        {
                            // make sure we only push multi line properties
                            var text          = snapshot.GetLineFromPosition(oElement.nOffSet).GetText();
                            var substatements = text.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                            var words         = substatements[0].Split(new char[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
                            var singleLine    = false;
                            foreach (var word in words)
                            {
                                switch (word.ToLower())
                                {
                                case "auto":
                                case "get":
                                case "set":
                                    singleLine = true;
                                    break;

                                default:
                                    break;
                                }
                            }
                            if (!singleLine)
                            {
                                propertyList.Add(oElement);
                            }
                        }
                    }
                    //else if (oElement.eType == EntityType._Property)
                    //{
                    //    classStack.Push(oElement);
                    //}
                    else if (oElement.eType.HasBody() ||
                             oElement.eType == EntityType._VOStruct ||
                             oElement.eType == EntityType._Union)
                    {
                        int nStart, nEnd;
                        nStart = oElement.nOffSet;
                        nEnd   = oElement.nOffSet;
                        var oNext = oElement.oNext;
                        if (oElement.eType == EntityType._VOStruct ||
                            oElement.eType == EntityType._Union)
                        {
                            while (oNext != null && oNext.eType == EntityType._Field)
                            {
                                oNext = oNext.oNext;
                            }
                        }
                        if (oNext != null)
                        {
                            var nLine = oNext.nStartLine;
                            // our lines are 1 based and we want the line before, so -2
                            nEnd = snapshot.GetLineFromLineNumber(nLine - 2).Start;
                        }
                        else
                        {
                            if (oElement.oParent?.cName != XElement.GlobalName)
                            {
                                // find the endclass line after this element
                                foreach (var oLine in info.SpecialLines)
                                {
                                    if (oLine.eType == LineType.EndClass && oLine.Line > oElement.nStartLine)
                                    {
                                        var nLine = oLine.Line;
                                        // our lines are 1 based and we want the line before, so -2
                                        nEnd = snapshot.GetLineFromLineNumber(nLine - 2).Start;
                                        break;
                                    }
                                }
                            }
                            if (nEnd == nStart)
                            {
                                var nEndLine = snapshot.LineCount;
                                // walk the special lines collection to see if there are any 'end' lines at the end of the file
                                for (int i = info.SpecialLines.Count - 1; i >= 0; i--)
                                {
                                    var oLine = info.SpecialLines[i];
                                    switch (oLine.eType)
                                    {
                                    case LineType.EndNamespace:
                                    case LineType.EndClass:
                                        nEndLine = oLine.Line - 1;
                                        break;

                                    default:
                                        i = -1;     // exit the loop
                                        break;
                                    }
                                }
                                // Our lines are 1 based, so subtract 1
                                nEnd = snapshot.GetLineFromLineNumber(nEndLine - 1).Start;
                            }
                        }
                        if (nEnd > snapshot.Length)
                        {
                            nEnd = snapshot.Length;
                        }
                        AddRegionSpan(regions, snapshot, nStart, nEnd);
                    }
                }
            }
            var blockStack = new Stack <LineObject>();
            var nsStack    = new Stack <LineObject>();

            foreach (var oLine in info.SpecialLines)
            {
                int nStart = 0, nEnd = 0;
                switch (oLine.eType)
                {
                case LineType.BeginNamespace:
                    nsStack.Push(oLine);
                    break;

                case LineType.EndNamespace:
                    if (nsStack.Count > 0)
                    {
                        var nsStart = nsStack.Pop();
                        nStart = nsStart.OffSet;
                        nEnd   = oLine.OffSet;
                        AddRegionSpan(regions, snapshot, nStart, nEnd);
                    }
                    break;

                case LineType.EndClass:
                    if (classList.Count > 0)
                    {
                        var cls = classList[0];
                        classList.RemoveAt(0);
                        nStart = cls.nOffSet;
                        nEnd   = oLine.OffSet;
                        AddRegionSpan(regions, snapshot, nStart, nEnd);
                    }
                    break;

                case LineType.EndProperty:
                    if (propertyList.Count > 0)
                    {
                        var prop = propertyList[0];
                        propertyList.RemoveAt(0);
                        nStart = prop.nOffSet;
                        nEnd   = oLine.OffSet;
                        AddRegionSpan(regions, snapshot, nStart, nEnd);
                    }
                    break;

                case LineType.TokenIn:
                    blockStack.Push(oLine);
                    break;

                case LineType.TokenInOut:
                    if (blockStack.Count > 0)
                    {
                        var blStart = blockStack.Peek();
                        // remove previous ELSEIF but not the IF
                        if (blStart.eType == LineType.TokenInOut)
                        {
                            blockStack.Pop();
                            //}
                            if (blStart.cArgument == "DO" || blStart.cArgument == "SWITCH")
                            {
                                // no contents before the first case
                                ;
                            }
                            else
                            {
                                nStart = blStart.OffSet;
                                // our lines are 1 based.
                                // we do not want to include the next case line in the block from the previous one
                                nEnd = snapshot.GetLineFromLineNumber(oLine.Line - 2).Start;
                                AddRegionSpan(regions, snapshot, nStart, nEnd);
                            }
                        }
                    }
                    blockStack.Push(oLine);
                    break;

                case LineType.TokenOut:
                    if (blockStack.Count > 0)
                    {
                        // bop back to first token of the if .. endif or do case .. endcase
                        while (blockStack.Count > 0 && blockStack.Peek().eType == LineType.TokenInOut)
                        {
                            var blStart = blockStack.Pop();
                            nStart = blStart.OffSet;
                            nEnd   = snapshot.GetLineFromLineNumber(oLine.Line - 2).Start;
                            AddRegionSpan(regions, snapshot, nStart, nEnd);
                        }
                        if (blockStack.Count > 0)
                        {
                            var blStart = blockStack.Pop();
                            nStart = blStart.OffSet;
                            // get position of the line based on the line number
                            nEnd = snapshot.GetLineFromLineNumber(oLine.Line - 1).Start;
                            AddRegionSpan(regions, snapshot, nStart, nEnd);
                        }
                    }
                    break;

                default:
                    break;
                }
            }
            System.Diagnostics.Trace.WriteLine("<<-- XSharpClassifier.BuildRegionTags()");
            return(regions);
        }