private static void WriteString_( ICurlyBracketStringBuilder cbsb, ISchemaMember member) { var stringType = member.MemberType as IStringType; if (stringType.LengthSourceType == StringLengthSourceType.NULL_TERMINATED) { cbsb.WriteLine($"ew.WriteStringNT(this.{member.Name});"); } else if (stringType.IsEndianOrdered) { cbsb.WriteLine($"ew.WriteStringEndian(this.{member.Name});"); } else if (stringType.LengthSourceType == StringLengthSourceType.CONST) { cbsb.WriteLine( $"ew.WriteStringWithExactLength(this.{member.Name}, {stringType.ConstLength});"); } else { cbsb.WriteLine($"ew.WriteString(this.{member.Name});"); } }
private static void WriteStructure_( ICurlyBracketStringBuilder cbsb, ISchemaMember member) { // TODO: Do value types need to be handled differently? cbsb.WriteLine($"this.{member.Name}.Write(ew);"); }
private static void WriteArray_( ICurlyBracketStringBuilder cbsb, ITypeSymbol sourceSymbol, ISchemaMember member) { var arrayType = member.MemberType as ISequenceMemberType; if (arrayType.LengthSourceType != SequenceLengthSourceType.CONST) { var isImmediate = arrayType.LengthSourceType == SequenceLengthSourceType.IMMEDIATE_VALUE; if (isImmediate) { var writeType = SchemaGeneratorUtil.GetIntLabel( arrayType.ImmediateLengthType); var castType = SchemaGeneratorUtil.GetTypeName( SchemaPrimitiveTypesUtil.ConvertIntToNumber( arrayType.ImmediateLengthType)); var arrayLengthName = arrayType.SequenceType == SequenceType.ARRAY ? "Length" : "Count"; var arrayLengthAccessor = $"this.{member.Name}.{arrayLengthName}"; cbsb.WriteLine( $"ew.Write{writeType}(({castType}) {arrayLengthAccessor});"); } } SchemaWriterGenerator.WriteIntoArray_(cbsb, sourceSymbol, member); }
public void CheckMember( ISymbol memberSymbol, ISchemaMember schemaMember) { var blockAttribute = SymbolTypeUtil.GetAttribute <BlockAttribute>(memberSymbol); }
/// <summary> /// 将指定 Lambda 表达式中的成员访问式添加到当前模式成员中。 /// </summary> /// <typeparam name="TMember">泛型参数,表示成员访问表达式类型。</typeparam> /// <param name="expression">指定的包含成员访问的 Lambda 表达式。</param> /// <returns>返回当前模式。</returns> /// <example> /// <code> /// Schema.Empty<Apartment>() /// .Include(p => p.ApartmentId) /// .Include(p => p.ApartmentNo) /// .Include(p => p.Building.BuildingId) /// .Include(p => p.Building.BuildingNo) /// .Include(p => p.Building.ParkId) /// .Include(p => p.Building.Park.ParkId) /// .Include(p => p.Building.Park.ParkNo) /// .Include(p => p.Building.Park.Name) /// </code> /// </example> public Schema <T> Include <TMember>(Expression <Func <T, TMember> > expression) { ISchemaMember parent = null; var members = GetMembers(expression); foreach (var member in members) { var children = parent == null ? _members : parent.Children; if (!children.TryGetValue(member.Name, out var child)) { child = this.GetMember(member.Name, parent); if (child == null) { throw new DataArgumentException(member.Name); } children.Add(child); } parent = child; } return(this); }
public void Dispatch(object pTarget, uint index, UIAutomationParameter[] pParams, uint cParams) { ISchemaMember dispatchingMember = _schema.GetMemberByIndex(index); if (dispatchingMember == null) { throw new NotSupportedException("Dispatching of this method is not supported"); } dispatchingMember.DispatchCallToProvider(pTarget, new UiaParameterListHelper(pParams)); }
private static void Align_( ICurlyBracketStringBuilder cbsb, ISchemaMember member) { var align = member.Align; if (align != 0) { cbsb.WriteLine($"ew.Align({align});"); } }
private static void ReadPrimitive_( ICurlyBracketStringBuilder cbsb, ITypeSymbol sourceSymbol, ISchemaMember member) { var primitiveType = member.MemberType as IPrimitiveMemberType; if (primitiveType.PrimitiveType == SchemaPrimitiveType.BOOLEAN) { SchemaReaderGenerator.ReadBoolean_(cbsb, member); return; } var readType = SchemaGeneratorUtil.GetPrimitiveLabel( primitiveType.UseAltFormat ? SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( primitiveType.AltFormat) : primitiveType.PrimitiveType); var needToCast = primitiveType.UseAltFormat && primitiveType.PrimitiveType != SchemaPrimitiveTypesUtil.GetUnderlyingPrimitiveType( SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( primitiveType.AltFormat)); if (!primitiveType.IsReadonly) { var castText = ""; if (needToCast) { var castType = primitiveType.PrimitiveType == SchemaPrimitiveType.ENUM ? SymbolTypeUtil.GetQualifiedNameFromCurrentSymbol( sourceSymbol, primitiveType.TypeSymbol) : primitiveType.TypeSymbol.Name; castText = $"({castType}) "; } cbsb.WriteLine( $"this.{member.Name} = {castText}er.Read{readType}();"); } else { var castText = ""; if (needToCast) { var castType = SchemaGeneratorUtil.GetTypeName(primitiveType.AltFormat); castText = $"({castType}) "; } cbsb.WriteLine($"er.Assert{readType}({castText}this.{member.Name});"); } }
private static void ReadStructure_( ICurlyBracketStringBuilder cbsb, IStructureMemberType structureMemberType, ISchemaMember member) { // TODO: Do value types need to be handled differently? var memberName = member.Name; if (structureMemberType.IsChild) { cbsb.WriteLine($"this.{memberName}.Parent = this;"); } cbsb.WriteLine($"this.{memberName}.Read(er);"); }
private static void ReadString_( ICurlyBracketStringBuilder cbsb, ISchemaMember member) { var stringType = member.MemberType as IStringType; if (stringType.IsReadonly) { if (stringType.LengthSourceType == StringLengthSourceType.NULL_TERMINATED) { cbsb.WriteLine($"er.AssertStringNT(this.{member.Name});"); } else if (stringType.IsEndianOrdered) { cbsb.WriteLine($"er.AssertStringEndian(this.{member.Name});"); } else { cbsb.WriteLine($"er.AssertString(this.{member.Name});"); } return; } if (stringType.LengthSourceType == StringLengthSourceType.NULL_TERMINATED) { cbsb.WriteLine($"this.{member.Name} = er.ReadStringNT();"); return; } if (stringType.LengthSourceType == StringLengthSourceType.CONST) { if (stringType.IsEndianOrdered) { cbsb.WriteLine( $"this.{member.Name} = er.ReadStringEndian({stringType.ConstLength});"); } else { cbsb.WriteLine( $"this.{member.Name} = er.ReadString({stringType.ConstLength});"); } return; } // TODO: Handle more cases throw new NotImplementedException(); }
private static void WriteBoolean_( ICurlyBracketStringBuilder cbsb, ISchemaMember member) { var primitiveType = member.MemberType as IPrimitiveMemberType; var writeType = SchemaGeneratorUtil.GetPrimitiveLabel( SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( primitiveType.AltFormat)); var castType = SchemaGeneratorUtil.GetTypeName( primitiveType.AltFormat); cbsb.WriteLine( $"ew.Write{writeType}(({castType}) (this.{member.Name} ? 1 : 0));"); }
private static void ReadGeneric_( ICurlyBracketStringBuilder cbsb, ISchemaMember member) { // TODO: Handle generic types beyond just IBiSerializable var structureMemberType = member.MemberType as IStructureMemberType; // TODO: Do value types need to be handled differently? var memberName = member.Name; if (structureMemberType.IsChild) { cbsb.WriteLine($"this.{memberName}.Parent = this;"); } cbsb.WriteLine($"this.{memberName}.Read(er);"); }
private static void WriteMember(System.Text.StringBuilder text, ISchemaMember member) { text.Append(member.Name); if (member.Paging != null && member.Paging.Enabled) { text.Append(':'); text.Append(member.Paging.PageIndex.ToString()); text.Append('/'); text.Append(member.Paging.PageSize.ToString()); } if (member.Sortings != null && member.Sortings.Length > 0) { text.Append('('); for (int i = 0; i < member.Sortings.Length; i++) { if (i > 0) { text.Append(','); } text.Append(member.Sortings[i].ToString()); } text.Append(')'); } if (member.Criteria != null) { text.Append('?'); text.Append(member.Criteria.ToString()); } if (member.HasChildren) { text.Append('{'); WriteMembers(text, member.Children); text.Append('}'); } }
private static void ReadBoolean_( ICurlyBracketStringBuilder cbsb, ISchemaMember member) { var primitiveType = member.MemberType as IPrimitiveMemberType; var readType = SchemaGeneratorUtil.GetPrimitiveLabel( SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( primitiveType.AltFormat)); if (!primitiveType.IsReadonly) { cbsb.WriteLine( $"this.{member.Name} = er.Read{readType}() != 0;"); } else { cbsb.WriteLine( $"er.Assert{readType}(this.{member.Name} ? 1 : 0);"); } }
/// <summary> /// 将指定 Lambda 表达式中的成员访问式从当前模式成员中移除。 /// </summary> /// <typeparam name="TMember">泛型参数,表示成员访问表达式类型。</typeparam> /// <param name="expression">指定的包含成员访问的 Lambda 表达式。</param> /// <returns>返回当前模式。</returns> /// <example> /// <code> /// Schema.Empty<Apartment>() /// .Exclude(p => p.ApartmentId) /// .Exclude(p => p.ApartmentNo) /// .Exclude(p => p.Building.BuildingId) /// .Exclude(p => p.Building.BuildingNo) /// .Exclude(p => p.Building.Park) /// </code> /// </example> public Schema <T> Exclude <TMember>(Expression <Func <T, TMember> > expression) { var members = GetMembers(expression); ISchemaMember parent = null, child = null; foreach (var member in members) { if (child != null) { parent = child; } if (parent == null) { if (!_members.TryGetValue(member.Name, out child)) { return(this); } } else if (!parent.HasChildren || !parent.Children.TryGetValue(member.Name, out child)) { return(this); } } if (child != null) { if (parent == null) { _members.Remove(child); } else if (parent.HasChildren) { parent.Children.Remove(child); } } return(this); }
private static void WritePrimitive_( ICurlyBracketStringBuilder cbsb, ISchemaMember member) { var primitiveType = member.MemberType as IPrimitiveMemberType; if (primitiveType.PrimitiveType == SchemaPrimitiveType.BOOLEAN) { SchemaWriterGenerator.WriteBoolean_(cbsb, member); return; } var readType = SchemaGeneratorUtil.GetPrimitiveLabel( primitiveType.UseAltFormat ? SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( primitiveType.AltFormat) : primitiveType.PrimitiveType); var needToCast = primitiveType.UseAltFormat && primitiveType.PrimitiveType != SchemaPrimitiveTypesUtil.GetUnderlyingPrimitiveType( SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( primitiveType.AltFormat)); var castText = ""; if (needToCast) { var castType = SchemaGeneratorUtil.GetTypeName(primitiveType.AltFormat); castText = $"({castType}) "; } cbsb.WriteLine( $"ew.Write{readType}({castText}this.{member.Name});"); }
private static void WriteMember_( ICurlyBracketStringBuilder cbsb, ITypeSymbol sourceSymbol, ISchemaMember member) { if (member.IsPosition) { return; } if (member.Offset != null) { cbsb.WriteLine("throw new NotImplementedException();"); return; } SchemaWriterGenerator.Align_(cbsb, member); var ifBoolean = member.IfBoolean; if (ifBoolean != null) { if (ifBoolean.SourceType == IfBooleanSourceType.IMMEDIATE_VALUE) { var booleanNumberType = SchemaPrimitiveTypesUtil.ConvertIntToNumber( ifBoolean.ImmediateBooleanType); var booleanPrimitiveType = SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( booleanNumberType); var booleanNumberLabel = SchemaGeneratorUtil.GetTypeName(booleanNumberType); var booleanPrimitiveLabel = SchemaGeneratorUtil.GetPrimitiveLabel(booleanPrimitiveType); cbsb.WriteLine( $"ew.Write{booleanPrimitiveLabel}(({booleanNumberLabel}) (this.{member.Name} != null ? 1 : 0));") .EnterBlock($"if (this.{member.Name} != null)"); } else { cbsb.EnterBlock($"if (this.{ifBoolean.BooleanMember.Name})"); } } var memberType = member.MemberType; if (memberType is IGenericMemberType genericMemberType) { memberType = genericMemberType.ConstraintType; } switch (memberType) { case IPrimitiveMemberType: { SchemaWriterGenerator.WritePrimitive_(cbsb, member); break; } case IStringType: { SchemaWriterGenerator.WriteString_(cbsb, member); break; } case IStructureMemberType structureMemberType: { SchemaWriterGenerator.WriteStructure_(cbsb, member); break; } case ISequenceMemberType: { SchemaWriterGenerator.WriteArray_(cbsb, sourceSymbol, member); break; } default: // Anything that makes it down here probably isn't meant to be read. throw new NotImplementedException(); } if (ifBoolean != null) { cbsb.ExitBlock(); } }
private static void WriteIntoArray_( ICurlyBracketStringBuilder cbsb, ITypeSymbol sourceSymbol, ISchemaMember member) { var arrayType = member.MemberType as ISequenceMemberType; var elementType = arrayType.ElementType; if (elementType is IGenericMemberType genericElementType) { elementType = genericElementType.ConstraintType; } if (elementType is IPrimitiveMemberType primitiveElementType) { // Primitives that don't need to be cast are the easiest to write. if (!primitiveElementType.UseAltFormat) { var label = SchemaGeneratorUtil.GetPrimitiveLabel( primitiveElementType.PrimitiveType); cbsb.WriteLine($"ew.Write{label}s(this.{member.Name});"); return; } // Primitives that *do* need to be cast have to be written individually. var writeType = SchemaGeneratorUtil.GetPrimitiveLabel( SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( primitiveElementType.AltFormat)); var arrayLengthName = arrayType.SequenceType == SequenceType.ARRAY ? "Length" : "Count"; var castType = primitiveElementType.PrimitiveType == SchemaPrimitiveType.ENUM ? SymbolTypeUtil.GetQualifiedNameFromCurrentSymbol( sourceSymbol, primitiveElementType.TypeSymbol) : primitiveElementType.TypeSymbol.Name; cbsb.EnterBlock( $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)") .WriteLine( $"ew.Write{writeType}(({castType}) this.{member.Name}[i]);") .ExitBlock(); return; } if (elementType is IStructureMemberType structureElementType) { //if (structureElementType.IsReferenceType) { cbsb.EnterBlock($"foreach (var e in this.{member.Name})") .WriteLine("e.Write(ew);") .ExitBlock(); // TODO: Do value types need to be read like below? /*} * // Value types (mainly structs) have to be pulled out, read, then put * // back in. * else { * var arrayLengthName = arrayType.SequenceType == SequenceType.ARRAY * ? "Length" * : "Count"; * cbsb.EnterBlock( * $"for (var i = 0; i < this.{member.Name}.{arrayLengthName}; ++i)") * .WriteLine($"var e = this.{member.Name}[i];") * .WriteLine("e.Read(ew);") * .WriteLine($"this.{member.Name}[i] = e;") * .ExitBlock(); * }*/ return; } // Anything that makes it down here probably isn't meant to be read. throw new NotImplementedException(); }
private static void ReadArray_( ICurlyBracketStringBuilder cbsb, ITypeSymbol sourceSymbol, ISchemaMember member) { var arrayType = member.MemberType as ISequenceMemberType; if (arrayType.LengthSourceType != SequenceLengthSourceType.CONST) { var isImmediate = arrayType.LengthSourceType == SequenceLengthSourceType.IMMEDIATE_VALUE; var lengthName = isImmediate ? "c" : $"this.{arrayType.LengthMember!.Name}"; if (isImmediate) { var readType = SchemaGeneratorUtil.GetIntLabel( arrayType.ImmediateLengthType); cbsb.EnterBlock() .WriteLine($"var {lengthName} = er.Read{readType}();"); } cbsb.EnterBlock($"if ({lengthName} < 0)") .WriteLine( $"throw new Exception(\"Expected length to be nonnegative!\");") .ExitBlock(); var qualifiedElementName = SymbolTypeUtil.GetQualifiedNameFromCurrentSymbol( sourceSymbol, arrayType.ElementType.TypeSymbol); var hasReferenceElements = arrayType.ElementType is IStructureMemberType { IsReferenceType : true }; // TODO: Handle readonly lists, can't be expanded like this! if (arrayType.SequenceType == SequenceType.LIST) { cbsb.EnterBlock($"if (this.{member.Name}.Count < {lengthName})"); if (hasReferenceElements) { cbsb.WriteLine( $"this.{member.Name}.Add(new {qualifiedElementName}());"); } else { cbsb.WriteLine($"this.{member.Name}.Add(default);"); } cbsb.ExitBlock(); cbsb.EnterBlock( $"while (this.{member.Name}.Count > {lengthName})") .WriteLine($"this.{member.Name}.RemoveAt(0);") .ExitBlock(); } else { cbsb.WriteLine( $"this.{member.Name} = new {qualifiedElementName}[{lengthName}];"); if (hasReferenceElements) { cbsb.EnterBlock($"for (var i = 0; i < {lengthName}; ++i)") .WriteLine( $"this.{member.Name}[i] = new {qualifiedElementName}();") .ExitBlock(); } } if (isImmediate) { cbsb.ExitBlock(); } } SchemaReaderGenerator.ReadIntoArray_(cbsb, sourceSymbol, member); }
private static void ReadMember_( ICurlyBracketStringBuilder cbsb, ITypeSymbol sourceSymbol, ISchemaMember member) { if (member.IsPosition) { if (member.MemberType.IsReadonly) { cbsb.WriteLine($"er.AssertPosition(this.{member.Name});"); } else { cbsb.WriteLine($"this.{member.Name} = er.Position;"); } return; } SchemaReaderGenerator.Align_(cbsb, member); // TODO: How to handle both offset & if boolean together? var offset = member.Offset; if (offset != null) { cbsb.EnterBlock() .WriteLine("var tempLocation = er.Position;") .WriteLine( $"er.Position = this.{offset.StartIndexName.Name} + this.{offset.OffsetName.Name};"); } var ifBoolean = member.IfBoolean; var immediateIfBoolean = ifBoolean?.SourceType == IfBooleanSourceType.IMMEDIATE_VALUE; if (immediateIfBoolean) { cbsb.EnterBlock(); } if (ifBoolean != null) { if (ifBoolean.SourceType == IfBooleanSourceType.IMMEDIATE_VALUE) { var booleanNumberType = SchemaPrimitiveTypesUtil.ConvertIntToNumber( ifBoolean.ImmediateBooleanType); var booleanPrimitiveType = SchemaPrimitiveTypesUtil.ConvertNumberToPrimitive( booleanNumberType); var booleanPrimitiveLabel = SchemaGeneratorUtil.GetPrimitiveLabel(booleanPrimitiveType); cbsb.WriteLine($"var b = er.Read{booleanPrimitiveLabel}() != 0;") .EnterBlock("if (b)"); } else { cbsb.EnterBlock($"if (this.{ifBoolean.BooleanMember.Name})"); } if (member.MemberType is not IPrimitiveMemberType) { cbsb.WriteLine( $"this.{member.Name} = new {SymbolTypeUtil.GetQualifiedNameFromCurrentSymbol(sourceSymbol, member.MemberType.TypeSymbol)}();"); } } var memberType = member.MemberType; if (memberType is IGenericMemberType genericMemberType) { memberType = genericMemberType.ConstraintType; } switch (memberType) { case IPrimitiveMemberType: { SchemaReaderGenerator.ReadPrimitive_(cbsb, sourceSymbol, member); break; } case IStringType: { SchemaReaderGenerator.ReadString_(cbsb, member); break; } case IStructureMemberType structureMemberType: { SchemaReaderGenerator.ReadStructure_(cbsb, structureMemberType, member); break; } case ISequenceMemberType: { SchemaReaderGenerator.ReadArray_(cbsb, sourceSymbol, member); break; } default: { // Anything that makes it down here probably isn't meant to be read. throw new NotImplementedException(); } } if (ifBoolean != null) { cbsb.ExitBlock() .EnterBlock("else") .WriteLine($"this.{member.Name} = null;") .ExitBlock(); if (immediateIfBoolean) { cbsb.ExitBlock(); } } if (offset != null) { cbsb.WriteLine("er.Position = tempLocation;") .ExitBlock(); } }
private string GetSchemaNameSql(ISchemaMember sqlObject) { return keywordEncoder.Encode(sqlObject.Schema.Name); }
ISchemaMember ISchemaMemberProvider.GetMember(string name, ISchemaMember parent) => this.GetMember(name, parent);
protected abstract ISchemaMember GetMember(string name, ISchemaMember parent);