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)); } }
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); }