예제 #1
0
        public static void Test_UnitySerializedFieldImplementationProvider_Attribute_Method_Generator()
        {
            //arrange
            WiredToAttribute attri = new WiredToAttribute(System.Reflection.MemberTypes.Property, "SomethingProp", typeof(string).AssemblyQualifiedName);
            UnitySerializedFieldImplementationProvider provider = new UnitySerializedFieldImplementationProvider("blah", typeof(string), attri);
            string serializeFieldName = typeof(SerializeField).FullName;
            string compiledAttributes = null;

            //act
            var compileUnit = SyntaxFactory.CompilationUnit().
                              WithAttributeLists(provider.Attributes)
                              .WithEndOfFileToken(SyntaxFactory.Token(SyntaxKind.EndOfFileToken));

            StringBuilder sb = new StringBuilder();

            using (StringWriter writer = new StringWriter(sb))
            {
                Formatter.Format(compileUnit, new AdhocWorkspace()).WriteTo(writer);
            }

            compiledAttributes = sb.ToString();

            //assert
            //Tests that it contains [SerializeField]
            Assert.IsTrue(compiledAttributes.Contains(@"[" + typeof(SerializeField).FullName + @"(),") || compiledAttributes.Contains(@"[" + typeof(SerializeField).FullName + @","));
            //Tests that it contains WiredToAttribute(
            Assert.IsTrue(compiledAttributes.Contains(typeof(WiredToAttribute).FullName + @"("));
            //Tests that it contains ,"NAME" or , "NAME"
            Assert.IsTrue(compiledAttributes.Contains(@",""" + attri.WiredMemberName + @"""") || compiledAttributes.Contains(@", """ + attri.WiredMemberName + @""""));

            Assert.IsTrue(compiledAttributes.Contains(@",""" + attri.TypeWiredTo.FullName) || compiledAttributes.Contains(@", """ + attri.TypeWiredTo.FullName));
        }
        private SyntaxList <AttributeListSyntax> GenerateUnityAttributes(WiredToAttribute wiredAttribute)
        {
            //Code generated from: http://roslynquoter.azurewebsites.net/
            //This is NOT human written. Don't try to read it
            return(SyntaxFactory.SingletonList <AttributeListSyntax>(
                       SyntaxFactory.AttributeList(
                           SyntaxFactory.SeparatedList <AttributeSyntax>(
                               new SyntaxNodeOrToken[] {
                SyntaxFactory.Attribute(
                    SyntaxFactory.QualifiedName(
                        SyntaxFactory.IdentifierName(
                            @"UnityEngine"),
                        SyntaxFactory.IdentifierName(
                            @"SerializeField"))
                    .WithDotToken(
                        SyntaxFactory.Token(
                            SyntaxKind.DotToken)))
                .WithArgumentList(
                    SyntaxFactory.AttributeArgumentList()
                    .WithOpenParenToken(
                        SyntaxFactory.Token(
                            SyntaxKind.OpenParenToken))
                    .WithCloseParenToken(
                        SyntaxFactory.Token(
                            SyntaxKind.CloseParenToken))),
                SyntaxFactory.Token(
                    SyntaxKind.CommaToken),
                SyntaxFactory.Attribute(
                    SyntaxFactory.QualifiedName(
                        SyntaxFactory.QualifiedName(
                            SyntaxFactory.QualifiedName(
                                SyntaxFactory.IdentifierName(
                                    @"Testity"),
                                SyntaxFactory.IdentifierName(
                                    @"Common"))
                            .WithDotToken(
                                SyntaxFactory.Token(
                                    SyntaxKind.DotToken)),
                            SyntaxFactory.IdentifierName(
                                @"Unity3D"))
                        .WithDotToken(
                            SyntaxFactory.Token(
                                SyntaxKind.DotToken)),
                        SyntaxFactory.IdentifierName(
                            @"WiredToAttribute"))
                    .WithDotToken(
                        SyntaxFactory.Token(
                            SyntaxKind.DotToken)))
                .WithArgumentList(
                    SyntaxFactory.AttributeArgumentList(
                        SyntaxFactory.SeparatedList <AttributeArgumentSyntax>(
                            new SyntaxNodeOrToken[] {
                    SyntaxFactory.AttributeArgument(
                        SyntaxFactory.MemberAccessExpression(
                            SyntaxKind.SimpleMemberAccessExpression,
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.MemberAccessExpression(
                                    SyntaxKind.SimpleMemberAccessExpression,
                                    SyntaxFactory.IdentifierName(
                                        @"System"),
                                    SyntaxFactory.IdentifierName(
                                        @"Reflection"))
                                .WithOperatorToken(
                                    SyntaxFactory.Token(
                                        SyntaxKind.DotToken)),
                                SyntaxFactory.IdentifierName(
                                    @"MemberTypes"))
                            .WithOperatorToken(
                                SyntaxFactory.Token(
                                    SyntaxKind.DotToken)),
                            SyntaxFactory.IdentifierName(
                                wiredAttribute.WiredMemberType.ToString()))                                                                                 //modified from the auto-generated source. Inserts membertype in
                        .WithOperatorToken(
                            SyntaxFactory.Token(
                                SyntaxKind.DotToken))),
                    SyntaxFactory.Token(
                        SyntaxKind.CommaToken),
                    SyntaxFactory.AttributeArgument(
                        SyntaxFactory.LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            SyntaxFactory.Literal(wiredAttribute.WiredMemberName))),

                    //type it is wired to. Hand written
                    SyntaxFactory.Token(
                        SyntaxKind.CommaToken),

                    SyntaxFactory.AttributeArgument(
                        SyntaxFactory.LiteralExpression(
                            SyntaxKind.StringLiteralExpression,
                            SyntaxFactory.Literal(TypeToLoadableString(wiredAttribute.TypeWiredTo))))                                                                             //wiredAttribute.TypeWiredTo.ToString() + ", " + wiredAttribute.TypeWiredTo.Assembly.GetName().Name)))//wiredAttribute.TypeWiredTo.AssemblyQualifiedName.Remove(wiredAttribute.TypeWiredTo.AssemblyQualifiedName.TakeWhile(c => (two -= (c == ',' ? 1 : 0)) > 0).Count()))))//remove everything after the assembly. We can't have versioning info
                    //handwritten ended
                }))
                    .WithOpenParenToken(
                        SyntaxFactory.Token(
                            SyntaxKind.OpenParenToken))
                    .WithCloseParenToken(
                        SyntaxFactory.Token(
                            SyntaxKind.CloseParenToken)))
            }))
                       .WithOpenBracketToken(
                           SyntaxFactory.Token(
                               SyntaxKind.OpenBracketToken))
                       .WithCloseBracketToken(
                           SyntaxFactory.Token(
                               SyntaxKind.CloseBracketToken))));
        }
        public UnitySerializedFieldImplementationProvider(string memberName, string fullMemberName, WiredToAttribute wiredAttribute)
        {
            MemberName = SyntaxFactory.Identifier(memberName);
            Type       = SyntaxFactory.ParseName(fullMemberName);

            //These modifiers are the same for all unity members. We make them private because we've no reason to do otherwise
            //Modifiers: Private
            Modifiers = SyntaxFactory.TokenList(MemberImplementationModifier.Private.ToSyntaxKind().Select(x => SyntaxFactory.Token(x)));

            //Unity fields require two attributes.
            //Attributes: SerializeField and WiredToAttribute
            Attributes = GenerateUnityAttributes(wiredAttribute);
        }