コード例 #1
0
        public override CSharpSyntaxNode VisitCompilationUnit(VbSyntax.CompilationUnitSyntax node)
        {
            var cSharpSyntaxNode = (CsSyntax.CompilationUnitSyntax)base.VisitCompilationUnit(node);

            cSharpSyntaxNode = cSharpSyntaxNode.WithEndOfFileToken(
                cSharpSyntaxNode.EndOfFileToken.WithConvertedLeadingTriviaFrom(node.EndOfFileToken));

            return(TriviaConverter.IsAllTriviaConverted()
                ? cSharpSyntaxNode
                : cSharpSyntaxNode.WithAppendedTrailingTrivia(SyntaxFactory.Comment("/* Some trivia (e.g. comments) could not be converted */")));
        }
コード例 #2
0
        public static T WithCsTrailingErrorComment <T>(this T dummyDestNode,
                                                       VisualBasicSyntaxNode sourceNode,
                                                       Exception exception) where T : CSharpSyntaxNode
        {
            var errorDirective   = SyntaxFactory.ParseTrailingTrivia($"#error Cannot convert {sourceNode.GetType().Name} - see comment for details{Environment.NewLine}");
            var errorDescription = sourceNode.DescribeConversionError(exception);
            var commentedText    = "/* " + errorDescription + " */";
            var trailingTrivia   = SyntaxFactory.TriviaList(errorDirective.Concat(SyntaxFactory.Comment(commentedText)));

            return(dummyDestNode
                   .WithTrailingTrivia(trailingTrivia)
                   .WithAdditionalAnnotations(new SyntaxAnnotation(AnnotationConstants.ConversionErrorAnnotationKind, exception.ToString())));
        }
コード例 #3
0
        private static IEnumerable <SyntaxTrivia> ConvertVBTrivia(SyntaxTrivia t)
        {
            if (t.IsKind(VBSyntaxKind.CommentTrivia))
            {
                yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.SingleLineCommentTrivia, $"// {t.GetCommentText()}"));

                yield break;
            }
            if (t.IsKind(VBSyntaxKind.DocumentationCommentTrivia))
            {
                var previousWhitespace = t.GetPreviousTrivia(t.SyntaxTree, CancellationToken.None).ToString().Trim('\r', '\n');
                var commentTextLines   = t.GetCommentText().Replace("\r\n", "\n").Replace("\r", "\n").Split('\n');
                var outputCommentText  = "/// " + String.Join($"\r\n{previousWhitespace}/// ", commentTextLines) + Environment.NewLine;
                yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.SingleLineCommentTrivia, outputCommentText)); //It's always single line...even when it has multiple lines

                yield break;
            }

            if (t.IsKind(VBSyntaxKind.WhitespaceTrivia))
            {
                yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.WhitespaceTrivia, t.ToString()));

                yield break;
            }

            if (t.IsKind(VBSyntaxKind.EndOfLineTrivia))
            {
                // Mapping one to one here leads to newlines appearing where the natural line-end was in VB.
                // e.g. ToString\r\n()
                // Because C Sharp needs those brackets. Handling each possible case of this is far more effort than it's worth.
                yield return(SyntaxFactory.SyntaxTrivia(CSSyntaxKind.EndOfLineTrivia, t.ToString()));

                yield break;
            }

            //Each of these would need its own method to recreate for C# with the right structure probably so let's just warn about them for now.
            var convertedKind = t.GetCSKind();

            yield return(convertedKind.HasValue
                ? SyntaxFactory.Comment($"/* TODO ERROR: Skipped {convertedKind.Value} */")
                : default(SyntaxTrivia));
        }
        private static Document ConstructorWithCommentPrepended(
            Document document,
            SyntaxNode root,
            ClassDeclarationSyntax @class,
            ConstructorDeclarationSyntax constructor,
            string errorMessage)
        {
            var commentWithEndOfLine  = new[] { SF.Comment("//" + errorMessage) };
            var existingLeadingTrivia = constructor.GetLeadingTrivia();
            var combinedTrivia        = SF.TriviaList(
                Enumerable.Concat(commentWithEndOfLine, existingLeadingTrivia));

            var constructorWithNewLeadingTrivia = constructor.WithLeadingTrivia(combinedTrivia);

            var newClass        = @class.ReplaceNode(constructor, constructorWithNewLeadingTrivia);
            var newDocumentRoot = root.ReplaceNode(@class, newClass);
            var newDocument     = document.WithSyntaxRoot(newDocumentRoot);

            return(newDocument);
        }
        private static Document ClassDeclWithCommentAtOpeningBrace(
            Document document,
            SyntaxNode root,
            ClassDeclarationSyntax type,
            string errorMessage)
        {
            var explanatoryCommentTrivia = SF.Comment("//" + errorMessage);
            var endOfLineTrivia          = SF.EndOfLine("\r\n");
            var leadingTrivia            = @type.OpenBraceToken.LeadingTrivia;

            var typeUpdatedWithExplanatoryComment = @type.WithOpenBraceToken(
                SF.Token(
                    leadingTrivia,
                    SyntaxKind.OpenBraceToken,
                    SF.TriviaList(
                        explanatoryCommentTrivia,
                        endOfLineTrivia)));

            var newDocumentRoot = root.ReplaceNode(@type, typeUpdatedWithExplanatoryComment);
            var newDocument     = document.WithSyntaxRoot(newDocumentRoot);

            return(newDocument);
        }
コード例 #6
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.GetTypeInfo().GetCustomAttribute <ImmutableAttribute>() != null)
            {
                // Immutable types do not require copying.
                var typeName = type.GetParseableName(new TypeFormattingOptions(includeGlobal: false));
                var comment  = SF.Comment($"// No deep copy required since {typeName} is marked with the [Immutable] attribute.");
                body.Add(SF.ReturnStatement(originalVariable).WithLeadingTrivia(comment));
            }
            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))))));

                // Record this serialization.
                Expression <Action <ICopyContext> > recordObject =
                    ctx => ctx.RecordCopy(default(object), default(object));
                var context = SF.IdentifierName("context");
                body.Add(
                    SF.ExpressionStatement(
                        recordObject.Invoke(context)
                        .AddArgumentListArguments(SF.Argument(originalVariable), SF.Argument(resultVariable))));

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

                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()),
                     SF.Parameter(SF.Identifier("context")).WithType(typeof(ICopyContext).GetTypeSyntax()))
                 .AddBodyStatements(body.ToArray())
                 .AddAttributeLists(
                     SF.AttributeList().AddAttributes(SF.Attribute(typeof(CopierMethodAttribute).GetNameSyntax()))));
        }
コード例 #7
0
        public Task <SyntaxList <MemberDeclarationSyntax> > GenerateAsync(TransformationContext context, IProgress <Diagnostic> progress, CancellationToken cancellationToken)
        {
            m_context = context;

            m_class = m_context.ProcessingNode as ClassDeclarationSyntax;

            m_sym = m_context.SemanticModel.GetDeclaredSymbol(m_class);

            m_baseSym = m_sym.BaseType;

            var baseIsObject = m_baseSym.SpecialType == SpecialType.System_Object;


            var results = SF.List <MemberDeclarationSyntax>();

            ClassDeclarationSyntax copy = null;

            var applyToClassIdentifier = m_class.Identifier;

            if (m_class != null)
            {
                var fieldsComment = "version: 1\n";

                foreach (var member in m_class.Members)
                {
                    var field = member as FieldDeclarationSyntax;
                    if (field != null)
                    {
                        var decl = field.Declaration;

                        var type = decl.Type;

                        foreach (var v in decl.Variables)
                        {
                            m_fields.Add(v, type);
                            fieldsComment += $"({type.GetType().Name}){type} ({v.GetType().Name}){v}\n\r";
                        }
                    }
                }

                var leadingTrivia  = $"{fieldsComment}\r\n";
                var trailingTrivia = $"";

                leadingTrivia += $"\r\nViewers\r\n";

                foreach (var mem in m_context.Compilation.GlobalNamespace.GetMembers())
                {
                    GetClasses(ref m_dictClasses, mem);
                }

                leadingTrivia += $"Total Classes {m_dictClasses.Count}\r\n";


                foreach (var kvp in m_dictClasses)
                {
                    if (kvp.Key.Contains("View"))
                    {
                        var type = kvp.Value;

                        if (type.ContainingNamespace.Name == "net")
                        {
                            if (type.BaseType.Name == "View")
                            {
                                leadingTrivia += $"View class found {kvp.Value.ToDisplayString()}\r\n";
                            }
                        }
                    }
                }



                //var newUsing = SF.UsingDirective( SF.IdentifierName( "" ) );
                SyntaxList <MemberDeclarationSyntax> withMembers = new SyntaxList <MemberDeclarationSyntax>();

                try
                {
                    withMembers = CreateDefault();
                }
                catch (Exception ex)
                {
                    trailingTrivia += $"Exception running CreateDefault [{ex.Message}]";
                }


                if (baseIsObject)
                {
                    withMembers = withMembers.AddRange(CreateVersion());
                }

                withMembers = withMembers.AddRange(CreateProtectedConstructors());


                try
                {
                    withMembers = withMembers.AddRange(CreateWithFunctions());
                }
                catch (Exception ex)
                {
                    trailingTrivia += $"Exception running CreateWithFunctions [{ex.Message}]";
                }



                withMembers = withMembers.AddRange(CreateCreateFunctions());

                var leadingTriviaComment  = SF.Comment($"/*\r\n{leadingTrivia}\r\n*/");
                var trailingTriviaComment = SF.Comment($"/*\r\n{trailingTrivia}\r\n*/");

                copy = SF.ClassDeclaration(applyToClassIdentifier)
                       .WithTypeParameterList(m_class.TypeParameterList)
                       .WithModifiers(SyntaxTokenList.Create(SF.Token(SyntaxKind.PartialKeyword)))
                       .WithLeadingTrivia(leadingTriviaComment)
                       .WithTrailingTrivia(trailingTriviaComment)
                       .WithMembers(withMembers);
            }
            else
            {
                // TODO ERROR
            }


            if (copy != null)
            {
                results = results.Add(copy);
            }

            return(Task.FromResult(results));
        }
コード例 #8
0
 internal static StatementSyntax EmptyStatementWithComment(string comment)
 {
     return
         (SF.EmptyStatement(SF.Token(SyntaxKind.SemicolonToken)).WithTrailingTrivia(
              SF.Comment(string.Concat("/*", comment, "*/"))));
 }
コード例 #9
0
        public static T WithCsTrailingWarningComment <T>(this T dummyDestNode, string warning, string addtlInfo,
                                                         CSharpSyntaxNode convertedNode
                                                         ) where T : CSharpSyntaxNode
        {
            var warningDirective   = SyntaxFactory.ParseTrailingTrivia($"#warning {warning}{Environment.NewLine}");
            var warningDescription = convertedNode.DescribeConversionWarning(addtlInfo);
            var commentedText      = "/* " + warningDescription + " */";
            var trailingTrivia     = SyntaxFactory.TriviaList(warningDirective.Concat(SyntaxFactory.Comment(commentedText)));

            return(dummyDestNode
                   .WithTrailingTrivia(trailingTrivia));
        }