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)); } }
private static CommandDeclaration GetCommandDeclaration(DependencyObject obj) { if (!_commandDeclarations.ContainsKey(obj)) { CommandDeclaration decl = new CommandDeclaration(obj); _commandDeclarations.Add(obj, decl); } return(_commandDeclarations[obj]); }
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)); }
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)); }
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); }
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")); }
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")); }
private ApplicationServiceDeclaration CreateImportApplicationServiceDeclaration(CommandDeclaration commandDeclaration) { return(new ApplicationServiceDeclaration("ImportApplicationService", new[] { commandDeclaration })); }
public void Visit(CommandDeclaration node) { var fullName = FullName(node.Name); _knownTypes.Add(new KnownType(fullName, false)); }
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); }
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); } } }
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); }
private static void Add(CodeNamespace ns, ConventionsDeclaration conventions, SemanticModel model, NamespaceName namespaceName, CommandDeclaration declaration) { ns.Types.Add(CommandGenerator.CreateCommandDeclaration(model, namespaceName, declaration, conventions.CommandConventions)); }
public virtual CommandDeclaration Transform(CommandDeclaration declaration) { return(declaration); }
public bool Apply(CommandDeclaration arg, out MethodPatternInfo result) { throw new NotImplementedException(); }