Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API/other improvements for improved in-memory analysis. #2639

Merged
merged 11 commits into from
Mar 14, 2023

Conversation

michaelcfanning
Copy link
Member

No description provided.

@@ -15,8 +15,18 @@

namespace Microsoft.CodeAnalysis.Sarif
{
public static class ExtensionMethods
public static class SarifExtensions
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SarifExtensions

For publicly exposed extension methods classes, it's good to qualify the type name, to avoid collisions with this general name 'ExtensionMethods'.

@@ -101,11 +100,6 @@ public class SarifLogger : BaseLogger, IDisposable, IAnalysisLogger
RuleToIndexMap = new Dictionary<ReportingDescriptor, int>(ReportingDescriptor.ValueComparer);
ExtensionGuidToIndexMap = new Dictionary<Guid, int>();

if (dataToInsert.HasFlag(OptionallyEmittedData.Hashes))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dataToInsert

I'm deleting this aggressive hashing of targets data on initialization for now. First, we previously had at least three mechanisms for hashing, this one, the hash delegate and on-demand hashing via the insert data visitor. This particular mechanism always held all this data in memory, as opposed to the file regions cache mechanism, which only holds that previous 100 files hashed...

@@ -144,7 +139,8 @@ public class SarifLogger : BaseLogger, IDisposable, IAnalysisLogger
}

}
else if (_run.Tool.Driver?.Rules != null)

if (_run.Tool.Driver?.Rules != null)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if

Previously, this code insisted that all rule exist on the tool driver OR on the extensions property. In theory, there could be both. Unit test hole here.

sb.AppendLine($"\t{trace} : did not observe term 'elapsed' in rule timing notifications.");
}
// We expected timing data for every rule.
if (executionNotifications.Count != expectedNotificationsCount)

Check warning

Code scanning / CodeQL

Dereferenced variable may be null

Variable [executionNotifications](1) may be null at this access as suggested by [this](2) null check. Variable [executionNotifications](1) may be null at this access as suggested by [this](3) null check. Variable [executionNotifications](1) may be null at this access as suggested by [this](4) null check. Variable [executionNotifications](1) may be null at this access as suggested by [this](5) null check. Variable [executionNotifications](1) may be null at this access as suggested by [this](6) null check. Variable [executionNotifications](1) may be null at this access as suggested by [this](7) null check.

public virtual FileFormat ConfigurationFormat => FileFormat.Json;

protected MultithreadedAnalyzeCommandBase(IFileSystem fileSystem = null)
{
// TBD can we zap this?
Tool ??= Tool.CreateFromAssemblyData();

Check warning

Code scanning / CodeQL

Virtual call in constructor or destructor

Avoid virtual calls in a constructor or destructor.
}
}
catch (IOException) { }
catch (SecurityException) { }

Check notice

Code scanning / CodeQL

Poor error handling: empty catch block

Poor error handling: empty catch block.
}
}
catch (IOException) { }
catch (SecurityException) { }
catch (UnauthorizedAccessException) { }

Check notice

Code scanning / CodeQL

Poor error handling: empty catch block

Poor error handling: empty catch block.
@@ -197,12 +192,13 @@

foreach (string target in analysisTargets)
{
Uri uri = new Uri(UriHelper.MakeValidUri(target), UriKind.RelativeOrAbsolute);
string uriText = UriHelper.MakeValidUri(target);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MakeValidUri

We call this helper inconsistently and really should call it everywhere.

@@ -262,10 +258,6 @@
_run.Invocations.Add(invocation);
}

public Func<Uri, HashData> ComputeHashData { get; set; }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ComputeHashData

These mechanisms deleted in preference of a share file regions cache.

HelpText = "A semicolon delimited list to filter output of scan results to one or more failure levels. Valid values: Error, Warning and Note.")]
public IEnumerable<FailureLevel> Level { get; set; }

private FailureLevelSet failureLevels;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FailureLevelSet

Providing defaults in the options classes is problematic because it interferes with the context object default value functionality (which is much richer/close to the analysis model.). In the options classes, we should actually return null for all cases where the property isn't explicit on the command-line, otherwise reflect the command-line precisely. That's the model. There's more clean-up to do.

{
normalizedSpecifier = uri.LocalPath;
}
normalizedSpecifier = uri.GetFileName();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GetFileName

Here's another clean-up item, we need to call the GetFilePath and GetFileName helpers consistently across the code base (to properly process things like relative URLs).

@@ -38,13 +38,13 @@

public static bool RaiseUnhandledExceptionInDriverCode { get; set; }

protected virtual Tool Tool { get; set; }
public virtual Tool Tool { get; set; }
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

public

This property needs to be public in order to interact with it properly in scenarios where users proactively create a SARIF logger (and where skimmers may be loaded as extensions).

@@ -236,24 +236,27 @@
context.OutputFilePath = options.OutputFilePath;
context.AutomationGuid = options.AutomationGuid;
context.BaselineFilePath = options.BaselineFilePath;
context.Traces = InitializeStringSet(options.Trace);
context.Traces = options.Trace != null ? InitializeStringSet(options.Trace) : context.Traces;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trace

This pattern needs to be pushed through-out this code.

If options return null consistently, then we can override an existing config object with updated values but ONLY if the user has expressed an override on the command-line.

@@ -511,7 +511,7 @@ public void SarifLogger_ScrapesFilesFromResult()
{
using (var sarifLogger = new SarifLogger(textWriter,
analysisTargets: null,
dataToInsert: OptionallyEmittedData.Hashes,
dataToInsert: OptionallyEmittedData.None,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None

Interesting bug! Because we didn't have sufficient handling for the dataToInsert property, we missed a case where this data was requested but not available. The fix now prompts request for missing data. Since that's not the purpose of this test, I just dropped the request for hashes data.


using Xunit;

namespace Microsoft.CodeAnalysis.Sarif.Driver
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Microsoft

Turns out that test code doesn't use this delegate action injection mechanism highly, so I just ripped it out.

Moving forward we should be updating tests to use the new improved analysis model (which is designed to allow solid testing using the core analyze command mechanism, just as the actual client tool does). So this sort of testing model should wither away, rather than being built on.

@michaelcfanning michaelcfanning marked this pull request as ready for review March 13, 2023 23:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant