Example #1
0
        private static void addJSFiles(ExcessCompilation compilation, Scope scope)
        {
            var serverConfig = compilation.Scope.GetServerConfiguration();

            if (serverConfig == null)
            {
                throw new ArgumentException("IServerConfiguration");
            }

            var clientCode = serverConfig.GetClientInterface();

            if (string.IsNullOrWhiteSpace(clientCode))
            {
                return;
            }

            var servicePath = serverConfig.GetServicePath();

            if (servicePath == null)
            {
                throw new InvalidOperationException("cannot find the path");
            }

            compilation.AddContent(servicePath, Templates
                                   .jsServiceFile(new
            {
                Members = clientCode
            }));
        }
Example #2
0
        private static void jsService(SyntaxNode node, ExcessCompilation compilation, Scope scope)
        {
            Debug.Assert(node is ClassDeclarationSyntax);
            var @class = node as ClassDeclarationSyntax;

            var serviceAttribute = @class
                                   .AttributeLists
                                   .Where(attrList => attrList
                                          .Attributes
                                          .Any(attr => attr.Name.ToString() == "Service"))
                                   .SingleOrDefault()
                                   ?.Attributes
                                   .FirstOrDefault(attr => attr.Name.ToString() == "Service");

            var model  = compilation.GetSemanticModel(node);
            var config = scope.GetServerConfiguration();
            var name   = @class.Identifier.ToString();
            var id     = Guid.NewGuid();
            var body   = string.Empty;

            Debug.Assert(config != null);
            if (serviceAttribute == null)
            {
                //functions
                var @namespace = @class.FirstAncestorOrSelf <NamespaceDeclarationSyntax>(
                    ancestor => ancestor is NamespaceDeclarationSyntax);

                if (@namespace != null)
                {
                    name = @namespace.Name.ToString();
                }

                body = functionalBody(@class, model);
                if (body.Any())
                {
                    config.AddFunctionalContainer(name, body);
                }
                return; //td: separate
            }
            else
            {
                var guidString = serviceAttribute
                                 .ArgumentList
                                 .Arguments
                                 .Single(attr => attr.NameColon.Name.ToString() == "id")
                                 .Expression
                                 .ToString();

                id   = Guid.Parse(guidString.Substring(1, guidString.Length - 2));
                body = concurrentBody(@class, config, model);
            }

            config.AddClientInterface(node.SyntaxTree, Templates
                                      .jsService(new
            {
                Name = name,
                Body = body,
                ID   = id
            }));
        }
Example #3
0
        //generation
        private static bool isService(ClassDeclarationSyntax @class, ExcessCompilation compilation, Scope scope)
        {
            if (!isConcurrentClass(@class, compilation, scope))
            {
                var isFunctionClass = @class.Identifier.ToString() == "Functions" && Roslyn.IsStatic(@class);
                if (isFunctionClass)
                {
                    return(@class.ChildNodes()
                           .OfType <MethodDeclarationSyntax>()
                           .Any(method => method
                                .AttributeLists
                                .Any(attrList => attrList
                                     .Attributes
                                     .Any(attr => attr.Name.ToString() == "route"))));
                }

                return(false);
            }

            return(@class
                   .AttributeLists
                   .Any(attrList => attrList
                        .Attributes
                        .Any(attr => attr.Name.ToString() == "Service")));
        }
Example #4
0
 private static bool isConcurrentClass(ClassDeclarationSyntax @class, ExcessCompilation compilation, Scope scope)
 {
     return(@class
            .AttributeLists
            .Any(attrList => attrList
                 .Attributes
                 .Any(attr => attr.Name.ToString() == "Concurrent")));
 }
Example #5
0
        private static void jsConcurrentClass(SyntaxNode node, ExcessCompilation compilation, Scope scope)
        {
            Debug.Assert(node is ClassDeclarationSyntax);
            var @class = node as ClassDeclarationSyntax;
            var model  = compilation.GetSemanticModel(node);
            var config = scope.GetServerConfiguration();

            Debug.Assert(config != null);

            var body = concurrentBody(@class, config, model);

            config.AddClientInterface(node.SyntaxTree, Templates
                                      .jsConcurrentClass(new
            {
                Name = @class.Identifier.ToString(),
                Body = body
            }));
        }
Example #6
0
        public void buildFiles()
        {
            if (Files == null)
            {
                throw new InvalidProgramException("must specify which files to compile");
            }

            var actualFiles = Files.ToArray();

            if (actualFiles.Length == 0)
            {
                throw new InvalidProgramException($"must specify which files to compile");
            }

            var asExe = actualFiles
                        .Where(path => Path
                               .GetFileName(path)
                               .Equals("Program.cs"))
                        .Any();

            if (Extensions == null)
            {
                var exePath = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
                Extensions = directoryExtensions(exePath);
            }

            var compilation = new ExcessCompilation(
                analysis: new CompilationAnalysis(),
                extensions: Extensions,
                executable: asExe);

            foreach (var file in actualFiles)
            {
                if (file.EndsWith(".xs.cs"))
                {
                    continue;
                }

                var ext = Path.GetExtension(file);
                switch (ext)
                {
                case ".cs": compilation.addCSharpFile(file); break;

                case ".xs": compilation.addDocument(file); break;

                default: throw new InvalidOperationException($"invalid extension: {ext}");
                }
            }

            var errors = null as IEnumerable <Diagnostic>;
            var result = compilation.build(out errors);

            if (Transpile)
            {
                foreach (var document in compilation.Documents())
                {
                    var filename = compilation.DocumentFileName(document) + ".cs";
                    Console.WriteLine($"Generated: {filename}");

                    var text = document.SyntaxRoot.NormalizeWhitespace().ToFullString();
                    File.WriteAllText(filename, text);
                }

                foreach (var file in compilation.getCSharpFiles())
                {
                    var filename = Path.Combine(_directory, file.Key);
                    if (!File.Exists(file.Key) && !File.Exists(filename))
                    {
                        Console.WriteLine($"Generated: {filename}");

                        var text = file.Value.GetRoot().NormalizeWhitespace().ToFullString();
                        File.WriteAllText(filename, text);
                    }
                }
            }
            else if (result != null)
            {
                var outputPath = OutputPath;
                if (outputPath == null)
                {
                    outputPath = Path.Combine(
                        _directory,
                        Path.GetFileName(_directory));
                }

                if (Path.GetExtension(outputPath) == string.Empty)
                {
                    outputPath = outputPath + (asExe ? ".exe" : ".dll");
                }

                Debug.Assert(outputPath != null);

                outputPath = Path.GetFullPath(outputPath);
                File.WriteAllBytes(outputPath, result.GetBuffer());
                Console.WriteLine($"Successfully built: {outputPath}");
            }

            if (errors.Any())
            {
                foreach (var error in errors)
                {
                    Console.Error.WriteLine(error.ToString());
                }
            }
        }
Example #7
0
        public static TestConcurrentApp Build(string code,
                                              out IEnumerable <Diagnostic> errors,
                                              bool withInterface = false,
                                              bool withRemote    = false)
        {
            errors = null;

            var config = MockInjector(new Options
            {
                GenerateInterface = withInterface,
                GenerateRemote    = withRemote,
            });
            var compilation = new ExcessCompilation();

            compilation.addDocument("concurrent-test", code, config);

            Assembly assembly = compilation.build();

            if (assembly == null)
            {
                errors = compilation.errors();

                //debug
                StringBuilder errorLines = new StringBuilder();
                foreach (var error in errors)
                {
                    errorLines.AppendLine(error.ToString());
                }

                var errorString = errorLines.ToString();
                return(null);
            }

            var types  = new FactoryMap();
            var result = new TestConcurrentApp(types);

            foreach (var type in assembly.GetTypes())
            {
                var attributes = type.CustomAttributes;
                if (!attributes.Any(attr => attr.AttributeType == typeof(ConcurrentAttribute)))
                {
                    continue;
                }

                var typeName = type.ToString();
                if (attributes.Any(attr => attr.AttributeType == typeof(ConcurrentSingleton)))
                {
                    result.AddSingleton(typeName, (IConcurrentObject)Activator.CreateInstance(type));
                    continue;
                }

                var useParameterLess = type.GetConstructors().Length == 0;
                if (!useParameterLess)
                {
                    useParameterLess = type.GetConstructor(new Type[] { }) != null;
                }

                types[typeName] = (app, args) =>
                {
                    if (useParameterLess)
                    {
                        return((IConcurrentObject)Activator.CreateInstance(type));
                    }

                    var ctor = type.GetConstructor(args
                                                   .Select(arg => arg.GetType())
                                                   .ToArray());

                    if (ctor != null)
                    {
                        return((IConcurrentObject)ctor.Invoke(args));
                    }

                    throw new InvalidOperationException("unable to find a constructor");
                };
            }

            return(result);
        }