Beispiel #1
0
        public static string GetContainingMethodName(CSharpSyntaxNode node)
        {
            string methodName = "none";

            var a5 = node.Ancestors()
                     .Where(x => x.IsKind(SyntaxKind.MethodDeclaration))
                     .Cast <MethodDeclarationSyntax>().ToList();

            if (a5.Count > 0)
            {
                methodName = node.Ancestors()
                             .Where(x => x.IsKind(SyntaxKind.MethodDeclaration))
                             .Cast <MethodDeclarationSyntax>().First().Identifier.ToString();
            }

            return(methodName);
        }
Beispiel #2
0
        public static string GetContainingMethodBlock(CSharpSyntaxNode node)
        {
            string methodBlock = "<METHODBLOCK>";

            var a5 = node.Ancestors()
                     .Where(x => x.IsKind(SyntaxKind.MethodDeclaration))
                     .Cast <MethodDeclarationSyntax>().ToList();

            if (a5.Count > 0)
            {
                methodBlock = node.Ancestors()
                              .Where(x => x.IsKind(SyntaxKind.MethodDeclaration))
                              .Cast <MethodDeclarationSyntax>().FirstOrDefault().ToString();
            }

            return(methodBlock);
        }
Beispiel #3
0
        private static string GetClassModuleContext(CSharpSyntaxNode node, CodeAnalysisOptions displayInfo)
        {
            string classModuleContext = "";

            if (displayInfo.DisplayClassOrModuleName)
            {
                var inClassBlock = node.Ancestors()
                                   .Where(x => x.IsKind(SyntaxKind.ClassDeclaration))
                                   .Cast <ClassDeclarationSyntax>().ToList();

                //var inModuleBlock = node.Ancestors()
                //    .Where(x => x.IsKind(SyntaxKind.ModuleBlock))
                //    .Cast<ModuleBlockSyntax>().ToList();

                string typeName   = "unknown";
                string className  = "unknown";
                string moduleName = "unknown";

                if (inClassBlock.Count > 0)
                {
                    typeName = "Class";

                    className = node.Ancestors()
                                .Where(x => x.IsKind(SyntaxKind.ClassDeclaration))
                                .Cast <ClassDeclarationSyntax>().First().Identifier.ToString();
                }

                //if (inModuleBlock.Count > 0)
                //{
                //    typeName = "Module";

                //    moduleName = node.Ancestors()
                //        .Where(x => x.IsKind(SyntaxKind.ModuleBlock))
                //        .Cast<ModuleBlockSyntax>().First().ModuleStatement.Identifier.ToString();
                //}

                classModuleContext = String.Format("{0, 8}{1,6}:({2,-25})",
                                                   classModuleContext,
                                                   typeName,
                                                   typeName == "Class" ? className : moduleName);
            }

            return(classModuleContext);
        }
Beispiel #4
0
        public async Task <GenerationResult> GenerateAsync(CSharpSyntaxNode processedNode, AttributeData markerAttribute, TransformationContext context, CancellationToken cancellationToken)
        {
            var generatedMembers = await GenerateMembersAsync(processedNode, markerAttribute, context, cancellationToken);

            var wrappedMembers = processedNode.Ancestors().Aggregate(generatedMembers, WrapInAncestor);

            return(new GenerationResult {
                Members = wrappedMembers
            });
        }
        private MethodDeclarationSyntax FindParentMethod(CSharpSyntaxNode node)
        {
            var nodes = node.Ancestors()
                        .OfType <MethodDeclarationSyntax>();

            if (nodes.Any())
            {
                return(nodes.First());
            }
            return(null); //could be called from constructor
        }
Beispiel #6
0
        private Diagnostic AnalyzeExpressionStatementBlock(CSharpSyntaxNode node)
        {
            foreach (var ancestor in node.Ancestors())
            {
                switch (ancestor)
                {
                case BlockSyntax block:
                    return(AnalyzeExpressionStatement(block.Statements, node));

                case SwitchSectionSyntax section:
                    return(AnalyzeExpressionStatement(section.Statements, node));

                case MethodDeclarationSyntax _:
                case ClassDeclarationSyntax _:
                    return(null);    // stop lookup as there is no valid ancestor anymore
                }
            }

            return(null);
        }
 /// <summary>
 /// Wraps the given syntax with the ancestors nodes provided.
 /// </summary>
 /// <param name=""></param>
 /// <param name="syntax"></param>
 /// <returns></returns>
 public static SyntaxList <MemberDeclarationSyntax> WrapWithAncestors(
     this SyntaxList <MemberDeclarationSyntax> target,
     CSharpSyntaxNode source)
 => source.Ancestors().Aggregate(target, WrapInAncestor);
        /// <summary>
        /// Gets the default value for the <paramref name="parameter"/>.
        /// </summary>
        /// <param name="syntax">
        /// A syntax node corresponding to the invocation.
        /// </param>
        /// <param name="parameter">
        /// A parameter to get the default value for.
        /// </param>
        /// <param name="enableCallerInfo">
        /// Indicates if caller info is to be enabled when processing this optional parameter.
        /// The value <see cref="ThreeState.Unknown"/> means the decision is to be made based on the shape of the <paramref name="syntax"/> node.
        /// </param>
        /// <remarks>
        /// DELIBERATE SPEC VIOLATION: When processing an implicit invocation of an <c>Add</c> method generated
        /// for an element-initializer in a collection-initializer, the parameter <paramref name="enableCallerInfo"/> 
        /// is set to <see cref="ThreeState.True"/>. It means that if the optional parameter is annotated with <see cref="CallerLineNumberAttribute"/>,
        /// <see cref="CallerFilePathAttribute"/> or <see cref="CallerMemberNameAttribute"/>, and there is no explicit argument corresponding to it,
        /// we will provide caller information as a value of this parameter.
        /// This is done to match the native compiler behavior and user requests (see http://roslyn.codeplex.com/workitem/171). This behavior
        /// does not match the C# spec that currently requires to provide caller information only in explicit invocations and query expressions.
        /// </remarks>
        private BoundExpression GetDefaultParameterValue(CSharpSyntaxNode syntax, ParameterSymbol parameter, ThreeState enableCallerInfo)
        {
            // TODO: Ideally, the enableCallerInfo parameter would be of just bool type with only 'true' and 'false' values, and all callers
            // explicitly provided one of those values, so that we do not rely on shape of syntax nodes in the rewriter. There are not many immediate callers, 
            // but often the immediate caller does not have the required information, so all possible call chains should be analyzed and possibly updated
            // to pass this information, and this might be a big task. We should consider doing this when the time permits.

            TypeSymbol parameterType = parameter.Type;
            Debug.Assert(parameter.IsOptional);
            ConstantValue defaultConstantValue = parameter.ExplicitDefaultConstantValue;
            BoundExpression defaultValue;

            SourceLocation callerSourceLocation;

            if (parameter.IsCallerLineNumber && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null))
            {
                int line = callerSourceLocation.SourceTree.GetDisplayLineNumber(callerSourceLocation.SourceSpan);
                BoundExpression lineLiteral = MakeLiteral(syntax, ConstantValue.Create(line), _compilation.GetSpecialType(SpecialType.System_Int32));

                if (parameterType.IsNullableType())
                {
                    defaultValue = MakeConversion(lineLiteral, parameterType.GetNullableUnderlyingType(), false);

                    // wrap it in a nullable ctor.
                    defaultValue = new BoundObjectCreationExpression(
                        syntax,
                        GetNullableMethod(syntax, parameterType, SpecialMember.System_Nullable_T__ctor),
                        defaultValue);
                }
                else
                {
                    defaultValue = MakeConversion(lineLiteral, parameterType, false);
                }
            }
            else if (parameter.IsCallerFilePath && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null))
            {
                string path = callerSourceLocation.SourceTree.GetDisplayPath(callerSourceLocation.SourceSpan, _compilation.Options.SourceReferenceResolver);
                BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(path), _compilation.GetSpecialType(SpecialType.System_String));
                defaultValue = MakeConversion(memberNameLiteral, parameterType, false);
            }
            else if (parameter.IsCallerMemberName && ((callerSourceLocation = GetCallerLocation(syntax, enableCallerInfo)) != null))
            {
                string memberName;

                switch (_factory.TopLevelMethod.MethodKind)
                {
                    case MethodKind.Constructor:
                    case MethodKind.StaticConstructor:
                        // See if the code is actually part of a field, field-like event or property initializer and return the name of the corresponding member.
                        var memberDecl = syntax.Ancestors().OfType<MemberDeclarationSyntax>().FirstOrDefault();

                        if (memberDecl != null)
                        {
                            BaseFieldDeclarationSyntax fieldDecl;

                            if (memberDecl.Kind() == SyntaxKind.PropertyDeclaration)
                            {
                                var propDecl = (PropertyDeclarationSyntax)memberDecl;
                                EqualsValueClauseSyntax initializer = propDecl.Initializer;

                                if (initializer != null && initializer.Span.Contains(syntax.Span))
                                {
                                    memberName = propDecl.Identifier.ValueText;
                                    break;
                                }
                            }
                            else if ((fieldDecl = memberDecl as BaseFieldDeclarationSyntax) != null)
                            {
                                memberName = null;

                                foreach (VariableDeclaratorSyntax varDecl in fieldDecl.Declaration.Variables)
                                {
                                    EqualsValueClauseSyntax initializer = varDecl.Initializer;

                                    if (initializer != null && initializer.Span.Contains(syntax.Span))
                                    {
                                        memberName = varDecl.Identifier.ValueText;
                                        break;
                                    }
                                }

                                if (memberName != null)
                                {
                                    break;
                                }
                            }
                        }

                        goto default;

                    default:
                        memberName = _factory.TopLevelMethod.GetMemberCallerName();
                        break;
                }

                BoundExpression memberNameLiteral = MakeLiteral(syntax, ConstantValue.Create(memberName), _compilation.GetSpecialType(SpecialType.System_String));
                defaultValue = MakeConversion(memberNameLiteral, parameterType, false);
            }
            else if (defaultConstantValue == ConstantValue.NotAvailable)
            {
                // There is no constant value given for the parameter in source/metadata.
                if (parameterType.IsDynamic() || parameterType.SpecialType == SpecialType.System_Object)
                {
                    // We have something like M([Optional] object x). We have special handling for such situations.
                    defaultValue = GetDefaultParameterSpecial(syntax, parameter);
                }
                else
                {
                    // The argument to M([Optional] int x) becomes default(int)
                    defaultValue = new BoundDefaultOperator(syntax, parameterType);
                }
            }
            else if (defaultConstantValue.IsNull && parameterType.IsValueType)
            {
                // We have something like M(int? x = null) or M(S x = default(S)),
                // so replace the argument with default(int?).
                defaultValue = new BoundDefaultOperator(syntax, parameterType);
            }
            else if (parameterType.IsNullableType())
            {
                // We have something like M(double? x = 1.23), so replace the argument
                // with new double?(1.23).

                TypeSymbol constantType = _compilation.GetSpecialType(defaultConstantValue.SpecialType);
                defaultValue = MakeLiteral(syntax, defaultConstantValue, constantType);

                // The parameter's underlying type might not match the constant type. For example, we might have
                // a default value of 5 (an integer) but a parameter type of decimal?.

                defaultValue = MakeConversion(defaultValue, parameterType.GetNullableUnderlyingType(), @checked: false, acceptFailingConversion: true);

                // Finally, wrap it in a nullable ctor.
                defaultValue = new BoundObjectCreationExpression(
                    syntax,
                    GetNullableMethod(syntax, parameterType, SpecialMember.System_Nullable_T__ctor),
                    defaultValue);
            }
            else if (defaultConstantValue.IsNull || defaultConstantValue.IsBad)
            {
                defaultValue = MakeLiteral(syntax, defaultConstantValue, parameterType);
            }
            else
            {
                // We have something like M(double x = 1.23), so replace the argument with 1.23.

                TypeSymbol constantType = _compilation.GetSpecialType(defaultConstantValue.SpecialType);
                defaultValue = MakeLiteral(syntax, defaultConstantValue, constantType);
                // The parameter type might not match the constant type.
                defaultValue = MakeConversion(defaultValue, parameterType, @checked: false, acceptFailingConversion: true);
            }

            return defaultValue;
        }
Beispiel #9
0
        private static string GetAncestorContext(CSharpSyntaxNode node, CodeAnalysisOptions displayInfo)
        {
            string ancestorContext = "";

            if (displayInfo.DisplayContainingBlock)
            {
                ancestorContext += GetContainingBlock(node).Kind().ToString();
            }

            if (displayInfo.InTryBlock)
            {
                var inTryBlock = node.Ancestors()
                                 .Where(x => x.IsKind(SyntaxKind.TryStatement))
                                 .Cast <TryStatementSyntax>().ToList();

                if (inTryBlock.Count > 0)
                {
                    ancestorContext += "T ";
                }
            }

            if (displayInfo.InWhileBlock)
            {
                var inDoWhileBlock = node.Ancestors()
                                     .Where(x => x.IsKind(SyntaxKind.WhileStatement))
                                     .Cast <WhileStatementSyntax>().ToList();

                if (inDoWhileBlock.Count > 0)
                {
                    ancestorContext += "W ";
                }
            }

            if (displayInfo.InForBlock)
            {
                var inForBlock = node.Ancestors()
                                 .Where(x => x.IsKind(SyntaxKind.ForStatement))
                                 .Cast <ForStatementSyntax>().ToList();

                if (inForBlock.Count > 0)
                {
                    ancestorContext += "F ";
                }
            }

            if (displayInfo.InIfBlock)
            {
                var inMultiLineIfBlock = node.Ancestors()
                                         .Where(x => x.IsKind(SyntaxKind.IfStatement))
                                         .Cast <IfStatementSyntax>().ToList();

                if (inMultiLineIfBlock.Count > 0)
                {
                    ancestorContext += "I ";
                }
            }

            if (ancestorContext.Length > 0)
            {
                ancestorContext = string.Format("{0,8}", ancestorContext);
            }

            return(ancestorContext);
        }
Beispiel #10
0
 public static SyntaxList <MemberDeclarationSyntax> WrapWithAncestors(this SyntaxList <MemberDeclarationSyntax> nodesToWrap, CSharpSyntaxNode sourceNode)
 {
     return(sourceNode.Ancestors().Aggregate(nodesToWrap, WrapInAncestor));
 }