Esempio n. 1
0
    public void OnFileChanged(DocumentChange documentChange)
    {
      ResetCache();
      Project.UpdateProperties();

      var visitor = new CalcSymbolErrorsAstVisitor();
      this.Ast.Accept(visitor);
      var errorCount = visitor.ErrorCount;
      if (_errorCount != errorCount)
        OnRedraw();
      _errorCount = errorCount;
    }
        /// <summary>
        /// The process of generated document commit (in the case of primary document incremental reparse) can be overridden in this method.
        /// Returns null if full regeneration is required.
        /// This method is not allowed to do destructive changes due to interruptibility!
        /// </summary>
        public override ICollection<ICommitBuildResult> ExecuteSecondaryDocumentCommitWork(PrimaryFileModificationInfo primaryFileModificationInfo,
            CachedPsiFile cachedPsiFile, TreeTextRange oldTreeRange, string newText)
        {
            var rangeTranslator = (RangeTranslatorWithGeneratedRangeMap) cachedPsiFile.PsiFile.SecondaryRangeTranslator;
            if (rangeTranslator == null)
                return null;

            TreeTextRange range = rangeTranslator.OriginalToGenerated(oldTreeRange, JetPredicate<IUserDataHolder>.True);
            DocumentRange documentRange = cachedPsiFile.PsiFile.DocumentRangeTranslator.Translate(range);
            if (!documentRange.IsValid())
                return null;

            var documentChange = new DocumentChange(documentRange.Document, documentRange.TextRange.StartOffset, documentRange.TextRange.Length, newText,
                documentRange.Document.LastModificationStamp, TextModificationSide.NotSpecified);

            return new ICommitBuildResult[] {
                new CommitBuildResult(cachedPsiFile.WorkIncrementalParse(documentChange), null, documentChange, null, TextRange.InvalidRange, string.Empty),
                new FixRangeTranslatorsOnSharedRangeCommitBuildResult(rangeTranslator, null, new TreeTextRange<Original>(oldTreeRange), new TreeTextRange<Generated>(range), newText)
            };
        }
Esempio n. 3
0
    private bool OnFileChanged(IProjectFile projectFile, DocumentChange documentChange)
    {
      var project = projectFile.GetProject();
      if (project != null)
      {
        XXLanguageXXProject nitraProject;
        if (_projectsMap.TryGetValue(project, out nitraProject))
        {
          var nitraFile = nitraProject.TryGetFile(projectFile);
          if (nitraFile != null)
          {
            nitraFile.OnFileChanged(documentChange);
            return true;
          }
        }
      }

      return false;
    }
Esempio n. 4
0
        public AP.ExtractMethodResponse ExtractMethod(AP.ExtractMethodRequest input, int version)
        {
            // tighten up the selection so that we don't expand into any enclosing nodes because we overlap w/ their white space...
            var selectionStart = input.startIndex;

            while (selectionStart < _code.Length &&
                   Char.IsWhiteSpace(_code[selectionStart]))
            {
                selectionStart++;
            }

            var selectionEnd = input.endIndex;

            if (selectionEnd == _code.Length)
            {
                selectionEnd -= 1;
            }
            while (selectionEnd >= 0 && char.IsWhiteSpace(_code[selectionEnd]))
            {
                selectionEnd -= 1;
            }

            var walker = new EnclosingNodeWalker(_ast, selectionStart, selectionEnd);

            _ast.Walk(walker);

            Debug.Assert(walker.Target != null);
            if (walker.Target == null)
            {
                return(new AP.ExtractMethodResponse()
                {
                    cannotExtractReason = AP.CannotExtractReason.InvalidTargetSelected
                });
            }

            bool expanded = false;

            // expand the selection if we aren't currently covering a full expression/statement
            if (!walker.Target.IsValidSelection)
            {
                return(new AP.ExtractMethodResponse()
                {
                    cannotExtractReason = AP.CannotExtractReason.InvalidExpressionSelected
                });
            }

            expanded = WasSelectionExpanded(walker.Target, selectionStart, selectionEnd);

            // check for things we cannot handle
            if (!IsValidExtraction(walker.Target, out var failureReason))
            {
                return(new AP.ExtractMethodResponse()
                {
                    // Note: this returns the unformatted error
                    cannotExtractReason = failureReason
                });
            }

            // get the variables which are read by the selected statement(s)
            var varCollector = new InnerVariableWalker(_ast);

            walker.Target.Walk(varCollector);

            // Walk the target to understand flow control and definite assignment to further understand
            // what we need to flow in.  For example if a variable is assigned to both in the un-extracted
            // and extracted code but it's definitely assigned in the extracted code then we don't need
            // to flow the variable in.

            // Run flow checker, first on any nested scopes...
            foreach (ScopeStatement scope in varCollector._scopes)
            {
                FlowChecker.Check(scope);
            }

            // then on our extracted code
            var parent = walker.Target.Parents[walker.Target.Parents.Count - 1];
            HashSet <PythonVariable> readBeforeInit;
            FlowChecker extractedChecker = null;

            if (parent.ScopeVariables != null)
            {
                extractedChecker = new FlowChecker(parent);

                walker.Target.Walk(extractedChecker);
                readBeforeInit = extractedChecker.ReadBeforeInitializedVariables;
            }
            else
            {
                readBeforeInit = new HashSet <PythonVariable>();
            }

            // then on code which follows our extracted body
            var afterStmts = walker.Target.GetStatementsAfter();
            HashSet <PythonVariable> readByFollowingCodeBeforeInit = null;
            var parentNode = walker.Target.Parents[walker.Target.Parents.Count - 1];
            var outputVars = new HashSet <PythonVariable>();

            if (parentNode.ScopeVariables != null)
            {
                var checker = new FlowChecker(parentNode);

                foreach (var afterStmt in afterStmts)
                {
                    afterStmt.Walk(checker);
                }

                readByFollowingCodeBeforeInit = checker.ReadBeforeInitializedVariables;

                foreach (var variable in varCollector._allWrittenVariables)
                {
                    if (variable != null && variable.Scope is PythonAst)
                    {
                        // global variable assigned to in outer scope, and left with
                        // a valid value (not deleted) from the extracted code.  We
                        // need to pass the value back out and assign to it in the
                        // global scope.
                        if (!checker.IsInitialized(variable) &&
                            extractedChecker.IsAssigned(variable))
                        {
                            outputVars.Add(variable);
                        }
                    }
                }
            }

            // collect any nested scopes, and see if they read any free variables
            var scopeCollector = new ScopeCollector();

            foreach (var afterStmt in afterStmts)
            {
                afterStmt.Walk(scopeCollector);
            }

            foreach (var scope in scopeCollector._scopes)
            {
                if (scope.FreeVariables != null)
                {
                    foreach (var freeVar in scope.FreeVariables)
                    {
                        if (varCollector._allWrittenVariables.Contains(freeVar))
                        {
                            // we've assigned to a variable accessed from an inner
                            // scope, we need to get the value of the variable back out.
                            outputVars.Add(freeVar);
                        }
                    }
                }
            }


            // discover any variables which are consumed and need to be available as outputs...
            var outputCollector = new OuterVariableWalker(_ast, walker.Target, varCollector, readBeforeInit, readByFollowingCodeBeforeInit, outputVars);

            _ast.Walk(outputCollector);

            if (outputCollector._outputVars.Count > 0 &&
                walker.Target.ContainsReturn)
            {
                return(new AP.ExtractMethodResponse {
                    cannotExtractReason = AP.CannotExtractReason.MethodAssignsVariablesAndReturns
                });
            }

            var targetScope = walker.Target.Parents[input.scope ?? 0];
            var creator     = new OutOfProcExtractedMethodCreator(
                _ast,
                walker.Target.Parents,
                outputCollector._inputVars,
                outputCollector._outputVars,
                walker.Target,
                input.indentSize,
                !input.convertTabsToSpaces,
                input.newLine,
                input.name,
                input.parameters ?? new string[0],
                walker.Target.Parents[input.scope ?? 0]
                );

            // get the new method body...
            var newMethod = creator.GetExtractionResult();

            var changes = new List <DocumentChange>();

            var callChange   = DocumentChange.Replace(walker.Target.StartIncludingIndentation, walker.Target.End, newMethod.Call);
            var methodChange = DocumentChange.Insert(newMethod.Method, walker.Target.InsertLocations[targetScope]);

            if (callChange.ReplacedSpan.Start < methodChange.ReplacedSpan.Start)
            {
                changes.Add(callChange);
                changes.Add(methodChange);
            }
            else
            {
                changes.Add(methodChange);
                changes.Add(callChange);
            }

            List <AP.ScopeInfo> scopes = new List <AP.ScopeInfo>();

            for (int i = 0; i < walker.Target.Parents.Count; i++)
            {
                var scope     = walker.Target.Parents[i];
                var scopeInfo = new AP.ScopeInfo()
                {
                    name      = scope.Name,
                    id        = i,
                    type      = GetScopeType(scope),
                    variables = GetScopeVariables(scope, outputCollector._inputVars)
                };
                scopes.Add(scopeInfo);
            }

            return(new AP.ExtractMethodResponse()
            {
                changes = changes.Select(AP.ChangeInfo.FromDocumentChange).ToArray(),
                methodBody = newMethod.Method,
                variables = outputCollector._inputVars.Select(x => x.Name).ToArray(),
                scopes = scopes.ToArray(),
                wasExpanded = expanded,
                startLine = walker.Target.StartIncludingIndentation.Line,
                startCol = walker.Target.StartIncludingIndentation.Column,
                endLine = walker.Target.End.Line,
                endCol = walker.Target.End.Column,
                version = version
            });
        }
Esempio n. 5
0
 internal void OnDocumentChange()
 {
     DocumentChange?.Invoke();
 }
Esempio n. 6
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:
                        if (compilationDocumentLines.LastOrDefault() == null)
                        {
                            continue;
                        }
                        if (compilationDocumentLines.Count < textChange.LineIndex)     //Avoid line remove exception
                        {
                            continue;
                        }

                        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);
            }
        }
        public void DidChangeTextDocument(DidChangeTextDocumentParams @params)
        {
            _disposableBag.ThrowIfDisposed();
            var uri = @params.textDocument.uri;
            var doc = _rdt.GetDocument(uri);

            if (doc != null)
            {
                var changes = new List <DocumentChange>();
                foreach (var c in @params.contentChanges)
                {
                    var change = c.range.HasValue ? DocumentChange.Replace(c.range.Value, c.text) : DocumentChange.ReplaceAll(c.text);
                    changes.Add(change);
                }
                doc.Update(changes);
                _indexManager.AddPendingDoc(doc);
            }
            else
            {
                _log?.Log(TraceEventType.Warning, $"Unable to find document for {@params.textDocument.uri}");
            }
        }
Esempio n. 8
0
        internal static IList <DocumentChange <ITokensLine> > ScanTextLinesChanges(TextSourceInfo textSourceInfo, ISearchableReadOnlyList <TokensLine> documentLines, IList <DocumentChange <ICobolTextLine> > textLinesChanges, PrepareDocumentLineForUpdate prepareDocumentLineForUpdate, TypeCobolOptions compilerOptions, List <RemarksDirective.TextNameVariation> copyTextNameVariations,
                                                                                   [CanBeNull] MultilineScanState scanState)
        {
            // Collect all changes applied to the tokens lines during the incremental scan
            IList <DocumentChange <ITokensLine> > tokensLinesChanges = new List <DocumentChange <ITokensLine> >();

            // There are 3 reasons to scan a line after a text change :
            // 1. New text lines which were just inserted or updated must be scanned for the first time
            // 2. Text lines must be scanned again if their initial scan state changed : a new scan of the previous line can alter the scan state at the beginning of the following line
            // 3. Continuation lines and multiline tokens : if a line participates in a continuation on several lines, scan the group of lines as a whole

            // IMPORTANT : the text changes are ordered in increasing order of line index
            for (int textChangeIndex = 0; textChangeIndex < textLinesChanges.Count; textChangeIndex++)
            {
                // Local variables used to optimize navigation in the document
                int        nextLineToScanIndex = -1;
                TokensLine nextLineToScan      = null;

                // Update tokens depending on the current text change
                DocumentChange <ICobolTextLine> textChange = textLinesChanges[textChangeIndex];
                if (textChange.Type == DocumentChangeType.DocumentCleared)
                {
                    tokensLinesChanges.Add(new DocumentChange <ITokensLine>(DocumentChangeType.DocumentCleared, 0, null));
                    continue;
                }
                else if (textChange.Type == DocumentChangeType.LineInserted || textChange.Type == DocumentChangeType.LineUpdated)
                {
                    // We update lines as a group below, but we remember here which lines were inserted
                    if (textChange.Type == DocumentChangeType.LineInserted)
                    {
                        tokensLinesChanges.Add(new DocumentChange <ITokensLine>(DocumentChangeType.LineInserted, textChange.LineIndex, (ITokensLine)textChange.NewLine));
                    }

                    // Text lines which were inserted or updated must be scanned again
                    ScanTokensLineWithMultilineScanState(textChange.LineIndex, (TokensLine)textChange.NewLine, textSourceInfo, documentLines, prepareDocumentLineForUpdate, compilerOptions, copyTextNameVariations, tokensLinesChanges, scanState, out nextLineToScanIndex, out nextLineToScan);
                }
                else if (textChange.Type == DocumentChangeType.LineRemoved)
                {
                    tokensLinesChanges.Add(new DocumentChange <ITokensLine>(DocumentChangeType.LineRemoved, textChange.LineIndex, (ITokensLine)textChange.NewLine));

                    // Get the last line just before the line that was removed
                    TokensLine previousLine = null;
                    if (textChange.LineIndex > 0)
                    {
                        previousLine = documentLines[textChange.LineIndex - 1];
                    }

                    // When a text line is removed :
                    // - the previous line must be scanned again if the line which was removed was a member of a multiline continuation group
                    if (previousLine != null && previousLine.HasTokenContinuedOnNextLine)
                    {
                        ScanTokensLineWithMultilineScanState(textChange.LineIndex - 1, previousLine, textSourceInfo, documentLines, prepareDocumentLineForUpdate, compilerOptions, copyTextNameVariations, tokensLinesChanges, scanState, out nextLineToScanIndex, out nextLineToScan);
                    }
                    if (nextLineToScan == null && textChange.LineIndex < documentLines.Count)
                    {
                        nextLineToScanIndex = textChange.LineIndex;
                        nextLineToScan      = documentLines[nextLineToScanIndex];
                    }
                    // - the next line must be scanned again if the scan state at the end of the previous line is different from the scan state at the beginning of the next line
                    if (nextLineToScan != null && nextLineToScanIndex == textChange.LineIndex && previousLine != null &&
                        nextLineToScan.InitialScanState.Equals(previousLine.ScanState))
                    {
                        ScanTokensLineWithMultilineScanState(textChange.LineIndex, nextLineToScan, textSourceInfo, documentLines, prepareDocumentLineForUpdate, compilerOptions, copyTextNameVariations, tokensLinesChanges, scanState, out nextLineToScanIndex, out nextLineToScan);
                    }
                }

                // We can skip all text changes with an index smaller than the index of the last line which was already scanned
                if (nextLineToScan == null)
                {
                    break;
                }
                else if (textChangeIndex < (textLinesChanges.Count - 1))
                {
                    int nextTextChangeIndex = textChangeIndex;
                    DocumentChange <ICobolTextLine> nextTextChange = null;
                    do
                    {
                        nextTextChangeIndex++;
                        nextTextChange = textLinesChanges[nextTextChangeIndex];
                    }while (nextTextChangeIndex < (textLinesChanges.Count - 1) &&
                            nextTextChange.LineIndex <= nextLineToScanIndex);
                    textChangeIndex = nextTextChangeIndex - 1;
                }
            }

            return(tokensLinesChanges);
        }
Esempio n. 9
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);
            }
        }
Esempio n. 10
0
 public abstract void NotifyAboutWork(DocumentChange change);
 public DocumentChangeWrapper(DocumentChange documentChange)
 {
     _documentChange = documentChange ?? throw new ArgumentNullException(nameof(documentChange));
 }
Esempio n. 12
0
        private void DeleteStatement(List <DocumentChange> changes, SourceSpan span, bool insertPass)
        {
            // remove the entire node, leave any trailing whitespace/comments, but include the
            // newline and any indentation.

            int start  = _ast.LocationToIndex(span.Start);
            int length = _ast.GetSpanLength(span);
            int cur    = start - 1;

            if (!insertPass)
            {
                // backup to remove any indentation
                while (start - 1 > 0)
                {
                    var curChar = _code[start - 1];
                    if (curChar == ' ' || curChar == '\t' || curChar == '\f')
                    {
                        length++;
                        start--;
                    }
                    else
                    {
                        break;
                    }
                }
            }

            // extend past any trailing whitespace characters
            while (start + length < _code.Length)
            {
                var curChar = _code[start + length];
                if (curChar == ' ' || curChar == '\t' || curChar == '\f')
                {
                    length++;
                }
                else
                {
                    break;
                }
            }

            // remove the trailing newline as well.
            if (!insertPass)
            {
                if (start + length < _code.Length)
                {
                    var newlineText = _code[start + length];
                    if (newlineText == '\r')
                    {
                        if (start + length + 1 < _code.Length)
                        {
                            newlineText = _code[start + length + 1];
                            if (newlineText == '\n')
                            {
                                length += 2;
                            }
                            else
                            {
                                length++;
                            }
                        }
                        else
                        {
                            length++;
                        }
                    }
                    else if (newlineText == '\n')
                    {
                        length++;
                    }
                }
            }

            changes.Add(DocumentChange.Replace(
                            _ast,
                            start,
                            length,
                            insertPass ? "pass": null
                            ));
        }
Esempio n. 13
0
        public IReadOnlyList <DocumentChange> ReplaceCode()
        {
            var edits          = new List <DocumentChange>();
            var oldLineMapping = new Dictionary <string, List <int> >();   // line to line #

            for (int i = 0; i < _oldLines.Count; i++)
            {
                List <int> lineInfo;
                if (!oldLineMapping.TryGetValue(GetOldText(i), out lineInfo))
                {
                    oldLineMapping[GetOldText(i)] = lineInfo = new List <int>();
                }
                lineInfo.Add(i);
            }

            int curOldLine = 0;

            for (int curNewLine = 0; curOldLine < _oldLines.Count && curNewLine < _newLines.Count; curOldLine++)
            {
                if (GetOldText(curOldLine) == GetNewText(curNewLine))
                {
                    curNewLine++;
                    continue;
                }

                bool replaced = false;
                // replace starts on this line, figure out where it ends...
                int startNewLine = curNewLine;
                for (curNewLine += 1; curNewLine < _newLines.Count; curNewLine++)
                {
                    List <int> lines;
                    if (oldLineMapping.TryGetValue(GetNewText(curNewLine), out lines))
                    {
                        foreach (var matchingLineNo in lines)
                        {
                            if (matchingLineNo > curOldLine)
                            {
                                // Replace the lines from curOldLine to matchingLineNo-1 with the text
                                // from startNewLine - curNewLine - 1.
                                ReplaceLines(edits, curOldLine, matchingLineNo, startNewLine, curNewLine);
                                replaced   = true;
                                curOldLine = matchingLineNo - 1;
                                break;
                            }
                        }
                    }

                    if (replaced)
                    {
                        break;
                    }
                }

                if (!replaced)
                {
                    ReplaceLines(edits, curOldLine, _oldLines.Count, startNewLine, _newLines.Count);
                    curOldLine = _oldLines.Count;
                    break;
                }
            }

            if (curOldLine < _oldLines.Count)
            {
                // remove the remaining new lines
                edits.Add(
                    DocumentChange.Delete(new SourceSpan(
                                              _oldLines[curOldLine].SourceStart,
                                              _oldLines[_oldLines.Count - 1].SourceEnd
                                              ))
                    );
            }
            return(edits.ToArray());
        }
Esempio n. 14
0
        public void DidChangeTextDocument(DidChangeTextDocumentParams @params)
        {
            _disposableBag.ThrowIfDisposed();
            var doc = _rdt.GetDocument(@params.textDocument.uri);

            if (doc != null)
            {
                doc.Update(@params.contentChanges
                           .Select(c => c.range.HasValue ? DocumentChange.Replace(c.range.Value, c.text) : DocumentChange.ReplaceAll(c.text)));
                _indexManager.AddPendingDoc(doc);
            }
            else
            {
                _log?.Log(TraceEventType.Warning, $"Unable to find document for {@params.textDocument.uri}");
            }
        }
 private void OnDocumentChange(DocumentChange change)
 {
     OnChangeInternal(change.TriggeredByReplicationThread);
 }
 public DocumentChangeWrapper(DocumentChange documentChange)
 {
     DocumentChange = documentChange;
 }
        /// <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);
            }
        }
Esempio n. 18
0
 public abstract void NotifyAboutWork(DocumentChange documentChange, CounterChange counterChange);
Esempio n. 19
0
        public override IEnumerable <PatternInstance> DetectAsPatternInstances(ILogProvider logProvider)
        {
            // we only consider "Create" because people often do not close the application at all.
            List <Event> list = logProvider.LoggedEvents.Where(x => x is DocumentChange || (x is RunCommand && !((RunCommand)x).IsTerminate)).ToList();

            Event lastRun = null;

            List <ParameterTuneElement> deleteOffsets = new List <ParameterTuneElement>();

            foreach (int i in Enumerable.Range(0, list.Count))
            {
                if (list[i] is RunCommand)
                {
                    RunCommand currentRun = (RunCommand)list[i];

                    if (lastRun != null)
                    {
                        // TODO: Make it as an option! Current value is 1 min.
                        if (currentRun.Timestamp - lastRun.Timestamp <= 45000)
                        {
                            foreach (var element in deleteOffsets)
                            {
                                if (CheckElement(element))
                                {
                                    var result = new PatternInstance(
                                        lastRun,
                                        -1,
                                        "Deleted: \"" + element.DeletedText + "\", Inserted: \"" + element.InsertedText + "\""
                                        );
                                    yield return(result);
                                }
                            }
                        }
                    }

                    lastRun = currentRun;
                    deleteOffsets.Clear();
                }
                else if (list[i] is DocumentChange)
                {
                    DocumentChange dc = (DocumentChange)list[i];
                    if (dc is Delete)
                    {
                        Delete delete = (Delete)dc;

                        // TODO: Merge delete offsets if necessary!
                        foreach (int j in Enumerable.Range(0, deleteOffsets.Count))
                        {
                            if (deleteOffsets[j].Confirmed)
                            {
                                continue;
                            }

                            if (deleteOffsets[j].DeleteOffset > delete.Offset)
                            {
                                deleteOffsets[j].DeleteOffset -= delete.Length;
                            }
                        }

                        deleteOffsets.Add(new ParameterTuneElement(delete));
                    }
                    else if (dc is Insert)
                    {
                        Insert insert = (Insert)dc;

                        foreach (int j in Enumerable.Range(0, deleteOffsets.Count))
                        {
                            if (deleteOffsets[j].Confirmed)
                            {
                                continue;
                            }

                            if (deleteOffsets[j].DeleteOffset > insert.Offset)
                            {
                                deleteOffsets[j].DeleteOffset += insert.Length;
                            }
                            else if (deleteOffsets[j].DeleteOffset == insert.Offset)
                            {
                                deleteOffsets[j].InsertedText = insert.Text;
                                deleteOffsets[j].Confirmed    = true;
                            }
                        }
                    }
                    else if (dc is Replace && !logProvider.CausedByAutoIndent(dc) && !logProvider.CausedByAssist(dc))
                    {
                        Replace replace = (Replace)dc;

                        deleteOffsets.Add(new ParameterTuneElement(replace));

                        foreach (int j in Enumerable.Range(0, deleteOffsets.Count))
                        {
                            if (deleteOffsets[j].Confirmed)
                            {
                                continue;
                            }

                            if (deleteOffsets[j].DeleteOffset == replace.Offset)
                            {
                                deleteOffsets[j].DeleteOffset -= replace.Length;
                                deleteOffsets[j].DeleteOffset += replace.InsertionLength;
                            }
                        }
                    }
                }
            }
        }
Esempio n. 20
0
 public abstract void Reset(DocumentChange change);
Esempio n. 21
0
 private void OnDocumentChange(DocumentChange change)
 {
     NotifyAboutWork(documentChange: change, counterChange: null);
 }