void AddTransition(Transition transition) { //============================== // Source Errors //============================== if(transition.Source != null) { if(transition.Source.Declaration == null) { _diagnostics.Add(new Diagnostic( transition.Source.Location, DiagnosticDescriptors.Semantic.Nav0011CannotResolveNode0, transition.Source.Name)); } else if(transition.Source.Declaration is TaskNodeSymbol) { _diagnostics.Add(new Diagnostic( transition.Source.Location, DiagnosticDescriptors.Semantic.Nav0100TaskNode0MustNotContainLeavingEdges, transition.Source.Name)); } else if(transition.Source.Declaration is ExitNodeSymbol) { _diagnostics.Add(new Diagnostic( transition.Source.Location, DiagnosticDescriptors.Semantic.Nav0101ExitNodeMustNotContainLeavingEdges)); } else if(transition.Source.Declaration is EndNodeSymbol) { _diagnostics.Add(new Diagnostic( transition.Source.Location, DiagnosticDescriptors.Semantic.Nav0102EndNodeMustNotContainLeavingEdges) ); } else if(transition.Source.Declaration is InitNodeSymbol) { var node = (InitNodeSymbol) transition.Source.Declaration; node.Outgoings.Add(transition); node.References.Add(transition.Source); } else if(transition.Source.Declaration is DialogNodeSymbol) { var node = (DialogNodeSymbol) transition.Source.Declaration; node.Outgoings.Add(transition); node.References.Add(transition.Source); } else if(transition.Source.Declaration is ViewNodeSymbol) { var node = (ViewNodeSymbol) transition.Source.Declaration; node.Outgoings.Add(transition); node.References.Add(transition.Source); } else if(transition.Source.Declaration is ChoiceNodeSymbol) { var node = (ChoiceNodeSymbol) transition.Source.Declaration; node.Outgoings.Add(transition); node.References.Add(transition.Source); } } //============================== // Target Errors //============================== if (transition.Target != null) { if (transition.Target.Declaration == null) { _diagnostics.Add(new Diagnostic( transition.Target.Location, DiagnosticDescriptors.Semantic.Nav0011CannotResolveNode0, transition.Target.Name)); } else if (transition.Target.Declaration is InitNodeSymbol) { _diagnostics.Add(new Diagnostic( transition.Target.Location, DiagnosticDescriptors.Semantic.Nav0103InitNodeMustNotContainIncomingEdges)); } else if (transition.Target.Declaration is EndNodeSymbol) { var node = (EndNodeSymbol)transition.Target.Declaration; node.Incomings.Add(transition); node.References.Add(transition.Target); } else if (transition.Target.Declaration is ExitNodeSymbol) { var node = (ExitNodeSymbol)transition.Target.Declaration; node.Incomings.Add(transition); node.References.Add(transition.Target); } else if (transition.Target.Declaration is DialogNodeSymbol) { var node = (DialogNodeSymbol)transition.Target.Declaration; node.Incomings.Add(transition); node.References.Add(transition.Target); } else if (transition.Target.Declaration is ViewNodeSymbol) { var node = (ViewNodeSymbol)transition.Target.Declaration; node.Incomings.Add(transition); node.References.Add(transition.Target); } else if (transition.Target.Declaration is ChoiceNodeSymbol) { var node = (ChoiceNodeSymbol)transition.Target.Declaration; node.Incomings.Add(transition); node.References.Add(transition.Target); } else if (transition.Target.Declaration is TaskNodeSymbol) { var node = (TaskNodeSymbol)transition.Target.Declaration; node.Incomings.Add(transition); node.References.Add(transition.Target); } } //============================== // Edge Errors //============================== if (transition.EdgeMode !=null) { if(transition.EdgeMode.EdgeMode != EdgeMode.Goto) { if(transition.Target?.Declaration is ChoiceNodeSymbol) { _diagnostics.Add(new Diagnostic( transition.EdgeMode.Location, DiagnosticDescriptors.Semantic.Nav0104ChoiceNode0MustOnlyReachedByGoTo, transition.Target.Name)); } if(transition.Target?.Declaration is ExitNodeSymbol) { _diagnostics.Add(new Diagnostic( transition.EdgeMode.Location, DiagnosticDescriptors.Semantic.Nav0105ExitNode0MustOnlyReachedByGoTo, transition.Target.Name) ); } if(transition.Target?.Declaration is EndNodeSymbol) { _diagnostics.Add(new Diagnostic( transition.EdgeMode.Location, DiagnosticDescriptors.Semantic.Nav0106EndNode0MustOnlyReachedByGoTo, transition.Target.Name) ); } } } //============================== // Trigger Errors //============================== if (transition.Triggers.Any()) { foreach(var trigger in transition.Triggers.Where(t=>t.IsSpontaneousTrigger)) { if(!(transition.Source?.Declaration is DialogNodeSymbol || transition.Source?.Declaration is ViewNodeSymbol || transition.Source?.Declaration is InitNodeSymbol)) { _diagnostics.Add(new Diagnostic( trigger.Location, DiagnosticDescriptors.Semantic.Nav0202SpontaneousOnlyAllowedAfterViewAndInitNodes)); } } foreach (var trigger in transition.Triggers.Where(t => t.IsSignalTrigger)) { if (transition.Source?.Declaration is InitNodeSymbol) { _diagnostics.Add(new Diagnostic( trigger.Location, DiagnosticDescriptors.Semantic.Nav0200SignalTriggerNotAllowedAfterInit)); } if (transition.Source?.Declaration is ChoiceNodeSymbol) { _diagnostics.Add(new Diagnostic( trigger.Location, DiagnosticDescriptors.Semantic.Nav0203TriggerNotAllowedAfterChoice)); } // TODO Keyword in eigene Klasse if (trigger.Name == "spontaneous" || trigger.Name == "spont") { _diagnostics.Add(new Diagnostic( trigger.Location, DiagnosticDescriptors.Semantic.Nav0201SpontaneousNotAllowedInSignalTrigger)); } } } //============================== // Condition Clause Errors //============================== if (transition.Syntax.ConditionClause != null) { if(transition.Source != null && ! ( transition.Source?.Declaration is InitNodeSymbol || transition.Source?.Declaration is ChoiceNodeSymbol)){ _diagnostics.Add(new Diagnostic( transition.Syntax.ConditionClause.GetLocation(), DiagnosticDescriptors.Semantic.Nav0220ConditionsAreOnlySupportedAfterInitAndChoiceNodes)); } } _taskDefinition.Transitions.Add(transition); }
public override void VisitTransitionDefinition(TransitionDefinitionSyntax transitionDefinitionSyntax) { // Source NodeReferenceSymbol sourceNodeReference = null; var sourceNodeSyntax = transitionDefinitionSyntax.SourceNode; if (sourceNodeSyntax != null) { var sourceNode = _taskDefinition.NodeDeclarations.TryFindSymbol(sourceNodeSyntax.Name); // Special case "init": Hier ist implizit auch Großschreibung erlaubt // TODO Keyword in eigene Klasse if (sourceNode == null && sourceNodeSyntax.Name=="init") { sourceNode = _taskDefinition.NodeDeclarations.TryFindSymbol("Init"); } var location = sourceNodeSyntax.GetLocation(); if(location != null) { sourceNodeReference = new NodeReferenceSymbol(sourceNodeSyntax.Name, location, sourceNode); } } // Target NodeReferenceSymbol targetNodeReference = null; var targetNodeSyntax = transitionDefinitionSyntax.TargetNode; if (targetNodeSyntax != null) { var targetNode = _taskDefinition.NodeDeclarations.TryFindSymbol(targetNodeSyntax.Name); var location = targetNodeSyntax.GetLocation(); if (location != null) { targetNodeReference = new NodeReferenceSymbol(targetNodeSyntax.Name, location, targetNode); } } // Edge EdgeModeSymbol edgeMode=null; var edgeSyntax = transitionDefinitionSyntax.Edge; if (edgeSyntax != null) { var location = edgeSyntax.GetLocation(); if(location != null) { edgeMode = new EdgeModeSymbol(edgeSyntax.ToString(), location, edgeSyntax.Mode); } } // Triggers var triggers = GetTriggers(transitionDefinitionSyntax); var transition = new Transition(_taskDefinition, transitionDefinitionSyntax, sourceNodeReference, edgeMode, targetNodeReference, triggers); AddTransition(transition); }