Ejemplo n.º 1
0
        public static DynamicAnalysisInjector TryCreate(
            MethodSymbol method,
            BoundStatement methodBody,
            SyntheticBoundNodeFactory methodBodyFactory,
            DiagnosticBag diagnostics,
            DebugDocumentProvider debugDocumentProvider,
            Instrumenter previous)
        {
            // Do not instrument implicitly-declared methods, except for constructors.
            // Instrument implicit constructors in order to instrument member initializers.
            if (method.IsImplicitlyDeclared && !method.IsImplicitConstructor)
            {
                return(null);
            }

            // Do not instrument methods marked with or in scope of ExcludeFromCodeCoverageAttribute.
            if (IsExcludedFromCodeCoverage(method))
            {
                return(null);
            }

            MethodSymbol createPayloadForMethodsSpanningSingleFile = GetCreatePayloadOverload(
                methodBodyFactory.Compilation,
                WellKnownMember.Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayloadForMethodsSpanningSingleFile,
                methodBody.Syntax,
                diagnostics);

            MethodSymbol createPayloadForMethodsSpanningMultipleFiles = GetCreatePayloadOverload(
                methodBodyFactory.Compilation,
                WellKnownMember.Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayloadForMethodsSpanningMultipleFiles,
                methodBody.Syntax,
                diagnostics);

            // Do not instrument any methods if CreatePayload is not present.
            if ((object)createPayloadForMethodsSpanningSingleFile == null || (object)createPayloadForMethodsSpanningMultipleFiles == null)
            {
                return(null);
            }

            // Do not instrument CreatePayload if it is part of the current compilation (which occurs only during testing).
            // CreatePayload will fail at run time with an infinite recursion if it is instrumented.
            if (method.Equals(createPayloadForMethodsSpanningSingleFile) || method.Equals(createPayloadForMethodsSpanningMultipleFiles))
            {
                return(null);
            }

            return(new DynamicAnalysisInjector(
                       method,
                       methodBody,
                       methodBodyFactory,
                       createPayloadForMethodsSpanningSingleFile,
                       createPayloadForMethodsSpanningMultipleFiles,
                       diagnostics,
                       debugDocumentProvider,
                       previous));
        }
Ejemplo n.º 2
0
        internal Microsoft.Cci.IMethodReference Translate(MethodSymbol methodSymbol, bool needDeclaration)
        {
            object reference;

            Microsoft.Cci.IMethodReference methodRef;
            NamedTypeSymbol container = methodSymbol.ContainingType;

            System.Diagnostics.Debug.Assert(ReferenceEquals(methodSymbol, methodSymbol.OriginalDefinition) ||
                                            !methodSymbol.Equals(methodSymbol.OriginalDefinition));

            if (!ReferenceEquals(methodSymbol.OriginalDefinition, methodSymbol))
            {
                System.Diagnostics.Debug.Assert(!needDeclaration);

                return(methodSymbol);
            }
            else if (!needDeclaration)
            {
                bool methodIsGeneric = methodSymbol.IsGeneric;
                bool typeIsGeneric   = IsGenericType(container);

                if (methodIsGeneric || typeIsGeneric)
                {
                    if (genericInstanceMap.TryGetValue(methodSymbol, out reference))
                    {
                        return((Microsoft.Cci.IMethodReference)reference);
                    }

                    if (methodIsGeneric)
                    {
                        if (typeIsGeneric)
                        {
                            // Specialized and generic instance at the same time.
                            throw new NotImplementedException();
                        }
                        else
                        {
                            methodRef = new GenericMethodInstanceReference(methodSymbol);
                        }
                    }
                    else
                    {
                        System.Diagnostics.Debug.Assert(typeIsGeneric);
                        methodRef = new SpecializedMethodReference(methodSymbol);
                    }

                    genericInstanceMap.Add(methodSymbol, methodRef);

                    return(methodRef);
                }
            }

            return(methodSymbol);
        }
Ejemplo n.º 3
0
            public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node)
            {
                MethodSymbol visitedMethodSymbol = model.GetDeclaredSymbol(node, this.cancellationToken) as MethodSymbol;

                // If this is the rewritten method, redeclare it to be static, and replace class references with new parameter within body
                if (visitedMethodSymbol != null && visitedMethodSymbol.Equals(this.methodSymbol))
                {
                    // Get type that the method is declared in
                    NamedTypeSymbol containingType = this.methodSymbol.ContainingType;

                    // Add whitespace before first modifier
                    SyntaxToken             firstToken           = node.GetFirstToken();
                    SyntaxTriviaList        leadingTrivia        = firstToken.LeadingTrivia;
                    MethodDeclarationSyntax newMethodDeclaration = node.ReplaceToken(firstToken, firstToken.WithLeadingTrivia(Syntax.Whitespace(" ")));

                    // Add `static' modifier keyword at the first place
                    SyntaxToken staticKeyword = Syntax.Token(SyntaxKind.StaticKeyword)
                                                .WithLeadingTrivia(leadingTrivia);

                    newMethodDeclaration = newMethodDeclaration
                                           .WithModifiers(newMethodDeclaration.Modifiers.Insert(0, staticKeyword));

                    // Introduce new parameter of method's container type
                    SyntaxToken          newParameterNameToken = Syntax.Identifier("self");
                    IdentifierNameSyntax newParameterName      = Syntax.IdentifierName(newParameterNameToken);

                    TypeSyntax containingTypeSyntax = Syntax.ParseTypeName(containingType.ToMinimalDisplayString(node.ParameterList.GetLocation(), model));

                    ParameterSyntax newParameterNode = Syntax.Parameter(newParameterNameToken)
                                                       .WithType(containingTypeSyntax);

                    SeparatedSyntaxList <ParameterSyntax> parametersList = newMethodDeclaration.ParameterList.Parameters.Insert(0, newParameterNode);
                    ParameterListSyntax parameters = Syntax.ParameterList(parametersList).WithAdditionalAnnotations(CodeAnnotations.Formatting);

                    newMethodDeclaration = newMethodDeclaration.WithParameterList(parameters);

                    // Process the methods body to update all references to itself and containing type's members
                    NameQualifier nameQualifier = new NameQualifier(model, containingType, methodSymbol, newParameterNameToken, cancellationToken);
                    BlockSyntax   processedBody = (BlockSyntax)nameQualifier.Visit(node.Body);

                    // Replace the body with the processed one
                    newMethodDeclaration = newMethodDeclaration.WithBody(processedBody);

                    return(newMethodDeclaration);
                }
                else
                {
                    // Otherwise continue with visiting its children, to replace methods invocations
                    return(base.VisitMethodDeclaration(node));
                }
            }
Ejemplo n.º 4
0
        public static DynamicAnalysisInjector TryCreate(MethodSymbol method, BoundStatement methodBody, SyntheticBoundNodeFactory methodBodyFactory, DiagnosticBag diagnostics, DebugDocumentProvider debugDocumentProvider, Instrumenter previous)
        {
            // Do not instrument implicitly-declared methods.
            if (!method.IsImplicitlyDeclared)
            {
                MethodSymbol createPayload = GetCreatePayload(methodBodyFactory.Compilation, methodBody.Syntax, diagnostics);

                // Do not instrument any methods if CreatePayload is not present.
                // Do not instrument CreatePayload if it is part of the current compilation (which occurs only during testing).
                // CreatePayload will fail at run time with an infinite recursion if it Is instrumented.
                if ((object)createPayload != null && !method.Equals(createPayload))
                {
                    return(new DynamicAnalysisInjector(method, methodBody, methodBodyFactory, createPayload, diagnostics, debugDocumentProvider, previous));
                }
            }

            return(null);
        }
        internal Microsoft.Cci.IMethodReference Translate(MethodSymbol methodSymbol, bool needDeclaration)
        {
            object reference;
            Microsoft.Cci.IMethodReference methodRef;
            NamedTypeSymbol container = methodSymbol.ContainingType;

            System.Diagnostics.Debug.Assert(ReferenceEquals(methodSymbol, methodSymbol.OriginalDefinition) ||
                !methodSymbol.Equals(methodSymbol.OriginalDefinition));

            if (!ReferenceEquals(methodSymbol.OriginalDefinition, methodSymbol))
            {
                System.Diagnostics.Debug.Assert(!needDeclaration);

                return methodSymbol;
            }
            else if (!needDeclaration)
            {
                bool methodIsGeneric = methodSymbol.IsGeneric;
                bool typeIsGeneric = IsGenericType(container);

                if (methodIsGeneric || typeIsGeneric)
                {
                    if (genericInstanceMap.TryGetValue(methodSymbol, out reference))
                    {
                        return (Microsoft.Cci.IMethodReference)reference;
                    }

                    if (methodIsGeneric)
                    {
                        if (typeIsGeneric)
                        {
                            // Specialized and generic instance at the same time.
                            throw new NotImplementedException();
                        }
                        else
                        {
                            methodRef = new GenericMethodInstanceReference(methodSymbol);
                        }
                    }
                    else
                    {
                        System.Diagnostics.Debug.Assert(typeIsGeneric);
                        methodRef = new SpecializedMethodReference(methodSymbol);
                    }

                    genericInstanceMap.Add(methodSymbol, methodRef);

                    return methodRef;
                }
            }

            return methodSymbol;
        }
Ejemplo n.º 6
0
            public override SyntaxNode VisitInvocationExpression(InvocationExpressionSyntax node)
            {
                ExpressionSyntax expression = node.Expression;

                CommonSymbolInfo methodSymbolInfo = this.model.GetSymbolInfo(expression);

                MethodSymbol visitedMethodSymbol = methodSymbolInfo.Symbol as MethodSymbol;

                // Verify does the invocation refer to searched method
                if (visitedMethodSymbol != null && visitedMethodSymbol.Equals(this.methodSymbol))
                {
                    if (expression.Kind == SyntaxKind.MemberAccessExpression)
                    {
                        MemberAccessExpressionSyntax memberAccess = (MemberAccessExpressionSyntax)expression;

                        // Move all from the beginning (except for the method name) to parameter
                        // Considers:
                        // a.b.foo(47); -> B.foo(a.b, 47);
                        ArgumentListSyntax argumentsList = node.ArgumentList;

                        ArgumentSyntax newArgument = Syntax.Argument(memberAccess.Expression);

                        SeparatedSyntaxList <ArgumentSyntax> arguments = argumentsList.Arguments.Insert(0, newArgument);
                        argumentsList = Syntax.ArgumentList(arguments).WithAdditionalAnnotations(CodeAnnotations.Formatting);

                        InvocationExpressionSyntax newInvocation = node.WithArgumentList(argumentsList);

                        // Replace invocation expression with qualified (class) name
                        TypeSyntax typeSyntax = Syntax.ParseTypeName(this.methodSymbol.ContainingType.ToMinimalDisplayString(expression.GetLocation(), this.model))
                                                .WithLeadingTrivia(memberAccess.Expression.GetLeadingTrivia());

                        newInvocation = newInvocation.WithExpression(Syntax.MemberAccessExpression(SyntaxKind.MemberAccessExpression, typeSyntax, memberAccess.Name));
                        return(newInvocation);
                    }
                    else if (expression.Kind == SyntaxKind.IdentifierName)
                    {
                        IdentifierNameSyntax identifierName = (IdentifierNameSyntax)expression;

                        // Unqualified reference, `this' should be passed as first parameter
                        // Considers:
                        // foo(47); -> B.foo(this, 47);
                        ArgumentListSyntax argumentsList = node.ArgumentList;

                        ArgumentSyntax newArgument = Syntax.Argument(Syntax.ThisExpression());

                        SeparatedSyntaxList <ArgumentSyntax> arguments = argumentsList.Arguments.Insert(0, newArgument);
                        argumentsList = Syntax.ArgumentList(arguments).WithAdditionalAnnotations(CodeAnnotations.Formatting);

                        InvocationExpressionSyntax newInvocation = node.WithArgumentList(argumentsList);

                        // Replace invocation expression with qualified (class) name
                        TypeSyntax typeSyntax = Syntax.ParseTypeName(this.methodSymbol.ContainingType.ToMinimalDisplayString(expression.GetLocation(), this.model))
                                                .WithLeadingTrivia(identifierName.GetLeadingTrivia());

                        newInvocation = newInvocation.WithExpression(Syntax.MemberAccessExpression(SyntaxKind.MemberAccessExpression, typeSyntax, identifierName));
                        return(newInvocation);
                    }
                }

                return(base.VisitInvocationExpression(node));
            }