//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"))); }
public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax node) { if (_class.IsSignal(node)) { _isStatic = Roslyn.IsStatic(node); return(base.VisitMethodDeclaration(node)); } return(node); }
private static MethodDeclarationSyntax concurrentMethod(Class ctx, MethodDeclarationSyntax method, bool forever = false, bool asVirtual = false) { var name = method.Identifier.ToString(); var body = method.Body; var returnStatements = body .DescendantNodes() .OfType <ReturnStatementSyntax>(); var lastReturn = body.Statements.LastOrDefault() as ReturnStatementSyntax; if (returnStatements.Any()) { body = body .ReplaceNodes(returnStatements, (on, nn) => Templates .ExpressionReturn .Get <StatementSyntax>(nn.Expression == null || nn.Expression.IsMissing ? Roslyn.@null : nn.Expression, Roslyn.Quoted(method.Identifier.ToString()))); } if (forever) { body = CSharp.Block( CSharp.ForStatement(body)); } else if (lastReturn == null) { body = body.AddStatements(Templates .ExpressionReturn .Get <StatementSyntax>( Roslyn.@null, Roslyn.Quoted(method.Identifier.ToString()))); } var result = Templates .ConcurrentMethod .Get <MethodDeclarationSyntax>("__concurrent" + name); result = result .WithParameterList(method .ParameterList .AddParameters(result .ParameterList .Parameters .ToArray())) .WithBody(body); if (asVirtual) { result = result .WithModifiers(CSharp.TokenList( CSharp.Token(SyntaxKind.ProtectedKeyword), CSharp.Token(SyntaxKind.VirtualKeyword))); } if (Roslyn.IsStatic(method)) { result = result.AddModifiers(CSharp.Token(SyntaxKind.StaticKeyword)); } ctx.AddMember(result); return(result); }
private static bool compileMethod(MethodDeclarationSyntax methodDeclaration, Class ctx, Scope scope, Options options, bool isSingleton) { var method = methodDeclaration; var name = method.Identifier.ToString(); var isMain = name == "main"; var isProtected = method .Modifiers .Where(m => m.Kind() == SyntaxKind.ProtectedKeyword) .Any(); var isVisible = isProtected || Roslyn.IsVisible(method); var isStatic = Roslyn.IsStatic(method); var hasReturnType = method.ReturnType.ToString() != "void"; var returnType = hasReturnType ? method.ReturnType : Roslyn.boolean; var isEmptySignal = method.Body == null || method.Body.IsMissing; if (isEmptySignal) { if (method.ParameterList.Parameters.Count > 0) { scope.AddError("concurrent03", "empty signals cannot contain parameters", method); } if (method.ReturnType.ToString() != "void") { scope.AddError("concurrent04", "empty signals cannot return values", method); } method = method .WithSemicolonToken(CSharp.MissingToken(SyntaxKind.SemicolonToken)) .WithBody(CSharp.Block()); } var cc = parseConcurrentBlock(ctx, method.Body, scope, isStatic); if (cc != null) { method = method.WithBody(cc); } //remove attributes, until needed method = method.WithAttributeLists(CSharp.List <AttributeListSyntax>()); if (isMain) { if (ctx.HasMain) { scope.AddError("concurrent06", "multiple main methods", method); return(false); } ctx.HasMain = true; var statements = method.Body.Statements; var isContinued = (cc == null) && checkContinued(statements); if (isContinued) { method = method .WithBody(CSharp.Block(statements .Take(statements.Count - 1))); } var mainMethod = concurrentMethod(ctx, method); //hook up our start method int currentIndex = 0; ctx.Replace(methodDeclaration, Templates .StartObject .Get <MethodDeclarationSyntax>(Templates .ConcurrentMain .Get <InvocationExpressionSyntax>() .WithArgumentList(CSharp.ArgumentList(CSharp.SeparatedList( mainMethod .ParameterList .Parameters .Where(param => param.Identifier.ToString() != "__cancellation" && param.Identifier.ToString() != "__success" && param.Identifier.ToString() != "__failure") .Select(param => CSharp.Argument(Templates .StartObjectArgument .Get <ExpressionSyntax>( param.Type, currentIndex++))) .Union(new[] { CSharp.Argument(Templates.NullCancelationToken), CSharp.Argument(Roslyn.@null), CSharp.Argument(Roslyn.@null), })))))); return(false); } if (isVisible) { if (isEmptySignal) { Debug.Assert(!isStatic); //td: error ctx.AddMember(Templates .EmptySignalMethod .Get <MethodDeclarationSyntax>( "__concurrent" + name, Roslyn.Quoted(name), isProtected ? Roslyn.@true : Roslyn.@false)); } else { concurrentMethod(ctx, method, asVirtual: options.GenerateRemote); } } else if (cc != null) { concurrentMethod(ctx, method); } else if (isEmptySignal) { ctx.AddMember(Templates .EmptySignalMethod .Get <MethodDeclarationSyntax>( "__concurrent" + name, Roslyn.Quoted(name), isProtected? Roslyn.@true : Roslyn.@false)); } else { return(false); } var signal = ctx.AddSignal(name, returnType, isVisible, isStatic); if (isVisible) { method = createPublicSignals(ctx, method, signal, isSingleton); if (isSingleton) { ctx.Replace(methodDeclaration, method); } } else { ctx.Replace(methodDeclaration, method .WithBody(CSharp.Block() .WithStatements(CSharp.List(new[] { isEmptySignal ? Templates.SignalDispatcher.Get <StatementSyntax>(Roslyn.Quoted(method.Identifier.ToString())) : Templates.PrivateSignal })))); return(false); } return(true); }