//TODO: Investigate removing these. private void ImportPseudoMembers(PseudoClassMembers memberSet, ClassSymbol classSymbol) { // Import pseudo members that go on the class but aren't defined in mscorlib.dll // These are meant to be used by internal compiler-generated transformations etc. // and aren't meant to be referenced directly in C# code. if (memberSet == PseudoClassMembers.Script) { AddScriptSymbolPseudoMembers(classSymbol); return; } if (memberSet == PseudoClassMembers.Arguments) { TypeSymbol objectType = (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(Object), null, SymbolFilter.Types); Debug.Assert(objectType != null); IndexerSymbol indexer = new IndexerSymbol(classSymbol, objectType, MemberVisibility.Public | MemberVisibility.Static); indexer.SetScriptIndexer(); classSymbol.AddMember(indexer); return; } if (memberSet == PseudoClassMembers.Dictionary) { TypeSymbol intType = (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(Int32), null, SymbolFilter.Types); Debug.Assert(intType != null); TypeSymbol stringType = (TypeSymbol)((ISymbolTable)symbols.SystemNamespace).FindSymbol(nameof(String), null, SymbolFilter.Types); Debug.Assert(stringType != null); // Define Dictionary.Keys MethodSymbol getKeysMethod = new MethodSymbol("GetKeys", classSymbol, symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static); getKeysMethod.SetTransformName(DSharpStringResources.ScriptExportMember("keys")); classSymbol.AddMember(getKeysMethod); // Define Dictionary.Values MethodSymbol getValuesMethod = new MethodSymbol("GetValues", classSymbol, symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static); getValuesMethod.SetTransformName(DSharpStringResources.ScriptExportMember("values")); classSymbol.AddMember(getValuesMethod); // Define Dictionary.GetCount MethodSymbol countMethod = new MethodSymbol("GetKeyCount", classSymbol, intType, MemberVisibility.Public | MemberVisibility.Static); countMethod.SetTransformName(DSharpStringResources.ScriptExportMember("keyCount")); classSymbol.AddMember(countMethod); } }
private void ImportProperties(TypeSymbol typeSymbol) { TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference; foreach (PropertyDefinition property in type.Properties) { if (property.IsSpecialName) { continue; } if (property.GetMethod == null) { continue; } if (property.GetMethod.IsPrivate || property.GetMethod.IsAssembly || property.GetMethod.IsFamilyAndAssembly) { continue; } string propertyName = property.Name; bool scriptField = MetadataHelpers.ShouldTreatAsScriptField(property); // TODO: Why are we ignoring the other bits... // bool dummyPreserveName; // bool preserveCase; // string dummyName = MetadataHelpers.GetScriptName(property, out dummyPreserveName, out preserveCase); TypeSymbol propertyType = ResolveType(property.PropertyType); if (propertyType == null) { continue; } PropertySymbol propertySymbol = null; if (property.Parameters.Count != 0) { IndexerSymbol indexerSymbol = new IndexerSymbol(typeSymbol, propertyType); ImportMemberDetails(indexerSymbol, property.GetMethod, property); if (scriptField) { indexerSymbol.SetScriptIndexer(); } propertySymbol = indexerSymbol; // propertySymbol.SetNameCasing(preserveCase); } else { if (scriptField) { // Properties marked with this attribute are to be thought of as // fields. If they are read-only, the C# compiler will enforce that, // so we don't have to worry about making them read-write via a field // instead of a property FieldSymbol fieldSymbol = new FieldSymbol(propertyName, typeSymbol, propertyType); ImportMemberDetails(fieldSymbol, property.GetMethod, property); string transformedName = MetadataHelpers.GetTransformedName(property); if (string.IsNullOrEmpty(transformedName) == false) { fieldSymbol.SetTransformName(transformedName); } typeSymbol.AddMember(fieldSymbol); } else { propertySymbol = new PropertySymbol(propertyName, typeSymbol, propertyType); ImportMemberDetails(propertySymbol, property.GetMethod, property); propertySymbol.SetNameCasing(true); string transformedName = MetadataHelpers.GetTransformedName(property.GetMethod); if (string.IsNullOrEmpty(transformedName) == false) { propertySymbol.SetTransformedName(transformedName); } } } if (propertySymbol != null) { SymbolImplementationFlags implFlags = SymbolImplementationFlags.Regular; if (property.SetMethod == null) { implFlags |= SymbolImplementationFlags.ReadOnly; } if (property.GetMethod.IsAbstract) { implFlags |= SymbolImplementationFlags.Abstract; } propertySymbol.SetImplementationState(implFlags); typeSymbol.AddMember(propertySymbol); } } }
private void ImportPseudoMembers(PseudoClassMembers memberSet, ClassSymbol classSymbol) { // Import pseudo members that go on the class but aren't defined in mscorlib.dll // These are meant to be used by internal compiler-generated transformations etc. // and aren't meant to be referenced directly in C# code. if (memberSet == PseudoClassMembers.Script) { TypeSymbol objectType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Object", null, SymbolFilter.Types); Debug.Assert(objectType != null); TypeSymbol stringType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("String", null, SymbolFilter.Types); Debug.Assert(stringType != null); TypeSymbol boolType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Boolean", null, SymbolFilter.Types); Debug.Assert(boolType != null); TypeSymbol dateType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Date", null, SymbolFilter.Types); Debug.Assert(dateType != null); // Enumerate - IEnumerable.GetEnumerator gets mapped to this MethodSymbol enumerateMethod = new MethodSymbol("Enumerate", classSymbol, objectType, MemberVisibility.Public | MemberVisibility.Static); enumerateMethod.SetAlias("ss.enumerate"); enumerateMethod.AddParameter(new ParameterSymbol("obj", enumerateMethod, objectType, ParameterMode.In)); classSymbol.AddMember(enumerateMethod); // TypeName - Type.Name gets mapped to this MethodSymbol typeNameMethod = new MethodSymbol("GetTypeName", classSymbol, stringType, MemberVisibility.Public | MemberVisibility.Static); typeNameMethod.SetAlias("ss.typeName"); typeNameMethod.AddParameter(new ParameterSymbol("obj", typeNameMethod, objectType, ParameterMode.In)); classSymbol.AddMember(typeNameMethod); // CompareDates - Date equality checks get converted to call to compareDates MethodSymbol compareDatesMethod = new MethodSymbol("CompareDates", classSymbol, boolType, MemberVisibility.Public | MemberVisibility.Static); compareDatesMethod.SetAlias("ss.compareDates"); compareDatesMethod.AddParameter(new ParameterSymbol("d1", compareDatesMethod, dateType, ParameterMode.In)); compareDatesMethod.AddParameter(new ParameterSymbol("d2", compareDatesMethod, dateType, ParameterMode.In)); classSymbol.AddMember(compareDatesMethod); return; } if (memberSet == PseudoClassMembers.Arguments) { TypeSymbol objectType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Object", null, SymbolFilter.Types); Debug.Assert(objectType != null); IndexerSymbol indexer = new IndexerSymbol(classSymbol, objectType, MemberVisibility.Public | MemberVisibility.Static); indexer.SetScriptIndexer(); classSymbol.AddMember(indexer); return; } if (memberSet == PseudoClassMembers.Dictionary) { TypeSymbol intType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("Int32", null, SymbolFilter.Types); Debug.Assert(intType != null); TypeSymbol stringType = (TypeSymbol)((ISymbolTable)_symbols.SystemNamespace).FindSymbol("String", null, SymbolFilter.Types); Debug.Assert(stringType != null); // Define Dictionary.Keys MethodSymbol getKeysMethod = new MethodSymbol("GetKeys", classSymbol, _symbols.CreateArrayTypeSymbol(stringType), MemberVisibility.Public | MemberVisibility.Static); getKeysMethod.SetAlias("ss.keys"); classSymbol.AddMember(getKeysMethod); // Define Dictionary.GetCount MethodSymbol countMethod = new MethodSymbol("GetKeyCount", classSymbol, intType, MemberVisibility.Public | MemberVisibility.Static); countMethod.SetAlias("ss.keyCount"); classSymbol.AddMember(countMethod); return; } }