public override ExpressionSyntax VisitNamespace(INamespaceSymbol symbol)
            {
                var syntax = AddInformationTo(symbol.Name.ToIdentifierName(), symbol);

                if (symbol.ContainingNamespace == null)
                {
                    return(syntax);
                }

                if (symbol.ContainingNamespace.IsGlobalNamespace)
                {
                    return(AddInformationTo(
                               SyntaxFactory.AliasQualifiedName(
                                   SyntaxFactory.IdentifierName(
                                       SyntaxFactory.Token(SyntaxKind.GlobalKeyword)
                                       ),
                                   syntax
                                   ),
                               symbol
                               ));
                }
                else
                {
                    var container = symbol.ContainingNamespace.Accept(this) !;
                    return(CreateMemberAccessExpression(symbol, container, syntax));
                }
            }
 /// <summary>
 /// We always unilaterally add "global::" to all named types/namespaces.  This
 /// will then be trimmed off if possible by calls to
 /// <see cref="Simplifier.ReduceAsync(Document, OptionSet, CancellationToken)"/>
 /// </summary>
 private TypeSyntax AddGlobalAlias(INamespaceOrTypeSymbol symbol, SimpleNameSyntax syntax)
 {
     return(AddInformationTo(
                SyntaxFactory.AliasQualifiedName(
                    CreateGlobalIdentifier(),
                    syntax), symbol));
 }
        /// <summary>
        /// Returns <see cref="ParenthesizedExpressionSyntax"/>  representing parenthesized binary expression of  <paramref name="bindingFlags"/>.
        /// </summary>
        /// <param name="operationKind">
        /// The kind of the binary expression.
        /// </param>
        /// <param name="bindingFlags">
        /// The binding flags.
        /// </param>
        /// <returns>
        /// <see cref="ParenthesizedExpressionSyntax"/> representing parenthesized binary expression of <paramref name="bindingFlags"/>.
        /// </returns>
        public static ParenthesizedExpressionSyntax GetBindingFlagsParenthesizedExpressionSyntax(SyntaxKind operationKind, params BindingFlags[] bindingFlags)
        {
            if (bindingFlags.Length < 2)
            {
                throw new ArgumentOutOfRangeException(
                          "bindingFlags",
                          string.Format("Can't create parenthesized binary expression with {0} arguments", bindingFlags.Length));
            }

            var flags = SyntaxFactory.AliasQualifiedName(SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), SyntaxFactory.IdentifierName("System")).Member("Reflection").Member("BindingFlags");
            var bindingFlagsBinaryExpression = SyntaxFactory.BinaryExpression(
                operationKind,
                flags.Member(bindingFlags[0].ToString()),
                flags.Member(bindingFlags[1].ToString()));

            for (var i = 2; i < bindingFlags.Length; i++)
            {
                bindingFlagsBinaryExpression = SyntaxFactory.BinaryExpression(
                    operationKind,
                    bindingFlagsBinaryExpression,
                    flags.Member(bindingFlags[i].ToString()));
            }

            return(SyntaxFactory.ParenthesizedExpression(bindingFlagsBinaryExpression));
        }
 private static QualifiedNameSyntax CreateSystemObject()
 {
     return(SyntaxFactory.QualifiedName(
                SyntaxFactory.AliasQualifiedName(
                    CreateGlobalIdentifier(),
                    SyntaxFactory.IdentifierName("System")),
                SyntaxFactory.IdentifierName("Object")));
 }
            public override ExpressionSyntax VisitNamedType(INamedTypeSymbol symbol)
            {
                if (
                    TypeSyntaxGeneratorVisitor.TryCreateNativeIntegerType(
                        symbol,
                        out var typeSyntax
                        )
                    )
                {
                    return(typeSyntax);
                }

                typeSyntax = TypeSyntaxGeneratorVisitor.Create().CreateSimpleTypeSyntax(symbol);
                if (!(typeSyntax is SimpleNameSyntax))
                {
                    return(typeSyntax);
                }

                var simpleNameSyntax = (SimpleNameSyntax)typeSyntax;

                if (symbol.ContainingType != null)
                {
                    if (symbol.ContainingType.TypeKind == TypeKind.Submission)
                    {
                        return(simpleNameSyntax);
                    }
                    else
                    {
                        var container = symbol.ContainingType.Accept(this) !;
                        return(CreateMemberAccessExpression(symbol, container, simpleNameSyntax));
                    }
                }
                else if (symbol.ContainingNamespace != null)
                {
                    if (symbol.ContainingNamespace.IsGlobalNamespace)
                    {
                        if (symbol.TypeKind != TypeKind.Error)
                        {
                            return(AddInformationTo(
                                       SyntaxFactory.AliasQualifiedName(
                                           SyntaxFactory.IdentifierName(
                                               SyntaxFactory.Token(SyntaxKind.GlobalKeyword)
                                               ),
                                           simpleNameSyntax
                                           ),
                                       symbol
                                       ));
                        }
                    }
                    else
                    {
                        var container = symbol.ContainingNamespace.Accept(this) !;
                        return(CreateMemberAccessExpression(symbol, container, simpleNameSyntax));
                    }
                }

                return(simpleNameSyntax);
            }
        public override SyntaxNode MakeSyntaxNode()
        {
            var res = SyntaxFactory.AliasQualifiedName(Alias, ColonColonToken, Name);

// if (Arity != null) res = res.WithArity(Arity);
// if (IsVar != null) res = res.WithIsVar(IsVar);
            IsChanged = false;
            return(res);
        }
            public override TypeSyntax VisitNamedType(INamedTypeSymbol symbol)
            {
                var typeSyntax = CreateSimpleTypeSyntax(symbol);

                if (!(typeSyntax is SimpleNameSyntax))
                {
                    return(typeSyntax);
                }

                var simpleNameSyntax = (SimpleNameSyntax)typeSyntax;

                if (symbol.ContainingType != null)
                {
                    if (symbol.ContainingType.TypeKind == TypeKind.Submission)
                    {
                        return(typeSyntax);
                    }
                    else
                    {
                        var containingTypeSyntax = symbol.ContainingType.Accept(this);
                        if (containingTypeSyntax is NameSyntax)
                        {
                            return(AddInformationTo(
                                       SyntaxFactory.QualifiedName((NameSyntax)containingTypeSyntax, simpleNameSyntax),
                                       symbol));
                        }
                        else
                        {
                            return(AddInformationTo(simpleNameSyntax, symbol));
                        }
                    }
                }
                else if (symbol.ContainingNamespace != null)
                {
                    if (symbol.ContainingNamespace.IsGlobalNamespace)
                    {
                        if (symbol.TypeKind != TypeKind.Error)
                        {
                            return(AddInformationTo(
                                       SyntaxFactory.AliasQualifiedName(
                                           SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)),
                                           simpleNameSyntax), symbol));
                        }
                    }
                    else
                    {
                        var container = symbol.ContainingNamespace.Accept(this);
                        return(AddInformationTo(SyntaxFactory.QualifiedName(
                                                    (NameSyntax)container,
                                                    simpleNameSyntax), symbol));
                    }
                }

                return(simpleNameSyntax);
            }
Exemple #8
0
 internal static NameSyntax PrependExternAlias(IdentifierNameSyntax externAliasSyntax, NameSyntax nameSyntax)
 {
     if (nameSyntax is QualifiedNameSyntax qualifiedNameSyntax)
     {
         return(SyntaxFactory.QualifiedName(
                    PrependExternAlias(externAliasSyntax, qualifiedNameSyntax.Left),
                    qualifiedNameSyntax.Right));
     }
     else
     {
         return(SyntaxFactory.AliasQualifiedName(externAliasSyntax, (SimpleNameSyntax)nameSyntax));
     }
 }
Exemple #9
0
        public override SyntaxNode VisitIdentifierName(IdentifierNameSyntax node)
        {
            if (_ignore.Contains(node.ToString()))
            {
                return(node);
            }

            if (node.Parent != null)
            {
                return(node);
            }

            return(SyntaxFactory.AliasQualifiedName(SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), node));
        }
Exemple #10
0
        /// <summary>
        /// Converts a <see cref="Type"/> to a <see cref="TypeSyntax"/>.
        /// </summary>
        /// <param name="t">The type</param>
        /// <param name="useGlobalAlias">Whether the to qualify type names with "global::"</param>
        /// <returns>A <see cref="TypeSyntax"/> representing the type.</returns>
        public static TypeSyntax ToTypeSyntax(this Type t, bool useGlobalAlias = false)
        {
            if (t == typeof(void))
            {
                return(SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.VoidKeyword)));
            }

            if (t.IsGenericParameter)
            {
                return(SyntaxFactory.IdentifierName(t.Name));
            }

            if (t.IsArray)
            {
                return(SyntaxFactory.ArrayType(
                           t.GetElementType().ToTypeSyntax(useGlobalAlias),
                           SyntaxFactory.SingletonList(
                               SyntaxFactory.ArrayRankSpecifier(
                                   SyntaxFactory.SingletonSeparatedList <ExpressionSyntax>(
                                       SyntaxFactory.OmittedArraySizeExpression())))));
            }

            if (t.IsPointer)
            {
                return(SyntaxFactory.PointerType(t.GetElementType().ToTypeSyntax(useGlobalAlias)));
            }

            TypeSyntax qualification = t.IsNested
                ? t.DeclaringType.ToTypeSyntax(useGlobalAlias)
                : t.Namespace.Split('.')
                                       .Select(s => (NameSyntax)SyntaxFactory.IdentifierName(s))
                                       .Aggregate((acc, next) =>
            {
                // see if we should qualify with global::
                NameSyntax left = useGlobalAlias && acc is IdentifierNameSyntax identifier
                            ? SyntaxFactory.AliasQualifiedName(SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)), identifier)
                            : acc;

                return(SyntaxFactory.QualifiedName(left, (SimpleNameSyntax)next));
            });

            SimpleNameSyntax name = t.IsGenericType
                ? SyntaxFactory.GenericName(t.Name.Substring(0, t.Name.IndexOf('`', StringComparison.Ordinal)))
                                    .WithTypeArgumentList(SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(t.GenericTypeArguments.Select(typeArg => typeArg.ToTypeSyntax(useGlobalAlias)))))
                : (SimpleNameSyntax)SyntaxFactory.IdentifierName(t.Name);

            return(SyntaxFactory.QualifiedName((NameSyntax)qualification, name));
        }
        private NameSyntax AddOrReplaceAlias(NameSyntax nameSyntax, IdentifierNameSyntax alias)
        {
            if (nameSyntax is SimpleNameSyntax simpleName)
            {
                return(SyntaxFactory.AliasQualifiedName(alias, simpleName));
            }

            if (nameSyntax is QualifiedNameSyntax qualifiedName)
            {
                return(qualifiedName.WithLeft(AddOrReplaceAlias(qualifiedName.Left, alias)));
            }

            var aliasName = nameSyntax as AliasQualifiedNameSyntax;

            return(aliasName.WithAlias(alias));
        }
Exemple #12
0
        private static ExpressionSyntax GenerateMemberAccess(params string[] names)
        {
            ExpressionSyntax result = SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword));

            for (int i = 0; i < names.Length; i++)
            {
                var name = SyntaxFactory.IdentifierName(names[i]);
                if (i == 0)
                {
                    result = SyntaxFactory.AliasQualifiedName((IdentifierNameSyntax)result, name);
                }
                else
                {
                    result = SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, result, name);
                }
            }

            return(result);
        }
Exemple #13
0
        private async Task <Solution> ReplaceParameter(Diagnostic diagnostic, CodeFixContext context, CancellationToken cancellationToken)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false);

            var diagnosticSpan = diagnostic.Location.SourceSpan;
            // Find the type declaration identified by the diagnostic.
            var methodDeclaration = root.FindToken(diagnosticSpan.Start).Parent.AncestorsAndSelf().OfType <MethodDeclarationSyntax>().First();
            var parameterList     = methodDeclaration.ParameterList;

            TypeSyntax parameterTypeSyntax;

            if (parameterList.Parameters.Count > 0)
            {
                var firstParameter = parameterList.Parameters.First();
                var typeInfo       = semanticModel.GetTypeInfo(firstParameter.Type);


                if (NDPGenerator.TypeSymbolMatchesType(typeInfo.ConvertedType, Generator.OnChangingArgs, semanticModel, false))
                {
                    parameterTypeSyntax = firstParameter.Type; // if we had the correct type then its ok.
                }
                else
                {
                    var newType = firstParameter.Type;
                    if (NDPGenerator.TypeSymbolMatchesType(typeInfo.ConvertedType, typeof(NDProperty.Propertys.OnChangingArg <, ,>), semanticModel, false) ||
                        NDPGenerator.TypeSymbolMatchesType(typeInfo.ConvertedType, typeof(NDProperty.Propertys.OnChangingArg <,>), semanticModel, false))
                    {
                        newType = firstParameter.Type.DescendantNodesAndSelf().OfType <GenericNameSyntax>().First().TypeArgumentList.Arguments.First();
                    }
                    parameterTypeSyntax = SyntaxFactory.QualifiedName(
                        SyntaxFactory.QualifiedName(
                            SyntaxFactory.AliasQualifiedName(
                                SyntaxFactory.IdentifierName(
                                    SyntaxFactory.Token(SyntaxKind.GlobalKeyword)),
                                SyntaxFactory.IdentifierName(nameof(NDProperty))),
                            SyntaxFactory.IdentifierName(nameof(NDProperty.Propertys))),
                        GetTypeArgumentList(SyntaxFactory.GenericName(
                                                SyntaxFactory.Identifier(nameof(NDProperty.Propertys.OnChangingArg))), newType));
                }
            }
            else
            {
                parameterTypeSyntax = SyntaxFactory.QualifiedName(
                    SyntaxFactory.QualifiedName(
                        SyntaxFactory.AliasQualifiedName(
                            SyntaxFactory.IdentifierName(
                                SyntaxFactory.Token(SyntaxKind.GlobalKeyword)),
                            SyntaxFactory.IdentifierName(nameof(NDProperty))),
                        SyntaxFactory.IdentifierName(nameof(NDProperty.Propertys))),
                    GetTypeArgumentList(SyntaxFactory.GenericName(
                                            SyntaxFactory.Identifier(nameof(NDProperty.Propertys.OnChangingArg))),
                                        SyntaxFactory.PredefinedType(
                                            SyntaxFactory.Token(SyntaxKind.ObjectKeyword))));
            }

            var newParameterList = SyntaxFactory.ParameterList(
                SyntaxFactory.SingletonSeparatedList(
                    SyntaxFactory.Parameter(
                        SyntaxFactory.Identifier("arg"))
                    .WithType(parameterTypeSyntax)));

            root = root.ReplaceNode(parameterList, newParameterList);

            // Produce a new solution that has all references to that type renamed, including the declaration.
            var originalSolution = context.Document.Project.Solution;

            return(originalSolution.WithDocumentSyntaxRoot(context.Document.Id, root));
        }
        /// <summary>
        /// Try to get a new node to replace given node, which is a reference to a top-level type declared inside the namespce to be changed.
        /// If this reference is the right side of a qualified name, the new node returned would be the entire qualified name. Depends on
        /// whether <paramref name="newNamespaceParts"/> is provided, the name in the new node might be qualified with this new namespace instead.
        /// </summary>
        /// <param name="reference">A reference to a type declared inside the namespce to be changed, which is calculated based on results from
        /// `SymbolFinder.FindReferencesAsync`.</param>
        /// <param name="newNamespaceParts">If specified, and the reference is qualified with namespace, the namespace part of original reference
        /// will be replaced with given namespace in the new node.</param>
        /// <param name="old">The node to be replaced. This might be an ancestor of original reference.</param>
        /// <param name="new">The replacement node.</param>
        public override bool TryGetReplacementReferenceSyntax(
            SyntaxNode reference,
            ImmutableArray <string> newNamespaceParts,
            ISyntaxFactsService syntaxFacts,
            out SyntaxNode old,
            out SyntaxNode @new)
        {
            if (!(reference is SimpleNameSyntax nameRef))
            {
                old = @new = null;
                return(false);
            }

            // A few different cases are handled here:
            //
            // 1. When the reference is not qualified (i.e. just a simple name), then there's nothing need to be done.
            //    And both old and new will point to the original reference.
            //
            // 2. When the new namespace is not specified, we don't need to change the qualified part of reference.
            //    Both old and new will point to the qualified reference.
            //
            // 3. When the new namespace is "", i.e. we are moving type referenced by name here to global namespace.
            //    As a result, we need replace qualified reference with the simple name.
            //
            // 4. When the namespace is specified and not "", i.e. we are moving referenced type to a different non-global
            //    namespace. We need to replace the qualified reference with a new qualified reference (which is qualified
            //    with new namespace.)

            if (syntaxFacts.IsRightSideOfQualifiedName(nameRef))
            {
                old = nameRef.Parent;
                var aliasQualifier = GetAliasQualifierOpt(old);

                if (IsGlobalNamespace(newNamespaceParts))
                {
                    // If new namespace is "", then name will be declared in global namespace.
                    // We will replace qualified reference with simple name qualified with alias (global if it's not alias qualified)
                    var aliasNode = aliasQualifier?.ToIdentifierName() ?? SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword));
                    @new = SyntaxFactory.AliasQualifiedName(aliasNode, nameRef.WithoutTrivia());
                }
                else
                {
                    var qualifiedNamespaceName = CreateNameSyntax(newNamespaceParts, aliasQualifier, newNamespaceParts.Length - 1);
                    @new = SyntaxFactory.QualifiedName(qualifiedNamespaceName, nameRef.WithoutTrivia());
                }

                // We might lose some trivia associated with children of `outerMostNode`.
                @new = @new.WithTriviaFrom(old);
                return(true);
            }

            if (nameRef.Parent is NameMemberCrefSyntax crefName && crefName.Parent is QualifiedCrefSyntax qualifiedCref)
            {
                // This is the case where the reference is the right most part of a qualified name in `cref`.
                // for example, `<see cref="Foo.Baz.Bar"/>` and `<see cref="SomeAlias::Foo.Baz.Bar"/>`.
                // This is the form of `cref` we need to handle as a spacial case when changing namespace name or
                // changing namespace from non-global to global, other cases in these 2 scenarios can be handled in the
                // same way we handle non cref references, for example, `<see cref="SomeAlias::Foo"/>` and `<see cref="Foo"/>`.

                var container      = qualifiedCref.Container;
                var aliasQualifier = GetAliasQualifierOpt(container);

                if (IsGlobalNamespace(newNamespaceParts))
                {
                    // If new namespace is "", then name will be declared in global namespace.
                    // We will replace entire `QualifiedCrefSyntax` with a `TypeCrefSyntax`,
                    // which is a alias qualified simple name, similar to the regular case above.

                    old = qualifiedCref;
                    var aliasNode          = aliasQualifier?.ToIdentifierName() ?? SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword));
                    var aliasQualifiedNode = SyntaxFactory.AliasQualifiedName(aliasNode, nameRef.WithoutTrivia());
                    @new = SyntaxFactory.TypeCref(aliasQualifiedNode);
                }
                else
                {
                    // if the new namespace is not global, then we just need to change the container in `QualifiedCrefSyntax`,
                    // which is just a regular namespace node, no cref node involve here.
                    old  = container;
                    @new = CreateNameSyntax(newNamespaceParts, aliasQualifier, newNamespaceParts.Length - 1);
                }

                return(true);
            }

            // Simple name reference, nothing to be done.
            // The name will be resolved by adding proper import.
            old = @new = nameRef;
            return(false);
        }
Exemple #15
0
        /// <summary>
        /// Returns syntax for the deserializer method.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="fields">The fields.</param>
        /// <returns>Syntax for the deserializer method.</returns>
        private static MemberDeclarationSyntax GenerateDeserializerMethod(Type type, List <FieldInfoMember> fields)
        {
            Expression <Action> deserializeInner =
                () => SerializationManager.DeserializeInner(default(Type), default(BinaryTokenStreamReader));
            var streamParameter = SF.IdentifierName("stream");

            var resultDeclaration =
                SF.LocalDeclarationStatement(
                    SF.VariableDeclaration(type.GetTypeSyntax())
                    .AddVariables(
                        SF.VariableDeclarator("result")
                        .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type)))));
            var resultVariable = SF.IdentifierName("result");

            var body = new List <StatementSyntax> {
                resultDeclaration
            };

            // Value types cannot be referenced, only copied, so there is no need to box & record instances of value types.
            if (!type.IsValueType)
            {
                // Record the result for cyclic deserialization.
                Expression <Action> recordObject = () => DeserializationContext.Current.RecordObject(default(object));
                var currentSerializationContext  =
                    SyntaxFactory.AliasQualifiedName(
                        SF.IdentifierName(SF.Token(SyntaxKind.GlobalKeyword)),
                        SF.IdentifierName("Orleans"))
                    .Qualify("Serialization")
                    .Qualify("DeserializationContext")
                    .Qualify("Current");
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(currentSerializationContext)
                        .AddArgumentListArguments(SF.Argument(resultVariable))));
            }

            // Deserialize all fields.
            foreach (var field in fields)
            {
                var deserialized =
                    deserializeInner.Invoke()
                    .AddArgumentListArguments(
                        SF.Argument(SF.TypeOfExpression(field.Type)),
                        SF.Argument(streamParameter));
                body.Add(
                    SF.ExpressionStatement(
                        field.GetSetter(
                            resultVariable,
                            SF.CastExpression(field.Type, deserialized))));
            }

            body.Add(SF.ReturnStatement(SF.CastExpression(type.GetTypeSyntax(), resultVariable)));
            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "Deserializer")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("expected")).WithType(typeof(Type).GetTypeSyntax()),
                     SF.Parameter(SF.Identifier("stream")).WithType(typeof(BinaryTokenStreamReader).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList()
                     .AddAttributes(SF.Attribute(typeof(DeserializerMethodAttribute).GetNameSyntax()))));
        }
Exemple #16
0
        /// <summary>
        /// Returns syntax for the deep copier method.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="fields">The fields.</param>
        /// <returns>Syntax for the deep copier method.</returns>
        private static MemberDeclarationSyntax GenerateDeepCopierMethod(Type type, List <FieldInfoMember> fields)
        {
            var originalVariable = SF.IdentifierName("original");
            var inputVariable    = SF.IdentifierName("input");
            var resultVariable   = SF.IdentifierName("result");

            var body = new List <StatementSyntax>();

            if (type.GetCustomAttribute <ImmutableAttribute>() != null)
            {
                // Immutable types do not require copying.
                body.Add(SF.ReturnStatement(originalVariable));
            }
            else
            {
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("input")
                            .WithInitializer(
                                SF.EqualsValueClause(
                                    SF.ParenthesizedExpression(
                                        SF.CastExpression(type.GetTypeSyntax(), originalVariable)))))));
                body.Add(
                    SF.LocalDeclarationStatement(
                        SF.VariableDeclaration(type.GetTypeSyntax())
                        .AddVariables(
                            SF.VariableDeclarator("result")
                            .WithInitializer(SF.EqualsValueClause(GetObjectCreationExpressionSyntax(type))))));

                // Copy all members from the input to the result.
                foreach (var field in fields)
                {
                    body.Add(SF.ExpressionStatement(field.GetSetter(resultVariable, field.GetGetter(inputVariable))));
                }

                // Record this serialization.
                Expression <Action> recordObject =
                    () => SerializationContext.Current.RecordObject(default(object), default(object));
                var currentSerializationContext =
                    SyntaxFactory.AliasQualifiedName(
                        SF.IdentifierName(SF.Token(SyntaxKind.GlobalKeyword)),
                        SF.IdentifierName("Orleans"))
                    .Qualify("Serialization")
                    .Qualify("SerializationContext")
                    .Qualify("Current");
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(currentSerializationContext)
                        .AddArgumentListArguments(SF.Argument(originalVariable), SF.Argument(resultVariable))));

                body.Add(SF.ReturnStatement(resultVariable));
            }

            return
                (SF.MethodDeclaration(typeof(object).GetTypeSyntax(), "DeepCopier")
                 .AddModifiers(SF.Token(SyntaxKind.PublicKeyword), SF.Token(SyntaxKind.StaticKeyword))
                 .AddParameterListParameters(
                     SF.Parameter(SF.Identifier("original")).WithType(typeof(object).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList().AddAttributes(SF.Attribute(typeof(CopierMethodAttribute).GetNameSyntax()))));
        }
Exemple #17
0
            private ExpressionSyntax FullyQualifyIdentifierName(
                ISymbol symbol,
                ExpressionSyntax rewrittenNode,
                ExpressionSyntax originalNode,
                bool replaceNode,
                bool isInsideCref,
                bool omitLeftHandSide)
            {
                Debug.Assert(!replaceNode || rewrittenNode.Kind() == SyntaxKind.IdentifierName);

                //// TODO: use and expand Generate*Syntax(isymbol) to not depend on symbol display any more.
                //// See GenerateExpressionSyntax();

                var result = rewrittenNode;

                // only if this symbol has a containing type or namespace there is work for us to do.
                if (replaceNode || symbol.ContainingType != null || symbol.ContainingNamespace != null)
                {
                    ImmutableArray <SymbolDisplayPart> displayParts;

                    ExpressionSyntax left = null;

                    // we either need to create an AliasQualifiedName if the symbol is directly contained in the global namespace,
                    // otherwise it a QualifiedName.
                    if (!replaceNode && symbol.ContainingType == null && symbol.ContainingNamespace.IsGlobalNamespace)
                    {
                        return(rewrittenNode.CopyAnnotationsTo(
                                   SyntaxFactory.AliasQualifiedName(
                                       SyntaxFactory.IdentifierName(SyntaxFactory.Token(SyntaxKind.GlobalKeyword)),
                                       (SimpleNameSyntax)rewrittenNode.WithLeadingTrivia(null))
                                   .WithLeadingTrivia(rewrittenNode.GetLeadingTrivia())));
                    }

                    displayParts = replaceNode
                        ? symbol.ToDisplayParts(s_typeNameFormatWithGenerics)
                        : ((ISymbol)symbol.ContainingType ?? (ISymbol)symbol.ContainingNamespace).ToDisplayParts(s_typeNameFormatWithGenerics);

                    rewrittenNode = TryAddTypeArgumentToIdentifierName(rewrittenNode, symbol);

                    // Replaces the '<' token with the '{' token since we are inside crefs
                    rewrittenNode = TryReplaceAngleBracesWithCurlyBraces(rewrittenNode, isInsideCref);
                    result        = rewrittenNode;

                    if (!omitLeftHandSide)
                    {
                        left = SyntaxFactory.ParseTypeName(displayParts.ToDisplayString());

                        // Replaces the '<' token with the '{' token since we are inside crefs
                        left = TryReplaceAngleBracesWithCurlyBraces(left, isInsideCref);

                        if (replaceNode)
                        {
                            return(left
                                   .WithLeadingTrivia(rewrittenNode.GetLeadingTrivia())
                                   .WithTrailingTrivia(rewrittenNode.GetTrailingTrivia()));
                        }

                        // now create syntax for the combination of left and right syntax, or a simple replacement in case of an identifier
                        var parent        = originalNode.Parent;
                        var leadingTrivia = rewrittenNode.GetLeadingTrivia();
                        rewrittenNode = rewrittenNode.WithLeadingTrivia(null);

                        switch (parent.Kind())
                        {
                        case SyntaxKind.QualifiedName:
                            var qualifiedParent = (QualifiedNameSyntax)parent;

                            result = rewrittenNode.CopyAnnotationsTo(
                                SyntaxFactory.QualifiedName(
                                    (NameSyntax)left,
                                    (SimpleNameSyntax)rewrittenNode));

                            break;

                        case SyntaxKind.SimpleMemberAccessExpression:
                            var memberAccessParent = (MemberAccessExpressionSyntax)parent;

                            result = rewrittenNode.CopyAnnotationsTo(
                                SyntaxFactory.MemberAccessExpression(
                                    SyntaxKind.SimpleMemberAccessExpression,
                                    left,
                                    (SimpleNameSyntax)rewrittenNode));

                            break;

                        default:
                            Debug.Assert(rewrittenNode is SimpleNameSyntax);

                            if (SyntaxFacts.IsInNamespaceOrTypeContext(originalNode))
                            {
                                var right = (SimpleNameSyntax)rewrittenNode;
                                result = rewrittenNode.CopyAnnotationsTo(SyntaxFactory.QualifiedName((NameSyntax)left, right.WithAdditionalAnnotations(Simplifier.SpecialTypeAnnotation)));
                            }
                            else if (originalNode.Parent is CrefSyntax)
                            {
                                var right = (SimpleNameSyntax)rewrittenNode;
                                result = rewrittenNode.CopyAnnotationsTo(SyntaxFactory.QualifiedName((NameSyntax)left, right));
                            }
                            else
                            {
                                result = rewrittenNode.CopyAnnotationsTo(
                                    SyntaxFactory.MemberAccessExpression(
                                        SyntaxKind.SimpleMemberAccessExpression,
                                        left,
                                        (SimpleNameSyntax)rewrittenNode));
                            }

                            break;
                        }

                        result = result.WithLeadingTrivia(leadingTrivia);
                    }
                }

                return(result);
            }