<PackageReference Include="Microsoft.CSharp" Version="4.6.0-rc1.19456.4" />

UserStringBuilder

using Microsoft.CSharp.RuntimeBinder.Semantics; using Microsoft.CSharp.RuntimeBinder.Syntax; using System.Globalization; using System.Text; namespace Microsoft.CSharp.RuntimeBinder.Errors { internal struct UserStringBuilder { private StringBuilder _strBuilder; private void BeginString() { if (_strBuilder == null) _strBuilder = new StringBuilder(); } private string EndString() { string result = _strBuilder.ToString(); _strBuilder.Clear(); return result; } private static string ErrSK(SYMKIND sk) { MessageID id; switch (sk) { case SYMKIND.SK_MethodSymbol: id = MessageID.SK_METHOD; break; case SYMKIND.SK_AggregateSymbol: id = MessageID.SK_CLASS; break; case SYMKIND.SK_NamespaceSymbol: id = MessageID.SK_NAMESPACE; break; case SYMKIND.SK_FieldSymbol: id = MessageID.SK_FIELD; break; case SYMKIND.SK_LocalVariableSymbol: id = MessageID.SK_VARIABLE; break; case SYMKIND.SK_PropertySymbol: id = MessageID.SK_PROPERTY; break; case SYMKIND.SK_EventSymbol: id = MessageID.SK_EVENT; break; case SYMKIND.SK_TypeParameterSymbol: id = MessageID.SK_TYVAR; break; default: id = MessageID.SK_UNKNOWN; break; } return ErrId(id); } private void ErrAppendParamList(TypeArray params, bool isParamArray) { if (params != null) { for (int i = 0; i < params.Count; i++) { if (i > 0) ErrAppendString(", "); if (isParamArray && i == params.Count - 1) ErrAppendString("params "); ErrAppendType(params[i], null); } } } private void ErrAppendString(string str) { _strBuilder.Append(str); } private void ErrAppendChar(char ch) { _strBuilder.Append(ch); } private void ErrAppendPrintf(string format, params object[] args) { ErrAppendString(string.Format(CultureInfo.InvariantCulture, format, args)); } private void ErrAppendName(Name name) { if (name == NameManager.GetPredefinedName(PredefinedName.PN_INDEXERINTERNAL)) ErrAppendString("this"); else ErrAppendString(name.Text); } private void ErrAppendParentSym(Symbol sym, SubstContext pctx) { ErrAppendParentCore(sym.parent, pctx); } private void ErrAppendParentCore(Symbol parent, SubstContext pctx) { if (parent == null || parent == NamespaceSymbol.Root) return; if (pctx != null && !pctx.IsNop) { AggregateSymbol aggregateSymbol = parent as AggregateSymbol; if (aggregateSymbol != null && aggregateSymbol.GetTypeVarsAll().Count != 0) { CType pType = TypeManager.SubstType(aggregateSymbol.getThisType(), pctx); ErrAppendType(pType, null); goto IL_004d; } } ErrAppendSym(parent, null); goto IL_004d; IL_004d: ErrAppendChar('.'); } private void ErrAppendTypeParameters(TypeArray params, SubstContext pctx) { if (params != null && params.Count != 0) { ErrAppendChar('<'); ErrAppendType(params[0], pctx); for (int i = 1; i < params.Count; i++) { ErrAppendString(","); ErrAppendType(params[i], pctx); } ErrAppendChar('>'); } } private void ErrAppendMethod(MethodSymbol meth, SubstContext pctx, bool fArgs) { if (meth.IsExpImpl() && (bool)meth.swtSlot) { ErrAppendParentSym(meth, pctx); SubstContext pctx2 = new SubstContext(TypeManager.SubstType(meth.swtSlot.GetType(), pctx)); ErrAppendSym(meth.swtSlot.Sym, pctx2, fArgs); } else { MethodKindEnum methKind = meth.MethKind; switch (methKind) { case MethodKindEnum.PropAccessor: { PropertySymbol property = meth.getProperty(); ErrAppendSym(property, pctx); if (property.GetterMethod == meth) ErrAppendString(".get"); else ErrAppendString(".set"); break; } case MethodKindEnum.EventAccessor: { EventSymbol event = meth.getEvent(); ErrAppendSym(event, pctx); if (event.methAdd == meth) ErrAppendString(".add"); else ErrAppendString(".remove"); break; } default: ErrAppendParentSym(meth, pctx); switch (methKind) { case MethodKindEnum.Constructor: ErrAppendName(meth.getClass().name); break; case MethodKindEnum.Destructor: ErrAppendChar('~'); goto case MethodKindEnum.Constructor; case MethodKindEnum.ExplicitConv: ErrAppendString("explicit"); goto IL_0118; case MethodKindEnum.ImplicitConv: ErrAppendString("implicit"); goto IL_0118; default: { if (meth.isOperator) { ErrAppendString("operator "); ErrAppendString(Operators.OperatorOfMethodName(meth.name)); } else if (!meth.IsExpImpl()) { ErrAppendName(meth.name); } break; } IL_0118: ErrAppendString(" operator "); ErrAppendType(meth.RetType, pctx); break; } ErrAppendTypeParameters(meth.typeVars, pctx); if (fArgs) { ErrAppendChar('('); ErrAppendParamList(TypeManager.SubstTypeArray(meth.Params, pctx), meth.isParamArray); ErrAppendChar(')'); } break; } } } private void ErrAppendIndexer(IndexerSymbol indexer, SubstContext pctx) { ErrAppendString("this["); ErrAppendParamList(TypeManager.SubstTypeArray(indexer.Params, pctx), indexer.isParamArray); ErrAppendChar(']'); } private void ErrAppendProperty(PropertySymbol prop, SubstContext pctx) { ErrAppendParentSym(prop, pctx); if (prop.IsExpImpl()) { if (prop.swtSlot.Sym != null) { SubstContext pctx2 = new SubstContext(TypeManager.SubstType(prop.swtSlot.GetType(), pctx)); ErrAppendSym(prop.swtSlot.Sym, pctx2); } else { IndexerSymbol indexerSymbol = prop as IndexerSymbol; if (indexerSymbol != null) { ErrAppendChar('.'); ErrAppendIndexer(indexerSymbol, pctx); } } } else { IndexerSymbol indexerSymbol2 = prop as IndexerSymbol; if (indexerSymbol2 != null) ErrAppendIndexer(indexerSymbol2, pctx); else ErrAppendName(prop.name); } } private void ErrAppendId(MessageID id) { ErrAppendString(ErrId(id)); } private void ErrAppendSym(Symbol sym, SubstContext pctx) { ErrAppendSym(sym, pctx, true); } private void ErrAppendSym(Symbol sym, SubstContext pctx, bool fArgs) { switch (sym.getKind()) { case SYMKIND.SK_EventSymbol: break; case SYMKIND.SK_AggregateSymbol: { string niceName = PredefinedTypes.GetNiceName(sym as AggregateSymbol); if (niceName != null) ErrAppendString(niceName); else { ErrAppendParentSym(sym, pctx); ErrAppendName(sym.name); ErrAppendTypeParameters(((AggregateSymbol)sym).GetTypeVars(), pctx); } break; } case SYMKIND.SK_MethodSymbol: ErrAppendMethod((MethodSymbol)sym, pctx, fArgs); break; case SYMKIND.SK_PropertySymbol: ErrAppendProperty((PropertySymbol)sym, pctx); break; case SYMKIND.SK_NamespaceSymbol: if (sym == NamespaceSymbol.Root) ErrAppendId(MessageID.GlobalNamespace); else { ErrAppendParentSym(sym, null); ErrAppendName(sym.name); } break; case SYMKIND.SK_FieldSymbol: ErrAppendParentSym(sym, pctx); ErrAppendName(sym.name); break; case SYMKIND.SK_TypeParameterSymbol: if (sym.name == null) { TypeParameterSymbol typeParameterSymbol = (TypeParameterSymbol)sym; if (typeParameterSymbol.IsMethodTypeParameter()) ErrAppendChar('!'); ErrAppendChar('!'); ErrAppendPrintf("{0}", typeParameterSymbol.GetIndexInTotalParameters()); } else ErrAppendName(sym.name); break; case SYMKIND.SK_LocalVariableSymbol: ErrAppendName(sym.name); break; } } private void ErrAppendType(CType pType, SubstContext pctx) { if (pctx != null && !pctx.IsNop) pType = TypeManager.SubstType(pType, pctx); switch (pType.TypeKind) { case TypeKind.TK_AggregateType: { AggregateType aggregateType = (AggregateType)pType; string niceName = PredefinedTypes.GetNiceName(aggregateType.OwningAggregate); if (niceName != null) ErrAppendString(niceName); else { if (aggregateType.OuterType != null) { ErrAppendType(aggregateType.OuterType, null); ErrAppendChar('.'); } else ErrAppendParentSym(aggregateType.OwningAggregate, null); ErrAppendName(aggregateType.OwningAggregate.name); } ErrAppendTypeParameters(aggregateType.TypeArgsThis, null); break; } case TypeKind.TK_TypeParameterType: { TypeParameterType typeParameterType = (TypeParameterType)pType; if (typeParameterType.Name == null) { if (typeParameterType.IsMethodTypeParameter) ErrAppendChar('!'); ErrAppendChar('!'); ErrAppendPrintf("{0}", typeParameterType.IndexInTotalParameters); } else ErrAppendName(typeParameterType.Name); break; } case TypeKind.TK_NullType: ErrAppendId(MessageID.NULL); break; case TypeKind.TK_MethodGroupType: ErrAppendId(MessageID.MethodGroup); break; case TypeKind.TK_ArgumentListType: ErrAppendString(TokenFacts.GetText(TokenKind.ArgList)); break; case TypeKind.TK_ArrayType: { CType baseElementType = ((ArrayType)pType).BaseElementType; ErrAppendType(baseElementType, null); baseElementType = pType; while (true) { ArrayType arrayType = baseElementType as ArrayType; if (arrayType == null) break; int rank = arrayType.Rank; ErrAppendChar('['); if (rank == 1) { if (!arrayType.IsSZArray) ErrAppendChar('*'); } else { for (int num = rank; num > 1; num--) { ErrAppendChar(','); } } ErrAppendChar(']'); baseElementType = arrayType.ElementType; } break; } case TypeKind.TK_VoidType: ErrAppendName(NameManager.GetPredefinedName(PredefinedName.PN_VOID)); break; case TypeKind.TK_ParameterModifierType: { ParameterModifierType parameterModifierType = (ParameterModifierType)pType; ErrAppendString(parameterModifierType.IsOut ? "out " : "ref "); ErrAppendType(parameterModifierType.ParameterType, null); break; } case TypeKind.TK_PointerType: ErrAppendType(((PointerType)pType).ReferentType, null); ErrAppendChar('*'); break; case TypeKind.TK_NullableType: ErrAppendType(((NullableType)pType).UnderlyingType, null); ErrAppendChar('?'); break; } } public bool ErrArgToString(out string psz, ErrArg parg, out bool fUserStrings) { fUserStrings = false; psz = null; bool result = true; switch (parg.eak) { case ErrArgKind.SymKind: psz = ErrSK(parg.sk); break; case ErrArgKind.Type: BeginString(); ErrAppendType(parg.pType, null); psz = EndString(); fUserStrings = true; break; case ErrArgKind.Sym: BeginString(); ErrAppendSym(parg.sym, null); psz = EndString(); fUserStrings = true; break; case ErrArgKind.Name: if (parg.name == NameManager.GetPredefinedName(PredefinedName.PN_INDEXERINTERNAL)) psz = "this"; else psz = parg.name.Text; break; case ErrArgKind.Str: psz = parg.psz; break; case ErrArgKind.SymWithType: { SubstContext pctx2 = new SubstContext(parg.swtMemo.ats, null); BeginString(); ErrAppendSym(parg.swtMemo.sym, pctx2, true); psz = EndString(); fUserStrings = true; break; } case ErrArgKind.MethWithInst: { SubstContext pctx = new SubstContext(parg.mpwiMemo.ats, parg.mpwiMemo.typeArgs); BeginString(); ErrAppendSym(parg.mpwiMemo.sym, pctx, true); psz = EndString(); fUserStrings = true; break; } default: result = false; break; } return result; } private static string ErrId(MessageID id) { return ErrorFacts.GetMessage(id); } } }