edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializer.Generated.cs;C434537 File: Initializer.Generated.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializer.Generated.cs;C434537 (server) 5/8/2008 2:10 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializer.Generated.cs;MutableString5 @@ -44,7 +44,7 @@ #endif // Skipped primitive: Object Ruby.Builtins.RubyModule def34 = DefineModule("System::Collections::Generic::IDictionary", typeof(System.Collections.Generic.IDictionary), new System.Action(LoadSystem__Collections__Generic__IDictionary_Instance), null, new Ruby.Builtins.RubyModule[] {def28, }); - Ruby.Builtins.RubyModule def47 = DefineModule("System::Collections::IEnumerable", typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def28, }); + DefineModule("System::Collections::IEnumerable", typeof(System.Collections.IEnumerable), new System.Action(LoadSystem__Collections__IEnumerable_Instance), null, new Ruby.Builtins.RubyModule[] {def28, }); Ruby.Builtins.RubyModule def42 = DefineModule("System::Collections::IList", typeof(System.Collections.IList), new System.Action(LoadSystem__Collections__IList_Instance), null, new Ruby.Builtins.RubyModule[] {def28, }); DefineModule("System::IComparable", typeof(System.IComparable), new System.Action(LoadSystem__IComparable_Instance), null, new Ruby.Builtins.RubyModule[] {def40, }); DefineGlobalClass("Time", typeof(System.DateTime), typeof(Ruby.Builtins.TimeOps), new System.Action(LoadTime_Instance), new System.Action(LoadTime_Class), classRef1, new Ruby.Builtins.RubyModule[] {def40, }, new System.Delegate[] { @@ -71,7 +71,7 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.ArrayOps.CreateArray), }); DefineGlobalClass("Binding", typeof(Ruby.Builtins.Binding), typeof(Ruby.Builtins.BindingOps), null, null, Context.ObjectClass, Ruby.Builtins.RubyModule.EmptyArray, null); - DefineGlobalClass("ClrString", typeof(System.String), typeof(Ruby.Builtins.StringOps), new System.Action(LoadClrString_Instance), null, Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def47, }, null); + DefineGlobalClass("ClrString", typeof(System.String), typeof(Ruby.Builtins.StringOps), new System.Action(LoadClrString_Instance), null, Context.ObjectClass, Ruby.Builtins.RubyModule.EmptyArray, null); Ruby.Builtins.RubyClass def13 = DefineClass("Digest::Class", typeof(Ruby.StandardLibrary.Digest.Class), null, null, new System.Action(LoadDigest__Class_Class), Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def14, }, null); DefineGlobalClass("Dir", typeof(Ruby.Builtins.RubyDir), null, new System.Action(LoadDir_Instance), new System.Action(LoadDir_Class), Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def28, }, null); Ruby.Builtins.RubyClass def41 = Context.ExceptionClass = DefineGlobalClass("Exception", typeof(System.Exception), typeof(Ruby.Builtins.ExceptionOps), new System.Action(LoadException_Instance), new System.Action(LoadException_Class), Context.ObjectClass, Ruby.Builtins.RubyModule.EmptyArray, new System.Delegate[] { @@ -101,15 +101,18 @@ DefineGlobalClass("Range", typeof(Ruby.Builtins.Range), typeof(Ruby.Builtins.RangeOps), new System.Action(LoadRange_Instance), null, Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def28, }, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RangeOps.CreateRange), }); - DefineGlobalClass("Regexp", typeof(Ruby.Builtins.Regexp), typeof(Ruby.Builtins.RegexpOps), new System.Action(LoadRegexp_Instance), new System.Action(LoadRegexp_Class), Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def28, }, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), + DefineGlobalClass("Regexp", typeof(Ruby.Builtins.RubyRegex), typeof(Ruby.Builtins.RegexpOps), new System.Action(LoadRegexp_Instance), new System.Action(LoadRegexp_Class), Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def28, }, new System.Delegate[] { + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Create), }); - DefineGlobalClass("String", typeof(Ruby.Builtins.MutableString), typeof(Ruby.Builtins.MutableStringOps), new System.Action(LoadString_Instance), null, Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def28, def40, }, null); + DefineGlobalClass("String", typeof(Ruby.Builtins.MutableString), typeof(Ruby.Builtins.MutableStringOps), new System.Action(LoadString_Instance), null, Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def28, def40, }, new System.Delegate[] { + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Create), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Create), + }); DefineGlobalClass("StringScanner", typeof(Ruby.Builtins.StringScanner), null, new System.Action(LoadStringScanner_Instance), new System.Action(LoadStringScanner_Class), Context.ObjectClass, Ruby.Builtins.RubyModule.EmptyArray, null); DefineGlobalClass("Struct", typeof(Ruby.Builtins.RubyStruct), typeof(Ruby.Builtins.RubyStructOps), new System.Action(LoadStruct_Instance), null, Context.ObjectClass, new Ruby.Builtins.RubyModule[] {def28, }, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyStructOps.CreateStructClass), @@ -1622,7 +1625,6 @@ module.DefineMethod("puts", 0x9, new System.Delegate[] { new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyIOOps.PutsEmptyLine), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyIOOps.Puts), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyIOOps.Puts), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyIOOps.Puts), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyIOOps.Puts), @@ -1674,8 +1676,6 @@ }); module.DefineMethod("write", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyIOOps.Write), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyIOOps.Write), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyIOOps.Write), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RubyIOOps.Write), }); @@ -2855,26 +2855,26 @@ module.SetConstant("MULTILINE", Ruby.Builtins.RegexpOps.MULTILINE); module.DefineMethod("~", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.ImplicitMatch), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.ImplicitMatch), }); module.DefineMethod("=~", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.MatchIndex), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.MatchIndex), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.MatchIndex), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.MatchIndex), }); module.DefineMethod("===", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.CaseCompare), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.CaseCompare), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.CaseCompare), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.CaseCompare), }); module.DefineMethod("match", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Match), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Match), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Match), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Match), }); module.DefineMethod("source", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Source), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Source), }); } @@ -2885,12 +2885,12 @@ module.SetConstant("MULTILINE", Ruby.Builtins.RegexpOps.MULTILINE); module.DefineMethod("compile", 0x11, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.RegexpOps.Compile), }); module.DefineMethod("escape", 0x11, new System.Delegate[] { @@ -2918,7 +2918,7 @@ }); module.DefineMethod("*", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Repeat), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Repeat), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Repeat), }); @@ -2931,9 +2931,9 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), }); module.DefineMethod("[]=", 0x9, new System.Delegate[] { @@ -2964,7 +2964,7 @@ }); module.DefineMethod("=~", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Match), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Match), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Match), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Match), }); @@ -3073,23 +3073,22 @@ }); module.DefineMethod("gsub", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.BlockReplaceAll), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAll), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.BlockReplaceAll), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAll), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAll), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAll), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAll), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAll), }); module.DefineMethod("gsub!", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.BlockReplaceAllInPlace), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAllInPlace), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.BlockReplaceAllInPlace), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAllInPlace), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAllInPlace), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAllInPlace), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAllInPlace), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceAllInPlace), }); module.DefineMethod("include?", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Include), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Include), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Include), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Include), @@ -3105,9 +3104,9 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Index), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Index), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Index), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Index), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Index), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Index), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Index), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Index), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Index), }); module.DefineMethod("initialize", 0xa, new System.Delegate[] { @@ -3145,7 +3144,7 @@ }); module.DefineMethod("match", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.MatchRegexp), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.MatchRegexp), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.MatchObject), }); @@ -3163,10 +3162,10 @@ }); module.DefineMethod("scan", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Scan), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Scan), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Scan), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Scan), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Scan), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Scan), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Scan), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Scan), }); @@ -3184,9 +3183,9 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.GetChars), }); module.DefineMethod("slice!", 0x9, new System.Delegate[] { @@ -3197,9 +3196,9 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.RemoveCharInPlace), }); @@ -3210,8 +3209,8 @@ new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Split), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Split), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Split), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Split), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Split), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Split), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.Split), }); module.DefineMethod("strip", 0x9, new System.Delegate[] { @@ -3223,18 +3222,18 @@ }); module.DefineMethod("sub", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.BlockReplaceFirst), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirst), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.BlockReplaceFirst), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirst), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirst), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirst), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirst), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirst), }); module.DefineMethod("sub!", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.BlockReplaceFirstInPlace), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirstInPlace), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.BlockReplaceFirstInPlace), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirstInPlace), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirstInPlace), - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirstInPlace), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirstInPlace), new Microsoft.Scripting.Utils.Function(Ruby.Builtins.MutableStringOps.ReplaceFirstInPlace), }); @@ -3320,11 +3319,11 @@ }); module.DefineMethod("check", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.Check), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.Check), }); module.DefineMethod("check_until", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.CheckUntil), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.CheckUntil), }); module.DefineMethod("clear", 0x9, new System.Delegate[] { @@ -3344,7 +3343,7 @@ }); module.DefineMethod("exist?", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function>(Ruby.Builtins.StringScanner.Exist), + new Microsoft.Scripting.Utils.Function>(Ruby.Builtins.StringScanner.Exist), }); module.DefineMethod("get_byte", 0x9, new System.Delegate[] { @@ -3364,7 +3363,7 @@ }); module.DefineMethod("match?", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function>(Ruby.Builtins.StringScanner.Match), + new Microsoft.Scripting.Utils.Function>(Ruby.Builtins.StringScanner.Match), }); module.DefineMethod("matched", 0x9, new System.Delegate[] { @@ -3436,27 +3435,27 @@ }); module.DefineMethod("scan", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.Scan), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.Scan), }); module.DefineMethod("scan_full", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.ScanFull), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.ScanFull), }); module.DefineMethod("scan_until", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.ScanUntil), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.ScanUntil), }); module.DefineMethod("search_full", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.SearchFull), + new Microsoft.Scripting.Utils.Function(Ruby.Builtins.StringScanner.SearchFull), }); module.DefineMethod("skip", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function>(Ruby.Builtins.StringScanner.Skip), + new Microsoft.Scripting.Utils.Function>(Ruby.Builtins.StringScanner.Skip), }); module.DefineMethod("skip_until", 0x9, new System.Delegate[] { - new Microsoft.Scripting.Utils.Function>(Ruby.Builtins.StringScanner.SkipUntil), + new Microsoft.Scripting.Utils.Function>(Ruby.Builtins.StringScanner.SkipUntil), }); module.DefineMethod("string", 0x9, new System.Delegate[] { =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Protocols.cs;C429806 File: Protocols.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Protocols.cs;C429806 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Protocols.cs;MutableString5 @@ -23,6 +23,7 @@ using Microsoft.Scripting.Math; using Ruby.Builtins; using Microsoft.Scripting.Runtime; +using System.Text.RegularExpressions; namespace Ruby.Runtime { /// @@ -160,10 +161,10 @@ } public static double ConvertStringToFloat(CodeContext context, MutableString value) { try { - return double.Parse(value.ToString(), System.Globalization.CultureInfo.InvariantCulture.NumberFormat); + return double.Parse(value.ConvertToString(), System.Globalization.CultureInfo.InvariantCulture.NumberFormat); } catch (FormatException x) { MutableString valueString = RubySites.Inspect(context, value); - throw RubyExceptions.CreateArgumentError("invalid value for Float(): " + valueString.ToString(), x); + throw RubyExceptions.CreateArgumentError("invalid value for Float(): " + valueString.ConvertToString(), x); } } #endregion @@ -173,9 +174,8 @@ /// Convert to a Regexp from an object via a string /// Makes sure that we escape characters in the string. /// - public static Regexp ConvertToRegexp(CodeContext/*!*/ context, object/*!*/ pattern) { - string patternString = Protocols.CastToString(context, pattern); - return new Regexp(new System.Text.RegularExpressions.Regex(System.Text.RegularExpressions.Regex.Escape(patternString))); + public static RubyRegex/*!*/ ConvertToRegexp(CodeContext/*!*/ context, object/*!*/ pattern) { + return new RubyRegex(RubyRegex.Escape(Protocols.CastToString(context, pattern)), RegexOptions.None); } #endregion @@ -452,7 +452,7 @@ if (result == null) { MutableString argErrMsg = RubySites.Inspect(context, obj); argErrMsg.Append(" is not a symbol"); - throw RubyExceptions.CreateArgumentError(argErrMsg.ToString()); + throw RubyExceptions.CreateArgumentError(argErrMsg.ConvertToString()); } RubyUtils.GetExecutionContext(context).ReportWarning("do not use Fixnums as Symbols"); return (SymbolId)result; @@ -465,7 +465,7 @@ MutableString typeErrMsg = RubySites.Inspect(context, obj); typeErrMsg.Append(" is not a symbol"); - throw RubyExceptions.CreateTypeError(typeErrMsg.ToString()); + throw RubyExceptions.CreateTypeError(typeErrMsg.ConvertToString()); } #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/BigNumOps.cs;C390406 File: BigNumOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/BigNumOps.cs;C390406 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/BigNumOps.cs;MutableString5 @@ -712,13 +712,15 @@ #endregion #region to_s + /// /// Returns a string containing the representation of self base 10. /// [RubyMethod("to_s")] public static object ToString(BigInteger/*!*/ self) { - return new MutableString(self.ToString()); + return MutableString.Create(self.ToString()); } + /// /// Returns a string containing the representation of self base radix (2 through 36). /// @@ -726,12 +728,13 @@ [RubyMethod("to_s")] public static object ToString(BigInteger/*!*/ self, uint radix) { if (radix < 2 || radix > 36) { - throw RubyExceptions.CreateArgumentError("illegal radix " + radix.ToString()); + throw RubyExceptions.CreateArgumentError(String.Format("illegal radix {0}", radix)); } // TODO: Can we do the ToLower in BigInteger? - return new MutableString(self.ToString((uint)radix).ToLower()); + return MutableString.Create(self.ToString((uint)radix).ToLower()); } + #endregion #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ClassOps.cs;C429806 File: ClassOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ClassOps.cs;C429806 (server) 5/8/2008 3:17 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ClassOps.cs;MutableString5 @@ -89,11 +89,12 @@ Type type = self.Tracker.Type; int required = type.GetGenericArguments().Length; if (required == 0) { - throw RubyExceptions.CreateArgumentError(string.Format("'{0}' is not a generic type", type.ToString())); + throw RubyExceptions.CreateArgumentError(String.Format("'{0}' is not a generic type", type.FullName)); } + int provided = typeArgs == null ? 0 : typeArgs.Length; if (required != provided) { - throw RubyExceptions.CreateArgumentError(string.Format("Type '{0}' requires {1} generic type arguments, {2} provided", type.ToString(), required, provided)); + throw RubyExceptions.CreateArgumentError(String.Format("Type '{0}' requires {1} generic type arguments, {2} provided", type.FullName, required, provided)); } // pull out the type arguments =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Dir.cs;C415805 File: Dir.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Dir.cs;C415805 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Dir.cs;MutableString5 @@ -53,12 +53,13 @@ #endregion public RubyDir([NotNull]MutableString/*!*/ dirname) { + string strName = dirname.ConvertToString(); try { - _rawEntries = Directory.GetFileSystemEntries(dirname); + _rawEntries = Directory.GetFileSystemEntries(strName); } catch (Exception ex) { - throw ToRubyException(ex, dirname, DirectoryOperation.Open); + throw ToRubyException(ex, strName, DirectoryOperation.Open); } - _dirName = new MutableString(NormalizePathSeparators(dirname)); + _dirName = MutableString.Create(NormalizePathSeparators(strName)); _closed = false; _pos = -2; } @@ -72,19 +73,20 @@ [RubyMethod("chdir", RubyMethodAttributes.PublicSingleton)] public static object ChangeDirectory(CodeContext context, object self, BlockParam block, MutableString dir) { Debug.Assert(block == null || context != null); + string strDir = dir.ConvertToString(); if (block == null) { try { - Directory.SetCurrentDirectory(dir); + Directory.SetCurrentDirectory(strDir); } catch (Exception ex) { - throw ToRubyException(ex, dir, DirectoryOperation.ChangeDir); + throw ToRubyException(ex, strDir, DirectoryOperation.ChangeDir); } return 0; } else { string current = Directory.GetCurrentDirectory(); object ret = null; try { - Directory.SetCurrentDirectory(dir); + Directory.SetCurrentDirectory(strDir); block.BlockJumped(ret = _ChrdirSite.Invoke(context, block, dir)); } finally { Directory.SetCurrentDirectory(current); @@ -116,7 +118,7 @@ throw new ArgumentException("HOME/LOGDIR not set"); } - return ChangeDirectory(self, new MutableString(defaultDirectory)); + return ChangeDirectory(self, MutableString.Create(defaultDirectory)); #else throw new InvalidOperationException(); #endif @@ -131,29 +133,31 @@ [RubyMethod("rmdir", RubyMethodAttributes.PublicSingleton)] [RubyMethod("unlink", RubyMethodAttributes.PublicSingleton)] public static int RemoveDirectory(object self, [NotNull]MutableString/*!*/ dirname) { + string strDir = dirname.ConvertToString(); try { - Directory.Delete(dirname); + Directory.Delete(strDir); } catch (Exception ex) { - throw ToRubyException(ex, dirname, DirectoryOperation.Delete); + throw ToRubyException(ex, strDir, DirectoryOperation.Delete); } return 0; } [RubyMethod("entries", RubyMethodAttributes.PublicSingleton)] public static RubyArray/*!*/ GetEntries(object self, [NotNull]MutableString/*!*/ dirname) { + string strDir = dirname.ConvertToString(); string[] rawEntries = null; try { - rawEntries = Directory.GetFileSystemEntries(dirname); + rawEntries = Directory.GetFileSystemEntries(strDir); } catch (Exception ex) { - throw ToRubyException(ex, dirname, DirectoryOperation.Open); + throw ToRubyException(ex, strDir, DirectoryOperation.Open); } RubyArray ret = new RubyArray(rawEntries.Length + 2); - ret.Add(new MutableString(".")); - ret.Add(new MutableString("..")); + ret.Add(MutableString.Create(".")); + ret.Add(MutableString.Create("..")); foreach (string entry in rawEntries) { - ret.Add(new MutableString(Path.GetFileName(entry))); + ret.Add(MutableString.Create(Path.GetFileName(entry))); } return ret; } @@ -171,7 +175,7 @@ [RubyMethod("getwd", RubyMethodAttributes.PublicSingleton)] [RubyMethod("pwd", RubyMethodAttributes.PublicSingleton)] public static MutableString/*!*/ GetCurrentDirectory(object self) { - return new MutableString(NormalizePathSeparators(Directory.GetCurrentDirectory())); + return MutableString.Create(NormalizePathSeparators(Directory.GetCurrentDirectory())); } // TODO: ruby specific pattern matching... @@ -179,28 +183,29 @@ [RubyMethod("glob", RubyMethodAttributes.PublicSingleton)] public static void Glob(CodeContext/*!*/ context, object self, BlockParam block, [NotNull]MutableString/*!*/ pattern, [Optional]int flags) { - foreach (string entry in Directory.GetFileSystemEntries(Directory.GetCurrentDirectory(), pattern)) { - if (block.BlockJumped(_GlobSite.Invoke(context, block, new MutableString(Path.GetFileName(entry))))) return; + foreach (string entry in Directory.GetFileSystemEntries(Directory.GetCurrentDirectory(), pattern.ConvertToString())) { + if (block.BlockJumped(_GlobSite.Invoke(context, block, MutableString.Create(Path.GetFileName(entry))))) return; } } [RubyMethod("glob", RubyMethodAttributes.PublicSingleton)] [RubyMethod("[]", RubyMethodAttributes.PublicSingleton)] public static RubyArray/*!*/ Glob(object self, [NotNull]MutableString/*!*/ pattern, [Optional]int flags) { - string[] rawEntries = Directory.GetFileSystemEntries(Directory.GetCurrentDirectory(), pattern); + string[] rawEntries = Directory.GetFileSystemEntries(Directory.GetCurrentDirectory(), pattern.ConvertToString()); RubyArray ret = new RubyArray(rawEntries.Length); foreach (string entry in rawEntries) { - ret.Add(new MutableString(Path.GetFileName(entry))); + ret.Add(MutableString.Create(Path.GetFileName(entry))); } return ret; } [RubyMethod("mkdir", RubyMethodAttributes.PublicSingleton)] public static int MakeDirectory(object self, [NotNull]MutableString/*!*/ dirname, [Optional]object permissions) { + string strDir = dirname.ConvertToString(); try { - Directory.CreateDirectory(dirname); + Directory.CreateDirectory(strDir); } catch (Exception ex) { - throw ToRubyException(ex, dirname, DirectoryOperation.Create); + throw ToRubyException(ex, strDir, DirectoryOperation.Create); } return 0; } @@ -276,11 +281,11 @@ MutableString ret; if (self._pos == -2) { - ret = new MutableString("."); + ret = MutableString.Create("."); } else if (self._pos == -1) { - ret = new MutableString(".."); + ret = MutableString.Create(".."); } else { - ret = new MutableString(Path.GetFileName(self._rawEntries[self._pos])); + ret = MutableString.Create(Path.GetFileName(self._rawEntries[self._pos])); } self._pos++; return ret; @@ -314,7 +319,7 @@ private void ThrowIfClosed() { if (_closed) { - throw IOErrorOps.Factory(new MutableString("closed directory")); + throw IOErrorOps.Factory(MutableString.Create("closed directory")); } } @@ -358,7 +363,7 @@ } // throw anyway - return SystemCallErrorOps.Factory(new MutableString(String.Format("unknown scenario - {0}, {1}, {2}", + return SystemCallErrorOps.Factory(MutableString.Create(String.Format("unknown scenario - {0}, {1}, {2}", exceptionType, path, op))); } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/EnvironmentSingletonOps.cs;C404624 File: EnvironmentSingletonOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/EnvironmentSingletonOps.cs;C404624 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/EnvironmentSingletonOps.cs;MutableString5 @@ -32,12 +32,13 @@ [RubyMethod("[]", RubyMethodAttributes.PublicInstance)] public static MutableString GetVariable(object/*!*/ self, [NotNull]MutableString/*!*/ name) { - return new MutableString(Environment.GetEnvironmentVariable(name.ToString())); + string value = Environment.GetEnvironmentVariable(name.ConvertToString()); + return (value != null) ? MutableString.Create(value) : null; } [RubyMethod("[]=", RubyMethodAttributes.PublicInstance)] public static MutableString GetVariable(object/*!*/ self, [NotNull]MutableString/*!*/ name, MutableString value) { - Environment.SetEnvironmentVariable(name.ToString(), (value != null) ? value : null); + Environment.SetEnvironmentVariable(name.ConvertToString(), (value != null) ? value.ConvertToString() : null); return value; } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Errno.cs;C390406 File: Errno.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Errno.cs;C390406 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Errno.cs;MutableString5 @@ -31,8 +31,8 @@ internal static string/*!*/ MakeMessage(ref MutableString message, string/*!*/ baseMessage) { Assert.NotNull(baseMessage); - string result = MakeMessage(message != null ? message.ToString() : null, baseMessage); - message = new MutableString(result); + string result = MakeMessage(message != null ? message.ConvertToString() : null, baseMessage); + message = MutableString.Create(result); return result; } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ExceptionOps.cs;C422137 File: ExceptionOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ExceptionOps.cs;C422137 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ExceptionOps.cs;MutableString5 @@ -83,7 +83,7 @@ } internal static string/*!*/ MakeMessage(MutableString message, string/*!*/ className) { - return (message == null) ? className : message.ToString(); + return (message == null) ? className : message.ConvertToString(); } #endregion @@ -107,7 +107,7 @@ Assert.NotNull(self); if (message == null) { - message = new MutableString(SymbolTable.IdToString(RubyUtils.GetExecutionContext(context).GetClassOf(self).Name)); + message = MutableString.Create(SymbolTable.IdToString(RubyUtils.GetExecutionContext(context).GetClassOf(self).Name)); } RubyExceptionData data = RubyExceptionData.GetInstance(self); @@ -173,7 +173,7 @@ return className; } - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); result.Append("#<"); result.Append(className); result.Append(": "); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FalseClass.cs;C420856 File: FalseClass.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FalseClass.cs;C420856 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FalseClass.cs;MutableString5 @@ -27,7 +27,7 @@ [RubyMethodAttribute("to_s")] public static MutableString/*!*/ ToString(bool self) { Debug.Assert(self == false); - return new MutableString("false"); + return MutableString.Create("false"); } [RubyMethodAttribute("&")] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FileOps.cs;C422137 File: FileOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FileOps.cs;C422137 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FileOps.cs;MutableString5 @@ -29,12 +29,12 @@ [RubyConstructor] public static RubyIO CreateIO(CodeContext/*!*/ context, MutableString/*!*/ path) { - return new RubyFile(RubyUtils.GetExecutionContext(context), path, "r"); + return new RubyFile(RubyUtils.GetExecutionContext(context), path.ConvertToString(), "r"); } [RubyConstructor] public static RubyIO CreateIO(CodeContext/*!*/ context, MutableString/*!*/ path, [NotNull] MutableString/*!*/ modeString) { - return new RubyFile(RubyUtils.GetExecutionContext(context), path, modeString); + return new RubyFile(RubyUtils.GetExecutionContext(context), path.ConvertToString(), modeString.ConvertToString()); } #region Private Singleton Methods @@ -59,10 +59,11 @@ [RubyMethod("delete", RubyMethodAttributes.PublicSingleton)] public static int Delete(CodeContext/*!*/ context, object/*!*/ self, MutableString/*!*/ path) { - if (!File.Exists(path)) - throw new Errno.NoEntryError(String.Format("No such file or directory - {0}", path)); + string strPath = path.ConvertToString(); + if (!File.Exists(strPath)) + throw new Errno.NoEntryError(String.Format("No such file or directory - {0}", strPath)); - File.Delete(path); + File.Delete(strPath); return 1; } @@ -81,13 +82,13 @@ [RubyMethod("directory?", RubyMethodAttributes.PublicSingleton)] public static bool IsDirectory(object/*!*/ self, MutableString/*!*/ path) { - return Directory.Exists(path); + return Directory.Exists(path.ConvertToString()); } [RubyMethod("dirname", RubyMethodAttributes.PublicSingleton)] public static MutableString DirName(object/*!*/ self, MutableString/*!*/ path) { - string directoryName = System.IO.Path.GetDirectoryName(path); - return new MutableString(String.IsNullOrEmpty(directoryName) ? "." : directoryName); + string directoryName = System.IO.Path.GetDirectoryName(path.ConvertToString()); + return MutableString.Create(String.IsNullOrEmpty(directoryName) ? "." : directoryName); } //executable? @@ -96,7 +97,8 @@ [RubyMethod("exist?", RubyMethodAttributes.PublicSingleton)] [RubyMethod("exists?", RubyMethodAttributes.PublicSingleton)] public static bool Exists(object self/*!*/, MutableString/*!*/ path) { - return File.Exists(path) || Directory.Exists(path); + string strPath = path.ConvertToString(); + return File.Exists(strPath) || Directory.Exists(strPath); } [RubyMethod("exist?", RubyMethodAttributes.PublicSingleton)] @@ -115,7 +117,7 @@ [RubyMethod("join", RubyMethodAttributes.PublicSingleton)] public static MutableString Join(CodeContext/*!*/ context, object/*!*/ self, [NotNull] params object[] strings) { - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); for (int i = 0; i < strings.Length; ++i) { result.Append(Protocols.ConvertToString(context, strings[i])); @@ -150,20 +152,20 @@ #else try { if (path == null || path.Length == 0) - return new MutableString(Directory.GetCurrentDirectory()); + return MutableString.Create(Directory.GetCurrentDirectory()); - if (path.Length == 1 && path[0] == '~') - return new MutableString(System.IO.Path.GetFullPath(Environment.GetEnvironmentVariable("HOME"))); + if (path.Length == 1 && path.GetChar(0) == '~') + return MutableString.Create(System.IO.Path.GetFullPath(Environment.GetEnvironmentVariable("HOME"))); - if (path[0] == '~' && (path[1] == System.IO.Path.DirectorySeparatorChar || path[1] == System.IO.Path.AltDirectorySeparatorChar)) { + if (path.GetChar(0) == '~' && (path.GetChar(1) == System.IO.Path.DirectorySeparatorChar || path.GetChar(1) == System.IO.Path.AltDirectorySeparatorChar)) { string homeDirectory = Environment.GetEnvironmentVariable("HOME"); - return path.Length < 3 ? new MutableString(homeDirectory) : new MutableString(System.IO.Path.Combine(homeDirectory, path.Substring(2))); + return path.Length < 3 ? MutableString.Create(homeDirectory) : MutableString.Create(System.IO.Path.Combine(homeDirectory, path.GetSlice(2).ConvertToString())); } else { - return new MutableString(System.IO.Path.GetFullPath(path)); + return MutableString.Create(System.IO.Path.GetFullPath(path.ConvertToString())); } } catch (Exception e) { // Re-throw exception as a reasonable Ruby exception - throw new Errno.InvalidError(path, e); + throw new Errno.InvalidError(path.ConvertToString(), e); } #endif } @@ -181,10 +183,10 @@ [RubyMethod("expand_path", RubyMethodAttributes.PublicSingleton)] public static MutableString ExpandPath(object/*!*/ self, [NotNull]MutableString/*!*/ path, [NotNull]MutableString/*!*/ basePath) { // We ignore basePath parameter if first string starts with a ~ - if (path.Length > 0 && path[0] == '~') { + if (path.Length > 0 && path.GetChar(0) == '~') { return ParsePathForProfileDir(path); } else { - return new MutableString(System.IO.Path.GetFullPath(System.IO.Path.Combine(ParsePathForProfileDir(basePath), path))); + return MutableString.Create(System.IO.Path.GetFullPath(System.IO.Path.Combine(ParsePathForProfileDir(basePath).ConvertToString(), path.ConvertToString()))); } } @@ -241,14 +243,12 @@ [RubyMethod("inspect")] public static MutableString/*!*/ Inspect(CodeContext/*!*/ context, RubyFile/*!*/ self) { - MutableString result = new MutableString(); - result.Append("#"); - return result; + return MutableString.CreateMutable("#'); } [RubyMethod("path")] public static MutableString/*!*/ Path(RubyFile/*!*/ self) { - return new MutableString(self.Path); + return MutableString.Create(self.Path); } //truncate @@ -257,12 +257,12 @@ #region Declared Constants [RubyConstant] - public readonly static MutableString ALT_SEPARATOR = new MutableString("\\"); + public readonly static MutableString ALT_SEPARATOR = MutableString.Create("\\"); [RubyConstant] - public readonly static MutableString PATH_SEPARATOR = new MutableString(";"); + public readonly static MutableString PATH_SEPARATOR = MutableString.Create(";"); - private readonly static MutableString INTERNAL_SEPARATOR = new MutableString("/"); + private readonly static MutableString INTERNAL_SEPARATOR = MutableString.Create("/"); [RubyConstant] public readonly static MutableString SEPARATOR = INTERNAL_SEPARATOR; =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FixnumOps.cs;C405838 File: FixnumOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FixnumOps.cs;C405838 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FixnumOps.cs;MutableString5 @@ -843,7 +843,7 @@ /// 12345.to_s => "12345" [RubyMethod("to_s")] public static object ToString(object self) { - return new MutableString(self.ToString()); + return MutableString.Create(self.ToString()); } /// /// Returns a string representing the value of self using base radix. @@ -863,7 +863,7 @@ } // TODO: Should we try to use a Fixnum specific ToString? // TODO: Can we do the ToLower in BigInteger? - return new MutableString(self.ToString((uint)radix).ToLower()); + return MutableString.Create(self.ToString((uint)radix).ToLower()); } #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FloatOps.cs;C420856 File: FloatOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FloatOps.cs;C420856 (server) 5/8/2008 11:20 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/FloatOps.cs;MutableString5 @@ -540,7 +540,7 @@ /// [RubyMethod("to_s")] public static MutableString ToString(CodeContext/*!*/ context, double self) { - StringFormatter sf = new StringFormatter(context, new MutableString("%.15g"), new object[] { self }); + StringFormatter sf = new StringFormatter(context, "%.15g", new object[] { self }); sf.TrailingZeroAfterWholeFloat = true; return sf.Format(); } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Integer.cs;C417565 File: Integer.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Integer.cs;C417565 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Integer.cs;MutableString5 @@ -83,7 +83,7 @@ throw RubyExceptions.CreateRangeError(intSelf.ToString() + " out of char range"); } // TODO: this is incorrect right now, and we fail some specs because we don't have byte strings - return new MutableString(((char)intSelf).ToString()); + return MutableString.Create(((char)intSelf).ToString()); } #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/IoOps.cs;C415805 File: IoOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/IoOps.cs;C415805 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/IoOps.cs;MutableString5 @@ -91,7 +91,7 @@ [RubyMethod("foreach", RubyMethodAttributes.PublicSingleton)] public static void ForEach(CodeContext/*!*/ context, RubyClass/*!*/ self, BlockParam/*!*/ block, MutableString path, MutableString separator) { - using (RubyIO io = new RubyIO(RubyUtils.GetExecutionContext(context), File.OpenRead(path), "r")) + using (RubyIO io = new RubyIO(RubyUtils.GetExecutionContext(context), File.OpenRead(path.ConvertToString()), "r")) Each(context, io, block, separator); } @@ -123,10 +123,11 @@ } private static RubyIO OpenFileForRead(CodeContext/*!*/ context, MutableString/*!*/ path) { - if (!File.Exists(path)) { - throw new Errno.NoEntryError(String.Format("No such file or directory - {0}", path)); + string strPath = path.ConvertToString(); + if (!File.Exists(strPath)) { + throw new Errno.NoEntryError(String.Format("No such file or directory - {0}", strPath)); } - return new RubyIO(RubyUtils.GetExecutionContext(context), File.OpenRead(path), "r"); + return new RubyIO(RubyUtils.GetExecutionContext(context), File.OpenRead(strPath), "r"); } //pipe @@ -184,7 +185,7 @@ [RubyMethod("readlines", RubyMethodAttributes.PublicSingleton)] public static List ReadLines(CodeContext/*!*/ context, RubyClass/*!*/ self, MutableString path, MutableString separator) { - using (RubyIO io = new RubyIO(RubyUtils.GetExecutionContext(context), File.OpenRead(path), "r")) { + using (RubyIO io = new RubyIO(RubyUtils.GetExecutionContext(context), File.OpenRead(path.ConvertToString()), "r")) { return ReadLines(context, io, separator); } } @@ -304,13 +305,13 @@ } int separatorOffset = 0; - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); char? c; while ((c = self.GetChar()) != null) { - result.Append(c); + result.Append(c.Value); - if (separator != null && c == separator.Chars[separatorOffset]) { + if (separator != null && c == separator.GetChar(separatorOffset)) { if (separatorOffset == separator.Length - 1) break; separatorOffset++; @@ -369,45 +370,56 @@ } [RubyMethod("print")] - public static object Print(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull] string/*!*/ val) { + public static object Print(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull]string/*!*/ val) { return LibrarySites.InvokeWrite(context, self, val); } [RubyMethod("print")] - public static object Print(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull] MutableString/*!*/ val) { + public static object Print(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull]MutableString/*!*/ val) { return LibrarySites.InvokeWrite(context, self, val); } [RubyMethod("print")] - public static object Print(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull] params object[]/*!*/ args) { + public static object Print(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull]params object[]/*!*/ args) { MutableString delimiter = RubyUtils.GetExecutionContext(context).OutputSeparator; object result = null; for (int i = 0; i < args.Length; i++) { - string str = ToPrintedString(context, args[i]); - result = Print(context, self, delimiter == null ? str : str + delimiter); + MutableString str = ToPrintedString(context, args[i]); + if (delimiter != null) { + str.Append(delimiter); + } + result = Print(context, self, str); } return result; } //printf [RubyMethod("putc")] - public static MutableString/*!*/ Putc(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull] string/*!*/ val) { - return Putc(context, self, new MutableString(val)); + public static MutableString/*!*/ Putc(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull]string/*!*/ val) { + if (val.Length == 0) { + throw RubyExceptions.CreateTypeError("can't convert String into Integer"); + } + MutableString c = MutableString.CreateMutable(1).Append(val[0]); + LibrarySites.InvokeWrite(context, self, c); + return c; } [RubyMethod("putc")] - public static MutableString/*!*/ Putc(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull] MutableString/*!*/ val) { - if (val.Length == 0) + public static MutableString/*!*/ Putc(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull]MutableString/*!*/ val) { + if (val.Length == 0) { throw RubyExceptions.CreateTypeError("can't convert String into Integer"); - - LibrarySites.InvokeWrite(context, self, val[0]); - return val; + } + MutableString c = val.GetSlice(0, 1); + LibrarySites.InvokeWrite(context, self, c); + return c; } [RubyMethod("putc")] - public static int Putc(CodeContext/*!*/ context, RubyIO/*!*/ self, int chr) { - LibrarySites.InvokeWrite(context, self, Convert.ToChar(chr)); - return chr; + public static int Putc(CodeContext/*!*/ context, RubyIO/*!*/ self, int c) { + // TODO: + MutableString str = MutableString.CreateBinary(1).Append(unchecked((byte)c)); + LibrarySites.InvokeWrite(context, self, str); + return c; } [RubyMethod("putc")] @@ -415,8 +427,8 @@ return Putc(context, self, (int)Protocols.CastToInteger(context, obj)); } - public static string/*!*/ ToPrintedString(CodeContext/*!*/ context, object obj) { - MutableString str = new MutableString(); + public static MutableString/*!*/ ToPrintedString(CodeContext/*!*/ context, object obj) { + MutableString str = MutableString.CreateMutable(); List list = obj as List; IDictionary hash; @@ -430,15 +442,15 @@ str.Append((bool)obj ? "true" : "false"); } else if (obj is double) { if ((double)(int)(double)obj == (double)obj) { - str.Append(obj); + str.Append(obj.ToString()); str.Append(".0"); } else { - str.Append(obj); + str.Append(obj.ToString()); } } else { str.Append(RubySites.ToS(context, obj)); } - return str.ToString(); + return str; } [RubyMethod("puts")] @@ -447,24 +459,20 @@ } [RubyMethod("puts")] - public static object Puts(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull] string/*!*/ val) { - if (!val.EndsWith("\n")) - val += "\n"; + public static object Puts(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull]MutableString/*!*/ val) { + if (!val.EndsWith('\n')) { + val = MutableString.Create(val).Append('\n'); + } return LibrarySites.InvokeWrite(context, self, val); } [RubyMethod("puts")] - public static object Puts(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull] MutableString/*!*/ val) { - return Puts(context, self, val.ToString()); - } - - [RubyMethod("puts")] - public static object Puts(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull] object/*!*/ val) { + public static object Puts(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull]object/*!*/ val) { return Puts(context, self, ToPrintedString(context, val)); } [RubyMethod("puts")] - public static object Puts(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull] params object[]/*!*/ vals) { + public static object Puts(CodeContext/*!*/ context, RubyIO/*!*/ self, [NotNull]params object[]/*!*/ vals) { object result = null; for (int i = 0; i < vals.Length; ++i) result = Puts(context, self, vals[i]); @@ -480,10 +488,11 @@ buffer.Clear(); for (int i = 0; i < bytes; ++i) { char? c = self.GetChar(); - if (c == null) + if (c == null) { return buffer; - else - buffer.Append(c); + } else { + buffer.Append(c.Value); + } } return buffer; } @@ -491,16 +500,17 @@ [RubyMethod("read")] public static MutableString Read(CodeContext/*!*/ context, RubyIO/*!*/ self, int bytes) { self.AssertOpenedForReading(); - return Read(context, self, bytes, new MutableString()); + return Read(context, self, bytes, MutableString.CreateMutable()); } [RubyMethod("read")] public static MutableString Read(CodeContext/*!*/ context, RubyIO/*!*/ self) { self.AssertOpenedForReading(); - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); char? c; - while ((c = self.GetChar()) != null) - result.Append(c); + while ((c = self.GetChar()) != null) { + result.Append(c.Value); + } return result; } @@ -600,25 +610,13 @@ //ungetc [RubyMethod("write")] - public static int Write(RubyIO/*!*/ self, char val) { + public static int Write(RubyIO/*!*/ self, [NotNull]MutableString/*!*/ val) { self.AssertOpenedForWriting(); self.Write(val); - return 1; - } - - [RubyMethod("write")] - public static int Write(RubyIO/*!*/ self, [NotNull] string/*!*/ val) { - self.AssertOpenedForWriting(); - self.Write(val); return val.Length; } [RubyMethod("write")] - public static int Write(RubyIO/*!*/ self, [NotNull] MutableString/*!*/ val) { - return Write(self, val.ToString()); - } - - [RubyMethod("write")] public static int Write(CodeContext/*!*/ context, RubyIO/*!*/ self, object/*!*/ obj) { // TODO: make a ConvertToString and make this call it return Write(self, Protocols.ConvertToString(context, obj)); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C434537 File: Kernel.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C434537 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;MutableString5 @@ -152,7 +152,7 @@ [RubyMethod("exit", RubyMethodAttributes.PrivateInstance)] [RubyMethod("exit", RubyMethodAttributes.PublicSingleton)] public static void Exit(CodeContext/*!*/ context, object self, int exitCode) { - throw new SystemExit(exitCode, new MutableString("exit")); + throw new SystemExit(exitCode, "exit"); } [RubyMethod("exit!", RubyMethodAttributes.PrivateInstance)] @@ -192,7 +192,7 @@ RubyArray arguments = ec.InputProvider.CommandLineArguments; // TODO: - MutableString result = new MutableString(""); + MutableString result = MutableString.Create(""); scope.LastInputLine = result; @@ -210,7 +210,7 @@ foreach (KeyValuePair global in ec.GlobalVariables) { if (global.Value.IsEnumerated) { // TODO: Ruby 1.9 returns symbols: - result.Add(new MutableString(SymbolTable.IdToString(global.Key))); + result.Add(MutableString.Create(SymbolTable.IdToString(global.Key))); } } } @@ -237,13 +237,13 @@ [RubyMethod("load", RubyMethodAttributes.PrivateInstance)] [RubyMethod("load", RubyMethodAttributes.PublicSingleton)] public static bool Load(CodeContext/*!*/ context, object self, MutableString/*!*/ libraryName) { - return RubyUtils.GetExecutionContext(context).Loader.LoadModule(context, self, libraryName, LoadFlags.None); + return RubyUtils.GetExecutionContext(context).Loader.LoadModule(context, self, libraryName.ConvertToString(), LoadFlags.None); } [RubyMethod("load", RubyMethodAttributes.PrivateInstance)] [RubyMethod("load", RubyMethodAttributes.PublicSingleton)] public static bool Load(CodeContext/*!*/ context, object self, MutableString/*!*/ libraryName, bool wrap) { - return RubyUtils.GetExecutionContext(context).Loader.LoadModule(context, self, libraryName, wrap ? LoadFlags.LoadIsolated : LoadFlags.None); + return RubyUtils.GetExecutionContext(context).Loader.LoadModule(context, self, libraryName.ConvertToString(), wrap ? LoadFlags.LoadIsolated : LoadFlags.None); } [RubyMethod("local_variables", RubyMethodAttributes.PrivateInstance)] @@ -254,7 +254,7 @@ RubyArray result = new RubyArray(symbols.Count); for (int i = 0; i < symbols.Count; i++) { - result.Add(new MutableString(symbols[i])); + result.Add(MutableString.Create(symbols[i])); } return result; } @@ -289,13 +289,13 @@ [RubyMethod("putc", RubyMethodAttributes.PrivateInstance)] [RubyMethod("putc", RubyMethodAttributes.PublicSingleton)] - public static void Putc(CodeContext/*!*/ context, object/*!*/ self, [NotNull]object arg) { + public static void Putc(CodeContext/*!*/ context, object self, [NotNull]object arg) { LibrarySites.InvokePutc(context, RubyUtils.GetExecutionContext(context).StandardOutput, arg); } [RubyMethod("puts", RubyMethodAttributes.PrivateInstance)] [RubyMethod("puts", RubyMethodAttributes.PublicSingleton)] - public static void PutString(CodeContext/*!*/ context, object/*!*/ self, [NotNull]params object[] args) { + public static void PutString(CodeContext/*!*/ context, object self, [NotNull]params object[]/*!*/ args) { LibrarySites.InvokePuts(context, RubyUtils.GetExecutionContext(context).StandardOutput, new List(args)); } @@ -407,7 +407,7 @@ str = RubySites.ToStr(context, format); } - return new StringFormatter(context, str, args).Format(); + return new StringFormatter(context, str.ConvertToString(), args).Format(); } //srand @@ -665,7 +665,7 @@ RubyArray result = new RubyArray(symbols.Length); foreach (SymbolId id in symbols) { - result.Add(new MutableString(id)); + result.Add(MutableString.Create(id)); } return result; } @@ -833,7 +833,7 @@ [RubyMethod("require")] [RubyMethod("require", RubyMethodAttributes.PublicSingleton)] public static bool Require(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ libraryName) { - return RubyUtils.GetExecutionContext(context).Loader.LoadModule(context, self, libraryName.ToString(), LoadFlags.LoadOnce); + return RubyUtils.GetExecutionContext(context).Loader.LoadModule(context, self, libraryName.ConvertToString(), LoadFlags.LoadOnce); } #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/LibrarySites.cs;C429806 File: LibrarySites.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/LibrarySites.cs;C429806 (server) 5/8/2008 3:39 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/LibrarySites.cs;MutableString5 @@ -197,9 +197,9 @@ return _PrecSite.Invoke(context, value, klass); } - private static DynamicSite _MatchSite = DynamicSite.Create( + private static DynamicSite _MatchSite = DynamicSite.Create( InstanceCallAction("match", ArgumentKind.Simple)); - public static object InvokeMatch(CodeContext/*!*/ context, Regexp regex, MutableString str) { + public static object InvokeMatch(CodeContext/*!*/ context, RubyRegex regex, MutableString str) { return _MatchSite.Invoke(context, regex, str); } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MatchDataOps.cs;C417565 File: MatchDataOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MatchDataOps.cs;C417565 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MatchDataOps.cs;MutableString5 @@ -39,7 +39,7 @@ [RubyMethod("[]")] public static MutableString GetGroup(Match/*!*/ self, int i) { i = IListOps.NormalizeIndex(self.Groups.Count, i); - return (i >= 0 && i < self.Groups.Count) ? new MutableString(self.Groups[i].Value) : null; + return (i >= 0 && i < self.Groups.Count) ? MutableString.Create(self.Groups[i].Value) : null; } [RubyMethod("[]")] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C434537 File: ModuleOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C434537 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;MutableString5 @@ -555,7 +555,7 @@ RubyArray result = new RubyArray(); self.ForEachClassVariable(true, delegate(RubyModule/*!*/ module, SymbolId name, object value) { if (!name.IsEmpty && !visited.ContainsKey(name)) { - result.Add(new MutableString(name)); + result.Add(MutableString.Create(name)); visited.Add(name, true); } return false; @@ -627,7 +627,7 @@ if (!visited.ContainsKey(name)) { visited.Add(name, true); - result.Add(new MutableString(name)); + result.Add(MutableString.Create(name)); } return false; }); @@ -728,7 +728,7 @@ } else if (method.IsUndefined) { visited.Add(name, true); } else if (((RubyMethodAttributes)method.Visibility & attributes) != 0 && !visited.ContainsKey(name)) { - result.Add(new MutableString(name)); + result.Add(MutableString.Create(name)); visited.Add(name, true); } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C428766 File: MutableStringOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;C428766 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/MutableStringOps.cs;MutableString5 @@ -49,6 +49,16 @@ [Includes(typeof(Enumerable), typeof(Comparable))] public class MutableStringOps { + [RubyConstructor] + public static MutableString/*!*/ Create(CodeContext/*!*/ context) { + return MutableString.CreateMutable(); + } + + [RubyConstructor] + public static MutableString/*!*/ Create(CodeContext/*!*/ context, [NotNull]MutableString/*!*/ str) { + return MutableString.Create(str); + } + #region Helpers private static readonly DynamicSite/*!*/ @@ -86,23 +96,23 @@ // \x00-0xDD # all characters in hex range public class IntervalParser { - private string _range; + private readonly MutableString/*!*/ _range; private int _pos; private bool _rangeStarted; private char _startRange; - public IntervalParser(string range) { + public IntervalParser(MutableString/*!*/ range) { _range = range; _pos = 0; _rangeStarted = false; } public char? PeekChar() { - return _pos >= _range.Length ? (char?)null : _range[_pos]; + return _pos >= _range.Length ? (char?)null : _range.GetChar(_pos); } public char? GetChar() { - return _pos >= _range.Length ? (char?)null : _range[_pos++]; + return _pos >= _range.Length ? (char?)null : _range.GetChar(_pos++); } public int HexToInt(char? c) { @@ -168,15 +178,15 @@ public MutableString/*!*/ ParseSequence() { _pos = 0; - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); if (_range.Length == 0) return result; bool negate = false; - if (_range[0] == '^') { + if (_range.GetChar(0) == '^') { // Special case of ^ if (_range.Length == 1) { - result.Append("^"); + result.Append('^'); return result; } @@ -193,10 +203,11 @@ // _startRange - c. ignore ranges which are the reverse sequence if (_startRange <= c) { for (int i = _startRange; i <= c; ++i) { - if (negate) + if (negate) { array.Set(i, false); - else + } else { result.Append((char)i); + } } } _rangeStarted = false; @@ -209,7 +220,7 @@ array.Set((char)c, false); array.Set('-', false); } else { - result.Append(c); + result.Append(c.Value); result.Append('-'); } break; @@ -217,20 +228,22 @@ _startRange = (char)c; if (_rangeStarted) { - if (negate) + if (negate) { array.Set('-', false); - else + } else { result.Append('-'); + } _rangeStarted = false; } else { _rangeStarted = true; } _pos++; // consume - } else { - if (negate) + if (negate) { array.Set((char)c, false); - else - result.Append(c); + } else { + result.Append(c.Value); + } } } } @@ -253,7 +266,7 @@ return result; bool negate = false; - if (_range[0] == '^') { + if (_range.GetChar(0) == '^') { // Special case of ^ if (_range.Length == 1) { result.Set('^', true); @@ -304,9 +317,9 @@ public class RangeParser { - private string[]/*!*/ _ranges; + private readonly MutableString[]/*!*/ _ranges; - public RangeParser(params string[]/*!*/ ranges) { + public RangeParser(params MutableString[]/*!*/ ranges) { ContractUtils.RequiresNotNull(ranges, "ranges"); _ranges = ranges; } @@ -365,7 +378,7 @@ if (args == null) { args = new object[] { arg }; } - StringFormatter formatter = new StringFormatter(context, self, args); + StringFormatter formatter = new StringFormatter(context, self.ConvertToString(), args); return Kernel.FlowTaint(context, self, formatter.Format()); } @@ -374,24 +387,22 @@ #region * [RubyMethod("*")] - public static MutableString Repeat(MutableString/*!*/ self, int times) { - if (times < 0) + public static MutableString/*!*/ Repeat(CodeContext/*!*/ context, MutableString/*!*/ self, int times) { + if (times < 0) { throw RubyExceptions.CreateArgumentError("negative argument"); + } - if (times == 0) { - self.Clear(); - } else { - string current = self.Chars.ToString(); - for (int i = 0; i < times - 1; ++i) - self.Append(current); + MutableString result = MutableString.CreateMutable(); + for (int i = 0; i < times; i++) { + result.Append(self); } - return self; + return Kernel.FlowTaint(context, self, CreateSubClass(context, self, result)); } [RubyMethod("*")] public static MutableString Repeat(CodeContext/*!*/ context, MutableString/*!*/ self, object times) { - return Repeat(self, Protocols.CastToFixnum(context, times)); + return Repeat(context, self, Protocols.CastToFixnum(context, times)); } #endregion @@ -408,7 +419,7 @@ [RubyMethod("+")] public static MutableString Concatenate(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]MutableString/*!*/ other) { - return Kernel.FlowTaint(context, self, other, new MutableString(self).Append(other)); + return Kernel.FlowTaint(context, self, other, MutableString.Create(self).Append(other)); } [RubyMethod("+")] @@ -547,7 +558,7 @@ #region slice! - private static Group MatchRegexp(CodeContext/*!*/ context, MutableString/*!*/ self, Regexp regex, int occurrance) { + private static Group MatchRegexp(CodeContext/*!*/ context, MutableString/*!*/ self, RubyRegex regex, int occurrance) { Match match = RegexpOps.Match(context, regex, self); if (match == null || !match.Success) return null; @@ -568,12 +579,14 @@ [RubyMethod("slice!")] public static object RemoveCharInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, int index) { - if (!InRangeNormalized(self, ref index)) + if (!InRangeNormalized(self, ref index)) { return null; + } Kernel.RequiresNotFrozen(context, self); - object result = (object)(int)self[index]; + // TODO: optimize if the value is not read: + int result = self.PeekByte(index); self.Remove(index, 1); return result; } @@ -597,7 +610,7 @@ length = self.Length - start; } - MutableString result = CreateSubClass(context, self, self.Substring(start, length)); + MutableString result = CreateSubClass(context, self, self.GetSlice(start, length)); self.Remove(start, length); return Kernel.FlowTaint(context, self, result); } @@ -632,40 +645,45 @@ } [RubyMethod("slice!")] - public static MutableString RemoveCharInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex) { - if (regex.Regex.ToString() == String.Empty) + public static MutableString RemoveCharInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex) { + if (regex.IsEmpty) { return Kernel.FlowTaint(context, self, regex, CreateSubClass(context, self)); + } Match match = RegexpOps.Match(context, regex, self); - if (match == null || !match.Success) + if (match == null || !match.Success) { return null; + } return Kernel.FlowTaint(context, regex, RemoveCharInPlace(context, self, match.Index, match.Length)); } [RubyMethod("slice!")] - public static MutableString RemoveCharInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex, int occurrance) { - if (regex.Regex.ToString() == String.Empty) + public static MutableString RemoveCharInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex, int occurrance) { + if (regex.IsEmpty) { return Kernel.FlowTaint(context, self, regex, CreateSubClass(context, self)); + } Group group = MatchRegexp(context, self, regex, occurrance); return group == null ? null : Kernel.FlowTaint(context, regex, RemoveCharInPlace(context, self, group.Index, group.Length)); } [RubyMethod("slice!")] - public static MutableString RemoveCharInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex, [NotNull]object/*!*/ occurrance) { + public static MutableString RemoveCharInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex, [NotNull]object/*!*/ occurrance) { return RemoveCharInPlace(context, self, regex, Protocols.CastToFixnum(context, occurrance)); } [RubyMethod("slice!")] public static MutableString RemoveCharInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]MutableString/*!*/ searchStr) { // Odd behavior: taint only flows from searchStr and *not* self. Seems like a bug in Ruby to me. - if (searchStr.Length == 0) + if (searchStr.Length == 0) { return Kernel.FlowTaint(context, searchStr, CreateSubClass(context, self)); + } - int index = self.ToString().IndexOf(searchStr); - if (index < 0) + int index = self.IndexOf(searchStr); + if (index < 0) { return null; + } RemoveCharInPlace(context, self, index, searchStr.Length); return Kernel.FlowTaint(context, searchStr, CreateSubClass(context, searchStr, searchStr)); @@ -678,7 +696,7 @@ [RubyMethod("[]")] [RubyMethod("slice")] public static object GetChar(MutableString/*!*/ self, int index) { - return InRangeNormalized(self, ref index) ? (object)(int)self[index] : null; + return InRangeNormalized(self, ref index) ? (object)(int)self.GetByte(index) : null; } [RubyMethod("[]")] @@ -701,7 +719,7 @@ if (start + length > self.Length) length = self.Length - start; - return Kernel.FlowTaint(context, self, CreateSubClass(context, self, self.Substring(start, length))); + return Kernel.FlowTaint(context, self, CreateSubClass(context, self, self.GetSlice(start, length))); } [RubyMethod("[]")] @@ -740,36 +758,43 @@ [RubyMethod("[]")] [RubyMethod("slice")] public static MutableString GetChars(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]MutableString/*!*/ searchStr) { - return self.ToString().Contains(searchStr.ToString()) ? Kernel.FlowTaint(context, self, searchStr, CreateSubClass(context, searchStr, searchStr)) : null; + if (self.IndexOf(searchStr) != -1) { + return Kernel.FlowTaint(context, self, searchStr, CreateSubClass(context, searchStr, searchStr)); + } else { + return null; + } } [RubyMethod("[]")] [RubyMethod("slice")] - public static MutableString GetChars(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex) { - if (regex.Regex.ToString() == String.Empty) + public static MutableString GetChars(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex) { + if (regex.IsEmpty) { return Kernel.FlowTaint(context, self, regex, CreateSubClass(context, self)); + } Match match = RegexpOps.Match(context, regex, self); - if (match == null) + if (match == null) { return null; + } string result = match.Value; - return result == String.Empty ? null : Kernel.FlowTaint(context, self, regex, CreateSubClass(context, self, new MutableString(result))); + return result == String.Empty ? null : Kernel.FlowTaint(context, self, regex, CreateSubClass(context, self, MutableString.Create(result))); } [RubyMethod("[]")] [RubyMethod("slice")] - public static MutableString GetChars(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex, int occurrance) { - if (regex.Regex.ToString() == String.Empty) + public static MutableString GetChars(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex, int occurrance) { + if (regex.IsEmpty) { return Kernel.FlowTaint(context, self, regex, CreateSubClass(context, self)); + } Group group = MatchRegexp(context, self, regex, occurrance); - return group == null ? null : Kernel.FlowTaint(context, self, regex, CreateSubClass(context, self, new MutableString(group.Value))); + return group == null ? null : Kernel.FlowTaint(context, self, regex, CreateSubClass(context, self, MutableString.Create(group.Value))); } [RubyMethod("[]")] [RubyMethod("slice")] - public static MutableString GetChars(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex, object occurrance) { + public static MutableString GetChars(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex, object occurrance) { return GetChars(context, self, regex, Protocols.CastToFixnum(context, occurrance)); } @@ -779,7 +804,7 @@ public static MutableString/*!*/ RemoveChar(MutableString/*!*/ self, int index) { self.Remove(index, 1); - return new MutableString(); + return MutableString.CreateMutable(); } [RubyMethod("[]=")] @@ -795,8 +820,8 @@ return RemoveChar(self, index); } - self[index] = value[value.Length - 1]; - self.Insert(index, value.Substring(0, value.Length - 1)); + self.Replace(index, 1, value); + Kernel.FlowTaint(context, value, self); return value; } @@ -806,10 +831,11 @@ Kernel.RequiresNotFrozen(context, self); index = index < 0 ? index + self.Length : index; - if (index < 0 || index >= self.Length) + if (index < 0 || index >= self.Length) { throw RubyExceptions.CreateIndexError(String.Format("index {0} out of string", index)); + } - self[index] = (char)((int)value & 0xFF); + self.SetByte(index, unchecked((byte)value)); return value; } @@ -833,7 +859,8 @@ } [RubyMethod("[]=")] - public static MutableString SetChar(CodeContext/*!*/ context, MutableString/*!*/ self, int start, int charsToOverwrite, [NotNull]MutableString/*!*/ value) { + public static MutableString SetChar(CodeContext/*!*/ context, MutableString/*!*/ self, int start, int charsToOverwrite, + [NotNull]MutableString/*!*/ value) { Kernel.RequiresNotFrozen(context, self); if (charsToOverwrite < 0) @@ -852,18 +879,15 @@ insertIndex = self.Length; } - for (int i = 0; i < limit; ++i) - self[start + i] = value[i]; - - Insert(context, self, insertIndex, value.Substring(limit)); + self.Replace(start, limit, value); } else { int deleteIndex = start + value.Length; int limit = value.Length; if (deleteIndex > self.Length) { + // TODO: ??? } - for (int i = 0; i < value.Length; ++i) - self[start + i] = value[i]; + self.Replace(start, value.Length, value); int pos = start + value.Length; int charsToRemove = charsToOverwrite - value.Length; @@ -901,30 +925,30 @@ #region casecmp, capitalize, capitalize!, downcase, downcase!, swapcase, swapcase!, upcase, upcase! public static bool UpCaseChar(MutableString/*!*/ self, int index) { - char current = self.Chars[index]; + char current = self.GetChar(index); if (current >= 'a' && current <= 'z') { - self.Chars[index] = Char.ToUpper(current); + self.SetChar(index, Char.ToUpper(current)); return true; } return false; } public static bool DownCaseChar(MutableString/*!*/ self, int index) { - char current = self.Chars[index]; + char current = self.GetChar(index); if (current >= 'A' && current <= 'Z') { - self.Chars[index] = Char.ToLower(current); + self.SetChar(index, Char.ToLower(current)); return true; } return false; } public static bool SwapCaseChar(MutableString/*!*/ self, int index) { - char current = self.Chars[index]; + char current = self.GetChar(index); if (current >= 'A' && current <= 'Z') { - self.Chars[index] = Char.ToLower(current); + self.SetChar(index, Char.ToLower(current)); return true; } else if (current >= 'a' && current <= 'z') { - self.Chars[index] = Char.ToUpper(current); + self.SetChar(index, Char.ToUpper(current)); return true; } return false; @@ -992,7 +1016,7 @@ [RubyMethod("capitalize")] public static MutableString/*!*/ Capitalize(CodeContext/*!*/ context, MutableString/*!*/ self) { - MutableString result = new MutableString(self); + MutableString result = MutableString.Create(self); CapitalizeMutableString(result); return Kernel.FlowTaint(context, self, CreateSubClass(context, self, result)); } @@ -1014,7 +1038,7 @@ [RubyMethod("downcase")] public static MutableString/*!*/ DownCase(CodeContext/*!*/ context, MutableString/*!*/ self) { - MutableString result = new MutableString(self); + MutableString result = MutableString.Create(self); DownCaseMutableString(result); return Kernel.FlowTaint(context, self, CreateSubClass(context, self, result)); } @@ -1037,7 +1061,7 @@ [RubyMethod("swapcase")] public static MutableString/*!*/ SwapCase(CodeContext/*!*/ context, MutableString/*!*/ self) { - MutableString result = new MutableString(self); + MutableString result = MutableString.Create(self); SwapCaseMutableString(result); return Kernel.FlowTaint(context, self, CreateSubClass(context, self, result)); } @@ -1059,7 +1083,7 @@ [RubyMethod("upcase")] public static MutableString/*!*/ UpCase(CodeContext/*!*/ context, MutableString/*!*/ self) { - MutableString result = new MutableString(self); + MutableString result = MutableString.Create(self); UpCaseMutableString(result); return Kernel.FlowTaint(context, self, CreateSubClass(context, self, result)); } @@ -1081,21 +1105,25 @@ return self; } if (padding == null) { - padding = new MutableString(" "); + padding = MutableString.Create(" "); } + char[] charArray = new char[length]; int n = (length - self.Length) / 2; + for (int i = 0; i < n; i++) { - charArray[i] = padding[(i % padding.Length)]; + charArray[i] = padding.GetChar(i % padding.Length); } + for (int i = 0; i < self.Length; i++) { - charArray[n + i] = self[i]; + charArray[n + i] = self.GetChar(i); } + int m = length - self.Length - n; for (int i = 0; i < m; i++) { - charArray[n + self.Length + i] = padding[(i % padding.Length)]; + charArray[n + self.Length + i] = padding.GetChar(i % padding.Length); } - return new MutableString(new string(charArray)); + return MutableString.Create(new string(charArray)); } //----------------------------------------------------------- String#chomp @@ -1122,11 +1150,21 @@ if (offset < 0) { return false; } - for (int i = 0; i < terminator.Length; i++) { - if (str[offset + i] != terminator[i]) { - return false; + + if (str.IsBinary) { + for (int i = 0; i < terminator.Length; i++) { + if (str.GetChar(offset + i) != terminator.GetChar(i)) { + return false; + } } + } else { + for (int i = 0; i < terminator.Length; i++) { + if (str.GetByte(offset + i) != terminator.GetByte(i)) { + return false; + } + } } + return true; } @@ -1134,16 +1172,16 @@ int end = str.Length; while (true) { if (end > 1) { - if (str[end - 1] == '\n') { - end -= str[end - 2] == '\r' ? 2 : 1; - } else if (removeCarriageReturnsToo && str[end - 1] == '\r') { + if (str.GetChar(end - 1) == '\n') { + end -= str.GetChar(end - 2) == '\r' ? 2 : 1; + } else if (removeCarriageReturnsToo && str.GetChar(end - 1) == '\r') { end -= 1; } else { break; } } else if (end > 0) { - if (str[end - 1] == '\n' || str[end - 1] == '\r') { + if (str.GetChar(end - 1) == '\n' || str.GetChar(end - 1) == '\r') { end -= 1; } break; @@ -1151,7 +1189,7 @@ break; } } - return str.Substring(0, end); + return str.GetSlice(0, end); } private static MutableString InternalChomp(CodeContext/*!*/ context, MutableString/*!*/ self, MutableString separator) { @@ -1163,12 +1201,12 @@ return Kernel.FlowTaint(context, self, ChompTrailingCarriageReturns(self, false)); // Remove single trailing CR/LFs - MutableString result = Kernel.FlowTaint(context, self, CreateSubClass(context, self, new MutableString(self))); + MutableString result = Kernel.FlowTaint(context, self, CreateSubClass(context, self, MutableString.Create(self))); int length = result.Length; - if (separator.Length == 1 && separator[0] == '\n') { - if (length > 1 && result[length - 2] == '\r' && result[length - 1] == '\n') { + if (separator.Length == 1 && separator.GetChar(0) == '\n') { + if (length > 1 && result.GetChar(length - 2) == '\r' && result.GetChar(length - 1) == '\n') { result.Remove(length - 2, 2); - } else if (length > 0 && (self[length - 1] == '\n' || result[length - 1] == '\r')) { + } else if (length > 0 && (self.GetChar(length - 1) == '\n' || result.GetChar(length - 1) == '\r')) { result.Remove(length - 1, 1); } } else if (EndsWith(result, separator)) { @@ -1235,7 +1273,7 @@ // "x".chop.chop #=> "" private static MutableString Chop(MutableString/*!*/ self) { - if (self.Length == 1 || self[self.Length - 2] != '\r' || self[self.Length - 1] != '\n') { + if (self.Length == 1 || self.GetChar(self.Length - 2) != '\r' || self.GetChar(self.Length - 1) != '\n') { self.Remove(self.Length - 1, 1); } else { self.Remove(self.Length - 2, 2); @@ -1252,7 +1290,7 @@ [RubyMethod("chop")] public static MutableString Chop(CodeContext/*!*/ context, MutableString/*!*/ self) { - MutableString result = self.Length == 0 ? new MutableString() : Chop(new MutableString(self)); + MutableString result = self.Length == 0 ? MutableString.CreateMutable() : Chop(MutableString.Create(self)); return Kernel.FlowTaint(context, self, CreateSubClass(context, self, result)); } @@ -1294,19 +1332,20 @@ case '#': return "\\#"; default: - if (c < 32 || c > 126) + if (c < 32 || c > 126) { return GetOctalRepresentationOfChar(c); - else + } else { return c.ToString(); + } } } [RubyMethod("dump")] [RubyMethod("inspect")] public static MutableString/*!*/ Dump(CodeContext/*!*/ context, MutableString/*!*/ self) { - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); result.Append("\""); - foreach (char c in self.ToString()) { + foreach (char c in self.ConvertToString()) { result.Append(GetStringRepresentationOfChar(c)); } result.Append("\""); @@ -1336,7 +1375,7 @@ int i = 0; while (i < str.Length) { - object result = EachByteSharedSite.Invoke(context, block, str[i]); + object result = EachByteSharedSite.Invoke(context, block, str.GetByte(i)); if (block.BlockJumped(result)) return result; i++; } @@ -1381,14 +1420,16 @@ [RubyMethod("each_line")] public static object EachLine(CodeContext/*!*/ context, MutableString/*!*/ self, BlockParam block, [NotNull]MutableString/*!*/ separator) { bool paragraphMode = false; - string sep = separator; + MutableString sep = separator; if (separator.Length == 0) { paragraphMode = true; - sep = "\n"; + sep = MutableString.Create("\n"); } + MutableString doubleSep = (paragraphMode) ? MutableString.Create(sep).Append(sep) : null; + // TODO: this is slow, refactor when we redo MutableString - string str = self; + MutableString str = self; int start = 0; // In "normal" mode just split the string at the end of each seperator occurrance. @@ -1404,7 +1445,7 @@ end = str.Length; } } else { - end = str.IndexOf(sep + sep, start); + end = str.IndexOf(doubleSep, start); if (end >= 0) { end += (2 * sep.Length); while (str.IndexOf(sep, end) == end) { @@ -1416,7 +1457,7 @@ } // Yield the current line - MutableString line = new MutableString(str.Substring(start, end - start)); + MutableString line = MutableString.Create(str.GetSlice(start, end - start)); if (block.BlockJumped(_EachBlockSite.Invoke(context, block, Kernel.FlowTaint(context, self, CreateSubClass(context, self, line))))) return self; @@ -1525,19 +1566,19 @@ CallSiteFactory.CreateSimpleCallSite(RubyContext.RubyBinder); private static int InvokeReplaceBlock(Match/*!*/ match, MutableString/*!*/ self, MutableString/*!*/ result, CodeContext/*!*/ context, BlockParam/*!*/ block, int offset) { - object blockResult = ReplaceSharedSite.Invoke(context, block, new MutableString(match.Value)); + object blockResult = ReplaceSharedSite.Invoke(context, block, MutableString.Create(match.Value)); if (block.BlockJumped(blockResult)) throw RubyExceptions.CreateLocalJumpError("unexpected return"); Kernel.FlowTaint(context, self, blockResult, result); - result.Append(self.Substring(offset, match.Index - offset)); + result.Append(self.GetSlice(offset, match.Index - offset)); result.Append(Protocols.ConvertToString(context, blockResult)); return match.Index + match.Length; // return new offset } - private static object BlockReplaceN(CodeContext/*!*/ context, MutableString/*!*/ self, BlockParam/*!*/ block, Regexp/*!*/ pattern, int count, bool inPlace) { + private static MutableString/*!*/ BlockReplaceN(CodeContext/*!*/ context, MutableString/*!*/ self, BlockParam/*!*/ block, RubyRegex/*!*/ pattern, int count, bool inPlace) { MutableString result = CreateSubClass(context, self); RubyScope localScope = RubyUtils.GetScope(context); Match originalMatch = localScope.CurrentMatch; @@ -1557,7 +1598,7 @@ } } else if (count == -1) { try { - MatchCollection matches = pattern.Regex.Matches(self); + MatchCollection matches = pattern.Matches(self); if (matches.Count > 0 && inPlace) Kernel.RequiresNotFrozenRuntimeError(context, self); @@ -1573,11 +1614,11 @@ throw new ArgumentOutOfRangeException("count must be 1 or -1"); } - result.Append(self.Substring(offset, self.Length - offset)); // append remainder of string + result.Append(self.GetSlice(offset, self.Length - offset)); // append remainder of string return result; } - private static MutableString ReplaceN(CodeContext/*!*/ context, MutableString/*!*/ self, Regexp/*!*/ pattern, MutableString/*!*/ replacement, int count, bool inPlace) { + private static MutableString ReplaceN(CodeContext/*!*/ context, MutableString/*!*/ self, RubyRegex/*!*/ pattern, MutableString/*!*/ replacement, int count, bool inPlace) { MutableString result = CreateSubClass(context, self); Match match = null; int offset = 0; @@ -1586,7 +1627,7 @@ // case of 1 match = RegexpOps.Match(context, pattern, self); if (match != null) { - result.Append(self.Substring(0, match.Index - offset)); + result.Append(self.GetSlice(0, match.Index - offset)); if (match.Success) { if (inPlace) Kernel.RequiresNotFrozen(context, self); @@ -1596,12 +1637,12 @@ } } else if (count == -1) { // case of all - MatchCollection matches = pattern.Regex.Matches(self); + MatchCollection matches = pattern.Matches(self); if (matches.Count > 0 && inPlace) Kernel.RequiresNotFrozen(context, self); foreach (Match current in matches) { - result.Append(self.Substring(offset, current.Index - offset)); + result.Append(self.GetSlice(offset, current.Index - offset)); result.Append(replacement); offset = current.Index + current.Length; match = current; @@ -1611,27 +1652,27 @@ throw new ArgumentOutOfRangeException("count must be 1 or -1"); } - result.Append(self.Substring(offset, self.Length - offset)); + result.Append(self.GetSlice(offset, self.Length - offset)); return Kernel.FlowTaint(context, self, replacement, result); } [RubyMethod("sub")] - public static object BlockReplaceFirst(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]Regexp/*!*/ pattern) { + public static object BlockReplaceFirst(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]RubyRegex/*!*/ pattern) { return BlockReplaceN(context, self, block, pattern, 1, false); } [RubyMethod("gsub")] - public static object BlockReplaceAll(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]Regexp pattern) { + public static object BlockReplaceAll(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]RubyRegex pattern) { return BlockReplaceN(context, self, block, pattern, -1, false); } [RubyMethod("sub")] - public static MutableString ReplaceFirst(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ pattern, [NotNull]MutableString/*!*/ replacement) { + public static MutableString ReplaceFirst(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, [NotNull]MutableString/*!*/ replacement) { return ReplaceN(context, self, pattern, replacement, 1, false); } [RubyMethod("gsub")] - public static MutableString ReplaceAll(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ pattern, [NotNull]MutableString/*!*/ replacement) { + public static MutableString ReplaceAll(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, [NotNull]MutableString/*!*/ replacement) { return ReplaceN(context, self, pattern, replacement, -1, false); } @@ -1646,12 +1687,12 @@ } [RubyMethod("sub")] - public static MutableString ReplaceFirst(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ pattern, object/*!*/ replacement) { + public static MutableString ReplaceFirst(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, object/*!*/ replacement) { return ReplaceN(context, self, pattern, Protocols.CastToString(context, replacement), 1, false); } [RubyMethod("gsub")] - public static MutableString ReplaceAll(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ pattern, object/*!*/ replacement) { + public static MutableString ReplaceAll(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, object/*!*/ replacement) { return ReplaceN(context, self, pattern, Protocols.CastToString(context, replacement), -1, false); } @@ -1687,18 +1728,17 @@ // Performs the substitutions of +String#gsub+ in place, returning // _str_, or +nil+ if no substitutions were performed. - private static object ReplaceInPlaceN(CodeContext/*!*/ context, MutableString/*!*/ self, BlockParam/*!*/ block, Regexp/*!*/ pattern, int count) { - object result = BlockReplaceN(context, self, block, pattern, count, true); + private static object ReplaceInPlaceN(CodeContext/*!*/ context, MutableString/*!*/ self, BlockParam/*!*/ block, RubyRegex/*!*/ pattern, int count) { + MutableString result = BlockReplaceN(context, self, block, pattern, count, true); if (result.Equals(self)) { return null; } else { - self.Clear(); - self.Append(result); + self.Replace(0, self.Length, result); return Kernel.FlowTaint(context, result, self); } } - private static MutableString ReplaceInPlaceN(CodeContext/*!*/ context, MutableString/*!*/ self, Regexp/*!*/ pattern, MutableString/*!*/ replacement, int count) { + private static MutableString ReplaceInPlaceN(CodeContext/*!*/ context, MutableString/*!*/ self, RubyRegex/*!*/ pattern, MutableString/*!*/ replacement, int count) { MutableString result = ReplaceN(context, self, pattern, replacement, count, true); if (result.Equals(self)) { return null; @@ -1710,22 +1750,22 @@ } [RubyMethod("sub!")] - public static object BlockReplaceFirstInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]Regexp/*!*/ pattern) { + public static object BlockReplaceFirstInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]RubyRegex/*!*/ pattern) { return ReplaceInPlaceN(context, self, block, pattern, 1); } [RubyMethod("gsub!")] - public static object BlockReplaceAllInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]Regexp/*!*/ pattern) { + public static object BlockReplaceAllInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]RubyRegex/*!*/ pattern) { return ReplaceInPlaceN(context, self, block, pattern, -1); } [RubyMethod("sub!")] - public static MutableString ReplaceFirstInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ pattern, [NotNull]MutableString/*!*/ replacement) { + public static MutableString ReplaceFirstInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, [NotNull]MutableString/*!*/ replacement) { return ReplaceInPlaceN(context, self, pattern, replacement, 1); } [RubyMethod("gsub!")] - public static MutableString ReplaceAllInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ pattern, [NotNull]MutableString/*!*/ replacement) { + public static MutableString ReplaceAllInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, [NotNull]MutableString/*!*/ replacement) { return ReplaceInPlaceN(context, self, pattern, replacement, -1); } @@ -1740,12 +1780,12 @@ } [RubyMethod("sub!")] - public static MutableString ReplaceFirstInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ pattern, object/*!*/ replacement) { + public static MutableString ReplaceFirstInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, object/*!*/ replacement) { return ReplaceFirstInPlace(context, self, pattern, Protocols.CastToString(context, replacement)); } [RubyMethod("gsub!")] - public static MutableString ReplaceAllInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ pattern, object/*!*/ replacement) { + public static MutableString ReplaceAllInPlace(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, object/*!*/ replacement) { return ReplaceAllInPlace(context, self, pattern, Protocols.CastToString(context, replacement)); } @@ -1835,23 +1875,23 @@ } [RubyMethod("index")] - public static object Index(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex) { + public static object Index(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex) { Match match = RegexpOps.Match(context, regex, self); return (match != null && match.Success) ? (object)match.Index : null; } [RubyMethod("index")] - public static object Index(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex, int startAt) { + public static object Index(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex, int startAt) { startAt = NormalizeIndex(self, startAt); if (startAt < 0 || startAt > self.Length) return null; - Match match = regex.Regex.Match(self, startAt); + Match match = regex.Match(self, startAt); return match.Success ? (object)match.Index : null; } [RubyMethod("index")] - public static object Index(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex, object startAt) { + public static object Index(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex, object startAt) { return Index(context, self, regex, Protocols.CastToFixnum(context, startAt)); } @@ -1872,15 +1912,16 @@ #region delete private static MutableString/*!*/ InternalDelete(CodeContext/*!*/ context, MutableString/*!*/ self, params object[]/*!*/ str) { - string[] ranges = new string[str.Length]; + MutableString[] ranges = new MutableString[str.Length]; for (int i = 0; i < str.Length; i++) { ranges[i] = Protocols.CastToString(context, str[i]); } BitArray map = new RangeParser(ranges).Parse(); - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); for (int i = 0; i < self.Length; i++) { - if (!map.Get(self[i])) - result.Append(self[i]); + if (!map.Get(self.GetChar(i))) { + result.Append(self.GetChar(i)); + } } return Kernel.FlowTaint(context, self, result); } @@ -1951,14 +1992,14 @@ // TDOO: BitArray helper can be refactored private static object InternalCount(CodeContext/*!*/ context, MutableString/*!*/ self, params object[]/*!*/ str) { - string[] ranges = new string[str.Length]; + MutableString[] ranges = new MutableString[str.Length]; for (int i = 0; i < str.Length; i++) { ranges[i] = Protocols.CastToString(context, str[i]); } BitArray map = new RangeParser(ranges).Parse(); int count = 0; for (int i = 0; i < self.Length; i++) { - if (map.Get(self[i])) + if (map.Get(self.GetChar(i))) count++; } return RuntimeHelpers.Int32ToObject(count); @@ -1986,23 +2027,18 @@ #region include? [RubyMethod("include?")] - public static bool Include(MutableString/*!*/ str, string subString) { - return str.ToString().IndexOf(subString) != -1; - } - - [RubyMethod("include?")] public static bool Include(CodeContext/*!*/ context, MutableString/*!*/ str, object other) { return Include(str, Protocols.CastToString(context, other)); } [RubyMethod("include?")] public static bool Include(MutableString/*!*/ str, MutableString subString) { - return str.IndexOf(subString.ToString()) != -1; + return str.IndexOf(subString) != -1; } [RubyMethod("include?")] public static bool Include(MutableString/*!*/ str, int c) { - return str.ToString().IndexOf((char)(c % 256)) != -1; + return str.IndexOf((char)(c % 256)) != -1; } #endregion @@ -2060,7 +2096,7 @@ #region match [RubyMethod("=~")] - public static object Match(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex) { + public static object Match(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex) { return RegexpOps.MatchIndex(context, regex, self); } @@ -2078,14 +2114,14 @@ } [RubyMethod("match")] - public static object MatchRegexp(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull] Regexp/*!*/ regex) { + public static object MatchRegexp(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull] RubyRegex/*!*/ regex) { return LibrarySites.InvokeMatch(context, regex, self); } [RubyMethod("match")] public static object MatchObject(CodeContext/*!*/ context, MutableString/*!*/ self, object obj) { - Regex regex = new Regex(Protocols.CastToString(context, obj)); - return LibrarySites.InvokeMatch(context, new Regexp(regex), self); + RubyRegex regex = new RubyRegex(Protocols.CastToString(context, obj), RegexOptions.None); + return LibrarySites.InvokeMatch(context, regex, self); } #endregion @@ -2123,19 +2159,19 @@ #region scan [RubyMethod("scan")] - public static RubyArray/*!*/ Scan(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regex) { - MatchCollection matches = regex.Regex.Matches(self); + public static RubyArray/*!*/ Scan(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regex) { + MatchCollection matches = regex.Matches(self); RubyArray result = new RubyArray(matches.Count); if (matches.Count == 0) { RubyUtils.GetScope(context).CurrentMatch = null; } else { foreach (Match match in matches) { if (match.Groups.Count == 1) { - result.Add(Kernel.FlowTaint(context, self, regex, new MutableString(match.Value))); + result.Add(Kernel.FlowTaint(context, self, regex, MutableString.Create(match.Value))); } else { RubyArray m = new RubyArray(match.Groups.Count - 1); for (int i = 1; i < match.Groups.Count; i++) { - m.Add(Kernel.FlowTaint(context, self, regex, new MutableString(match.Groups[i].Value))); + m.Add(Kernel.FlowTaint(context, self, regex, MutableString.Create(match.Groups[i].Value))); } result.Add(m); } @@ -2147,7 +2183,7 @@ [RubyMethod("scan")] public static RubyArray/*!*/ Scan(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]MutableString/*!*/ search) { - return Scan(context, self, Kernel.FlowTaint(context, search, new Regexp(new Regex(Regex.Escape(search))))); + return Scan(context, self, Kernel.FlowTaint(context, search, new RubyRegex(RubyRegex.Escape(search), RegexOptions.None))); } [RubyMethod("scan")] @@ -2162,20 +2198,20 @@ DynamicSite.Create(CallAction.Make(RubyContext.RubyBinder, new CallSignature(ArgumentKind.List))); [RubyMethod("scan")] - public static object/*!*/ Scan(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]Regexp regex) { - MatchCollection matches = regex.Regex.Matches(self); + public static object/*!*/ Scan(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]RubyRegex regex) { + MatchCollection matches = regex.Matches(self); if (matches.Count == 0) { RubyUtils.GetScope(context).CurrentMatch = null; } else { foreach (Match match in matches) { if (match.Groups.Count == 1) { - if (block.BlockJumped(ScanStringSharedSite.Invoke(context, block, Kernel.FlowTaint(context, self, regex, new MutableString(match.Value))))) { + if (block.BlockJumped(ScanStringSharedSite.Invoke(context, block, Kernel.FlowTaint(context, self, regex, MutableString.Create(match.Value))))) { return self; } } else { RubyArray args = new RubyArray(match.Groups.Count - 1); for (int i = 1; i < match.Groups.Count; i++) { - args.Add(Kernel.FlowTaint(context, self, regex, new MutableString(match.Groups[i].Value))); + args.Add(Kernel.FlowTaint(context, self, regex, MutableString.Create(match.Groups[i].Value))); } if (block.BlockJumped(ScanRegexSharedSite.Invoke(context, block, args))) { return self; @@ -2189,7 +2225,7 @@ [RubyMethod("scan")] public static object/*!*/ Scan(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]BlockParam/*!*/ block, [NotNull]MutableString/*!*/ search) { - return Scan(context, self, block, Kernel.FlowTaint(context, search, new Regexp(new Regex(Regex.Escape(search))))); + return Scan(context, self, block, Kernel.FlowTaint(context, search, new RubyRegex(RubyRegex.Escape(search), RegexOptions.None))); } [RubyMethod("scan")] @@ -2228,7 +2264,7 @@ public static int GetIndexOfRightmostAlphaNumericCharacter(MutableString/*!*/ str, int index) { for (int i = index; i >= 0; --i) - if (Char.IsLetterOrDigit(str[i])) + if (Char.IsLetterOrDigit(str.GetChar(i))) return i; return -1; @@ -2236,23 +2272,23 @@ // TODO: remove recursion public static void IncrementAlphaNumericChar(MutableString/*!*/ str, int index) { - char c = str[index]; + char c = str.GetChar(index); if (c == 'z' || c == 'Z' || c == '9') { int nextIndex = GetIndexOfRightmostAlphaNumericCharacter(str, index - 1); if (c == 'z') { - str[index] = 'a'; + str.SetChar(index, 'a'); if (nextIndex == -1) str.Insert(index, "a"); else IncrementAlphaNumericChar(str, nextIndex); } else if (c == 'Z') { - str[index] = 'A'; + str.SetChar(index, 'A'); if (nextIndex == -1) str.Insert(index, "A"); else IncrementAlphaNumericChar(str, nextIndex); } else { - str[index] = '0'; + str.SetChar(index, '0'); if (nextIndex == -1) str.Insert(index, "1"); else @@ -2264,15 +2300,15 @@ } public static void IncrementChar(MutableString/*!*/ str, int index) { - byte c = (byte)str[index]; + byte c = unchecked((byte)str.GetChar(index)); if (c == 255) { - str[index] = (char)0; + str.SetChar(index, '\0'); if (index > 0) IncrementChar(str, index - 1); else str.Insert(0, "\u0001"); } else { - str[index] = ((char)(c + 1)); + str.SetChar(index, unchecked((char)(c + 1))); } } @@ -2294,7 +2330,7 @@ [RubyMethod("succ")] public static MutableString/*!*/ Succ(CodeContext/*!*/ context, MutableString/*!*/ self) { - return Kernel.FlowTaint(context, self, SuccInPlace(context, new MutableString(self))); + return Kernel.FlowTaint(context, self, SuccInPlace(context, MutableString.Create(self))); } #endregion @@ -2340,10 +2376,10 @@ #region split - private static RubyArray/*!*/ MakeRubyArray(CodeContext/*!*/ context, MutableString/*!*/ self, string[]/*!*/ elements) { + private static RubyArray/*!*/ MakeRubyArray(CodeContext/*!*/ context, MutableString/*!*/ self, MutableString[]/*!*/ elements) { RubyArray result = new RubyArray(elements.Length); - foreach (string element in elements) { - result.Add(Kernel.FlowTaint(context, self, CreateSubClass(context, self, new MutableString(element)))); + foreach (MutableString element in elements) { + result.Add(Kernel.FlowTaint(context, self, CreateSubClass(context, self, element))); } return result; } @@ -2359,43 +2395,31 @@ return index + 1; } - private static RubyArray/*!*/ WhitespaceSplit(CodeContext/*!*/ context, MutableString/*!*/ self, StringSplitOptions options, int maxComponents) { + private static RubyArray/*!*/ WhitespaceSplit(CodeContext/*!*/ context, MutableString/*!*/ self, int maxComponents) { char[] separators = new char[] { ' ', '\n', '\r', '\t', '\v' }; - bool keep_empty = (options & StringSplitOptions.RemoveEmptyEntries) != StringSplitOptions.RemoveEmptyEntries; + MutableString[] elements = self.Split(separators, (maxComponents < 0) ? Int32.MaxValue : maxComponents, StringSplitOptions.RemoveEmptyEntries); -#if SILVERLIGHT - string[] all = self.ToString().Split(separators); - string[] elements; - if (maxComponents == Int32.MaxValue) { - elements = all; - } else { - elements = new string[maxComponents]; - Array.Copy(all, elements, maxComponents); - } -#else - string[] elements = maxComponents < 0 ? self.ToString().Split(separators) : self.ToString().Split(separators, maxComponents); -#endif - RubyArray result = new RubyArray(); - foreach (string element in elements) { - if (!String.IsNullOrEmpty(element)) - result.Add(Kernel.FlowTaint(context, self, CreateSubClass(context, self, new MutableString(element)))); + foreach (MutableString element in elements) { + result.Add(Kernel.FlowTaint(context, self, CreateSubClass(context, self, element))); } // Strange behavior to match Ruby semantics - if (maxComponents < 0) + if (maxComponents < 0) { result.Add(Kernel.FlowTaint(context, self, CreateSubClass(context, self))); + } return result; } private static RubyArray/*!*/ InternalSplit(CodeContext/*!*/ context, MutableString/*!*/ self, MutableString separator, StringSplitOptions options, int maxComponents) { - if (separator == null || separator == " ") { - return WhitespaceSplit(context, self, options, maxComponents); + if (separator == null || separator.Length == 1 && separator.GetChar(0) == ' ') { + return WhitespaceSplit(context, self, maxComponents); } - if (maxComponents <= 0) + if (maxComponents <= 0) { maxComponents = Int32.MaxValue; + } RubyArray result = new RubyArray(maxComponents == Int32.MaxValue ? 1 : maxComponents + 1); bool keep_empty = (options & StringSplitOptions.RemoveEmptyEntries) != StringSplitOptions.RemoveEmptyEntries; @@ -2405,7 +2429,7 @@ while (maxComponents > 1 && i < self.Length && (next = IndexOf(self, separator, i)) != -1) { if (next > i || keep_empty) { - result.Add(Kernel.FlowTaint(context, self, CreateSubClass(context, self, self.Substring(i, next - i)))); + result.Add(Kernel.FlowTaint(context, self, CreateSubClass(context, self, self.GetSlice(i, next - i)))); maxComponents--; } @@ -2413,7 +2437,7 @@ } if (i < self.Length || keep_empty) { - result.Add(Kernel.FlowTaint(context, self, CreateSubClass(context, self, self.Substring(i)))); + result.Add(Kernel.FlowTaint(context, self, CreateSubClass(context, self, self.GetSlice(i)))); } return result; @@ -2423,8 +2447,8 @@ object separator = RubyUtils.GetExecutionContext(context).StringSeparator; if (separator == null) return Split(context, self, (MutableString)null, limit); - else if (separator is Regexp) - return Split(context, self, (Regexp)separator, limit); + else if (separator is RubyRegex) + return Split(context, self, (RubyRegex)separator, limit); else return Split(context, self, Protocols.CastToString(context, separator), limit); } @@ -2475,18 +2499,19 @@ } [RubyMethod("split")] - public static RubyArray/*!*/ Split(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regexp) { + public static RubyArray/*!*/ Split(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regexp) { return Split(context, self, regexp, 0); } [RubyMethod("split")] - public static RubyArray/*!*/ Split(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]Regexp/*!*/ regexp, int limit) { - if (String.IsNullOrEmpty(regexp.Regex.ToString())) - return Split(context, self, new MutableString(), limit); + public static RubyArray/*!*/ Split(CodeContext/*!*/ context, MutableString/*!*/ self, [NotNull]RubyRegex/*!*/ regexp, int limit) { + if (regexp.IsEmpty) { + return Split(context, self, MutableString.CreateEmpty(), limit); + } if (limit == 0) { // suppress trailing empty fields - RubyArray array = MakeRubyArray(context, self, regexp.Regex.Split(self)); + RubyArray array = MakeRubyArray(context, self, regexp.Split(self)); while (array.Count != 0 && ((MutableString)array[array.Count - 1]).Length == 0) { array.RemoveAt(array.Count - 1); } @@ -2498,10 +2523,10 @@ return result; } else if (limit < 0) { // does not suppress trailing fields when negative - return MakeRubyArray(context, self, regexp.Regex.Split(self)); + return MakeRubyArray(context, self, regexp.Split(self)); } else { // limit > 1 limits to N fields - return MakeRubyArray(context, self, regexp.Regex.Split(self, limit)); + return MakeRubyArray(context, self, regexp.Split(self, limit)); } } @@ -2520,12 +2545,12 @@ [RubyMethod("strip")] public static object Strip(CodeContext/*!*/ context, MutableString/*!*/ self) { - return Kernel.FlowTaint(context, self, new MutableString(self.ToString().Trim())); + return Kernel.FlowTaint(context, self, MutableString.Create(self.ConvertToString().Trim())); } [RubyMethod("strip!")] public static object StripInPlace(CodeContext/*!*/ context, MutableString/*!*/ self) { - string original = self.ToString(); + string original = self.ConvertToString(); string stripped = original.Trim(); if (original == stripped) @@ -2563,12 +2588,14 @@ private static string/*!*/ StripWhitespace(MutableString/*!*/ str) { int i = 0; while (i < str.Length) { - if (str[i] == ' ' || str[i] == '_' || str[i] == '\t' || str[i] == '\n' || str[i] == '\r') + char c = str.GetChar(i); + if (c == ' ' || c == '_' || c == '\t' || c == '\n' || c == '\r') { i += 1; - else - return str.Substring(i).ToString().Replace("_", ""); + } else { + return str.GetSlice(i).ConvertToString().Replace("_", ""); + } } - return str.ToString().Replace("_", ""); + return str.ConvertToString().Replace("_", ""); } private static string/*!*/ ParseSign(string/*!*/ number, ref bool isNegative) { @@ -2631,7 +2658,7 @@ [RubyMethod("to_i")] public static object ToInteger(CodeContext/*!*/ context, MutableString/*!*/ self, object @base) { - return ParseInteger(context, self, Protocols.CastToFixnum(context, @base)); + return ParseInteger(context, self.ConvertToString(), Protocols.CastToFixnum(context, @base)); } #endregion @@ -2640,12 +2667,12 @@ [RubyMethod("to_str")] public static MutableString/*!*/ ToS(CodeContext/*!*/ context, MutableString/*!*/ self) { RubyClass cls = RubyUtils.GetExecutionContext(context).GetClassOf(self); - return cls.Name.ToString() == "String" ? self : Kernel.FlowTaint(context, self, new MutableString(self)); + return cls.Name.ToString() == "String" ? self : Kernel.FlowTaint(context, self, MutableString.Create(self)); } [RubyMethod("to_clr_string")] public static string/*!*/ ToClrString(MutableString/*!*/ str) { - return str.ToString(); + return str.ConvertToString(); } //---------------------------------------------------------- String#to_sym @@ -2672,12 +2699,15 @@ if (self.Length == 0) throw RubyExceptions.CreateArgumentError("interning empty string"); + string str = self.ConvertToString(); + // Cannot convert a string that contains null to a symbol for (int i = 0; i < self.Length; i++) { - if (self[i] == 0) + if (str[i] == 0) { throw RubyExceptions.CreateArgumentError("symbol string may not contain '\0'"); + } } - return SymbolTable.StringToId(self.ToString()); + return SymbolTable.StringToId(str); } //------------------------------------------------------------ String#upto @@ -2765,7 +2795,7 @@ [RubyMethod("tr")] public static MutableString/*!*/ Tr(CodeContext/*!*/ context, MutableString/*!*/ self, MutableString/*!*/ from, MutableString/*!*/ to) { - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); IntervalParser parser = new IntervalParser(from); // TODO: a single pass to generate both? @@ -2774,19 +2804,21 @@ MutableString dest = new IntervalParser(to).ParseSequence(); - char? lastChar = dest.Length == 0 ? (char?)null : dest[dest.Length - 1]; + int lastChar = (dest.Length) == 0 ? -1 : dest.GetChar(dest.Length - 1); for (int i = 0; i < self.Length; i++) { - if (bitmap.Get(self[i])) { - int index = source.IndexOf(self[i]); + char c = self.GetChar(i); + if (bitmap.Get(c)) { + int index = source.IndexOf(c); if (index >= dest.Length) { - if (lastChar != null) - result.Append(lastChar); + if (lastChar != -1) { + result.Append((char)lastChar); + } } else { - result.Append(dest[index]); + result.Append(dest.GetChar(index)); } } else { - result.Append(self[i]); + result.Append(c); } } @@ -2847,7 +2879,7 @@ for (int i = 0; i < iterations; i++) result.Append(padding); - result.Append(padding.Substring(0, remainder)); + result.Append(padding.GetSlice(0, remainder)); return Kernel.FlowTaint(context, self, padding, result); } @@ -2865,13 +2897,13 @@ [RubyMethod("ljust")] public static MutableString/*!*/ LeftJustify(CodeContext/*!*/ context, MutableString/*!*/ self, int width) { // TODO: is this correct? Is it just a space or is this some configurable whitespace thing? - return LeftJustify(context, self, width, new MutableString(" ")); + return LeftJustify(context, self, width, MutableString.Create(" ")); } [RubyMethod("ljust")] public static MutableString/*!*/ LeftJustify(CodeContext/*!*/ context, MutableString/*!*/ self, object width) { // TODO: is this correct? Is it just a space or is this some configurable whitespace thing? - return LeftJustify(context, self, Protocols.CastToFixnum(context, width), new MutableString(" ")); + return LeftJustify(context, self, Protocols.CastToFixnum(context, width), MutableString.Create(" ")); } #endregion @@ -2905,7 +2937,7 @@ for (int i = 0; i < iterations; i++) result.Append(padding); - result.Append(padding.Substring(0, remainder)); + result.Append(padding.GetSlice(0, remainder)); result.Append(self); return Kernel.FlowTaint(context, self, padding, result); @@ -2924,13 +2956,13 @@ [RubyMethod("rjust")] public static MutableString/*!*/ RightJustify(CodeContext/*!*/ context, MutableString/*!*/ self, int width) { // TODO: is this correct? Is it just a space or is this some configurable whitespace thing? - return RightJustify(context, self, width, new MutableString(" ")); + return RightJustify(context, self, width, MutableString.Create(" ")); } [RubyMethod("rjust")] public static MutableString/*!*/ RightJustify(CodeContext/*!*/ context, MutableString/*!*/ self, object width) { // TODO: is this correct? Is it just a space or is this some configurable whitespace thing? - return RightJustify(context, self, Protocols.CastToFixnum(context, width), new MutableString(" ")); + return RightJustify(context, self, Protocols.CastToFixnum(context, width), MutableString.Create(" ")); } #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/NilClassOps.cs;C390406 File: NilClassOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/NilClassOps.cs;C390406 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/NilClassOps.cs;MutableString5 @@ -83,13 +83,13 @@ [RubyMethodAttribute("inspect")] public static MutableString Inspect(object self) { - return new MutableString("nil"); + return MutableString.Create("nil"); } [RubyMethodAttribute("to_s")] public static MutableString/*!*/ ToString(object self) { Debug.Assert(self == null); - return new MutableString(); + return MutableString.Create(String.Empty); } [SpecialName] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RegexpOps.cs;C428766 File: RegexpOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RegexpOps.cs;C428766 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/RegexpOps.cs;MutableString5 @@ -21,7 +21,7 @@ using Microsoft.Scripting.Runtime; namespace Ruby.Builtins { - [RubyClass("Regexp", Extends = typeof(Regexp), Inherits = typeof(Object)), Includes(typeof(Enumerable))] + [RubyClass("Regexp", Extends = typeof(RubyRegex), Inherits = typeof(Object)), Includes(typeof(Enumerable))] public static class RegexpOps { //declared private instance methods: // initialize @@ -65,63 +65,63 @@ #region constructors, compile [RubyConstructor] - public static Regexp/*!*/ Create() { - return new Regexp(); + public static RubyRegex/*!*/ Create() { + return new RubyRegex(); } [RubyConstructor] - public static Regexp/*!*/ Create([NotNull]MutableString/*!*/ str) { - return RubyOps.CreateRegexp(Ruby.Compiler.Ast.RegExOptions.NONE, str); + public static RubyRegex/*!*/ Create([NotNull]MutableString/*!*/ str) { + return new RubyRegex(str, RegexOptions.None); } [RubyConstructor] - public static Regexp/*!*/ Create(CodeContext/*!*/ context, object str) { + public static RubyRegex/*!*/ Create(CodeContext/*!*/ context, object str) { return Create(Protocols.CastToString(context, str)); } [RubyConstructor] - public static Regexp/*!*/ Create([NotNull]MutableString/*!*/ str, int options) { - return RubyOps.CreateRegexp((Ruby.Compiler.Ast.RegExOptions)options, str); + public static RubyRegex/*!*/ Create([NotNull]MutableString/*!*/ str, int options) { + return new RubyRegex(str, RubyRegex.ToClrOptions((Ruby.Compiler.Ast.RegExOptions)options)); } [RubyConstructor] - public static Regexp/*!*/ Create([NotNull]MutableString/*!*/ str, int options, [NotNull]MutableString/*!*/ lang) { + public static RubyRegex/*!*/ Create([NotNull]MutableString/*!*/ str, int options, [NotNull]MutableString/*!*/ lang) { // TODO: today we are ignoring the lang parameter return Create(str, options); } [RubyConstructor] - public static Regexp/*!*/ Create(CodeContext/*!*/ context, [NotNull]MutableString/*!*/ str, int options, object lang) { + public static RubyRegex/*!*/ Create(CodeContext/*!*/ context, [NotNull]MutableString/*!*/ str, int options, object lang) { return Create(str, options, Protocols.CastToString(context, lang)); } [RubyMethod("compile", RubyMethodAttributes.PublicSingleton)] - public static Regexp/*!*/ Compile(RubyClass/*!*/ self) { + public static RubyRegex/*!*/ Compile(RubyClass/*!*/ self) { return Create(); } [RubyMethod("compile", RubyMethodAttributes.PublicSingleton)] - public static Regexp/*!*/ Compile(RubyClass/*!*/ self, [NotNull]MutableString/*!*/ str) { + public static RubyRegex/*!*/ Compile(RubyClass/*!*/ self, [NotNull]MutableString/*!*/ str) { return Create(str); } [RubyMethod("compile", RubyMethodAttributes.PublicSingleton)] - public static Regexp/*!*/ Compile(CodeContext/*!*/ context, RubyClass/*!*/ self, object str) { + public static RubyRegex/*!*/ Compile(CodeContext/*!*/ context, RubyClass/*!*/ self, object str) { return Create(Protocols.CastToString(context, str)); } [RubyMethod("compile", RubyMethodAttributes.PublicSingleton)] - public static Regexp/*!*/ Compile(RubyClass/*!*/ self, [NotNull]MutableString/*!*/ str, int options) { + public static RubyRegex/*!*/ Compile(RubyClass/*!*/ self, [NotNull]MutableString/*!*/ str, int options) { return Create(str, options); } [RubyMethod("compile", RubyMethodAttributes.PublicSingleton)] - public static Regexp/*!*/ Compile(RubyClass/*!*/ self, [NotNull]MutableString/*!*/ str, int options, [NotNull]MutableString/*!*/ lang) { + public static RubyRegex/*!*/ Compile(RubyClass/*!*/ self, [NotNull]MutableString/*!*/ str, int options, [NotNull]MutableString/*!*/ lang) { return Create(str, options, lang); } [RubyMethod("compile", RubyMethodAttributes.PublicSingleton)] - public static Regexp/*!*/ Compile(CodeContext/*!*/ context, RubyClass/*!*/ self, [NotNull]MutableString/*!*/ str, int options, object lang) { + public static RubyRegex/*!*/ Compile(CodeContext/*!*/ context, RubyClass/*!*/ self, [NotNull]MutableString/*!*/ str, int options, object lang) { return Create(str, options, Protocols.CastToString(context, lang)); } @@ -146,21 +146,21 @@ // /(.)(.)(.)/.match("abc")[2] #=> "b" // Not directly callable from Ruby since Ruby has no concept of startAt in their Regexp - public static Match Match(CodeContext/*!*/ context, Regexp/*!*/ self, MutableString str, int startAt) { + public static Match Match(CodeContext/*!*/ context, RubyRegex/*!*/ self, MutableString str, int startAt) { if (str == null) return null; - Match match = self.Regex.Match(str, startAt); + Match match = self.Match(str, startAt); RubyUtils.GetScope(context).CurrentMatch = match.Success ? match : null; return match.Success? match : null; } [RubyMethod("match")] - public static Match Match(CodeContext/*!*/ context, Regexp/*!*/ self, [NotNull]MutableString/*!*/ str) { + public static Match Match(CodeContext/*!*/ context, RubyRegex/*!*/ self, [NotNull]MutableString/*!*/ str) { return Match(context, self, str, 0); } [RubyMethod("match")] - public static Match Match(CodeContext/*!*/ context, Regexp/*!*/ self, object str) { + public static Match Match(CodeContext/*!*/ context, RubyRegex/*!*/ self, object str) { return Match(context, self, Protocols.CastToString(context, str), 0); } @@ -174,13 +174,13 @@ // /(.)(.)(.)/.match("abc")[2] #=> "b" [RubyMethod("=~")] - public static object MatchIndex(CodeContext/*!*/ context, Regexp/*!*/ self, [NotNull]MutableString/*!*/ str) { + public static object MatchIndex(CodeContext/*!*/ context, RubyRegex/*!*/ self, [NotNull]MutableString/*!*/ str) { Match match = Match(context, self, str, 0); return (match != null && match.Success) ? (object)match.Index : null; } [RubyMethod("=~")] - public static object MatchIndex(CodeContext/*!*/ context, Regexp/*!*/ self, object str) { + public static object MatchIndex(CodeContext/*!*/ context, RubyRegex/*!*/ self, object str) { return MatchIndex(context, self, Protocols.CastToString(context, str)); } @@ -200,13 +200,13 @@ // Upper case [RubyMethod("===")] - public static bool CaseCompare(CodeContext/*!*/ context, Regexp/*!*/ self, [NotNull]MutableString/*!*/ str) { + public static bool CaseCompare(CodeContext/*!*/ context, RubyRegex/*!*/ self, [NotNull]MutableString/*!*/ str) { Match match = Match(context, self, str, 0); return (match != null && match.Success) ? true : false; } [RubyMethod("===")] - public static bool CaseCompare(CodeContext/*!*/ context, Regexp/*!*/ self, object str) { + public static bool CaseCompare(CodeContext/*!*/ context, RubyRegex/*!*/ self, object str) { return CaseCompare(context, self, Protocols.CastToString(context, str)); } @@ -220,7 +220,7 @@ // ~ /at/ #=> 7 [RubyMethod("~")] - public static object ImplicitMatch(CodeContext/*!*/ context, Regexp/*!*/ self) { + public static object ImplicitMatch(CodeContext/*!*/ context, RubyRegex/*!*/ self) { return MatchIndex(context, self, RubyUtils.GetScope(context).LastInputLine); } @@ -232,8 +232,8 @@ // /ab+c/ix.source #=> "ab+c" [RubyMethod("source")] - public static MutableString/*!*/ Source(Regexp/*!*/ self) { - return new MutableString(self.Regex.ToString()); + public static MutableString/*!*/ Source(RubyRegex/*!*/ self) { + return self.GetPattern(); } //--------------------------------------------------------- Regexp::escape @@ -250,7 +250,7 @@ [RubyMethod("escape", RubyMethodAttributes.PublicSingleton)] [RubyMethod("quote", RubyMethodAttributes.PublicSingleton)] public static MutableString/*!*/ Escape(CodeContext/*!*/ context, object/*!*/ self, [NotNull]MutableString/*!*/ str) { - return Kernel.FlowTaint(context, str, new MutableString(Regex.Escape(str))); + return Kernel.FlowTaint(context, str, MutableString.Create(RubyRegex.Escape(str))); } [RubyMethod("escape", RubyMethodAttributes.PublicSingleton)] @@ -281,7 +281,7 @@ [RubyMethod("last_match", RubyMethodAttributes.PublicSingleton)] public static MutableString/*!*/ LastMatch(CodeContext/*!*/ context, object/*!*/ self, int group) { - return new MutableString(RubyUtils.GetScope(context).CurrentMatch.Groups[group].Value); + return MutableString.Create(RubyUtils.GetScope(context).CurrentMatch.Groups[group].Value); } [RubyMethod("last_match", RubyMethodAttributes.PublicSingleton)] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SingletonOps.cs;C434537 File: SingletonOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SingletonOps.cs;C434537 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SingletonOps.cs;MutableString5 @@ -43,7 +43,7 @@ [RubyMethod("to_s", RubyMethodAttributes.PublicInstance)] public static MutableString/*!*/ ToS(object/*!*/ self) { - return new MutableString("main"); + return MutableString.Create("main"); } [RubyMethod("public", RubyMethodAttributes.PublicInstance)] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Socket.cs;C417565 File: Socket.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Socket.cs;C417565 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Socket.cs;MutableString5 @@ -163,13 +163,13 @@ [RubyMethod("recv")] public static MutableString/*!*/ Receive(BasicSocket/*!*/ self, int len, [Optional]int flags) { byte[] buffer = new byte[len]; - int bytes = self.Socket.Receive(buffer, (SocketFlags)flags); - return new MutableString(buffer, 0, bytes); + int count = self.Socket.Receive(buffer, (SocketFlags)flags); + return MutableString.CreateBinary(count).Append(buffer, 0, count); } [RubyMethod("send")] public static int Send(BasicSocket/*!*/ self, MutableString/*!*/ data, int flags) { - return self.Socket.Send(data.ToByteArray(), (SocketFlags)flags); + return self.Socket.Send(data.ConvertToBytes(), (SocketFlags)flags); } [RubyMethod("shutdown")] @@ -205,11 +205,10 @@ // try special port name mappings // TODO: are there more of these? - switch (str) { - case "ftp": - return 21; - case "http": - return 80; + if (str.Equals("ftp")) { + return 21; + } else if (str.Equals("http")) { + return 80; } int result; @@ -229,8 +228,8 @@ } [RubyMethod("getaddress", RubyMethodAttributes.PublicSingleton)] - public static string GetAddress(IPSocket/*!*/ self, MutableString hostName) { - return Dns.GetHostEntry(hostName).AddressList[0].ToString(); + public static string GetAddress(IPSocket/*!*/ self, [NotNull]MutableString/*!*/ hostName) { + return Dns.GetHostEntry(hostName.ConvertToString()).AddressList[0].ToString(); } @@ -248,10 +247,10 @@ RubyArray result = ArrayOps.CreateArray(); IPEndPoint ep = (IPEndPoint)endPoint; - result.Add(new MutableString(AddressFamilyToString(ep.AddressFamily))); + result.Add(MutableString.Create(AddressFamilyToString(ep.AddressFamily))); result.Add(ep.Port); - result.Add(new MutableString(System.Net.Dns.GetHostEntry(ep.Address).HostName)); - result.Add(new MutableString(ep.Address.ToString())); + result.Add(MutableString.Create(System.Net.Dns.GetHostEntry(ep.Address).HostName)); + result.Add(MutableString.Create(ep.Address.ToString())); return result; } @@ -284,19 +283,19 @@ } [RubyMethod("gethostbyname", RubyMethodAttributes.PublicSingleton)] - public static RubyArray/*!*/ GetHostByName(object self, MutableString hostName) { + public static RubyArray/*!*/ GetHostByName(object self, [NotNull]MutableString/*!*/ hostName) { RubyArray result = new RubyArray(); - IPHostEntry hostEntry = Dns.GetHostEntry(hostName); + IPHostEntry hostEntry = Dns.GetHostEntry(hostName.ConvertToString()); result.Add(hostName); RubyArray aliases = new RubyArray(hostEntry.Aliases.Length); foreach (string alias in hostEntry.Aliases) { - aliases.Add(new MutableString(alias)); + aliases.Add(MutableString.Create(alias)); } result.Add(aliases); result.Add((int)hostEntry.AddressList[0].AddressFamily); - result.Add(new MutableString(hostEntry.AddressList[0].ToString())); + result.Add(MutableString.Create(hostEntry.AddressList[0].ToString())); return result; } @@ -304,7 +303,7 @@ public static TCPSocket/*!*/ CreateTCPSocket(CodeContext/*!*/ context, object remoteHost, object remotePort, [Optional]object localHost, [Optional]object localPort) { // TODO: handle localHost, localPort & any other args - MutableString hostname = Protocols.CastToString(context, remoteHost); + string hostname = Protocols.CastToString(context, remoteHost).ConvertToString(); int port = ConverToPort(context, remotePort); Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); @@ -319,7 +318,7 @@ len = self.Socket.Receive(buffer, len, (SocketFlags)flags); RubyArray result = ArrayOps.CreateArray(); - result.Add(new MutableString(buffer, 0, len)); + result.Add(MutableString.CreateBinary(len).Append(buffer, 0, len)); result.Add(null); return result; } @@ -338,7 +337,7 @@ if (hostname == Missing.Value) { listeningInterface = new IPAddress(0); } else { - string hostnameStr = Protocols.CastToString(context, hostname).ToString(); + string hostnameStr = Protocols.CastToString(context, hostname).ConvertToString(); // try to parse it as an IP address first if (!IPAddress.TryParse(hostnameStr, out listeningInterface)) { =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StringFormatter.cs;C417565 File: StringFormatter.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StringFormatter.cs;C417565 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StringFormatter.cs;MutableString5 @@ -66,16 +66,16 @@ set { _TrailingZeroAfterWholeFloat = value; } } - #region Instance members const int UnspecifiedPrecision = -1; // Use the default precision - private IList _data; - + private readonly IList/*!*/ _data; + private readonly string/*!*/ _format; + private readonly CodeContext/*!*/ _context; + private bool? _useAbsolute; private int _relativeIndex; private bool _tainted; - private MutableString _str; private int _index; private char _curCh; @@ -86,15 +86,13 @@ private MutableString _buf; - private CodeContext/*!*/ _context; - #endregion - + #region Constructors - internal StringFormatter(CodeContext/*!*/ context, MutableString/*!*/ str, IList/*!*/ data) { - Assert.NotNull(context, str, data); + internal StringFormatter(CodeContext/*!*/ context, string/*!*/ format, IList/*!*/ data) { + Assert.NotNull(context, format, data); - _str = str; + _format = format; _data = data; _context = context; } @@ -105,16 +103,16 @@ public MutableString/*!*/ Format() { _index = 0; - _buf = new MutableString(_str.Length * 2); + _buf = MutableString.CreateMutable(_format.Length * 2); _tainted = false; int modIndex; - while ((modIndex = _str.IndexOf('%', _index)) != -1) { - _buf.Append(_str, _index, modIndex - _index); + while ((modIndex = _format.IndexOf('%', _index)) != -1) { + _buf.Append(_format, _index, modIndex - _index); _index = modIndex + 1; DoFormatCode(); } - _buf.Append(_str, _index, _str.Length - _index); + _buf.Append(_format, _index, _format.Length - _index); if (_tainted) Kernel.Taint(_context, _buf); @@ -137,13 +135,13 @@ private void DoFormatCode() { // we already pulled the first % - if (_index == _str.Length) { + if (_index == _format.Length) { // '%' at the end of the string. Just print it and we are done. _buf.Append('%'); return; } - _curCh = _str[_index++]; + _curCh = _format[_index++]; if (_curCh == '%') { // Escaped '%' character using "%%". Just print it and we are done @@ -184,10 +182,10 @@ // TODO: we need to rewrite how we parse these things to line up our error messages with MRI if (fFoundConversion) { - if (_index >= _str.Length) + if (_index >= _format.Length) throw RubyExceptions.CreateArgumentError("illegal format character - %"); - _curCh = _str[_index++]; + _curCh = _format[_index++]; } } while (fFoundConversion); @@ -196,11 +194,11 @@ private int? TryReadArgumentIndex() { if (char.IsDigit(_curCh)) { int end = _index; - while (end < _str.Length && char.IsDigit(_str[end])) { + while (end < _format.Length && char.IsDigit(_format[end])) { end++; } - if (end < _str.Length && _str[end] == '$') { - int argIndex = int.Parse(_str.Substring(_index - 1, end - _index + 1)); + if (end < _format.Length && _format[end] == '$') { + int argIndex = int.Parse(_format.Substring(_index - 1, end - _index + 1)); _index = end + 1; return argIndex; } @@ -212,15 +210,15 @@ int res = 0; // default value if (_curCh == '*') { int? argindex = TryReadArgumentIndex(); - _curCh = _str[_index++]; + _curCh = _format[_index++]; res = Protocols.CastToFixnum(_context, GetData(argindex)); } else { if (Char.IsDigit(_curCh)) { res = 0; - while (Char.IsDigit(_curCh) && _index < this._str.Length) { + while (Char.IsDigit(_curCh) && _index < this._format.Length) { res = res * 10 + ((int)(_curCh - '0')); - _curCh = _str[_index++]; + _curCh = _format[_index++]; } } } @@ -231,13 +229,13 @@ _opts.FieldWidth = ReadNumberOrStar(); if (_opts.FieldWidth == Int32.MaxValue) { // TODO: this should be thrown by the converter - throw RangeErrorOps.Factory(new MutableString("bignum too big to convert into `long'")); + throw RangeErrorOps.Factory(MutableString.Create("bignum too big to convert into `long'")); } } private void ReadPrecision() { if (_curCh == '.') { - _curCh = _str[_index++]; + _curCh = _format[_index++]; // possibility: "8.f", "8.0f", or "8.2f" _opts.Precision = ReadNumberOrStar(); } else { @@ -414,7 +412,7 @@ } else { AppendNumeric(v, v >= 0, type, false); } - if (v < 0 && v > -1 && _buf[0] != '-') { + if (v < 0 && v > -1 && _buf.GetChar(0) != '-') { FixupFloatMinus(); } @@ -428,10 +426,11 @@ if (_opts.FieldWidth != 0) { // try and remove the extra character we're adding. for (int i = 0; i < _buf.Length; i++) { - if (_buf[i] == ' ' || _buf[i] == '0') { + char c = _buf.GetChar(i); + if (c == ' ' || c == '0') { _buf.Remove(i, 1); break; - } else if (_buf[i] != '-' && _buf[i] != '+') { + } else if (c != '-' && c != '+') { break; } } @@ -443,7 +442,8 @@ // sprintf("%.0f", -0.1) => "-0" bool fNeedMinus = true; for (int i = 0; i < _buf.Length; i++) { - if (_buf[i] != '.' && _buf[i] != '0' && _buf[i] != ' ') { + char c = _buf.GetChar(i); + if (c != '.' && c != '0' && c != ' ') { fNeedMinus = false; break; } @@ -452,14 +452,14 @@ if (fNeedMinus) { if (_opts.FieldWidth != 0) { // trim us back down to the correct field width... - if (_buf[_buf.Length - 1] == ' ') { + if (_buf.GetChar(_buf.Length - 1) == ' ') { _buf.Insert(0, "-"); _buf.Remove(_buf.Length - 1, 1); } else { int index = 0; - while (_buf[index] == ' ') index++; + while (_buf.GetChar(index) == ' ') index++; if (index > 0) index--; - _buf[index] = '-'; + _buf.SetChar(index, '-'); } } else { _buf.Insert(0, "-"); @@ -878,8 +878,8 @@ AppendString(str); } - private void AppendString(string s) { - if (_opts.Precision != UnspecifiedPrecision && s.Length > _opts.Precision) s = s.Substring(0, _opts.Precision); + private void AppendString(MutableString/*!*/ s) { + if (_opts.Precision != UnspecifiedPrecision && s.Length > _opts.Precision) s = s.GetSlice(0, _opts.Precision); if (!_opts.LeftAdj && _opts.FieldWidth > s.Length) { _buf.Append(' ', _opts.FieldWidth - s.Length); } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StringOps.cs;C390406 File: StringOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StringOps.cs;C390406 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StringOps.cs;MutableString5 @@ -32,7 +32,7 @@ [RubyMethod("to_str", RubyMethodAttributes.PublicInstance)] [RubyMethod("to_s", RubyMethodAttributes.PublicInstance)] public static MutableString/*!*/ ToStr(string/*!*/ self) { - return new MutableString(self); + return MutableString.Create(self); } [RubyMethod("to_clr_string", RubyMethodAttributes.PublicInstance)] @@ -42,7 +42,7 @@ [RubyMethod("inspect", RubyMethodAttributes.PublicInstance)] public static MutableString/*!*/ Inspect(string/*!*/ self) { - MutableString str = new MutableString(); + MutableString str = MutableString.CreateMutable(); str.Append("\""); for (int i = 0; i < self.Length; i++) { str.Append(MutableStringOps.GetStringRepresentationOfChar(self[i])); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StringScanner.cs;C413883 File: StringScanner.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StringScanner.cs;C413883 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/StringScanner.cs;MutableString5 @@ -79,7 +79,7 @@ [RubyMethod("[]")] public static MutableString GetMatchSubgroup(StringScanner/*!*/ self, int subgroup) { if (subgroup == 0 && self.LastMatch != null) { - return new MutableString(self.LastMatch); + return MutableString.Create(self.LastMatch); } if (self.LastMatchingGroups == null) { return null; @@ -90,22 +90,22 @@ if (subgroup >= self.LastMatchingGroups.Count) { return null; } - return new MutableString(self.LastMatchingGroups[subgroup].ToString()); + return MutableString.Create(self.LastMatchingGroups[subgroup].ToString()); } [RubyMethod("beginning_of_line?")] [RubyMethod("bol?")] public static bool BeginningOfLine(StringScanner/*!*/ self) { - return (self.CurrentPosition == 0) || (self.ScanString[self.CurrentPosition - 1] == '\n'); + return (self.CurrentPosition == 0) || (self.ScanString.GetChar(self.CurrentPosition - 1) == '\n'); } [RubyMethod("check")] - public static MutableString Check(StringScanner/*!*/ self, [NotNull]Regexp/*!*/ pattern) { + public static MutableString Check(StringScanner/*!*/ self, [NotNull]RubyRegex/*!*/ pattern) { return (ScanFull(self, pattern, false, true) as MutableString); } [RubyMethod("check_until")] - public static MutableString CheckUntil(StringScanner/*!*/ self, [NotNull]Regexp/*!*/ pattern) { + public static MutableString CheckUntil(StringScanner/*!*/ self, [NotNull]RubyRegex/*!*/ pattern) { return (SearchFull(self, pattern, false, true) as MutableString); } @@ -116,7 +116,7 @@ } [RubyMethod("exist?")] - public static int? Exist(StringScanner self, [NotNull]Regexp/*!*/ pattern) { + public static int? Exist(StringScanner self, [NotNull]RubyRegex/*!*/ pattern) { if (!self.Match(pattern, false, false)) return null; return self.FoundPosition + self.LastMatch.Length; @@ -130,8 +130,8 @@ } self.PreviousPosition = self.CurrentPosition; self.FoundPosition = self.CurrentPosition; - self.LastMatch = self.ScanString.Substring(self.CurrentPosition++, 1); - return new MutableString(self.LastMatch); + self.LastMatch = self.ScanString.GetSlice(self.CurrentPosition++, 1); + return MutableString.Create(self.LastMatch); } [RubyMethod("getch")] @@ -141,18 +141,18 @@ } self.PreviousPosition = self.CurrentPosition; self.FoundPosition = self.CurrentPosition; - self.LastMatch = self.ScanString.Substring(self.CurrentPosition++, 1); - return new MutableString(self.LastMatch); + self.LastMatch = self.ScanString.GetSlice(self.CurrentPosition++, 1); + return MutableString.Create(self.LastMatch); } [RubyMethod("inspect")] [RubyMethod("to_s")] public static MutableString ToString(StringScanner/*!*/ self) { - return new MutableString(self.ToString()); + return MutableString.Create(self.ToString()); } [RubyMethod("match?")] - public static int? Match(StringScanner/*!*/ self, [NotNull]Regexp/*!*/ pattern) { + public static int? Match(StringScanner/*!*/ self, [NotNull]RubyRegex/*!*/ pattern) { if (!self.Match(pattern, true, false)) { return null; } @@ -164,7 +164,7 @@ if (self.LastMatch == null) { return null; } - return new MutableString(self.LastMatch); + return MutableString.Create(self.LastMatch); } [RubyMethod("matched?")] @@ -192,9 +192,9 @@ len = maxlen; } if (self.CurrentPosition >= self.Length || len == 0) { - return new MutableString(); + return MutableString.CreateMutable(); } - return self.ScanString.Substring(self.CurrentPosition, len); + return self.ScanString.GetSlice(self.CurrentPosition, len); } [RubyMethod("pos")] @@ -225,9 +225,9 @@ int position = self.FoundPosition + self.LastMatch.Length; int len = self.Length - position; if (len <= 0) { - return new MutableString(""); + return MutableString.Create(""); } - return self.ScanString.Substring(position, len); + return self.ScanString.GetSlice(position, len); } [RubyMethod("pre_match")] @@ -235,7 +235,7 @@ if (self.LastMatch == null) { return null; } - return self.ScanString.Substring(0, self.FoundPosition); + return self.ScanString.GetSlice(0, self.FoundPosition); } [RubyMethod("reset")] @@ -248,9 +248,9 @@ public static MutableString Rest(StringScanner/*!*/ self) { int len = self.Length - self.CurrentPosition; if (len <= 0) { - return new MutableString(""); + return MutableString.Create(""); } - return self.ScanString.Substring(self.CurrentPosition, len); + return self.ScanString.GetSlice(self.CurrentPosition, len); } [RubyMethod("rest?")] @@ -265,17 +265,17 @@ } [RubyMethod("scan")] - public static MutableString Scan(StringScanner/*!*/ self, [NotNull]Regexp/*!*/ pattern) { + public static MutableString Scan(StringScanner/*!*/ self, [NotNull]RubyRegex/*!*/ pattern) { return (ScanFull(self, pattern, true, true) as MutableString); } [RubyMethod("scan_full")] - public static object ScanFull(StringScanner/*!*/ self, [NotNull]Regexp/*!*/ pattern, bool advance_pointer_p, bool return_string_p) { + public static object ScanFull(StringScanner/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, bool advance_pointer_p, bool return_string_p) { bool match = self.Match(pattern, true, advance_pointer_p); object result = null; if (match) { if (return_string_p) { - result = new MutableString(self.LastMatch); + result = MutableString.Create(self.LastMatch); } else { result = self.LastMatch.Length; } @@ -284,18 +284,18 @@ } [RubyMethod("scan_until")] - public static MutableString ScanUntil(StringScanner/*!*/ self, [NotNull]Regexp/*!*/ pattern) { + public static MutableString ScanUntil(StringScanner/*!*/ self, [NotNull]RubyRegex/*!*/ pattern) { return (SearchFull(self, pattern, true, true) as MutableString); } [RubyMethod("search_full")] - public static object SearchFull(StringScanner/*!*/ self, [NotNull]Regexp/*!*/ pattern, bool advance_pointer_p, bool return_string_p) { + public static object SearchFull(StringScanner/*!*/ self, [NotNull]RubyRegex/*!*/ pattern, bool advance_pointer_p, bool return_string_p) { bool match = self.Match(pattern, false, advance_pointer_p); object result = null; if (match) { int length = self.LastMatch.Length + (self.FoundPosition - self.PreviousPosition); if (return_string_p) { - result = self.ScanString.Substring(self.PreviousPosition, length); + result = self.ScanString.GetSlice(self.PreviousPosition, length); } else { result = length; } @@ -304,7 +304,7 @@ } [RubyMethod("skip")] - public static int? Skip(StringScanner/*!*/ self, [NotNull]Regexp/*!*/ pattern) { + public static int? Skip(StringScanner/*!*/ self, [NotNull]RubyRegex/*!*/ pattern) { bool match = self.Match(pattern, true, true); if (!match) { return null; @@ -313,7 +313,7 @@ } [RubyMethod("skip_until")] - public static int? SkipUntil(StringScanner/*!*/ self, [NotNull]Regexp/*!*/ pattern) { + public static int? SkipUntil(StringScanner/*!*/ self, [NotNull]RubyRegex/*!*/ pattern) { bool match = self.Match(pattern, false, true); if (!match) { return null; @@ -328,7 +328,7 @@ [RubyMethod("string=")] public static MutableString SetString(CodeContext/*!*/ context, StringScanner/*!*/ self, [NotNull]MutableString/*!*/ str) { - self.ScanString = (MutableString)Kernel.Freeze(context, new MutableString(str)); + self.ScanString = (MutableString)Kernel.Freeze(context, MutableString.Create(str)); self.Reset(); return str; } @@ -356,8 +356,8 @@ #region Helpers - private bool Match(Regexp/*!*/ pattern, bool currentPositionOnly, bool advancePosition) { - Match match = pattern.Regex.Match(_scanString, _currentPosition); + private bool Match(RubyRegex/*!*/ pattern, bool currentPositionOnly, bool advancePosition) { + Match match = pattern.Match(_scanString, _currentPosition); _lastMatch = null; _lastMatchingGroups = null; _foundPosition = 0; @@ -370,7 +370,7 @@ int length = (match.Index - _currentPosition) + match.Length; _foundPosition = match.Index; _previousPosition = _currentPosition; - _lastMatch = _scanString.Substring(_foundPosition, match.Length); + _lastMatch = _scanString.GetSlice(_foundPosition, match.Length); _lastMatchingGroups = match.Groups; if (advancePosition) { _currentPosition += length; @@ -451,7 +451,7 @@ public override string ToString() { // # - string scanstr = ScanString.ToString(); + string scanstr = ScanString.ConvertToString(); StringBuilder sb = new StringBuilder("#= Length || CurrentPosition < 0) { sb.Append("fin >"); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Struct.cs;C415805 File: Struct.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Struct.cs;C415805 (server) 5/7/2008 6:06 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Struct.cs;MutableString5 @@ -271,7 +271,7 @@ public static MutableString/*!*/ Inspect(CodeContext/*!*/ context, RubyStruct/*!*/ self) { RubyExecutionContext ec = RubyUtils.GetExecutionContext(context); // # - MutableString str = new MutableString("# infinite = RubyUtils.TryPushInfinite(self); @@ -410,8 +410,8 @@ MutableString str = Protocols.AsString(context, items[0]); if (str != null) { // TODO: move to a common place - if (!char.IsUpper(str.Chars[0])) { - throw RubyExceptions.CreateNameError(string.Format("identifier {0} needs to be constant", str.ToString())); + if (!Char.IsUpper(str.GetChar(0))) { + throw RubyExceptions.CreateNameError(String.Format("identifier {0} needs to be constant", str)); } className = str.ToSymbol(); firstSymbol = 1; =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SymbolOps.cs;C390406 File: SymbolOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SymbolOps.cs;C390406 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/SymbolOps.cs;MutableString5 @@ -29,12 +29,12 @@ [RubyMethod("id2name")] [RubyMethod("to_s")] public static MutableString/*!*/ ToString(SymbolId self) { - return new MutableString(SymbolTable.IdToString(self)); + return MutableString.Create(SymbolTable.IdToString(self)); } [RubyMethod("inspect")] public static MutableString/*!*/ Inspect(SymbolId self) { - return new MutableString(":" + SymbolTable.IdToString(self)); + return MutableString.Create(":" + SymbolTable.IdToString(self)); } [RubyMethod("to_i")] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TimeOps.cs;C422137 File: TimeOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TimeOps.cs;C422137 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TimeOps.cs;MutableString5 @@ -605,7 +605,7 @@ [RubyMethod("inspect")] [RubyMethod("to_s")] public static MutableString/*!*/ ToString(DateTime self) { - return new MutableString(self.ToString("ddd MMM dd HH:mm:ss K yyyy")); + return MutableString.Create(self.ToString("ddd MMM dd HH:mm:ss K yyyy")); } } } \ No newline at end of file =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TrueClass.cs;C420856 File: TrueClass.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TrueClass.cs;C420856 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/TrueClass.cs;MutableString5 @@ -27,7 +27,7 @@ [RubyMethodAttribute("to_s")] public static MutableString/*!*/ ToString(bool self) { Debug.Assert(self == true); - return new MutableString("true"); + return MutableString.Create("true"); } [RubyMethodAttribute("&")] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/UnboundMethod.cs;C390406 File: UnboundMethod.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/UnboundMethod.cs;C390406 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/UnboundMethod.cs;MutableString5 @@ -87,7 +87,7 @@ internal static MutableString/*!*/ ToS(SymbolId methodName, RubyModule/*!*/ declaringModule, RubyModule/*!*/ targetModule, string/*!*/ classDisplayName) { - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); result.Append("#<"); result.Append(classDisplayName); result.Append(": "); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Digest/Digest.cs;C390406 File: Digest.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Digest/Digest.cs;C390406 (server) 5/7/2008 6:02 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Digest/Digest.cs;MutableString5 @@ -65,7 +65,7 @@ protected Base(HashAlgorithm/*!*/ algorithm) { Assert.NotNull(algorithm); _algorithm = algorithm; - _buffer = new MutableString(); + _buffer = MutableString.CreateBinary(); } [RubyMethod("<<")] @@ -77,21 +77,21 @@ [RubyMethod("finish", RubyMethodAttributes.PrivateInstance)] public static MutableString/*!*/ Finish(CodeContext/*!*/ context, Base/*!*/ self) { - byte[] input = self._buffer.ToByteArray(); + byte[] input = self._buffer.ConvertToBytes(); byte[] hash = self._algorithm.ComputeHash(input); - return new MutableString(hash, 0, hash.Length); + return MutableString.CreateBinary(hash); } [RubyMethod("reset")] public static Base/*!*/ Reset(CodeContext/*!*/ context, Base/*!*/ self) { - self._buffer = new MutableString(); + self._buffer = MutableString.CreateBinary(); self._algorithm.Initialize(); return self; } //TODO: should this be initialize_copy method? void IDuplicable.InitializeFrom(object copyFrom) { - _buffer = new MutableString(((Base)copyFrom)._buffer); + _buffer = MutableString.Create(((Base)copyFrom)._buffer); } } @@ -116,11 +116,11 @@ #region Helpers internal static MutableString/*!*/ Bytes2Hex(byte[]/*!*/ bytes) { - return new MutableString(System.BitConverter.ToString(bytes).Replace("-", "").ToLower()); + return MutableString.Create(System.BitConverter.ToString(bytes).Replace("-", "").ToLower()); } internal static MutableString/*!*/ HexEncode(MutableString/*!*/ str) { - return Bytes2Hex(str.ToByteArray()); + return Bytes2Hex(str.ConvertToBytes()); } #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;C417565 File: IDictionaryOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;C417565 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IDictionaryOps.cs;MutableString5 @@ -274,7 +274,7 @@ } if (defaultValue == Missing.Value) { - throw IndexErrorOps.Factory(new MutableString("key not found")); + throw IndexErrorOps.Factory(MutableString.Create("key not found")); } return defaultValue; @@ -320,10 +320,10 @@ public static MutableString Inspect(CodeContext/*!*/ context, IDictionary/*!*/ self) { Dictionary infinite = RubyUtils.TryPushInfinite(self); if (infinite == null) { - return new MutableString("{...}"); + return MutableString.Create("{...}"); } try { - MutableString str = new MutableString(); + MutableString str = MutableString.CreateMutable(); str.Append('{'); foreach (KeyValuePair pair in self) { if (str.Length != 1) { =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs;C417565 File: IListOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs;C417565 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/IListOps.cs;MutableString5 @@ -1110,10 +1110,10 @@ public static MutableString Inspect(CodeContext/*!*/ context, IList/*!*/ self) { Dictionary infinite = RubyUtils.TryPushInfinite(self); if (infinite == null) { - return new MutableString("[...]"); + return MutableString.Create("[...]"); } try { - MutableString str = new MutableString(); + MutableString str = MutableString.CreateMutable(); str.Append('['); foreach (object obj in self) { if (str.Length != 1) { @@ -1172,19 +1172,19 @@ Assert.NotNull(context, self); MutableString separator = RubyUtils.GetExecutionContext(context).ItemSeparator; - return Join(context, self, (separator != null ? separator.ToString() : String.Empty)); + return Join(context, self, (separator != null ? separator.ConvertToString() : String.Empty)); } [RubyMethod("join")] public static MutableString Join(CodeContext/*!*/ context, IList/*!*/ self, string separator) { - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); RecursiveJoin(context, self, separator, result, new Dictionary(ReferenceEqualityComparer.Instance)); return result; } [RubyMethod("join")] public static MutableString Join(CodeContext/*!*/ context, IList/*!*/ self, [NotNull]MutableString/*!*/ separator) { - return Join(context, self, separator.ToString()); + return Join(context, self, separator.ConvertToString()); } #endregion =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/OpenSSL/OpenSSL.cs;C390406 File: OpenSSL.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/OpenSSL/OpenSSL.cs;C390406 (server) 5/7/2008 7:38 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/OpenSSL/OpenSSL.cs;MutableString5 @@ -54,7 +54,7 @@ default: algorithm = null; break; } #else - algorithm = Crypto.HMAC.Create("HMAC" + algorithmName.ToString()); + algorithm = Crypto.HMAC.Create("HMAC" + algorithmName.ConvertToString()); #endif if (algorithm == null) { @@ -74,10 +74,10 @@ [NotNull]MutableString/*!*/ key, [NotNull]MutableString/*!*/ data) { // TODO: does MRI really modify the digest object? - digest.Algorithm.Key = key.ToByteArray(); - byte[] hash = digest.Algorithm.ComputeHash(data.ToByteArray()); + digest.Algorithm.Key = key.ConvertToBytes(); + byte[] hash = digest.Algorithm.ComputeHash(data.ConvertToBytes()); - return new MutableString(BitConverter.ToString(hash).Replace("-", "").ToLower()); + return MutableString.Create(BitConverter.ToString(hash).Replace("-", "").ToLower()); } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Zlib/zlib.cs;C427877 File: zlib.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Zlib/zlib.cs;C427877 (server) 5/7/2008 7:39 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Zlib/zlib.cs;MutableString5 @@ -204,7 +204,7 @@ [RubyMethod("inflate")] public static MutableString/*!*/ InflateStream(Inflate/*!*/ self, MutableString/*!*/ zstring) { - foreach (byte b in zstring.ToByteArray()) { + foreach (byte b in zstring.ConvertToBytes()) { self._inputBuffer.Add(b); } if (self._rawDeflate == false) { @@ -326,7 +326,7 @@ [RubyMethod("close")] public static MutableString/*!*/ Close(Inflate/*!*/ self) { - return new MutableString(self._outputBuffer.ToArray(), 0, self._outputBuffer.Count); + return MutableString.CreateBinary(self._outputBuffer); } private void NoCompression() { @@ -663,19 +663,19 @@ } } - _originalName = new MutableString(); + _originalName = MutableString.CreateBinary(); if (fname) { - while (_originalName.IndexOf('\0') == -1) { - _originalName.Append((char)_inputBuffer[++_inPos]); + while (_originalName.IndexOf(0) == -1) { + _originalName.Append(_inputBuffer[++_inPos]); } _originalName.Remove(_originalName.Length - 1, 1); } - _comment = new MutableString(); + _comment = MutableString.CreateBinary(); if (fcomment) { - while (_comment.IndexOf('\0') == -1) { - _comment.Append((char)_inputBuffer[++_inPos]); + while (_comment.IndexOf(0) == -1) { + _comment.Append(_inputBuffer[++_inPos]); } _comment.Remove(_originalName.Length - 1, 1); @@ -695,7 +695,7 @@ [RubyMethod("read")] public static MutableString/*!*/ Read(GZipReader/*!*/ self) { Inflate z = new Inflate(-MAX_WBITS); - return Inflate.InflateStream(z, new MutableString(self._contents.ToArray(), 0, self._contents.Count)); + return Inflate.InflateStream(z, MutableString.CreateBinary(self._contents)); } [RubyMethod("open", RubyMethodAttributes.PrivateInstance)] =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C429806 File: Ruby.csproj =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;C429806 (server) 5/7/2008 1:43 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Ruby.csproj;MutableString5 @@ -88,6 +88,7 @@ + =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/IO.cs;C413883 File: IO.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/IO.cs;C413883 (server) 5/8/2008 2:07 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/IO.cs;MutableString5 @@ -255,11 +255,17 @@ } public void Write(string/*!*/ value) { - foreach (char c in value) { - _stream.WriteByte((byte)c); - } + // TODO: + byte[] bytes = StringUtils.DefaultEncoding.GetBytes(value); + _stream.Write(bytes, 0, bytes.Length); } + public void Write(MutableString/*!*/ value) { + // TODO: + byte[] bytes = value.ConvertToBytes(); + _stream.Write(bytes, 0, bytes.Length); + } + public char? GetChar() { if (IsEndOfStream()) return null; =================================================================== add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.Content.cs File: MutableString.Content.cs =================================================================== --- [no source file] +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.Content.cs;MutableString5 @@ -1,0 +1,859 @@ +?/* **************************************************************************** + * + * Copyright (c) Microsoft Corporation. + * + * This source code is subject to terms and conditions of the Microsoft Public License. A + * copy of the license can be found in the License.html file at the root of this distribution. If + * you cannot locate the Microsoft Public License, please send an email to + * ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound + * by the terms of the Microsoft Public License. + * + * You must not remove this notice, or any other, from this software. + * + * + * ***************************************************************************/ + +using System; +using System.Text; +using Microsoft.Scripting; +using Microsoft.Scripting.Utils; +using Ruby.Runtime; +using System.Text.RegularExpressions; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Ruby.Builtins { + public partial class MutableString { + [Serializable] + private abstract class Content { + protected MutableString/*!*/ _owner; + + internal void SetOwner(MutableString/*!*/ owner) { + Assert.NotNull(owner); + _owner = owner; + } + + protected Content(MutableString/*!*/ owner) { + Assert.NotNull(owner); + _owner = owner; + } + + protected BinaryContent/*!*/ ToContent(byte[]/*!*/ bytes) { + BinaryContent result = new BinaryContent(_owner, new List(bytes)); + _owner.SetContent(result); + return result; + } + + protected StringBuilderContent/*!*/ ToContent(StringBuilder/*!*/ sb) { + StringBuilderContent result = new StringBuilderContent(_owner, sb); + _owner.SetContent(result); + return result; + } + + public virtual string/*!*/ ConvertToString() { + return GetStringSlice(0, Length); + } + + public virtual byte[]/*!*/ ConvertToBytes() { + return GetBinarySlice(0, Length); + } + + public abstract GenericRegex/*!*/ ToRegularExpression(RegexOptions options); + + // read: + public abstract bool IsBinary { get; } + public abstract int Length { get; } + public abstract void GetDebugView(out string/*!*/ value, out string/*!*/ type); + public abstract Content/*!*/ Clone(MutableString/*!*/ newOwner); + + public abstract char GetChar(int index); + public abstract byte GetByte(int index); + public abstract byte PeekByte(int index); + public abstract char PeekChar(int index); + public abstract string/*!*/ GetStringSlice(int start, int count); + public abstract byte[]/*!*/ GetBinarySlice(int start, int count); + + public abstract int CompareTo(string/*!*/ str); + public abstract int CompareTo(byte[]/*!*/ bytes); + public abstract int ReverseCompareTo(Content/*!*/ str); + + // the owner of the reuslt is the current owner: + public abstract Content/*!*/ GetSlice(int start, int count); + + public abstract int IndexOf(char c, int start, int count); + public abstract int IndexOf(byte b, int start, int count); + public abstract int IndexOf(string/*!*/ str, int start, int count); + public abstract int IndexOf(byte[]/*!*/ bytes, int start, int count); + public abstract int IndexIn(Content/*!*/ str, int start, int count); + + // write: + public abstract Content/*!*/ Append(char c, int repeatCount); + public abstract Content/*!*/ Append(byte b, int repeatCount); + public abstract Content/*!*/ Append(string/*!*/ str, int start, int count); + public abstract Content/*!*/ Append(byte[]/*!*/ bytes, int start, int count); + public abstract Content/*!*/ AppendTo(Content/*!*/ str, int start, int count); + + public abstract Content/*!*/ AppendFormat(IFormatProvider provider, string/*!*/ format, object[]/*!*/ args); + + public abstract Content/*!*/ Insert(int index, char c); + public abstract Content/*!*/ Insert(int index, byte b); + public abstract Content/*!*/ Insert(int index, string/*!*/ str, int start, int count); + public abstract Content/*!*/ Insert(int index, byte[]/*!*/ bytes, int start, int count); + public abstract Content/*!*/ InsertTo(Content/*!*/ str, int index, int start, int count); + + public abstract Content/*!*/ SetItem(int index, byte b); + public abstract Content/*!*/ SetItem(int index, char c); + + public abstract Content/*!*/ Remove(int start, int count); + } + + [Serializable] + private sealed class StringContent : Content { + private readonly string/*!*/ _data; + + public StringContent(MutableString/*!*/ owner, string/*!*/ data) + : base(owner) { + Assert.NotNull(data); + _data = data; + } + + #region GetHashCode, Length, Clone + + public override int GetHashCode() { + return _data.GetHashCode(); + } + + public override bool IsBinary { + get { return false; } + } + + public override int Length { + get { return _data.Length; } + } + + public override void GetDebugView(out string/*!*/ value, out string/*!*/ type) { + value = _data; + type = "String (immutable)"; + } + + public override Content/*!*/ Clone(MutableString/*!*/ newOwner) { + return new StringContent(newOwner, _data); + } + + #endregion + + #region Conversions + + // internal representation is immutable so we can pass it outside: + public override string/*!*/ ConvertToString() { + return _data; + } + + public override GenericRegex/*!*/ ToRegularExpression(RegexOptions options) { + return new StringRegex(_data, options); + } + + private BinaryContent/*!*/ ToBinary() { + return ToContent(_owner._encoding.GetBytes(_data)); + } + + private StringBuilderContent/*!*/ ToMutable() { + return ToContent(new StringBuilder(_data)); + } + + #endregion + + #region CompareTo + + public override int CompareTo(string/*!*/ str) { + return _data.CompareTo(str); + } + + public override int CompareTo(byte[]/*!*/ bytes) { + return ToBinary().CompareTo(bytes); + } + + public override int ReverseCompareTo(Content/*!*/ str) { + return str.CompareTo(_data); + } + + #endregion + + #region Slices + + public override char GetChar(int index) { + return _data[index]; + } + + public override byte GetByte(int index) { + return ToBinary().DataGetByte(index); + } + + public override char PeekChar(int index) { + return _data[index]; + } + + public override byte PeekByte(int index) { + byte[] bytes = new byte[4]; + _owner._encoding.GetBytes(_data, index, 1, bytes, 0); + return bytes[0]; + } + + public override string/*!*/ GetStringSlice(int start, int count) { + return _data.Substring(start, count); + } + + public override byte[]/*!*/ GetBinarySlice(int start, int count) { + return ToBinary().DataGetSlice(start, count); + } + + public override Content/*!*/ GetSlice(int start, int count) { + return new StringContent(_owner, _data.Substring(start, count)); + } + + #endregion + + #region IndexOf + + public override int IndexOf(char c, int start, int count) { + return _data.IndexOf(c, start, count); + } + + public override int IndexOf(byte b, int start, int count) { + return ToBinary().DataIndexOf(b, start, count); + } + + public override int IndexOf(string/*!*/ str, int start, int count) { + return _data.IndexOf(str, start, count); + } + + public override int IndexOf(byte[]/*!*/ bytes, int start, int count) { + return ToBinary().DataIndexOf(bytes, start, count); + } + + public override int IndexIn(Content/*!*/ str, int start, int count) { + return str.IndexOf(_data, start, count); + } + + #endregion + + #region Append + + public override Content/*!*/ Append(char c, int repeatCount) { + return ToMutable().DataAppend(c, repeatCount); + } + + public override Content/*!*/ Append(byte b, int repeatCount) { + return ToBinary().DataAppend(b, repeatCount); + } + + public override Content/*!*/ Append(string/*!*/ str, int start, int count) { + return ToMutable().DataAppend(str, start, count); + } + + public override Content/*!*/ Append(byte[]/*!*/ bytes, int start, int count) { + return ToBinary().DataAppend(bytes, start, count); + } + + public override Content/*!*/ AppendFormat(IFormatProvider provider, string/*!*/ format, object[]/*!*/ args) { + return ToMutable().DataAppendFormat(provider, format, args); + } + + public override Content/*!*/ AppendTo(Content/*!*/ str, int start, int count) { + return str.Append(_data, start, count); + } + + #endregion + + #region Insert + + public override Content/*!*/ Insert(int index, char c) { + return ToMutable().DataInsert(index, c); + } + + public override Content/*!*/ Insert(int index, byte b) { + return ToBinary().DataInsert(index, b); + } + + public override Content/*!*/ Insert(int index, string/*!*/ str, int start, int count) { + return ToMutable().DataInsert(index, str, start, count); + } + + public override Content/*!*/ Insert(int index, byte[]/*!*/ bytes, int start, int count) { + return ToBinary().DataInsert(index, bytes, start, count); + } + + public override Content/*!*/ InsertTo(Content/*!*/ str, int index, int start, int count) { + return str.Insert(index, _data, start, count); + } + + public override Content/*!*/ SetItem(int index, byte b) { + return ToBinary().DataSetByte(index, b); + } + + public override Content/*!*/ SetItem(int index, char c) { + return ToMutable().DataSetChar(index, c); + } + + #endregion + + #region Remove + + public override Content/*!*/ Remove(int start, int count) { + return ToMutable().DataRemove(start, count); + } + + #endregion + } + + [Serializable] + private sealed class StringBuilderContent : Content { + private readonly StringBuilder/*!*/ _data; + + public StringBuilderContent(MutableString/*!*/ owner, StringBuilder/*!*/ data) + : base(owner) { + Assert.NotNull(data); + _data = data; + } + + #region Utils + + public char DataGetChar(int index) { + return _data[index]; + } + + public StringBuilderContent/*!*/ DataSetChar(int index, char c) { + _data[index] = c; + return this; + } + + public string/*!*/ DataGetSlice(int start, int count) { + return _data.ToString(start, count); + } + + public int DataCompareTo(string/*!*/ str) { + // TODO + return _data.ToString().CompareTo(str); + } + + public int DataIndexOf(char c, int start, int count) { + for (int i = start; i < start + count; i++) { + if (_data[i] == c) { + return i; + } + } + return -1; + } + + public int DataIndexOf(string str, int start, int count) { + // TODO: is there a better way? + return _data.ToString().IndexOf(str, start, count); + } + + public StringBuilderContent/*!*/ DataAppend(char c, int repeatCount) { + _data.Append(c, repeatCount); + return this; + } + + public StringBuilderContent/*!*/ DataAppend(string/*!*/ str, int start, int count) { + _data.Append(str, start, count); + return this; + } + + public StringBuilderContent/*!*/ DataAppendFormat(IFormatProvider provider, string/*!*/ format, object[]/*!*/ args) { + _data.AppendFormat(provider, format, args); + return this; + } + + public StringBuilderContent/*!*/ DataInsert(int index, char c) { + _data.Insert(index, new String(c, 1)); + return this; + } + + public StringBuilderContent/*!*/ DataInsert(int index, string/*!*/ str, int start, int count) { + _data.Insert(index, str.ToCharArray(), start, count); + return this; + } + + public StringBuilderContent/*!*/ DataInsert(int index, char c, int repeatCount) { + // TODO: + _data.Insert(index, c.ToString(), repeatCount); + return this; + } + + public StringBuilderContent/*!*/ DataRemove(int start, int count) { + _data.Remove(start, count); + return this; + } + + #endregion + + #region GetHashCode, Length, Clone + + public override int GetHashCode() { + int result = 5381; + for (int i = 0; i < _data.Length; i++) { + result = unchecked(((result << 5) + result) ^ _data[i]); + } + return result; + } + + public override bool IsBinary { + get { return false; } + } + + public override int Length { + get { return _data.Length; } + } + + public override Content/*!*/ Clone(MutableString/*!*/ newOwner) { + return new StringBuilderContent(newOwner, new StringBuilder(_data.ToString())); + } + + public override void GetDebugView(out string/*!*/ value, out string/*!*/ type) { + value = _data.ToString(); + type = "String (mutable)"; + } + + #endregion + + #region Conversions + + private BinaryContent/*!*/ ToBinary() { + return ToContent(_owner._encoding.GetBytes(_data.ToString())); + } + + public override GenericRegex/*!*/ ToRegularExpression(RegexOptions options) { + return new StringRegex(_data.ToString(), options); + } + + #endregion + + #region CompareTo + + public override int CompareTo(string/*!*/ str) { + return DataCompareTo(str); + } + + public override int CompareTo(byte[]/*!*/ bytes) { + return ToBinary().CompareTo(bytes); + } + + public override int ReverseCompareTo(Content/*!*/ str) { + return str.CompareTo(_data.ToString()); + } + + #endregion + + #region Slices + + public override char GetChar(int index) { + return _data[index]; + } + + public override byte GetByte(int index) { + return ToBinary().DataGetByte(index); + } + + public override char PeekChar(int index) { + return _data[index]; + } + + public override byte PeekByte(int index) { + byte[] bytes = new byte[4]; + _owner._encoding.GetBytes(_data.ToString(), index, 1, bytes, 0); + return bytes[0]; + } + + public override string/*!*/ GetStringSlice(int start, int count) { + return _data.ToString(start, count); + } + + public override byte[]/*!*/ GetBinarySlice(int start, int count) { + return ToBinary().DataGetSlice(start, count); + } + + public override Content/*!*/ GetSlice(int start, int count) { + return new StringBuilderContent(_owner, new StringBuilder(_data.ToString(start, count))); + } + + #endregion + + #region IndexOf + + public override int IndexOf(char c, int start, int count) { + return DataIndexOf(c, start, count); + } + + public override int IndexOf(byte b, int start, int count) { + return ToBinary().DataIndexOf(b, start, count); + } + + public override int IndexOf(string/*!*/ str, int start, int count) { + return DataIndexOf(str, start, count); + } + + public override int IndexOf(byte[]/*!*/ bytes, int start, int count) { + return ToBinary().DataIndexOf(bytes, start, count); + } + + public override int IndexIn(Content/*!*/ str, int start, int count) { + return str.IndexOf(_data.ToString(), start, count); + } + + #endregion + + #region Append + + public override Content/*!*/ Append(char c, int repeatCount) { + return DataAppend(c, repeatCount); + } + + public override Content/*!*/ Append(byte b, int repeatCount) { + return ToBinary().DataAppend(b, repeatCount); + } + + public override Content/*!*/ Append(string/*!*/ str, int start, int count) { + return DataAppend(str, start, count); + } + + public override Content/*!*/ Append(byte[]/*!*/ bytes, int start, int count) { + return ToBinary().DataAppend(bytes, start, count); + } + + public override Content/*!*/ AppendFormat(IFormatProvider provider, string/*!*/ format, object[]/*!*/ args) { + return DataAppendFormat(provider, format, args); + } + + public override Content/*!*/ AppendTo(Content/*!*/ str, int start, int count) { + return str.Append(_data.ToString(), start, count); + } + + #endregion + + #region Insert + + public override Content/*!*/ Insert(int index, char c) { + return DataInsert(index, c); + } + + public override Content/*!*/ Insert(int index, byte b) { + return ToBinary().DataInsert(index, b); + } + + public override Content/*!*/ Insert(int index, string/*!*/ str, int start, int count) { + return DataInsert(index, str, start, count); + } + + public override Content/*!*/ Insert(int index, byte[]/*!*/ bytes, int start, int count) { + return ToBinary().DataInsert(index, bytes, start, count); + } + + public override Content/*!*/ InsertTo(Content/*!*/ str, int index, int start, int count) { + return str.Insert(index, _data.ToString(), start, count); + } + + public override Content/*!*/ SetItem(int index, byte b) { + return ToBinary().DataSetByte(index, b); + } + + public override Content/*!*/ SetItem(int index, char c) { + return DataSetChar(index, c); + } + + #endregion + + #region Remove + + public override Content/*!*/ Remove(int start, int count) { + return DataRemove(start, count); + } + + #endregion + } + + [Serializable] + private sealed class BinaryContent : Content { + // TODO: replace by resizable byte[] + // List is not efficient + private readonly List _data; + + internal BinaryContent(MutableString/*!*/ owner, List/*!*/ data) + : base(owner) { + Assert.NotNull(data); + _data = data; + } + + #region Utils + + private byte[]/*!*/ GetSlice(byte[]/*!*/ bytes, int start, int count) { + byte[] range = new byte[count]; + Buffer.BlockCopy(bytes, start, range, 0, count); + return range; + } + + public int DataCompareTo(byte[]/*!*/ bytes) { + if (_data.Count != bytes.Length) { + return _data.Count - bytes.Length; + } + + for (int i = 0; i < bytes.Length; i++) { + if (_data[i] != bytes[i]) { + return (int)_data[i] - bytes[i]; + } + } + + return 0; + } + + public byte DataGetByte(int index) { + return _data[index]; + } + + public BinaryContent/*!*/ DataSetByte(int index, byte b) { + _data[index] = b; + return this; + } + + public byte[]/*!*/ DataGetSlice(int start, int count) { + return GetSlice(_data.ToArray(), start, count); + } + + public BinaryContent/*!*/ DataAppend(byte b, int repeatCount) { + _data.Add(b); + return this; + } + + public BinaryContent/*!*/ DataAppend(byte[]/*!*/ bytes, int start, int count) { + _data.AddRange(bytes); + return this; + } + + public BinaryContent/*!*/ DataInsert(int index, byte b) { + _data.Insert(index, b); + return this; + } + + public BinaryContent/*!*/ DataInsert(int index, byte[]/*!*/ bytes, int start, int count) { + _data.InsertRange(index, bytes); + return this; + } + + public int DataIndexOf(byte b, int start, int count) { + for (int i = start; i < start + count; i++) { + if (_data[i] == b) { + return i; + } + } + return -1; + } + + public int DataIndexOf(byte[]/*!*/ bytes, int start, int count) { + // TODO: + for (int i = start; i < start + count - bytes.Length + 1; i++) { + bool match = true; + for (int j = 0; j < bytes.Length; j++) { + if (bytes[j] != _data[i]) { + match = false; + break; + } + } + + if (match) { + return i; + } + } + return -1; + } + + #endregion + + #region GetHashCode, Length, Clone + + public override bool IsBinary { + get { return true; } + } + + public override int GetHashCode() { + return _data.GetHashCode(); + } + + public override int Length { + get { return _data.Count; } + } + + public override Content/*!*/ Clone(MutableString/*!*/ newOwner) { + return new BinaryContent(newOwner, new List(_data)); + } + + public override void GetDebugView(out string/*!*/ value, out string/*!*/ type) { + byte[] bytes = _data.ToArray(); + value = _owner._encoding.GetString(bytes, 0, bytes.Length); + type = "String (binary)"; + } + + #endregion + + #region Conversions + + private StringBuilderContent/*!*/ ToStringBuilder() { + return ToStringBuilder(0); + } + + private StringBuilderContent/*!*/ ToStringBuilder(int additionalCapacity) { + byte[] bytes = _data.ToArray(); + string data = _owner._encoding.GetString(bytes, 0, bytes.Length); + return ToContent(new StringBuilder(data, data.Length + additionalCapacity)); + } + + public override GenericRegex/*!*/ ToRegularExpression(RegexOptions options) { + return new BinaryRegex(_data.ToArray(), options); + } + + #endregion + + #region CompareTo + + public override int CompareTo(string/*!*/ str) { + return ToStringBuilder().DataCompareTo(str); + } + + public override int CompareTo(byte[]/*!*/ bytes) { + return DataCompareTo(bytes); + } + + public override int ReverseCompareTo(Content/*!*/ str) { + return str.CompareTo(_data.ToArray()); + } + + #endregion + + #region Slices + + public override char GetChar(int index) { + return ToStringBuilder().DataGetChar(index); + } + + public override byte GetByte(int index) { + return DataGetByte(index); + } + + public override char PeekChar(int index) { + // TODO: max bytes per char? + int bc = _data.Count < 8 ? _data.Count : 8; + return _owner._encoding.GetChars(_data.ToArray(), index, bc)[0]; + } + + public override byte PeekByte(int index) { + return _data[index]; + } + + public override string/*!*/ GetStringSlice(int start, int count) { + return ToStringBuilder().DataGetSlice(start, count); + } + + public override byte[]/*!*/ GetBinarySlice(int start, int count) { + return DataGetSlice(start, count); + } + + public override Content/*!*/ GetSlice(int start, int count) { + return new BinaryContent(_owner, new List(DataGetSlice(start, count))); + } + + #endregion + + #region IndexOf + + public override int IndexOf(char c, int start, int count) { + return ToStringBuilder().DataIndexOf(c, start, count); + } + + public override int IndexOf(byte b, int start, int count) { + return DataIndexOf(b, start, count); + } + + public override int IndexOf(string/*!*/ str, int start, int count) { + return ToStringBuilder().DataIndexOf(str, start, count); + } + + public override int IndexOf(byte[]/*!*/ bytes, int start, int count) { + return DataIndexOf(bytes, start, count); + } + + public override int IndexIn(Content/*!*/ str, int start, int count) { + return str.IndexOf(_data.ToArray(), start, count); + } + + #endregion + + #region Append + + public override Content/*!*/ Append(char c, int repeatCount) { + return ToStringBuilder(repeatCount).DataAppend(c, repeatCount); + } + + public override Content/*!*/ Append(byte b, int repeatCount) { + return DataAppend(b, repeatCount); + } + + public override Content/*!*/ Append(string/*!*/ str, int start, int count) { + return ToStringBuilder(count).DataAppend(str, start, count); + } + + public override Content/*!*/ Append(byte[]/*!*/ bytes, int start, int count) { + return DataAppend(bytes, start, count); + } + + public override Content/*!*/ AppendFormat(IFormatProvider provider, string/*!*/ format, object[]/*!*/ args) { + return ToStringBuilder().DataAppendFormat(provider, format, args); + } + + public override Content/*!*/ AppendTo(Content/*!*/ str, int start, int count) { + return str.Append(_data.ToArray(), start, count); + } + + #endregion + + #region Insert + + public override Content/*!*/ Insert(int index, char c) { + return ToStringBuilder(1).DataInsert(index, c); + } + + public override Content/*!*/ Insert(int index, byte b) { + return DataInsert(index, b); + } + + public override Content/*!*/ Insert(int index, string/*!*/ str, int start, int count) { + return ToStringBuilder(count).DataInsert(index, str, start, count); + } + + public override Content/*!*/ Insert(int index, byte[]/*!*/ bytes, int start, int count) { + return DataInsert(index, bytes, start, count); + } + + public override Content/*!*/ InsertTo(Content/*!*/ str, int index, int start, int count) { + return str.Insert(index, _data.ToArray(), start, count); + } + + public override Content/*!*/ SetItem(int index, byte b) { + return DataSetByte(index, b); + } + + public override Content/*!*/ SetItem(int index, char c) { + return ToStringBuilder().DataSetChar(index, c); + } + + #endregion + + #region Remove + + public override Content/*!*/ Remove(int start, int count) { + _data.RemoveRange(start, count); + return this; + } + + #endregion + } + } +} =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.cs;C417565 File: MutableString.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.cs;C417565 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/MutableString.cs;MutableString5 @@ -18,216 +18,214 @@ using Microsoft.Scripting; using Microsoft.Scripting.Utils; using Ruby.Runtime; +using System.Text.RegularExpressions; +using System.Collections.Generic; +using System.Diagnostics; +using Microsoft.Scripting.Runtime; namespace Ruby.Builtins { + // TODO: + public abstract class MutableStringBase { + protected abstract string/*!*/ BaseToString(); + + public sealed override string/*!*/ ToString() { + return BaseToString(); + } + } + [Serializable] - public class MutableString : IEquatable, IDuplicable { - // StringBuilder will eventually be replaced by a byte[] - private readonly StringBuilder/*!*/ _data; + [DebuggerDisplay("{GetDebugValue()}", Type = "{GetDebugType()}")] + public partial class MutableString : MutableStringBase, IEquatable, IComparable, IDuplicable { + private Content/*!*/ _content; + private Encoding/*!*/ _encoding; - private int CalculateNextPowerOfTwo(int v) { - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - return v++; - } + #region Construction - // TODO: make explicit! - public static implicit operator string(MutableString/*!*/ self) { - return self.ToString(); + private MutableString(Content/*!*/ content, Encoding/*!*/ encoding) { + Assert.NotNull(content); + content.SetOwner(this); + _content = content; + _encoding = encoding; } - public MutableString() { - _data = new StringBuilder(); + private void SetContent(Content/*!*/ content) { + Assert.NotNull(content); + _content = content; } - public MutableString(char c) { - _data = new StringBuilder(); - _data.Append(c); + private MutableString(MutableString/*!*/ str) { + Assert.NotNull(str); + _content = str._content.Clone(this); + _encoding = str._encoding; } - public MutableString(int capacity) { - _data = new StringBuilder(capacity); + // mutable + private MutableString(StringBuilder/*!*/ sb, Encoding/*!*/ encoding) { + _content = new StringBuilderContent(this, sb); + _encoding = encoding; } - public MutableString(SymbolId symbol) { - _data = new StringBuilder(SymbolTable.IdToString(symbol)); + // binary + private MutableString(List/*!*/ bytes, Encoding/*!*/ encoding) { + _content = new BinaryContent(this, bytes); + _encoding = encoding; } - - public MutableString(string str) { - _data = new StringBuilder(str != null ? str : String.Empty); + + // immutable + private MutableString(string/*!*/ str, Encoding/*!*/ encoding) { + _content = new StringContent(this, str); + _encoding = encoding; } - public MutableString(MutableString str) { - _data = new StringBuilder(str != null ? str.ToString() : null); + // for Ruby derived classes: + // TODO: protected + public MutableString(CodeContext/*!*/ context) + : this(new StringBuilder(), StringUtils.DefaultEncoding) { } - public MutableString(string/*!*/ str, int startIndex, int charCount) { - ContractUtils.RequiresNotNull(str, "str"); - ContractUtils.RequiresArrayRange(str, startIndex, charCount, "startIndex", "charCount"); - - _data = new StringBuilder(str, startIndex, charCount, charCount > 0 ? CalculateNextPowerOfTwo(charCount) : 0); + public static MutableString/*!*/ CreateEmpty() { + return new MutableString(new StringBuilder(0), StringUtils.DefaultEncoding); } - public MutableString(byte[]/*!*/ bytes, int startIndex, int count) { - ContractUtils.RequiresNotNull(bytes, "bytes"); - ContractUtils.RequiresArrayRange(bytes, startIndex, count, "startIndex", "count"); - - _data = new StringBuilder(count); - for (int i = startIndex; i < count; i++) { - _data.Append((char)bytes[i]); - } + public static MutableString/*!*/ CreateMutable() { + return new MutableString(new StringBuilder(), StringUtils.DefaultEncoding); } - public char this[int index] { - get { return _data[index]; } - set { _data[index] = value; } + public static MutableString/*!*/ CreateMutable(int capacity) { + return new MutableString(new StringBuilder(capacity), StringUtils.DefaultEncoding); } - public StringBuilder/*!*/ Chars { - get { return _data; } + public static MutableString/*!*/ CreateMutable(string/*!*/ str, int capacity) { + return new MutableString(new StringBuilder(str, capacity), StringUtils.DefaultEncoding); } - public MutableString/*!*/ Append(string str) { - _data.Append(str); - return this; + public static MutableString/*!*/ CreateMutable(string/*!*/ str) { + return new MutableString(new StringBuilder(str), StringUtils.DefaultEncoding); } - public MutableString/*!*/ Append(string/*!*/ str, int startIndex, int charCount) { + public static MutableString/*!*/ Create(string str) { ContractUtils.RequiresNotNull(str, "str"); - ContractUtils.RequiresArrayRange(str, startIndex, charCount, "startIndex", "charCount"); - - _data.Append(str, startIndex, charCount); - return this; + return new MutableString(str, StringUtils.DefaultEncoding); } - public MutableString/*!*/ Append(char value) { - _data.Append(value); - return this; + public static MutableString/*!*/ Create(SymbolId/*!*/ symbol) { + return new MutableString(SymbolTable.IdToString(symbol), StringUtils.DefaultEncoding); } - public MutableString/*!*/ Append(char value, int repeatCount) { - _data.Append(value, repeatCount); - return this; + public static MutableString/*!*/ Create(MutableString/*!*/ str) { + ContractUtils.RequiresNotNull(str, "str"); + return new MutableString(str); } - public MutableString/*!*/ Append(MutableString/*!*/ str) { - if (str != null) { - _data.Append(str.Chars); - } - return this; + public static MutableString/*!*/ CreateBinary() { + return new MutableString(new List(), StringUtils.DefaultEncoding); } - public MutableString/*!*/ Append(object obj) { - _data.Append(obj); - return this; + public static MutableString/*!*/ CreateBinary(int capacity) { + return new MutableString(new List(capacity), StringUtils.DefaultEncoding); } - public MutableString/*!*/ AppendFormat(string/*!*/ format, object arg0) { - _data.AppendFormat(format, arg0); - return this; + public static MutableString/*!*/ CreateBinary(byte[]/*!*/ bytes) { + ContractUtils.RequiresNotNull(bytes, "bytes"); + return CreateBinary((IList)bytes, bytes.Length); } - public MutableString/*!*/ AppendFormat(string/*!*/ format, object arg0, object arg1) { - _data.AppendFormat(format, arg0, arg1); - return this; + public static MutableString/*!*/ CreateBinary(IList/*!*/ bytes) { + ContractUtils.RequiresNotNull(bytes, "bytes"); + return CreateBinary(bytes, bytes.Count); } - public MutableString/*!*/ AppendFormat(string/*!*/ format, object arg0, object arg1, object arg2) { - _data.AppendFormat(format, arg0, arg1, arg2); - return this; + public static MutableString/*!*/ CreateBinary(byte[]/*!*/ bytes, int capacity) { + return CreateBinary((IList)bytes, capacity); } - public MutableString/*!*/ AppendFormat(string/*!*/ format, params object[] args) { - _data.AppendFormat(format, args); - return this; + public static MutableString/*!*/ CreateBinary(IList/*!*/ bytes, int capacity) { + ContractUtils.RequiresNotNull(bytes, "bytes"); + List list = new List(capacity); + list.AddRange(bytes); + return new MutableString(list, StringUtils.DefaultEncoding); } - public MutableString/*!*/ AppendFormat(IFormatProvider/*!*/ provider, string/*!*/ format, params object[] args) { - _data.AppendFormat(provider, format, args); - return this; - } - - public MutableString/*!*/ Insert(int index, string value) { - _data.Insert(index, value); - return this; - } - - public MutableString/*!*/ Insert(int index, MutableString value) { - if (value != null) { - _data.Insert(index, value.ToString()); + public static MutableString[]/*!*/ MakeArray(params string[]/*!*/ strArray) { + ContractUtils.RequiresNotNull(strArray, "strArray"); + MutableString[] result = new MutableString[strArray.Length]; + for (int i = 0; i < result.Length; i++) { + result[i] = MutableString.Create(strArray[i]); } - return this; + return result; } - // TODO: write a real implementation instead of converting to string first and then calling String.IndexOf() - public int IndexOf(char c) { - return _data.ToString().IndexOf(c); - } + #endregion - public int IndexOf(char c, int index) { - return _data.ToString().IndexOf(c, index); - } + #region Conversions - public int IndexOf(string str) { - return _data.ToString().IndexOf(str); + public GenericRegex/*!*/ ToRegularExpression(RegexOptions options) { + return _content.ToRegularExpression(options); } - public int IndexOf(MutableString/*!*/ self) { - return _data.ToString().IndexOf(self.ToString()); + public SymbolId ToSymbol() { + return SymbolTable.StringToId(_content.GetStringSlice(0, _content.Length)); } - public int IndexOf(string str, int offset) { - return _data.ToString().IndexOf(str, offset); + /// + /// Switches internal representation to textual. + /// + /// A copy of the internal representation unless it is immutable (string). + public string/*!*/ ConvertToString() { + return _content.ConvertToString(); } - public int IndexOf(MutableString/*!*/ self, int offset) { - return _data.ToString().IndexOf(self.ToString(), offset); + /// + /// Switches internal representation to binary. + /// + /// A copy of the internal representation. + public byte[]/*!*/ ConvertToBytes() { + return _content.ConvertToBytes(); } - public int CompareTo(MutableString/*!*/ other) { - return _data.ToString().CompareTo(other); + // used by auto-conversions + [Obsolete("Do not use in code")] + public static implicit operator string(MutableString/*!*/ self) { + return self._content.ConvertToString(); } - public MutableString Remove(int position, int count) { - _data.Remove(position, count); - return this; + // used by auto-conversions + [Obsolete("Do not use in code")] + public static implicit operator byte[](MutableString/*!*/ self) { + return self._content.ConvertToBytes(); } - public MutableString Substring(int start) { - return new MutableString(_data.ToString(), start, _data.Length - start); - } + #endregion - public MutableString Substring(int start, int length) { - return new MutableString(_data.ToString(), start, length); + #region Comparisons + + public static bool operator ==(MutableString self, char other) { + return Equals(self, other); } - public void Clear() { - _data.Remove(0, _data.Length); + public static bool operator !=(MutableString self, char other) { + return !Equals(self, other); } - public int Length { - get { return _data.Length; } + public static bool operator ==(MutableString self, MutableString other) { + return Equals(self, other); } - public override string ToString() { - return _data.ToString(); + public static bool operator !=(MutableString self, MutableString other) { + return !Equals(self, other); } - public byte[]/*!*/ ToByteArray() { - byte[] bytes = new byte[_data.Length]; - for (int i = 0; i < bytes.Length; i++) { - bytes[i] = (byte)_data[i]; - } - return bytes; + private static bool Equals(MutableString self, MutableString other) { + if (ReferenceEquals(self, other)) return true; + if (ReferenceEquals(self, null)) return false; + if (ReferenceEquals(other, null)) return false; + return other._content.ReverseCompareTo(self._content) == 0; } - public SymbolId ToSymbol() { - return SymbolTable.StringToId(_data.ToString()); + private static bool Equals(MutableString self, char other) { + if (ReferenceEquals(self, null)) return false; + return self.Length == 1 && self.GetChar(0) == other; } public override bool Equals(object other) { @@ -235,190 +233,436 @@ } public bool Equals(MutableString other) { - if (ReferenceEquals(this, other)) return true; - if (other == null) return false; - if (_data.Length != other.Length) return false; + return CompareTo(other) == 0; + } - for (int i = 0; i < _data.Length; ++i) - if (_data[i] != other.Chars[i]) - return false; + public int CompareTo(MutableString other) { + if (ReferenceEquals(this, other)) return 0; + if (ReferenceEquals(other, null)) return 1; + return other._content.ReverseCompareTo(_content); + } - return true; + public static bool IsNullOrEmpty(MutableString/*!*/ str) { + return ReferenceEquals(str, null) || str.Length == 0; } - public override int GetHashCode() { - // Can't use _data.GetHashCode() because StringBuilder - // doesn't implement it. - // TODO: fix this to be an O(1) hash algorithm - return _data.ToString().GetHashCode(); + #endregion + + #region StartsWith, EndsWith + + public bool EndsWith(char value) { + return GetLastChar() == value; } + + public bool EndsWith(string/*!*/ value) { + // TODO: + return _content.ConvertToString().EndsWith(value); + } + + #endregion - void IDuplicable.InitializeFrom(object other) { - MutableString str = other as MutableString; - ContractUtils.Requires(str != null && _data.Length == 0); - _data.Append(str.ToString()); + #region Slices + + // converts the result, not the string + public char PeekChar(int index) { + return _content.PeekChar(index); } - } -#if false - public class MutableStringNextGen { + // converts the result, not the string + public byte PeekByte(int index) { + return _content.PeekByte(index); + } - //^ invariant (_chars == null || _string == null) == (_bytes != null) - //^ invariant (_bytes != null) == (_encoding != null) - //^ invariant (_bytes != null) ==> (_count <= _bytes.length) - //^ invariant (_chars != null) ==> (_count <= _chars.length) - //^ invariant (_count >= 0) + // converts the string representation to text if not already + public char GetChar(int index) { + return _content.GetChar(index); + } - private byte[] _bytes; - private char[] _chars; - private string _string; - private int _byteBufferSize; - private int _charBufferSize; + // converts the string representation to binary if not already + public byte GetByte(int index) { + return _content.GetByte(index); + } - // When we convert to a CLR string, this flag indicates that we need to enable - // round-tripping of the encoding. - private bool _preserveEncoding; + // returns -1 if the string is empty + public int GetLastChar() { + return (_content.Length > 0) ? _content.GetChar(0) : -1; + } - // Used whenever we convert to Unicode (for scenarios like upcase and downcase) - private Encoding _encoding; + /// + /// Returns a new mutable string containing a substring of the current one. + /// + public MutableString/*!*/ GetSlice(int start) { + return GetSlice(start, Length - start); + } - public MutableStringNextGen() { - _charBufferSize = 0; - _chars = null; + public MutableString/*!*/ GetSlice(int start, int count) { + RequiresArrayRange(start, count); + return new MutableString(_content.GetSlice(start, count), _encoding); } - public MutableStringNextGen(byte[]/*!*/ bytes, Encoding/*!*/ encoding) : this(bytes, encoding, false) { } + public string/*!*/ GetStringSlice(int start) { + return GetStringSlice(start, Length - start); + } - public MutableStringNextGen(byte[]/*!*/ bytes, Encoding/*!*/ encoding, bool preserveEncoding) { - Assert.NotNull(bytes, encoding); - _bytes = bytes; - _byteBufferSize = bytes.Length; - _string = null; - _encoding = encoding; - _preserveEncoding = preserveEncoding; + public string/*!*/ GetStringSlice(int start, int count) { + RequiresArrayRange(start, count); + return _content.GetStringSlice(start, count); } - public MutableStringNextGen(string str) { - Assert.NotNull(str); - _bytes = null; - _byteBufferSize = 0; - _string = str; - _encoding = null; - _preserveEncoding = false; + public byte[]/*!*/ GetBinarySlice(int start) { + return GetBinarySlice(start, Length - start); } - public static void AssociateEncoding(string str, Encoding encoding) { - // spooky hashtable magic + public byte[]/*!*/ GetBinarySlice(int start, int count) { + RequiresArrayRange(start, count); + return _content.GetBinarySlice(start, count); } - public static Encoding/*!*/ GetAssociatedEncoding(string str) { - // return default encoding if we can't find it in the weak hash - return Encoding.UTF8; + #endregion + + #region Split, Join, Trim + + // TODO: binary ops, ... + public MutableString[]/*!*/ Split(char[]/*!*/ separators, int maxComponents, StringSplitOptions options) { + // TODO: + return MakeArray(StringUtils.Split(_content.ConvertToString(), separators, maxComponents, options)); } + + #endregion - public Encoding Encoding { - get { return _encoding == null ? Encoding.UTF8 : _encoding; } + #region IndexOf + + public int IndexOf(char value) { + return IndexOf(value, 0, Length); } - public char[] Chars { - get { - if (_chars == null) { - _chars = _string.ToCharArray(); - _charBufferSize = _chars.Length; - } - return _chars; + public int IndexOf(char value, int start) { + return IndexOf(value, start, Length - start); + } + + public int IndexOf(char value, int start, int count) { + RequiresArrayRange(start, count); + return _content.IndexOf(value, start, count); + } + + public int IndexOf(byte value) { + return IndexOf(value, 0); + } + + public int IndexOf(byte value, int start) { + return IndexOf(value, start, Length - start); + } + + public int IndexOf(byte value, int start, int count) { + RequiresArrayRange(start, count); + return _content.IndexOf(value, start, count); + } + + public int IndexOf(string/*!*/ value) { + return IndexOf(value, 0, Length); + } + + public int IndexOf(string/*!*/ value, int start) { + return IndexOf(value, start, Length - start); + } + + public int IndexOf(string/*!*/ value, int start, int count) { + ContractUtils.RequiresNotNull(value, "value"); + RequiresArrayRange(start, count); + + return _content.IndexOf(value, start, count); + } + + public int IndexOf(byte[]/*!*/ value) { + return IndexOf(value, 0, Length); + } + + public int IndexOf(byte[]/*!*/ value, int start) { + return IndexOf(value, start, Length - start); + } + + public int IndexOf(byte[]/*!*/ value, int start, int count) { + ContractUtils.RequiresNotNull(value, "value"); + RequiresArrayRange(start, count); + + return _content.IndexOf(value, start, count); + } + + public int IndexOf(MutableString/*!*/ value) { + return IndexOf(value, 0, Length); + } + + public int IndexOf(MutableString/*!*/ value, int start) { + return IndexOf(value, start, Length - start); + } + + public int IndexOf(MutableString/*!*/ value, int start, int count) { + ContractUtils.RequiresNotNull(value, "value"); + RequiresArrayRange(start, count); + + return value._content.IndexIn(_content, start, count); + } + + #endregion + + #region Append + + public MutableString/*!*/ Append(char value) { + _content.Append(value, 1); + return this; + } + + public MutableString/*!*/ Append(char value, int repeatCount) { + _content.Append(value, repeatCount); + return this; + } + + public MutableString/*!*/ Append(byte value) { + _content.Append(value, 1); + return this; + } + + public MutableString/*!*/ Append(byte value, int repeatCount) { + _content.Append(value, repeatCount); + return this; + } + + public MutableString/*!*/ Append(SymbolId value) { + return Append(SymbolTable.IdToString(value)); + } + + public MutableString/*!*/ Append(StringBuilder value) { + if (value != null) { + _content.Append(value.ToString(), 0, value.Length); } + return this; } - public byte[] Bytes { - get { - if (_bytes == null) { - _bytes = _chars == null ? Encoding.GetBytes(_string) : Encoding.GetBytes(_chars); - _byteBufferSize = _bytes.Length; - } - return _bytes; + public MutableString/*!*/ Append(string value) { + if (value != null) { + _content.Append(value, 0, value.Length); } + return this; } - public int Length { - get { - if (_chars != null) - return _charBufferSize; - else if (_bytes != null) - return _byteBufferSize; - else - return _string.Length; + public MutableString/*!*/ Append(string/*!*/ value, int startIndex, int charCount) { + ContractUtils.RequiresNotNull(value, "value"); + ContractUtils.RequiresArrayRange(value, startIndex, charCount, "startIndex", "charCount"); + + _content.Append(value, startIndex, charCount); + return this; + } + + public MutableString/*!*/ Append(byte[] value) { + if (value != null) { + _content.Append(value, 0, value.Length); } + return this; } - public override string ToString() { - if (Chars != null) { - return new string(Chars); - } else { - string result = _encoding.GetString(_bytes); - if (_preserveEncoding) { - AssociateEncoding(result, _encoding); - } - return result; + public MutableString/*!*/ Append(byte[]/*!*/ value, int start, int count) { + ContractUtils.RequiresNotNull(value, "value"); + ContractUtils.RequiresArrayRange(value, start, count, "startIndex", "count"); + + _content.Append(value, start, count); + return this; + } + + public MutableString/*!*/ Append(MutableString/*!*/ value) { + if (value != null) { + value._content.AppendTo(_content, 0, value.Length); } + return this; } - public byte GetByte(int index) { - return Bytes[index]; + public MutableString/*!*/ Append(MutableString/*!*/ str, int start, int count) { + ContractUtils.RequiresNotNull(str, "str"); + str.RequiresArrayRange(start, count); + + str._content.AppendTo(_content, start, count); + return this; } - public char GetChar(int index) { - return Chars[index]; + public MutableString/*!*/ AppendFormat(string/*!*/ format, params object[] args) { + return AppendFormat(null, format, args); } - public void SetChar(int index, char value) { - Chars[index] = value; + public MutableString/*!*/ AppendFormat(IFormatProvider provider, string/*!*/ format, params object[] args) { + ContractUtils.RequiresNotNull(format, "format"); + _content.AppendFormat(provider, format, args); + return this; } - public void SetByte(int index, byte value) { - Bytes[index] = value; + #endregion + + #region Insert + + public MutableString/*!*/ SetChar(int index, char c) { + _content.SetItem(index, c); + return this; } - private int CalculateNextPowerOfTwo(int v) { - v--; - v |= v >> 1; - v |= v >> 2; - v |= v >> 4; - v |= v >> 8; - v |= v >> 16; - return v++; + public MutableString/*!*/ SetByte(int index, byte b) { + _content.SetItem(index, b); + return this; } - private void ExpandByteBuffer(int desiredSize) { - int newSize = CalculateNextPowerOfTwo(desiredSize); - byte[] current = _bytes; - _bytes = new byte[newSize]; - Array.Copy(current, _bytes, current.Length); + public MutableString/*!*/ Insert(int index, char c) { + RequiresArrayInsertIndex(index); + _content.Insert(index, c); + return this; } - private void ExpandCharBuffer(int desiredSize) { - int newSize = CalculateNextPowerOfTwo(desiredSize); - char[] current = _chars; - _chars = new char[newSize]; - Array.Copy(current, _chars, current.Length); + public MutableString/*!*/ Insert(int index, byte b) { + RequiresArrayInsertIndex(index); + _content.Insert(index, b); + return this; } - public void Append(byte[] bytes) { - if (_byteBufferSize + bytes.Length > _bytes.Length) - ExpandByteBuffer(_byteBufferSize + bytes.Length); + public MutableString/*!*/ Insert(int index, string value) { + RequiresArrayInsertIndex(index); + if (value != null) { + _content.Insert(index, value, 0, value.Length); + } + return this; + } - Array.Copy(bytes, 0, _bytes, _byteBufferSize, bytes.Length); - _byteBufferSize += bytes.Length; + public MutableString/*!*/ Insert(int index, string/*!*/ value, int start, int count) { + RequiresArrayInsertIndex(index); + ContractUtils.RequiresNotNull(value, "value"); + ContractUtils.RequiresArrayRange(value, start, count, "start", "count"); + + _content.Insert(index, value, start, count); + return this; } - public void Append(string str) { - char[] chars = str.ToCharArray(); - if (_charBufferSize + chars.Length > _chars.Length) - ExpandCharBuffer(_charBufferSize + chars.Length); + public MutableString/*!*/ Insert(int index, byte[] value) { + RequiresArrayInsertIndex(index); + if (value != null) { + _content.Insert(index, value, 0, value.Length); + } + return this; + } - Array.Copy(chars, 0, _chars, _charBufferSize, chars.Length); - _charBufferSize += chars.Length; + public MutableString/*!*/ Insert(int index, byte[]/*!*/ value, int start, int count) { + RequiresArrayInsertIndex(index); + ContractUtils.RequiresNotNull(value, "value"); + ContractUtils.RequiresArrayRange(value, start, count, "start", "count"); + + _content.Insert(index, value, start, count); + return this; } + + public MutableString/*!*/ Insert(int index, MutableString value) { + RequiresArrayInsertIndex(index); + if (value != null) { + value._content.InsertTo(_content, index, 0, value.Length); + } + return this; + } + + public MutableString/*!*/ Insert(int index, MutableString/*!*/ value, int start, int count) { + RequiresArrayInsertIndex(index); + ContractUtils.RequiresNotNull(value, "value"); + value.RequiresArrayRange(start, count); + + value._content.InsertTo(_content, index, start, count); + return this; + } + + #endregion + + #region Replace + + public MutableString/*!*/ Replace(int start, int count, MutableString value) { + RequiresArrayRange(start, count); + + // TODO: + return Remove(start, count).Insert(start, value); + } + + #endregion + + #region Remove, Clear + + public MutableString/*!*/ Remove(int start, int count) { + RequiresArrayRange(start, count); + _content.Remove(start, count); + return this; + } + + public void Clear() { + _content = _content.GetSlice(0, 0); + } + + #endregion + + #region Misc + + public bool IsBinary { + get { + return _content.IsBinary; + } + } + + public override int GetHashCode() { + return _content.GetHashCode(); + } + + public int Length { + get { return _content.Length; } + } + + void IDuplicable.InitializeFrom(object other) { + MutableString str = other as MutableString; + ContractUtils.Requires(str != null && Length == 0); + _encoding = str._encoding; + _content = str._content.Clone(this); + } + + protected override string BaseToString() { + return ConvertToString(); + } + + [Obsolete("Use ConvertToString()")] + public new string ToString() { + throw new InvalidOperationException(); + } + + internal string/*!*/ GetDebugValue() { + string value, type; + _content.GetDebugView(out value, out type); + return value; + } + + internal string/*!*/ GetDebugType() { + string value, type; + _content.GetDebugView(out value, out type); + return type; + } + + #endregion + + #region Utils + + /// + /// Requires the range [offset, offset + count] to be a subset of [0, array.Count]. + /// + /// String is null. + /// Offset or count are out of range. + private void RequiresArrayRange(int start, int count) { + if (count < 0) throw new ArgumentOutOfRangeException("count"); + if (start < 0 || _content.Length - start < count) throw new ArgumentOutOfRangeException("start"); + } + + /// + /// Requires the specified index to point inside the array or at the end + /// + /// Index is outside the array. + private void RequiresArrayInsertIndex(int index) { + if (index < 0 || index > Length) throw new ArgumentOutOfRangeException("index"); + } + + #endregion } -#endif } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/Regexp.cs;C428766 File: Regexp.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/Regexp.cs;C428766 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/Regexp.cs;MutableString5 @@ -16,33 +16,184 @@ using System.Text.RegularExpressions; using Microsoft.Scripting.Utils; using Ruby.Runtime; +using System; namespace Ruby.Builtins { - public class Regexp : IDuplicable { - private Regex/*!*/ _regex; - - public Regex/*!*/ Regex { get { return _regex; } } + public abstract class GenericRegex { + public abstract bool IsEmpty { get; } + public abstract MutableString/*!*/ GetPatern(); - public Regexp() { } + public abstract Match/*!*/ Match(MutableString/*!*/ input, int start, int count); + public abstract MatchCollection/*!*/ Matches(MutableString/*!*/ input, int start); + public abstract MutableString[]/*!*/ Split(MutableString/*!*/ input, int count, int start); - public Regexp(Regex/*!*/ regex) { + protected GenericRegex() { + } + } + + public class BinaryRegex : GenericRegex { + private readonly byte[]/*!*/ _pattern; + private readonly RegexOptions _options; + + internal protected BinaryRegex(byte[]/*!*/ pattern, RegexOptions options) { + Assert.NotNull(pattern); + _pattern = ArrayUtils.Copy(pattern); + _options = options; + } + + public override bool IsEmpty { + get { return _pattern.Length == 0; } + } + + public override Match/*!*/ Match(MutableString/*!*/ input, int start, int count) { + throw new NotImplementedException(); + } + + public override MatchCollection/*!*/ Matches(MutableString/*!*/ input, int start) { + throw new NotImplementedException(); + } + + public override MutableString/*!*/ GetPatern() { + return MutableString.CreateBinary(_pattern); + } + + public override MutableString[]/*!*/ Split(MutableString/*!*/ input, int count, int start) { + throw new NotImplementedException(); + } + } + + public class StringRegex : GenericRegex { + internal static readonly StringRegex Empty = new StringRegex(new Regex(String.Empty, RegexOptions.None)); + + private readonly Regex/*!*/ _regex; + + internal protected StringRegex(string/*!*/ pattern, RegexOptions options) { + Assert.NotNull(pattern); + _regex = new Regex(pattern, options); + } + + internal protected StringRegex(Regex/*!*/ regex) { + Assert.NotNull(regex); + _regex = regex; + } + + public override bool IsEmpty { + get { return _regex.ToString().Length == 0; } + } + + public override Match/*!*/ Match(MutableString/*!*/ input, int start, int count) { + return _regex.Match(input.ConvertToString(), start, count); + } + + public override MatchCollection Matches(MutableString/*!*/ input, int start) { + return _regex.Matches(input.ConvertToString(), start); + } + + public override MutableString/*!*/ GetPatern() { + return MutableString.Create(_regex.ToString()); + } + + public override MutableString[]/*!*/ Split(MutableString/*!*/ input, int count, int start) { + return MutableString.MakeArray(_regex.Split(input.ConvertToString(), count, start)); + } + } + + public class RubyRegex : IDuplicable { + private GenericRegex/*!*/ _regex; + + public RubyRegex() { + _regex = StringRegex.Empty; + } + + public RubyRegex(MutableString/*!*/ pattern, RegexOptions options) { + ContractUtils.RequiresNotNull(pattern, "pattern"); + _regex = pattern.ToRegularExpression(options); + } + + public RubyRegex(string/*!*/ pattern, RegexOptions options) { + ContractUtils.RequiresNotNull(pattern, "pattern"); + _regex = new StringRegex(pattern, options); + } + + public RubyRegex(byte[]/*!*/ pattern, RegexOptions options) { + ContractUtils.RequiresNotNull(pattern, "pattern"); + _regex = new BinaryRegex(pattern, options); + } + + public RubyRegex(Regex/*!*/ regex) { ContractUtils.RequiresNotNull(regex, "regex"); - _regex = regex; + _regex = new StringRegex(regex); } - public Regexp(MutableString/*!*/ str) { - ContractUtils.RequiresNotNull(str, "str"); - _regex = new Regex(str); + public bool IsEmpty { + get { return _regex.IsEmpty; } } + public MutableString/*!*/ GetPattern() { + return _regex.GetPatern(); + } + + public Match/*!*/ Match(MutableString/*!*/ input) { + return Match(input, 0); + } + + public Match/*!*/ Match(MutableString/*!*/ input, int start) { + ContractUtils.RequiresNotNull(input, "input"); + return Match(input, start, input.Length - start); + } + + public Match/*!*/ Match(MutableString/*!*/ input, int start, int count) { + ContractUtils.RequiresNotNull(input, "input"); + return _regex.Match(input, start, count); + } + + public MatchCollection/*!*/ Matches(MutableString/*!*/ input) { + return Matches(input, 0); + } + + public MatchCollection/*!*/ Matches(MutableString/*!*/ input, int start) { + ContractUtils.RequiresNotNull(input, "input"); + return _regex.Matches(input, start); + } + + public MutableString[]/*!*/ Split(MutableString/*!*/ input) { + return _regex.Split(input, 0, 0); + } + + public MutableString[]/*!*/ Split(MutableString/*!*/ input, int count) { + return _regex.Split(input, count, 0); + } + + public MutableString[]/*!*/ Split(MutableString/*!*/ input, int count, int start) { + return _regex.Split(input, count, start); + } + + // TODO: + public static MutableString/*!*/ Escape(MutableString/*!*/ str) { + return MutableString.Create(Regex.Escape(str.ConvertToString())); + } + #region IDuplicable Members public void InitializeFrom(object other) { - Regexp regexp = other as Regexp; + RubyRegex regexp = other as RubyRegex; ContractUtils.Requires(regexp != null); _regex = regexp._regex; } #endregion + + public static RegexOptions ToClrOptions(Ruby.Compiler.Ast.RegExOptions options) { + RegexOptions result = RegexOptions.None; + + if ((options & Ruby.Compiler.Ast.RegExOptions.IGNORECASE) > 0) + result |= RegexOptions.IgnoreCase; + if ((options & Ruby.Compiler.Ast.RegExOptions.MULTILINE) > 0) + result |= RegexOptions.Multiline; + if ((options & Ruby.Compiler.Ast.RegExOptions.SINGLELINE) > 0) + result |= RegexOptions.Singleline; + + return result; + } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyInputProvider.cs;C413883 File: RubyInputProvider.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyInputProvider.cs;C413883 (server) 5/8/2008 1:12 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyInputProvider.cs;MutableString5 @@ -66,7 +66,7 @@ public MutableString/*!*/ CurrentFileName { get { // TODO: - return new MutableString("-"); + return MutableString.Create("-"); } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C434537 File: RubyModule.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;C434537 (server) 5/8/2008 1:14 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Builtins/RubyModule.cs;MutableString5 @@ -706,7 +706,7 @@ if (IsSingletonClass) { RubyClass c = (RubyClass)this; object singletonOf; - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); int nestings = 0; while (true) { @@ -735,7 +735,7 @@ } return result.Append('>', nestings); } else if (_name.IsEmpty) { - MutableString result = new MutableString(); + MutableString result = MutableString.CreateMutable(); result.Append("#<"); result.Append(SymbolTable.IdToString(_executionContext.GetClassOf(this).Name)); result.Append(':'); @@ -743,7 +743,7 @@ result.Append('>'); return result; } else { - return new MutableString(_name); + return MutableString.Create(_name); } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/RegularExpression.cs;C413883 File: RegularExpression.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/RegularExpression.cs;C413883 (server) 5/8/2008 3:57 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Expressions/RegularExpression.cs;MutableString5 @@ -48,9 +48,9 @@ internal override MSA.Expression/*!*/ TransformRead(AstGenerator/*!*/ gen) { // TODO: if (_pattern.Count == 1) { - return AstFactory.OpCall("CreateRegex", Ast.Constant(_options), _pattern[0].TransformRead(gen)); + return AstFactory.OpCall("CreateRegex", Ast.CodeContext(), Ast.Constant(_options), _pattern[0].TransformRead(gen)); } else { - return AstFactory.OpCall("CreateRegex2", Ast.Constant(_options), Ast.NewArray(typeof(object[]), gen.TranformExpressions(_pattern))); + return AstFactory.OpCall("CreateRegexConcat", Ast.CodeContext(), Ast.Constant(_options), Ast.NewArray(typeof(object[]), gen.TranformExpressions(_pattern))); } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyOptionsParser.cs;C413883 File: RubyOptionsParser.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyOptionsParser.cs;C413883 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyOptionsParser.cs;MutableString5 @@ -61,7 +61,7 @@ } else { RubyArray args = new RubyArray(); for (int i = 1; i < options.Arguments.Length; ++i) - args.Add(new MutableString(options.Arguments[i])); + args.Add(MutableString.Create(options.Arguments[i])); main.SetConstant("ARGV", args); } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;C427406 File: Loader.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;C427406 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/Loader.cs;MutableString5 @@ -76,7 +76,7 @@ // TODO: initialization _loadPaths = new RubyArray(); - _loadPaths.Add(new MutableString(".")); + _loadPaths.Add(MutableString.Create(".")); _loadedFiles = new RubyArray(); } @@ -237,7 +237,7 @@ if (path == null) { throw RubyExceptions.CreateTypeError(String.Format("Can't convert $:[{0}] into String", i)); } - result[i] = path.ToString(); + result[i] = path.ConvertToString(); } } return result; @@ -248,7 +248,7 @@ lock (_loadPaths) { foreach (string path in paths) { - _loadPaths.Add(new MutableString(path)); + _loadPaths.Add(MutableString.Create(path)); } } } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptionData.cs;C413883 File: RubyExceptionData.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptionData.cs;C413883 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptionData.cs;MutableString5 @@ -56,7 +56,7 @@ continue; } - result.Add(new MutableString(string.Format( + result.Add(MutableString.Create(string.Format( "{0}:{1}:in `{2}'", frame.GetFileName(), frame.GetFileLineNumber(), @@ -81,7 +81,7 @@ public MutableString/*!*/ Message { get { if (_message == null) { - _message = new MutableString(_exception.Message); + _message = MutableString.Create(_exception.Message); } return _message; } =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptions.cs;C429806 File: RubyExceptions.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptions.cs;C429806 (server) 5/7/2008 10:16 AM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExceptions.cs;MutableString5 @@ -92,7 +92,7 @@ } public static Exception/*!*/ InvalidValueForType(CodeContext/*!*/ context, object obj, string type) { - return CreateArgumentError("invalid value for " + type + ": " + RubySites.Inspect(context, obj).ToString()); + return CreateArgumentError(String.Format("invalid value for {0}: {1}", type, RubySites.Inspect(context, obj).ConvertToString())); } public static Exception/*!*/ CreateUndefinedMethodError(RubyModule/*!*/ module, SymbolId methodName) { @@ -127,12 +127,12 @@ } public static Exception CreateMethodMissing(CodeContext/*!*/ context, object/*!*/ self, SymbolId name) { - // TODO: is this correct? + // TODO: use protocols: RubyExecutionContext ec = RubyUtils.GetExecutionContext(context); string strObject; if (RubySites.RespondTo(context, self, "to_s")) { - strObject = RubySites.ToS(context, self); + strObject = RubySites.ToS(context, self).ConvertToString(); } else if (self != null) { strObject = self.ToString(); } else { =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;C428766 File: RubyExecutionContext.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;C428766 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;MutableString5 @@ -231,7 +231,7 @@ _currentException = null; _currentSafeLevel = 0; - _inputSeparator = new MutableString("\n"); + _inputSeparator = MutableString.Create("\n"); _outputSeparator = null; _stringSeparator = null; _itemSeparator = null; @@ -298,10 +298,10 @@ private void InitializeGlobalConstants() { Debug.Assert(_objectClass != null); - MutableString version = new MutableString(RubyContext.MriVersion); - MutableString platform = new MutableString("i386-mswin32"); // TODO: make this the correct string for MAC OS X in Silverlight - MutableString releaseDate = new MutableString(RubyContext.MriReleaseDate); - MutableString rubyEngine = new MutableString("ironruby"); + MutableString version = MutableString.Create(RubyContext.MriVersion); + MutableString platform = MutableString.Create("i386-mswin32"); // TODO: make this the correct string for MAC OS X in Silverlight + MutableString releaseDate = MutableString.Create(RubyContext.MriReleaseDate); + MutableString rubyEngine = MutableString.Create("ironruby"); _objectClass.SetConstant("RUBY_ENGINE", rubyEngine); _objectClass.SetConstant("RUBY_VERSION", version); @@ -312,7 +312,7 @@ _objectClass.SetConstant("PLATFORM", platform); _objectClass.SetConstant("RELEASE_DATE", releaseDate); - _objectClass.SetConstant("IRONRUBY_VERSION", new MutableString(RubyContext.IronRubyVersionString)); + _objectClass.SetConstant("IRONRUBY_VERSION", MutableString.Create(RubyContext.IronRubyVersionString)); _objectClass.SetConstant("STDIN", StandardInput); _objectClass.SetConstant("STDOUT", StandardOutput); =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C429806 File: RubyOps.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C429806 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;MutableString5 @@ -14,21 +14,21 @@ * ***************************************************************************/ using System; -using System.Collections.Generic; +using System.IO; using System.Diagnostics; using System.Reflection; -using System.Text; +using System.Collections.Generic; +using System.Text.RegularExpressions; + using Microsoft.Scripting; using Microsoft.Scripting.Actions; using Microsoft.Scripting.Ast; -using Microsoft.Scripting.Hosting; using Microsoft.Scripting.Utils; +using Microsoft.Scripting.Runtime; + using Ruby.Builtins; using Ruby.Compiler; using Ruby.Runtime.Calls; -using System.IO; -using Microsoft.Scripting.Runtime; -using System.Text.RegularExpressions; namespace Ruby.Runtime { /// @@ -51,8 +51,6 @@ } } - // obsolete: static bool _libraryInitialized = false; - internal static MethodInfo/*!*/ GetMethod(string/*!*/ name) { MethodInfo result = typeof(RubyOps).GetMethod(name, BindingFlags.Public | BindingFlags.Static); Assert.NotNull(result); @@ -228,7 +226,8 @@ public static void PrintInteractiveResult(RubyScope/*!*/ scope, object value) { TextWriter output = scope.LanguageContext.DomainManager.SharedIO.OutputWriter; output.Write("=> "); - output.WriteLine(value); + // TODO: + output.WriteLine(value ?? "nil"); } // emitted: @@ -677,27 +676,16 @@ #region Regex - public static Regexp CreateRegexp(Ruby.Compiler.Ast.RegExOptions options, string pattern) { - RegexOptions regexOptions = RegexOptions.None; - - if ((options & Ruby.Compiler.Ast.RegExOptions.IGNORECASE) > 0) - regexOptions |= RegexOptions.IgnoreCase; - if ((options & Ruby.Compiler.Ast.RegExOptions.MULTILINE) > 0) - regexOptions |= RegexOptions.Multiline; - if ((options & Ruby.Compiler.Ast.RegExOptions.SINGLELINE) > 0) - regexOptions |= RegexOptions.Singleline; - - return new Regexp(new System.Text.RegularExpressions.Regex(pattern, regexOptions)); - } - // emitted: - public static object CreateRegex(Ruby.Compiler.Ast.RegExOptions options, object pattern) { - return CreateRegexp(options, pattern.ToString()); + public static RubyRegex/*!*/ CreateRegex(CodeContext/*!*/ context, Ruby.Compiler.Ast.RegExOptions options, object pattern) { + // TODO: + return new RubyRegex(ConcatMutableString(context, new object[] { pattern }), RubyRegex.ToClrOptions(options)); } // emitted: - public static object CreateRegex2(Ruby.Compiler.Ast.RegExOptions options, object[] patterns) { - return CreateRegexp(options, Concat(patterns).ToString()); + public static RubyRegex/*!*/ CreateRegexConcat(CodeContext/*!*/ context, Ruby.Compiler.Ast.RegExOptions options, object[] patterns) { + // TODO: + return new RubyRegex(ConcatMutableString(context, patterns), RubyRegex.ToClrOptions(options)); } // emitted (RegexMatchReference): @@ -731,24 +719,11 @@ #endregion // emitted: - public static object Concat(object[] parts) { + public static MutableString/*!*/ ConcatMutableString(CodeContext/*!*/ context, object[] parts) { Assert.NotNull(parts); - // TODO: - StringBuilder result = new StringBuilder(); + MutableString str = MutableString.CreateMutable(); foreach (object part in parts) { - result.Append(part); - } - - return result.ToString(); - } - - // emitted: - public static object ConcatMutableString(CodeContext/*!*/ context, object[] parts) { - Assert.NotNull(parts); - - MutableString str = new MutableString(); - foreach (object part in parts) { str.Append(RubySites.ToS(context, part)); } return str; @@ -757,7 +732,7 @@ // emitted: public static SymbolId CreateSymbol(MutableString/*!*/ str) { // TODO: - return SymbolTable.StringToId(str.ToString()); + return SymbolTable.StringToId(str.ConvertToString()); } // emitted: @@ -914,7 +889,7 @@ if (str is MutableString) return (MutableString)str; else - return new MutableString(str.ToString()); + return MutableString.Create(str.ToString()); } #region Dynamic Actions =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyScope.cs;C431660 File: RubyScope.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyScope.cs;C431660 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyScope.cs;MutableString5 @@ -132,7 +132,7 @@ Debug.Assert(index >= 0); if (_currentMatch != null && index < _currentMatch.Groups.Count) { - return new MutableString(_currentMatch.Groups[index].Value); + return MutableString.Create(_currentMatch.Groups[index].Value); } return null; @@ -140,7 +140,7 @@ internal MutableString GetCurrentMatchLastGroup() { if (_currentMatch != null && _currentMatch.Groups.Count > 0) { - return new MutableString(_currentMatch.Groups[_currentMatch.Groups.Count - 1].Value); + return MutableString.Create(_currentMatch.Groups[_currentMatch.Groups.Count - 1].Value); } return null; @@ -191,8 +191,8 @@ public DebugView(RubyScope/*!*/ scope) { Assert.NotNull(scope); _scope = scope; - _selfClassName = _scope.ExecutionContext.GetImmediateClassOf(_scope._selfObject).GetDisplayName().ToString(); - _matchClassName = _scope.ExecutionContext.GetImmediateClassOf(_scope._currentMatch).GetDisplayName().ToString(); + _selfClassName = _scope.ExecutionContext.GetImmediateClassOf(_scope._selfObject).GetDisplayName().ConvertToString(); + _matchClassName = _scope.ExecutionContext.GetImmediateClassOf(_scope._currentMatch).GetDisplayName().ConvertToString(); } [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] @@ -204,7 +204,7 @@ foreach (KeyValuePair variable in scope._frame.SymbolAttributes) { string name = SymbolTable.IdToString(variable.Key); if (!name.StartsWith("#")) { - string className = _scope.ExecutionContext.GetImmediateClassOf(variable.Value).GetDisplayName().ToString(); + string className = _scope.ExecutionContext.GetImmediateClassOf(variable.Value).GetDisplayName().ConvertToString(); if (scope != _scope) { name += " (outer)"; } @@ -256,7 +256,7 @@ internal struct VariableView { [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly string/*!*/ _name; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] + [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)] private readonly object _value; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly string/*!*/ _valueClassName; =================================================================== edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C434537 File: RubyUtils.cs =================================================================== --- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C434537 (server) 5/8/2008 1:15 PM +++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;MutableString5 @@ -89,7 +89,7 @@ public static MutableString/*!*/ ObjectToMutableString(CodeContext/*!*/ context, object obj) { RubyExecutionContext ec = RubyUtils.GetExecutionContext(context); - MutableString str = new MutableString(); + MutableString str = MutableString.CreateMutable(); str.Append("#<"); str.Append(ec.GetClassOf(obj).Name); @@ -376,7 +376,7 @@ RubyModule module = obj as RubyModule; if (module == null) { throw RubyExceptions.CreateTypeError( - RubyUtils.ObjectToMutableString(context, obj).Append(" is not a class/module").ToString() + RubyUtils.ObjectToMutableString(context, obj).Append(" is not a class/module").ConvertToString() ); } return module; @@ -435,7 +435,7 @@ Scope globalScope = targetScope.GlobalScope; RubyMethodScope methodScope = targetScope.GetInnerMostMethodScope(); - SourceUnit source = ec.Context.CreateSnippet(code.ToString()); + SourceUnit source = ec.Context.CreateSnippet(code.ConvertToString()); RubyCompilerOptions options = new RubyCompilerOptions(); options.IsEval = true; @@ -452,7 +452,7 @@ Assert.NotNull(self, code); RubyContext language = self.ExecutionContext.Context; - SourceUnit source = language.CreateSnippet(code.ToString()); + SourceUnit source = language.CreateSnippet(code.ConvertToString()); RubyCompilerOptions options = new RubyCompilerOptions(); ===================================================================