PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/IronPython_Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Extensions/TypeGroupOps.cs

#
C# | 195 lines | 144 code | 33 blank | 18 comment | 15 complexity | 2e1eeea60c4779924f5f00d1cbbfaa50 MD5 | raw file
Possible License(s): GPL-2.0, MPL-2.0-no-copyleft-exception, CPL-1.0, CC-BY-SA-3.0, BSD-3-Clause, ISC, AGPL-3.0, LGPL-2.1, Apache-2.0
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Apache License, Version 2.0. A
  6. * copy of the license can be found in the License.html file at the root of this distribution. If
  7. * you cannot locate the Apache License, Version 2.0, please send an email to
  8. * ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
  9. * by the terms of the Apache License, Version 2.0.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. #if !CLR2
  16. using System.Linq.Expressions;
  17. #else
  18. using Microsoft.Scripting.Ast;
  19. #endif
  20. using System;
  21. using System.Dynamic;
  22. using Microsoft.Scripting.Runtime;
  23. using Microsoft.Scripting.Actions;
  24. using IronRuby.Runtime;
  25. using IronRuby.Runtime.Calls;
  26. using IronRuby.Compiler.Generation;
  27. using System.Runtime.CompilerServices;
  28. using System.Collections.Generic;
  29. using Microsoft.Scripting.Utils;
  30. namespace IronRuby.Builtins {
  31. using Ast = Expression;
  32. using AstUtils = Microsoft.Scripting.Ast.Utils;
  33. [RubyClass(Extends = typeof(TypeGroup), Restrictions = ModuleRestrictions.None)]
  34. [Includes(typeof(Enumerable))]
  35. public static class TypeGroupOps {
  36. [RubyMethod("of")]
  37. [RubyMethod("[]")]
  38. public static RubyModule/*!*/ Of(RubyContext/*!*/ context, TypeGroup/*!*/ self, [NotNullItems]params object/*!*/[]/*!*/ typeArgs) {
  39. TypeTracker tracker = self.GetTypeForArity(typeArgs.Length);
  40. if (tracker == null) {
  41. throw RubyExceptions.CreateArgumentError("Invalid number of type arguments for `{0}'", self.Name);
  42. }
  43. Type concreteType;
  44. if (typeArgs.Length > 0) {
  45. concreteType = tracker.Type.MakeGenericType(Protocols.ToTypes(context, typeArgs));
  46. } else {
  47. concreteType = tracker.Type;
  48. }
  49. return context.GetModule(concreteType);
  50. }
  51. [RubyMethod("of")]
  52. [RubyMethod("[]")]
  53. public static RubyModule/*!*/ Of(RubyContext/*!*/ context, TypeGroup/*!*/ self, int genericArity) {
  54. TypeTracker tracker = self.GetTypeForArity(genericArity);
  55. if (tracker == null) {
  56. throw RubyExceptions.CreateArgumentError("Type group `{0}' does not contain a type of generic arity {1}", self.Name, genericArity);
  57. }
  58. return context.GetModule(tracker.Type);
  59. }
  60. [RubyMethod("each")]
  61. public static object EachType(RubyContext/*!*/ context, BlockParam/*!*/ block, TypeGroup/*!*/ self) {
  62. if (block == null) {
  63. throw RubyExceptions.NoBlockGiven();
  64. }
  65. foreach (Type type in self.Types) {
  66. RubyModule module = context.GetModule(type);
  67. object result;
  68. if (block.Yield(module, out result)) {
  69. return result;
  70. }
  71. }
  72. return self;
  73. }
  74. [RubyMethod("name")]
  75. [RubyMethod("to_s")]
  76. public static MutableString/*!*/ GetName(RubyContext/*!*/ context, TypeGroup/*!*/ self) {
  77. return MutableString.Create(self.Name, context.GetIdentifierEncoding());
  78. }
  79. [RubyMethod("inspect")]
  80. public static MutableString/*!*/ Inspect(RubyContext/*!*/ context, TypeGroup/*!*/ self) {
  81. var result = MutableString.CreateMutable(context.GetIdentifierEncoding());
  82. result.Append("#<TypeGroup: ");
  83. bool isFirst = true;
  84. foreach (var entry in self.TypesByArity.ToSortedList((x, y) => x.Key - y.Key)) {
  85. Type type = entry.Value;
  86. if (!isFirst) {
  87. result.Append(", ");
  88. } else {
  89. isFirst = false;
  90. }
  91. result.Append(context.GetTypeName(type, true));
  92. }
  93. result.Append('>');
  94. return result;
  95. }
  96. private static Type/*!*/ GetNonGenericType(TypeGroup/*!*/ self) {
  97. TypeTracker type = self.GetTypeForArity(0);
  98. if (type == null) {
  99. throw RubyExceptions.CreateTypeError("type group doesn't include non-generic type");
  100. }
  101. return type.Type;
  102. }
  103. [Emitted]
  104. public static RubyClass/*!*/ GetNonGenericClass(RubyContext/*!*/ context, TypeGroup/*!*/ typeGroup) {
  105. Type type = GetNonGenericType(typeGroup);
  106. if (type.IsInterface) {
  107. throw RubyExceptions.CreateTypeError("cannot instantiate an interface");
  108. }
  109. return context.GetClass(type);
  110. }
  111. private static object New(string/*!*/ methodName, CallSiteStorage<Func<CallSite, object, object, object>>/*!*/ storage,
  112. TypeGroup/*!*/ self, params object[]/*!*/ args) {
  113. var cls = GetNonGenericClass(storage.Context, self);
  114. var site = storage.GetCallSite(methodName,
  115. new RubyCallSignature(1, RubyCallFlags.HasImplicitSelf | RubyCallFlags.HasSplattedArgument)
  116. );
  117. return site.Target(site, cls, RubyOps.MakeArrayN(args));
  118. }
  119. private static object New(string/*!*/ methodName, CallSiteStorage<Func<CallSite, object, object, object, object>>/*!*/ storage, BlockParam block,
  120. TypeGroup/*!*/ self, params object[]/*!*/ args) {
  121. var cls = GetNonGenericClass(storage.Context, self);
  122. var site = storage.GetCallSite(methodName,
  123. new RubyCallSignature(1, RubyCallFlags.HasImplicitSelf | RubyCallFlags.HasSplattedArgument | RubyCallFlags.HasBlock)
  124. );
  125. return site.Target(site, cls, block != null ? block.Proc : null, RubyOps.MakeArrayN(args));
  126. }
  127. // ARGS: N
  128. [RubyMethod("new")]
  129. public static object/*!*/ New(CallSiteStorage<Func<CallSite, object, object, object>>/*!*/ storage,
  130. TypeGroup/*!*/ self, params object[]/*!*/ args) {
  131. return New("new", storage, self, args);
  132. }
  133. // ARGS: N&
  134. [RubyMethod("new")]
  135. public static object New(CallSiteStorage<Func<CallSite, object, object, object, object>>/*!*/ storage, BlockParam block,
  136. TypeGroup/*!*/ self, params object[]/*!*/ args) {
  137. return New("new", storage, block, self, args);
  138. }
  139. [RubyMethod("superclass")]
  140. public static RubyClass GetSuperclass(RubyContext/*!*/ context, TypeGroup/*!*/ self) {
  141. Type type = GetNonGenericType(self);
  142. return type.IsInterface ? null : context.GetClass(type).SuperClass;
  143. }
  144. // ARGS: N
  145. [RubyMethod("clr_new")]
  146. public static object/*!*/ ClrNew(CallSiteStorage<Func<CallSite, object, object, object>>/*!*/ storage,
  147. TypeGroup/*!*/ self, params object[]/*!*/ args) {
  148. return New("clr_new", storage, self, args);
  149. }
  150. // ARGS: N&
  151. [RubyMethod("clr_new")]
  152. public static object ClrNew(CallSiteStorage<Func<CallSite, object, object, object, object>>/*!*/ storage, BlockParam block,
  153. TypeGroup/*!*/ self, params object[]/*!*/ args) {
  154. return New("clr_new", storage, block, self, args);
  155. }
  156. [RubyMethod("clr_ctor")]
  157. [RubyMethod("clr_constructor")]
  158. public static RubyMethod/*!*/ GetClrConstructor(RubyContext/*!*/ context, TypeGroup/*!*/ self) {
  159. return ClassOps.GetClrConstructor(GetNonGenericClass(context, self));
  160. }
  161. }
  162. }