Skip to content

Commit

Permalink
Investigate InvalidCastException
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthurvdv committed Dec 11, 2024
1 parent f62a1b2 commit 591de91
Showing 1 changed file with 55 additions and 46 deletions.
101 changes: 55 additions & 46 deletions BusinessCentral.LinterCop/Design/Rule0044AnalyzeTransferField.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,72 +55,81 @@ private void AnalyzeTableExtension(SyntaxNodeAnalysisContext ctx)

private async void AnalyzeTransferFields(OperationAnalysisContext ctx)
{
if (ctx.Operation.Syntax.GetType() != typeof(InvocationExpressionSyntax))
return;
// Investigate https://github.com/StefanMaron/BusinessCentral.LinterCop/issues/828
try
{
if (ctx.Operation.Syntax.GetType() != typeof(InvocationExpressionSyntax))
return;

if (((IInvocationExpression)ctx.Operation).TargetMethod.MethodKind != MethodKind.BuiltInMethod)
return;
if (((IInvocationExpression)ctx.Operation).TargetMethod.MethodKind != MethodKind.BuiltInMethod)
return;

if (ctx.Operation.Syntax is not InvocationExpressionSyntax invocationExpression)
return;
if (ctx.Operation.Syntax is not InvocationExpressionSyntax invocationExpression)
return;

Tuple<string, string>? records = GetInvokingRecordNames(invocationExpression);
Tuple<string, string>? records = GetInvokingRecordNames(invocationExpression);

if (records == null)
return;
if (records == null)
return;

Task<SyntaxNode> localVariablesTask = ctx.ContainingSymbol.DeclaringSyntaxReference!.GetSyntaxAsync();
Task<SyntaxNode> globalVariablesTask = ctx.ContainingSymbol.ContainingSymbol!.DeclaringSyntaxReference!.GetSyntaxAsync();
Task<SyntaxNode> localVariablesTask = ctx.ContainingSymbol.DeclaringSyntaxReference!.GetSyntaxAsync();
Task<SyntaxNode> globalVariablesTask = ctx.ContainingSymbol.ContainingSymbol!.DeclaringSyntaxReference!.GetSyntaxAsync();

List<VariableDeclarationBaseSyntax> variables = new List<VariableDeclarationBaseSyntax>();
List<VariableDeclarationBaseSyntax> variables = new List<VariableDeclarationBaseSyntax>();

SyntaxNode localVariables = await localVariablesTask;
variables.AddRange(FindVariables(localVariables, SyntaxKind.VarSection));
SyntaxNode globalVariables = await globalVariablesTask;
variables.AddRange(FindVariables(globalVariables, SyntaxKind.GlobalVarSection));
SyntaxNode localVariables = await localVariablesTask;
variables.AddRange(FindVariables(localVariables, SyntaxKind.VarSection));
SyntaxNode globalVariables = await globalVariablesTask;
variables.AddRange(FindVariables(globalVariables, SyntaxKind.GlobalVarSection));

string? tableName1 = GetObjectName(variables.FirstOrDefault(x =>
{
string? name = x.GetNameStringValue();
string? tableName1 = GetObjectName(variables.FirstOrDefault(x =>
{
string? name = x.GetNameStringValue();

if (name == null)
return false;
if (name == null)
return false;

return name.Equals(records.Item1);
}));
return name.Equals(records.Item1);
}));

string? tableName2 = GetObjectName(variables.FirstOrDefault(x =>
{
string? name = x.GetNameStringValue();
string? tableName2 = GetObjectName(variables.FirstOrDefault(x =>
{
string? name = x.GetNameStringValue();

if (name == null)
return false;
if (name == null)
return false;

return name.Equals(records.Item2);
}));
return name.Equals(records.Item2);
}));

if (tableName1 == null && (records.Item1.ToLower().Equals("rec") || records.Item1.ToLower().Equals("xrec")))
tableName1 = GetObjectSourceTable(globalVariables, ctx.Compilation);
if (tableName1 == null && (records.Item1.ToLower().Equals("rec") || records.Item1.ToLower().Equals("xrec")))
tableName1 = GetObjectSourceTable(globalVariables, ctx.Compilation);

if (tableName2 == null && (records.Item2.ToLower().Equals("rec") || records.Item2.ToLower().Equals("xrec")))
tableName2 = GetObjectSourceTable(globalVariables, ctx.Compilation);
if (tableName2 == null && (records.Item2.ToLower().Equals("rec") || records.Item2.ToLower().Equals("xrec")))
tableName2 = GetObjectSourceTable(globalVariables, ctx.Compilation);

if (tableName1 == tableName2 || tableName1 == null || tableName2 == null)
return;
if (tableName1 == tableName2 || tableName1 == null || tableName2 == null)
return;

Dictionary<string, TableExtensionSyntax> tableExtensions = GetTableExtensions(ctx.Compilation);
Table table1 = GetTableWithFieldsByTableName(ctx.Compilation, tableName1);
Table table2 = GetTableWithFieldsByTableName(ctx.Compilation, tableName2);
Dictionary<string, TableExtensionSyntax> tableExtensions = GetTableExtensions(ctx.Compilation);
Table table1 = GetTableWithFieldsByTableName(ctx.Compilation, tableName1);
Table table2 = GetTableWithFieldsByTableName(ctx.Compilation, tableName2);

List<IGrouping<int, Field>> fieldGroups = GetFieldsWithSameIDAndApplyFilter(table1.Fields, table2.Fields, DifferentNameAndTypeFilter);
List<IGrouping<int, Field>> fieldGroups = GetFieldsWithSameIDAndApplyFilter(table1.Fields, table2.Fields, DifferentNameAndTypeFilter);

if (fieldGroups.Any())
{
ReportFieldDiagnostics(ctx, table1, fieldGroups);
ReportFieldDiagnostics(ctx, table2, fieldGroups);
if (fieldGroups.Any())
{
ReportFieldDiagnostics(ctx, table1, fieldGroups);
ReportFieldDiagnostics(ctx, table2, fieldGroups);

if (table1.Fields.Any(x => x.Location != null) || table2.Fields.Any(x => x.Location != null))
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0044AnalyzeTransferFields, invocationExpression.GetLocation(), table1.Name, table2.Name));
if (table1.Fields.Any(x => x.Location != null) || table2.Fields.Any(x => x.Location != null))
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0044AnalyzeTransferFields, invocationExpression.GetLocation(), table1.Name, table2.Name));

}
}
catch (InvalidCastException)
{
ctx.ReportDiagnostic(Diagnostic.Create(DiagnosticDescriptors.Rule0000ErrorInRule, ctx.Operation.Syntax.GetLocation(), new Object[] { "Rule0044", "InvalidCastException", "" }));
}
}

Expand Down

0 comments on commit 591de91

Please sign in to comment.