Skip to content
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
ReturnCode=Warning_
6 errors in "input\DocGen.tcbl":
Line 9[13,18] <37, Warning, General> - Warning: Type Definition does not support Parameters field
Line 9[13,18] <37, Warning, General> - Warning: Formalized comment field is declared more than once : params
Line 13[12,17] <37, Warning, General> - Warning: Formalized comment field is declared more than once : Params
Line 9[13,18] <37, Warning, General> - Warning: Type Definition does not support Parameters field
Line 60[12,14] <37, Warning, General> - Warning: Parameter name does not match to any function parameter: blu
Line 65[21,26] <37, Warning, General> - Warning: Parameter does not have any description inside the formalized comments: myBool
Line 67[21,23] <37, Warning, General> - Warning: Parameter does not have any description inside the formalized comments: bli
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
ReturnCode=Warning_
4 errors in "input\Callee.rdz.tcbl":
7 errors in "input\Callee.rdz.tcbl":
Line 48[15,21] <37, Warning, General> - Warning: Parameter name does not match to any program parameter: MyType2
Line 49[15,21] <37, Warning, General> - Warning: Parameter name does not match to any program parameter: MyType3
Line 50[15,20] <37, Warning, General> - Warning: Parameter name does not match to any program parameter: Mydate
Line 78[17,22] <37, Warning, General> - Warning: Parameter does not have any description inside the formalized comments: mydate
Line 79[17,23] <37, Warning, General> - Warning: Parameter does not have any description inside the formalized comments: myDate2
Line 90[17,22] <37, Warning, General> - Warning: Parameter does not have any description inside the formalized comments: mydate
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
{
"category": 1,
"message": "{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"uri\":\"file:///C:/Users/MAYANJE/AppData/Local/Temp/1/tcbl/DVZZJCM54976774298083657321.cee\",\"diagnostics\":[]}}"
"message": "{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"uri\":\"file:///C:/Users/MAYANJE/AppData/Local/Temp/1/tcbl/DVZZJCM54976774298083657321.cee\",\"diagnostics\":[{\"range\":{\"start\":{\"line\":10,\"character\":18},\"end\":{\"line\":10,\"character\":22}},\"severity\":2,\"code\":\"37\",\"source\":\"\",\"message\":\"Warning: Parameter name does not match to any program parameter: bDate\"},{\"range\":{\"start\":{\"line\":11,\"character\":18},\"end\":{\"line\":11,\"character\":22}},\"severity\":2,\"code\":\"37\",\"source\":\"\",\"message\":\"Warning: Parameter name does not match to any program parameter: bTime\"}]}}"
},
{
"category": 0,
Expand All @@ -35,7 +35,7 @@
},
{
"category": 1,
"message": "{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"uri\":\"file:///C:/Users/MAYANJE/AppData/Local/Temp/1/tcbl/DVZZJCM54976774298083657321.cee\",\"diagnostics\":[]}}"
"message": "{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"uri\":\"file:///C:/Users/MAYANJE/AppData/Local/Temp/1/tcbl/DVZZJCM54976774298083657321.cee\",\"diagnostics\":[{\"range\":{\"start\":{\"line\":10,\"character\":18},\"end\":{\"line\":10,\"character\":22}},\"severity\":2,\"code\":\"37\",\"source\":\"\",\"message\":\"Warning: Parameter name does not match to any program parameter: bDate\"},{\"range\":{\"start\":{\"line\":11,\"character\":18},\"end\":{\"line\":11,\"character\":22}},\"severity\":2,\"code\":\"37\",\"source\":\"\",\"message\":\"Warning: Parameter name does not match to any program parameter: bTime\"}]}}"
},
{
"category": 0,
Expand All @@ -59,7 +59,7 @@
},
{
"category": 1,
"message": "{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"uri\":\"file:///C:/Users/MAYANJE/AppData/Local/Temp/1/tcbl/DVZZJCM54976774298083657321.cee\",\"diagnostics\":[]}}"
"message": "{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/publishDiagnostics\",\"params\":{\"uri\":\"file:///C:/Users/MAYANJE/AppData/Local/Temp/1/tcbl/DVZZJCM54976774298083657321.cee\",\"diagnostics\":[{\"range\":{\"start\":{\"line\":10,\"character\":18},\"end\":{\"line\":10,\"character\":22}},\"severity\":2,\"code\":\"37\",\"source\":\"\",\"message\":\"Warning: Parameter name does not match to any program parameter: bDate\"},{\"range\":{\"start\":{\"line\":11,\"character\":18},\"end\":{\"line\":11,\"character\":22}},\"severity\":2,\"code\":\"37\",\"source\":\"\",\"message\":\"Warning: Parameter name does not match to any program parameter: bTime\"}]}}"
}
],
"didClose": "{\"jsonrpc\":\"2.0\",\"method\":\"textDocument/didClose\",\"params\":{\"textDocument\":{\"uri\":\"file:/C:/Users/MAYANJE/AppData/Local/Temp/1/tcbl/DVZZJCM54976774298083657321.cee\"}}}",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
--- Diagnostics ---
Line 22[33,41] <37, Warning, General> - Warning: Debugging mode is active OffendingSymbol=[33,41:DEBUGGING]<DEBUGGING>
Line 23[38,46] <37, Warning, General> - Warning: Debugging mode is active OffendingSymbol=[38,46:DEBUGGING]<DEBUGGING>
Line 55[22,23] <27, Error, Syntax> - Syntax error : Empty string cannot be used as currency symbol.
Line 56[43,44] <27, Error, Syntax> - Syntax error : Empty string cannot be used as currency symbol.
Line 57[17,27] <27, Error, Syntax> - Syntax error : Currency symbol must be one single character.
Expand Down
34 changes: 34 additions & 0 deletions TypeCobol/Compiler/CompilationUnit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ public void RefreshCodeElementsDocumentSnapshot()
codeElementsLinesChanged(this, documentChangedEvent);
}
}

#if DEBUG
//Update CE diag count for future checks
_codeElementDiagnosticCount = OnlyCodeElementDiagnostics().Count;
#endif
}

/// <summary>
Expand All @@ -147,6 +152,23 @@ public void RefreshCodeElementsDocumentSnapshot()
/// </summary>
public PerfStatsForParsingStep PerfStatsForCodeElementsParser { get; private set; }

#if DEBUG
private int _codeElementDiagnosticCount;

/// <summary>
/// Debug-only check to avoid creation of diagnostics on CodeElements after they have been created/refreshed.
/// Must be called at the end of each compilation step defined after <see cref="RefreshCodeElementsDocumentSnapshot"/>.
/// </summary>
private void CheckCodeElementDiagnostics()
{
var actualCodeElementDiagnosticCount = OnlyCodeElementDiagnostics().Count;
if (actualCodeElementDiagnosticCount != _codeElementDiagnosticCount)
{
System.Diagnostics.Debug.Fail("CodeElement diagnostics should not be created after CE phase !");
}
}
#endif

public string AntlrResult {
get
{
Expand Down Expand Up @@ -213,6 +235,10 @@ public void RefreshProgramClassDocumentSnapshot()
{
programClassNotChanged(this, new ProgramClassEvent() { Version = ProgramClassDocumentSnapshot.CurrentVersion });
}

#if DEBUG
CheckCodeElementDiagnostics();
#endif
}

/// <summary>
Expand Down Expand Up @@ -287,6 +313,10 @@ public void ProduceTemporarySemanticDocument()
PerfStatsForTemporarySemantic.OnStopRefreshParsingStep();
}
}

#if DEBUG
CheckCodeElementDiagnostics();
#endif
}

/// <summary>
Expand Down Expand Up @@ -369,6 +399,10 @@ bool CodeAnalysisDocumentNeedsUpdate(out int newVersion)
{
codeAnalysisCompleted(this, new ProgramClassEvent() { Version = CodeAnalysisDocumentSnapshot.CurrentVersion });
}

#if DEBUG
CheckCodeElementDiagnostics();
#endif
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -809,9 +809,6 @@ public virtual void EndFunctionDeclaration(FunctionDeclarationEnd end)

public virtual void StartFunctionProcedureDivision(ProcedureDivisionHeader header)
{
if (header.UsingParameters != null && header.UsingParameters.Count > 0)
DiagnosticUtils.AddError(header, "TCRFUN_DECLARATION_NO_USING");//TODO#249

Enter(new ProcedureDivision(header), header);
Dispatcher.StartFunctionProcedureDivision(header);
}
Expand Down
13 changes: 0 additions & 13 deletions TypeCobol/Compiler/Diagnostics/Cobol2002Checker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,6 @@ public static void CheckTypeDefinition(TypeDefinition typeDefinition)
}
}

// Add a warning if a parameters field is set inside the formalized comment
if (typeDefinition.CodeElement.FormalizedCommentDocumentation != null && typeDefinition.CodeElement.FormalizedCommentDocumentation.Parameters.Any())
{
var token = typeDefinition.CodeElement.ConsumedTokens
.FirstOrDefault(t => t.TokenType == TokenType.FORMALIZED_COMMENTS_PARAMETERS);
if (token != null)
{
DiagnosticUtils.AddError(typeDefinition.CodeElement,
"Type Definition does not support Parameters field",
token, code: MessageCode.Warning);
}
}

//Check circular reference if not already done by TypeCobolLinker
TypeCobolLinker.CheckCircularReferences(typeDefinition);
}
Expand Down
107 changes: 12 additions & 95 deletions TypeCobol/Compiler/Diagnostics/CrossChecker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public override bool BeginCodeElement(CodeElement codeElement)
public override bool Visit(FunctionDeclaration functionDeclaration)
{
FunctionDeclarationChecker.OnNode(functionDeclaration);
CheckMultipleFormComParam(functionDeclaration.CodeElement);
FormalizedCommentsChecker.CheckFunctionComments(functionDeclaration);
return true;
}

Expand Down Expand Up @@ -138,13 +138,6 @@ public override bool Visit(ProcedureDivision procedureDivision)
LibraryChecker.CheckLibrary(procedureDivision);
//initializing the current section to null
_currentSection = null;
ProcedureDivisionHeader ce = procedureDivision.CodeElement as ProcedureDivisionHeader;
if (ce?.FormalizedCommentDocumentation != null && procedureDivision.Parent is FunctionDeclaration)
{
DiagnosticUtils.AddError(ce,
"Formalized Comments can be placed above Procedure Division only for Programs",
MessageCode.ErrorFormalizedCommentMissplaced);
}
return true;
}

Expand Down Expand Up @@ -501,66 +494,16 @@ public override bool Visit(TypeDefinition typeDefinition)
//TODO need to clarify if we have 1 visitor per LanguageLevel
//For performance reason it seems better to have only one here
TypeDefinitionChecker.CheckTypeDefinition(typeDefinition);
CheckMultipleFormComParam(typeDefinition.CodeElement);
FormalizedCommentsChecker.CheckTypeComments(typeDefinition);
return true;
}

public override bool Visit(Program program)
{
// Check that program has a closing end
CheckEndProgram(program);

//// Set a Warning if the FormCom parameter in unknown or if the program parameter have no description

ProcedureDivisionHeader procedureDivision =
program.Children.FirstOrDefault(c => c is ProcedureDivision)?.CodeElement as ProcedureDivisionHeader;
var formCom = procedureDivision?.FormalizedCommentDocumentation;

if (formCom != null && procedureDivision.UsingParameters != null)
{
CheckMultipleFormComParam(procedureDivision);
// Get the parameters inside the Formalized Comment that are not inside the program parameters
var formComParamOrphan = formCom.Parameters.Keys.Except(
procedureDivision.UsingParameters.Select(p =>
p.StorageArea.SymbolReference?.Name)) ?? Enumerable.Empty<string>();

// For each of them, place a warning on the orphan parameter definition (UserDefinedWord Token inside the FormCom)
foreach (var orphan in formComParamOrphan)
{
var tokens =
procedureDivision.ConsumedTokens.Where(t =>
t.TokenType == TokenType.UserDefinedWord && t.Text == orphan);
foreach (var token in tokens)
{
DiagnosticUtils.AddError(procedureDivision,
"Parameter name does not match to any program parameter: " + orphan,
token, code: MessageCode.Warning);
}
}


// Get the parameters inside the program parameters that are not inside the Formalized Comment
var sameParameters = procedureDivision.UsingParameters.Where(p =>
formCom.Parameters.Keys.Contains(p.StorageArea.SymbolReference?.Name));

var programParamWithoutDesc = procedureDivision.UsingParameters.Except(sameParameters);

// For each of them, place a warning on the parameter definition
foreach (var param in programParamWithoutDesc)
{
var tokens = procedureDivision.ConsumedTokens.Where(t =>
t.TokenType == TokenType.UserDefinedWord &&
t.Text == param.StorageArea.SymbolReference?.Name);
foreach (var token in tokens)
{
DiagnosticUtils.AddError(procedureDivision,
"Parameter does not have any description inside the formalized comments: " +
param.StorageArea.SymbolReference?.Name,
token, code: MessageCode.Warning);
}
}
}


FormalizedCommentsChecker.CheckProgramComments(program);
return true;
}

Expand Down Expand Up @@ -702,7 +645,7 @@ public override bool Visit(End end)
CodeElement parentCodeElement = end.Parent.CodeElement; ;
if (parentCodeElement?.IsInsideCopy() == false && end.IsInsideCopy() == false)
{
CheckEndNode(parentCodeElement, end.CodeElement);
CheckEndNode(parentCodeElement, end);
}
}
return true;
Expand All @@ -717,7 +660,7 @@ public override bool Visit(FunctionEnd functionEnd)
if (parentCodeElement?.IsInsideCopy() == false && functionEnd.IsInsideCopy() == false)
{
Token openingDeclareToken = parentCodeElement.ConsumedTokens.FirstOrDefault(t => t.TokenType == TokenType.DECLARE);
CheckEndNode(openingDeclareToken, functionEnd.CodeElement);
CheckEndNode(openingDeclareToken, functionEnd);
}
}
return true;
Expand Down Expand Up @@ -752,16 +695,6 @@ public override bool Visit(DataDescription dataDescription)
return true;
}

public override bool Visit(SourceComputer sourceComputer)
{
if (sourceComputer.CodeElement.DebuggingMode?.Value == true)
{
Token token = sourceComputer.CodeElement.DebuggingMode.Token;
DiagnosticUtils.AddError(sourceComputer.CodeElement, "Debugging mode is active", token, null, MessageCode.Warning);
}
return true;
}

/// <summary>
/// Test if the received DataDefinition has other children than DataConditionEntry or DataRenamesEntry
/// </summary>
Expand Down Expand Up @@ -1101,26 +1034,6 @@ private static void IndexAndFlagDataDefiniton(DataDefinitionPath dataDefinitionP
}
}

/// <summary>
/// Add a warning if a Field is set more than one time
/// </summary>
private static void CheckMultipleFormComParam(CodeElement codeElement)
{
var tokenGroups = codeElement.ConsumedTokens.GroupBy(t => t.TokenType);
foreach (var tokenGroup in tokenGroups)
{
if ((int) tokenGroup.Key >= 513 && (int) tokenGroup.Key <= 520 && tokenGroup.Count() > 1)
{
foreach (var token in tokenGroup)
{
DiagnosticUtils.AddError(codeElement,
"Formalized comment field is declared more than once : " + token.Text,
token, code: MessageCode.Warning);
}
}
}
}

private static void FlagNodeAndCreateQualifiedStorageAreas(Node.Flag flag, Node node, StorageArea storageArea,
DataDefinitionPath dataDefinitionPath)
{
Expand All @@ -1132,13 +1045,17 @@ private static void FlagNodeAndCreateQualifiedStorageAreas(Node.Flag flag, Node
node.QualifiedStorageAreas.Add(storageArea, dataDefinitionPath);
}

private void CheckEndNode([CanBeNull]IToken openingToken, CodeElement endCodeElement)
private void CheckEndNode([CanBeNull]IToken openingToken, Node endNode)
{
System.Diagnostics.Debug.Assert(endNode is End || endNode is FunctionEnd);
System.Diagnostics.Debug.Assert(endNode.CodeElement != null);

// Check end statement is aligned with the matching opening statement
var endCodeElement = endNode.CodeElement;
if (openingToken != null && openingToken.Line != endCodeElement.Line &&
openingToken.StartIndex != endCodeElement.StartIndex)
{
DiagnosticUtils.AddError(endCodeElement,
DiagnosticUtils.AddError(endNode,
"a End statement is not aligned with the matching opening statement",
_compilerOptions.CheckEndAlignment.GetMessageCode());
}
Expand Down
Loading