private void ImportEnumFields(TypeSymbol enumTypeSymbol) { TypeDefinition type = (TypeDefinition)enumTypeSymbol.MetadataReference; foreach (FieldDefinition field in type.Fields) { if (field.IsSpecialName) { continue; } Debug.Assert(enumTypeSymbol is EnumerationSymbol); EnumerationSymbol enumSymbol = (EnumerationSymbol)enumTypeSymbol; TypeSymbol fieldType; if (enumSymbol.UseNamedValues) { fieldType = symbols.ResolveIntrinsicType(IntrinsicType.String); } else { fieldType = symbols.ResolveIntrinsicType(IntrinsicType.Integer); } string fieldName = field.Name; EnumerationFieldSymbol fieldSymbol = new EnumerationFieldSymbol(fieldName, enumTypeSymbol, field.Constant, fieldType); ImportMemberDetails(fieldSymbol, null, field); enumTypeSymbol.AddMember(fieldSymbol); } }
private void ImportDelegateInvoke(TypeSymbol delegateTypeSymbol) { TypeDefinition type = (TypeDefinition)delegateTypeSymbol.MetadataReference; foreach (MethodDefinition method in type.Methods) { if (string.CompareOrdinal(method.Name, "Invoke") != 0) { continue; } TypeSymbol returnType = ResolveType(method.MethodReturnType.ReturnType); Debug.Assert(returnType != null); if (returnType == null) { continue; } MethodSymbol methodSymbol = new MethodSymbol("Invoke", delegateTypeSymbol, returnType, MemberVisibility.Public); methodSymbol.SetImplementationState(SymbolImplementationFlags.Abstract); methodSymbol.SetTransformedName(string.Empty); delegateTypeSymbol.AddMember(methodSymbol); } }
private void ImportEvents(TypeSymbol typeSymbol) { TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference; foreach (EventDefinition eventDef in type.Events) { if (eventDef.IsSpecialName) { continue; } if ((eventDef.AddMethod == null) || (eventDef.RemoveMethod == null)) { continue; } if (eventDef.AddMethod.IsPrivate || eventDef.AddMethod.IsAssembly || eventDef.AddMethod.IsFamilyAndAssembly) { continue; } string eventName = eventDef.Name; TypeSymbol eventHandlerType = ResolveType(eventDef.EventType); if (eventHandlerType == null) { continue; } EventSymbol eventSymbol = new EventSymbol(eventName, typeSymbol, eventHandlerType); ImportMemberDetails(eventSymbol, eventDef.AddMethod, eventDef); typeSymbol.AddMember(eventSymbol); } }
private void ImportFields(TypeSymbol typeSymbol) { TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference; foreach (FieldDefinition field in type.Fields) { if (field.IsSpecialName) { continue; } if (field.IsPrivate || field.IsAssembly || field.IsFamilyAndAssembly) { continue; } string fieldName = field.Name; TypeSymbol fieldType = ResolveType(field.FieldType); if (fieldType == null) { continue; } MemberVisibility visibility = MemberVisibility.PrivateInstance; if (field.IsStatic) { visibility |= MemberVisibility.Static; } if (field.IsPublic) { visibility |= MemberVisibility.Public; } else if (field.IsFamily || field.IsFamilyOrAssembly) { visibility |= MemberVisibility.Protected; } FieldSymbol fieldSymbol = new FieldSymbol(fieldName, typeSymbol, fieldType); fieldSymbol.SetVisibility(visibility); ImportMemberDetails(fieldSymbol, null, field); if (field.IsLiteral && field.HasConstant && !typeSymbol.IsCoreType && (field.FieldType.IsPrimitive || field.FieldType.Name == "String")) { fieldSymbol.SetConstant(); fieldSymbol.Value = field.Constant; } typeSymbol.AddMember(fieldSymbol); } }
private void ImportEvents(TypeSymbol typeSymbol) { TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference; foreach (EventDefinition eventDef in type.Events) { if (eventDef.IsSpecialName) { continue; } if (eventDef.AddMethod == null || eventDef.RemoveMethod == null) { continue; } if (eventDef.AddMethod.IsPrivate || eventDef.AddMethod.IsAssembly || eventDef.AddMethod.IsFamilyAndAssembly) { continue; } string eventName = eventDef.Name; TypeSymbol eventHandlerType = ResolveType(eventDef.EventType); if (eventHandlerType == null) { continue; } EventSymbol eventSymbol = new EventSymbol(eventName, typeSymbol, eventHandlerType); ImportMemberDetails(eventSymbol, eventDef.AddMethod, eventDef); if (MetadataHelpers.GetScriptEventAccessors(eventDef, out string addAccessor, out string removeAccessor)) { eventSymbol.SetAccessors(addAccessor, removeAccessor); } typeSymbol.AddMember(eventSymbol); } }
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 ImportMethods(TypeSymbol typeSymbol) { // NOTE: We do not import parameters for imported members. // Parameters are used in the script model generation phase to populate // symbol tables, which is not done for imported methods. TypeDefinition type = (TypeDefinition)typeSymbol.MetadataReference; foreach (MethodDefinition method in type.Methods) { if (method.IsSpecialName) { continue; } if (method.IsPrivate || method.IsAssembly || method.IsFamilyAndAssembly) { continue; } string methodName = method.Name; if (typeSymbol.GetMember(methodName) != null) { // Ignore if its an overload since we don't care about parameters // for imported methods, overloaded ctors don't matter. // We just care about return values pretty much, and existence of the // method. continue; } TypeSymbol returnType = ResolveType(method.MethodReturnType.ReturnType); if (returnType == null) { continue; } // skip symbol generation for members decorated with [ScriptIgnore] if (MetadataHelpers.IsIgnored(method)) { continue; } MethodSymbol methodSymbol = new MethodSymbol( methodName, typeSymbol, returnType, MetadataHelpers.IsExtensionMethod(method)); if (MetadataHelpers.ShouldIgnoreMethodGeneratedTypeArguments(method)) { methodSymbol.IgnoreGeneratedTypeArguments = true; } methodSymbol.SetParseContext(method); ImportMemberDetails(methodSymbol, method, method); if (method.HasGenericParameters) { List <GenericParameterSymbol> genericArguments = new List <GenericParameterSymbol>(); foreach (GenericParameter genericParameter in method.GenericParameters) { GenericParameterSymbol arg = new GenericParameterSymbol(genericParameter.Position, genericParameter.Name, /* typeArgument */ false, symbols.GlobalNamespace); genericArguments.Add(arg); } methodSymbol.AddGenericArguments(genericArguments); } if (method.IsAbstract) { // NOTE: We're ignoring the override scenario - it doesn't matter in terms // of the compilation and code generation methodSymbol.SetImplementationState(SymbolImplementationFlags.Abstract); } if (MetadataHelpers.ShouldSkipFromScript(method)) { methodSymbol.SetSkipGeneration(); } string transformedName = MetadataHelpers.GetTransformedName(method); if (string.IsNullOrEmpty(transformedName) == false) { methodSymbol.SetTransformName(transformedName); } string scriptName = MetadataHelpers.GetScriptName(method, out _, out _); if (string.IsNullOrEmpty(scriptName) == false && !methodSymbol.IsTransformed) { methodSymbol.SetTransformedName(scriptName); } string selector = MetadataHelpers.GetScriptMethodSelector(method); if (string.IsNullOrEmpty(selector) == false) { methodSymbol.SetSelector(selector); } if (MetadataHelpers.ShouldTreatAsConditionalMethod(method, out ICollection <string> conditions)) { methodSymbol.SetConditions(conditions); } typeSymbol.AddMember(methodSymbol); } }
private void BuildMembers(TypeSymbol typeSymbol) { if (typeSymbol.Type == SymbolType.Delegate) { DelegateTypeNode delegateNode = (DelegateTypeNode)typeSymbol.ParseContext; TypeSymbol returnType = typeSymbol.SymbolSet.ResolveType(delegateNode.ReturnType, _symbolTable, typeSymbol); Debug.Assert(returnType != null); if (returnType != null) { MethodSymbol invokeMethod = new MethodSymbol("Invoke", typeSymbol, returnType, MemberVisibility.Public); invokeMethod.SetTransformedName(String.Empty); // Mark the method as abstract, as there is no actual implementation of the method // to be generated invokeMethod.SetImplementationState(SymbolImplementationFlags.Abstract); typeSymbol.AddMember(invokeMethod); } return; } CustomTypeNode typeNode = (CustomTypeNode)typeSymbol.ParseContext; foreach (MemberNode member in typeNode.Members) { MemberSymbol memberSymbol = null; switch (member.NodeType) { case ParseNodeType.FieldDeclaration: case ParseNodeType.ConstFieldDeclaration: memberSymbol = BuildField((FieldDeclarationNode)member, typeSymbol); break; case ParseNodeType.PropertyDeclaration: memberSymbol = BuildPropertyAsField((PropertyDeclarationNode)member, typeSymbol); if (memberSymbol == null) { memberSymbol = BuildProperty((PropertyDeclarationNode)member, typeSymbol); } break; case ParseNodeType.IndexerDeclaration: memberSymbol = BuildIndexer((IndexerDeclarationNode)member, typeSymbol); break; case ParseNodeType.ConstructorDeclaration: case ParseNodeType.MethodDeclaration: if ((member.Modifiers & Modifiers.Extern) != 0) { // Extern methods are there for defining overload signatures, so // we just skip them as far as metadata goes. The validator has // taken care of the requirements/constraints around use of extern methods. continue; } memberSymbol = BuildMethod((MethodDeclarationNode)member, typeSymbol); break; case ParseNodeType.EventDeclaration: memberSymbol = BuildEvent((EventDeclarationNode)member, typeSymbol); break; case ParseNodeType.EnumerationFieldDeclaration: memberSymbol = BuildEnumField((EnumerationFieldNode)member, typeSymbol); break; } if (memberSymbol != null) { memberSymbol.SetParseContext(member); if ((typeSymbol.IsApplicationType == false) && ((memberSymbol.Type == SymbolType.Constructor) || (typeSymbol.GetMember(memberSymbol.Name) != null))) { // If the type is an imported type, then it is allowed to contain // overloads, and we're simply going to ignore its existence, as long // as one overload has been added to the member table. continue; } typeSymbol.AddMember(memberSymbol); if ((typeSymbol.Type == SymbolType.Class) && (memberSymbol.Type == SymbolType.Event)) { EventSymbol eventSymbol = (EventSymbol)memberSymbol; if (eventSymbol.DefaultImplementation) { // Add a private field that will serve as the backing member // later on in the conversion (eg. in non-event expressions) MemberVisibility visibility = MemberVisibility.PrivateInstance; if ((eventSymbol.Visibility & MemberVisibility.Static) != 0) { visibility |= MemberVisibility.Static; } FieldSymbol fieldSymbol = new FieldSymbol("__" + Utility.CreateCamelCaseName(eventSymbol.Name), typeSymbol, eventSymbol.AssociatedType); fieldSymbol.SetVisibility(visibility); fieldSymbol.SetParseContext(((EventDeclarationNode)eventSymbol.ParseContext).Field); typeSymbol.AddMember(fieldSymbol); } } } } }