public void Test_Translate_Constructor() { FunctionModel a = GraphModel.CreateFunction("A", Vector2.zero); // Debug.Log(...) MethodInfo logMethod = typeof(Debug).GetMethod(nameof(Debug.Log), new[] { typeof(object) }); Assume.That(logMethod, Is.Not.Null); FunctionCallNodeModel log = a.CreateStackedNode <FunctionCallNodeModel>("Log", 0, SpawnFlags.Default, n => n.MethodInfo = logMethod); // new Vector4(x, y) ConstructorInfo ctor = typeof(Vector4).GetConstructor(new[] { typeof(float), typeof(float) }); Assume.That(ctor, Is.Not.Null); FunctionCallNodeModel newV4 = GraphModel.CreateNode <FunctionCallNodeModel>("New Vector4", Vector2.left * 200, SpawnFlags.Default, n => n.MethodInfo = ctor); GraphModel.CreateEdge(log.GetParameterPorts().First(), newV4.OutputPort); var b = new RoslynTranslator(Stencil); var c = b.Translate(GraphModel, CompilationOptions.Default); SyntaxNode d = c.GetRoot(); StatementSyntax stmt = d.DescendantNodes().OfType <MethodDeclarationSyntax>().First(n => n.Identifier.ValueText == "A") .Body.Statements.First(); ExpressionSyntax arg = ((InvocationExpressionSyntax)((ExpressionStatementSyntax)stmt).Expression).ArgumentList.Arguments.Single().Expression; Assert.That(arg.ToFullString(), Is.EqualTo("new UnityEngine.Vector4(0F, 0F)")); }
public static IEnumerable <SyntaxNode> Build(this RoslynTranslator translator, LogNodeModel model, IPortModel portModel) { var obj = translator.BuildPort(model.InputPort).SingleOrDefault() as ExpressionSyntax; string methodName; switch (model.LogType) { case LogNodeModel.LogTypes.Message: methodName = nameof(Debug.Log); break; case LogNodeModel.LogTypes.Warning: methodName = nameof(Debug.LogWarning); break; case LogNodeModel.LogTypes.Error: methodName = nameof(Debug.LogError); break; default: throw new ArgumentOutOfRangeException(); } var arg = obj != null?Argument(obj) : Argument(LiteralExpression(SyntaxKind.NullLiteralExpression)); yield return(RoslynBuilder.MethodInvocation(methodName, IdentifierName(nameof(Debug)), arg)); }
public void NestedIfs() { var a = GraphModel.CreateFunction("A", Vector2.zero); StackBaseModel b, c; CreateIfThenElseStacks(a, "b", "c", out b, out c); var d = GraphModel.CreateStack("d", Vector2.left); var e = GraphModel.CreateStack("e", Vector2.left); b.CreateStackedNode <Type0FakeNodeModel>("b"); c.CreateStackedNode <Type0FakeNodeModel>("c"); d.CreateStackedNode <Type0FakeNodeModel>("d"); e.CreateStackedNode <Type0FakeNodeModel>("e"); var cIfNode = c.CreateStackedNode <IfConditionNodeModel>("if_c"); GraphModel.CreateEdge(b.InputPorts[0], cIfNode.ThenPort); GraphModel.CreateEdge(d.InputPorts[0], cIfNode.ElsePort); GraphModel.CreateEdge(e.InputPorts[0], b.OutputPorts[0]); GraphModel.CreateEdge(e.InputPorts[0], d.OutputPorts[0]); // as C has an if node, a common descendant of (C,X) must be a descendant of (B,D,X), here E Assert.That(RoslynTranslator.FindCommonDescendant(a, a, c), Is.EqualTo(e)); Assert.That(RoslynTranslator.FindCommonDescendant(a, b, c), Is.EqualTo(e)); }
SyntaxNode CompileCurrentGraphModel() { var roslynTr = new RoslynTranslator(GraphModel.Stencil); var ast = roslynTr.Translate(GraphModel, CompilationOptions.Profiling); return(ast.GetRoot()); }
public static StatementSyntax DeclareLocalVariable(this IVariableDeclarationModel decl, RoslynTranslator translator, bool useInitialization = true) { var variableDeclarationSyntax = decl.DeclareVariable(translator, useInitialization, false); return(SyntaxFactory.LocalDeclarationStatement(variableDeclarationSyntax)); }
public override void OnInspectorGUI() { VSGraphModel graph = (VSGraphModel)target; EditorGUILayout.LabelField("Stencil Properties"); EditorGUI.indentLevel++; EditorGUI.BeginChangeCheck(); var stencilObject = new SerializedObject(graph.Stencil); foreach (var propertyName in graph.Stencil.PropertiesVisibleInGraphInspector()) { EditorGUILayout.PropertyField(stencilObject.FindProperty(propertyName)); } stencilObject.ApplyModifiedProperties(); EditorGUI.indentLevel--; if (EditorGUI.EndChangeCheck()) { graph.Stencil.RecompilationRequested = true; } if (graph.Stencil is IHasOrderedStacks) { if (m_ReorderableList == null) { m_ReorderableList = new ReorderableList(null, typeof(IOrderedStack)) { displayAdd = false, displayRemove = false, drawHeaderCallback = rect => GUI.Label(rect, "Execution Order"), drawElementCallback = (rect, index, active, focused) => { var orderedStack = (IOrderedStack)m_ReorderableList.list[index]; GUI.Label(rect, orderedStack.Title); }, onReorderCallbackWithDetails = (list, oldIndex, newIndex) => { for (int i = 0; i < m_ReorderableList.list.Count; i++) { var orderedStack = (IOrderedStack)m_ReorderableList.list[i]; orderedStack.Order = i; } graph.Stencil.RecompilationRequested = true; } } } ; m_ReorderableList.list = RoslynTranslator.GetEntryPointStacks(graph).OfType <IOrderedStack>().OrderBy(x => x.Order).ToList(); m_ReorderableList.DoLayoutList(); } base.OnInspectorGUI(); } }
public void UnjoinedIfHasNoCommonDescendant() { var a = GraphModel.CreateFunction("A", Vector2.zero); StackBaseModel b, c; CreateIfThenElseStacks(a, "b", "c", out b, out c); Assert.That(RoslynTranslator.FindCommonDescendant(a, b, c), Is.Null); }
public static FieldDeclarationSyntax DeclareField(this IVariableDeclarationModel decl, RoslynTranslator translator, bool useInitialization = true) { var declaration = decl.DeclareVariable(translator, useInitialization, true); var modifier = SyntaxFactory.Token(decl.IsExposed ? SyntaxKind.PublicKeyword : SyntaxKind.PrivateKeyword); var fieldDeclaration = SyntaxFactory.FieldDeclaration(declaration) .WithModifiers(SyntaxFactory.TokenList(modifier)); return(fieldDeclaration); }
public void Test_Translate_SimpleResizableMethod() { GraphModel.CreateFunction("A", Vector2.zero); var b = new RoslynTranslator(Stencil); var c = b.Translate(GraphModel, CompilationOptions.Default); var d = c.GetRoot(); Assert.That(d.DescendantNodes().OfType <MethodDeclarationSyntax>().Where(n => n.Identifier.ValueText == "A").ToArray().Length, Is.EqualTo(1)); Assert.That(d.DescendantNodes().OfType <ParameterSyntax>().ToArray().Length, Is.EqualTo(0)); }
public void SimpleIf() { var a = GraphModel.CreateFunction("A", Vector2.zero); StackBaseModel b, c, d; CreateIfThenElseStacks(a, "b", "c", out b, out c); JoinStacks(b, c, "d", out d); Assert.That(RoslynTranslator.FindCommonDescendant(a, b, c), Is.EqualTo(d)); }
public void IfNoThen() { var a = GraphModel.CreateFunction("A", Vector2.zero); StackBaseModel b, c; CreateIfThenElseStacks(a, "b", "c", out b, out c); GraphModel.CreateEdge(b.InputPorts[0], c.OutputPorts[0]); Assert.That(RoslynTranslator.FindCommonDescendant(a, b, c), Is.EqualTo(b)); }
protected virtual void VisitStack(IStackModel stack, HashSet <IStackModel> visitedStacks, HashSet <INodeModel> visitedNodes) { visitedStacks.Add(stack); // instance/data ports on stacks foreach (var inputPortModel in stack.InputPorts) { if (inputPortModel.PortType != PortType.Execution && inputPortModel.Connected) { bool any = false; foreach (var connectionPortModel in inputPortModel.ConnectionPortModels) { if (!visitedNodes.Contains(connectionPortModel.NodeModel)) { VisitNode(connectionPortModel.NodeModel, visitedNodes); } any = true; stack.OnConnection(inputPortModel, connectionPortModel); } if (!any) { stack.OnConnection(inputPortModel, null); } } } // Still not visiting variable parameters... if (stack is IHasVariableDeclaration hasVariableDeclaration) { foreach (var variableDeclaration in hasVariableDeclaration.VariableDeclarations) { VisitVariableDeclaration(variableDeclaration); } } foreach (INodeModel nodeModel in stack.NodeModels) { VisitNode(nodeModel, visitedNodes); } foreach (StackBaseModel connectedStack in RoslynTranslator.GetConnectedStacks(stack)) { if (connectedStack == null || visitedStacks.Contains(connectedStack)) { continue; } VisitStack(connectedStack, visitedStacks, visitedNodes); } }
public void Test_Translate_UsingAlias() { var b = new RoslynTranslator(Stencil); b.AddUsingAlias("TestAlias", "UnityEditor.VisualScriptingTests.Roslyn.TestAlias"); var c = b.Translate(GraphModel, CompilationOptions.Default); var d = c.GetRoot(); var ud = d.DescendantNodes().OfType <UsingDirectiveSyntax>().Where(n => n.Alias != null).ToList(); Assert.That(ud.Count, Is.EqualTo(5)); Assert.That(ud.Count(u => u.Alias.Name.Identifier.Text == "TestAlias"), Is.EqualTo(1)); }
public void Test_Translate_DetectInfiniteLoop() { var function = GraphModel.CreateFunction("Function", Vector2.zero); var stack0 = GraphModel.CreateStack(string.Empty, Vector2.zero); var stack1 = GraphModel.CreateStack(string.Empty, Vector2.zero); GraphModel.CreateEdge(stack0.InputPorts[0], function.OutputPort); GraphModel.CreateEdge(stack0.InputPorts[0], stack1.OutputPorts[0]); GraphModel.CreateEdge(stack1.InputPorts[0], stack0.OutputPorts[0]); var b = new RoslynTranslator(Stencil); Assert.Throws <LoopDetectedException>(() => b.Translate(GraphModel, CompilationOptions.Default)); }
public void ThreeWayIf() { var a = GraphModel.CreateFunction("A", Vector2.zero); StackBaseModel b, c, d, e, f; CreateIfThenElseStacks(a, "b", "c", out b, out c); CreateIfThenElseStacks(c, "d", "e", out d, out e); JoinStacks(d, e, "f", out f); GraphModel.CreateEdge(f.InputPorts[0], b.OutputPorts[0]); Assert.That(RoslynTranslator.FindCommonDescendant(a, d, e), Is.EqualTo(f)); Assert.That(RoslynTranslator.FindCommonDescendant(a, b, c), Is.EqualTo(f)); }
public void Test_Translate_UsingDirective() { var type = typeof(TestObject); var a = GraphModel.CreateFunction("A", Vector2.zero); var i = typeof(TestObject).GetMethod(nameof(TestObject.DoStuff)); a.CreateStackedNode <FunctionCallNodeModel>("Do", 0, SpawnFlags.Default, n => n.MethodInfo = i); var b = new RoslynTranslator(Stencil); var c = b.Translate(GraphModel, CompilationOptions.Default); var d = c.GetRoot(); var ud = d.DescendantNodes().OfType <UsingDirectiveSyntax>(); Assert.That(ud.Count(n => n.Name.ToString() == type.Namespace), Is.EqualTo(1)); }
public void Test_Translate_SimpleMethod2Params() { var a = GraphModel.CreateFunction("A", Vector2.zero); a.CreateFunctionVariableDeclaration("l", typeof(int).GenerateTypeHandle(GraphModel.Stencil)); a.CreateAndRegisterFunctionParameterDeclaration("a", typeof(int).GenerateTypeHandle(GraphModel.Stencil)); var b = new RoslynTranslator(Stencil); var c = b.Translate(GraphModel, CompilationOptions.Default); var d = c.GetRoot(); Assert.That(d.DescendantNodes().OfType <MethodDeclarationSyntax>().Where(n => n.Identifier.ValueText == "A").ToArray().Length, Is.EqualTo(1)); Assert.That(d.DescendantNodes().OfType <ParameterSyntax>().ToArray().Length, Is.EqualTo(1)); Assert.That(d.DescendantNodes().OfType <LocalDeclarationStatementSyntax>().ToArray().Length, Is.EqualTo(1)); }
public static ExpressionSyntax BuildCall(RoslynTranslator translator, GetInputNodeModel model, string methodName, out ExpressionSyntax inputName) { if (model.InputPort.Connected || model.InputPort.EmbeddedValue != null) { inputName = translator.BuildPort(model.InputPort).FirstOrDefault() as ExpressionSyntax; } else { inputName = RoslynBuilder.EmptyStringLiteralExpression(); } var methodParameters = new[] { SyntaxFactory.Argument(inputName) }; var method = RoslynBuilder.MethodInvocation(methodName, typeof(Input).ToTypeSyntax(), methodParameters, Enumerable.Empty <TypeSyntax>()); return(method); }
public void TwoLevelIfs() { var a = GraphModel.CreateFunction("A", Vector2.zero); StackBaseModel b, c, d, e, f, g, h, i, j; CreateIfThenElseStacks(a, "b", "c", out b, out c); CreateIfThenElseStacks(b, "d", "e", out d, out e); CreateIfThenElseStacks(c, "f", "g", out f, out g); JoinStacks(d, e, "h", out h); JoinStacks(f, g, "i", out i); JoinStacks(h, i, "h", out j); Assert.That(RoslynTranslator.FindCommonDescendant(a, b, c), Is.EqualTo(j)); Assert.That(RoslynTranslator.FindCommonDescendant(a, d, e), Is.EqualTo(h)); Assert.That(RoslynTranslator.FindCommonDescendant(a, f, g), Is.EqualTo(i)); Assert.That(RoslynTranslator.FindCommonDescendant(a, d, f), Is.EqualTo(j)); }
public ExpressionSyntax BuildCall(RoslynTranslator translator, IPortModel portModel, out ExpressionSyntax inputName, out string methodName) { if (InputPort.IsConnected || InputPort.EmbeddedValue != null) { inputName = translator.BuildPort(InputPort).FirstOrDefault() as ExpressionSyntax; } else { inputName = SyntaxFactory.LiteralExpression( SyntaxKind.DefaultLiteralExpression, SyntaxFactory.Token(SyntaxKind.DefaultKeyword)); } var method = RoslynBuilder.MethodInvocation(methodName = MethodName(portModel), typeof(Input).ToTypeSyntax(), SyntaxFactory.Argument(inputName)); return(method); }
public void Test_Field_Name_Declaration() { //ARRANGE var translator = new RoslynTranslator(GraphModel.Stencil); Mock <IVariableDeclarationModel> mock = CreateFieldDeclarationMock(); //ACT var declaration = mock.Object.DeclareField(translator); //ASSERT var declaredFieldName = declaration .DescendantNodes().OfType <VariableDeclarationSyntax>() .First() .Variables.First().Identifier.Value; Assert.That(declaredFieldName, Is.EqualTo("fieldA")); }
public void Test_Field_Type_Declaration() { //ARRANGE var translator = new RoslynTranslator(Stencil); Mock <IVariableDeclarationModel> mock = CreateFieldDeclarationMock(); //ACT var declaration = mock.Object.DeclareField(translator); //ASSERT var declaredFieldTypename = declaration .DescendantNodes().OfType <VariableDeclarationSyntax>() .First() .Type.ToFullString(); Assert.That(declaredFieldTypename, Is.EqualTo("int")); }
public void Test_Private_Field_Declaration() { //ARRANGE var translator = new RoslynTranslator(Stencil); Mock <IVariableDeclarationModel> mock = CreateFieldDeclarationMock(); mock.Setup(decl => decl.IsExposed).Returns(false); //ACT var declaration = mock.Object.DeclareField(translator); //ASSERT var fieldScope = declaration .Modifiers.First().ValueText; Assert.That(fieldScope, Is.EqualTo("private")); }
public void IfNoThenElseIfNoThen() { var a = GraphModel.CreateFunction("A", Vector2.zero); StackBaseModel b, c; CreateIfThenElseStacks(a, "b", "c", out b, out c); b.CreateStackedNode <Type0FakeNodeModel>("b"); c.CreateStackedNode <Type0FakeNodeModel>("c"); var cIfNode = c.CreateStackedNode <IfConditionNodeModel>("if_c"); GraphModel.CreateEdge(b.InputPorts[0], cIfNode.ThenPort); // as C has an if node with a disconnect else branch, B cannot be a descendant of both branches // so common(b,c) should return null Assert.That(RoslynTranslator.FindCommonDescendant(a, b, c), Is.Null); }
public void FourWayJoin() { var a = GraphModel.CreateFunction("A", Vector2.zero); StackBaseModel b, c, d, e, f, g, h; CreateIfThenElseStacks(a, "b", "c", out b, out c); CreateIfThenElseStacks(b, "d", "e", out d, out e); CreateIfThenElseStacks(c, "f", "g", out f, out g); JoinStacks(d, e, "h", out h); GraphModel.CreateEdge(h.InputPorts[0], f.OutputPorts[0]); GraphModel.CreateEdge(h.InputPorts[0], g.OutputPorts[0]); Assert.That(RoslynTranslator.FindCommonDescendant(a, b, c), Is.EqualTo(h)); Assert.That(RoslynTranslator.FindCommonDescendant(a, d, e), Is.EqualTo(h)); Assert.That(RoslynTranslator.FindCommonDescendant(a, f, g), Is.EqualTo(h)); Assert.That(RoslynTranslator.FindCommonDescendant(a, d, f), Is.EqualTo(h)); }
public void VisitGraph(VSGraphModel vsGraphModel) { HashSet <IStackModel> visitedStacks = new HashSet <IStackModel>(); HashSet <INodeModel> visitedNodes = new HashSet <INodeModel>(); foreach (var rootStack in RoslynTranslator.GetEntryPointStacks(vsGraphModel)) { VisitStack(rootStack, visitedStacks, visitedNodes); } // floating stacks foreach (var stack in vsGraphModel.StackModels) { if (visitedStacks.Contains(stack)) { continue; } VisitStack(stack, visitedStacks, visitedNodes); } // floating nodes foreach (var node in vsGraphModel.NodeModels) { if (node == null || node is IStackModel || visitedNodes.Contains(node)) { continue; } VisitNode(node, visitedNodes); } foreach (var variableDeclaration in vsGraphModel.GraphVariableModels) { VisitVariableDeclaration(variableDeclaration); } foreach (var edgeModel in vsGraphModel.EdgeModels) { VisitEdge(edgeModel); } }
public void Test_Initialized_Field() { //ARRANGE var translator = new RoslynTranslator(Stencil); Mock <IVariableDeclarationModel> mock = CreateFieldDeclarationMock(); //mock.Setup(decl => decl.requiresInitialization).Returns(true); mock.Setup(decl => decl.InitializationModel).Returns(GraphModel.CreateConstantNode("var1_init", typeof(int).GenerateTypeHandle(GraphModel.Stencil), Vector2.zero, SpawnFlags.Orphan | SpawnFlags.Default)); //ACT var variableDeclarationSyntax = mock.Object.DeclareField(translator); //ASSERT var numberOfInitStatement = variableDeclarationSyntax .DescendantNodes().OfType <EqualsValueClauseSyntax>() .Count(); Assert.That(numberOfInitStatement, Is.EqualTo(1)); }
public void Test_Initialized_Field_Is_Explicitly_Typed() { //ARRANGE var translator = new RoslynTranslator(Stencil); Mock <IVariableDeclarationModel> mock = CreateFieldDeclarationMock(); //mock.Setup(decl => decl.requiresInitialization).Returns(true); mock.Setup(decl => decl.InitializationModel).Returns(GraphModel.CreateConstantNode("var1_init", typeof(int).GenerateTypeHandle(GraphModel.Stencil), Vector2.zero, SpawnFlags.Orphan | SpawnFlags.Default)); //ACT var fieldDeclarationSyntax = mock.Object.DeclareField(translator); //ASSERT var isImplicitlyType = fieldDeclarationSyntax .DescendantNodes().OfType <VariableDeclarationSyntax>() .First().Type.IsVar; Assert.That(isImplicitlyType, Is.False); }
public void Test_Profile() { // turn on profiling FunctionModel isIntEvenFunction = CreateIsIntEvenFunction(); // enable profiling for this function isIntEvenFunction.EnableProfiling = true; // needed to set the owning function of each stack new PortInitializationTraversal().VisitGraph(GraphModel); // compile graph var roslynTr = new RoslynTranslator(Stencil); var ast = roslynTr.Translate(GraphModel, CompilationOptions.Profiling); SyntaxNode astRoot = ast.GetRoot(); // check there's only one IsIntEven method IEnumerable <MethodDeclarationSyntax> methods = astRoot.DescendantNodes().OfType <MethodDeclarationSyntax>().ToList(); Assert.That(methods.Count, Is.EqualTo(1)); MethodDeclarationSyntax method = methods.First(); // check there's only a CustomSampler declaration and then a try/finally statement including everything BlockSyntax body = method.Body; Assert.That(body.Statements.Count, Is.EqualTo(2)); StatementSyntax statement1 = body.Statements[0]; Assert.That(statement1, Is.TypeOf(typeof(LocalDeclarationStatementSyntax))); StatementSyntax statement2 = body.Statements[1]; Assert.That(statement2, Is.TypeOf(typeof(TryStatementSyntax))); TryStatementSyntax tryStatement = (TryStatementSyntax)statement2; // check that there is code inside the try and finally statements Assert.That(tryStatement.Block.Statements.Count, Is.GreaterThan(0)); Assert.That(tryStatement.Finally.Block.Statements.Count, Is.GreaterThan(0)); }
public void UpdateNodeState(Dictionary <IGraphElementModel, GraphElement> modelsToNodeMapping) { void ProcessDependency(INodeModel nodeModel, ModelState state) { if (nodeModel.State == ModelState.Disabled) { state = ModelState.Disabled; } if (modelsToNodeMapping.TryGetValue(nodeModel, out var nodeUI) && nodeUI is INodeState nodeState && state == ModelState.Enabled) { nodeState.UIState = NodeUIState.Enabled; } if (!m_DependenciesByNode.TryGetValue(nodeModel, out var dependencies)) { return; } foreach (var dependency in dependencies) { ProcessDependency(dependency.Value.DependentNode, state); } } foreach (var node in modelsToNodeMapping.Values.OfType <INodeState>()) { node.UIState = node.GraphElementModel is INodeModel nodeModel && nodeModel.State == ModelState.Disabled ? NodeUIState.Disabled : NodeUIState.Unused; } foreach (var root in RoslynTranslator.GetEntryPointStacks((VSGraphModel)this.m_VseGraphView.store.GetState().CurrentGraphModel)) { ProcessDependency(root, ModelState.Enabled); } foreach (var node in modelsToNodeMapping.Values.OfType <INodeState>()) { node.ApplyNodeState(); } }