public ConditionalAccessInfo(SemanticModel semanticModel, ConditionalAccessExpressionSyntax node) { Node = node; var expressionType = semanticModel.GetTypeInfo(node.Expression).Type; ExpressionType = SyntaxFactory.ParseTypeName(expressionType.ToMinimalDisplayString(semanticModel, node.Expression.GetLocation().SourceSpan.Start)); var resultType = semanticModel.GetTypeInfo(node).Type; ResultType = SyntaxFactory.ParseTypeName(resultType.ToMinimalDisplayString(semanticModel, node.GetLocation().SourceSpan.Start)); IsResultVoid = resultType.SpecialType == SpecialType.System_Void; IsComplex = IsExpressionComplexEnoughToGetATemporaryVariable.IsComplex(semanticModel, node.Expression); }
public ConditionalAccessInfo(SemanticModel semanticModel, ConditionalAccessExpressionSyntax node) { Node = node; var expressionType = semanticModel.GetTypeInfo(node.Expression).Type; ExpressionType = SyntaxFactory.ParseTypeName(expressionType.ToMinimalDisplayString(semanticModel, node.Expression.GetLocation().SourceSpan.Start)); this.IsNullable = expressionType.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T; if (this.IsNullable) { UnderlyingNullableType = ((INamedTypeSymbol)expressionType).TypeArguments[0]; ExpressionType = SyntaxFactory.ParseTypeName(UnderlyingNullableType.ToMinimalDisplayString(semanticModel, node.Expression.GetLocation().SourceSpan.Start)); } var resultType = semanticModel.GetTypeInfo(node).Type; ResultType = SyntaxFactory.ParseTypeName(resultType.ToMinimalDisplayString(semanticModel, node.GetLocation().SourceSpan.Start)); IsResultVoid = resultType.SpecialType == SpecialType.System_Void; IsComplex = IsExpressionComplexEnoughToGetATemporaryVariable.IsComplex(semanticModel, node.Expression); }
public SyntaxNode Replace(SyntaxNode root, SemanticModel model) { var switches = root.DescendantNodes().OfType <SwitchStatementSyntax>().Where(sw => { return(sw.Sections.Any(s => s.Labels.Any(l => l is CasePatternSwitchLabelSyntax || l is CaseSwitchLabelSyntax csl && csl.Value is CastExpressionSyntax ce && ce.Expression.Kind() == SyntaxKind.DefaultLiteralExpression))); }); var tempKey = 0; root = root.ReplaceNodes(switches, (s1, sw) => { try { var ifNodes = new List <IfStatementSyntax>(); BlockSyntax defaultBlock = null; var isComplex = IsExpressionComplexEnoughToGetATemporaryVariable.IsComplex(model, s1.Expression); var switchExpression = sw.Expression; StatementSyntax switchConditionVariable = null; var iType = model.GetTypeInfo(s1.Expression).Type; var expressionType = SyntaxFactory.ParseTypeName(iType.ToMinimalDisplayString(model, s1.Expression.GetLocation().SourceSpan.Start)); if (isComplex) { var key = tempKey++; var keyArg = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("case_pattern" + key)); var methodIdentifier = SyntaxFactory.IdentifierName("global::Bridge.Script.ToTemp"); var toTemp = SyntaxFactory.InvocationExpression(methodIdentifier, SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(keyArg), SyntaxFactory.Argument(switchExpression) }))); switchConditionVariable = SyntaxFactory.ExpressionStatement(toTemp).NormalizeWhitespace(); var parentMethodIdentifier = SyntaxFactory.GenericName(SyntaxFactory.Identifier("global::Bridge.Script.FromTemp"), SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(new[] { expressionType }))); switchExpression = SyntaxFactory.InvocationExpression(parentMethodIdentifier, SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(keyArg) }))); } foreach (var section in sw.Sections) { // This should catch most (if not all) unhandled yet natively supported syntax usage try { var tuple = CollectCondition(switchExpression, section.Labels, expressionType); var condition = tuple.Item1; var variables = tuple.Item2; var whens = tuple.Item3; var body = SyntaxFactory.Block(); var whenBody = SyntaxFactory.Block(); foreach (var variable in variables) { body = body.WithStatements(body.Statements.Add(SyntaxFactory.LocalDeclarationStatement(variable))); } foreach (var statement in section.Statements) { if (whens.Count > 0) { whenBody = whenBody.WithStatements(whenBody.Statements.Add(statement)); } else { body = body.WithStatements(body.Statements.Add(statement)); } } if (whens.Count > 0) { ExpressionSyntax whenCondition = whens[0]; for (int i = 1; i < whens.Count; ++i) { whenCondition = SyntaxFactory.BinaryExpression(SyntaxKind.LogicalOrExpression, whenCondition, whens[i]); } body = body.WithStatements(body.Statements.Add(SyntaxFactory.IfStatement(whenCondition, whenBody))); } if (condition == null) { defaultBlock = body .WithLeadingTrivia(section.GetLeadingTrivia()) .WithTrailingTrivia(section.GetTrailingTrivia()); break; } ifNodes.Add(SyntaxFactory.IfStatement(condition, body).WithLeadingTrivia(section.GetLeadingTrivia())); } catch (Exception e) { throw new ReplacerException(section, e); } } var doBlock = SyntaxFactory.Block(); if (switchConditionVariable != null) { doBlock = doBlock.WithStatements(doBlock.Statements.Add(switchConditionVariable)); } doBlock = doBlock.WithStatements(doBlock.Statements.AddRange(ifNodes)); if (defaultBlock != null) { doBlock = doBlock.WithStatements(doBlock.Statements.Add(defaultBlock)); } var doStatement = SyntaxFactory.DoStatement(doBlock, SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression)); doStatement = doStatement.WithLeadingTrivia(sw.GetLeadingTrivia().Concat(doStatement.GetLeadingTrivia())).WithTrailingTrivia(sw.GetTrailingTrivia()); return(doStatement.NormalizeWhitespace()); } catch (Exception e) { throw new ReplacerException(sw, e); } }); return(root); }