Esempio n. 1
0
        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);
            }
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
            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));
            }