<commit_before>﻿PlatformSpecific
==================

This analyzer helps make sure that your Win10 apps are *universal* - will run on all Win10 devices.

* References > Manage NuGet References > install [PlatformSpecific.Analyzer](https://www.nuget.org/packages/PlatformSpecific.Analyzer)
* [Watch training video](https://github.com/ljw1004/blog/raw/master/Analyzers/PlatformSpecificAnalyzer/ReadMe.mp4) [3mins]

![screenshot](https://raw.githubusercontent.com/ljw1004/blog/master/Analyzers/PlatformSpecificAnalyzer/Screenshot.png)


Explanation
-------------

When you're writing a UWP app, it's hard to know whether a given API is
platform-specific (and hence needs an "adaptivity check") or if it's part
of core UWP. All you can do is either read the docs rigorously, or run your
code on all different platforms to see if it crashes.

This analyzer fixes that problem.

If ever your code calls into a platform-specific API, this analyzer verifies
that you've done an adaptivity check around it -- if you haven't then it reports
a warning. It also provides a handy "quick-fix" to insert the correct check,
by pressing Ctrl+Dot or clicking on the lightbulb.

For advanced scenarios, this analyzer also supports "transitivity" -- you can declare
that an entire method of yours is platform-specific, eliminating the need
for any checks inside, but forcing you to check before invoking the method.
It also supports "feature flags" -- you can declare that a given field
or property embodies the result of calling ApiInformation.IsTypePresent, so
that checking this field is as good as calling it directly.

The analyzer does have a few false positives, in cases where you've written your
own idiosyncratic style of adaptive checks that are technically valid but aren't
conventional. And it has quite a few false negatives, where your method does
some the wrong adaptivity check. That's because there are too many reasonable ways
to do adaptivity check and the analyzer can't possibly reason about them all, so it
errs on the side of permissiveness.

In the end, the analyzer makes sure you're doing adaptivity in a good standard
easy-to-read coding pattern. Its goal is to make sure you didn't flat-out forget
to do the adaptivity checks you need. It doesn't try to check that you've done the
exact right check, and it doesn't aim to be a complete rigorous proof that your
entire app is adaptivity-safe.



Technical specification
-------------------------

Some platform methods come from a specific UWP platform extension SDK.
And some methods might have the [PlatformSpecific] attribute on them.
And some fields/properties might have the [PlatformSpecific] attribute too.

This analyzer checks that any invocation of a method that's in Windows.* namespace
but outside the common UWP platform, and any invocation of a method with a
[*Specific] attribute on it, either (1) is in a method/class/assembly
marked as [*Specific], or (2) is "properly guarded" as defined below.

*Properly Guarded*. You must either have the invocation or a Return statement
inside the positive branch of an `If` block whose conditional includes a "proper guard".
A proper guard is either an invocation of any method inside
a type called ApiInformation, or an access of a field/property that has
a `[*Specific]` attribute on it.

The package provides one attribute `[System.Runtime.CompilerServices.PlatformSpecific]`,
and this is the one that the code-fixes suggest to insert. But you can chose to define
your own more descriptive attributes, e.g. `[MyNamespace.XboxSpecific]`, and all
attributes that end in `Specific` are treated as identical by this analyzer.


Bugs
------

* This analyzer currently only examines platform invocations to check whether they're
platform-specific. WinRT only has a limited number of operations, and I believe the
other operations to check are just *constructions* and *property-access* and
*AddHandler*. (I believe it's not necessary to check for when you access fields of
structs, nor enum values. I also believe it's not necessary to check when you merely<commit_msg>Minor typo fixes to the readme.<commit_after>﻿PlatformSpecific
==================

This analyzer helps make sure that your Win10 apps are *universal* - will run on all Win10 devices.

* References > Manage NuGet References > install [PlatformSpecific.Analyzer](https://www.nuget.org/packages/PlatformSpecific.Analyzer)
* [Watch training video](https://github.com/ljw1004/blog/raw/master/Analyzers/PlatformSpecificAnalyzer/ReadMe.mp4) [3mins]

![screenshot](https://raw.githubusercontent.com/ljw1004/blog/master/Analyzers/PlatformSpecificAnalyzer/Screenshot.png)


Explanation
-------------

When you're writing a UWP app, it's hard to know whether a given API is
platform-specific (and hence needs an "adaptivity check") or if it's part
of core UWP. All you can do is either read the docs rigorously, or run your
code on all different platforms to see if it crashes.

This analyzer fixes that problem.

If ever your code calls into a platform-specific API, this analyzer verifies
that you've done an adaptivity check around it -- if you haven't then it reports
a warning. It also provides a handy "quick-fix" to insert the correct check,
by pressing Ctrl+Dot or clicking on the lightbulb.

For advanced scenarios, this analyzer also supports "transitivity" -- you can declare
that an entire method of yours is platform-specific, eliminating the need
for any checks inside, but forcing you to check before invoking your method.
It also supports "feature flags" -- you can declare that a given field
or property embodies the result of calling ApiInformation.IsTypePresent, so
that checking this field is as good as calling IsTypePresent directly.

The analyzer does have a few false positives, in cases where you've written your
own idiosyncratic style of adaptive checks that are technically valid but aren't
conventional. And it has quite a few false negatives, where your method does
an adaptivity check but checks for the wrong thing. That's because there are too many
reasonable ways to do adaptivity check and the analyzer can't possibly reason about
them all, so it errs on the side of permissiveness.

In the end, the analyzer makes sure you're doing adaptivity in a good standard
easy-to-read coding pattern. Its goal is to make sure you didn't flat-out forget
to do the adaptivity checks you need. It doesn't try to check that you've done the
exact right check, and it doesn't aim to be a complete rigorous proof that your
entire app is adaptivity-safe.



Technical specification
-------------------------

Some platform methods come from a specific UWP platform extension SDK.
And some methods might have the [PlatformSpecific] attribute on them.
And some fields/properties might have the [PlatformSpecific] attribute too.

This analyzer checks that any invocation of a method that's in Windows.* namespace
but outside the common UWP platform, and any invocation of a method with a
[*Specific] attribute on it, either (1) is in a method/class/assembly
marked as [*Specific], or (2) is "properly guarded" as defined below.

*Properly Guarded*. You must either have the invocation itself or a Return statement
inside the positive branch of an `If` block whose conditional includes a "proper guard".
A proper guard is either an invocation of any method inside
a type called ApiInformation, or an access of a field/property that has
a `[*Specific]` attribute on it.

The package provides one attribute `[System.Runtime.CompilerServices.PlatformSpecific]`,
and this is the one that the code-fixes suggest to insert. But you can chose to define
your own more descriptive attributes, e.g. `[MyNamespace.XboxSpecific]`, and all
attributes that end in `Specific` are treated as identical by this analyzer.


Bugs
------

* This analyzer currently only examines platform invocations to check whether they're
platform-specific. WinRT only has a limited number of operations, and I believe the
other operations to check are just *constructions* and *property-access* and
*AddHandler*. (I believe it's not necessary to check for when you access fields of
structs, nor enum values. I also believe it's not necessary to check when you merely
{'fraction_non_alphanumeric': 0.06657740993184032, 'fraction_numerical': 0.0038948393378773127, 'mean_word_length': 4.5, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 6, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '814459', 'n_tokens_mistral': 2177, 'n_tokens_neox': 1991, 'n_words': 1165}