예제 #1
0
 /// <summary>
 /// Merge another object representing a dependency into this object.
 /// </summary>
 /// <param name="config">Object to merge in.</param>
 private void Merge(ConfigObjC config)
 {
     foreach (string name in config.TypeNameSkipList)
     {
         if (!TypeNameSkipList.Contains(name))
         {
             TypeNameSkipList.Add(name);
         }
     }
     foreach (string name in config.TypeNameWhiteList)
     {
         if (!TypeNameWhiteList.Contains(name))
         {
             TypeNameWhiteList.Add(name);
         }
     }
 }
예제 #2
0
        /**
         * Returns true if should generate binding for type
         *
         * Use the skip and white lists to control binding generation for individual types.
         * If a type is skipped then no binding will occur for any code element
         * ie: class, property, method, parameter etc that uses the skipped type.
         *
         * For simple binding scenarios type skipping will likely not be required but for more
         * complex situations it can greatly reduce the size and complexity of the generated bindings.
         */
        public bool GenerateTypeBinding(string typename)
        {
            bool isSkipListed  = false;
            bool isWhiteListed = true;

            // a type name will be delimited either by the end of the string
            // or by the occurence of any of the type name delimiter characters
            string typeNameDelimiters = ",<>[]& ";

            // is the type to be skipped?
            // we potentially skip if a matching typename occurs anywhere in the type signature, including as a generic type parameter.
            isSkipListed = TypeNameSkipList.Any(e => typename.IndexOf(e) != -1);

            // if type is not skip listed then use default whitelist state
            if (!isSkipListed)
            {
                return(isWhiteListed);
            }

            // check for whitelist override.
            isWhiteListed = false;

            StringBuilder sbTypeName = new StringBuilder(typename);

            foreach (var whiteTypeName in TypeNameWhiteList)
            {
                // replace each instance of white listed type with ?...
                int idx = 0;

                // note that some types, esp generics, may have the same type name repeated multiple times
                // so we need to scan the entire type name
                while (idx < sbTypeName.Length)
                {
                    // look for any match
                    idx = sbTypeName.ToString().IndexOf(whiteTypeName, idx);
                    if (idx == -1)
                    {
                        break;
                    }

                    // we have a match but it may be a partial one:
                    // e.g. System.Threading.Tasks.Task will match System.Threading.Tasks.TaskFactory
                    // so we try and determine if our match is a full one.
                    int idxEnd = idx + whiteTypeName.Length - 1;
                    if (idxEnd + 1 < sbTypeName.Length)
                    {
                        // we can test the next character to see if indicates that the matched type
                        // is part of a constructed type.
                        string cursor = sbTypeName[idxEnd + 1].ToString();

                        // we need to match nested types in order to support
                        // generic type definitions
                        // e.g. System.Nullable`1<System.Nullable+T>
                        if (cursor == "+")
                        {
                            // advance the end index to before next type delimiter
                            idxEnd++;
                            while (idxEnd + 1 < sbTypeName.Length)
                            {
                                cursor = sbTypeName[idxEnd + 1].ToString();
                                if (typeNameDelimiters.Contains(cursor))
                                {
                                    break;
                                }
                                idxEnd++;
                            }
                        }

                        // if the next char is not a delimiter then we have a partial match
                        // e.g. matching System.Action within System.Action`1
                        // and should continue our search after the current type
                        else if (!typeNameDelimiters.Contains(cursor))
                        {
                            // advance the index to the next type delimiter
                            idx = idxEnd + 1;
                            while (idx + 1 < sbTypeName.Length)
                            {
                                idx++;
                                cursor = sbTypeName[idx].ToString();
                                if (typeNameDelimiters.Contains(cursor))
                                {
                                    break;
                                }
                            }
                            continue;
                        }
                    }

                    // replace all characters of match with a type neutral character
                    for (; idx <= idxEnd; idx++)
                    {
                        sbTypeName[idx] = '?';
                    }
                    idx++;
                }
            }

            // any white listed types have been neutralised.
            // if any  skip listed types remain then the whitelisting has failed
            isSkipListed  = TypeNameSkipList.Any(e => sbTypeName.ToString().IndexOf(e) != -1);
            isWhiteListed = !isSkipListed;

            return(isWhiteListed);
        }