コード例 #1
0
        private void OnCodeElementLine(object sender, DocumentChangedEvent <ICodeElementsLine> e)
        {
            System.Console.WriteLine("+++ OnCodeElementLine(..):");
            int c = 0;

            if (e.DocumentChanges != null)
            {
                foreach (var change in e.DocumentChanges)
                {
                    System.Console.WriteLine(" - " + change.Type + "@" + change.LineIndex);
                    if (change.NewLine == null)
                    {
                        System.Console.WriteLine("Line NIL");
                    }
                    else
                    if (change.NewLine.CodeElements == null)
                    {
                        System.Console.WriteLine("CodeElements NIL");
                    }
                    else
                    {
                        int i = 0;
                        foreach (var ce in change.NewLine.CodeElements)
                        {
                            System.Console.WriteLine("   - " + ce);
                            i++;
                        }
                        System.Console.WriteLine("   " + i + " CodeElements");
                    }
                    c++;
                }
            }
            System.Console.WriteLine("+++ --> " + (c > 0?("" + c):(e.DocumentChanges == null?"?":"0")) + " changes");
        }
コード例 #2
0
 public Controller(ICategoryService categoryService, IDocumentService documentService, IElementService elementService, IFilterService filterService, IParameterService parameterService, DocumentChangedEvent documentChangedEvent)
 {
     CategoryController   = new CategoryController(categoryService);
     DocumentController   = new DocumentController(documentService);
     ElementController    = new ElementController(elementService);
     FilterController     = new FilterController(filterService);
     ParameterController  = new ParameterController(parameterService);
     DocumentChangedEvent = documentChangedEvent;
 }
コード例 #3
0
        // --- Handle Scanner and error events ---

        public void OnNext(DocumentChangedEvent <ITokensLine> tokensLinesChangedEvent)
        {
            // Refresh the display of all the lines which were not directly modified
            // but which were rescanned because of a scanner state change on a previous or following line
            foreach (var documentChange in tokensLinesChangedEvent.DocumentChanges)
            {
                DocumentLine rescannedLine = Document.GetLineByNumber(documentChange.LineIndex);
                TextArea.TextView.Redraw(rescannedLine.Offset, rescannedLine.Length);
            }
        }
コード例 #4
0
        private void HandleDocumentChanged(object sender, DocumentChangedEvent e)
        {
            SLogManager.getInstance().Info("HandleDocumentChanged received in DocumentManagerSupport");
            _controlsForSave.Add(e.RequestData.VisualControl);
            foreach (DevExpress.XtraBars.BarItem item in _saveAllComponents)
            {
                item.Enabled = true;
            }

            if (e.RequestData.VisualControl == _activeControl)
            {
                foreach (DevExpress.XtraBars.BarItem item in _saveComponents)
                {
                    item.Enabled = true;
                }
            }
        }
コード例 #5
0
        private void OnTextLine(object sender, DocumentChangedEvent <ICobolTextLine> e)
        {
            System.Console.WriteLine("--- OnTextLine(..):");
            int c = 0;

            if (e.DocumentChanges != null)
            {
                foreach (var change in e.DocumentChanges)
                {
                    System.Console.Write(" + " + change.Type + "@" + change.LineIndex + ": ");
                    if (change.NewLine == null)
                    {
                        System.Console.WriteLine("?");
                    }
                    else
                    {
                        System.Console.WriteLine("\"" + change.NewLine.SourceText + "\"");
                    }
                    c++;
                }
            }
            System.Console.WriteLine("--- --> " + (c > 0?("" + c):(e.DocumentChanges == null?"?":"0")) + " changes");
        }
コード例 #6
0
        /// <summary>
        /// Creates a new snapshot of the document viewed as CodeElement objects after parsing.
        /// (if the processed tokens lines changed since the last time this method was called)
        /// Thread-safe : this method can be called from any thread.
        /// </summary>
        public void RefreshCodeElementsDocumentSnapshot()
        {
            // Make sure two threads don't try to update this snapshot at the same time
            lock (lockObjectForCodeElementsDocumentSnapshot)
            {
                // Capture previous snapshots at one point in time
                ProcessedTokensDocument processedTokensDocument      = ProcessedTokensDocumentSnapshot;
                CodeElementsDocument    previousCodeElementsDocument = CodeElementsDocumentSnapshot;

                // Check if an update is necessary and compute changes to apply since last version
                bool scanAllDocumentLines = false;
                IList <DocumentChange <IProcessedTokensLine> > processedTokensLineChanges = null;
                if (previousCodeElementsDocument == null)
                {
                    scanAllDocumentLines = true;
                }
                else if (processedTokensDocument.CurrentVersion == previousCodeElementsDocument.PreviousStepSnapshot.CurrentVersion)
                {
                    // Processed tokens lines did not change since last update => nothing to do
                    return;
                }
                else
                {
                    DocumentVersion <IProcessedTokensLine> previousProcessedTokensDocumentVersion = previousCodeElementsDocument.PreviousStepSnapshot.CurrentVersion;
                    processedTokensLineChanges = previousProcessedTokensDocumentVersion.GetReducedAndOrderedChangesInNewerVersion(processedTokensDocument.CurrentVersion);
                }

                // Start perf measurement
                var perfStatsForParserInvocation = PerfStatsForCodeElementsParser.OnStartRefreshParsingStep();

                // Track all changes applied to the document while updating this snapshot
                DocumentChangedEvent <ICodeElementsLine> documentChangedEvent = null;

                // Apply text changes to the compilation document
                if (scanAllDocumentLines)
                {
                    if (processedTokensDocument != null)
                    {
                        // Parse the whole document for the first time
                        CodeElementsParserStep.ParseDocument(TextSourceInfo, ((ImmutableList <CodeElementsLine>)processedTokensDocument.Lines), CompilerOptions, perfStatsForParserInvocation);

                        // Create the first code elements document snapshot
                        CodeElementsDocumentSnapshot = new CodeElementsDocument(processedTokensDocument, new DocumentVersion <ICodeElementsLine>(this), ((ImmutableList <CodeElementsLine>)processedTokensDocument.Lines));
                    }
                }
                else
                {
                    ImmutableList <CodeElementsLine> .Builder   codeElementsDocumentLines = ((ImmutableList <CodeElementsLine>)processedTokensDocument.Lines).ToBuilder();
                    IList <DocumentChange <ICodeElementsLine> > documentChanges           = CodeElementsParserStep.ParseProcessedTokensLinesChanges(TextSourceInfo, codeElementsDocumentLines, processedTokensLineChanges, PrepareDocumentLineForUpdate, CompilerOptions, perfStatsForParserInvocation);

                    // Create a new version of the document to track these changes
                    DocumentVersion <ICodeElementsLine> currentCodeElementsLinesVersion = previousCodeElementsDocument.CurrentVersion;
                    currentCodeElementsLinesVersion.changes = documentChanges;
                    currentCodeElementsLinesVersion.next    = new DocumentVersion <ICodeElementsLine>(currentCodeElementsLinesVersion);

                    // Prepare an event to signal document change to all listeners
                    documentChangedEvent            = new DocumentChangedEvent <ICodeElementsLine>(currentCodeElementsLinesVersion, currentCodeElementsLinesVersion.next);
                    currentCodeElementsLinesVersion = currentCodeElementsLinesVersion.next;

                    // Update the code elements document snapshot
                    CodeElementsDocumentSnapshot = new CodeElementsDocument(processedTokensDocument, currentCodeElementsLinesVersion, codeElementsDocumentLines.ToImmutable());
                }

                // Stop perf measurement
                PerfStatsForCodeElementsParser.OnStopRefreshParsingStep();

                // Send events to all listeners
                EventHandler <DocumentChangedEvent <ICodeElementsLine> > codeElementsLinesChanged = CodeElementsLinesChanged; // avoid race condition
                if (documentChangedEvent != null && codeElementsLinesChanged != null)
                {
                    codeElementsLinesChanged(this, documentChangedEvent);
                }
            }
        }
コード例 #7
0
        /// <summary>
        /// Update the tokens lines of the document if the text lines changed since the last time this method was called.
        /// NOT thread-safe : this method can only be called from the owner thread.
        /// </summary>
        public void UpdateTokensLines(System.Action onVersion = null)
        {
            // This method can only be called by the document owner thread
            if (documentOwnerThread == null)
            {
                documentOwnerThread = Thread.CurrentThread;
            }
            else
            {
                VerifyAccess();
            }

            // Check if an update is necessary and compute changes to apply since last version
            bool scanAllDocumentLines = false;
            IList <DocumentChange <ICobolTextLine> > textLineChanges = null;

            if (textLinesVersionForCurrentTokensLines == null)
            {
                scanAllDocumentLines = true;
            }
            else if (currentTextLinesVersion == textLinesVersionForCurrentTokensLines)
            {
                // Text lines did not change since last update => nothing to do
                return;
            }
            else
            {
                textLineChanges = textLinesVersionForCurrentTokensLines.GetReducedAndOrderedChangesInNewerVersion(currentTextLinesVersion);
            }

            // Make sure we don't update the document while taking a snapshot
            DocumentChangedEvent <ITokensLine> documentChangedEvent = null;

            lock (lockObjectForDocumentLines)
            {
                // Start perf measurement
                PerfStatsForScanner.OnStartRefresh();

                // Apply text changes to the compilation document
                if (scanAllDocumentLines)
                {
                    ScannerStep.ScanDocument(TextSourceInfo, compilationDocumentLines, CompilerOptions, CopyTextNamesVariations, initialScanStateForCopy);
                }
                else
                {
                    IList <DocumentChange <ITokensLine> > documentChanges = ScannerStep.ScanTextLinesChanges(TextSourceInfo, compilationDocumentLines, textLineChanges, PrepareDocumentLineForUpdate, CompilerOptions, CopyTextNamesVariations, initialScanStateForCopy);

                    // Create a new version of the document to track these changes
                    currentTokensLinesVersion.changes = documentChanges;
                    currentTokensLinesVersion.next    = new DocumentVersion <ITokensLine>(currentTokensLinesVersion);

                    // Prepare an event to signal document change to all listeners
                    documentChangedEvent      = new DocumentChangedEvent <ITokensLine>(currentTokensLinesVersion, currentTokensLinesVersion.next);
                    currentTokensLinesVersion = currentTokensLinesVersion.next;
                    if (onVersion != null)
                    {
                        onVersion();
                    }
                }

                // Register that the tokens lines were synchronized with the current text lines version
                textLinesVersionForCurrentTokensLines = currentTextLinesVersion;

                // Stop perf measurement
                PerfStatsForScanner.OnStopRefresh();
            }

            // Send events to all listeners
            EventHandler <DocumentChangedEvent <ITokensLine> > tokensLinesChanged = TokensLinesChanged; // avoid race condition

            if (documentChangedEvent != null && tokensLinesChanged != null)
            {
                tokensLinesChanged(this, documentChangedEvent);
            }
        }
コード例 #8
0
        /// <summary>
        /// Update the text lines of the document after a text change event.
        /// NOT thread-safe : this method can only be called from the owner thread.
        /// </summary>
        public void UpdateTextLines(TextChangedEvent textChangedEvent)
        {
            // This method can only be called by the document owner thread
            if (documentOwnerThread == null)
            {
                documentOwnerThread = Thread.CurrentThread;
            }
            else
            {
                VerifyAccess();
            }

            // Make sure we don't update the document while taking a snapshot
            DocumentChangedEvent <ICobolTextLine> documentChangedEvent = null;

            lock (lockObjectForDocumentLines)
            {
                // Start perf measurement
                PerfStatsForText.OnStartRefresh();

                // Apply text changes to the compilation document
                IList <DocumentChange <ICobolTextLine> > documentChanges = new List <DocumentChange <ICobolTextLine> >(textChangedEvent.TextChanges.Count);
                foreach (TextChange textChange in textChangedEvent.TextChanges)
                {
                    DocumentChange <ICobolTextLine> appliedChange = null;
                    CodeElementsLine newLine = null;
                    bool             encounteredCodeElement;
                    switch (textChange.Type)
                    {
                    case TextChangeType.DocumentCleared:
                        compilationDocumentLines.Clear();
                        appliedChange = new DocumentChange <ICobolTextLine>(DocumentChangeType.DocumentCleared, 0, null);
                        // Ignore all previous document changes : they are meaningless now that the document was completely cleared
                        documentChanges.Clear();
                        break;

                    case TextChangeType.LineInserted:
                        newLine = CreateNewDocumentLine(textChange.NewLine, TextSourceInfo.ColumnsLayout);
                        compilationDocumentLines.Insert(textChange.LineIndex, newLine);

                        encounteredCodeElement = false;                                                       //Will allow to update allow line index without erasing all diagnostics after the first encountered line with CodeElements

                        foreach (var lineToUpdate in compilationDocumentLines.Skip(textChange.LineIndex + 1)) //Loop on every line that appears after added line
                        {
                            //Remove generated diagnostics for the line below the inserted line.
                            if (!encounteredCodeElement)
                            {
                                lineToUpdate.ResetDiagnostics();     //Reset diag when on the same zone
                            }
                            lineToUpdate.LineIndex++;
                            lineToUpdate.UpdateDiagnositcsLine();

                            if (lineToUpdate.CodeElements != null)
                            {
                                encounteredCodeElement = true;
                            }
                        }

                        appliedChange = new DocumentChange <ICobolTextLine>(DocumentChangeType.LineInserted, textChange.LineIndex, newLine);
                        break;

                    case TextChangeType.LineUpdated:
                        newLine = CreateNewDocumentLine(textChange.NewLine, TextSourceInfo.ColumnsLayout);
                        compilationDocumentLines[textChange.LineIndex] = newLine;
                        // Check to see if this change can be merged with a previous one
                        bool changeAlreadyApplied = false;
                        foreach (DocumentChange <ICobolTextLine> documentChangeToAdjust in documentChanges)
                        {
                            if (documentChangeToAdjust.LineIndex == textChange.LineIndex)
                            {
                                changeAlreadyApplied = true;
                                break;
                            }
                        }
                        if (!changeAlreadyApplied)
                        {
                            appliedChange = new DocumentChange <ICobolTextLine>(DocumentChangeType.LineUpdated, textChange.LineIndex, newLine);
                        }
                        // Line indexes are not impacted
                        break;

                    case TextChangeType.LineRemoved:
                        compilationDocumentLines.RemoveAt(textChange.LineIndex);
                        encounteredCodeElement = false;                                                   //Will allow to update allow line index without erasing all diagnostics after the first encountered line with CodeElements

                        foreach (var lineToUpdate in compilationDocumentLines.Skip(textChange.LineIndex)) //Loop on every line that appears after deleted line
                        {
                            //Remove generated diagnostics for the line below the deleted line.
                            if (!encounteredCodeElement)
                            {
                                lineToUpdate.ResetDiagnostics();
                            }

                            lineToUpdate.LineIndex--;
                            lineToUpdate.UpdateDiagnositcsLine();

                            if (lineToUpdate.CodeElements != null)
                            {
                                encounteredCodeElement = true;
                            }
                        }

                        appliedChange = new DocumentChange <ICobolTextLine>(DocumentChangeType.LineRemoved, textChange.LineIndex, null);
                        // Recompute the line indexes of all the changes prevously applied
                        IList <DocumentChange <ICobolTextLine> > documentChangesToRemove = null;
                        foreach (DocumentChange <ICobolTextLine> documentChangeToAdjust in documentChanges)
                        {
                            if (documentChangeToAdjust.LineIndex > textChange.LineIndex)
                            {
                                documentChangeToAdjust.LineIndex = documentChangeToAdjust.LineIndex - 1;
                            }
                            else if (documentChangeToAdjust.LineIndex == textChange.LineIndex)
                            {
                                if (documentChangesToRemove == null)
                                {
                                    documentChangesToRemove = new List <DocumentChange <ICobolTextLine> >(1);
                                }
                                documentChangesToRemove.Add(documentChangeToAdjust);
                            }
                        }
                        // Ignore all previous changes applied to a line now removed
                        if (documentChangesToRemove != null)
                        {
                            foreach (DocumentChange <ICobolTextLine> documentChangeToRemove in documentChangesToRemove)
                            {
                                documentChanges.Remove(documentChangeToRemove);
                            }
                        }
                        break;
                    }
                    if (appliedChange != null)
                    {
                        documentChanges.Add(appliedChange);
                    }
                }

                // Create a new version of the document to track these changes
                currentTextLinesVersion.changes = documentChanges;
                currentTextLinesVersion.next    = new DocumentVersion <ICobolTextLine>(currentTextLinesVersion);

                // Prepare an event to signal document change to all listeners
                documentChangedEvent    = new DocumentChangedEvent <ICobolTextLine>(currentTextLinesVersion, currentTextLinesVersion.next);
                currentTextLinesVersion = currentTextLinesVersion.next;

                // Stop perf measurement
                PerfStatsForText.OnStopRefresh();
            }

            // Send events to all listeners
            EventHandler <DocumentChangedEvent <ICobolTextLine> > textLinesChanged = TextLinesChanged; // avoid race condition

            if (textLinesChanged != null)
            {
                textLinesChanged(this, documentChangedEvent);
            }
        }
コード例 #9
0
        void OnDocumentChanged(object sender, DocumentChangedEventArgs e)
        {
            var document = e.GetDocument();
            var added    = e.GetAddedElementIds();
            var deleted  = e.GetDeletedElementIds();
            var modified = e.GetModifiedElementIds();

            if (added.Count > 0 || deleted.Count > 0 || modified.Count > 0)
            {
                foreach (GH_Document definition in Instances.DocumentServer)
                {
                    bool expireNow =
                        (e.Operation == UndoOperation.TransactionCommitted || e.Operation == UndoOperation.TransactionUndone || e.Operation == UndoOperation.TransactionRedone) &&
                        GH_Document.EnableSolutions &&
                        Instances.ActiveCanvas.Document == definition &&
                        definition.Enabled &&
                        definition.SolutionState != GH_ProcessStep.Process;

                    var change = new DocumentChangedEvent()
                    {
                        Operation  = e.Operation,
                        Document   = document,
                        Definition = definition
                    };

                    foreach (var obj in definition.Objects)
                    {
                        if (obj is Parameters.IGH_ElementIdParam persistentParam)
                        {
                            if (persistentParam.DataType == GH_ParamData.remote)
                            {
                                continue;
                            }

                            if (persistentParam.Phase == GH_SolutionPhase.Blank)
                            {
                                continue;
                            }

                            if (persistentParam.NeedsToBeExpired(document, added, deleted, modified))
                            {
                                if (expireNow)
                                {
                                    persistentParam.ExpireSolution(false);
                                }
                                else
                                {
                                    change.ExpiredObjects.Add(persistentParam);
                                }
                            }
                        }
                        else if (obj is Components.IGH_ElementIdComponent persistentComponent)
                        {
                            if (persistentComponent.NeedsToBeExpired(e))
                            {
                                if (expireNow)
                                {
                                    persistentComponent.ExpireSolution(false);
                                }
                                else
                                {
                                    change.ExpiredObjects.Add(persistentComponent);
                                }
                            }
                        }
                    }

                    if (definition.SolutionState != GH_ProcessStep.Process)
                    {
                        changeQuque.Enqueue(change);
                    }
                    else if (definition == Instances.ActiveCanvas.Document)
                    {
                        if (change.ExpiredObjects.Count > 0)
                        {
                            foreach (var obj in change.ExpiredObjects)
                            {
                                obj.ClearData();
                                obj.AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, $"This object was expired because it contained obsolete Revit elements.");
                            }

                            Instances.DocumentEditor.SetStatusBarEvent
                            (
                                new GH_RuntimeMessage
                                (
                                    change.ExpiredObjects.Count == 1 ?
                                    $"An object was expired because it contained obsolete Revit elements." :
                                    $"{change.ExpiredObjects.Count} objects were expired because them contained obsolete Revit elements.",
                                    GH_RuntimeMessageLevel.Remark,
                                    "Document"
                                )
                            );
                        }
                    }
                }
            }
        }
コード例 #10
0
ファイル: TypeCobolEditor.cs プロジェクト: osmedile/TypeCobol
 // --- Handle Scanner and error events ---
 public void OnNext(DocumentChangedEvent<ITokensLine> tokensLinesChangedEvent)
 {
     // Refresh the display of all the lines which were not directly modified
     // but which were rescanned because of a scanner state change on a previous or following line
     foreach (var documentChange in tokensLinesChangedEvent.DocumentChanges)
     {
         DocumentLine rescannedLine = Document.GetLineByNumber(documentChange.LineIndex);
         TextArea.TextView.Redraw(rescannedLine.Offset, rescannedLine.Length);
     }
 }
コード例 #11
0
ファイル: CompilationUnit.cs プロジェクト: osmedile/TypeCobol
        /// <summary>
        /// Creates a new snapshot of the document viewed as CodeElement objects after parsing.
        /// (if the processed tokens lines changed since the last time this method was called)
        /// Thread-safe : this method can be called from any thread.
        /// </summary>
        public void RefreshCodeElementsDocumentSnapshot()
        {
            // Make sure two threads don't try to update this snapshot at the same time
            lock (lockObjectForCodeElementsDocumentSnapshot)
            {
                // Capture previous snapshots at one point in time
                ProcessedTokensDocument processedTokensDocument = ProcessedTokensDocumentSnapshot;
                CodeElementsDocument previousCodeElementsDocument = CodeElementsDocumentSnapshot;

                // Check if an update is necessary and compute changes to apply since last version
                bool scanAllDocumentLines = false;
                IList<DocumentChange<IProcessedTokensLine>> processedTokensLineChanges = null;
                if (previousCodeElementsDocument == null)
                {
                    scanAllDocumentLines = true;
                }
                else if (processedTokensDocument.CurrentVersion == previousCodeElementsDocument.PreviousStepSnapshot.CurrentVersion)
                {
                    // Processed tokens lines did not change since last update => nothing to do
                    return;
                }
                else
                {
                    DocumentVersion<IProcessedTokensLine> previousProcessedTokensDocumentVersion = previousCodeElementsDocument.PreviousStepSnapshot.CurrentVersion;
                    processedTokensLineChanges = previousProcessedTokensDocumentVersion.GetReducedAndOrderedChangesInNewerVersion(processedTokensDocument.CurrentVersion);
                }

                // Start perf measurement
                PerfStatsForCodeElementsParser.OnStartRefresh();

                // Track all changes applied to the document while updating this snapshot
                DocumentChangedEvent<ICodeElementsLine> documentChangedEvent = null;

                // Apply text changes to the compilation document
                if (scanAllDocumentLines)
                {
                    // Parse the whole document for the first time
                    CodeElementsParserStep.ParseDocument(TextSourceInfo, ((ImmutableList<CodeElementsLine>)processedTokensDocument.Lines), CompilerOptions);

                    // Create the first code elements document snapshot
                    CodeElementsDocumentSnapshot = new CodeElementsDocument(processedTokensDocument, new DocumentVersion<ICodeElementsLine>(this), ((ImmutableList<CodeElementsLine>)processedTokensDocument.Lines));
                }
                else
                {
                    ImmutableList<CodeElementsLine>.Builder codeElementsDocumentLines = ((ImmutableList<CodeElementsLine>)processedTokensDocument.Lines).ToBuilder();
                    IList<DocumentChange<ICodeElementsLine>> documentChanges = CodeElementsParserStep.ParseProcessedTokensLinesChanges(TextSourceInfo, codeElementsDocumentLines, processedTokensLineChanges, PrepareDocumentLineForUpdate, CompilerOptions);

                    // Create a new version of the document to track these changes
                    DocumentVersion<ICodeElementsLine> currentCodeElementsLinesVersion = previousCodeElementsDocument.CurrentVersion;
                    currentCodeElementsLinesVersion.changes = documentChanges;
                    currentCodeElementsLinesVersion.next = new DocumentVersion<ICodeElementsLine>(currentCodeElementsLinesVersion);

                    // Prepare an event to signal document change to all listeners
                    documentChangedEvent = new DocumentChangedEvent<ICodeElementsLine>(currentCodeElementsLinesVersion, currentCodeElementsLinesVersion.next);
                    currentCodeElementsLinesVersion = currentCodeElementsLinesVersion.next;

                    // Update the code elements document snapshot
                    CodeElementsDocumentSnapshot = new CodeElementsDocument(processedTokensDocument, currentCodeElementsLinesVersion, codeElementsDocumentLines.ToImmutable());
                }

                // Stop perf measurement
                PerfStatsForCodeElementsParser.OnStopRefresh();

                // Send events to all listeners
                EventHandler<DocumentChangedEvent<ICodeElementsLine>> codeElementsLinesChanged = CodeElementsLinesChanged; // avoid race condition
                if (documentChangedEvent != null && codeElementsLinesChanged != null)
                {
                    codeElementsLinesChanged(this, documentChangedEvent);
                }
            }
        }
コード例 #12
0
        /// <summary>
        /// Update the tokens lines of the document if the text lines changed since the last time this method was called.
        /// NOT thread-safe : this method can only be called from the owner thread.
        /// </summary>
        public void UpdateTokensLines()
        {
            // This method can only be called by the document owner thread
            if (documentOwnerThread == null)
            {
                documentOwnerThread = Thread.CurrentThread;
            }
            else
            {
                VerifyAccess();
            }

            // Check if an update is necessary and compute changes to apply since last version
            bool scanAllDocumentLines = false;
            IList<DocumentChange<ICobolTextLine>> textLineChanges = null;
            if(textLinesVersionForCurrentTokensLines == null)
            {
                scanAllDocumentLines = true;
            }
            else if(currentTextLinesVersion == textLinesVersionForCurrentTokensLines)
            {
                // Text lines did not change since last update => nothing to do
                return;
            }
            else
            {
                textLineChanges = textLinesVersionForCurrentTokensLines.GetReducedAndOrderedChangesInNewerVersion(currentTextLinesVersion);
            }

            // Make sure we don't update the document while taking a snapshot
            DocumentChangedEvent<ITokensLine> documentChangedEvent = null;
            lock (lockObjectForDocumentLines)
            {
                // Start perf measurement
                PerfStatsForScanner.OnStartRefresh();

                // Apply text changes to the compilation document
                if (scanAllDocumentLines)
                {
                    ScannerStep.ScanDocument(TextSourceInfo, compilationDocumentLines, CompilerOptions);
                }
                else
                {
                    IList<DocumentChange<ITokensLine>> documentChanges = ScannerStep.ScanTextLinesChanges(TextSourceInfo, compilationDocumentLines, textLineChanges, PrepareDocumentLineForUpdate, CompilerOptions);

                    // Create a new version of the document to track these changes
                    currentTokensLinesVersion.changes = documentChanges;
                    currentTokensLinesVersion.next = new DocumentVersion<ITokensLine>(currentTokensLinesVersion);

                    // Prepare an event to signal document change to all listeners
                    documentChangedEvent = new DocumentChangedEvent<ITokensLine>(currentTokensLinesVersion, currentTokensLinesVersion.next);
                    currentTokensLinesVersion = currentTokensLinesVersion.next;
                }

                // Register that the tokens lines were synchronized with the current text lines version
                textLinesVersionForCurrentTokensLines = currentTextLinesVersion;

                // Stop perf measurement
                PerfStatsForScanner.OnStopRefresh();
            }

            // Send events to all listeners
            EventHandler<DocumentChangedEvent<ITokensLine>> tokensLinesChanged = TokensLinesChanged; // avoid race condition
            if (documentChangedEvent != null && tokensLinesChanged != null)
            {
                tokensLinesChanged(this, documentChangedEvent);
            }
        }
コード例 #13
0
        /// <summary>
        /// Update the text lines of the document after a text change event.
        /// NOT thread-safe : this method can only be called from the owner thread.
        /// </summary>
        public void UpdateTextLines(TextChangedEvent textChangedEvent)
        {
            // This method can only be called by the document owner thread
            if (documentOwnerThread == null)
            {
                documentOwnerThread = Thread.CurrentThread;
            }
            else
            {
                VerifyAccess();
            }

            // Make sure we don't update the document while taking a snapshot
            DocumentChangedEvent<ICobolTextLine> documentChangedEvent = null;
            lock (lockObjectForDocumentLines)
            {
                // Start perf measurement
                PerfStatsForText.OnStartRefresh();

                // Apply text changes to the compilation document
                IList<DocumentChange<ICobolTextLine>> documentChanges = new List<DocumentChange<ICobolTextLine>>(textChangedEvent.TextChanges.Count);
                foreach (TextChange textChange in textChangedEvent.TextChanges)
                {
                    DocumentChange<ICobolTextLine> appliedChange = null;
                    CodeElementsLine newLine = null;
                    switch (textChange.Type)
                    {
                        case TextChangeType.DocumentCleared:
                            compilationDocumentLines.Clear();
                            appliedChange = new DocumentChange<ICobolTextLine>(DocumentChangeType.DocumentCleared, 0, null);
                            // Ignore all previous document changes : they are meaningless now that the document was completely cleared
                            documentChanges.Clear();
                            break;
                        case TextChangeType.LineInserted:
                            newLine = CreateNewDocumentLine(textChange.NewLine, TextSourceInfo.ColumnsLayout);
                            compilationDocumentLines.Insert(textChange.LineIndex, newLine);
                            appliedChange = new DocumentChange<ICobolTextLine>(DocumentChangeType.LineInserted, textChange.LineIndex, newLine);
                            // Recompute the line indexes of all the changes prevously applied
                            foreach (DocumentChange<ICobolTextLine> documentChangeToAdjust in documentChanges)
                            {
                                if(documentChangeToAdjust.LineIndex >= textChange.LineIndex)
                                {
                                    documentChangeToAdjust.LineIndex = documentChangeToAdjust.LineIndex + 1;
                                }
                            }
                            break;
                        case TextChangeType.LineUpdated:
                            newLine = CreateNewDocumentLine(textChange.NewLine, TextSourceInfo.ColumnsLayout);
                            compilationDocumentLines[textChange.LineIndex] = newLine;
                            // Check to see if this change can be merged with a previous one
                            bool changeAlreadyApplied = false;
                            foreach (DocumentChange<ICobolTextLine> documentChangeToAdjust in documentChanges)
                            {
                                if (documentChangeToAdjust.LineIndex == textChange.LineIndex)
                                {
                                    changeAlreadyApplied = true;
                                    break;
                                }
                            }
                            if (!changeAlreadyApplied)
                            {
                                appliedChange = new DocumentChange<ICobolTextLine>(DocumentChangeType.LineUpdated, textChange.LineIndex, newLine);
                            }
                            // Line indexes are not impacted
                            break;
                        case TextChangeType.LineRemoved:
                            compilationDocumentLines.RemoveAt(textChange.LineIndex);
                            appliedChange = new DocumentChange<ICobolTextLine>(DocumentChangeType.LineRemoved, textChange.LineIndex, null);
                            // Recompute the line indexes of all the changes prevously applied
                            IList<DocumentChange<ICobolTextLine>> documentChangesToRemove = null;
                            foreach (DocumentChange<ICobolTextLine> documentChangeToAdjust in documentChanges)
                            {
                                if (documentChangeToAdjust.LineIndex > textChange.LineIndex)
                                {
                                    documentChangeToAdjust.LineIndex = documentChangeToAdjust.LineIndex - 1;
                                }
                                else if(documentChangeToAdjust.LineIndex == textChange.LineIndex)
                                {
                                    if(documentChangesToRemove == null)
                                    {
                                        documentChangesToRemove = new List<DocumentChange<ICobolTextLine>>(1);
                                    }
                                    documentChangesToRemove.Add(documentChangeToAdjust);
                                }
                            }
                            // Ignore all previous changes applied to a line now removed
                            if(documentChangesToRemove != null)
                            {
                                foreach (DocumentChange<ICobolTextLine> documentChangeToRemove in documentChangesToRemove)
                                {
                                    documentChanges.Remove(documentChangeToRemove);
                                }
                            }
                            break;
                    }
                    if (appliedChange != null)
                    {
                        documentChanges.Add(appliedChange);
                    }
                }

                // Create a new version of the document to track these changes
                currentTextLinesVersion.changes = documentChanges;
                currentTextLinesVersion.next = new DocumentVersion<ICobolTextLine>(currentTextLinesVersion);

                // Prepare an event to signal document change to all listeners
                documentChangedEvent = new DocumentChangedEvent<ICobolTextLine>(currentTextLinesVersion, currentTextLinesVersion.next);
                currentTextLinesVersion = currentTextLinesVersion.next;

                // Stop perf measurement
                PerfStatsForText.OnStopRefresh();
            }

            // Send events to all listeners
            EventHandler<DocumentChangedEvent<ICobolTextLine>> textLinesChanged = TextLinesChanged; // avoid race condition
            if (textLinesChanged != null)
            {
                textLinesChanged(this, documentChangedEvent);
            }
        }