public static ArgumentSyntax WithRef(this ArgumentSyntax syntax, bool isRef) { if (isRef) { return(syntax.WithRefOrOutKeyword(SyntaxFactory.Token(SyntaxKind.RefKeyword))); } else { return(syntax.WithRefOrOutKeyword(default(SyntaxToken))); } }
public static ArgumentSyntax AddOutKeywordToArgument(ArgumentSyntax argument) { var newArgument = argument? .WithRefOrOutKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword)) .NormalizeWhitespace(); return(newArgument); }
private StatementSyntax ToManagedMethod(string target, ArgumentSyntax source, JSFunctionTypeInfo info) { List <ArgumentSyntax> arguments = new List <ArgumentSyntax>(); arguments.Add(source.WithRefOrOutKeyword(Token(SyntaxKind.OutKeyword))); for (int i = 0; i < info.ArgsTypeInfo.Length; i++) { var sourceType = info.ArgsTypeInfo[i]; if (!_isAction && i + 1 == info.ArgsTypeInfo.Length) { arguments.Add(ArgToManaged(i, sourceType.Syntax, _argumentMarshalerTypes[i])); } else { arguments.Add(ArgToJS(i, sourceType.Syntax, _argumentMarshalerTypes[i])); } } return(ExpressionStatement(InvocationExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(target), GetToManagedMethod(Type))) .WithArgumentList(ArgumentList(SeparatedList(arguments))))); }
private StatementSyntax ToManagedMethod(string target, ArgumentSyntax source, TypeSyntax sourceType) { return(ExpressionStatement(InvocationExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(target), GetToManagedMethod(Type))) .WithArgumentList(ArgumentList(SeparatedList(new[] { source.WithRefOrOutKeyword(Token(SyntaxKind.OutKeyword)), Argument(ParenthesizedLambdaExpression() .WithModifiers(TokenList(Token(SyntaxKind.StaticKeyword))) .WithParameterList(ParameterList(SeparatedList(new[] { Parameter(Identifier("__task_result_arg")) .WithModifiers(TokenList(Token(SyntaxKind.RefKeyword))) .WithType(IdentifierName(Constants.JSMarshalerArgumentGlobal)), Parameter(Identifier("__task_result")) .WithModifiers(TokenList(Token(SyntaxKind.OutKeyword))) .WithType(sourceType) }))) .WithBlock(Block(SingletonList <StatementSyntax>(ExpressionStatement( InvocationExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName("__task_result_arg"), GetToManagedMethod(_resultMarshalerType))) .WithArgumentList(ArgumentList(SeparatedList(new[] { Argument(IdentifierName("__task_result")).WithRefOrOutKeyword(Token(SyntaxKind.OutKeyword)), })))))))) }))))); }
private StatementSyntax ToManagedMethodVoid(string target, ArgumentSyntax source) { return(ExpressionStatement(InvocationExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, IdentifierName(target), GetToManagedMethod(Type))) .WithArgumentList(ArgumentList(SingletonSeparatedList(source.WithRefOrOutKeyword(Token(SyntaxKind.OutKeyword))))))); }
public CodeActionEdit GetEdit(CancellationToken cancellationToken) { SyntaxNode root = (SyntaxNode)this.document.GetSyntaxRoot(cancellationToken); ISemanticModel model = this.document.GetSemanticModel(cancellationToken); ISymbol typeSymbol = model.GetDeclaredSymbol(this.typeDeclaration, cancellationToken); string typeName = typeSymbol.Name; string methodName = String.Format("Create{0}", typeName); // Note: typeSyntax will already contain template parameters, same as class definition TypeSyntax typeSyntax = Syntax.ParseTypeName(typeSymbol.ToMinimalDisplayString(this.ctorDeclaration.GetLocation(), model)); // Filter out access modifiers var accessModifiers = this.ctorDeclaration.Modifiers.Where(IsAccessModifier); // Define modifiers, access modifier same as in constructor + static keyword SyntaxTokenList modifiers = Syntax.TokenList(accessModifiers) .Add(Syntax.Token(SyntaxKind.StaticKeyword)); // Forward parameters to arguments, from ctor declaration to ctor call SeparatedSyntaxList <ArgumentSyntax> arguments = Syntax.SeparatedList <ArgumentSyntax>(); foreach (ParameterSyntax parameter in this.ctorDeclaration.ParameterList.Parameters) { ArgumentSyntax argument = Syntax.Argument(Syntax.IdentifierName(parameter.Identifier)); // Perfect forwarding // If parameter if `ref' or `out', it must be forwarded with same keyword if (parameter.Modifiers.Any(SyntaxKind.OutKeyword)) { argument = argument.WithRefOrOutKeyword(Syntax.Token(SyntaxKind.OutKeyword)); } else if (parameter.Modifiers.Any(SyntaxKind.RefKeyword)) { argument = argument.WithRefOrOutKeyword(Syntax.Token(SyntaxKind.RefKeyword)); } arguments = arguments.Add(argument); } // If class is a parametrized type (template), factory method should also handle those parameters // TODO: // class A<T,U> { public A(){} } -> class A<T,U> { private A(){} public static A<V,Z> CreateA<V,Z>(){...} } // Create object creation expression ObjectCreationExpressionSyntax objectCreationExpression = Syntax.ObjectCreationExpression(typeSyntax) .WithArgumentList(Syntax.ArgumentList(arguments)); // Create simple factory method, return new TYPE(ARGUMENTS); BlockSyntax methodBody = Syntax.Block(Syntax.List <StatementSyntax>(Syntax.ReturnStatement(objectCreationExpression))); // Define factory method MethodDeclarationSyntax factoryMethod = Syntax.MethodDeclaration(typeSyntax, methodName) .WithBody(methodBody) .WithModifiers(modifiers) .WithParameterList(this.ctorDeclaration.ParameterList) .WithLeadingTrivia(Syntax.ElasticCarriageReturnLineFeed) .WithAdditionalAnnotations(CodeAnnotations.Formatting); ReplaceConstructorWithFactoryMethodRewriter visitor = new ReplaceConstructorWithFactoryMethodRewriter(model, typeSymbol, cancellationToken, methodName, factoryMethod, ctorDeclaration, this.typeDeclaration); SyntaxNode newRoot = visitor.Visit(root); return(new CodeActionEdit(document.UpdateSyntaxRoot(newRoot))); }
public static ArgumentSyntax WithOutKeyword(this ArgumentSyntax argument) { return(argument.WithRefOrOutKeyword(OutKeyword.ToToken())); }
protected virtual ArgumentSyntax ToManagedMethodRefOrOut(ArgumentSyntax argument) { return(argument.WithRefOrOutKeyword(Token(SyntaxKind.OutKeyword))); }
public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { if (!Settings.IsAnyCodeFixEnabled( CodeFixIdentifiers.AddOutModifierToArgument, CodeFixIdentifiers.RemoveRefModifier, CodeFixIdentifiers.CreateSingletonArray)) { return; } SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false); ArgumentSyntax argument = root .FindNode(context.Span, getInnermostNodeForTie: true)? .FirstAncestorOrSelf <ArgumentSyntax>(); Debug.Assert(argument != null, $"{nameof(argument)} is null"); if (argument == null) { return; } foreach (Diagnostic diagnostic in context.Diagnostics) { switch (diagnostic.Id) { case CompilerDiagnosticIdentifiers.ArgumentMustBePassedWithOutKeyword: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddOutModifierToArgument)) { return; } CodeAction codeAction = CodeAction.Create( "Add 'out' modifier", cancellationToken => { ArgumentSyntax newArgument = argument .WithRefOrOutKeyword(CSharpFactory.OutKeyword()) .WithFormatterAnnotation(); return(context.Document.ReplaceNodeAsync(argument, newArgument, context.CancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.ArgumentMayNotBePassedWithRefKeyword: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.RemoveRefModifier)) { return; } CodeAction codeAction = CodeAction.Create( "Remove 'ref' modifier", cancellationToken => { ArgumentSyntax newArgument = argument .WithRefOrOutKeyword(default(SyntaxToken)) .PrependToLeadingTrivia(argument.RefOrOutKeyword.GetLeadingAndTrailingTrivia()) .WithFormatterAnnotation(); return(context.Document.ReplaceNodeAsync(argument, newArgument, context.CancellationToken)); }, GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } case CompilerDiagnosticIdentifiers.CannotConvertArgumentType: { if (!Settings.IsCodeFixEnabled(CodeFixIdentifiers.AddOutModifierToArgument)) { return; } ExpressionSyntax expression = argument.Expression; if (expression?.IsMissing == false) { SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false); ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(expression); if (typeSymbol?.IsErrorType() == false) { foreach (ITypeSymbol typeSymbol2 in DetermineParameterTypeHelper.DetermineParameterTypes(argument, semanticModel, context.CancellationToken)) { if (!typeSymbol.Equals(typeSymbol2) && typeSymbol2.IsArrayType()) { var arrayType = (IArrayTypeSymbol)typeSymbol2; if (semanticModel.IsImplicitConversion(expression, arrayType.ElementType)) { CodeAction codeAction = CodeAction.Create( "Create singleton array", cancellationToken => CreateSingletonArrayRefactoring.RefactorAsync(context.Document, expression, arrayType.ElementType, semanticModel, cancellationToken), GetEquivalenceKey(diagnostic)); context.RegisterCodeFix(codeAction, diagnostic); break; } } } } } break; } } } }