/// <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)));
            }
Exemple #6
0
		/// <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);
		}
Exemple #9
0
        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();
		}
Exemple #16
0
        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;
        }