/// <summary> /// Replaces <paramref name="methodDeclaration" />'s body with an invocation of the port's delegate. /// </summary> /// <param name="methodDeclaration">The method declaration whose body should be replaced.</param> private MethodDeclarationSyntax ReplaceBodyWithDelegateInvocation(MethodDeclarationSyntax methodDeclaration) { var fieldReference = SyntaxFactory.ParseExpression("this." + GetFieldName()); var arguments = methodDeclaration.ParameterList.Parameters.Select(parameter => { var argument = SyntaxFactory.Argument(SyntaxFactory.IdentifierName(parameter.Identifier)); if (parameter.Modifiers.IndexOf(SyntaxKind.RefKeyword) != -1) return argument.WithRefOrOutKeyword(SyntaxFactory.Token(SyntaxKind.RefKeyword)); if (parameter.Modifiers.IndexOf(SyntaxKind.OutKeyword) != -1) return argument.WithRefOrOutKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword)); return argument; }); var argumentList = SyntaxFactory.SeparatedList(arguments); var body = SyntaxFactory.InvocationExpression(fieldReference, SyntaxFactory.ArgumentList(argumentList)); var arrowExpression = SyntaxFactory.ArrowExpressionClause(body); methodDeclaration = methodDeclaration.WithBody(null).WithExpressionBody(arrowExpression.NormalizeWhitespace()); if (methodDeclaration.SemicolonToken.Kind() != SyntaxKind.SemicolonToken) return methodDeclaration.WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); return methodDeclaration; }
/// <summary> /// Normalizes the <paramref name="declaration" />. /// </summary> public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax declaration) { // Nothing to do here for methods without expression bodies if (declaration.ExpressionBody == null) return declaration; // Nothing to do here for methods not defined in fault effects or for methods that are no overrides of some port var methodSymbol = declaration.GetMethodSymbol(SemanticModel); if (!methodSymbol.ContainingType.IsFaultEffect(SemanticModel) || !methodSymbol.IsOverride) return declaration; var originalDeclaration = declaration; var statements = AsStatementBody(methodSymbol, declaration.ExpressionBody.Expression); declaration = declaration.WithSemicolonToken(default(SyntaxToken)).WithExpressionBody(null); return declaration.WithBody(statements).EnsureLineCount(originalDeclaration); }
/// <summary> /// Normalizes the <paramref name="declaration" />. /// </summary> public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax declaration) { _methodSymbol = declaration.GetMethodSymbol(SemanticModel); if (!_methodSymbol.ContainingType.IsComponent(SemanticModel) || !_methodSymbol.IsRequiredPort(SemanticModel)) return declaration; var body = CreateBindingCode(); var originalDeclaration = declaration; var index = declaration.Modifiers.IndexOf(SyntaxKind.ExternKeyword); var delegateFieldName = Syntax.LiteralExpression(GetBindingDelegateFieldName()); var infoFieldName = Syntax.LiteralExpression(GetBinderFieldName()); var defaultMethod = Syntax.LiteralExpression(GetUnboundPortAssignmentMethodName()); declaration = declaration.WithModifiers(declaration.Modifiers.RemoveAt(index)).WithSemicolonToken(default(SyntaxToken)); declaration = (MethodDeclarationSyntax)Syntax.AddAttribute<DebuggerHiddenAttribute>(declaration); declaration = (MethodDeclarationSyntax)Syntax.AddAttribute<BindingMetadataAttribute>(declaration, delegateFieldName, infoFieldName, defaultMethod); return declaration.WithBody(body).EnsureLineCount(originalDeclaration); }
private async Task<Document> MultipleStatementsAsync(Document document, MethodDeclarationSyntax declaration, CancellationToken c) { SyntaxList<StatementSyntax> statements = new SyntaxList<StatementSyntax>(); SyntaxList<StatementSyntax> initializeStatements = declaration.Body.Statements; var newBlock = declaration.Body; foreach (ExpressionStatementSyntax statement in initializeStatements) { var expression = statement.Expression as InvocationExpressionSyntax; var expressionStart = expression.Expression as MemberAccessExpressionSyntax; if (expressionStart == null || expressionStart.Name == null || expressionStart.Name.ToString() != "RegisterSyntaxNodeAction") { continue; } if (expression.ArgumentList == null || expression.ArgumentList.Arguments.Count() != 2) { continue; } var argumentMethod = expression.ArgumentList.Arguments[0].Expression as IdentifierNameSyntax; var argumentKind = expression.ArgumentList.Arguments[1].Expression as MemberAccessExpressionSyntax; var preArgumentKind = argumentKind.Expression as IdentifierNameSyntax; if (argumentMethod.Identifier == null || argumentKind.Name == null || preArgumentKind.Identifier == null || argumentKind.Name.Identifier.Text != "IfStatement" || preArgumentKind.Identifier.ValueText != "SyntaxKind") { continue; } statements = statements.Add(statement); } SyntaxList<StatementSyntax> statementsToAdd = new SyntaxList<StatementSyntax>(); statementsToAdd = statementsToAdd.Add(statements[0]); newBlock = newBlock.WithStatements(statementsToAdd); var newDeclaration = declaration.WithBody(newBlock); return await ReplaceNode(declaration, newDeclaration, document); }
private MethodDeclarationSyntax AddMethodBody(MethodDeclarationSyntax containingMethod, MetaField field, Func<ExpressionSyntax, InvocationExpressionSyntax> mutatingInvocationFactory) { var returnExpression = field.IsLocallyDefined ? (ExpressionSyntax)SyntaxFactory.InvocationExpression( // this.With(field: this.field.SomeOperation(someArgs)) Syntax.ThisDot(WithMethodName), SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList( SyntaxFactory.Argument( SyntaxFactory.NameColon(field.Name), NoneToken, mutatingInvocationFactory(Syntax.ThisDot(field.NameAsField)))))) : SyntaxFactory.CastExpression( // (TemplateType)base.SameMethod(sameArgs) GetFullyQualifiedSymbolName(this.generator.applyToSymbol), SyntaxFactory.InvocationExpression( Syntax.BaseDot(SyntaxFactory.IdentifierName(containingMethod.Identifier)), SyntaxFactory.ArgumentList( Syntax.JoinSyntaxNodes( SyntaxKind.CommaToken, containingMethod.ParameterList.Parameters.Select(p => SyntaxFactory.Argument(SyntaxFactory.IdentifierName(p.Identifier))))))); return containingMethod.WithBody(SyntaxFactory.Block( SyntaxFactory.ReturnStatement(returnExpression))); }
/// <summary> /// Removes any existing code that was added previously for this dependency /// </summary> protected virtual MethodDeclarationSyntax RemoveExistingCodeDependencyFromMethod (MethodDeclarationSyntax method) { var statements = method.Body.Statements; var newStatements = statements; foreach (var statement in statements) { if (this.IsCodeDependencyStatement (statement)) { newStatements = newStatements.Remove (statement); } } return method.WithBody (method.Body.WithStatements (newStatements)); }
// gets ride of multiple statement inside Initialize, keeping one correct statement private async Task<Document> MultipleStatementsAsync(Document document, MethodDeclarationSyntax declaration, CancellationToken c) { SyntaxList<StatementSyntax> statements = new SyntaxList<StatementSyntax>(); SyntaxList<StatementSyntax> initializeStatements = declaration.Body.Statements; foreach (ExpressionStatementSyntax statement in initializeStatements) { bool correctRegister = CodeFixHelper.IsCorrectRegister(statement); if (correctRegister) { statements = statements.Add(statement); break; } } BlockSyntax newBlock = declaration.Body; newBlock = newBlock.WithStatements(statements); MethodDeclarationSyntax newDeclaration = declaration.WithBody(newBlock); return await ReplaceNode(declaration, newDeclaration, document); }
/// <summary> /// Normalizes the <paramref name="declaration" />. /// </summary> public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax declaration) { var originalDeclaration = declaration; var methodSymbol = declaration.GetMethodSymbol(SemanticModel); if (!methodSymbol.ContainingType.IsFaultEffect(SemanticModel) || !methodSymbol.IsOverride) return declaration; var memberAccess = Syntax.MemberAccessExpression(Syntax.BaseExpression(), methodSymbol.Name); var invocation = Syntax.InvocationExpression(memberAccess, CreateInvocationArguments(methodSymbol.Parameters)); declaration = declaration.WithBody(CreateBody(methodSymbol, declaration.Body, invocation)); return declaration.EnsureLineCount(originalDeclaration); }
public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node) { //handle language constructs string typeName = node.ReturnType.ToString(); switch (typeName) { case "on": return rewriteEventHandler(node); case "function": return rewriteFunction(node, false); case "method": return rewriteFunction(node, true); case "typedef": return rewriteTypedef(node); case "": { switch (node.Identifier.ToString()) { case "constructor": return rewriteConstructor(node); } break; } } //handle dsls IDSLHandler dsl = null; DSLSurroundings ds = node.Parent is CompilationUnitSyntax ? DSLSurroundings.Global : DSLSurroundings.TypeBody; string id = null; if (!node.ReturnType.IsMissing) { dsl = ctx_.CreateDSL(typeName); id = node.Identifier.ToString(); } else dsl = ctx_.CreateDSL(node.Identifier.ToString()); if (dsl != null) { DSLContext dctx = new DSLContext { MainNode = node, Surroundings = ds, Id = id, ExtraMembers = members_ }; return dsl.compile(ctx_, dctx); } return node.WithBody((BlockSyntax)base.Visit(node.Body)); }
private static async Task<Document> GenerateMethodImplementationAsync(Document document, MethodDeclarationSyntax methodSyntax, CancellationToken cancellationToken) { var semanticModel = await document.GetSemanticModelAsync(cancellationToken); IMethodSymbol methodSymbol = semanticModel.GetDeclaredSymbol(methodSyntax); MethodDeclarationSyntax modifiedMethodSyntax = methodSyntax; if (methodSymbol.Parameters.Length == 1) { var sourceClassSymbol = methodSymbol.ContainingType; var targetClassSymbol = methodSymbol.Parameters[0].Type as INamedTypeSymbol; if (targetClassSymbol == null) return document; var matchedProperties = RetrieveMatchedProperties(sourceClassSymbol, targetClassSymbol); modifiedMethodSyntax = methodSyntax.WithBody(GenerateMethodBody(methodSymbol, matchedProperties, semanticModel, methodSyntax.Body.Span.End - 1)); } else if (methodSymbol.Parameters.Length == 2) { var sourceClassSymbol = methodSymbol.Parameters[0].Type as INamedTypeSymbol; var targetClassSymbol = methodSymbol.Parameters[1].Type as INamedTypeSymbol; if (sourceClassSymbol == null || targetClassSymbol == null) return document; var matchedProperties = RetrieveMatchedProperties(sourceClassSymbol, targetClassSymbol); modifiedMethodSyntax = methodSyntax.WithBody(GenerateMethodBody(methodSymbol, matchedProperties, semanticModel, methodSyntax.Body.Span.End - 1)); } // replace root and return modified document var root = await document.GetSyntaxRootAsync(cancellationToken); var newRoot = root.ReplaceNode(methodSyntax, modifiedMethodSyntax); var newDocument = document.WithSyntaxRoot(newRoot); return newDocument; }
private async Task<Document> HandleMethodDeclaration(MethodDeclarationSyntax declaration, Document document, CancellationToken cancellationToken) { var returnStatement = SyntaxFactory.ReturnStatement( returnKeyword: SyntaxFactory.Token(SyntaxKind.ReturnKeyword), expression: declaration.ExpressionBody.Expression, semicolonToken: declaration.SemicolonToken); var newDeclaration = declaration .WithBody(SyntaxFactory.Block(returnStatement)) .WithExpressionBody(null) .WithSemicolonToken(default(SyntaxToken)) .WithAdditionalAnnotations(Formatter.Annotation); var oldRoot = await document.GetSyntaxRootAsync(cancellationToken); var newRoot = oldRoot.ReplaceNode(declaration, newDeclaration); return document.WithSyntaxRoot(newRoot); }
private static MethodDeclarationSyntax MakeInterfaceMethod(MethodDeclarationSyntax methodSyntax) { return methodSyntax.WithBody(null) .WithModifiers(new SyntaxTokenList()) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); }
private async Task<Document> ReturnSelfAsync(Document document, MethodDeclarationSyntax method, CancellationToken cancellationToken) { var syntaxList = method.Body.Statements; foreach (var s in syntaxList.ToArray()) { if (s is ReturnStatementSyntax) { syntaxList = syntaxList.Replace(s, SyntaxFactory.ReturnStatement( SyntaxFactory.ThisExpression()) .WithLeadingTrivia( s.GetLeadingTrivia() ) ) ; } } var newMethod = method .WithBody(SyntaxFactory.Block(syntaxList).WithTriviaFrom(method.Body)) .WithReturnType(SyntaxFactory.ParseTypeName(method.Parent.Identifier()).WithTriviaFrom(method.ReturnType)) ; var root = await document.GetSyntaxRootAsync(); var newRoot = root.ReplaceNode(method, newMethod); return document.WithSyntaxRoot(newRoot); }
private static ClassDeclarationSyntax AddObjectInvariantsToExistingMethod(MethodDeclarationSyntax old_invariant_method, BlockSyntax new_invariants) { Contract.Requires(old_invariant_method != null); Contract.Requires(new_invariants != null); var parentclass = old_invariant_method.Parent as ClassDeclarationSyntax; Contract.Assert(parentclass != null); // var new_body = old_invariant_method.Body.AddStatements(new_invariants.Statements); // this doesnt pass the type checker !? var new_body = old_invariant_method.Body; Contract.Assert(new_body != null); foreach (var inv in new_invariants.Statements) { new_body = new_body.AddStatements(inv); } var new_invariant_method = old_invariant_method.WithBody(new_body); parentclass = parentclass.ReplaceNode(old_invariant_method, new_invariant_method); return parentclass; }
/// <summary> /// Normalizes the <paramref name="methodDeclaration" />. /// </summary> protected override SyntaxNode Normalize(MethodDeclarationSyntax methodDeclaration) { var returnCount = methodDeclaration.Descendants<ReturnStatementSyntax>().Count(); // If there is no return statement within the method's body, there's nothing to do if (returnCount == 0) return methodDeclaration; // If there is only one return and it is the last method body's last statement, there's nothing to do if (returnCount == 1 && methodDeclaration.Body.Statements[methodDeclaration.Body.Statements.Count - 1] is ReturnStatementSyntax) return methodDeclaration; // Otherwise, we have to normalize the method var nameScope = methodDeclaration.GetNameScope(SemanticModel, includeLocals: true); var symbol = methodDeclaration.GetMethodSymbol(SemanticModel); _returnsValue = !symbol.ReturnsVoid; _hasReturnedVariable = SyntaxFactory.IdentifierName(nameScope.MakeUnique("hasReturned")); _returnValueVariable = _returnsValue ? SyntaxFactory.IdentifierName(nameScope.MakeUnique("returnValue")) : null; var rewriter = new Rewriter(Syntax, _hasReturnedVariable); methodDeclaration = (MethodDeclarationSyntax)rewriter.Visit(methodDeclaration); methodDeclaration = (MethodDeclarationSyntax)base.Normalize(methodDeclaration); // Generate the declarations for the local variables var hasReturnedLocal = Syntax.LocalDeclarationStatement(Syntax.TypeExpression<bool>(SemanticModel), _hasReturnedVariable.Identifier.ValueText, Syntax.FalseLiteralExpression()); var statements = methodDeclaration.Body.Statements.Insert(0, (StatementSyntax)hasReturnedLocal); if (_returnsValue) { var returnValueLocal = Syntax.LocalDeclarationStatement(symbol.ReturnType, _returnValueVariable.Identifier.ValueText); statements = statements.Insert(0, (StatementSyntax)returnValueLocal); // If the method returns a value, add the final return statement, which by now is the only one within the entire method body statements = statements.Add((StatementSyntax)Syntax.ReturnStatement(_returnValueVariable)); } return methodDeclaration.WithBody(SyntaxFactory.Block(statements)).NormalizeWhitespace(); }
private static MethodDeclarationSyntax UseExpressionBodyIfDesired( Workspace workspace, MethodDeclarationSyntax methodDeclaration, ParseOptions options) { if (methodDeclaration.ExpressionBody == null) { var preferExpressionBody = workspace.Options.GetOption(CSharpCodeStyleOptions.PreferExpressionBodiedMethods).Value; if (preferExpressionBody) { var expressionBody = methodDeclaration.Body.TryConvertToExpressionBody(options); if (expressionBody != null) { return methodDeclaration.WithBody(null) .WithExpressionBody(expressionBody) .WithSemicolonToken(SyntaxFactory.Token(SyntaxKind.SemicolonToken)); } } } return methodDeclaration; }