Helper class for creating the corresponding .NET exceptions from the Ruby error names
Exemplo n.º 1
0
        private bool LoadAssembly(Assembly /*!*/ assembly, string typeName, bool throwOnError)
        {
            Utils.Log(String.Format("Loading assembly '{0}' and type '{1}'", assembly, typeName), "LOADER");
            Type initializerType;

            if (typeName != null)
            {
                // load Ruby library:
                initializerType = assembly.GetType(typeName);
                if (initializerType == null)
                {
                    if (throwOnError)
                    {
                        throw new TypeLoadException(
                                  String.Format("Unhandled Exception: System.TypeLoadException: Could not load type '{0}' from assembly '{1}'.",
                                                typeName, assembly.FullName)
                                  );
                    }
                    return(false);
                }

                LoadLibrary(initializerType, false);
            }
            else
            {
                // load namespaces:
                try {
                    DomainManager.LoadAssembly(assembly);
                } catch (Exception e) {
                    if (throwOnError)
                    {
                        throw RubyExceptions.CreateLoadError(e);
                    }
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Converts an Integer to a Fixnum.
        /// Don't call any conversion methods--just handles Fixnum & Bignum
        /// </summary>
        /// <param name="value"></param>
        /// <returns>true if value is an Integer, false otherwise</returns>
        /// <exception cref="ArgumentOutOfRangeException">Throws a RangeError if value is a
        /// BigInteger but can't be converted to a Fixnum</exception>
        public static bool IntegerAsFixnum(object value, out int result)
        {
            if (value is int)
            {
                result = (int)value;
                return(true);
            }

            var bignum = value as BigInteger;

            if ((object)bignum != null)
            {
                if (!bignum.AsInt32(out result))
                {
                    throw RubyExceptions.CreateRangeError("bignum too big to convert into `long'");
                }
                return(true);
            }

            result = 0;
            return(false);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Casts to symbol. Note that this doesn't actually use to_sym -- it uses to_str.
        /// That's just how Ruby does it.
        ///
        /// Another fun detail: you can pass Fixnums as Symbols. If you pass a Fixnum that
        /// doesn't map to a Symbol (i.e. Fixnum#to_sym returns nil), you get an ArgumentError
        /// instead of a TypeError. At least it produces a warning about using Fixnums as Symbols
        /// </summary>
        public static string /*!*/ CastToSymbol(RubyContext /*!*/ context, object obj)
        {
            if (obj is SymbolId)
            {
                return(SymbolTable.IdToString((SymbolId)obj));
            }

            if (obj is int)
            {
                return(RubyOps.ConvertFixnumToSymbol(context, (int)obj));
            }
            else
            {
                MutableString str = AsString(context, obj);
                if (str != null)
                {
                    return(RubyOps.ConvertMutableStringToSymbol(str));
                }
            }

            throw RubyExceptions.CreateTypeError(String.Format("{0} is not a symbol", RubySites.Inspect(context, obj)));
        }
Exemplo n.º 4
0
        private static RubyClass /*!*/ ToSuperClass(RubyContext /*!*/ ec, object superClassObject)
        {
            if (superClassObject != null)
            {
                RubyClass superClass = superClassObject as RubyClass;
                if (superClass == null)
                {
                    throw RubyExceptions.CreateTypeError(String.Format("superclass must be a Class ({0} given)", ec.GetClassOf(superClassObject).Name));
                }

                if (superClass.IsSingletonClass)
                {
                    throw RubyExceptions.CreateTypeError("can't make subclass of virtual class");
                }

                return(superClass);
            }
            else
            {
                return(ec.ObjectClass);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Like CastToInteger, but converts the result to an unsigned int.
        /// </summary>
        public static ulong CastToUInt64Unchecked(RubyContext /*!*/ context, object obj)
        {
            if (obj == null)
            {
                throw RubyExceptions.CreateTypeError("no implicit conversion from nil to integer");
            }

            int        fixnum;
            BigInteger bignum;

            CastToInteger(context, obj, out fixnum, out bignum);
            if ((object)bignum != null)
            {
                ulong u;
                if (bignum.AsUInt64(out u))
                {
                    return(u);
                }
                throw RubyExceptions.CreateRangeError("bignum too big to convert into `quad long'");
            }

            return(unchecked ((ulong)fixnum));
        }
Exemplo n.º 6
0
        /// <summary>
        /// Try to convert obj to an Array using #to_ary
        /// 1. If obj is an Array (or a subtype), returns it
        /// 2. Calls to_ary if it exists, possibly throwing if to_ary doesn't return an Array
        /// 3. else returns null
        /// </summary>
        public static IList AsArray(RubyContext /*!*/ context, object obj)
        {
            // Don't call to_a on types derived from Array
            IList ary = obj as IList;

            if (ary != null)
            {
                return(ary);
            }

            if (RubySites.RespondTo(context, obj, "to_ary"))
            {
                object result = _ToAry.Target(_ToAry, context, obj);
                ary = result as IList;
                if (ary != null)
                {
                    return(ary);
                }

                throw RubyExceptions.MethodShouldReturnType(context, obj, "to_ary", "Array");
            }

            return(null);
        }
Exemplo n.º 7
0
        private bool LoadAssembly(Assembly /*!*/ assembly, string typeName, bool throwOnError)
        {
            Utils.Log(String.Format("Loading assembly '{0}' and type '{1}'", assembly, typeName), "LOADER");
            Type initializerType;

            if (typeName != null)
            {
                // load Ruby library:
                try {
                    initializerType = assembly.GetType(typeName, true);
                } catch (Exception e) {
                    if (throwOnError)
                    {
                        throw new LoadError(e.Message, e);
                    }
                    return(false);
                }

                LoadLibrary(initializerType, false);
            }
            else
            {
                // load namespaces:
                try {
                    DomainManager.LoadAssembly(assembly);
                } catch (Exception e) {
                    if (throwOnError)
                    {
                        throw RubyExceptions.CreateLoadError(e);
                    }
                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 8
0
        /// <exception cref="LoadError"></exception>
        private void LoadLibrary(Type /*!*/ initializerType, bool builtin)
        {
            LibraryInitializer initializer;

            try {
                initializer = Activator.CreateInstance(initializerType) as LibraryInitializer;
            } catch (TargetInvocationException e) {
                throw RubyExceptions.CreateLoadError(e.InnerException);
            } catch (Exception e) {
                throw RubyExceptions.CreateLoadError(e);
            }

            if (initializer == null)
            {
                throw RubyExceptions.CreateLoadError(String.Format("Specified type {0} is not a subclass of {1}",
                                                                   initializerType.FullName,
                                                                   typeof(LibraryInitializer).FullName)
                                                     );
            }

            // Propagate exceptions from initializers (do not wrap them to LoadError).
            // E.g. TypeError (can't modify frozen module) can be thrown.
            initializer.LoadModules(_context, builtin);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Searches file in load directories and then appends extensions.
        /// </summary>
        private IList <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)
            {
                var file = ResolveFile(path, extension, appendExtensions, sourceFileExtensions);
                return(file != null ? new[] { file } : new ResolvedFile[0]);
            }

            string[] loadPaths = GetLoadPathStrings();

            if (loadPaths.Length == 0)
            {
                return(new ResolvedFile[0]);
            }

            // 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))
            {
                var file = ResolveFile(path, extension, appendExtensions, sourceFileExtensions);
                return(file != null ? new[] { file } : new ResolvedFile[0]);
            }

            var result = new List <ResolvedFile>();
            foreach (var dir in loadPaths)
            {
                ResolvedFile file = ResolveFile(RubyUtils.CombinePaths(dir, path), extension, appendExtensions, sourceFileExtensions);
                if (file != null)
                {
                    result.Add(file);
                }
            }

            return(result);
        }
Exemplo n.º 10
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);
            }

            IList <ResolvedFile> files = FindFile(path, (flags & LoadFlags.AppendExtensions) != 0, sourceFileExtensions);

            if (files.Count == 0)
            {
                // MRI: doesn't throw an exception if the path is in $" (performs resolution first though):
                if (AlreadyLoaded(path, null, flags, sourceFileExtensions))
                {
                    loaded = null;
                    return(false);
                }
                throw RubyExceptions.CreateLoadError(String.Format("no such file to load -- {0}", path));
            }

            ResolvedFile file = files.First();

            string pathWithExtension = path;

            if (file.AppendedExtension != null)
            {
                pathWithExtension += file.AppendedExtension;
            }

            if (AlreadyLoaded(path, files, flags) || _unfinishedFiles.Contains(file.Path))
            {
                if ((flags & LoadFlags.ResolveLoaded) != 0)
                {
                    if (file.SourceUnit != null)
                    {
                        Scope loadedScope;
                        if (!LoadedScripts.TryGetValue(file.Path, out loadedScope))
                        {
                            throw RubyExceptions.CreateLoadError(String.Format("no such file to load -- {0}", file.Path));
                        }
                        loaded = loadedScope;
                    }
                    else
                    {
                        loaded = Platform.LoadAssemblyFromPath(file.Path);
                    }
                }
                else
                {
                    loaded = null;
                }
                return(false);
            }

            try {
                // save path as is, no canonicalization nor combination with an extension or directory:
                _unfinishedFiles.Push(file.Path);

                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(file.Path);
                        DomainManager.LoadAssembly(assembly);
                        loaded = assembly;
                    } catch (Exception e) {
                        throw RubyExceptions.CreateLoadError(e);
                    }
                }

                FileLoaded(MutableString.Create(file.Path, pathEncoding), flags);
            } finally {
                _unfinishedFiles.Pop();
            }

            return(true);
        }
Exemplo n.º 11
0
        private ResolvedFile FindFile(string /*!*/ path, bool appendExtensions, string[] sourceFileExtensions)
        {
            Assert.NotNull(path);
            bool   isAbsolutePath;
            string extension;
            string home = null;

#if !SILVERLIGHT
            if (path.StartsWith("~/", StringComparison.Ordinal) || path.StartsWith("~\\", StringComparison.Ordinal))
            {
                try {
                    home = Environment.GetEnvironmentVariable("HOME");
                } catch (SecurityException) {
                    home = null;
                }

                if (home == null)
                {
                    throw RubyExceptions.CreateArgumentError(String.Format("couldn't find HOME environment -- expanding `{0}'", path));
                }
            }
#endif
            try {
                if (home != null)
                {
                    path = RubyUtils.CombinePaths(home, path.Substring(2));
                }

                isAbsolutePath = Platform.IsAbsolutePath(path);
                extension      = RubyUtils.GetExtension(path);
            } catch (ArgumentException e) {
                throw RubyExceptions.CreateLoadError(e);
            }

            // 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)
            {
                try {
                    ResolvedFile result = ResolveFile(RubyUtils.CombinePaths(dir, path), extension, appendExtensions, sourceFileExtensions);
                    if (result != null)
                    {
                        return(result);
                    }
                } catch (ArgumentException) {
                    // invalid characters in path
                }
            }

            return(null);
        }
Exemplo n.º 12
0
 internal Exception /*!*/ ReadOnlyError(string /*!*/ name)
 {
     return(RubyExceptions.CreateNameError(String.Format("${0} is a read-only variable", name)));
 }
Exemplo n.º 13
0
 public static Exception /*!*/ CreateArgumentError(DecoderFallbackException /*!*/ e, RubyEncoding /*!*/ encoding)
 {
     return(RubyExceptions.CreateArgumentError(String.Format("invalid byte sequence {0} in {1}",
                                                             BitConverter.ToString(e.BytesUnknown), encoding)));
 }
Exemplo n.º 14
0
 public static Exception /*!*/ CreateArgumentError(EncoderFallbackException /*!*/ e, RubyEncoding /*!*/ encoding)
 {
     return(RubyExceptions.CreateArgumentError(String.Format("character U+{0:X4} can't be encoded in {1}",
                                                             e.CharUnknownHigh != '\0' ? Tokenizer.ToCodePoint(e.CharUnknownHigh, e.CharUnknownLow) : (int)e.CharUnknown, encoding)));
 }
Exemplo n.º 15
0
        private ResolvedFile FindFile(Scope /*!*/ globalScope, string /*!*/ path, bool appendExtensions)
        {
            Assert.NotNull(path);
            bool   isAbsolutePath;
            string extension;
            string home = null;

#if !SILVERLIGHT
            if (path.StartsWith("~/") || path.StartsWith("~\\"))
            {
                try {
                    home = Environment.GetEnvironmentVariable("HOME");
                } catch (SecurityException) {
                    home = null;
                }

                if (home == null)
                {
                    throw RubyExceptions.CreateArgumentError(String.Format("couldn't find HOME environment -- expanding `{0}'", path));
                }
            }
#endif

            try {
                if (home != null)
                {
                    path = Path.Combine(home, path.Substring(2));
                }

                isAbsolutePath = Platform.IsAbsolutePath(path);
                extension      = Path.GetExtension(path);
            } catch (ArgumentException e) {
                throw new LoadError(e.Message, e);
            }

            string[] knownExtensions = DomainManager.Configuration.GetFileExtensions();
            Array.Sort(knownExtensions, DlrConfiguration.FileExtensionComparer);

            // Absolute path -> load paths not consulted.
            if (isAbsolutePath)
            {
                return(ResolveFile(path, extension, appendExtensions, knownExtensions));
            }

            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("./") || path.StartsWith("../") || path.StartsWith(".\\") || path.StartsWith("..\\"))
            {
                return(ResolveFile(path, extension, appendExtensions, knownExtensions));
            }

            foreach (var dir in loadPaths)
            {
                try {
                    ResolvedFile result = ResolveFile(Path.Combine(dir, path), extension, appendExtensions, knownExtensions);
                    if (result != null)
                    {
                        return(result);
                    }
                } catch (ArgumentException) {
                    // invalid characters in path
                }
            }

            return(null);
        }
Exemplo n.º 16
0
 public static Exception /*!*/ CreateUndefinedMethodError(RubyModule /*!*/ module, string /*!*/ methodName)
 {
     return(RubyExceptions.CreateNameError(String.Format("undefined method `{0}' for {2} `{1}'",
                                                         methodName, module.Name, module.IsClass ? "class" : "module")));
 }