Example #1
0
        public IEnumerable <MethodDefinition> GenerateCommand(CommandDeclaration command, string handleTypeName, TypeDeclaration handleType, bool isExtension = false)
        {
            var lastParam = command.Params.Last();

            bool lastParamIsArray = lastParam.Type.PointerType == PointerType.Pointer &&
                                    lastParam.Dimensions != null &&
                                    lastParam.Dimensions.Any(x => x.Type != LenType.NullTerminated);

            bool lastParamLenFieldByRef = lastParamIsArray &&
                                          lastParam.Dimensions[0].Value is LenExpressionToken &&
                                          command.Params.Single(x => x.VkName == ((LenExpressionToken)lastParam.Dimensions[0].Value).Value).Type.PointerType == PointerType.Pointer;

            bool lastParamReturns = !lastParam.Type.PointerType.IsConst() &&
                                    (typeData[lastParam.Type.VkName].IsOutputOnly ||
                                     lastParam.Type.PointerType.GetPointerCount() == 2 ||
                                     (typeData[lastParam.Type.VkName].Pattern != TypePattern.MarshalledStruct && typeData[lastParam.Type.VkName].Pattern != TypePattern.NonMarshalledStruct) ||
                                     lastParamLenFieldByRef ||
                                     command.Verb == "get") &&
                                    (command.ReturnType == "VkResult" || command.ReturnType == "void");

            bool enumeratePattern = command.Verb == "enumerate" || (lastParamIsArray && lastParamLenFieldByRef);
            bool isBatchMethod    = lastParamIsArray && !enumeratePattern;

            yield return(this.GenerateCommandVariant(command, handleTypeName, handleType, isExtension, enumeratePattern, lastParamIsArray, lastParamReturns, false));

            if (isBatchMethod)
            {
                yield return(this.GenerateCommandVariant(command, handleTypeName, handleType, isExtension, enumeratePattern, lastParamIsArray, lastParamReturns, true));
            }
        }
Example #2
0
 private static CommandDeclaration GetCommandDeclaration(DependencyObject obj)
 {
     if (!_commandDeclarations.ContainsKey(obj))
     {
         CommandDeclaration decl = new CommandDeclaration(obj);
         _commandDeclarations.Add(obj, decl);
     }
     return(_commandDeclarations[obj]);
 }
Example #3
0
        public HotkeyCommand(CommandManager <TSettings> parentManager, KeyBinding binding, Func <TSettings> currentSettingsGetter)
        {
            Debug.Assert(parentManager != null);
            Debug.Assert(binding != null);
            Debug.Assert(currentSettingsGetter != null);

            _parentManager         = parentManager;
            Hotkey                 = binding.Keys ?? throw new ArgumentNullException(nameof(binding.Keys));
            Enabled                = binding.Enabled;
            _commandToDispatch     = binding.Command ?? throw new ArgumentNullException(nameof(binding.Command));
            _currentSettingsGetter = currentSettingsGetter ?? throw new ArgumentNullException(nameof(currentSettingsGetter));
        }
Example #4
0
        private CodeCompileUnit CompileImportEmployeeCommand()
        {
            var commandDeclaration = new CommandDeclaration("ImportEmployeeCommand",
                                                            new[]
            {
                new PropertyDeclaration("EmployeeNumber", new SimpleType(typeof(int))),
                new PropertyDeclaration("FirstName", new StringReferenceType()),
                new PropertyDeclaration("LastName", new StringReferenceType())
            });
            var model = CreateSemanticModelWith(commandDeclaration);

            return(CodeDomCompiler.Compile(model));
        }
Example #5
0
        public static CodeTypeDeclaration CreateCommandDeclaration(
            SemanticModel model, NamespaceName namespaceName,
            CommandDeclaration declaration,
            CommandConventions conventions)
        {
            var type = CreateTypeWithValueSemantics(
                ValueObjectSpecification.CreateClass(
                    namespaceName, declaration.Name,
                    declaration.Properties.ToArray(),
                    conventions.BaseTypes,
                    true, false),
                model.KnownTypes);

            return(type);
        }
Example #6
0
        public void CommandDeclaration_WithNestedDto_Dto_ShouldCompile()
        {
            var dtoDeclaration     = new DtoDeclaration("AmountDto", new[] { new PropertyDeclaration("Amount", new SimpleType(typeof(decimal))) });
            var commandDeclaration = new CommandDeclaration("ImportEmployeeCommand",
                                                            new[]
            {
                new PropertyDeclaration("EmployeeNumber", new SimpleType(typeof(int))),
                new PropertyDeclaration("Salary", new TypeName("AmountDto"))
            });
            var model  = CreateSemanticModelWith(dtoDeclaration, commandDeclaration);
            var actual = CodeDomCompiler.Compile(model);

            Assert.That(actual, Is.Not.Null);
            var source = CompileToSource(actual);

            Assert.That(source, Is.StringContaining("class ImportEmployeeCommand"));
            Assert.That(source, Is.StringMatching(@"public.*AmountDto\s+Salary"));
        }
Example #7
0
        public void CommandDeclaration_WithNestedDto_Enum_ShouldCompile()
        {
            var enumDeclaration    = new EnumDeclaration("Role", new[] { "Tester", "Developer" });
            var commandDeclaration = new CommandDeclaration("ImportEmployeeCommand",
                                                            new[]
            {
                new PropertyDeclaration("EmployeeNumber", new SimpleType(typeof(int))),
                new PropertyDeclaration("Role", new TypeName("Role")),
            });
            var model  = CreateSemanticModelWith(enumDeclaration, commandDeclaration);
            var actual = CodeDomCompiler.Compile(model);

            Assert.That(actual, Is.Not.Null);
            var source = CompileToSource(actual);

            Assert.That(source, Is.StringContaining("class ImportEmployeeCommand"));
            Assert.That(source, Is.StringMatching(@"public.*Role\s+Role"));
        }
Example #8
0
 private ApplicationServiceDeclaration CreateImportApplicationServiceDeclaration(CommandDeclaration commandDeclaration)
 {
     return(new ApplicationServiceDeclaration("ImportApplicationService", new[]
     {
         commandDeclaration
     }));
 }
Example #9
0
        public void Visit(CommandDeclaration node)
        {
            var fullName = FullName(node.Name);

            _knownTypes.Add(new KnownType(fullName, false));
        }
Example #10
0
        public MethodDefinition GenerateCommand(CommandDeclaration command, string handleTypeName, TypeDeclaration handleType, bool isExtension = false)
        {
            var newMethod = new MethodDefinition
            {
                Name       = command.Name,
                ReturnType = "void",
                Comment    = this.commentGenerator.Lookup(command.VkName),
                IsPublic   = true,
                IsUnsafe   = true,
                IsStatic   = isExtension,
                AllocatesUnmanagedMemory = true
            };

            var handleExpression = isExtension ? Variable("extendedHandle") : This;

            var handleLookup = new Dictionary <string, Action <ExpressionBuilder> >
            {
                [handleTypeName] = handleExpression
            };

            if (handleType.Parent != null)
            {
                handleLookup.Add(handleType.Parent, Member(handleExpression, "parent"));
            }

            Action <ExpressionBuilder> GetHandle(string handleName)
            {
                if (!handleLookup.TryGetValue(handleName, out var result))
                {
                    return(Default(this.typeData[handleName].Name));
                }

                return(result);
            }

            var lastParam = command.Params.Last();

            bool lastParamIsArray = lastParam.Type.PointerType == PointerType.Pointer &&
                                    lastParam.Dimensions != null &&
                                    lastParam.Dimensions.Any(x => x.Type != LenType.NullTerminated);

            bool lastParamLenFieldByRef = lastParamIsArray &&
                                          lastParam.Dimensions[0].Value is LenExpressionToken &&
                                          command.Params.Single(x => x.VkName == ((LenExpressionToken)lastParam.Dimensions[0].Value).Value).Type.PointerType == PointerType.Pointer;

            bool lastParamReturns = !lastParam.Type.PointerType.IsConst() &&
                                    (typeData[lastParam.Type.VkName].IsOutputOnly ||
                                     lastParam.Type.PointerType.GetPointerCount() == 2 ||
                                     (typeData[lastParam.Type.VkName].Pattern != TypePattern.MarshalledStruct && typeData[lastParam.Type.VkName].Pattern != TypePattern.NonMarshalledStruct) ||
                                     lastParamLenFieldByRef ||
                                     command.Verb == "get") &&
                                    (command.ReturnType == "VkResult" || command.ReturnType == "void");

            if (command.HandleParamsCount == 0)
            {
                Debug.Assert(lastParamReturns);

                newMethod.IsStatic = true;
            }

            bool enumeratePattern = command.Verb == "enumerate" || (lastParamIsArray && lastParamLenFieldByRef);

            int parameterIndex = 0;

            newMethod.ParamActions  = new List <ParamActionDefinition>();
            newMethod.MemberActions = new List <MethodAction>();

            var marshalFromActions = new List <MethodAction>();
            var marshalMidActions  = new List <MethodAction>();
            var marshalToActions   = new List <MethodAction>();

            var marshalledValues = new List <Action <ExpressionBuilder> >();

            if (isExtension)
            {
                var extendedHandleType = this.nameLookup.Lookup(new TypeReference {
                    VkName = handleTypeName
                }, false);

                newMethod.ParamActions.Add(new ParamActionDefinition
                {
                    Param = new ParamDefinition
                    {
                        Name    = "extendedHandle",
                        Type    = "this " + extendedHandleType,
                        Comment = new List <string>
                        {
                            $"The {handleType.Name} handle to extend."
                        }
                    }
                });

                marshalToActions.Add(new DeclarationAction
                {
                    MemberType = "CommandCache",
                    MemberName = "commandCache"
                });

                marshalToActions.Add(new AssignAction
                {
                    TargetExpression = Variable("commandCache"),
                    ValueExpression  = Member(Variable("extendedHandle"), "commandCache")
                });
            }

            foreach (var parameter in command.Params)
            {
                var newParams = this.GenerateParameter(command, newMethod, parameter, parameterIndex, enumeratePattern, lastParamIsArray, lastParamReturns, marshalFromActions, marshalMidActions, marshalToActions, marshalledValues, GetHandle, handleLookup);

                if (newParams != null)
                {
                    newMethod.ParamActions.AddRange(newParams);
                }

                parameterIndex++;
            }

            string invokeReturnType = null;
            string invokeReturnName = null;;

            if (command.ReturnType == "VkResult")
            {
                invokeReturnType = this.typeData["VkResult"].Name;
                invokeReturnName = "methodResult";
            }
            else if (this.typeData[command.ReturnType].Pattern == TypePattern.Delegate)
            {
                newMethod.ReturnType = "IntPtr";
                invokeReturnName     = "result";
            }

            newMethod.MemberActions.AddRange(marshalToActions);

            string delegateName = "SharpVk.Interop." + string.Join(".", this.namespaceMap.Map(command.Extension)) + $".{command.HandleTypeName}{command.Name}Delegate";

            newMethod.MemberActions.Add(new InvokeAction
            {
                TypeName       = "Interop.Commands",
                MethodName     = command.VkName,
                ReturnName     = invokeReturnName,
                ReturnType     = invokeReturnType,
                LookupDelegate = command.Extension != null,
                DelegateName   = delegateName,
                Parameters     = marshalledValues.ToArray()
            });

            if (command.ReturnType == "VkResult")
            {
                newMethod.MemberActions.Add(new ValidateAction
                {
                    VariableName = "methodResult"
                });
            }

            if (enumeratePattern)
            {
                newMethod.MemberActions.AddRange(marshalMidActions);

                newMethod.MemberActions.Add(new InvokeAction
                {
                    TypeName       = "Interop.Commands",
                    MethodName     = command.VkName,
                    LookupDelegate = command.Extension != null,
                    Parameters     = marshalledValues.ToArray()
                });
            }

            newMethod.MemberActions.AddRange(marshalFromActions);

            return(newMethod);
        }
Example #11
0
        private IEnumerable <ParamActionDefinition> GenerateParameter(CommandDeclaration command, MethodDefinition newMethod, ParamDeclaration parameter, int parameterIndex, bool isEnumeratePattern, bool isLastParamArray, bool lastParamReturns, List <MethodAction> marshalFromActions, List <MethodAction> marshalMidActions, List <MethodAction> marshalToActions, List <Action <ExpressionBuilder> > marshalledValues, Func <string, Action <ExpressionBuilder> > getHandle, Dictionary <string, Action <ExpressionBuilder> > handleLookup)
        {
            string paramName = parameter.Name;
            var    paramType = typeData[parameter.Type.VkName];

            string GetMarshalledName(string baseName)
            {
                return("marshalled" + baseName.TrimStart('@').FirstToUpper());
            }

            List <ParamActionDefinition> result = new List <ParamActionDefinition>();

            if (parameterIndex >= command.HandleParamsCount)
            {
                if (lastParamReturns && parameterIndex == command.Params.Count() - 2 && isEnumeratePattern)
                {
                    newMethod.MemberActions.Add(new DeclarationAction
                    {
                        MemberType = paramType.Name,
                        MemberName = paramName
                    });

                    marshalledValues.Add(AddressOf(Variable(paramName)));

                    var patternInfo = new MemberPatternInfo();

                    this.memberPatternRules.ApplyFirst(command.Params, command.Params.Last(), new MemberPatternContext(command.Verb, true, command.Extension, getHandle, command.VkName), patternInfo);

                    string marshalledName = GetMarshalledName(patternInfo.Interop.Name);

                    marshalMidActions.Add(new AssignAction
                    {
                        Type             = AssignActionType.Alloc,
                        MemberType       = patternInfo.InteropFullType.TrimEnd('*'),
                        TargetExpression = Variable(marshalledName),
                        LengthExpression = Cast("uint", Variable(paramName))
                    });
                }
                else if (lastParamReturns && parameterIndex == command.Params.Count() - 1)
                {
                    if (isLastParamArray)
                    {
                        var patternInfo = new MemberPatternInfo();

                        this.memberPatternRules.ApplyFirst(command.Params, parameter, new MemberPatternContext(command.Verb, true, command.Extension, getHandle, command.VkName), patternInfo);

                        string marshalledName = GetMarshalledName(patternInfo.Interop.Name);

                        marshalToActions.Add(new DeclarationAction
                        {
                            MemberType = patternInfo.InteropFullType,
                            MemberName = marshalledName
                        });

                        var newMarshalFrom = patternInfo.MarshalFrom.Select(action => action(targetName => Variable("result"), valueName => Variable(GetMarshalledName(valueName)))).ToArray();

                        if (!isEnumeratePattern)
                        {
                            var lengthExpression = newMarshalFrom.OfType <AssignAction>().First(x => x.IsLoop).LengthExpression;

                            marshalToActions.Add(new AssignAction
                            {
                                Type             = AssignActionType.Alloc,
                                MemberType       = patternInfo.InteropFullType.TrimEnd('*'),
                                TargetExpression = Variable(marshalledName),
                                LengthExpression = lengthExpression
                            });
                        }

                        marshalFromActions.AddRange(newMarshalFrom);

                        marshalledValues.Add(Variable(marshalledName));

                        newMethod.ReturnType = patternInfo.ReturnType ?? patternInfo.Public.Single().Type;
                    }
                    else
                    {
                        var patternInfo = new MemberPatternInfo();

                        var effectiveParam = new ParamDeclaration
                        {
                            Name       = parameter.Name,
                            Type       = parameter.Type.Deref(),
                            Dimensions = parameter.Dimensions,
                            VkName     = parameter.VkName
                        };

                        this.memberPatternRules.ApplyFirst(command.Params, effectiveParam, new MemberPatternContext(command.Verb, true, command.Extension, getHandle, command.VkName), patternInfo);

                        string marshalledName = GetMarshalledName(patternInfo.Interop.Name);

                        marshalToActions.Add(new DeclarationAction
                        {
                            MemberType = patternInfo.InteropFullType,
                            MemberName = marshalledName
                        });

                        marshalFromActions.AddRange(patternInfo.MarshalFrom.Select(action => action(targetName => Variable("result"), valueName => Variable(GetMarshalledName(valueName)))));

                        marshalledValues.Add(AddressOf(Variable(marshalledName)));

                        newMethod.ReturnType = patternInfo.Public.Single().Type;
                    }
                }
                else
                {
                    var patternInfo = new MemberPatternInfo();

                    this.memberPatternRules.ApplyFirst(command.Params, parameter, new MemberPatternContext(command.Verb, true, command.Extension, getHandle, command.VkName), patternInfo);

                    var actionList = marshalToActions;

                    Func <string, Action <ExpressionBuilder> > getValue = valueName => Variable(valueName);

                    foreach (var publicMember in patternInfo.Public)
                    {
                        result.Add(new ParamActionDefinition
                        {
                            Param = new ParamDefinition
                            {
                                Name         = publicMember.Name,
                                Comment      = publicMember.Comment,
                                Type         = publicMember.Type,
                                DefaultValue = publicMember.DefaultValue
                            }
                        });
                    }

                    if (patternInfo.MarshalTo.Any())
                    {
                        string marshalledName = patternInfo.Interop.Name;

                        if (patternInfo.Public.Any())
                        {
                            marshalledName = GetMarshalledName(patternInfo.Interop.Name);
                        }

                        var newMarshalToActions = patternInfo.MarshalTo.Select(action => action(targetName => Variable(marshalledName), getValue));

                        var  lastParam         = command.Params.Last();
                        bool isLenForLastParam = lastParamReturns && lastParam.Dimensions != null && lastParam.Dimensions.Any(dimension => dimension.Type == LenType.Expression && this.tokenCheck.Check(dimension.Value, parameter.VkName));

                        if (!isLenForLastParam &&
                            newMarshalToActions.Count() == 1 &&
                            newMarshalToActions.First() is AssignAction newAssignAction &&
                            newAssignAction.Type == AssignActionType.Assign &&
                            !newAssignAction.IsLoop)
                        {
                            marshalledValues.Add(newAssignAction.ValueExpression);
                        }
                        else
                        {
                            marshalToActions.Add(new DeclarationAction
                            {
                                MemberType = patternInfo.InteropFullType,
                                MemberName = marshalledName
                            });

                            marshalledValues.Add(Variable(marshalledName));

                            actionList.AddRange(newMarshalToActions);
                        }
                    }

                    foreach (var lookup in patternInfo.HandleLookup)
                    {
                        handleLookup[lookup.Item1] = lookup.Item2(getValue);
                    }
                }
            }
Example #12
0
        private MethodDefinition GenerateCommandVariant(CommandDeclaration command, string handleTypeName, TypeDeclaration handleType, bool isExtension, bool enumeratePattern, bool lastParamIsArray, int returnParamsCount, bool isBatchSingleMethod)
        {
            var handleExpression = isExtension ? Variable("extendedHandle") : This;

            var handleLookup = new Dictionary <string, Action <ExpressionBuilder> >
            {
                [handleTypeName] = handleExpression
            };

            if (handleType.Parent != null)
            {
                handleLookup.Add(handleType.Parent, Member(handleExpression, "parent"));
            }

            Action <ExpressionBuilder> GetHandle(string handleName)
            {
                if (!handleLookup.TryGetValue(handleName, out var result))
                {
                    return(Default(this.typeData[handleName].Name));
                }

                return(result);
            }

            string methodName = command.Name;

            if (isBatchSingleMethod && methodName.EndsWith("s"))
            {
                methodName = methodName.Substring(0, methodName.Length - 1);
            }

            var newMethod = new MethodDefinition
            {
                Name       = methodName,
                ReturnType = "void",
                Comment    = this.commentGenerator.Lookup(command.VkName),
                IsPublic   = true,
                IsUnsafe   = true,
                IsStatic   = isExtension,
                AllocatesUnmanagedMemory = true
            };

            newMethod.ParamActions  = new List <ParamActionDefinition>();
            newMethod.MemberActions = new List <MethodAction>();

            if (command.HandleParamsCount == 0)
            {
                Debug.Assert(returnParamsCount > 0);

                newMethod.IsStatic = true;
                newMethod.ParamActions.Add(new ParamActionDefinition
                {
                    Param = new ParamDefinition
                    {
                        Type = "CommandCache",
                        Name = "commandCache"
                    }
                });
            }

            int parameterIndex = 0;

            var marshalFromActions = new List <MethodAction>();
            var marshalMidActions  = new List <MethodAction>();
            var marshalToActions   = new List <MethodAction>();

            var marshalledValues = new List <Action <ExpressionBuilder> >();

            if (isExtension)
            {
                var extendedHandleType = this.nameLookup.Lookup(new TypeReference {
                    VkName = handleTypeName
                }, false);

                newMethod.ParamActions.Add(new ParamActionDefinition
                {
                    Param = new ParamDefinition
                    {
                        Name    = "extendedHandle",
                        Type    = "this " + extendedHandleType,
                        Comment = new List <string>
                        {
                            $"The {handleType.Name} handle to extend."
                        }
                    }
                });

                marshalToActions.Add(new DeclarationAction
                {
                    MemberType = "CommandCache",
                    MemberName = "commandCache"
                });

                marshalToActions.Add(new AssignAction
                {
                    TargetExpression = Variable("commandCache"),
                    ValueExpression  = Member(Variable("extendedHandle"), "commandCache")
                });
            }

            foreach (var parameter in command.Params)
            {
                var newParams = this.GenerateParameter(command, newMethod, parameter, parameterIndex, enumeratePattern, lastParamIsArray, returnParamsCount, isBatchSingleMethod, marshalFromActions, marshalMidActions, marshalToActions, marshalledValues, GetHandle, handleLookup);

                if (newParams != null)
                {
                    newMethod.ParamActions.AddRange(newParams);
                }

                parameterIndex++;
            }

            string invokeReturnType = null;
            string invokeReturnName = null;;

            if (command.ReturnType == "VkResult")
            {
                if (command.MultipleSuccessCodes && newMethod.ReturnType == "void")
                {
                    newMethod.ReturnType = this.typeData["VkResult"].Name;
                    invokeReturnName     = "result";
                }
                else
                {
                    invokeReturnType = this.typeData["VkResult"].Name;
                    invokeReturnName = "methodResult";
                }
            }
            else if (this.typeData[command.ReturnType].Pattern == TypePattern.Delegate)
            {
                newMethod.ReturnType = "IntPtr";
                invokeReturnName     = "result";
            }

            newMethod.MemberActions.AddRange(marshalToActions);

            string delegateName = string.Join(".", new[] { "SharpVk", "Interop" }.Concat(this.namespaceMap.Map(command.ExtensionNamespace))) + $".{command.HandleTypeName}{command.Name}Delegate";
            string lookupScope  = command.Extension != null ? this.extensions[command.Extension].Scope : "";

            newMethod.MemberActions.Add(new InvokeAction
            {
                TypeName       = "Interop.Commands",
                MethodName     = command.VkName,
                ReturnName     = invokeReturnName,
                ReturnType     = invokeReturnType,
                LookupDelegate = true,
                DelegateName   = delegateName,
                LookupScope    = lookupScope,
                Parameters     = marshalledValues.ToArray()
            });

            if (command.ReturnType == "VkResult")
            {
                newMethod.MemberActions.Add(new ValidateAction
                {
                    VariableName = invokeReturnName
                });
            }

            if (enumeratePattern)
            {
                newMethod.MemberActions.AddRange(marshalMidActions);

                newMethod.MemberActions.Add(new InvokeAction
                {
                    TypeName       = "Interop.Commands",
                    MethodName     = command.VkName,
                    LookupDelegate = true,
                    Parameters     = marshalledValues.ToArray()
                });
            }

            newMethod.MemberActions.AddRange(marshalFromActions);

            return(newMethod);
        }
Example #13
0
 private static void Add(CodeNamespace ns, ConventionsDeclaration conventions, SemanticModel model, NamespaceName namespaceName, CommandDeclaration declaration)
 {
     ns.Types.Add(CommandGenerator.CreateCommandDeclaration(model, namespaceName, declaration, conventions.CommandConventions));
 }
Example #14
0
 public virtual CommandDeclaration Transform(CommandDeclaration declaration)
 {
     return(declaration);
 }
 public bool Apply(CommandDeclaration arg, out MethodPatternInfo result)
 {
     throw new NotImplementedException();
 }