private async Task <Document> IntroduceGuardAsync(Document document, SyntaxNode node, HowToGuard g, CancellationToken cancellationToken) { // + if (Windows.Foundation.Metadata.ApiInformation.IsTypePresent(targetContainingType)) // { // old-statement // + } try { var oldStatement = node.FirstAncestorOrSelf <StatementSyntax>(); var oldLeadingTrivia = oldStatement.GetLeadingTrivia(); var conditionReceiver = SyntaxFactory.ParseName($"Windows.Foundation.Metadata.ApiInformation.{g.KindOfCheck}").WithAdditionalAnnotations(Simplifier.Annotation); ArgumentListSyntax conditionArgument = null; if (g.MemberToCheck == null) { var conditionString1 = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(g.TypeToCheck)); conditionArgument = SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(conditionString1))); } else { var conditionString1 = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(g.TypeToCheck)); var conditionString2 = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(g.MemberToCheck)); var conditionInt3 = SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(g.ParameterCountToCheck ?? 0)); IEnumerable <ArgumentSyntax> conditions = null; if (g.ParameterCountToCheck.HasValue) { conditions = new ArgumentSyntax[] { SyntaxFactory.Argument(conditionString1), SyntaxFactory.Argument(conditionString2), SyntaxFactory.Argument(conditionInt3) }; } else { conditions = new ArgumentSyntax[] { SyntaxFactory.Argument(conditionString1), SyntaxFactory.Argument(conditionString2) }; } conditionArgument = SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(conditions)); } var condition = SyntaxFactory.InvocationExpression(conditionReceiver, conditionArgument); var thenStatements = SyntaxFactory.Block(oldStatement.WithoutLeadingTrivia()); var ifStatement = SyntaxFactory.IfStatement(condition, thenStatements).WithLeadingTrivia(oldLeadingTrivia).WithAdditionalAnnotations(Formatter.Annotation); var oldRoot = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var newRoot = oldRoot.ReplaceNode(oldStatement, ifStatement); return(document.WithSyntaxRoot(newRoot)); } catch { } return(document); }
/// <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"); } }