Skip to content

Commit e2893cc

Browse files
mayanjefm-117
andauthored
WI #2046 Find various NullReferenceException (#2049)
* WI #2046 Find various NullReferenceException * WI #2046 Change Review * WI #2046 use cup preprocessor. * WI #2046 Refactor Cup vs ANTLR preprocessor choice Co-authored-by: fm-117 <milletfl@e-i.com>
1 parent 84a21a0 commit e2893cc

File tree

11 files changed

+112
-86
lines changed

11 files changed

+112
-86
lines changed

TypeCobol.LanguageServer/TypeCobolServer.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,16 @@ protected void MissingCopiesDetected(TextDocumentIdentifier textDocument, List<s
173173

174174
#if EUROINFO_RULES
175175
ILookup<bool, string> lookup = copiesName.ToLookup(s => Workspace.CompilationProject.CompilationOptions.HasCpyCopy(s));
176-
missingCopiesParam.Copies = lookup[false].ToList();
177-
missingCopiesParam.CpyCopies = lookup[true].ToList();
176+
//----------------------------------------------------------
177+
// We need to review this mechanism with RTC.
178+
// Because actually it produces bad results and it will
179+
// be clarified with RTC specifications. (see TFS 117645)
180+
//----------------------------------------------------------
181+
//missingCopiesParam.Copies = lookup[false].ToList();
182+
//missingCopiesParam.CpyCopies = lookup[true].ToList();
183+
//----------------------------------------------------------
184+
missingCopiesParam.Copies = copiesName;
185+
missingCopiesParam.CpyCopies = new List<string>();
178186
#else
179187
missingCopiesParam.Copies = copiesName;
180188
missingCopiesParam.CpyCopies = new List<string>();

TypeCobol.LanguageServer/Workspace.cs

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ private FileCompiler OpenTextDocument(DocumentContext docContext, string sourceT
253253

254254
if (lsrOptions != LsrTestingOptions.LsrSourceDocumentTesting)
255255
{
256-
fileCompiler.CompileOnce(lsrOptions.ExecutionStep(fileCompiler.CompilerOptions.ExecToStep.Value), fileCompiler.CompilerOptions.HaltOnMissingCopy, fileCompiler.CompilerOptions.UseAntlrProgramParsing); //Let's parse file for the first time after opening.
256+
fileCompiler.CompileOnce(lsrOptions.ExecutionStep(fileCompiler.CompilerOptions.ExecToStep.Value), fileCompiler.CompilerOptions.HaltOnMissingCopy); //Let's parse file for the first time after opening.
257257
}
258258

259259
return fileCompiler;
@@ -317,7 +317,7 @@ public void UpdateSourceFile(Uri fileUri, TextChangedEvent textChangedEvent)
317317
//further it's for semantic, which is handle by NodeRefresh method
318318

319319

320-
fileCompilerToUpdate.CompileOnce(execStep, fileCompilerToUpdate.CompilerOptions.HaltOnMissingCopy, fileCompilerToUpdate.CompilerOptions.UseAntlrProgramParsing);
320+
fileCompilerToUpdate.CompileOnce(execStep, fileCompilerToUpdate.CompilerOptions.HaltOnMissingCopy);
321321
fileCompilerToUpdate.ExecutionStepEventHandler -= handler.Invoke;
322322

323323

@@ -405,7 +405,8 @@ private void TimerEvent(Uri fileUri)
405405
catch (Exception e)
406406
{
407407
//In case Timer Thread crash
408-
ExceptionTriggered(null, new ThreadExceptionEventArgs(e));
408+
if (ExceptionTriggered != null)
409+
ExceptionTriggered(null, new ThreadExceptionEventArgs(e));
409410
}
410411

411412
void Refresh()
@@ -687,7 +688,7 @@ private void RefreshCustomSymbols()
687688
_customSymbols = Tools.APIHelpers.Helpers.LoadIntrinsic(Configuration.Copies, Configuration.Format, DiagnosticsErrorEvent); //Refresh Intrinsics
688689
_customSymbols = Tools.APIHelpers.Helpers.LoadDependencies(Configuration, _customSymbols, DiagnosticsErrorEvent, out List<RemarksDirective.TextNameVariation> usedCopies, out IDictionary<string, IEnumerable<string>> missingCopies); //Refresh Dependencies
689690

690-
if (missingCopies.Count > 0)
691+
if (MissingCopiesEvent != null && missingCopies.Count > 0)
691692
{
692693
MissingCopiesEvent(missingCopies.First().Key, new MissingCopiesEvent() { Copies = missingCopies.SelectMany(c => c.Value).Distinct().ToList() });
693694
return;//Do not report diagnostics if copies are missing
@@ -696,7 +697,8 @@ private void RefreshCustomSymbols()
696697
if (diagDetected)
697698
{
698699
var message = "An error occured while trying to load Intrinsics or Dependencies files.";
699-
LoadingIssueEvent(null, new LoadingIssueEvent() {Message = message}); //Send notification to client
700+
if (LoadingIssueEvent!= null)
701+
LoadingIssueEvent(null, new LoadingIssueEvent() {Message = message}); //Send notification to client
700702

701703
var sb = new StringBuilder();
702704
sb.AppendLine(message);
@@ -709,16 +711,19 @@ private void RefreshCustomSymbols()
709711
sb.AppendLine(" - " + diagText); //Add associated diagnostics
710712
}
711713
}
712-
WarningTrigger(null, sb.ToString()); //Send warning notification to display info to the user.
714+
if (WarningTrigger != null)
715+
WarningTrigger(null, sb.ToString()); //Send warning notification to display info to the user.
713716
}
714717
else
715718
{//Send an LoadingIssueEvent with an empty message to tell the client that there are no issues.
716-
LoadingIssueEvent(null, new LoadingIssueEvent() { Message = "" });
719+
if (LoadingIssueEvent != null)
720+
LoadingIssueEvent(null, new LoadingIssueEvent() { Message = "" });
717721
}
718722
}
719723
catch (TypeCobolException typeCobolException)
720724
{
721-
LoadingIssueEvent(null, new LoadingIssueEvent() { Message = "An error occured while trying to load Intrinsics or Dependencies files." }); //Send notification to client
725+
if (LoadingIssueEvent != null)
726+
LoadingIssueEvent(null, new LoadingIssueEvent() { Message = "An error occured while trying to load Intrinsics or Dependencies files." }); //Send notification to client
722727

723728
AnalyticsWrapper.Telemetry.TrackException(typeCobolException, typeCobolException.Path);
724729

@@ -727,7 +732,8 @@ private void RefreshCustomSymbols()
727732
}
728733
catch (Exception e)
729734
{
730-
LoadingIssueEvent(null, new LoadingIssueEvent() { Message = "An error occured while trying to load Intrinsics or Dependencies files." }); //Send notification to client
735+
if (LoadingIssueEvent != null)
736+
LoadingIssueEvent(null, new LoadingIssueEvent() { Message = "An error occured while trying to load Intrinsics or Dependencies files." }); //Send notification to client
731737

732738
AnalyticsWrapper.Telemetry.TrackException(e, null);
733739
AnalyticsWrapper.Telemetry.SendMail(e, Configuration.InputFiles, Configuration.CopyFolders, Configuration.CommandLine);
@@ -768,10 +774,11 @@ private void FinalCompilationStepCompleted(object cUnit, ProgramClassEvent progr
768774
diags = diags.Any() ? diags.Concat(group) : group;
769775
}
770776
}
771-
772-
DiagnosticsEvent(fileUri, new DiagnosticEvent() { Diagnostics = diags.Take(Configuration.MaximumDiagnostics == 0 ? 200 : Configuration.MaximumDiagnostics) });
773777

774-
if (compilationUnit?.MissingCopies.Count > 0)
778+
if (DiagnosticsEvent != null)
779+
DiagnosticsEvent(fileUri, new DiagnosticEvent() { Diagnostics = diags.Take(Configuration.MaximumDiagnostics == 0 ? 200 : Configuration.MaximumDiagnostics) });
780+
781+
if (MissingCopiesEvent != null && compilationUnit?.MissingCopies.Count > 0)
775782
MissingCopiesEvent(fileUri, new MissingCopiesEvent() { Copies = new List<string>(compilationUnit.MissingCopies) });
776783

777784
DocumentModifiedEvent?.Invoke(fileUri, new EventArgs());

TypeCobol.Test/Parser/Preprocessor/PreprocessorUtils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ internal static class PreprocessorUtils
1818
private static ProcessedTokensDocument GetProcessedTokensDocument(CompilationProject currentProject, string testName)
1919
{
2020
FileCompiler fileCompiler = new FileCompiler(currentProject, testName, false);
21-
fileCompiler.CompileOnce(ExecutionStep.Preprocessor, false, false);
21+
fileCompiler.CompileOnce(ExecutionStep.Preprocessor, false);
2222
return fileCompiler.CompilationResultsForProgram.ProcessedTokensDocumentSnapshot;
2323
}
2424

TypeCobol.Test/Utils/ParserUtils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static CompilationDocument ScanCobolFile(string relativePath, string text
3232
documentFormat, new TypeCobolOptions(), null);
3333

3434
FileCompiler compiler = new FileCompiler(null, textName, documentFormat.ColumnsLayout, isCopy, project.SourceFileProvider, project, new TypeCobolOptions(), null, project);
35-
compiler.CompileOnce(ExecutionStep.Preprocessor, false, false);
35+
compiler.CompileOnce(ExecutionStep.Preprocessor, false);
3636

3737
return compiler.CompilationResultsForProgram;
3838
}

TypeCobol/Compiler/CompilationDocument.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,9 @@ public void RefreshProcessedTokensDocumentSnapshot()
647647
else
648648
{
649649
ImmutableList<CodeElementsLine>.Builder processedTokensDocumentLines = ((ImmutableList<CodeElementsLine>) tokensDocument.Lines).ToBuilder();
650-
IList<DocumentChange<IProcessedTokensLine>> documentChanges = PreprocessorStep.ProcessTokensLinesChanges(this, processedTokensDocumentLines, tokensLineChanges, PrepareDocumentLineForUpdate, _documentImporter, perfStatsForParserInvocation, out missingCopies);
650+
IList<DocumentChange<IProcessedTokensLine>> documentChanges = PreprocessorStep.ProcessChanges(this,
651+
processedTokensDocumentLines, tokensLineChanges, PrepareDocumentLineForUpdate,
652+
_documentImporter, perfStatsForParserInvocation, out missingCopies);
651653

652654
// Create a new version of the document to track these changes
653655
DocumentVersion<IProcessedTokensLine> currentProcessedTokensLineVersion = previousProcessedTokensDocument.CurrentVersion;

TypeCobol/Compiler/CupPreprocessor/CompilerDirectiveBuilder.cs

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -84,53 +84,49 @@ public virtual void EnterCopyCompilerStatementBody(QualifiedTextName qualifiedTe
8484
var copy = (CopyDirective)CompilerDirective;
8585
copy.TextName = GetName(qualifiedTextName.TextName);
8686
copy.TextNameSymbol = qualifiedTextName.TextName;
87-
{
8887
#if EUROINFO_RULES
88+
if (copy.TextName != null)
89+
{
8990
if (TypeCobolOptions.UseEuroInformationLegacyReplacingSyntax)
9091
{
91-
if (copy.TextName != null)
92+
// Find the list of copy text names variations declared by previous REMARKS compiler directives
93+
var variations = CopyTextNameVariations;
94+
if (TypeCobolOptions.AutoRemarksEnable &&
95+
(variations == null ||
96+
!variations.Any(
97+
v =>
98+
string.Equals(v.TextNameWithSuffix, copy.TextName,
99+
StringComparison.InvariantCultureIgnoreCase))))
100+
//If it does not exists, create the text variation (AutoRemarks mechanism Issue #440)
92101
{
93-
94-
// Find the list of copy text names variations declared by previous REMARKS compiler directives
95-
var variations = CopyTextNameVariations;
96-
if (TypeCobolOptions.AutoRemarksEnable &&
97-
(variations == null ||
98-
!variations.Any(
99-
v =>
100-
string.Equals(v.TextNameWithSuffix, copy.TextName,
101-
StringComparison.InvariantCultureIgnoreCase))))
102-
//If it does not exists, create the text variation (AutoRemarks mechanism Issue #440)
103-
{
104-
variations = new List<RemarksDirective.TextNameVariation>
102+
variations = new List<RemarksDirective.TextNameVariation>
105103
{
106104
new RemarksDirective.TextNameVariation(copy.TextName)
107105
};
106+
CopyTextNameVariations.AddRange(variations);
107+
}
108108

109-
CopyTextNameVariations.AddRange(variations);
110-
}
111-
112-
if (variations != null)
109+
if (variations != null)
110+
{
111+
var declaration = variations.Find(d => String.Equals(d.TextNameWithSuffix, copy.TextName,
112+
StringComparison.InvariantCultureIgnoreCase));
113+
if (declaration != null && this.TypeCobolOptions.HasCpyCopy(declaration.TextName))
113114
{
114-
var declaration = variations.Find(d => String.Equals(d.TextNameWithSuffix, copy.TextName,
115-
StringComparison.InvariantCultureIgnoreCase));
116-
if (declaration != null && this.TypeCobolOptions.HasCpyCopy(declaration.TextName))
115+
// Declaration found and copy name starts with Y => apply the legacy REPLACING semantics to the copy directive
116+
copy.RemoveFirst01Level = true;
117+
if (declaration.HasSuffix)
117118
{
118-
// Declaration found and copy name starts with Y => apply the legacy REPLACING semantics to the copy directive
119-
copy.RemoveFirst01Level = true;
120-
if (declaration.HasSuffix)
121-
{
122-
copy.TextName = declaration.TextName;
123-
copy.InsertSuffixChar = true;
124-
copy.Suffix = declaration.Suffix;
125-
copy.PreSuffix = declaration.PreSuffix;
126-
}
119+
copy.TextName = declaration.TextName;
120+
copy.InsertSuffixChar = true;
121+
copy.Suffix = declaration.Suffix;
122+
copy.PreSuffix = declaration.PreSuffix;
127123
}
128124
}
129125
}
130126
}
131127
_document.CollectUsedCopy(copy);
132-
#endif
133128
}
129+
#endif
134130
copy.LibraryName = GetName(qualifiedTextName.LibraryName);
135131
copy.LibraryNameSymbol = qualifiedTextName.LibraryName;
136132

TypeCobol/Compiler/Diagnostics/CrossChecker.cs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -628,28 +628,31 @@ public override bool Visit(DataDefinition dataDefinition)
628628

629629
}
630630

631-
//Check if Strict Typedef declaration uses Sync clause
632-
if (dataDefinition.SemanticData.HasFlag(Symbol.Flags.InsideTypedef) &&
633-
dataDefinition.SemanticData.HasFlag(Symbol.Flags.Sync))
631+
if (dataDefinition.SemanticData != null)
634632
{
635-
//Typedef instruction => check if it's marked Strict
636-
if (dataDefinition.SemanticData.Kind == Symbol.Kinds.Typedef && dataDefinition.SemanticData.HasFlag(Symbol.Flags.Strict))
633+
//Check if Strict Typedef declaration uses Sync clause
634+
if (dataDefinition.SemanticData.HasFlag(Symbol.Flags.InsideTypedef) &&
635+
dataDefinition.SemanticData.HasFlag(Symbol.Flags.Sync))
637636
{
638-
DiagnosticUtils.AddError(dataDefinition, $"Cannot declare Type definition {dataDefinition.Name} with Sync clause because it is Strict.");
637+
//Typedef instruction => check if it's marked Strict
638+
if (dataDefinition.SemanticData.Kind == Symbol.Kinds.Typedef && dataDefinition.SemanticData.HasFlag(Symbol.Flags.Strict))
639+
{
640+
DiagnosticUtils.AddError(dataDefinition, $"Cannot declare Type definition {dataDefinition.Name} with Sync clause because it is Strict.");
641+
}
642+
//Variable inside Typedef => check if parent typedef is marked Strict
643+
else if (dataDefinition.SemanticData.NearestParent(Symbol.Kinds.Typedef).HasFlag(Symbol.Flags.Strict))
644+
{
645+
DiagnosticUtils.AddError(dataDefinition, $"{dataDefinition.Name} is part of a declaration using Sync clause in Strict Type definition {dataDefinition.ParentTypeDefinition?.Name}.");
646+
}
647+
639648
}
640-
//Variable inside Typedef => check if parent typedef is marked Strict
641-
else if (dataDefinition.SemanticData.NearestParent(Symbol.Kinds.Typedef).HasFlag(Symbol.Flags.Strict))
649+
//Check if variable of user defined Strict Type is declared or has a parent declared with Sync clause (flag is inherited so no need to iterate through parents)
650+
else if (dataDefinition.SemanticData.HasFlag(Symbol.Flags.HasATypedefType) &&
651+
dataDefinition.TypeDefinition?.RestrictionLevel == RestrictionLevel.STRICT &&
652+
dataDefinition.SemanticData.HasFlag(Symbol.Flags.Sync))
642653
{
643-
DiagnosticUtils.AddError(dataDefinition, $"{dataDefinition.Name} is part of a declaration using Sync clause in Strict Type definition {dataDefinition.ParentTypeDefinition?.Name}.");
654+
DiagnosticUtils.AddError(dataDefinition, $"{dataDefinition.Name} cannot be declared or have a parent declared with Sync clause because its Type definition {dataDefinition.DataType.Name} is Strict.");
644655
}
645-
646-
}
647-
//Check if variable of user defined Strict Type is declared or has a parent declared with Sync clause (flag is inherited so no need to iterate through parents)
648-
else if (dataDefinition.SemanticData.HasFlag(Symbol.Flags.HasATypedefType) &&
649-
dataDefinition.TypeDefinition?.RestrictionLevel == RestrictionLevel.STRICT &&
650-
dataDefinition.SemanticData.HasFlag(Symbol.Flags.Sync))
651-
{
652-
DiagnosticUtils.AddError(dataDefinition, $"{dataDefinition.Name} cannot be declared or have a parent declared with Sync clause because its Type definition {dataDefinition.DataType.Name} is Strict.");
653656
}
654657

655658
if (HasChildrenThatDeclareData(dataDefinition))

TypeCobol/Compiler/FileCompiler.cs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -213,16 +213,15 @@ private FileCompiler(Tuple<string, string, ColumnsLayout, bool> fileInfo, ITextD
213213
/// </summary>
214214
public void CompileOnce()
215215
{
216-
CompileOnce(CompilerOptions.ExecToStep, CompilerOptions.HaltOnMissingCopy, CompilerOptions.UseAntlrProgramParsing);
216+
CompileOnce(CompilerOptions.ExecToStep, CompilerOptions.HaltOnMissingCopy);
217217
}
218218

219219
/// <summary>
220220
/// Perform a compilation based on an execution step.
221221
/// </summary>
222222
/// <param name="exec2Step">The execution step</param>
223223
/// <param name="haltOnMissingCopy">For preprocessing step, halt on missing copy options</param>
224-
/// <param name="useAntlrProgramParsing">Shall Antlr be used to parse the program</param>
225-
public void CompileOnce(ExecutionStep? exec2Step, bool haltOnMissingCopy, bool useAntlrProgramParsing)
224+
public void CompileOnce(ExecutionStep? exec2Step, bool haltOnMissingCopy)
226225
{
227226
if (exec2Step == null)
228227
exec2Step = ExecutionStep.CrossCheck;

TypeCobol/Compiler/Parser/CodeElementBuilder/CobolWordsBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1221,7 +1221,7 @@ public enum RecordingModeEnum
12211221
[CanBeNull]
12221222
internal EnumeratedValue CreateRecordingMode(CodeElementsParser.RecordingModeContext context)
12231223
{
1224-
return CreateEnumeratedValue(context.enumeratedValue1(), typeof(RecordingModeEnum));
1224+
return context != null ? CreateEnumeratedValue(context.enumeratedValue1(), typeof(RecordingModeEnum)) : null;
12251225
}
12261226

12271227
#endregion

0 commit comments

Comments
 (0)