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

Prefer ExactSpelling=true for known extern methods #4130

Conversation

Mrnikbobjeff
Copy link

@Mrnikbobjeff Mrnikbobjeff commented Sep 4, 2020

Implementation of #35695 the warning level was not explicitely stated as far as I can tell. I also extended the proposal to look at the EntryPoint parameter, as we would probably not want to flag
[DllImport("user32.dll", EntryPoint = "CallMsgFilterA", ExactSpelling = true)] public XXX CallMsgFilter(...)

@Mrnikbobjeff Mrnikbobjeff requested a review from a team as a code owner September 4, 2020 16:07
@codecov
Copy link

codecov bot commented Sep 4, 2020

Codecov Report

Merging #4130 into master will increase coverage by 0.01%.
The diff coverage is 93.35%.

@@            Coverage Diff             @@
##           master    #4130      +/-   ##
==========================================
+ Coverage   95.78%   95.80%   +0.01%     
==========================================
  Files        1163     1173      +10     
  Lines      262725   266697    +3972     
  Branches    15829    16077     +248     
==========================================
+ Hits       251655   255508    +3853     
- Misses       9064     9130      +66     
- Partials     2006     2059      +53     

@Mrnikbobjeff
Copy link
Author

Another question left open is if we want to include name manged functions. excluding them should be easy, and in my analysis no name mangled function exhibited behaviour which we want to catch with this analyzer @jkotas

@Mrnikbobjeff
Copy link
Author

Mrnikbobjeff commented Sep 7, 2020

@Evangelink thank you for the review, I believe I adressed all points which were not directly responded to and unclear.

…nto feature/ExactSpellingAnalyzer

# Conflicts:
#	src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx
Copy link
Member

@Evangelink Evangelink left a comment

Choose a reason for hiding this comment

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

A couple more cosmetic changes and then it's ok on my side.

Tagging @mavasani for extra review.

@Mrnikbobjeff
Copy link
Author

Thank you @Evangelink for the detailed review. For future PR's I have a way better understanding of desired formatting and can adapt accordingly. The remaining issues should be fixed now

var str = MicrosoftNetCoreAnalyzersResources.ResourceManager.GetObject("KnownApiList", CultureInfo.InvariantCulture);
using var stringReader = new StringReader(str.ToString());
using var reader = XmlReader.Create(stringReader);
var knownApis = (KnownApi[])serializer.Deserialize(reader);
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are we doing all these XML reader shenanigans? Can we please hard code the known APIs in source, just like all other analyzers do?

Copy link
Author

@Mrnikbobjeff Mrnikbobjeff Sep 8, 2020

Choose a reason for hiding this comment

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

Well there are currently 160k entries for known methods. I initially used the new generator feature to generate a compile time initialised dictionary with the constants, but the resulting compile time was an order of magnitude larger than compiling without the generated dictionary

Copy link
Contributor

Choose a reason for hiding this comment

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

Well there are currently 160k entries.

We would absolutely need performance measurements with this analyzer enabled then. It seems the initial load be pretty expensive?

Copy link
Author

@Mrnikbobjeff Mrnikbobjeff Sep 8, 2020

Choose a reason for hiding this comment

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

Yes the initial load is the heaviest part, it is below half a second though and once its done it is very cheap to query.

Copy link
Author

@Mrnikbobjeff Mrnikbobjeff Sep 8, 2020

Choose a reason for hiding this comment

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

Excluding name mangled symbols this would shring to 96k method symbols

{
[Serializable]
#pragma warning disable CA1034 // Nested types should not be visible
public class KnownApi //Only made public as XmlSerializer requires it
Copy link
Contributor

Choose a reason for hiding this comment

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

Please delete and hard code the dictionary in source.

Copy link
Author

Choose a reason for hiding this comment

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

See above

Copy link
Contributor

@mavasani mavasani left a comment

Choose a reason for hiding this comment

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

Marking as request changes till we figure out the branching for post .NET5 analyzers. Tagging @jmarolf and @jeffhandley

@Mrnikbobjeff
Copy link
Author

Marking as request changes till we figure out the branching for post .NET5 analyzers. Tagging @jmarolf and @jeffhandley

Once this is established I have branches already implemented for all analyers marked as api-approved in the dotnet/runtime repository with the feedback from this branch already ported. I would hold of sending a pr until this is figured out.

@jmarolf
Copy link
Contributor

jmarolf commented Sep 14, 2020

@mavasani which release is this intended for? .NET 5 or .NET 6 Preview 1?

@mavasani
Copy link
Contributor

@jmarolf I believe all new .NET SDK API analyzers are now for post .NET5. @jeffhandley to confirm.

@jeffhandley
Copy link
Member

I believe all new .NET SDK API analyzers are now for post .NET5.

That is correct. New analyzers should target 6.0 at this point.

@jmarolf
Copy link
Contributor

jmarolf commented Sep 15, 2020

alright then this getting merged into master is the correct thing. @mavasani can you unblock this merging?

@mavasani mavasani dismissed their stale review September 16, 2020 00:24

Dismissing my block, I am hoping to review the PR later this week.

return;
}

if (methods.Contains(methodName))
Copy link
Contributor

Choose a reason for hiding this comment

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

@jeffhandley I think someone from the runtime team should review the core analyzer semantics in terms of the analyzer implementation matching the recommended API usage.

Copy link
Member

Choose a reason for hiding this comment

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

It seems missing some scenarios which i commented here , but i would defer to @elinor-fung for final expected scenarios

@Mrnikbobjeff
Copy link
Author

@mavasani I integrated your formatting and spelling changes. The null checks you suggested are all redundant though, as we would check non-nullable value types for null. We have to check on their reference type properties, but these checks are already there

Copy link
Contributor

@mavasani mavasani left a comment

Choose a reason for hiding this comment

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

{
return;
}

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (isExactSpelling) // Bail out
return;
}

Comment on lines +157 to +158
if (isExactSpelling) //Bail out if known method has parameter set to true
return;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (isExactSpelling) //Bail out if known method has parameter set to true
return;

return;
}

if (!isCharSetUnicode && !isExactSpelling && methodName.EndsWith("A", StringComparison.Ordinal))
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if (!isCharSetUnicode && !isExactSpelling && methodName.EndsWith("A", StringComparison.Ordinal))
if (!isCharSetUnicode && methodName.EndsWith("A", StringComparison.Ordinal))

}
}

if (methods.Contains(methodName + "A") && !isCharSetUnicode)
Copy link
Member

Choose a reason for hiding this comment

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

I think this should be within the search condition above (row 138 if (methods.Contains(methodName))) and seems it is missing scenarios with W suffix @jkotas suggested :

When we see "Xxxx" in the entrypoint, the ExactSpelling autofixer needs to decide whether to suggest:

"XxxxW" + ExactSpelling=true. This should be suggested when we see "XxxxW" in the database.
"Xxxx" + ExactSpelling=true. This should be suggested when we see "Xxxx" and no "XxxxW" in the database
Leave the API alone. This should be the case when neither "Xxxx" nor "XxxxW" is in the database

  1. If methodName exist in DB (already covered with if (methods.Contains(methodName)) condition):
  2. If methodName + "W" exist we suggest adding "W" suffix and setting ExactSpelling=true
  3. If methodName + "W" does not exist we suggest only setting ExactSpelling=true

Probably we want to do same for "A" suffix but from from @elinor-fung's comment seems suggesting ExactSpelling=true when CharSet=CharSet.Ansi might not important or might not much helpful, if we want to cover it the rule should be same

  1. If methodName + "A" exist we suggest adding "A" suffix and setting ExactSpelling=true
  2. If methodName + "A" does not exist we suggest only setting ExactSpelling=true


if (methods.Contains(methodName))
{
if (isCharSetUnicode && !isExactSpelling && methodName.EndsWith("W", StringComparison.Ordinal))
Copy link
Member

Choose a reason for hiding this comment

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

!isExactSpelling better to be moved before DB search ( before if (methods.Contains(methodName))), here and all other occurrences below

Suggested change
if (isCharSetUnicode && !isExactSpelling && methodName.EndsWith("W", StringComparison.Ordinal))
if (isCharSetUnicode && methodName.EndsWith("W", StringComparison.Ordinal))

@mavasani
Copy link
Contributor

PR needs to be retargeted to release\6.0.xx branch. Do we still plan to target this PR for .NET6 release?

@buyaa-n
Copy link
Member

buyaa-n commented Feb 15, 2022

Closing this PR as there were no activity for a while, @Mrnikbobjeff feel free to reopen the PR after the feedbacks addressed and when its ready for review

@buyaa-n buyaa-n closed this Feb 15, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants