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; } MethodSymbol methodSymbol = new MethodSymbol(methodName, typeSymbol, returnType); 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(); } if ((methodSymbol.Visibility & MemberVisibility.Static) != 0) { string alias = MetadataHelpers.GetScriptAlias(method); if (String.IsNullOrEmpty(alias) == false) { methodSymbol.SetAlias(alias); } } ICollection<string> conditions; if (MetadataHelpers.ShouldTreatAsConditionalMethod(method, out 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); } } } } }
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); } }