Exemplo n.º 1
0
        /// <summary>
        /// returns instance of <see cref="HowToGuard"/> for <see cref="ISymbol"/>
        /// </summary>
        /// <param name="target">instance of <see cref="ISymbol"/></param>
        /// <returns>instance of <see cref="HowToGuard"/></returns>
        public static HowToGuard GetGuardForSymbol(ISymbol target)
        {
            var plat = Analyzer.GetPlatformForSymbol(target);

            switch (plat.Kind)
            {
            case PlatformKind.ExtensionSDK:
                return(new HowToGuard()
                {
                    TypeToCheck = target.Kind == SymbolKind.NamedType ? target.ToDisplayString() : target.ContainingType.ToDisplayString(),
                    KindOfCheck = "IsTypePresent"
                });

            case PlatformKind.Uwp:
                if (target.Kind == SymbolKind.NamedType)
                {
                    return(new HowToGuard()
                    {
                        TypeToCheck = target.ToDisplayString(),
                        KindOfCheck = "IsTypePresent"
                    });
                }
                else
                {
                    var g = new HowToGuard
                    {
                        TypeToCheck = target.ContainingType.ToDisplayString()
                    };

                    var d0 = Analyzer.GetUniversalApiAdditions(Analyzer.N0DifferencesRes);
                    var d1 = Analyzer.GetUniversalApiAdditions(Analyzer.N1DifferencesRes);

                    if (!d0.TryGetValue(g.TypeToCheck, out List <NewMember> newMembers))
                    {
                        d1.TryGetValue(g.TypeToCheck, out newMembers);
                    }

                    if (newMembers == null)
                    {
                        throw new InvalidOperationException("oops! expected this UWP version API to be in the dictionary of new things");
                    }

                    g.MemberToCheck = target.Name;

                    if (target.Kind == SymbolKind.Field)
                    {
                        // the only fields in WinRT are enum fields
                        g.KindOfCheck = "IsEnumNamedValuePresent";
                    }
                    else if (target.Kind == SymbolKind.Event)
                    {
                        g.KindOfCheck = "IsEventPresent";
                    }
                    else if (target.Kind == SymbolKind.Property)
                    {
                        // TODO: if SDK starts introducing additional accessors on properties, we'll have to change this
                        g.KindOfCheck = "IsPropertyPresent";
                    }
                    else if (target.Kind == SymbolKind.Method)
                    {
                        g.KindOfCheck = "IsMethodPresent";

                        if (target.Kind == SymbolKind.Method && plat.ByParameterCount)
                        {
                            g.ParameterCountToCheck = (target as IMethodSymbol).Parameters.Length;
                        }
                    }

                    return(g);
                }

            default:
                throw new InvalidOperationException("oops! don't know why I was asked to check something that's fine");
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// This function tells which version/platform the symbol is from.
        /// </summary>
        /// <param name="symbol">represents a compiler <see cref="ISymbol"/></param>
        /// <returns>instance of <see cref="Platform"/></returns>
        public static Platform GetPlatformForSymbol(ISymbol symbol)
        {
            if (symbol == null)
            {
                return(new Platform(PlatformKind.Unchecked));
            }

            if (symbol.ContainingNamespace != null && symbol.ContainingNamespace.ToDisplayString().StartsWith("Windows."))
            {
                var assembly = symbol.ContainingAssembly.Name;
                var version  = symbol.ContainingAssembly.Identity.Version.Major;

                // Any call to ApiInformation.* is allowed without warning
                if (symbol.ContainingType?.Name == "ApiInformation")
                {
                    return(new Platform(PlatformKind.Uwp, Analyzer.N2SDKVersion));
                }

                // Don't want to give warning when analyzing code in an PCL project.
                // In those two targets, every Windows type is found in Windows.winmd, so that's how we'll suppress it:
                if (assembly == "Windows")
                {
                    return(new Platform(PlatformKind.Unchecked));
                }

                // Some WinRT types like Windows.UI.Color get projected to come from .NET assemblies, always present:
                if (assembly.StartsWith("System.Runtime."))
                {
                    return(new Platform(PlatformKind.Uwp, Analyzer.N2SDKVersion));
                }

                // Some things are emphatically part of UWP.10240
                if (assembly == "Windows.Foundation.FoundationContract" || (assembly == "Windows.Foundation.UniversalApiContract" && version == 1))
                {
                    return(new Platform(PlatformKind.Uwp, Analyzer.N2SDKVersion));
                }

                if (assembly == "Windows.Foundation.UniversalApiContract")
                {
                    var isType = symbol.Kind == SymbolKind.NamedType;

                    var typeName = isType ? symbol.ToDisplayString() : symbol.ContainingType.ToDisplayString();

                    TypePresenceIndicator presentInN0ApiDiff = CheckCollectionForType(Analyzer.GetUniversalApiAdditions(Analyzer.N0DifferencesRes), typeName, symbol);

                    if (presentInN0ApiDiff == TypePresenceIndicator.New)
                    {
                        // the entire type was found in Target Version
                        return(new Platform(PlatformKind.Uwp, Analyzer.N0SDKVersion));
                    }
                    else if (presentInN0ApiDiff == TypePresenceIndicator.Changes)
                    {
                        // the entire type was found in Target Version with matching parameter lengths
                        return(new Platform(PlatformKind.Uwp, Analyzer.N0SDKVersion, true));
                    }
                    else
                    {
                        TypePresenceIndicator presentInN1ApiDiff = CheckCollectionForType(Analyzer.GetUniversalApiAdditions(Analyzer.N1DifferencesRes), typeName, symbol);

                        if (presentInN1ApiDiff == TypePresenceIndicator.New)
                        {
                            // the entire type was found in Target Version
                            return(new Platform(PlatformKind.Uwp, Analyzer.N1SDKVersion));
                        }
                        else if (presentInN1ApiDiff == TypePresenceIndicator.Changes)
                        {
                            // the entire type was found in Target Version with matching parameter lengths
                            return(new Platform(PlatformKind.Uwp, Analyzer.N1SDKVersion, true));
                        }
                        else
                        {
                            // the type was in Min version
                            return(new Platform(PlatformKind.Uwp, Analyzer.N2SDKVersion));
                        }
                    }
                }

                // All other Windows.* types come from platform-specific extensions
                return(new Platform(PlatformKind.ExtensionSDK));
            }
            else
            {
                return(new Platform(PlatformKind.Unchecked));
            }
        }