Exemplo n.º 1
0
        /// <summary>
        /// Returns a value indicating whether a method named <paramref name="methodName"/>
        /// exposed by the <see cref="Type"/> specified by <paramref name="typeName"/>
        /// from the reference project is also visible to the dependent project.
        /// </summary>
        /// <param name="typeName">The full name of the <see cref="Type"/> from the reference project.</param>
        /// <param name="methodName">The name of the method.</param>
        /// <param name="parameterTypeNames">The full type names of the method parameters, in the order they must be declared.</param>
        /// <returns>The <see cref="CodeMemberShareKind"/> representing whether it is shared and in what way.</returns>
        public CodeMemberShareKind GetMethodShareKind(string typeName, string methodName, IEnumerable <string> parameterTypeNames)
        {
            CodeMemberKey         key         = CodeMemberKey.CreateMethodKey(typeName, methodName, parameterTypeNames == null ? null : parameterTypeNames.ToArray());
            SharedCodeDescription description = this.GetSharedCodeDescription(key);

            return(description.ShareKind);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Returns a value indicating whether the a property named <paramref name="propertyName"/>
        /// exposed by the <see cref="Type"/> specified by <paramref name="typeName"/>
        /// from the reference project is also visible to the dependent project.
        /// </summary>
        /// <param name="typeName">The full name of the <see cref="Type"/> from the reference project.</param>
        /// <param name="propertyName">The name of the property.</param>
        /// <returns>The <see cref="CodeMemberShareKind"/> representing whether it is shared and in what way.</returns>
        public CodeMemberShareKind GetPropertyShareKind(string typeName, string propertyName)
        {
            CodeMemberKey         key         = CodeMemberKey.CreatePropertyKey(typeName, propertyName);
            SharedCodeDescription description = this.GetSharedCodeDescription(key);

            return(description.ShareKind);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns a value indicating whether the <see cref="Type"/>specified by <paramref name="typeName"/>
        /// from the reference project is also visible to the dependent project.
        /// </summary>
        /// <param name="typeName">The full name of the <see cref="Type"/>from the reference project.</param>
        /// <returns>The <see cref="CodeMemberShareKind"/> representing whether it is shared and in what way.</returns>
        public CodeMemberShareKind GetTypeShareKind(string typeName)
        {
            CodeMemberKey         key         = CodeMemberKey.CreateTypeKey(typeName);
            SharedCodeDescription description = this.GetSharedCodeDescription(key);

            return(description.ShareKind);
        }
Exemplo n.º 4
0
        /// <summary>
        /// Returns the <see cref="MethodBase"/> of the method or constructor from the
        /// set of shared assemblies, if it exists.
        /// </summary>
        /// <param name="typeName">The fully qualified type name declaring the method.</param>
        /// <param name="methodName">The name of the method</param>
        /// <param name="parameterTypeNames">The fully qualified type names of the method parameters.</param>
        /// <returns>The <see cref="MethodBase"/> if it exists in the shared assemblies, otherwise <c>null</c></returns>
        internal MethodBase GetSharedMethod(string typeName, string methodName, IEnumerable <string> parameterTypeNames)
        {
            Debug.Assert(!string.IsNullOrEmpty(typeName), "typeName cannot be null");
            Debug.Assert(!string.IsNullOrEmpty(methodName), "methodName cannot be null");

            MethodBase sharedMethod = null;
            Type       sharedType   = this.GetSharedType(typeName);

            if (sharedType != null)
            {
                CodeMemberKey key = CodeMemberKey.CreateMethodKey(typeName, methodName, parameterTypeNames == null ? new string[0] : parameterTypeNames.ToArray());
                sharedMethod = this.FindSharedMethodOrConstructor(sharedType, key);
            }

            return(sharedMethod);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Gets the <see cref="SharedCodeDescription"/> for the code member described by <paramref name="key"/>.
        /// </summary>
        /// <param name="key">Describes the code member.</param>
        /// <returns>The <see cref="SharedCodeDescription"/> or <c>null</c>.</returns>
        internal SharedCodeDescription GetSharedCodeDescription(CodeMemberKey key)
        {
            return(this._cachedDescriptions.GetOrAdd(key, k =>
            {
                string sharedAssemblyLocation = this.SharedAssemblies.GetSharedAssemblyPath(key);
                if (sharedAssemblyLocation != null)
                {
                    return new SharedCodeDescription(CodeMemberShareKind.SharedByReference, new[] { this._filenameMap.AddOrGet(sharedAssemblyLocation) });
                }

                int[] fileIds = this.SharedSourceFiles.GetSharedFileIds(key);
                if (fileIds != null && fileIds.Length != 0)
                {
                    return new SharedCodeDescription(CodeMemberShareKind.SharedBySource, fileIds);
                }

                return new SharedCodeDescription(CodeMemberShareKind.NotShared, null);
            }));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Returns the location of the shared assembly containing the
        /// code member described by <paramref name="key"/>.
        /// </summary>
        /// <param name="key">The description of the code element.</param>
        /// <returns>The location of the assembly that contains it or <c>null</c> if it is not in a shared assembly.</returns>
        internal string GetSharedAssemblyPath(CodeMemberKey key)
        {
            Debug.Assert(key != null, "key cannot be null");
            string location = null;

            Type type = this.GetSharedType(key.TypeName);

            if (type != null)
            {
                switch (key.KeyKind)
                {
                case CodeMemberKey.CodeMemberKeyKind.TypeKey:
                    location = type.Assembly.Location;
                    break;

                case CodeMemberKey.CodeMemberKeyKind.PropertyKey:
                    PropertyInfo propertyInfo = type.GetProperty(key.MemberName);
                    if (propertyInfo != null)
                    {
                        location = propertyInfo.DeclaringType.Assembly.Location;
                    }
                    break;

                case CodeMemberKey.CodeMemberKeyKind.MethodKey:
                    Type[] parameterTypes = this.GetSharedTypes(key.ParameterTypeNames);
                    if (parameterTypes != null)
                    {
                        MethodBase methodBase = this.FindSharedMethodOrConstructor(type, key);
                        if (methodBase != null)
                        {
                            location = methodBase.DeclaringType.Assembly.Location;
                        }
                    }
                    break;

                default:
                    Debug.Fail("unsupported key kind");
                    break;
                }
            }
            return(location);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Locates the <see cref="MethodBase"/> in the set of shared assemblies that
        /// corresponds to the method described by <paramref name="key"/>.
        /// </summary>
        /// <param name="sharedType">The <see cref="Type"/> we have already located in our set of shared assemblies.</param>
        /// <param name="key">The key describing the method to find.</param>
        /// <returns>The matching <see cref="MethodBase"/> or <c>null</c> if no match is found.</returns>
        private MethodBase FindSharedMethodOrConstructor(Type sharedType, CodeMemberKey key)
        {
            Type[] parameterTypes = this.GetSharedTypes(key.ParameterTypeNames);
            if (parameterTypes == null)
            {
                return(null);
            }
            bool isConstructor = key.IsConstructor;
            IEnumerable <MethodBase> methods = isConstructor ? sharedType.GetConstructors().Cast <MethodBase>() : sharedType.GetMethods().Cast <MethodBase>();

            foreach (MethodBase method in methods)
            {
                if (!isConstructor && !string.Equals(method.Name, key.MemberName, StringComparison.OrdinalIgnoreCase))
                {
                    continue;
                }
                ParameterInfo[] parameterInfos = method.GetParameters();
                if (parameterInfos.Length != parameterTypes.Length)
                {
                    continue;
                }
                int matchedParameters = 0;
                for (int i = 0; i < parameterInfos.Length; ++i)
                {
                    if (string.Equals(parameterInfos[i].ParameterType.FullName, parameterTypes[i].FullName, StringComparison.OrdinalIgnoreCase))
                    {
                        ++matchedParameters;
                    }
                    else
                    {
                        break;
                    }
                }

                if (matchedParameters == parameterInfos.Length)
                {
                    return(method);
                }
            }
            return(null);
        }
Exemplo n.º 8
0
        /// <summary>
        /// Override to provide property equality checks using value-based comparison.
        /// </summary>
        /// <param name="obj">The object to compare against the current instance.</param>
        /// <returns><c>true</c> if the objects are equal.</returns>
        public override bool Equals(object obj)
        {
            CodeMemberKey other = obj as CodeMemberKey;

            if (Object.ReferenceEquals(other, null))
            {
                return(false);
            }
            if (Object.ReferenceEquals(this, other))
            {
                return(true);
            }
            if ((this.KeyKind != other.KeyKind) ||
                !string.Equals(this.TypeName, other.TypeName, StringComparison.Ordinal) ||
                !string.Equals(this.MemberName, other.MemberName, StringComparison.Ordinal))
            {
                return(false);
            }
            int parameterCount      = this.ParameterTypeNames == null ? 0 : this.ParameterTypeNames.Length;
            int otherParameterCount = other.ParameterTypeNames == null ? 0 : other.ParameterTypeNames.Length;

            if (parameterCount != otherParameterCount)
            {
                return(false);
            }

            for (int i = 0; i < parameterCount; ++i)
            {
                if (!string.Equals(this.ParameterTypeNames[i], other.ParameterTypeNames[i], StringComparison.Ordinal))
                {
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 9
0
 /// <summary>
 /// Creates a new instance of the <see cref="CodeMemberKey"/> class that describes
 /// a property.
 /// </summary>
 /// <param name="propertyInfo">The <see cref="PropertyInfo"/> of that property.</param>
 /// <returns>A new instance which describes that property.</returns>
 public static CodeMemberKey CreatePropertyKey(PropertyInfo propertyInfo)
 {
     Debug.Assert(propertyInfo != null, "propertyInfo cannot be null");
     return(CodeMemberKey.CreatePropertyKey(propertyInfo.DeclaringType.AssemblyQualifiedName, propertyInfo.Name));
 }
Exemplo n.º 10
0
 /// <summary>
 /// Creates a new instance of the <see cref="CodeMemberKey"/> class
 /// to describe the a <see cref="Type"/> from the given <paramref name="type"/>.
 /// </summary>
 /// <param name="type">The <see cref="Type"/> from which to construct the key.</param>
 /// <returns>A new instance which describes that type.</returns>
 public static CodeMemberKey CreateTypeKey(Type type)
 {
     Debug.Assert(type != null, "type cannot be null");
     return(CodeMemberKey.CreateTypeKey(type.AssemblyQualifiedName));
 }
Exemplo n.º 11
0
 /// <summary>
 /// Creates a new instance of the <see cref="CodeMemberKey"/> class that describes
 /// a method or a constructor.
 /// </summary>
 /// <param name="methodBase">The <see cref="MethodBase"/> of the method or constructor.</param>
 /// <returns>A new instance that describes that method.</returns>
 public static CodeMemberKey CreateMethodKey(MethodBase methodBase)
 {
     Debug.Assert(methodBase != null, "methodBase cannot be null");
     string[] parameterTypes = methodBase.GetParameters().Select <ParameterInfo, string>(p => p.ParameterType.AssemblyQualifiedName).ToArray();
     return(CodeMemberKey.CreateMethodKey(methodBase.DeclaringType.AssemblyQualifiedName, methodBase.Name, parameterTypes));
 }
Exemplo n.º 12
0
        /// <summary>
        /// Gets the collection of internal ID's of the files that collectively
        /// define the code member described by <paramref name="key"/>.
        /// </summary>
        /// <param name="key">The key describing the code member.</param>
        /// <returns>The collection of internal ID's, or <c>null</c> if no shared files exist for this code element.</returns>
        internal int[] GetSharedFileIds(CodeMemberKey key)
        {
            Debug.Assert(key != null, "key cannot be null");

            // Early exit if no shared files were specified
            if (!this._anySharedFiles)
            {
                return(null);
            }

            Type type = key.Type;

            // If we don't have the type in this AppDomain, then we don't consider it shared.
            // For the sake of performance, System types are never considered
            // shared from the perspective of source files.   This optimization
            // skips attempts to open PDB's or reflect into system types.
            // We don't even add an entry in the cache for these.
            if (type == null || type.Assembly.IsSystemAssembly())
            {
                return(null);
            }

            int[] fileIds = null;

            switch (key.KeyKind)
            {
            case CodeMemberKey.CodeMemberKeyKind.TypeKey:
                IEnumerable <string> files = this.SourceFileLocationService.GetFilesForType(type);
                if (files != null && files.Any())
                {
                    IEnumerable <int> filesAsIds    = files.Select <string, int>(s => this.FileNameToSharedID(s)).Distinct();
                    int[]             sharedFileIds = filesAsIds.Where(i => i != SharedSourceFiles.NotShared).ToArray();
                    fileIds = sharedFileIds.Length == 0 ? null : sharedFileIds;
                }

                break;

            case CodeMemberKey.CodeMemberKeyKind.PropertyKey:
                PropertyInfo propertyInfo = key.PropertyInfo;
                if (propertyInfo == null)
                {
                    return(null);
                }
                string propertyFile         = this.SourceFileLocationService.GetFileForMember(propertyInfo);
                int    sharedPropertyFileId = this.FileNameToSharedID(propertyFile);
                if (sharedPropertyFileId != SharedSourceFiles.NotShared)
                {
                    fileIds = new int[] { sharedPropertyFileId };
                }

                break;

            case CodeMemberKey.CodeMemberKeyKind.MethodKey:
                MethodBase methodBase = key.MethodBase;
                if (methodBase == null)
                {
                    return(null);
                }
                string methodFile         = this.SourceFileLocationService.GetFileForMember(methodBase);
                int    sharedMethodFileId = this.FileNameToSharedID(methodFile);
                if (sharedMethodFileId != SharedSourceFiles.NotShared)
                {
                    fileIds = new int[] { sharedMethodFileId };
                }
                break;

            default:
                Debug.Fail("unsupported key kind");
                break;
            }
            return(fileIds);
        }