예제 #1
0
        // NOTE: May be called on invalid definitions
        public bool IsImported(CST.AssemblyDef assemblyDef, CST.TypeDef typeDef, CST.MethodDef methodDef)
        {
            var ctxt = CST.MessageContextBuilders.Member(env.Global, assemblyDef, typeDef, methodDef);

            var outerDef = typeDef.OuterPropertyOrEvent(methodDef.MethodSignature);
            if (outerDef != null)
            {
                switch (outerDef.Flavor)
                {
                case CST.MemberDefFlavor.Event:
                    {
                        var eventDef = (CST.EventDef)outerDef;
                        if (eventDef.Add != null && eventDef.Remove != null)
                        {
                            var n = 0;
                            if (attributeHelper.MethodHasAttribute
                                (assemblyDef,
                                 typeDef,
                                 typeDef.ResolveMethod(eventDef.Add),
                                 attributeHelper.ImportAttributeRef,
                                 false,
                                 false))
                                n++;
                            if (attributeHelper.MethodHasAttribute
                                (assemblyDef,
                                 typeDef,
                                 typeDef.ResolveMethod(eventDef.Remove),
                                 attributeHelper.ImportAttributeRef,
                                 false,
                                 false))
                                n++;
                            if (n == 1)
                            {
                                env.Log
                                    (new InvalidInteropMessage
                                         (ctxt, "events with adders and removers must be imported simultaneously"));
                                throw new DefinitionException();
                            }
                        }
                        break;
                    }
                case CST.MemberDefFlavor.Property:
                    {
                        var propDef = (CST.PropertyDef)outerDef;
                        if (propDef.Get != null && propDef.Set != null)
                        {
                            var n = 0;
                            if (attributeHelper.MethodHasAttribute
                                (assemblyDef,
                                 typeDef,
                                 typeDef.ResolveMethod(propDef.Get),
                                 attributeHelper.ImportAttributeRef,
                                 false,
                                 false))
                                n++;
                            if (attributeHelper.MethodHasAttribute
                                (assemblyDef,
                                 typeDef,
                                 typeDef.ResolveMethod(propDef.Set),
                                 attributeHelper.ImportAttributeRef,
                                 false,
                                 false))
                                n++;
                            if (n == 1)
                            {
                                env.Log
                                    (new InvalidInteropMessage
                                         (ctxt, "properties with getters and setters must be imported simultaneously"));
                                throw new DefinitionException();
                            }
                        }
                        break;
                    }
                case CST.MemberDefFlavor.Field:
                case CST.MemberDefFlavor.Method:
                    throw new InvalidOperationException("not a property or event");
                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            if (IsExtern(assemblyDef, typeDef, methodDef))
            {
                if (attributeHelper.MethodHasAttribute
                    (assemblyDef, typeDef, methodDef, attributeHelper.ImportAttributeRef, true, false))
                {
                    if (attributeHelper.MethodHasAttribute
                        (assemblyDef, typeDef, methodDef, env.Global.DllImportAttributeRef, false, false))
                    {
                        env.Log(new InvalidInteropMessage(ctxt, "cannot mix 'Import' and 'DllImport' attributes"));
                        throw new DefinitionException();
                    }
                    return true;
                }
                else
                    return false;
            }
            else
            {
                if (attributeHelper.MethodHasAttribute
                    (assemblyDef, typeDef, methodDef, attributeHelper.ImportAttributeRef, false, false))
                {
                    if (outerDef == null)
                    {
                        env.Log
                            (new InvalidInteropMessage
                                 (ctxt, "cannot Import a method which already has an implementation"));
                        throw new DefinitionException();
                    }
                    // else: C# doesn't allow extern properties, so be forgiving here
                    return true;
                }
                return false;
            }
        }