private static ExpressionSyntax SimplifyCast(CastExpressionSyntax node, SemanticModel semanticModel, OptionSet optionSet, CancellationToken cancellationToken) { if (!CastSimplifier.IsUnnecessaryCast(node, semanticModel, cancellationToken)) { return(node); } return(node.Uncast()); }
/// <summary> /// Adds to <paramref name="targetType"/> if it does not contain an anonymous /// type and binds to the same type at the given <paramref name="position"/>. /// </summary> public static ExpressionSyntax CastIfPossible( this ExpressionSyntax expression, ITypeSymbol targetType, int position, SemanticModel semanticModel, CancellationToken cancellationToken) { if (targetType.ContainsAnonymousType()) { return(expression); } if (targetType.IsSystemVoid()) { return(expression); } if (targetType.Kind == SymbolKind.DynamicType) { targetType = semanticModel.Compilation.GetSpecialType(SpecialType.System_Object); } var typeSyntax = targetType.GenerateTypeSyntax(); var type = semanticModel.GetSpeculativeTypeInfo( position, typeSyntax, SpeculativeBindingOption.BindAsTypeOrNamespace).Type; if (!targetType.Equals(type)) { return(expression); } var castExpression = expression.Cast(targetType); // Ensure that inserting the cast doesn't change the semantics. var specAnalyzer = new SpeculationAnalyzer(expression, castExpression, semanticModel, cancellationToken); var speculativeSemanticModel = specAnalyzer.SpeculativeSemanticModel; if (speculativeSemanticModel == null) { return(expression); } var speculatedCastExpression = (CastExpressionSyntax)specAnalyzer.ReplacedExpression; if (!CastSimplifier.IsUnnecessaryCast(speculatedCastExpression, speculativeSemanticModel, cancellationToken)) { return(expression); } return(castExpression); }
protected override async Task FixAllAsync( Document document, ImmutableArray <Diagnostic> diagnostics, SyntaxEditor editor, CodeActionOptionsProvider options, CancellationToken cancellationToken) { var castNodes = diagnostics.SelectAsArray( d => (ExpressionSyntax)d.AdditionalLocations[0].FindNode(getInnermostNodeForTie: true, cancellationToken)); await editor.ApplyExpressionLevelSemanticEditsAsync( document, castNodes, (semanticModel, castExpression) => CastSimplifier.IsUnnecessaryCast(castExpression, semanticModel, cancellationToken), (_, currentRoot, castExpression) => { var oldParent = castExpression.WalkUpParentheses(); var newParent = Recurse(oldParent); return(currentRoot.ReplaceNode(oldParent, newParent)); }, cancellationToken).ConfigureAwait(false); }
protected override bool IsUnnecessaryCast(SemanticModel model, ExpressionSyntax cast, CancellationToken cancellationToken) => CastSimplifier.IsUnnecessaryCast(cast, model, cancellationToken);