internal VisualScriptCompilerContext(VisualScriptAsset asset, Method method, Logger log) { // Create first block this.asset = asset; this.method = method; Log = log; }
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); }