示例#1
0
        private bool GetValue <T>(MessageContext ctxt, CCI.AttributeList attributes, CCI.TypeNode attrType, IProperty <T> property, ref T value)
        {
            var found = 0;

            foreach (var attribute in attributes)
            {
                if (IsAttribute(attribute, attrType))
                {
                    var thisValue = default(T);
                    if (GetValue(ctxt, attribute, attrType, property, ref thisValue))
                    {
                        if (found++ == 0)
                        {
                            value = thisValue;
                        }
                        else
                        {
                            if (!thisValue.Equals(value))
                            {
                                env.Log(new InvalidInteropMessage
                                            (RewriterMsgContext.AttributeProperty(ctxt, attribute, property.Name),
                                            "duplicate inconsistent bindings"));
                                throw new DefinitionException();
                            }
                        }
                    }
                }
            }
            return(found > 0);
        }
示例#2
0
        private void PopulateTypeNamesPositionsAndGlyphs()
        {
            Cci.TypeNodeList    types  = this.scTypeAndMemberDropdownBars.sortedDropDownTypes;
            Cci.AuthoringHelper helper = this.scTypeAndMemberDropdownBars.languageService.GetAuthoringHelper();
            int n = types == null ? 0 : types.Count;

            string[] typeNames    = new string[n];
            int[]    startColumns = new int[n];
            int[]    startLines   = new int[n];
            int[]    glyphs       = new int[n];
            for (int i = 0; i < n; i++)
            {
                Cci.TypeNode type = types[i];
                if (type == null || type.Name == null)
                {
                    Debug.Assert(false); continue;
                }
                typeNames[i]    = helper.GetFullTypeName(type);
                startColumns[i] = type.Name.SourceContext.StartColumn - 1;
                startLines[i]   = type.Name.SourceContext.StartLine - 1;
                glyphs[i]       = this.glyphProvider.GetGlyph(type);
            }
            this.dropDownTypeNames        = typeNames;
            this.dropDownTypeStartColumns = startColumns;
            this.dropDownTypeStartLines   = startLines;
            this.dropDownTypeGlyphs       = glyphs;
        }
示例#3
0
        public bool IsPrimitiveType(CCI.TypeNode type)
        {
            if (type.NodeType == CCI.NodeType.EnumNode)
            {
                return(true);
            }
            else
            {
                switch (type.TypeCode)
                {
                case TypeCode.String:
                case TypeCode.Char:
                case TypeCode.Double:
                case TypeCode.Single:
                case TypeCode.Decimal:
                case TypeCode.SByte:
                case TypeCode.Byte:
                case TypeCode.Int16:
                case TypeCode.UInt16:
                case TypeCode.Int32:
                case TypeCode.UInt32:
                case TypeCode.Int64:
                case TypeCode.UInt64:
                case TypeCode.Boolean:
                    return(true);

                default:
                    return(false);
                }
            }
        }
示例#4
0
        public T GetValue <T>(MessageContext ctxt, CCI.Node node, CCI.TypeNode attrType, IProperty <T> property, bool inheritable)
        {
            var res = default(T);

            if (!GetValue(ctxt, node, attrType, property, inheritable, ref res))
            {
                res = property.Default;
            }
            return(res);
        }
示例#5
0
 public bool HasAttribute(CCI.AttributeList attributes, CCI.TypeNode attrType)
 {
     foreach (var attr in attributes)
     {
         if (IsAttribute(attr, attrType))
         {
             return(true);
         }
     }
     return(false);
 }
示例#6
0
        public static MessageContext Type(MessageContext parent, CCI.TypeNode type)
        {
            var loc = default(Location);

            if (type.SourceContext.Document != null)
            {
                loc = type.SourceContext.ToLocation();
            }
            else if (type.Name != null && type.Name.SourceContext.Document != null)
            {
                loc = type.Name.SourceContext.ToLocation();
            }
            return(new MessageContext
                       (parent,
                       loc,
                       sb =>
            {
                sb.Append("Type ");
                sb.Append(type.FullName);
            }));
        }
示例#7
0
        public bool GetValue <T>(MessageContext ctxt, CCI.AttributeNode attribute, CCI.TypeNode attrType, IProperty <T> property, ref T value)
        {
            var expr = default(CCI.Literal);

            if (property.Position >= 0)
            {
                expr = attribute.GetPositionalArgument(property.Position) as CCI.Literal;
            }
            if (expr == null)
            {
                expr = attribute.GetNamedArgument(CCI.Identifier.For(property.Name)) as CCI.Literal;
            }
            if (expr != null)
            {
                value = property.Value(RewriterMsgContext.AttributeProperty(ctxt, attribute, property.Name), expr.Value);
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#8
0
 private void CheckTypeDefn(CCI.AssemblyNode expectedContainingAssembly, CCI.TypeNode typeDefn)
 {
     if (typeDefn.DeclaringModule == null || typeDefn.DeclaringModule.ContainingAssembly == null ||
         typeDefn.DeclaringModule.ContainingAssembly != expectedContainingAssembly || typeDefn.Name == null)
     {
         var refName     = expectedContainingAssembly.StrongName;
         var refInfo     = default(Info);
         var refFilename = "<unknown>";
         if (strongNameToInfo.TryGetValue(refName, out refInfo))
         {
             refFilename = refInfo.FileName;
         }
         env.Log(new UnresolvableReferenceMessage(refName, refFilename, "<unknown>"));
         throw new ExitException();
     }
     foreach (var member in typeDefn.Members)
     {
         var nestedTypeDefn = member as CCI.TypeNode;
         if (nestedTypeDefn != null)
         {
             CheckTypeDefn(expectedContainingAssembly, nestedTypeDefn);
         }
     }
 }
示例#9
0
        public bool GetValue <T>(MessageContext ctxt, CCI.Node node, CCI.TypeNode attrType, IProperty <T> property, bool inheritable, ref T value)
        {
            var assembly = node as CCI.AssemblyNode;

            if (assembly != null)
            {
                // Assembly has no parent
                return(GetValue
                           (RewriterMsgContext.Assembly(ctxt, assembly), assembly.Attributes, attrType, property, ref value));
            }

            var member = node as CCI.Member;

            if (member == null)
            {
                return(false);
            }

            if (GetValue(RewriterMsgContext.Member(ctxt, member), member.Attributes, attrType, property, ref value))
            {
                return(true);
            }

            if (inheritable)
            {
                var type = node as CCI.TypeNode;
                if (type != null)
                {
                    // Suppress inheritance for compiler-generated types, such as delegate environments
                    if (!HasAttribute(member.Attributes, env.CompilerGeneratedAttributeType))
                    {
                        if (type.DeclaringType != null)
                        {
                            // Parent of nested type is declaring type
                            return(GetValue
                                       (RewriterMsgContext.Type(ctxt, type),
                                       type.DeclaringType,
                                       attrType,
                                       property,
                                       true,
                                       ref value));
                        }
                        else
                        {
                            // Parent of type is assembly
                            return(GetValue
                                       (ctxt, type.DeclaringModule.ContainingAssembly, attrType, property, true, ref value));
                        }
                    }
                }

                var prop = node as CCI.Property;
                if (prop != null)
                {
                    // Parent of property is type
                    return(GetValue(ctxt, prop.DeclaringType, attrType, property, true, ref value));
                }

                var evnt = node as CCI.Event;
                if (evnt != null)
                {
                    // Parent of event is type
                    return(GetValue(ctxt, evnt.DeclaringType, attrType, property, true, ref value));
                }

                var method = node as CCI.Method;
                if (method != null)
                {
                    if (method.DeclaringMember != null)
                    {
                        // Parent of getter/setter/adder/remover is declaring member
                        return(GetValue(ctxt, method.DeclaringMember, attrType, property, true, ref value));
                    }
#if false
                    if (method.IsVirtual && method.OverriddenMethod != null)
                    {
                        var origDefn = method;
                        // Parent of virtual is virtual which introduced slot, unless it is from Object
                        do
                        {
                            origDefn = origDefn.OverriddenMethod;
                        }while (origDefn.IsVirtual && origDefn.OverriddenMethod != null);
                        if (origDefn.DeclaringType != env.ObjectType)
                        {
                            return(GetValue(ctxt, origDefn, attrType, property, true, ref value));
                        }
                    }
#endif
                    // Parent of ordinary method is type
                    return(GetValue(ctxt, method.DeclaringType, attrType, property, true, ref value));
                }
            }

            return(false);
        }
示例#10
0
        public bool HasAttribute(CCI.Node nodeDefn, CCI.TypeNode attrType, bool inheritable)
        {
            var assembly = nodeDefn as CCI.AssemblyNode;

            if (assembly != null)
            {
                // Assembly has no parent
                return(HasAttribute(assembly.Attributes, attrType));
            }

            var member = nodeDefn as CCI.Member;

            if (member == null)
            {
                return(false);
            }

            if (HasAttribute(member.Attributes, attrType))
            {
                return(true);
            }

            if (inheritable)
            {
                var typeDefn = nodeDefn as CCI.TypeNode;
                if (typeDefn != null)
                {
                    // Suppress inheritance for compiler-generated types, such as delegate environments
                    if (!HasAttribute(member.Attributes, env.CompilerGeneratedAttributeType))
                    {
                        if (typeDefn.DeclaringType != null)
                        {
                            // Parent of nested type is outer type
                            return(HasAttribute(typeDefn.DeclaringType, attrType, true));
                        }
                        else
                        {
                            // Parent of type is assembly
                            return(HasAttribute(typeDefn.DeclaringModule, attrType, true));
                        }
                    }
                }

                var propDefn = nodeDefn as CCI.Property;
                if (propDefn != null)
                {
                    // Parent of property is type
                    return(HasAttribute(propDefn.DeclaringType, attrType, true));
                }

                var evntDefn = nodeDefn as CCI.Event;
                if (evntDefn != null)
                {
                    // Parent of event is type
                    return(HasAttribute(evntDefn.DeclaringType, attrType, true));
                }

                var methodDefn = nodeDefn as CCI.Method;
                if (methodDefn != null)
                {
                    if (methodDefn.DeclaringMember != null)
                    {
                        // Parent of getter/setter/adder/remover is property/event
                        return(HasAttribute(methodDefn.DeclaringMember, attrType, true));
                    }

#if false
                    if (methodDefn.IsVirtual && methodDefn.OverriddenMethod != null)
                    {
                        var origDefn = methodDefn;
                        // Overridding methods have two parents: the virtual which introduced slot, and declaring type
                        do
                        {
                            origDefn = origDefn.OverriddenMethod;
                        }while (origDefn.IsVirtual && origDefn.OverriddenMethod != null);
                        if (origDefn.DeclaringType != env.ObjectType && HasAttribute(origDefn, attrType, true))
                        {
                            return(true);
                        }
                    }
#endif

                    // Parent of ordinary method is type
                    return(HasAttribute(methodDefn.DeclaringType, attrType, true));
                }
            }

            return(false);
        }
示例#11
0
        // ----------------------------------------------------------------------
        // Finding attributes and properties
        // ----------------------------------------------------------------------

        public bool IsAttribute(CCI.AttributeNode attr, CCI.TypeNode attrType)
        {
            return(attr.Type.IsAssignableTo(attrType));
        }
示例#12
0
        // ----------------------------------------------------------------------
        // Framework type helpers
        // ----------------------------------------------------------------------

        public bool IsNullableType(CCI.TypeNode type)
        {
            return(type.Template != null && type.TemplateArguments != null && type.TemplateArguments.Count == 1 &&
                   type.Template == env.NullableTypeConstructor);
        }
示例#13
0
 public T GetValue <T>(MessageContext ctxt, CCI.Node node, CCI.TypeNode attrType, IProperty <T> property)
 {
     return(GetValue <T>(ctxt, node, attrType, property, true));
 }
示例#14
0
 public static MessageContext Type(CCI.TypeNode type)
 {
     return(Type(null, type));
 }
示例#15
0
        public Global Load()
        {
            if (global != null)
                throw new InvalidOperationException("CCILoader::Load() should be invoked only once");
            
            var strongNameToInfo = new Dictionary<StrongAssemblyName, AssemblyInfo>();
            var fileNameToStrongName = new Dictionary<string, StrongAssemblyName>();
            // Entry for (referencor strong name, referencee strong name) for references know to be unresolvable
            var knownBad = new HashSet<string>();

            // ----------------------------------------
            // The assembly resolver invoked by CCI as needed
            // ----------------------------------------
            CCI.Module.AssemblyReferenceResolver resolver =
               (target, source) =>
               {
                   var targetinfo = default(AssemblyInfo);
                   var targetsn = StrongAssemblyNameFromCCIReference(target);
                   if (strongNameToInfo.TryGetValue(targetsn, out targetinfo))
                       return targetinfo.Assembly;
                   else
                   {
                       var sourceInfo = default(AssemblyInfo);
                       var sourceFileName = "<unknown>";
                       var sourcesn = StrongAssemblyNameFromCCIAssembly(source.ContainingAssembly);
                       if (strongNameToInfo.TryGetValue(sourcesn, out sourceInfo))
                           sourceFileName = sourceInfo.FileName;
                       var key = "(" + sourcesn + "," + targetsn + ")";
                       if (!knownBad.Contains(key))
                       {
                           knownBad.Add(key);
                           log
                               (new UnresolvableReferenceMessage
                                    (source.ContainingAssembly.StrongName, sourceFileName, target.StrongName));
                       }
                       throw new ExitException();
                       // turns out CCI will happily swallow this exception and replay it later...
                   }
               };

            // ----------------------------------------
            // Which assembly should we use for mscorlib?
            // ----------------------------------------
            var mscorlibCanonicalName = default(string);
            foreach (var fileName in fileNames)
            {
                var canonicalFileName = CanonicalFileName(fileName);
                if (fileNameToStrongName.ContainsKey(canonicalFileName))
                {
                    log(new DuplicateAssemblyFileNameMessage(fileName, canonicalFileName));
                    throw new ExitException();
                }
                fileNameToStrongName.Add(canonicalFileName, null);
                var baseName = Path.GetFileNameWithoutExtension(canonicalFileName);
                if (baseName.Equals("mscorlib", StringComparison.OrdinalIgnoreCase))
                {
                    if (mscorlibCanonicalName != null)
                    {
                        log(new DuplicateSpecialAssemblyMessage("mscorlib", mscorlibCanonicalName, canonicalFileName));
                        throw new ExitException();
                    }
                    mscorlibCanonicalName = canonicalFileName;
                }
            }
            if (mscorlibCanonicalName == null)
            {
                log(new MissingSpecialAssemblyMessage("mscorlib"));
                throw new ExitException();
            }

            // ----------------------------------------
            // Initialize CCI, which will implicitly load mscorlib
            // ----------------------------------------
            var frameworkDir = Path.GetDirectoryName(mscorlibCanonicalName);
            if (!Directory.Exists(frameworkDir))
            {
                log(new UnloadableMSCorLibMessage(frameworkDir));
                throw new ExitException();
            }

            // These special CCI assemblies, and mscorlib, will be picked up from the framework directory
            CCI.SystemDataAssemblyLocation.Location = null;
            CCI.SystemXmlAssemblyLocation.Location = null;

            CCI.TargetPlatform.SetToV2(frameworkDir);

            // At this point we could "fixup" CCI's hard-wired system assembly references:
            //
            //     foreach (var asmRefs in CCI.TargetPlatform.AssemblyReferenceFor.GetEnumerator())
            //     {
            //         var asmRef = (CCI.AssemblyReference)asmRefs.Value;
            //         asmRef.Location = <the right place>;
            //     }
            //     SystemAssemblyLocation.Location = <the right place>;
            //     SystemXmlAssemblyLocation.Location = <the right place>;
            // 
            // But so far that doesn't seem necessary

            CCI.SystemTypes.Initialize(false, true, resolver);

            // ----------------------------------------
            // Account for mscorlib being loaded
            // ----------------------------------------
            var mscorlib = CCI.SystemTypes.SystemAssembly;
            if (mscorlib == null || mscorlib.Directory == null)
            {
                log(new UnloadableMSCorLibMessage(frameworkDir));
                throw new ExitException();
            }

            var mscorlibName = StrongAssemblyNameFromCCIAssembly(mscorlib);
            fileNameToStrongName[mscorlibCanonicalName] = mscorlibName;
            strongNameToInfo.Add(mscorlibName, new AssemblyInfo { Assembly = mscorlib, FileName = mscorlibCanonicalName });
            log(new LoadedAssemblyMessage(mscorlib.StrongName, mscorlibCanonicalName));


            Void = ResolveCCIType(mscorlib, "System", "Void");
            ValueType = ResolveCCIType(mscorlib, "System", "ValueType");
            Enum = ResolveCCIType(mscorlib, "System", "Enum");

            global = new Global(mscorlibName);

            // The global environment is now ready for use...

            // ----------------------------------------
            // Load the remaining registered assemblies
            // ----------------------------------------
            var pending = new List<string>();
            foreach (var kv in fileNameToStrongName)
            {
                if (kv.Value == null)
                    pending.Add(kv.Key);
                // else: must have been mscorlib, which we loaded above
            }
            foreach (var canonicalFileName in pending)
            {
                var assembly = CCI.AssemblyNode.GetAssembly(canonicalFileName, null, false, true, true);
                if (assembly == null)
                {
                    log(new UnloadableAssemblyMessage(canonicalFileName));
                    throw new ExitException();
                }
                var sn = StrongAssemblyNameFromCCIAssembly(assembly);
                var info = default(AssemblyInfo);
                if (strongNameToInfo.TryGetValue(sn, out info))
                {
                    log(new DuplicateAssemblyStrongNameMessage(canonicalFileName, sn.ToString(), info.FileName));
                    throw new ExitException();
                }
                log(new LoadedAssemblyMessage(sn.ToString(), canonicalFileName));
                fileNameToStrongName[canonicalFileName] = sn;
                strongNameToInfo.Add(sn, new AssemblyInfo { Assembly = assembly, FileName = canonicalFileName });
                assembly.AssemblyReferenceResolution += resolver;
            }

            // ----------------------------------------
            // Convert all assemblies. Since we visit all assemblies and types this will also check that
            // all assembly references resolved to valid assemblies.
            // ----------------------------------------

            // We use the global environment for the first time here...

            var assemblies = new List<AssemblyDef>();
            foreach (var kv in strongNameToInfo)
            {
                try
                {
                    assemblies.Add(AssemblyDefFromCCIAssembly(kv.Value.Assembly));
                    log(new ResolvedAssemblyMessage(kv.Key.ToString(), kv.Value.FileName));
                }
                catch (InvalidOperationException)
                {
                    log(new UnresolvableAssemblyMessage(kv.Key.ToString(), kv.Value.FileName));
                    throw new ExitException();
                }
            }

            global.AddAssemblies(assemblies);

            // ----------------------------------------
            // Teardown CCI
            // ----------------------------------------

            cciQualifiedTypeNameCache.Clear();
            foreach (var kv in strongNameToInfo)
                kv.Value.Assembly.Dispose();
            strongNameToInfo.Clear();
            CCI.TargetPlatform.Clear();

            return global;
        }