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); }
/// <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); }
/// <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))); }
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); } }
/// <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)); }
/// <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); }
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); }
/// <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); }
/// <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); }
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); }
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); }
internal Exception /*!*/ ReadOnlyError(string /*!*/ name) { return(RubyExceptions.CreateNameError(String.Format("${0} is a read-only variable", name))); }
public static Exception /*!*/ CreateArgumentError(DecoderFallbackException /*!*/ e, RubyEncoding /*!*/ encoding) { return(RubyExceptions.CreateArgumentError(String.Format("invalid byte sequence {0} in {1}", BitConverter.ToString(e.BytesUnknown), encoding))); }
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))); }
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); }
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"))); }