/// <summary> /// Creates a temporary snapshot which contains element before the cross check phase /// Usefull to create a program symboltable without checking nodes. /// For instance : it's used to load all the symbols from every dependencies before running the cross check phase to resolve symbols. /// <param name="useAntlrProgramParsing">Shall ANTLR be used to parse TypeCobol Program, otherwise it will be CUP</param> /// </summary> public void ProduceTemporarySemanticDocument() { lock (lockObjectForTemporarySemanticDocument) { // Capture previous snapshot at one point in time CodeElementsDocument codeElementsDocument = CodeElementsDocumentSnapshot; if (CodeElementsDocumentSnapshot != null && (TemporaryProgramClassDocumentSnapshot == null || TemporaryProgramClassDocumentSnapshot.PreviousStepSnapshot.CurrentVersion != CodeElementsDocumentSnapshot.CurrentVersion)) { // Start perf measurement var perfStatsForParserInvocation = PerfStatsForTemporarySemantic.OnStartRefreshParsingStep(); // Program and Class parsing is not incremental : the objects are rebuilt each time this method is called SourceFile root; List <Diagnostic> newDiagnostics; Dictionary <CodeElement, Node> nodeCodeElementLinkers = new Dictionary <CodeElement, Node>(); //TODO cast to ImmutableList<CodeElementsLine> sometimes fails here ProgramClassParserStep.CupParseProgramOrClass(TextSourceInfo, ((ImmutableList <CodeElementsLine>)codeElementsDocument.Lines), CompilerOptions, CustomSymbols, perfStatsForParserInvocation, out root, out newDiagnostics, out nodeCodeElementLinkers); // Capture the produced results TemporaryProgramClassDocumentSnapshot = new TemporarySemanticDocument(codeElementsDocument, new DocumentVersion <ICodeElementsLine>(this), codeElementsDocument.Lines, root, newDiagnostics, nodeCodeElementLinkers); // Stop perf measurement PerfStatsForTemporarySemantic.OnStopRefreshParsingStep(); } } }
/// <summary> /// Creates a new snapshot of the document viewed as complete Cobol Program or Class. /// (if the code elements lines changed since the last time this method was called) /// Thread-safe : this method can be called from any thread. /// </summary> public void RefreshProgramClassDocumentSnapshot() { // Make sure two threads don't try to update this snapshot at the same time bool snapshotWasUpdated = false; lock (lockObjectForProgramClassDocumentSnapshot) { // Capture previous snapshot at one point in time CodeElementsDocument codeElementsDocument = CodeElementsDocumentSnapshot; // Check if an update is necessary and compute changes to apply since last version if ((CodeElementsDocumentSnapshot != null) && (ProgramClassDocumentSnapshot == null || ProgramClassDocumentSnapshot.PreviousStepSnapshot.CurrentVersion != codeElementsDocument.CurrentVersion)) { // Start perf measurement var perfStatsForParserInvocation = PerfStatsForProgramClassParser.OnStartRefreshParsingStep(); // Program and Class parsing is not incremental : the objects are rebuilt each time this method is called SourceFile root; IList <ParserDiagnostic> newDiagnostics; Dictionary <CodeElement, Node> nodeCodeElementLinkers = new Dictionary <CodeElement, Node>(); //TODO cast to ImmutableList<CodeElementsLine> sometimes fails here ProgramClassParserStep.ParseProgramOrClass(TextSourceInfo, ((ImmutableList <CodeElementsLine>)codeElementsDocument.Lines), CompilerOptions, CustomSymbols, perfStatsForParserInvocation, out root, out newDiagnostics, out nodeCodeElementLinkers); // Capture the result of the parse in a new snapshot ProgramClassDocumentSnapshot = new ProgramClassDocument( codeElementsDocument, ProgramClassDocumentSnapshot == null ? 0 : ProgramClassDocumentSnapshot.CurrentVersion + 1, root, newDiagnostics, nodeCodeElementLinkers); snapshotWasUpdated = true; // Stop perf measurement PerfStatsForProgramClassParser.OnStopRefreshParsingStep(); } } // Send events to all listeners EventHandler <ProgramClassEvent> programClassChanged = ProgramClassChanged; // avoid race condition EventHandler <ProgramClassEvent> programClassNotChanged = ProgramClassNotChanged; if (snapshotWasUpdated && programClassChanged != null) { programClassChanged(this, new ProgramClassEvent() { Version = ProgramClassDocumentSnapshot.CurrentVersion }); } else if (!snapshotWasUpdated && programClassNotChanged != null) { programClassNotChanged(this, new ProgramClassEvent() { Version = ProgramClassDocumentSnapshot.CurrentVersion }); } }
/// <summary> /// Creates a new snapshot of the document viewed as complete Cobol Program or Class. /// Thread-safe : this method can be called from any thread. /// </summary> public void RefreshProgramClassDocumentSnapshot() { // Make sure two threads don't try to update this snapshot at the same time bool snapshotWasUpdated = false; lock (lockObjectForProgramClassDocumentSnapshot) { // Capture previous snapshot at one point in time TemporarySemanticDocument temporarySnapshot = TemporaryProgramClassDocumentSnapshot; // Check if an update is necessary and compute changes to apply since last version if ((TemporaryProgramClassDocumentSnapshot != null) && (ProgramClassDocumentSnapshot == null || ProgramClassDocumentSnapshot.PreviousStepSnapshot.CurrentVersion != temporarySnapshot.CurrentVersion)) { PerfStatsForProgramCrossCheck.OnStartRefreshParsingStep(); // Program and Class parsing is not incremental : the objects are rebuilt each time this method is called SourceFile root = temporarySnapshot.Root; List <Diagnostic> diagnostics = new List <Diagnostic>(); Dictionary <CodeElement, Node> nodeCodeElementLinkers = temporarySnapshot.NodeCodeElementLinkers ?? new Dictionary <CodeElement, Node>(); ProgramClassParserStep.CrossCheckPrograms(root); // Capture the result of the parse in a new snapshot ProgramClassDocumentSnapshot = new ProgramClassDocument( temporarySnapshot, ProgramClassDocumentSnapshot?.CurrentVersion + 1 ?? 0, root, diagnostics, nodeCodeElementLinkers); snapshotWasUpdated = true;; PerfStatsForProgramCrossCheck.OnStopRefreshParsingStep(); } } // Send events to all listeners EventHandler <ProgramClassEvent> programClassChanged = ProgramClassChanged; // avoid race condition EventHandler <ProgramClassEvent> programClassNotChanged = ProgramClassNotChanged; if (snapshotWasUpdated && programClassChanged != null) { programClassChanged(this, new ProgramClassEvent() { Version = ProgramClassDocumentSnapshot.CurrentVersion }); } else if (!snapshotWasUpdated && programClassNotChanged != null) { programClassNotChanged(this, new ProgramClassEvent() { Version = ProgramClassDocumentSnapshot.CurrentVersion }); } }