/// <summary> /// Searches file in load directories and then appends extensions. /// </summary> private ResolvedFile FindFile(string /*!*/ path, bool appendExtensions, string[] sourceFileExtensions) { Assert.NotNull(path); bool isAbsolutePath; #if SILVERLIGHT { #else if (path.StartsWith("~/", StringComparison.Ordinal) || path.StartsWith("~\\", StringComparison.Ordinal)) { path = RubyUtils.ExpandPath(_context.Platform, path); isAbsolutePath = true; } else { #endif try { isAbsolutePath = Platform.IsAbsolutePath(path); } catch (ArgumentException e) { throw RubyExceptions.CreateLoadError(e); } } string extension = RubyUtils.GetExtension(path); // Absolute path -> load paths not consulted. if (isAbsolutePath) { return(ResolveFile(path, extension, appendExtensions, sourceFileExtensions)); } string[] loadPaths = GetLoadPathStrings(); if (loadPaths.Length == 0) { return(null); } // If load paths are non-empty and the path starts with .\ or ..\ then MRI also ignores the load paths. if (path.StartsWith("./", StringComparison.Ordinal) || path.StartsWith("../", StringComparison.Ordinal) || path.StartsWith(".\\", StringComparison.Ordinal) || path.StartsWith("..\\", StringComparison.Ordinal)) { return(ResolveFile(path, extension, appendExtensions, sourceFileExtensions)); } foreach (var dir in loadPaths) { ResolvedFile result = ResolveFile(RubyUtils.CombinePaths(dir, path), extension, appendExtensions, sourceFileExtensions); if (result != null) { return(result); } } return(null); }
/// <summary> /// Appends extensions if applicable. /// </summary> private ResolvedFile ResolveFile(string /*!*/ path, string /*!*/ extension, bool appendExtensions, string[] /*!*/ knownExtensions) { Debug.Assert(RubyUtils.GetExtension(path) == extension); string expandedPath = RubyUtils.ExpandPath(_context.Platform, path); // MRI doesn't load file w/o .rb extension: if (IsKnownExtension(extension, knownExtensions)) { return(GetSourceUnit(path, expandedPath, extension, false)); } if (_LibraryExtensions.IndexOf(extension, DlrConfiguration.FileExtensionComparer) != -1) { if (Platform.FileExists(expandedPath)) { return(new ResolvedFile(expandedPath, null)); } } else if (!appendExtensions) { return(GetSourceUnit(path, expandedPath, extension, false)); } if (appendExtensions) { List <string> matchingExtensions = GetExtensionsOfExistingFiles(expandedPath, knownExtensions); if (matchingExtensions.Count == 1) { return(GetSourceUnit(path + matchingExtensions[0], expandedPath + matchingExtensions[0], matchingExtensions[0], true)); } else if (matchingExtensions.Count > 1) { Exception e = new AmbiguousFileNameException(expandedPath + matchingExtensions[0], expandedPath + matchingExtensions[1]); throw RubyExceptions.CreateLoadError(e); } foreach (string libExtension in _LibraryExtensions) { if (Platform.FileExists(expandedPath + libExtension)) { return(new ResolvedFile(expandedPath + libExtension, libExtension)); } } } return(null); }
private bool LoadFromPath(Scope globalScope, object self, string /*!*/ path, RubyEncoding /*!*/ pathEncoding, LoadFlags flags, out object loaded) { Assert.NotNull(pathEncoding, path); string[] sourceFileExtensions; if ((flags & LoadFlags.AnyLanguage) != 0) { sourceFileExtensions = DomainManager.Configuration.GetFileExtensions(); } else { sourceFileExtensions = DomainManager.Configuration.GetFileExtensions(_context); } ResolvedFile file = FindFile(path, (flags & LoadFlags.AppendExtensions) != 0, sourceFileExtensions); // MRI 1.9: normalize the path string normalizedPath; if (_context.RubyOptions.Compatibility == RubyCompatibility.Ruby19) { normalizedPath = RubyUtils.ExpandPath(_context.Platform, path); } else { normalizedPath = path; } if (file == null) { // MRI: doesn't throw an exception if the path is in $" (performs resolution first though): if (AlreadyLoaded(path, normalizedPath, flags, sourceFileExtensions)) { loaded = null; return(false); } throw RubyExceptions.CreateLoadError(String.Format("no such file to load -- {0}", path)); } string pathWithExtension = path; if (file.AppendedExtension != null) { normalizedPath += file.AppendedExtension; pathWithExtension += file.AppendedExtension; } if (AlreadyLoaded(pathWithExtension, normalizedPath, flags) || _unfinishedFiles.Contains(normalizedPath)) { if ((flags & LoadFlags.ResolveLoaded) != 0) { if (_context.RubyOptions.Compatibility < RubyCompatibility.Ruby19) { normalizedPath = RubyUtils.ExpandPath(_context.Platform, path); } if (file.SourceUnit != null) { Scope loadedScope; if (!LoadedScripts.TryGetValue(normalizedPath, out loadedScope)) { throw RubyExceptions.CreateLoadError(String.Format("no such file to load -- {0}", file.Path)); } loaded = loadedScope; } else { loaded = Platform.LoadAssemblyFromPath(normalizedPath); } } else { loaded = null; } return(false); } try { // save path as is, no canonicalization nor combination with an extension or directory: _unfinishedFiles.Push(normalizedPath); if (file.SourceUnit != null) { AddScriptLines(file.SourceUnit); ScriptCode compiledCode; if (file.SourceUnit.LanguageContext == _context) { compiledCode = CompileRubySource(file.SourceUnit, flags); } else { compiledCode = file.SourceUnit.Compile(); } loaded = Execute(globalScope, compiledCode); } else { Debug.Assert(file.Path != null); try { Assembly assembly = Platform.LoadAssemblyFromPath(Platform.GetFullPath(file.Path)); DomainManager.LoadAssembly(assembly); loaded = assembly; } catch (Exception e) { throw RubyExceptions.CreateLoadError(e); } } FileLoaded(MutableString.Create(normalizedPath, pathEncoding), flags); } finally { _unfinishedFiles.Pop(); } return(true); }