Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        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);
        }