예제 #1
0
파일: SymbolNamer.cs 프로젝트: exyi/coberec
        static string NameMember(ITypeDefinition type, Dictionary <MemberSignature, string> names, string desiredName, bool?lowerCase, IEnumerable <string> blacklist = null)
        {
            desiredName = NameSanitizer.SanitizeMemberName(desiredName, lowerCase);

            var existingNames = new HashSet <string>(type.GetMembers(m => m.DeclaringTypeDefinition == type || m.IsVirtual).Select(m => m.Name));

            existingNames.UnionWith(type.NestedTypes.Select(t => t.Name));
            existingNames.UnionWith(names.Values);
            existingNames.UnionWith(blacklist ?? Enumerable.Empty <string>());
            for (IType p = type; p != null; p = p.DeclaringType)
            {
                existingNames.Add(p.Name);
            }

            if (!existingNames.Contains(desiredName))
            {
                return(desiredName);
            }
            for (int i = 2; true; i++)
            {
                if (!existingNames.Contains(desiredName + i))
                {
                    return(desiredName + i);
                }
            }
        }
예제 #2
0
파일: SymbolNamer.cs 프로젝트: exyi/coberec
        static string NameMethod(ITypeDefinition type, Dictionary <MemberSignature, string> names, string desiredName, int typeArgCount, TypeReference[] signature, bool isOverride, bool?lowerCase = false)
        {
            desiredName = NameSanitizer.SanitizeMemberName(desiredName, lowerCase);

            var existingNonmethods = new HashSet <string>(type.GetMembers(m => m.SymbolKind != SymbolKind.Method && (m.DeclaringTypeDefinition == type || m.IsVirtual)).Select(m => m.Name));

            for (IType p = type; p != null; p = p.DeclaringType)
            {
                existingNonmethods.Add(p.Name);
            }
            existingNonmethods.UnionWith(names.Where(n => !(n.Key is MethodSignature)).Select(n => n.Value));

            var existingMethods =
                type
                .GetMembers(m => m.SymbolKind == SymbolKind.Method && (m.DeclaringTypeDefinition == type || m.IsVirtual && !isOverride))
                .Cast <IMethod>()
                .Select(SymbolLoader.Method)
                .Concat(names.Where(m => m.Key is MethodSignature).Select(m => ((MethodSignature)m.Key).With(name: m.Value)))
                .ToLookup(m => m.Name);

            bool collides(string n)
            {
                if (existingNonmethods.Contains(n))
                {
                    return(true);
                }
                if (!existingMethods.Contains(n))
                {
                    return(false);
                }
                var methods = existingMethods[n];

                return(methods.Any(m => m.TypeParameters.Length == typeArgCount && m.Params.Length == signature.Length && m.Params.Select(p => p.Type).SequenceEqual(signature)));
            }

            if (!collides(desiredName))
            {
                return(desiredName);
            }
            for (int i = 2; true; i++)
            {
                if (!collides(desiredName + i))
                {
                    return(desiredName + i);
                }
            }
        }
예제 #3
0
파일: SymbolNamer.cs 프로젝트: exyi/coberec
        public static IParameter[] NameParameters(IEnumerable <IParameter> parameters)
        {
            // Except for sanitization and lowercasing, I'm not aware of any restrictions

            var usedNames = new HashSet <string>();

            return(parameters.Select(p => {
                var name = NameSanitizer.SanitizeCsharpName(p.Name, lowerCase: true);
                string name2 = name;
                int i = 2;
                while (!usedNames.Add(name2))
                {
                    name2 = name + (i++);
                }
                return (IParameter) new VirtualParameter(p.Type, name2, p.Owner, p.GetAttributes().ToArray(), p.ReferenceKind, p.IsRef, p.IsOut, p.IsIn, p.IsParams, p.IsOptional, p.GetConstantValue());
            }).ToArray());
        }
예제 #4
0
        public ITypeParameter Register(GenericParameter parameter, IEntity owner, int index)
        {
            if (store.TryGetValue(parameter.Id, out var existingP))
            {
                if (!existingP.Owner.Equals(owner))
                {
                    throw new Exception($"There is collision in the usage of generic parameter {parameter}: both {existingP.Owner} and {owner} use it.");
                }
                if (existingP.Index != index)
                {
                    throw new Exception($"There is collision in the usage of generic parameter {parameter} on {existingP.Owner}. It is used at index {existingP.Index} and {index}.");
                }
                return(existingP);
            }

            var newP = new DefaultTypeParameter(owner, index, name: NameSanitizer.SanitizeCsharpName(parameter.Name, lowerCase: null));

            SymbolLoader.RegisterTypeParameter(newP, parameter);
            store.TryAdd(parameter.Id, newP);
            return(Register(parameter, owner, index));
        }
예제 #5
0
파일: SymbolNamer.cs 프로젝트: exyi/coberec
        public static string NameType(string @namespace, string desiredName, int genericArgCount, ICompilation compilation, IEnumerable <string> blacklist = null)
        {
            desiredName = NameSanitizer.SanitizeTypeName(desiredName);
            var ns = compilation.RootNamespace.FindDescendantNamespace(@namespace);

            var existingNames =
                ns == null ? new HashSet <string>() :
                new HashSet <string>(ns.Types.Where(t => t.TypeArguments.Count == genericArgCount).Select(t => t.Name).Concat(ns.ChildNamespaces.Select(t => t.Name)), StringComparer.InvariantCultureIgnoreCase);

            existingNames.UnionWith(blacklist ?? Enumerable.Empty <string>());

            if (!existingNames.Contains(desiredName))
            {
                return(desiredName);
            }
            for (int i = 2; true; i++)
            {
                if (!existingNames.Contains(desiredName + i))
                {
                    return(desiredName + i);
                }
            }
        }