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

Partial results of running LOC8 to identify dead code. #17630

Closed
wants to merge 6 commits into from
Closed

Partial results of running LOC8 to identify dead code. #17630

wants to merge 6 commits into from

Conversation

zebmason
Copy link

@zebmason zebmason commented Mar 8, 2017

You'll want to review these changes to ensure the code identified as dead is actually dead. Some of it looks like it is there for debug purposes.

The tool used to find the "dead" code is currently under development with a log at https://github.com/zebmason/LOC8. More work is needed on the tool to avoid false positives. If you don't find this useful let me know and I'll train the tool on other code.

…ant to actually delete this code but wrap with #if DEBUG, etc.
@dnfclas
Copy link

dnfclas commented Mar 8, 2017

@zebmason,
Thanks for your contribution.
To ensure that the project team has proper rights to use your work, please complete the Contribution License Agreement at https://cla2.dotnetfoundation.org.

It will cover your contributions to all Microsoft-managed open source projects.
Thanks,
.NET Foundation Pull Request Bot

@@ -65,27 +65,5 @@ public override object Id
return _id;
}
}

private string GetDebuggerDisplay()
Copy link
Member

Choose a reason for hiding this comment

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

@zebmason This particular one is being used: the DebuggerDisplay attribute on the class will make this one matter.

Copy link
Member

@jasonmalinowski jasonmalinowski left a comment

Choose a reason for hiding this comment

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

I did see one false positive here.

@jasonmalinowski
Copy link
Member

Tagging @dotnet/roslyn-compiler, @dotnet/roslyn-ide and @dotnet/roslyn-analysis since some of these do look quite legitimate.

@heejaechang
Copy link
Contributor

@mavasani can you take a look?

@@ -137,13 +137,6 @@ private CompilationWithAnalyzers(Compilation compilation, ImmutableArray<Diagnos
_executingCompilationOrNonConcurrentTreeTask = null;
}

private void AddExceptionDiagnostic(Exception exception, DiagnosticAnalyzer analyzer, Diagnostic diagnostic)
Copy link
Contributor

Choose a reason for hiding this comment

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

So this seems to have uncovered a regression. This method should be hooked up in the constructor of CompilationWithAnalyzers and invoked when there is an exception from any analyzer. It seems this got regressed when we moved to AnalyzerDriver v2 in Dev14 Update3. Can you please retain this method and file a separate tracking issue to fix this and assign it to me?

@tannergooding
Copy link
Member

test windows_debug_vs-integration_prtest please

@tannergooding
Copy link
Member

test windows_release_vs-integration_prtest please

/// <summary>
/// Looks up a localized resource of type System.Byte[].
/// </summary>
internal static byte[] defaultWin32Manifest {
Copy link
Member

Choose a reason for hiding this comment

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

I don't see the corresponding change to resx file (which generates this cs file).

@@ -29,7 +29,6 @@ internal static class AnalyzerHelper

// Shared with Compiler
internal const string AnalyzerExceptionDiagnosticId = "AD0001";
internal const string AnalyzerDriverExceptionDiagnosticId = "AD0002";
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be left since it is supposed to be in sync with the one defined in compiler side.

# Conflicts:
#	src/Features/CSharp/Portable/InlineDeclaration/CSharpInlineDeclarationCodeFixProvider.cs
@@ -776,66 +776,5 @@ internal BoundStatement WrapWithVariablesAndLocalFunctionsIfAny(CSharpSyntaxNode
ImmutableArray.Create(statement))
{ WasCompilerGenerated = true };
}

internal string Dump()
Copy link
Member

Choose a reason for hiding this comment

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

This is not dead code. We use it for debugging.

Copy link
Author

Choose a reason for hiding this comment

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

I was being a bit ruthless. A lot of the code which appears designed to be run in the debugger don't have #if DEBUG guards, perhaps they should?

Copy link
Member

Choose a reason for hiding this comment

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

No. We still run things in the debugger when in release mode. Now, maybe we should introduce an attribute to call out that this is intentional and is not dead code. Then your tool could skip those guys.

Copy link
Author

Choose a reason for hiding this comment

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

Cyrus

Thanks for the feedback, the tool currently ignores build flavours and thus defines. Based on your comments I need to modify it so that it uses a tool specific build flavour in which all the relevant defines are specified.

Cheers

Zeb

@@ -379,14 +379,6 @@ internal static void FreeDeconstructionVariables(ArrayBuilder<DeconstructionVari

variables.Free();
}
private string GetDebuggerDisplay()
Copy link
Member

Choose a reason for hiding this comment

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

Not dead.

@@ -62,14 +62,6 @@ public bool IncrementallyEquivalent(Directive other)
}
}

// Can't be private as it's called by DirectiveStack in its GetDebuggerDisplay()
internal string GetDebuggerDisplay()
Copy link
Member

Choose a reason for hiding this comment

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

None of the GetDebbuggerDisplay methods are dead code.

@@ -346,12 +346,6 @@ private static void ValidateSpanFromBounds(ITextSnapshot snapshot, int start, in
Contract.Requires(start >= 0 && end <= snapshot.Length && start <= end);
}

[Conditional("DEBUG")]
private static void ValidateSpan(ITextSnapshot snapshot, int start, int length)
Copy link
Member

Choose a reason for hiding this comment

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

Are you testing with debug built?

Copy link
Author

Choose a reason for hiding this comment

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

Yes I built with debug, the analysis tool used needs a little work on it to select build flavours to ensure that when it uses Roslyn to create the semantic model that all the correct options are set.

@@ -131,28 +131,6 @@ public void Foo()
}");
}

private const string Code3 = @"
Copy link
Member

Choose a reason for hiding this comment

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

these worry me. t hey seem liek missed tests.

@CyrusNajmabadi
Copy link
Member

-18k lines is massive. We're going to need this broken up. perhaps it can be done so by grouping into folders.

Copy link
Member

@jaredpar jaredpar left a comment

Choose a reason for hiding this comment

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

All of the GetDebuggerDisplay removals are false positives. They are referenced on the type attributes and used at debug time. Can't delete those.

{
return $"{Imports.GetDebuggerDisplay()} ^ {ParentOpt?.GetHashCode() ?? 0}";
}

Copy link
Member

Choose a reason for hiding this comment

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

This is not dead code. It's referenced in the type attribute and used at debug time. Same for every other GetDebuggerDisplay that is referenced.

@@ -98,14026 +98,317 @@ internal class CSharpResources {
}

/// <summary>
/// Looks up a localized string similar to Elements cannot be null..
Copy link
Member

Choose a reason for hiding this comment

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

This file has like 13k deletes. Is that really supposed to be happening? Also, we may want to just have a Pr that is the designer resources cleanup.

@zebmason
Copy link
Author

I've got the number of false positives produced by my tool down to less than 1700, still a lot to wade through and I can see some extra tests that I need to write. I've been a bit more brutal than before and deleted lots of code which appears to exist for use within the debugger - where it is marked as debug I've added #if DEBUG guards.

Obviously there are several possible reasons for the code that I've identified as being dead, examples being

  1. It is there for debugging purposes
  2. I didn't compile with the correct option to activate that code
  3. It flags a regression
  4. The code is partially completed and a subsequent commit will ensure that the dead code gets used
  5. It wasn't tidied up after a commit

My tool uses Roslyn to parse the C# AST so I thought I might contribute something back by way of thanks. Hopefully the noise is minimal and there are some useful issues to address. I'll be quiet for a while now as I doubt that I've missed many members that my tool classifies as dead whilst I endeavour to productionise it for shipping.

@heejaechang
Copy link
Contributor

@zebmason can this tool written as diagnostic analyzer? that probably will make dead code to be removed much sooner.

@zebmason
Copy link
Author

@heejaechang the tool is currently written as a console application which is added as a pre-build step so that the warnings are printed to the output window to be clicked. It was my intention that once stabilised I turn it into a VS Extension and then sell it through VS Marketplace, however that is not currently a possibility. Apart from using Roslyn to parse C# (VB needs to be worked on) it uses libclang to parse C++ and its main purpose is for reviewing Lack of Cohesion problems - the dead code checking was only intended as a side function and I've been using it to verify that my C# parsing is correct.

Incidentally I've used it to refactor my own C# and C++ code - given that I was the only one to write that code it was embarrassing to find dead code and interesting to see where my design choices had reduced cohesion. On the latter point I've actually chopped up some classes so they make more sense and are more flexible.

@dotnet dotnet deleted a comment from dnfclas Nov 1, 2017
@jcouv jcouv added the Community The pull request was submitted by a contributor who is not a Microsoft employee. label Mar 31, 2018
Base automatically changed from master to main March 3, 2021 23:51
@jinujoseph jinujoseph requested review from a team as code owners March 3, 2021 23:51
@CyrusNajmabadi
Copy link
Member

Closing out. It's not feasible to take this in in the current state (esp with all the conflicts now). This is definitely an interesting thing to look at, but future PRs will have to be much smaller in scope (or broken into clear and easy commits to look at) to ensure that this is safe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Community The pull request was submitted by a contributor who is not a Microsoft employee.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants