Giter VIP home page Giter VIP logo

platform-compat's Introduction

Platform Compatibility Analyzer

This project has been replaced by analzyers that are built into the .NET SDK:

As such, it's archived.


Build Status Build Status

This tool provides Roslyn analyzers that find usages of .NET Core & .NET Standard APIs that are problematic on specific platforms or are deprecated.

You can find out more in our blog post!

Usage

In order to use it, install the NuGet package Microsoft.DotNet.Analyzers.Compatibility.

Experience

Usage of .NET Core and .NET Standard APIs that throw PlatformNotSupportedException

See PC001 for more details.

Usage of .NET Standard 2.0 APIs missing from .NET Framework 4.6.1

See PC002 for more details.

Usage of deprecated APIs

See DEXXX files in the docs folder for more details.

platform-compat's People

Contributors

caesar-chen avatar caesar1995 avatar dotnet-maestro[bot] avatar jeremyvignelles avatar jmarolf avatar karelz avatar mairaw avatar mjrousos avatar terrajobst avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

platform-compat's Issues

Support analyzing projects that target other frameworks

Currently, the exception analyzer only runs on projects that target .NET Standard or .NET Core. However, customers who are considering porting but haven't done so yet would still want to see the potential issues by running the analyzer on their projects that target .NET Framework.

Offer fixers

We should consider offering fixers, such as:

  1. Suppress and perform runtime check
  2. Cross-target
  3. Ignore warnings for affected platforms

Suppress and perform runtime check

int x = Console.Width;

--->

#pragma warning disable PNS0001;

if (Environment.OSVersion.Platform != PlatformID.MacOSX &&
    Environment.OSVersion.Platform != PlatformID.Unix)
{
    int x = Console.Width;
}

#pragma warning restore PNS0001;

Cross-target

int x = Console.Width;

--->

  • Configure project to cross compile for all known operating systems, except for the ones the developer already ignored
#if OS_PLATFORM_WIN

int x = Console.Width;

#else

#error Unknown platform

#endif

Ignore warnings for affected platforms

Should configure the project to ignore the platforms affected by the selected API, e.g.

<PropertyGroup>
    <PnsIgnoredPlatforms>Linux;MacOSX</PnsIgnoredPlatforms>
<PropertyGroup>

VSIX Release Version?

Would you consider releasing this as a VSIX?

Throughout the day I use Visual Studio to open and manage lots of different projects and adding analyzers to each one is not always possible. It would be nice to have a system-wide version that would work on any project open in my environment.

False positive for Activator.CreateInstance

I'm seeing the following warning:

PC001 Activator.CreateInstance(Type, params object[]) isn't supported on Linux, MacOSX, Windows	

But when testing this out with the following code, it works correctly on all platforms without throwing an exception:

using System;

namespace TestPlatform
{
    class Program
    {
        static void Main(string[] args)
        {
            var instance = Activator.CreateInstance(typeof(Test), 100, "42");
        }
    }

    class Test
    {
        int first;
        string second;

        public Test(int one, string two)
        {
            first = one;
            second = two;
        }
    }
}

Steer developers away from legacy/deprecated APIs

I'm not a fan of the obsolete attribute. The reasons are:

  • It's not contextual. Some APIs are only problematic when used with certain values on in certain context (i.e. calling vs overriding)
  • It's in metadata. Legacy/deprecation typically happens outside the usual shipping cycle.
  • It's very noisy. There is no grouping, you get warnings for every single violation. Worse, you cannot easily suppress specific classes of issues, you can only suppress globally or a specific occurrence.
  • No tie-in to fixers. Sometimes we just replace a given method with another; it would be nice to allow Roslyn-style fixers for that.

I think I could extend this tool to also cover legacy/deprecated API. For now, I'd like to gather a list of APIs so I can see what the kind of issues would look like and we'd like to surface/suppress them.

Thoughts?

Consider checking for UWP SDK-specific and platform-specific APIs

It would be nice if this analyzer had similar functionality as the Platform Specific Analyzer, that is no longer updated - checking for UWP APIs available only on specific device type or in newer SDK even though the app has TargetPlatformMinVersion lower, for instance:

<TargetPlatformVersion>10.0.15063.0</TargetPlatformVersion>
<TargetPlatformMinVersion>10.0.14393.0</TargetPlatformMinVersion>

The Platform Specific Analyzer does not support checks in Anniversary Update or newer SDKs.

Add support for detecting platform checks in analyzer

In @terrajobst's intro video to the compat package, it's shown that the analyzer can't detect that you already did a platform check, so you still get squiggles when the code has a proper platform guard. So you still have to use pragmas to remove the warnings.
image

However there's another similar analyzer that accomplishes this very thing:
https://github.com/ljw1004/platform-specific-analyzer
Once you add the api check, the warnings automatically disappear - no need to add pragmas.
This is demonstrated clearly in the video here:
https://github.com/ljw1004/platform-specific-analyzer/raw/master/ReadMe.mp4
Before:
image
After (no pragmas and no squiggles)
image
(Sorry for the VB - it's a Lucian thing :-)

So if this analyzer can do it, there's probably a good chance your analyzer can do it too.

Option to run same tooling on existing libraries

Would it be possible to run the analyzer on existing libraries (IL code)?

Motivation: You want to check NuGet dependencies (e.g. with only Desktop assets), if they are likely to fail/work on platform you are interested in (e.g. Linux).
The scan would be hard to read (you have no source code) and might you just point you to areas of concern ... (e.g. networking).

false PC001 warnings for MemoryMappedFile.CreateFromFile

All overloads trigger a "not supported on Linux+OSX" warning. But to my knowledge (which might be wrong) only the usage of named maps is unsupported on Linux.

From the source it looks implemented to me:
https://github.com/dotnet/corefx/blob/master/src/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedFile.Unix.cs
and
https://github.com/dotnet/corefx/blob/master/src/System.IO.MemoryMappedFiles/src/System/IO/MemoryMappedFiles/MemoryMappedView.Unix.cs

Rename project

The acronym has some problems. Without going into too much detail:

Proposals:

  • Terrajobst.CrossTargeting.Analyzers
  • Terrajobst.XTargeting.Analyzers
  • Terrajobst.Porting.Analyzers

Others?

Allow hyperlinks in warnings

Hyperlinks can lead to detailed explanation, and potential workarounds, for example: Project targeting System.Net.Http 4.3.1+ could point to breaking change info for the 3 broken methods.

Environment.OSVersion.Platform

Nice work, Immo!

How about a warning for Environment.OSVersion.Platform usage?

My main concern is with PlatformID.MacOSX. Back in the Silverlight days, Environment.OSVersion.Platform returned PlatformID.MacOSX on OSX. However, on .NET Core it returns PlatformID.Unix on macOS to match Mono's behavior.

This is already confusing for Xamarin.Mac developers and I think it's going to be confusing for .NET Core developers as well.

Code that compares Environment.OSVersion.Platform to PlatformID.MacOSX should use the newer RuntimeInformation.IsOSPlatform(OSPlatform.OSX) API instead.

Note that many of the other enum values are suspect as well:

public enum PlatformID
{
    Win32S = 0,
    Win32Windows = 1,
    Win32NT = 2,
    WinCE = 3,
    Unix = 4,
    Xbox = 5,
    MacOSX = 6
}

Reference: https://github.com/dotnet/corefx/issues/11878

Highlight usage of Obsolete methods/classes

In both .NET Core and .NET Standard, we have legacy technologies which we do not plan to improve going forward. It's ok to use them for compat, but devs should be aware their limitations.

Example HttpListener, should be replaced by Kestrel and friends.

We should highlight such Obsolete APIs.

Avoid "OSX" in warning messages?

The use of "MacOSX" in the warnings looks dated.

screen shot 2017-11-17 at 8 36 55 am

Apple no longer uses "OS X". They call it "macOS" (yes, lowercase 'm', to align with the naming of iOS, watchOS, and tvOS).

Should these warnings use "macOS" or simply "Mac", instead of "MacOSX"?

Version handling

For now the tool generates its data from a single version of CoreFX, for fine tuning the issues raised the tool needs to be able to distinguish between different versions and deal with warnings/suppressions take them into account.

Mark Environment.OSVersion as deprecated

Environment.OSVersion has issues, for starters it doesn't return a sensible value for macOS:

// Output:
//
//      macOS 10.12.6 (16G29)    --> Hello from Unix (Unix 16.7.0.0)
//      Ubuntu 16.04.3 LTS       --> Hello from Unix (Unix 4.4.0.43)
//      Windows 1709 (16299.19)  --> Hello from Win32NT (Microsoft Windows NT 6.2.9200.0)

Console.WriteLine($"Hello from {Environment.OSVersion.Platform} ({Environment.OSVersion})");

But as per @weshaggard there are other issues such as:

  1. People checking for exact enum values for PlatformId. That break things for Unix vs Linux vs OSX which value should I check for? I think our existing IsOSPlatform allows for better checking
  2. Also the enum value for the platform checks is nearly impossible to update in all our platforms as we add new ones. This is why OSPlatform can be default to a string until we can make the constant available in all our platforms.
  3. We cannot actually make the enum value different without breaking compat so things like OSX will never be returned as a platform as an example.
  4. Too much code does exact version checks instead of IsAtLeast this version type of check. We have yet to solve this.
  5. OS’s like windows start to lie about the OSVersion because of people doing exact version checks so then folks really don’t have a value to query. We can help with this with better version check APIs.
  6. We want to help folks find other ways to solve the scenarios they would use version for (i.e. feature light-up) to help eliminate some of the need to do version checks at all.

DE0006 False Positive

Shouldn't DE0006 be considered a false positive when using IDictionaries that are built into the base classes like Exception.Data? Is there another way to iterate over this object that doesn't trigger the analyzer?

Exception exception = new Exception();
exception.Data.Add("test", "123");
foreach (System.Collections.DictionaryEntry dictionaryentry in exception.Data)
{
    Console.WriteLine(dictionaryentry.Key + ": " + dictionaryentry.Value);
}

GlobalSuppressions causes DeprecatedAnalyzer to NRE

If I use VS code fix to add AD0001 to the GlobalSuppressions.cs, it causes DeprecatedAnalyzer to NRE.

[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "DE0001:API is deprecated", Justification = "<Pending>", Scope = "type", Target = "~T:Foo")]

AD0001 'Microsoft.DotNet.Analyzers.Compatibility.Deprecated.DeprecatedAnalyzer' threw an exception of type 'System.NullReferenceException' with message 'Object reference not set to an instance of an object.'.

Now since I don't have the granularity to globally suppress a certain deprecated type and not other deprecated types, I'll obviously not be using GlobalSuppressions.cs. But I thought I'd report it all the same.

Consider switching to IOperation

We currently analyze the language directly. Maybe we should switch to IOperation instead. This would allow us to handle C# and VB from the same code base.

HttpClientHandler.AutomaticDecompression default changed from .NET Core 1.1 to .NET Core 2.0

On .NET Core 1.1, the default value for the HttpClientHandler.AutomaticDecompression property was

DecompressionMethods.Deflate | DecompressionMethods.GZip

On .NET Core 2.0, the default is now:

DecompressionMethods.None;

This was changed so that it is now the same as .NET Framework.

If you need to change the default back to what it was in .NET Core 1.1, use the following code:

var handler = new HttpClientHandler();
handler.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
var client = new HttpClient(handler);

More powerful exclusion mechanism to PNSE scan

While having an exclusion list post auto PNSE scan is a must have we can minimize the manual exclusions by having exclusion at the scan level. This can benefit cases in which a single method/property throws in a very specific circumstance that does not happen in practice, e.g.: it throws if some parameter is not null but internally that code is always called with null.

False positives

While migrating https://github.com/Particular/NServiceBus to netstandard2.0, in addition to #32, I've come across some additional false positives:

  • Process.Id isn't supported on Linux, MacOSX
  • ProcessStartInfo.UseShellExecute isn't supported on Windows
  • ManualResetEvent.ManualResetEvent(bool) isn't supported on Linux, MacOSX
  • MD5CryptoServiceProvider.MD5CryptoServiceProvider() isn't supported on MacOSX
  • SHA1CryptoServiceProvider.SHA1CryptoServiceProvider() isn't supported on MacOSX

Deprecate HttpListener

System.Net.HttpListener does not support many modern protocols. It is compat-only (i.e. only critical fixes, no new improvements, enhancements). It's useful for low-volume basic server requests, but does not scale to modern requirements of HTTP servers (incl. performance).

Use KestrelHttpServer instead.

Allow deprecation information to be pulled from remote sources

At the moment the deprecation data is embedded into the analyzer.

This means that:

  • new deprecations require update of the package
  • I cannot add my own custom deprecations

It would be nice if the analyzer allowed me to configure sources where it looks for deprecations (ideally over the network), rather than just loading the embedded data.

Warning supression

We should allow developers to customize he warnings.

Ability to:

  • Disable warnings for method / type / assembly
  • Disable warnings for specific platform (Mac, iOS, Android, Xamarin)
  • Disable only PNSE / Obsolete warnings

I would recommend an option to have configuration in a config file (xml/json), which can be shared/copied between projects.
Allowing multiple configs may be even better (project-wide / team-wide + project-specific).

Prettify warnings

Reported by @weshaggard

Logger.cs(17,43): warning PC001: RegistryKey.OpenSubKey(string) isn't supported on Linux, MacOSX

We should clean up the warnings a little and add an “and” here.

Exception(SerializationInfo info, StreamingContext context) flagged as not compatible

    [Serializable]
    public class MessageDeserializationException : SerializationException
    {
...

        #pragma warning disable PC001
        protected MessageDeserializationException(SerializationInfo info, StreamingContext context) : base(info, context)
        {
        }
        #pragma warning restore PC001
    }

but it seems to be supported?

https://github.com/dotnet/coreclr/blob/release/2.0.0/src/mscorlib/shared/System/Runtime/Serialization/SerializationException.cs#L35

Each API should have its own rule

Right now, many APIs are contained inside a single rule (for example, PC001 covers all APIs which are not available cross platform). For more precise suppression, each API should have its own rule.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.