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)")); }
void CreateStackAndLogs(out StackBaseModel stack, out FunctionCallNodeModel[] log, int logCount = 1) { stack = GraphModel.CreateFunction("F", Vector2.zero); log = new FunctionCallNodeModel[logCount]; for (int i = 0; i < logCount; i++) { log[i] = stack.CreateFunctionCallNode(k_LogMethodInfo); } }
public void GenericInputTypeIsSolved(ClassType t, string methodName, Type connectedType, int methodParameterIndex, Type expectedInputType) { Type methodDeclaringType = t == ClassType.Plain ? typeof(C) : typeof(D <>); FunctionCallNodeModel call = GraphModel.CreateNode <FunctionCallNodeModel>("funcNode", Vector2.zero); call.GraphModel = GraphModel; call.MethodInfo = methodDeclaringType.GetMethod(methodName); Assert.NotNull(call.MethodInfo); var param = call.MethodInfo.GetParameters()[methodParameterIndex]; call.DefineNode(); var p = new PortModel { Direction = Direction.Output, PortType = PortType.Data, DataType = connectedType.GenerateTypeHandle(Stencil), }; var parameterPort = call.GetPortForParameter(param.Name); call.OnConnection(parameterPort, p); Assert.That(parameterPort.DataType, Is.EqualTo(expectedInputType.GenerateTypeHandle(Stencil))); }
public void GenericOutputTypeIsSolved(ClassType t, string methodName, Type connectedType, int methodParameterIndex, Type expectedOutputType) { Type methodDeclaringType = t == ClassType.Plain ? typeof(C) : typeof(D <>); FunctionCallNodeModel call = GraphModel.CreateNode <FunctionCallNodeModel>("funcNode", Vector2.zero); call.GraphModel = GraphModel; call.MethodInfo = methodDeclaringType.GetMethod(methodName); Assert.That(call.MethodInfo, Is.Not.Null); call.DefineNode(); IPortModel parameterPort; if (methodParameterIndex == k_InstanceIndex) { Assert.That(call.MethodInfo.IsStatic || call.MethodInfo.IsConstructor, Is.False); parameterPort = call.InstancePort; } else { var param = call.MethodInfo.GetParameters()[methodParameterIndex]; parameterPort = call.GetPortForParameter(param.Name); } var p = new PortModel { Direction = Direction.Output, PortType = PortType.Data, DataType = connectedType.GenerateTypeHandle(Stencil), }; call.OnConnection(parameterPort, p); if (expectedOutputType != typeof(void)) { Assert.That(call.OutputPort.DataType, Is.EqualTo(expectedOutputType.GenerateTypeHandle(Stencil))); } }
public void Test_EmbeddedConstantIsUsedWhenDisconnected([Values] TestingMode mode) { const float outerValue = 42f; const float innerValue = 347f; // make sure that we really test values that are not default Assume.That(outerValue, Is.Not.EqualTo(default(float))); Assume.That(innerValue, Is.Not.EqualTo(default(float))); var stencil = GraphModel.Stencil; 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); var logParameterPort = log.GetParameterPorts().Single(); // Math.Abs(...) MethodInfo absMethod = typeof(Mathf).GetMethod(nameof(Mathf.Abs), new[] { typeof(float) }); Assume.That(absMethod, Is.Not.Null); FunctionCallNodeModel abs = GraphModel.CreateNode <FunctionCallNodeModel>("Abs", Vector2.zero, SpawnFlags.Default, n => n.MethodInfo = absMethod); var absParameterPort = abs.GetParameterPorts().Single(); ((FloatConstantModel)abs.InputConstantsById[absParameterPort.UniqueId]).value = innerValue; GraphModel.CreateEdge(logParameterPort, abs.OutputPort); // float IConstantNodeModel outerFloat = GraphModel.CreateConstantNode("float42", typeof(float).GenerateTypeHandle(stencil), Vector2.zero); Assume.That(outerFloat, Is.Not.Null); ((FloatConstantModel)outerFloat).value = outerValue; string innerFloatString = SyntaxFactory.LiteralExpression( SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(innerValue)).ToFullString(); string outerFloatString = SyntaxFactory.LiteralExpression( SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(outerValue)).ToFullString(); TestPrereqActionPostreq(mode, () => { // outer float disconnected, check that we use the inner value SyntaxNode astRoot = CompileCurrentGraphModel(); LiteralExpressionSyntax literalInsideLogAbs = GetLiteralInsideLogAbs(astRoot); Assert.That(literalInsideLogAbs.ToFullString(), Is.EqualTo(innerFloatString)); return(new CreateEdgeAction(absParameterPort, outerFloat.OutputPort)); }, () => { // outer float connected, check that we use the outer value SyntaxNode astRoot = CompileCurrentGraphModel(); LiteralExpressionSyntax literalInsideLogAbs = GetLiteralInsideLogAbs(astRoot); Assert.That(literalInsideLogAbs.ToFullString(), Is.EqualTo(outerFloatString)); }); }
public static IEnumerable <SyntaxNode> BuildFunctionCall(this RoslynTranslator translator, FunctionCallNodeModel call, IPortModel portModel) { if (call.MethodInfo == null) { yield break; } var instance = BuildArgumentList(translator, call, out var argumentList); var typeArgumentList = new List <TypeSyntax>(); if (call.MethodInfo.IsGenericMethod) { foreach (var typeArgument in call.TypeArguments) { typeArgumentList.Add(TypeSystem.BuildTypeSyntax(typeArgument.Resolve(translator.Stencil))); } } TypeArgumentListSyntax typeArgList = null; if (typeArgumentList.Any()) { typeArgList = SyntaxFactory.TypeArgumentList(SyntaxFactory.SingletonSeparatedList(typeArgumentList.First())); } SyntaxNode method = RoslynBuilder.MethodInvocation(call.Title, call.MethodInfo, instance, argumentList, typeArgList); yield return(method); }
public static IEnumerable <SyntaxNode> BuildFunctionCall(this RoslynEcsTranslator translator, FunctionCallNodeModel call, IPortModel portModel) { if (call.MethodInfo == null) { yield break; } var instance = translator.BuildArgumentList(call, out var argumentList); var typeArgumentList = new List <TypeSyntax>(); if (call.MethodInfo.IsGenericMethod) { typeArgumentList.AddRange(call.TypeArguments.Select(t => IdentifierName(t.GetMetadata(translator.Stencil).Name))); } TypeArgumentListSyntax typeArgList = null; if (typeArgumentList.Any()) { typeArgList = TypeArgumentList(SingletonSeparatedList(typeArgumentList.First())); } var method = RoslynBuilder.MethodInvocation(call.MethodInfo.Name, call.MethodInfo, instance, argumentList, typeArgList); if (method is ExpressionSyntax exp && call.MethodInfo is MethodInfo mi && mi.ReturnType != typeof(void) && call.MethodInfo.DeclaringType.Namespace.StartsWith("UnityEngine")) { var key = call.DeclaringType.Name(translator.Stencil).ToPascalCase() + call.Title.ToPascalCase(); yield return(translator.context.GetCachedValue(key, exp, mi.ReturnType.GenerateTypeHandle(translator.Stencil))); }