//------------------------------------------------------------ // RemoveQuotesAndReplaceComma // /// <summary> /// <para>(sscli) RemoveQuotesAndReplaceComma (csharp\shared\fielcpp)</para> /// <para>Remove quote marks from a string. Also, commas (,) that are not quoted /// are converted to the pipe (|) character. /// The translation is done in-place, and the argument is returned.</para> /// </summary> /// <param name="sourceText"></param> /// <returns></returns> //------------------------------------------------------------ static internal string RemoveQuotesAndReplaceComma(string sourceText) { if (sourceText == null) { return(null); } string input = sourceText; StringBuilder buffer = new StringBuilder(); char ch; bool inQuote; int index = 0; inQuote = false; while (index < sourceText.Length) { switch (ch = sourceText[index]) { case '\0': // End of string. We're done. return(buffer.ToString()); case '\"': inQuote = !inQuote; break; case '|': DebugUtil.VsFail("How did we get this here!"); //__assume(0); goto default; case '\\': if (ProcessSlashes(sourceText, ref index, buffer)) { inQuote = !inQuote; } // Not break because ProcessSlashes has already advanced index continue; case ',': if (inQuote) { goto default; } buffer.Append('|'); break; default: buffer.Append(ch); break; } ++index; } return(buffer.ToString()); }
//------------------------------------------------------------ // MetaDataHelper.GetAggregateFlags // /// <summary> /// <para>Determine the flags for a typedef definition in metadata</para> /// <para>Use System.Reflection.TypeAttribuetes in place of CorTypeAttr of sscli.</para> /// <para>CorTypeAttr has a member named "Forwarder" which TypeAttributes does not has.</para> /// </summary> /// <param name="aggSym"></param> /// <returns></returns> //------------------------------------------------------------ internal static TypeAttributes GetAggregateFlags(AGGSYM aggSym) { TypeAttributes flags = 0; // Determine flags. // Set access flags. flags |= GetTypeAccessFlags(aggSym); // Set other flags switch (aggSym.AggKind) { case AggKindEnum.Class: if (aggSym.IsSealed) { flags |= TypeAttributes.Sealed; } if (aggSym.IsAbstract) { flags |= TypeAttributes.Abstract; } if (!aggSym.HasUserDefinedStaticCtor) { flags |= TypeAttributes.BeforeFieldInit; } break; case AggKindEnum.Interface: flags |= TypeAttributes.Interface | TypeAttributes.Abstract; break; case AggKindEnum.Enum: DebugUtil.Assert(aggSym.IsSealed); flags |= TypeAttributes.Sealed; break; case AggKindEnum.Struct: DebugUtil.Assert(aggSym.IsSealed); flags |= TypeAttributes.Sealed; if (!aggSym.HasUserDefinedStaticCtor) { flags |= TypeAttributes.BeforeFieldInit; } if (aggSym.IsFabricated) { flags |= TypeAttributes.SequentialLayout; // Fabricated structs are always sequential } break; case AggKindEnum.Delegate: DebugUtil.Assert(aggSym.IsSealed); flags |= TypeAttributes.Sealed; break; default: DebugUtil.Assert(false); break; } switch (aggSym.GetOutputFile().DefaultCharSet) { default: DebugUtil.VsFail("A new value was added to System.Runtime.InteropServices.CharSet that we need to handle"); goto case 0; case (System.Runtime.InteropServices.CharSet) 0: // Unset case System.Runtime.InteropServices.CharSet.None: // 1: break; case System.Runtime.InteropServices.CharSet.Ansi: // 2: flags |= TypeAttributes.AnsiClass; break; case System.Runtime.InteropServices.CharSet.Unicode: // 3: flags |= TypeAttributes.UnicodeClass; break; case System.Runtime.InteropServices.CharSet.Auto: // 4: flags |= TypeAttributes.AutoClass; break; } return(flags); }
//------------------------------------------------------------ // FUNCBREC.HasIEnumerable (2) // /// <summary> /// Rewrite HasIEnumerable for collection initializer. /// Return the IEnumerable or IEnumerable<T> instance. /// </summary> /// <param name="collection"></param> /// <param name="tree"></param> /// <param name="badType"></param> /// <param name="badMember"></param> /// <returns></returns> //------------------------------------------------------------ private AGGTYPESYM HasIEnumerable( TYPESYM collectionTypeSym/*, * BASENODE treeNode, * TYPESYM badTypeSym, * PREDEFNAME badMemberName*/ ) { AGGTYPESYM ifaceCandidateAts = null; // First try the generic interfaces AGGSYM gEnumAggSym = Compiler.GetOptPredefAgg(PREDEFTYPE.G_IENUMERABLE, true); TypeArray allIfacesTypeArray = null; AGGTYPESYM baseAts = null; // If generics don't exist or the type isn't an AGGTYPESYM // then we can't check the interfaces (and base-class interfaces) // for IEnumerable<T> so immediately try the non-generic IEnumerable if (gEnumAggSym == null) { goto NO_GENERIC; } if (collectionTypeSym.IsAGGTYPESYM) { if (collectionTypeSym.GetAggregate() == gEnumAggSym || collectionTypeSym.IsPredefType(PREDEFTYPE.IENUMERABLE)) { DebugUtil.Assert(false, "IEnumerable/ator types are bad!"); goto LERROR; } AGGTYPESYM tempAts = collectionTypeSym as AGGTYPESYM; allIfacesTypeArray = tempAts.GetIfacesAll(); baseAts = tempAts.GetBaseClass(); } else if (collectionTypeSym.IsTYVARSYM) { // Note: // we'll search the interface list before the class constraint, // but it doesn't matter since we require a unique instantiation of IEnumerable<T>. // Note: // The pattern search will usually find the interface constraint // - but if the class constraint has a non-public or non-applicable // or non-method GetEnumerator, // the interfaces are hidden in which case we will find them here. TYVARSYM tempTvSym = collectionTypeSym as TYVARSYM; allIfacesTypeArray = tempTvSym.AllInterfaces; baseAts = tempTvSym.BaseClassSym; } else { goto NO_GENERIC; } DebugUtil.Assert(allIfacesTypeArray != null); // If the type implements exactly one instantiation of // IEnumerable<T> then it's the one. // // If it implements none then try the non-generic interface. // // If it implements more than one, then it's an error. // // Search the direct and indirect interfaces via allIfacesTypeArray, // going up the base chain... // Work up the base chain for (; ;) { // Now work across all the interfaces for (int i = 0; i < allIfacesTypeArray.Count; ++i) { AGGTYPESYM iface = allIfacesTypeArray[i] as AGGTYPESYM; if (iface.GetAggregate() == gEnumAggSym) { if (ifaceCandidateAts == null) { // First implementation ifaceCandidateAts = iface; } else if (iface != ifaceCandidateAts) { // If this really is a different instantiation report an error Compiler.Error( treeNode, CSCERRID.ERR_MultipleIEnumOfT, new ErrArgRef(collectionTypeSym), new ErrArg(gEnumAggSym.GetThisType())); return(null); } } } // Check the base class. if (baseAts == null) { break; } allIfacesTypeArray = baseAts.GetIfacesAll(); baseAts = baseAts.GetBaseClass(); } // Report the one and only generic interface if (ifaceCandidateAts != null) { DebugUtil.Assert( CanConvert(collectionTypeSym, ifaceCandidateAts, ConvertTypeEnum.NOUDC)); return(ifaceCandidateAts); } NO_GENERIC: if (collectionTypeSym.IsPredefType(PREDEFTYPE.IENUMERABLE)) { DebugUtil.VsFail("Why didn't IEnumerator match the pattern?"); goto LERROR; } // No errors, no generic interfaces, try the non-generic interface ifaceCandidateAts = GetRequiredPredefinedType(PREDEFTYPE.IENUMERABLE); if (CanConvert(collectionTypeSym, ifaceCandidateAts, ConvertTypeEnum.NOUDC)) { return(ifaceCandidateAts); } LERROR: return(null); }