Example #1
0
 internal VisualScriptCompilerContext(VisualScriptAsset asset, Method method, Logger log)
 {
     // Create first block
     this.asset  = asset;
     this.method = method;
     Log         = log;
 }
Example #2
0
        public static VisualScriptCompilerResult Generate(VisualScriptAsset visualScriptAsset, VisualScriptCompilerOptions options)
        {
            var result = new VisualScriptCompilerResult();

            var members   = new List <MemberDeclarationSyntax>();
            var className = options.Class;

            // Generate variables
            foreach (var variable in visualScriptAsset.Properties)
            {
                var variableType = variable.Type;
                if (variableType == null)
                {
                    result.Error($"Variable {variable.Name} has no type, using \"object\" instead.");
                    variableType = "object";
                }

                var field =
                    FieldDeclaration(
                        VariableDeclaration(
                            ParseTypeName(variableType))
                        .WithVariables(
                            SingletonSeparatedList(
                                VariableDeclarator(
                                    Identifier(variable.Name)))))
                    .WithModifiers(
                        TokenList(
                            Token(SyntaxKind.PublicKeyword)));

                members.Add(field);
            }

            // Process each function
            foreach (var method in visualScriptAsset.Methods)
            {
                var functionStartBlock = method.Blocks.Values.OfType <FunctionStartBlock>().FirstOrDefault();
                if (functionStartBlock == null)
                {
                    continue;
                }

                var context = new VisualScriptCompilerContext(visualScriptAsset, method, result);

                context.ProcessEntryBlock(functionStartBlock);

                var methodModifiers = new SyntaxTokenList();
                methodModifiers = ConvertAccessibility(methodModifiers, method.Accessibility);
                methodModifiers = ConvertVirtualModifier(methodModifiers, method.VirtualModifier);
                if (method.IsStatic)
                {
                    methodModifiers = methodModifiers.Add(Token(SyntaxKind.StaticKeyword));
                }

                var parameters = new List <SyntaxNodeOrToken>();
                foreach (var parameter in method.Parameters)
                {
                    if (parameters.Count > 0)
                    {
                        parameters.Add(Token(SyntaxKind.CommaToken));
                    }

                    parameters.Add(
                        Parameter(Identifier(parameter.Name))
                        .WithModifiers(ConvertRefKind(parameter.RefKind))
                        .WithType(ParseTypeName(parameter.Type)));
                }

                // Generate method
                var methodDeclaration =
                    MethodDeclaration(
                        method.ReturnType == "void" ? PredefinedType(Token(SyntaxKind.VoidKeyword)) : ParseTypeName(method.ReturnType),
                        Identifier(method.Name))
                    .WithModifiers(methodModifiers)
                    .WithParameterList(ParameterList(
                                           SeparatedList <ParameterSyntax>(parameters)))
                    .WithBody(
                        Block(context.Blocks.SelectMany(x => x.Statements)))
                    .WithAdditionalAnnotations(GenerateAnnotation(method));

                members.Add(methodDeclaration);
            }

            // Generate class
            var classModifiers = new SyntaxTokenList();

            classModifiers = ConvertAccessibility(classModifiers, visualScriptAsset.Accessibility).Add(Token(SyntaxKind.PartialKeyword));
            if (visualScriptAsset.IsStatic)
            {
                classModifiers = classModifiers.Add(Token(SyntaxKind.StaticKeyword));
            }

            var @class =
                ClassDeclaration(className)
                .WithMembers(List(members))
                .WithModifiers(classModifiers);

            if (visualScriptAsset.BaseType != null)
            {
                @class = @class.WithBaseList(BaseList(SingletonSeparatedList <BaseTypeSyntax>(SimpleBaseType(IdentifierName(visualScriptAsset.BaseType)))));
            }

            // Generate namespace around class (if any)
            MemberDeclarationSyntax namespaceOrClass = @class;
            var @namespace = !string.IsNullOrEmpty(visualScriptAsset.Namespace) ? visualScriptAsset.Namespace : options.DefaultNamespace;

            if (@namespace != null)
            {
                namespaceOrClass =
                    NamespaceDeclaration(
                        IdentifierName(@namespace))
                    .WithMembers(
                        SingletonList <MemberDeclarationSyntax>(@class));
            }

            // Generate compilation unit
            var compilationUnit =
                CompilationUnit()
                .WithUsings(
                    List(visualScriptAsset.UsingDirectives.Select(x =>
                                                                  UsingDirective(
                                                                      IdentifierName(x)))))
                .WithMembers(
                    SingletonList(namespaceOrClass))
                .NormalizeWhitespace();

            // Generate actual source code
            result.GeneratedSource = compilationUnit.ToFullString();
            result.SyntaxTree      = SyntaxTree(compilationUnit, path: options.FilePath ?? string.Empty);

            return(result);
        }