示例#1
0
        public Type ResolveType(
            HashSet <string> imports,
            ReaderWriterLockSlim importsLock,
            string[] path,
            bool isFatal = true,
            bool isType  = false)
        {
            var ctx = new InteropTypeContext(imports, path, isType, importsLock);

            //lock (_contextLocks[ctx])
            lock (_pathLocks[path])
            {
                return(ResolveTypeCore(ctx, imports, path, isFatal, isType));
            }
        }
示例#2
0
        private Type ResolveTypeCore(
            InteropTypeContext ctx,
            HashSet <string> imports,
            string[] path,
            bool isFatal,
            bool isType)
        {
            _typeCacheLock.EnterReadLock();

            try
            {
                if (_typeCache.TryGetValue(ctx, out var t))
                {
                    return(t);
                }
            }
            finally
            {
                _typeCacheLock.ExitReadLock();
            }

            var importsCopy = imports.ToArray();

            var pathStr = string.Join(".", path);
            var offset  = !isType ? 1 : 0;

            var type = path
                       .Take(path.Length - offset)
                       .Select((x, i) => new
            {
                Count = i + 1,
                Path  = string.Join(".", path.Take(i + 1))
            })
                       .SelectMany(x =>
                                   new[] { "" }
                                   .Concat(importsCopy)
                                   .Select(y => new
            {
                x.Count,
                Path = y.Length > 0 ? y + "." + x.Path : x.Path,
            }))
                       .Select(x => new
            {
                PartCount = x.Count,
                Type      = ResolveType(x.Path),
            })
                       .FirstOrDefault(x => x.Type != null);

            if (type == null)
            {
                if (isFatal)
                {
                    throw Interpreter.CreateRuntimeException(
                              "Could not resolve member expression '{0}'.",
                              pathStr);
                }
#if TYPE_CACHE_NULL
                ctx.IsResolved = false;

                _typeCacheLock.EnterWriteLock();

                try
                {
                    _typeCache.Add(ctx, null);
                }
                finally
                {
                    _typeCacheLock.ExitWriteLock();
                }
#endif

                return(null);
            }

            if (type.PartCount != path.Length - offset)
            {
                throw Interpreter.CreateRuntimeException(
                          "Could not resolve member expression '{0}'",
                          pathStr);
            }

            ctx.IsResolved = type.Type != null;

            _typeCacheLock.EnterWriteLock();

            try
            {
                if (!_typeCache.ContainsKey(ctx))
                {
                    _typeCache.Add(ctx, type.Type);
                }
            }
            finally
            {
                _typeCacheLock.ExitWriteLock();
            }

            return(type.Type);
        }