/// <summary> /// Gets the translated code for the grammar structure. /// </summary> /// <returns>The translated code for the grammar structure.</returns> public override object Translate(TranslationContext context) { ITypedDeclaration value = GetDeclaration(context); switch (value) { case null: // Error already processed return(null); case GlobalListDeclaration _: return(new Block(BlockSpecs.GetItemOfList, Index.Balance().Translate(context), value.Name)); case StackValue scopedArray: if (scopedArray.StackSpace == 1) { return(scopedArray.CreateArrayLookup(Index.Balance().Translate(context))); } context.ErrorList.Add(new CompilerError($"'{value.Name}' is not an array", ErrorType.ImproperUsage, ErrorToken, FileName)); return(null); default: context.ErrorList.Add(new CompilerError($"'{value.Name}' is not an array", ErrorType.ImproperUsage, ErrorToken, FileName)); return(null); } }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (source.Name == "Next") { info.MarshalTo.Add((getTarget, getValue) => new AssignAction { ValueExpression = Null, TargetExpression = getTarget(source.Name) }); string typeName = this.nameLookup.Lookup(source.Type, true); info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; info.InteropFullType = typeName; return(true); } else { return(false); } }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (source.FixedValue != null) { var enumInfo = this.enumLookup[source.FixedValue]; var enumTypeName = this.nameLookup.Lookup(enumInfo.TypeVkName); info.MarshalTo.Add((getTarget, getValue) => new AssignAction { ValueExpression = EnumField(enumTypeName, enumInfo.FieldName), TargetExpression = getTarget(source.Name) }); string typeName = this.nameLookup.Lookup(source.Type, true); info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; info.InteropFullType = typeName; return(true); } else { return(false); } }
/// <summary> /// Creates a new instance of the <see cref="LookupExpression"/> class. /// </summary> /// <param name="variable">The variable being looked up.</param> /// <param name="fileName">The name of the file.</param> /// <param name="errorToken">The token to report any compiler errors to.</param> public LookupExpression(ITypedDeclaration variable, string fileName, IToken errorToken) { _variable = variable; _identifierName = variable.Name; FileName = fileName; ErrorToken = errorToken; }
/// <summary> /// Gets the translated code for the grammar structure. /// </summary> /// <returns>The translated code for the grammar structure.</returns> public virtual object Translate(TranslationContext context) { ITypedDeclaration variable = GetDeclaration(context); switch (variable) { case null: // Error already processed return(null); case StackValue stackValue: return(stackValue.CreateVariableLookup()); case ParamDeclaration _: return(new Block(BlockSpecs.GetParameter, variable.Name)); case GlobalVarDeclaration _: return(new Block(BlockSpecs.GetVariable, variable.Name)); case ConstDeclaration constDeclaration: return(constDeclaration.Value.Value); default: context.ErrorList.Add(new CompilerError($"'{_identifierName}' is not a variable", ErrorType.ImproperUsage, ErrorToken, FileName)); return(null); } }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (source.Name.EndsWith("Version") && source.Type.VkName.StartsWith("uint32")) { info.Public.Add(new TypedDefinition { Name = source.Name, Type = "Version" }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { ValueExpression = Cast("Version", getValue(source.Name)), TargetExpression = getTarget(source.Name), }); string typeName = this.nameLookup.Lookup(source.Type, true); info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; info.InteropFullType = typeName; return(true); } else { return(false); } }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (source.Name == "Next") { if (context.IsMethod) { var variableName = (context.VkName + "NextPointer").FirstToLower(); info.MarshalTo.Add((getTarget, getValue) => new DeclarationAction { MemberType = "void*", MemberName = variableName }); info.MarshalTo.Add((getTarget, getValue) => new AssignAction { ValueExpression = Variable(variableName), TargetExpression = getTarget(source.Name) }); } else { info.MarshalTo.Add((getTarget, getValue) => new AssignAction { ValueExpression = Null, TargetExpression = getTarget(source.Name) }); } string typeName = this.nameLookup.Lookup(source.Type, true); info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; info.InteropFullType = typeName; return(true); } else { return(false); } }
/// <summary> /// Finds a declaration (excluding methods) with the specified name /// </summary> /// <param name="name">The name of the declaration to search for.</param> /// <returns>The declaration with the specified name or null if not found.</returns> public IDeclaration GetDeclaration(string name) { // Project if (Project == null) { return(null); } IDeclaration superGlobalDeclaration = Project.GetDeclaration(name); if (superGlobalDeclaration != null) { return(superGlobalDeclaration); } // Sprite if (CurrentSprite == null) { return(null); } ITypedDeclaration globalDeclaration = CurrentSprite.GetDeclaration(name); if (globalDeclaration != null) { return(globalDeclaration); } // Methods if (CurrentScope == null) { return(null); } // Method params ParamDeclaration methodParam = (CurrentScope.Method as MethodDeclaration)?.FindParam(name); if (methodParam != null) { return(methodParam); } // Scoped variables return(CurrentScope.Search(name)); }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (source.Type.FixedLength.Type != FixedLengthType.None) { string name = source.Name; string memberType = this.nameLookup.Lookup(source.Type, false); string interopType = this.nameLookup.Lookup(source.Type, true); if (this.typeData[source.Type.VkName].Pattern == TypePattern.Primitive) { string length = "1"; if (source.Type.FixedLength.Type == FixedLengthType.IntegerLiteral) { length = source.Type.FixedLength.Value; } else { var constant = this.constantsLookup[source.Type.FixedLength.Value]; length = $"Constants.{constant.Name}"; } info.InteropFullType = interopType; name += $"[{length}]"; interopType = "fixed " + interopType; info.Interop = new TypedDefinition { Name = name, Type = interopType }; switch (source.Type.VkName) { case "char": info.Public.Add(new TypedDefinition { Name = source.Name, Type = "string" }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = StaticCall("Interop.HeapUtil", "MarshalStringFrom", getValue(source.Name), AsIs(length), Literal(true)) }); break; default: if (memberType == "byte" && source.Name.ToLower().EndsWith("uid")) { info.Public.Add(new TypedDefinition { Name = source.Name, Type = "Guid" }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = New("Guid", StaticCall("Interop.HeapUtil", "MarshalFrom", getValue(source.Name), AsIs(length))) }); } else { info.Public.Add(new TypedDefinition { Name = source.Name, Type = memberType + "[]" }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = StaticCall("Interop.HeapUtil", "MarshalFrom", getValue(source.Name), AsIs(length)) }); } info.MarshalTo.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = getValue(source.Name), Type = AssignActionType.FixedLengthMarshalTo, LengthExpression = AsIs(length) }); break; } } else { var elementType = source.Type.Deref(); var marshalling = this.marshallingRules.ApplyFirst(elementType); int count = 1; if (source.Type.FixedLength.Type == FixedLengthType.IntegerLiteral) { count = int.Parse(source.Type.FixedLength.Value); } else { var constant = this.constantsLookup[source.Type.FixedLength.Value]; count = int.Parse(constant.Value); } info.InteropFullType = interopType; info.Interop = new TypedDefinition { Name = name, Type = interopType, Repeats = count }; info.Public.Add(new TypedDefinition { Name = name, Type = memberType + "[]" }); string countMemberName = source.Name.TrimEnd('s') + "Count"; info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), MemberType = memberType, IsLoop = true, IsArray = true, IndexName = "index", Type = marshalling.MarshalFromActionType, NullCheckExpression = IsNotEqual(getValue(countMemberName), Literal(0)), LengthExpression = getValue(countMemberName), ValueExpression = marshalling.BuildMarshalFromValueExpression(Index(Brackets(AddressOf(Brackets(getValue(source.Name + "_0")))), Variable("index")), context.GetHandle) }); } return(true); } else { return(false); } }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { var lenExpressions = new List <(Func <Func <string, Action <ExpressionBuilder> >, Action <ExpressionBuilder> >, bool, bool)>(); foreach (var otherMember in others) { if (otherMember.Dimensions != null) { foreach (var dimension in otherMember.Dimensions) { if (dimension.Type == LenType.Expression && tokenCheck.Check(dimension.Value, source.VkName)) { if (dimension.Value is LenExpressionToken) { lenExpressions.Add((getValue => Coalesce(CoalesceMember(getValue(otherMember.Name), "Length"), Literal(0)), otherMember.NoAutoValidity, otherMember.IsOptional)); } } } } else if (otherMember.Type.FixedLength.Type != FixedLengthType.None && source.VkName == otherMember.VkName.TrimEnd('s') + "Count") { lenExpressions.Add((getValue => Coalesce(CoalesceMember(getValue(otherMember.Name), "Length"), Literal(0)), otherMember.NoAutoValidity, otherMember.IsOptional)); } } bool isArrayLenMember = lenExpressions.Any() && (source.IsOptional || lenExpressions.Any(x => !x.Item2)); if (isArrayLenMember) { var lenExpression = lenExpressions.Any(x => !x.Item2) ? lenExpressions.FirstOrDefault(x => !x.Item2) : lenExpressions.First(); MethodAction assign(Func <string, Action <ExpressionBuilder> > getTarget, Func <string, Action <ExpressionBuilder> > getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = Cast(this.nameLookup.Lookup(source.Type, false), lenExpression.Item1(getValue)) }; string typeName = this.nameLookup.Lookup(source.Type, true); if (source.IsOptional && lenExpressions.All(x => x.Item2) && lenExpressions.All(x => x.Item3)) { info.Public.Add(new TypedDefinition { Name = source.Name, Type = typeName + "?", DefaultValue = Null }); MethodAction optionalAssign(Func <string, Action <ExpressionBuilder> > getTarget, Func <string, Action <ExpressionBuilder> > getValue) { var result = new OptionalAction { NullCheckExpression = IsNotEqual(getValue(source.Name), Null) }; result.Actions.Add(new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = Member(getValue(source.Name), "Value") }); result.ElseActions.Add(assign(getTarget, getValue)); return(result); } info.MarshalTo.Add(optionalAssign); } else { info.MarshalTo.Add(assign); } info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; info.InteropFullType = typeName; } return(isArrayLenMember); }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { var lenExpressions = new List <(Func <Func <string, Action <ExpressionBuilder> >, Action <ExpressionBuilder> >, bool, bool)>(); bool isLenOfLastMember = false; foreach (var otherMember in others) { bool isLastMember = otherMember.VkName == others.Last().VkName; if (otherMember.Dimensions != null) { foreach (var dimension in otherMember.Dimensions) { if (dimension.Type == LenType.Expression && tokenCheck.Check(dimension.Value, source.VkName)) { if (dimension.Value is LenExpressionToken) { lenExpressions.Add((getValue => StaticCall("Interop.HeapUtil", "GetLength", getValue(otherMember.Name)), otherMember.NoAutoValidity, otherMember.IsOptional)); isLenOfLastMember |= isLastMember; } } } } else if (otherMember.Type.FixedLength.Type != FixedLengthType.None && source.VkName == otherMember.VkName.TrimEnd('s') + "Count") { lenExpressions.Add((getValue => StaticCall("Interop.HeapUtil", "GetLength", getValue(otherMember.Name)), otherMember.NoAutoValidity, otherMember.IsOptional)); isLenOfLastMember |= isLastMember; } } bool isArrayLenMember = lenExpressions.Any() && !(source.VkName == "descriptorCount" && context.VkName == "VkWriteDescriptorSet") && !(isLenOfLastMember && context.HasReturnValue && lenExpressions.Count == 1 && !context.IsBatchSingleMethod); if (isArrayLenMember) { string typeName = this.nameLookup.Lookup(source.Type, true); info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; info.InteropFullType = typeName; if (context.IsBatchSingleMethod && isLenOfLastMember) { info.MarshalTo.Add((getTarget, geValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = Literal(1) }); } else { var lenExpression = lenExpressions.Any(x => !x.Item2) ? lenExpressions.First(x => !x.Item2) : lenExpressions.First(); MethodAction assign(Func <string, Action <ExpressionBuilder> > getTarget, Func <string, Action <ExpressionBuilder> > getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = Cast(this.nameLookup.Lookup(source.Type, false), lenExpression.Item1(getValue)) }; if (source.IsOptional && (lenExpressions.All(x => x.Item2 && x.Item3))) { info.Public.Add(new TypedDefinition { Name = source.Name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = typeName + "?", DefaultValue = Null }); MethodAction optionalAssign(Func <string, Action <ExpressionBuilder> > getTarget, Func <string, Action <ExpressionBuilder> > getValue) { var result = new OptionalAction { CheckExpression = IsNotEqual(getValue(source.Name), Null) }; result.Actions.Add(new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = Member(getValue(source.Name), "Value") }); result.ElseActions.Add(assign(getTarget, getValue)); return(result); } info.MarshalTo.Add(optionalAssign); } else { info.MarshalTo.Add(assign); } } } return(isArrayLenMember); }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (this.patternRules == null) { this.patternRules = this.provider.GetServices <IMemberPatternRule>(); } string verbInfoPattern = context.MethodVerb + "info"; if (context.Extension != null) { verbInfoPattern += context.Extension; } verbInfoPattern = verbInfoPattern.ToLower(); if (context.MethodVerb != null && source.Dimensions == null && source.Type.VkName.ToLower().EndsWith(verbInfoPattern)) { var infoTypeData = this.typeData[source.Type.VkName]; var interopType = this.nameLookup.Lookup(source.Type, true); var interopBaseType = this.nameLookup.Lookup(source.Type, true, false); bool isPointer = source.Type.PointerType.IsPointer(); info.Interop = new TypedDefinition { Name = source.Name.FirstToLower(), Type = interopType }; info.InteropFullType = interopType; info.MarshalTo.Add((getTarget, getValue) => new AssignAction { ValueExpression = New(interopBaseType), TargetExpression = getTarget(source.Name), MemberType = interopBaseType, Type = isPointer ? AssignActionType.Alloc : AssignActionType.Assign }); foreach (var member in infoTypeData.Members) { var subPatternInfo = new MemberPatternInfo(); var relativeOthers = others.Select(x => { if (x.Dimensions?.Any() ?? false) { if (x.Dimensions[0].Value is LenExpressionReference lenRef) { if (lenRef.LeftOperand is LenExpressionToken lenLeftToken && lenLeftToken.Value == source.VkName) { return(new WrappedTypedDeclaration(x, new[] { new MemberLen { Type = LenType.Expression, Value = lenRef.RightOperand } })); } } } return(x); }); this.patternRules.ApplyFirst(infoTypeData.Members.Concat(relativeOthers), member, new MemberPatternContext(null, true, context.IsBatchSingleMethod, context.ReturnParamsCount, infoTypeData.Extension, context.GetHandle, source.Type.VkName), subPatternInfo); foreach (var subAction in subPatternInfo.MarshalTo) { info.MarshalTo.Add((getTarget, getValue) => { return(subAction(target => DerefMember(getTarget(source.Name), target), value => getValue(value.FirstToLower()))); }); } foreach (var lookup in subPatternInfo.HandleLookup) { info.HandleLookup.Add((lookup.Item1, x => lookup.Item2(value => x(value.FirstToLower())))); } info.Public.AddRange(subPatternInfo.Public.Select(x => new TypedDefinition { Name = x.Name.FirstToLower(), Comment = x.Comment, Type = x.Type, DefaultValue = x.DefaultValue })); } foreach (var extendStruct in infoTypeData.ExtendTypes) { var extendType = this.typeData[extendStruct]; string typeNamespace = ""; if (extendType.Extension != null) { typeNamespace += "." + string.Join(".", this.namespaceMap.Map(extendType.Extension)); } string paramName = extendType.Name.FirstToLower() + extendType.Extension; info.Public.Add(new TypedDefinition { Name = paramName, Type = $"SharpVk{typeNamespace}.{extendType.Name}?", Comment = new[] { "Extension struct" }.ToList(), DefaultValue = Null }); info.MarshalTo.Add((getTarget, getValue) => { var extendMarshalAction = new OptionalAction { CheckExpression = IsNotEqual(Variable(paramName), Null), Priority = -1 }; var variableName = (source.Type.VkName + "NextPointer").FirstToLower(); extendMarshalAction.Actions.AddRange(new MethodAction[] { new DeclarationAction { MemberType = $"SharpVk.Interop{typeNamespace}.{extendType.Name}*", MemberName = "extensionPointer" }, new AssignAction { TargetExpression = Variable("extensionPointer"), ValueExpression = Member(Variable(paramName), "Value"), MemberType = $"SharpVk.Interop{typeNamespace}.{extendType.Name}", Type = AssignActionType.MarshalTo }, new AssignAction { TargetExpression = DerefMember(Variable("extensionPointer"), "Next"), ValueExpression = Variable(variableName) }, new AssignAction { ValueExpression = Variable("extensionPointer"), TargetExpression = Variable(variableName) } }); return(extendMarshalAction); }); } return(true); } else { return(false); } }
/// <summary> /// Creates a new instance of the <see cref="ArrayLookupExpression"/> class. /// </summary> /// <param name="declaration">The array declaration.</param> /// <param name="index">The expression for the index of the item being looked up.</param> /// <param name="fileName">The name of the file.</param> /// <param name="errorToken">The token to report any compiler errors to.</param> public ArrayLookupExpression(ITypedDeclaration declaration, IExpression index, string fileName, IToken errorToken) : base(declaration, fileName, errorToken) { Index = index; }
public WrappedTypedDeclaration(ITypedDeclaration wrappedDeclaration, MemberLen[] dimensions) { this.wrappedDeclaration = wrappedDeclaration; this.Dimensions = dimensions; }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (this.patternRules == null) { this.patternRules = this.provider.GetServices <IMemberPatternRule>(); } string verbInfoPattern = context.MethodVerb + "info"; if (context.Extension != null) { verbInfoPattern += context.Extension; } verbInfoPattern = verbInfoPattern.ToLower(); if (context.MethodVerb != null && source.Dimensions == null && source.Type.VkName.ToLower().EndsWith(verbInfoPattern)) { var infoTypeData = this.typeData[source.Type.VkName]; var interopType = this.nameLookup.Lookup(source.Type, true); var interopBaseType = this.nameLookup.Lookup(source.Type, true, false); bool isPointer = source.Type.PointerType.IsPointer(); info.Interop = new TypedDefinition { Name = source.Name.FirstToLower(), Type = interopType }; info.InteropFullType = interopType; info.MarshalTo.Add((getTarget, getValue) => new AssignAction { ValueExpression = New(interopBaseType), TargetExpression = getTarget(source.Name), MemberType = interopBaseType, Type = isPointer ? AssignActionType.Alloc : AssignActionType.Assign }); foreach (var member in infoTypeData.Members) { var subPatternInfo = new MemberPatternInfo(); this.patternRules.ApplyFirst(infoTypeData.Members, member, new MemberPatternContext(null, true, infoTypeData.Extension, context.GetHandle, source.Type.VkName), subPatternInfo); foreach (var subAction in subPatternInfo.MarshalTo) { info.MarshalTo.Add((getTarget, getValue) => { return(subAction(target => DerefMember(getTarget(source.Name), target), value => getValue(value.FirstToLower()))); }); } foreach (var lookup in subPatternInfo.HandleLookup) { info.HandleLookup.Add((lookup.Item1, x => lookup.Item2(value => x(value.FirstToLower())))); } info.Public.AddRange(subPatternInfo.Public.Select(x => new TypedDefinition { Name = x.Name.FirstToLower(), Comment = x.Comment, Type = x.Type, DefaultValue = x.DefaultValue })); } return(true); } else { return(false); } }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { var marshalling = this.marshallingRules.ApplyFirst(source.Type); bool isOptional = source.IsOptional && this.typeData[source.Type.VkName].Pattern != TypePattern.Delegate && this.typeData[source.Type.VkName].Pattern != TypePattern.Handle; string memberType = marshalling.MemberType + (isOptional ? "?" : ""); info.Public.Add(new TypedDefinition { Name = source.Name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = memberType, DefaultValue = isOptional ? Default(memberType) : null }); string typeName = this.nameLookup.Lookup(source.Type, true); info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; info.InteropFullType = marshalling.InteropType; if (marshalling.HandleType != null) { info.HandleLookup.Add((marshalling.HandleType, getValue => getValue(source.Name))); } if (source.Type.PointerType.IsPointer()) { info.InteropFullType += new string('*', source.Type.PointerType.GetPointerCount()); } info.MarshalTo.Add((getTarget, getValue) => { var valueExpression = isOptional ? marshalling.BuildMarshalToValueExpression(Member(getValue(source.Name), "Value"), context.GetHandle) : marshalling.BuildMarshalToValueExpression(getValue(source.Name), context.GetHandle); var assignment = new AssignAction { ValueExpression = valueExpression, TargetExpression = getTarget(source.Name), MemberType = marshalling.InteropType, Type = marshalling.MarshalToActionType }; if (isOptional) { var result = new OptionalAction { CheckExpression = IsNotEqual(getValue(source.Name), Null) }; result.Actions.Add(assignment); result.ElseActions.Add(new AssignAction { Type = AssignActionType.Assign, TargetExpression = getTarget(source.Name), ValueExpression = Default(info.InteropFullType) }); return(result); } else { return(assignment); } }); bool optionalMarshalFrom = isOptional && source.Type.PointerType != PointerType.Value; info.MarshalFrom.Add((getTarget, getValue) => { var valueExpression = marshalling.BuildMarshalFromValueExpression(getValue(source.Name), context.GetHandle); var assignment = new AssignAction { ValueExpression = valueExpression, TargetExpression = getTarget(source.Name), MemberType = marshalling.MemberType, Type = marshalling.MarshalFromActionType }; if (optionalMarshalFrom) { var result = new OptionalAction { CheckExpression = IsNotEqual(getValue(source.Name), Null) }; result.Actions.Add(assignment); result.ElseActions.Add(new AssignAction { Type = AssignActionType.Assign, TargetExpression = getTarget(source.Name), ValueExpression = Null }); return(result); } else { return(assignment); } }); return(true); }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (source.Dimensions != null) { string typeName = this.nameLookup.Lookup(source.Type, true); info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; if (source.Dimensions.Length == 2) { info.Public.Add(new TypedDefinition { Name = source.Name, Type = "ArrayProxy<string>" + (context.IsMethod ? "?" : ""), DefaultValue = source.IsOptional ? Null : null, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName) }); info.MarshalTo.Add((getTarget, getValue) => { return(new AssignAction { ValueExpression = StaticCall("Interop.HeapUtil", "MarshalTo", getValue(source.Name)), TargetExpression = getTarget(source.Name), MemberType = this.nameLookup.Lookup(source.Type, false), Type = AssignActionType.Assign }); }); } else if (source.Dimensions.Length == 1) { switch (source.Dimensions[0].Type) { case LenType.NullTerminated: info.Public.Add(new TypedDefinition { Name = source.Name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = "string" }); info.InteropFullType = typeName; info.MarshalTo.Add((getTarget, getValue) => new AssignAction { ValueExpression = StaticCall("Interop.HeapUtil", "MarshalTo", getValue(source.Name)), TargetExpression = getTarget(source.Name), MemberType = this.nameLookup.Lookup(source.Type, false), Type = AssignActionType.Assign }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { ValueExpression = StaticCall("Interop.HeapUtil", "MarshalStringFrom", getValue(source.Name)), TargetExpression = getTarget(source.Name), MemberType = this.nameLookup.Lookup(source.Type, false), Type = AssignActionType.Assign }); break; case LenType.Expression: var elementType = source.Type.Deref(); bool isDoubleMarshalled = false; string semiMarshalledName = "semiMarshalled" + source.Name.FirstToUpper(); string semiMarshalType = this.nameLookup.Lookup(elementType, true); if (elementType.PointerType.IsPointer()) { info.MarshalTo.Add((getTarget, getValue) => new DeclarationAction { MemberType = semiMarshalType, MemberName = semiMarshalledName }); isDoubleMarshalled = true; elementType = elementType.Deref(); } if (elementType.VkName == "void") { elementType.VkName = "uint8_t"; } var marshalling = this.marshallingRules.ApplyFirst(elementType); //var singleValueMarshalling = this.marshallingRules.ApplyFirst(source.Type); info.InteropFullType = marshalling.InteropType; if (source.Type.PointerType.IsPointer()) { info.InteropFullType += new string('*', source.Type.PointerType.GetPointerCount()); } string arrayType = $"{marshalling.MemberType}[]"; if (context.IsMethod) { info.Public.Add(new TypedDefinition { Name = source.Name, Type = $"ArrayProxy<{marshalling.MemberType}>?", DefaultValue = source.IsOptional ? Null : null }); info.ReturnType = arrayType; info.MarshalTo.Add((getTarget, getValue) => { var proxyValue = Member(getValue(source.Name), "Value"); var isNullOptional = new OptionalAction { CheckExpression = Call(getValue(source.Name), "IsNull") }; var isSingleOptional = new OptionalAction { CheckExpression = IsEqual(Member(proxyValue, "Contents"), EnumField("ProxyContents", "Single")) }; var loopAssign = new AssignAction { TargetExpression = isDoubleMarshalled ? Variable(semiMarshalledName) : getTarget(source.Name), MemberType = marshalling.InteropType, IsLoop = true, IndexName = "index", Type = marshalling.MarshalToActionType, LengthExpression = StaticCall("Interop.HeapUtil", "GetLength", proxyValue), ValueExpression = marshalling.BuildMarshalToValueExpression(Index(proxyValue, Variable("index")), context.GetHandle) }; isSingleOptional.Actions.Add(new AssignAction { Type = AssignActionType.Alloc, TargetExpression = isDoubleMarshalled ? Variable(semiMarshalledName) : getTarget(source.Name), MemberType = marshalling.InteropType }); isSingleOptional.Actions.Add(new AssignAction { Type = marshalling.MarshalToActionType, MemberType = marshalling.InteropType, ValueExpression = marshalling.BuildMarshalToValueExpression(Call(proxyValue, "GetSingleValue"), context.GetHandle), TargetExpression = Deref(Cast(marshalling.InteropType + "*", isDoubleMarshalled ? Variable(semiMarshalledName) : getTarget(source.Name))) }); isSingleOptional.ElseActions.Add(loopAssign); if (isDoubleMarshalled) { isSingleOptional.ElseActions.Add(new AssignAction { TargetExpression = getTarget(source.Name), MemberType = semiMarshalType, IsLoop = true, IndexName = "index", Type = AssignActionType.Assign, LengthExpression = StaticCall("Interop.HeapUtil", "GetLength", proxyValue), ValueExpression = AddressOf(Index(Variable(semiMarshalledName), Variable("index"))), FieldPointerName = "marshalledFieldPointer" }); } isNullOptional.Actions.Add(new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = Null }); isNullOptional.ElseActions.Add(isSingleOptional); return(isNullOptional); }); } else { info.Public.Add(new TypedDefinition { Name = source.Name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = arrayType }); info.MarshalTo.Add((getTarget, getValue) => new AssignAction { TargetExpression = isDoubleMarshalled ? Variable(semiMarshalledName) : getTarget(source.Name), MemberType = marshalling.InteropType, IsLoop = true, IndexName = "index", Type = marshalling.MarshalToActionType, NullCheckExpression = IsNotEqual(getValue(source.Name), Null), LengthExpression = Member(getValue(source.Name), "Length"), ValueExpression = marshalling.BuildMarshalToValueExpression(Index(getValue(source.Name), Variable("index")), context.GetHandle) }); if (isDoubleMarshalled) { info.MarshalTo.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), MemberType = semiMarshalType, IsLoop = true, IndexName = "index", Type = AssignActionType.Assign, NullCheckExpression = IsNotEqual(getValue(source.Name), Null), LengthExpression = Member(getValue(source.Name), "Length"), ValueExpression = AddressOf(Index(Variable(semiMarshalledName), Variable("index"))) }); } } Action <ExpressionBuilder> lenValue = null; if (source.Dimensions[0].Value is LenExpressionToken lenToken) { lenValue = Variable(others.Single(x => x.VkName == lenToken.Value).Name); } else { lenValue = this.expressionBuilder.Build(source.Dimensions[0].Value, x => others.Single(y => y.VkName == x)); } info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), MemberType = marshalling.MemberType, IsLoop = true, IsArray = true, IndexName = "index", Type = marshalling.MarshalFromActionType, NullCheckExpression = IsNotEqual(getValue(source.Name), Null), LengthExpression = lenValue, ValueExpression = marshalling.BuildMarshalFromValueExpression(Index(getValue(source.Name), Variable("index")), context.GetHandle) }); break; } } return(true); } else { return(false); } }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (source.Dimensions != null) { string typeName = this.nameLookup.Lookup(source.Type, true); info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; if (source.Dimensions.Length == 2) { info.Public.Add(new TypedDefinition { Name = source.Name, Type = "string[]" }); info.MarshalTo.Add((getTarget, getValue) => { var marshalToAction = new OptionalAction { NullCheckExpression = IsNotEqual(getValue(source.Name), Null) }; marshalToAction.Actions.Add(new AssignAction { ValueExpression = StaticCall("Interop.HeapUtil", "MarshalTo", getValue(source.Name)), TargetExpression = getTarget(source.Name), MemberType = this.nameLookup.Lookup(source.Type, false), Type = AssignActionType.Assign }); return(marshalToAction); }); } else if (source.Dimensions.Length == 1) { switch (source.Dimensions[0].Type) { case LenType.NullTerminated: info.Public.Add(new TypedDefinition { Name = source.Name, Type = "string" }); info.InteropFullType = typeName; info.MarshalTo.Add((getTarget, getValue) => new AssignAction { ValueExpression = StaticCall("Interop.HeapUtil", "MarshalTo", getValue(source.Name)), TargetExpression = getTarget(source.Name), MemberType = this.nameLookup.Lookup(source.Type, false), Type = AssignActionType.Assign }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { ValueExpression = StaticCall("Interop.HeapUtil", "MarshalStringFrom", getValue(source.Name)), TargetExpression = getTarget(source.Name), MemberType = this.nameLookup.Lookup(source.Type, false), Type = AssignActionType.Assign }); break; case LenType.Expression: var elementType = source.Type.Deref(); bool isDoubleMarshalled = false; string semiMarshalledName = "semiMarshalled" + source.Name.FirstToUpper(); string semiMarshalType = this.nameLookup.Lookup(elementType, true); if (elementType.PointerType.IsPointer()) { info.MarshalTo.Add((getTarget, getValue) => new DeclarationAction { MemberType = semiMarshalType, MemberName = semiMarshalledName }); isDoubleMarshalled = true; elementType = elementType.Deref(); } if (elementType.VkName == "void") { elementType.VkName = "uint8_t"; } var marshalling = this.marshallingRules.ApplyFirst(elementType); info.InteropFullType = marshalling.InteropType; if (source.Type.PointerType.IsPointer()) { info.InteropFullType += new string('*', source.Type.PointerType.GetPointerCount()); } info.Public.Add(new TypedDefinition { Name = source.Name, Type = marshalling.MemberType + "[]" }); info.MarshalTo.Add((getTarget, getValue) => new AssignAction { TargetExpression = isDoubleMarshalled ? Variable(semiMarshalledName) : getTarget(source.Name), MemberType = marshalling.InteropType, IsLoop = true, IndexName = "index", Type = marshalling.MarshalToActionType, NullCheckExpression = IsNotEqual(getValue(source.Name), Null), LengthExpression = Member(getValue(source.Name), "Length"), ValueExpression = marshalling.BuildMarshalToValueExpression(Index(getValue(source.Name), Variable("index")), context.GetHandle) }); if (isDoubleMarshalled) { info.MarshalTo.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), MemberType = semiMarshalType, IsLoop = true, IndexName = "index", Type = AssignActionType.Assign, NullCheckExpression = IsNotEqual(getValue(source.Name), Null), LengthExpression = Member(getValue(source.Name), "Length"), ValueExpression = AddressOf(Index(Variable(semiMarshalledName), Variable("index"))) }); } Action <ExpressionBuilder> lenValue = null; if (source.Dimensions[0].Value is LenExpressionToken lenToken) { lenValue = Variable(others.Single(x => x.VkName == lenToken.Value).Name); } else { lenValue = this.expressionBuilder.Build(source.Dimensions[0].Value, x => others.Single(y => y.VkName == x)); } info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), MemberType = marshalling.MemberType, IsLoop = true, IsArray = true, IndexName = "index", Type = marshalling.MarshalFromActionType, NullCheckExpression = IsNotEqual(getValue(source.Name), Null), LengthExpression = lenValue, ValueExpression = marshalling.BuildMarshalFromValueExpression(Index(getValue(source.Name), Variable("index")), context.GetHandle) }); break; } } return(true); } else { return(false); } }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (source.Type.FixedLength.Type != FixedLengthType.None) { string name = source.Name; string memberType = this.nameLookup.Lookup(source.Type, false); string interopType = this.nameLookup.Lookup(source.Type, true); if (this.typeData[source.Type.VkName].Pattern == TypePattern.Primitive) { string length = "1"; if (source.Type.FixedLength.Type == FixedLengthType.IntegerLiteral) { length = source.Type.FixedLength.Value; } else { var constant = this.constantsLookup[source.Type.FixedLength.Value]; length = $"Constants.{constant.Name}"; } info.InteropFullType = interopType; name += $"[{length}]"; interopType = "fixed " + interopType; info.Interop = new TypedDefinition { Name = name, Type = interopType }; switch (source.Type.VkName) { case "char": info.Public.Add(new TypedDefinition { Name = source.Name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = "string" }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = StaticCall("Interop.HeapUtil", "MarshalStringFrom", getValue(source.Name), AsIs(length), Literal(true)) }); break; default: if (memberType == "byte" && source.Name.ToLower().EndsWith("uid")) { info.Public.Add(new TypedDefinition { Name = source.Name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = "Guid" }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = New("Guid", StaticCall("Interop.HeapUtil", "MarshalFrom", getValue(source.Name), AsIs(length))) }); info.MarshalTo.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = getValue(source.Name), Type = AssignActionType.FixedLengthMarshalTo, LengthExpression = AsIs(length) }); } else if (int.TryParse(length, out int count)) { info.Public.Add(new TypedDefinition { Name = source.Name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = "(" + string.Join(", ", Enumerable.Repeat(memberType, count)) + ")" }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), Type = AssignActionType.Assign, ValueExpression = NewValueTuple(Enumerable.Range(0, count).Select(x => Index(getValue(source.Name), Literal(x))).ToArray()) }); for (int index = 0; index < count; index++) { string valueFieldName = "Item" + (index + 1); int fieldIndex = index; info.MarshalTo.Add((getTarget, getValue) => new AssignAction { TargetExpression = Index(getTarget(source.Name), Literal(fieldIndex)), Type = AssignActionType.Assign, ValueExpression = Member(getValue(source.Name), valueFieldName) }); } } else { info.Public.Add(new TypedDefinition { Name = source.Name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = memberType + "[]" }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = StaticCall("Interop.HeapUtil", "MarshalFrom", getValue(source.Name), AsIs(length)) }); info.MarshalTo.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), ValueExpression = getValue(source.Name), Type = AssignActionType.FixedLengthMarshalTo, LengthExpression = AsIs(length) }); } break; } } else { var elementType = source.Type.Deref(); var marshalling = this.marshallingRules.ApplyFirst(elementType); int count = 1; if (source.Type.FixedLength.Type == FixedLengthType.IntegerLiteral) { count = int.Parse(source.Type.FixedLength.Value); } else { var constant = this.constantsLookup[source.Type.FixedLength.Value]; count = int.Parse(constant.Value); } info.InteropFullType = interopType; info.Interop = new TypedDefinition { Name = name, Type = interopType, Repeats = count }; if (count > 8) { info.Public.Add(new TypedDefinition { Name = name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = memberType + "[]" }); string countMemberName = source.Name.TrimEnd('s') + "Count"; info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), MemberType = memberType, IsLoop = true, IsArray = true, IndexName = "index", Type = marshalling.MarshalFromActionType, NullCheckExpression = IsNotEqual(getValue(countMemberName), Literal(0)), LengthExpression = getValue(countMemberName), ValueExpression = marshalling.BuildMarshalFromValueExpression(Index(Brackets(AddressOf(Brackets(getValue(source.Name + "_0")))), Variable("index")), context.GetHandle) }); info.MarshalTo.Add((getTarget, getValue) => { var marshalToAction = new OptionalAction { CheckExpression = LogicalAnd(IsNotEqual(getValue(source.Name), Null), GreaterThanEqualTo(Member(getValue(source.Name), "Length"), Literal(count))) }; for (int index = 0; index < count; index++) { string targetFieldName = source.Name + "_" + index; int valueIndex = index; marshalToAction.Actions.Add(new AssignAction { TargetExpression = getTarget(targetFieldName), Type = marshalling.MarshalToActionType, ValueExpression = marshalling.BuildMarshalToValueExpression(Index(getValue(source.Name), Literal(valueIndex)), context.GetHandle) }); } return(marshalToAction); }); } else { info.Public.Add(new TypedDefinition { Name = name, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), Type = "(" + string.Join(", ", Enumerable.Repeat(memberType, count)) + ")" }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), Type = AssignActionType.Assign, ValueExpression = NewValueTuple(Enumerable.Range(0, count).Select(x => getValue(source.Name + "_" + x)).ToArray()) }); for (int index = 0; index < count; index++) { string targetFieldName = source.Name + "_" + index; string valueFieldName = "Item" + (index + 1); info.MarshalTo.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(targetFieldName), Type = marshalling.MarshalToActionType, ValueExpression = marshalling.BuildMarshalToValueExpression(Member(getValue(source.Name), valueFieldName), context.GetHandle) }); } } } return(true); } else { return(false); } }
public bool Apply(IEnumerable <ITypedDeclaration> others, ITypedDeclaration source, MemberPatternContext context, MemberPatternInfo info) { if (source.Dimensions != null && source.Dimensions.Length == 1 && source.Dimensions[0].Type == LenType.Expression && context.IsBatchSingleMethod) { var resultMember = others.Last(); var resultLen = resultMember.Dimensions[0].Value; if (!this.expressionEqualityCheck.Check(resultLen, source.Dimensions[0].Value)) { return(false); } var verbInfoPattern = this.provider.GetServices <IMemberPatternRule>().OfType <VerbInfoMemberPattern>().Single(); //var verbInfoPatternInfo = new MemberPatternInfo(); if (verbInfoPattern.Apply(others, new ParamDeclaration { Name = source.Name, VkName = source.VkName, Dimensions = null, IsOptional = false, NoAutoValidity = false, Type = source.Type }, context, info)) { } else { string typeName = this.nameLookup.Lookup(source.Type, true); info.Interop = new TypedDefinition { Name = source.Name, Type = typeName }; var marshalling = this.marshallingRules.ApplyFirst(source.Type); info.InteropFullType = marshalling.InteropType.TrimEnd('*') + "*"; info.Public.Add(new TypedDefinition { Name = source.Name, Type = marshalling.MemberType, Comment = this.commentGenerator.Lookup(context.VkName, source.VkName), DefaultValue = null }); info.MarshalTo.Add((getTarget, getValue) => new AssignAction { Type = marshalling.MarshalToActionType, MemberType = marshalling.InteropType, ValueExpression = marshalling.BuildMarshalToValueExpression(getValue(source.Name), context.GetHandle), TargetExpression = getTarget(source.Name) }); info.MarshalFrom.Add((getTarget, getValue) => new AssignAction { TargetExpression = getTarget(source.Name), MemberType = marshalling.MemberType, Type = marshalling.MarshalFromActionType, NullCheckExpression = IsNotEqual(getValue(source.Name), Null), ValueExpression = marshalling.BuildMarshalFromValueExpression(getValue(source.Name), context.GetHandle) }); } return(true); } else { return(false); } }