private SyntaxNode InsertAttributeListSyntax(SyntaxNode syntaxNode, AttributeListSyntax attributeListSyntax) { SyntaxNode newSyntaxNode = null; attributeListSyntax = attributeListSyntax.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed); if (syntaxNode is InterfaceDeclarationSyntax interfaceDeclaratNode) { newSyntaxNode = interfaceDeclaratNode.AddAttributeLists(attributeListSyntax); } else if (syntaxNode is ClassDeclarationSyntax classDeclarationNode) { newSyntaxNode = classDeclarationNode.AddAttributeLists(attributeListSyntax); } else if (syntaxNode is StructDeclarationSyntax structDeclarationNode) { newSyntaxNode = structDeclarationNode.AddAttributeLists(attributeListSyntax); } else if (syntaxNode is MethodDeclarationSyntax methodDeclarationNode) { newSyntaxNode = methodDeclarationNode.AddAttributeLists(attributeListSyntax); } else if (syntaxNode is InterfaceDeclarationSyntax interfaceDeclarationNode) { newSyntaxNode = interfaceDeclarationNode.AddAttributeLists(attributeListSyntax); } return(newSyntaxNode); }
public static IEnumerable <AttributeListSyntax> SplitAttributes(AttributeListSyntax attributeList) { if (attributeList == null) { throw new ArgumentNullException(nameof(attributeList)); } SeparatedSyntaxList <AttributeSyntax> attributes = attributeList.Attributes; for (int i = 0; i < attributes.Count; i++) { AttributeListSyntax list = AttributeList(attributes[i]); if (i == 0) { list = list.WithLeadingTrivia(attributeList.GetLeadingTrivia()); } if (i == attributes.Count - 1) { list = list.WithTrailingTrivia(attributeList.GetTrailingTrivia()); } yield return(list.WithFormatterAnnotation()); } }
public static IEnumerable <AttributeListSyntax> SplitAttributes(AttributeListSyntax attributeList) { if (attributeList == null) { throw new ArgumentNullException(nameof(attributeList)); } for (int i = 0; i < attributeList.Attributes.Count; i++) { AttributeListSyntax list = SyntaxFactory.AttributeList( SyntaxFactory.SingletonSeparatedList(attributeList.Attributes[i])); if (i == 0) { list = list.WithLeadingTrivia(attributeList.GetLeadingTrivia()); } if (i == attributeList.Attributes.Count - 1) { list = list.WithTrailingTrivia(attributeList.GetTrailingTrivia()); } yield return(list); } }
public static IEnumerable <AttributeListSyntax> SplitAttributeList(AttributeListSyntax attributeList) { SeparatedSyntaxList <AttributeSyntax> attributes = attributeList.Attributes; for (int i = 0; i < attributes.Count; i++) { AttributeListSyntax list = AttributeList(attributes[i]); if (i == 0) { list = list.WithLeadingTrivia(attributeList.GetLeadingTrivia()); } if (i == attributes.Count - 1) { list = list.WithTrailingTrivia(attributeList.GetTrailingTrivia()); } yield return(list); } }
public override SyntaxNode VisitFieldDeclaration(FieldDeclarationSyntax node) { FieldDeclarationSyntax fieldDeclaration = (FieldDeclarationSyntax)base.VisitFieldDeclaration(node); var typeInfo = model.GetTypeInfo(node.Declaration.Type); if (typeInfo.Type == null) { UdonSharpUtils.LogWarning($"Could not find symbol for {node}"); return(fieldDeclaration); } ITypeSymbol rootType = typeInfo.Type; while (rootType.TypeKind == TypeKind.Array) { rootType = ((IArrayTypeSymbol)rootType).ElementType; } if (rootType.TypeKind == TypeKind.Error || rootType.TypeKind == TypeKind.Unknown) { UdonSharpUtils.LogWarning($"Type {typeInfo.Type} for field '{fieldDeclaration.Declaration}' is invalid"); return(fieldDeclaration); } IFieldSymbol firstFieldSymbol = (IFieldSymbol)model.GetDeclaredSymbol(node.Declaration.Variables.First()); rootType = firstFieldSymbol.Type; // If the field is not serialized or is using Odin already, we don't need to do anything. if (!IsFieldSerializedWithoutOdin(firstFieldSymbol)) { return(fieldDeclaration); } // Getting the type may fail if it's a user type that hasn't compiled on the C# side yet. For now we skip it, but we should do a simplified check for jagged arrays if (!TypeSymbol.TryGetSystemType(rootType, out Type systemType)) { return(fieldDeclaration); } // If Unity can serialize the type, we're good if (UnitySerializationUtility.GuessIfUnityWillSerialize(systemType)) { return(fieldDeclaration); } // Common type that gets picked up as serialized but shouldn't be // todo: Add actual checking for if a type is serializable, which isn't consistent. Unity/System library types in large part are serializable but don't have the System.Serializable tag, but types outside those assemblies need the tag to be serialized. if (systemType == typeof(VRCPlayerApi) || systemType == typeof(VRCPlayerApi[])) { return(fieldDeclaration); } Modified = true; NameSyntax odinSerializeName = IdentifierName("VRC"); odinSerializeName = QualifiedName(odinSerializeName, IdentifierName("Udon")); odinSerializeName = QualifiedName(odinSerializeName, IdentifierName("Serialization")); odinSerializeName = QualifiedName(odinSerializeName, IdentifierName("OdinSerializer")); odinSerializeName = QualifiedName(odinSerializeName, IdentifierName("OdinSerialize")); // Somehow it seems like there's literally no decent way to maintain the indent on inserted code so we'll just inline the comment because Roslyn is dumb SyntaxTrivia commentTrivia = Comment(" /* UdonSharp auto-upgrade: serialization */ "); AttributeListSyntax newAttribList = AttributeList(SeparatedList(new [] { Attribute(odinSerializeName) })).WithTrailingTrivia(commentTrivia); SyntaxList <AttributeListSyntax> attributeList = fieldDeclaration.AttributeLists; if (attributeList.Count > 0) { SyntaxTriviaList trailingTrivia = attributeList.Last().GetTrailingTrivia(); trailingTrivia = trailingTrivia.Insert(0, commentTrivia); attributeList.Replace(attributeList[attributeList.Count - 1], attributeList[attributeList.Count - 1].WithoutTrailingTrivia()); newAttribList = newAttribList.WithTrailingTrivia(trailingTrivia); } else { newAttribList = newAttribList.WithLeadingTrivia(fieldDeclaration.GetLeadingTrivia()); fieldDeclaration = fieldDeclaration.WithoutLeadingTrivia(); } attributeList = attributeList.Add(newAttribList); return(fieldDeclaration.WithAttributeLists(attributeList)); }