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 */"))); }
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()))); }
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); }
/// <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())))); }
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)); }
internal static StatementSyntax EmptyStatementWithComment(string comment) { return (SF.EmptyStatement(SF.Token(SyntaxKind.SemicolonToken)).WithTrailingTrivia( SF.Comment(string.Concat("/*", comment, "*/")))); }
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)); }