Пример #1
0
        public void AddMethod(int i, ScenarioTag.ScriptMethodDefinition scriptMethod)
        {
            var modifiers = SyntaxTokenList.Create(Token(SyntaxKind.PublicKeyword))
                            .Add(Token(SyntaxKind.AsyncKeyword));

            TypeSyntax returnType = ParseTypeName("Task");

            if (scriptMethod.ReturnType != ScriptDataType.Void)
            {
                returnType = GenericName("Task").AddTypeArgumentListArguments(SyntaxUtil.ScriptTypeSyntax(scriptMethod.ReturnType));
            }

            var method = MethodDeclaration(
                returnType,
                SyntaxUtil.SanitizeIdentifier(scriptMethod.Description))
                         .WithModifiers(modifiers);

            // Push root method body as first scope
            var block     = new StatementBlockContext();
            var rootScope = new Scope(scriptMethod.ReturnType, block, block);
            var retScope  = EvaluateNodes(scriptMethod.SyntaxNodeIndex, rootScope);

            Debug.Assert(rootScope == retScope, "Last scope wasn't the provided root");

            methods.Add(method.WithBody(Block(block.GetInnerStatements()))
                        .AddAttributeLists(AttributeList(SeparatedList(new[] {
                Attribute(IdentifierName(nameof(ScriptMethodAttribute).Replace("Attribute", "")))
                .AddArgumentListArguments(
                    AttributeArgument(SyntaxUtil.LiteralExpression(i)),
                    AttributeArgument(MemberAccessExpression(
                                          SyntaxKind.SimpleMemberAccessExpression,
                                          IdentifierName(nameof(Lifecycle)),
                                          IdentifierName(scriptMethod.Lifecycle.ToString()))))
            }))));
        }
Пример #2
0
        public StatementSyntax CreateWellKnownAssignment(TypeSyntax type,
                                                         string desiredName,
                                                         int itemIndex)
        {
            if (nameRepo.TryGetName(desiredName, nameof(ScenarioTag.EntityReference), itemIndex, out var name) == false)
            {
                throw new Exception("Unable to find property name");
            }

            ExpressionSyntax access = ElementAccessExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                                     IdentifierName("scenarioTag"),
                                                                                     IdentifierName(nameof(ScenarioTag.WellKnownItems))))
                                      .AddArgumentListArguments(Argument(SyntaxUtil.LiteralExpression(itemIndex)));

            access = ObjectCreationExpression(
                GenericName(nameof(ScenarioEntity <object>))
                .AddTypeArgumentListArguments(type))
                     .AddArgumentListArguments(
                Argument(SyntaxUtil.LiteralExpression(itemIndex)),
                Argument(access));

            var exp = AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
                                           IdentifierName(name),
                                           access);

            return(ExpressionStatement(exp));
        }
Пример #3
0
        public ScriptLoader(string generatedScriptOutput = null)
        {
            var suppressions = new Dictionary <string, ReportDiagnostic>
            {
                { "CS1998", ReportDiagnostic.Suppress }
            };


            var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
                                                                  specificDiagnosticOptions: suppressions,
                                                                  optimizationLevel: OptimizationLevel.Debug,
                                                                  platform: Platform.AnyCpu);

            var baseLibPath = Path.GetDirectoryName(typeof(object).Assembly.Location);

            var tpa = (string)AppContext.GetData("TRUSTED_PLATFORM_ASSEMBLIES");

            this.generatedScriptOutput = generatedScriptOutput;
            this.compilation           = CSharpCompilation.Create(AssemblyName, options: compilationOptions)
                                         .AddReferences(MetadataReference.CreateFromFile(typeof(ScriptLoader).Assembly.Location))
                                         .AddReferences(MetadataReference.CreateFromFile(Path.Combine(baseLibPath, "mscorlib.dll")))
                                         .AddReferences(MetadataReference.CreateFromFile(Path.Combine(baseLibPath, "System.dll")))
                                         .AddReferences(MetadataReference.CreateFromFile(Path.Combine(baseLibPath, "System.Core.dll")));

            foreach (var asmPath in tpa.Split(';'))
            {
                this.compilation = this.compilation.AddReferences(
                    MetadataReference.CreateFromFile(asmPath));
            }

            foreach (var reference in typeof(ScriptLoader).Assembly.GetReferencedAssemblies())
            {
                if (reference.CodeBase != null)
                {
                    compilation = compilation.AddReferences(MetadataReference.CreateFromFile(reference.CodeBase));
                }
            }

            var targetFrameworkUnit = SyntaxFactory.CompilationUnit()
                                      .AddAttributeLists(
                SyntaxFactory.AttributeList(
                    SyntaxFactory.SingletonSeparatedList(
                        SyntaxFactory.Attribute(SyntaxFactory.QualifiedName(
                                                    SyntaxFactory.QualifiedName(
                                                        SyntaxFactory.QualifiedName(
                                                            SyntaxFactory.IdentifierName("System"),
                                                            SyntaxFactory.IdentifierName("Runtime")),
                                                        SyntaxFactory.IdentifierName("Versioning")),
                                                    SyntaxFactory.IdentifierName("TargetFrameworkAttribute")))
                        .AddArgumentListArguments(
                            SyntaxFactory.AttributeArgument(SyntaxUtil.LiteralExpression(".NETStandard,Version=v2.1")),
                            SyntaxFactory.AttributeArgument(SyntaxUtil.LiteralExpression(""))
                            .WithNameEquals(SyntaxFactory.NameEquals(SyntaxFactory.IdentifierName("FrameworkDisplayName"))))))
                .WithTarget(SyntaxFactory.AttributeTargetSpecifier(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword))));

            this.compilation = this.compilation.AddSyntaxTrees(targetFrameworkUnit.SyntaxTree);
        }
Пример #4
0
        private void AddPublicProperty(ScriptDataType type, string name, int itemIndex)
        {
            var propName = nameRepo.RegisterName(name, type.ToString(), itemIndex);

            var scnrPropName = type switch
            {
                ScriptDataType.CameraPathTarget => nameof(ScenarioTag.CameraPathTargets),
                ScriptDataType.LocationFlag => nameof(ScenarioTag.LocationFlagDefinitions),
                ScriptDataType.CinematicTitle => nameof(ScenarioTag.CinematicTitleDefinitions),
                ScriptDataType.Trigger => nameof(ScenarioTag.TriggerVolumes),
                ScriptDataType.StartingProfile => nameof(ScenarioTag.StartingProfileDefinitions),
                ScriptDataType.DeviceGroup => nameof(ScenarioTag.DeviceGroupDefinitions),
                ScriptDataType.AI => nameof(ScenarioTag.AiSquadGroupDefinitions),
                ScriptDataType.AIOrders => nameof(ScenarioTag.AiOrderDefinitions),
                _ => throw new Exception("Not support!")
            };

            ExpressionSyntax access = ElementAccessExpression(MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                                     IdentifierName(nameof(ScenarioScriptBase.Scenario)),
                                                                                     IdentifierName(scnrPropName)))
                                      .AddArgumentListArguments(Argument(SyntaxUtil.LiteralExpression(itemIndex)));

            var scnrProp = ScenarioTagProperties[scnrPropName];

            if (scnrProp.PropertyType.HasElementType &&
                scnrProp.PropertyType.GetElementType().GetInterfaces().Any(i =>
                                                                           i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IGameObjectDefinition <>)))
            {
                access = MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                access,
                                                IdentifierName(nameof(IGameObjectDefinition <object> .GameObject)));
            }

            var prop = PropertyDeclaration(SyntaxUtil.ScriptTypeSyntax(type), propName)
                       .WithExpressionBody(ArrowExpressionClause(access))
                       .WithSemicolonToken(Token(SyntaxKind.SemicolonToken));


            properties.Add(prop.WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword))));
        }
Пример #5
0
        // Make squads into nested classes
        public void CreateNestedSquadClasses(ScenarioTag tag)
        {
            for (var i = 0; i < tag.AiSquadDefinitions.Length; i++)
            {
                var squad = tag.AiSquadDefinitions[i];

                var squadPropName = nameRepo.RegisterName(squad.Description, ScriptDataType.AI.ToString(), i);

                var dataClassProps = new List <PropertyDeclarationSyntax>();
                dataClassProps.Add(SyntaxUtil.CreateProperty(ParseTypeName(nameof(ScenarioTag)), nameof(ScenarioTag)));

                var nestedRepo = new MemberNameRepository();

                var m = 0;
                foreach (var ai in squad.StartingLocations)
                {
                    var propName = nestedRepo.RegisterName(ai.Description, ScriptDataType.AI.ToString(), m);

                    ExpressionSyntax startingLocationAccess = ElementAccessExpression(
                        MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                               ElementAccessExpression(
                                                   MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                          IdentifierName(nameof(ScenarioTag)),
                                                                          IdentifierName(nameof(tag.AiSquadDefinitions))))
                                               .AddArgumentListArguments(Argument(SyntaxUtil.LiteralExpression(i))),
                                               IdentifierName(nameof(squad.StartingLocations))))
                                                              .AddArgumentListArguments(Argument(SyntaxUtil.LiteralExpression(m)));

                    dataClassProps.Add(PropertyDeclaration(SyntaxUtil.ScriptTypeSyntax(ScriptDataType.AI), propName)
                                       .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
                                       .WithExpressionBody(ArrowExpressionClause(startingLocationAccess))
                                       .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));

                    m++;
                }

                ExpressionSyntax squadAccess = ElementAccessExpression(
                    MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                           IdentifierName(nameof(ScenarioTag)),
                                           IdentifierName(nameof(tag.AiSquadDefinitions))))
                                               .AddArgumentListArguments(Argument(SyntaxUtil.LiteralExpression(i)));

                // This is so the script can reference the squad itself, need special init handling
                dataClassProps.Add(PropertyDeclaration(SyntaxUtil.ScriptTypeSyntax(ScriptDataType.AI), "Squad")
                                   .WithModifiers(TokenList(Token(SyntaxKind.PublicKeyword)))
                                   .WithExpressionBody(ArrowExpressionClause(squadAccess))
                                   .WithSemicolonToken(Token(SyntaxKind.SemicolonToken)));

                var squadTypeName = "Squad_" + squadPropName;

                var cls = ClassDeclaration(squadTypeName)
                          .AddModifiers(Token(SyntaxKind.PublicKeyword))
                          .WithMembers(new SyntaxList <MemberDeclarationSyntax>(dataClassProps))
                          .AddMembers(ConstructorDeclaration(squadTypeName)
                                      .AddModifiers(Token(SyntaxKind.PublicKeyword))
                                      .AddParameterListParameters(
                                          Parameter(Identifier(nameof(ScenarioTag)))
                                          .WithType(ParseTypeName(nameof(ScenarioTag))))
                                      .WithBody(Block(new List <StatementSyntax>()
                {
                    ExpressionStatement(AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
                                                             MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                                    ThisExpression(),
                                                                                    IdentifierName(nameof(ScenarioTag))),
                                                             IdentifierName(nameof(ScenarioTag))))
                })));

                nestedDataClasses.Add(cls);
                nameRepo.NestedRepos.Add(squadPropName, nestedRepo);

                properties.Add(PropertyDeclaration(ParseTypeName(squadTypeName), squadPropName)
                               .AddModifiers(Token(SyntaxKind.PublicKeyword))
                               .WithAccessorList(SyntaxUtil.AutoPropertyAccessorList()));
            }
        }