diff --git a/JSIL/AST/JSExpressionTypes.cs b/JSIL/AST/JSExpressionTypes.cs index 3ec3a338e..fba34ecb4 100644 --- a/JSIL/AST/JSExpressionTypes.cs +++ b/JSIL/AST/JSExpressionTypes.cs @@ -1981,7 +1981,7 @@ internal static bool AllowBizarreReferenceCast (TypeReference currentType, TypeR return true; } - if (TypeUtil.IsEnum(currentType) && TypeUtil.IsIntegral(newType)) + if (TypeUtil.IsEnum(currentType) > 0 && TypeUtil.IsIntegral(newType)) return true; // Allow casting T*& to U*& diff --git a/JSIL/AssemblyTranslator.cs b/JSIL/AssemblyTranslator.cs index d7f8c7ccb..1568dc12a 100644 --- a/JSIL/AssemblyTranslator.cs +++ b/JSIL/AssemblyTranslator.cs @@ -131,6 +131,8 @@ public AssemblyTranslator ( Configuration = configuration; bool useDefaultProxies = configuration.UseDefaultProxies.GetValueOrDefault(true); + TypeUtil.s_ConfigurationChangeEnumToNumber = configuration.CodeGenerator.ChangeEnumToNumber.GetValueOrDefault(0); + Manifest = manifest ?? new AssemblyManifest(); if (typeInfoProvider != null) { @@ -294,6 +296,20 @@ protected bool IsRedirected (string assemblyName) { return false; } + protected bool IsAttributeIgnored(string attributeName) + { + List emitAttributes = Configuration.CodeGenerator.EmitAttributes; + if (emitAttributes.Count == 0) + return false; + foreach (var ia in emitAttributes) + { + if (Regex.IsMatch(attributeName, ia, RegexOptions.IgnoreCase)) + return false; + } + + return true; + } + public string ClassifyAssembly (AssemblyDefinition asm) { if (IsIgnored(asm.FullName)) return "ignored"; @@ -1153,6 +1169,18 @@ protected void DeclareType ( return; } + bool isAttribute = false; + TypeInfo typeBaseClass = typeInfo.BaseClass; + while (!isAttribute && typeBaseClass != null) + { + isAttribute = (typeBaseClass.FullName == "System.Attribute"); + typeBaseClass = typeBaseClass.BaseClass; + } + if (isAttribute && IsAttributeIgnored(typeInfo.FullName)) + { + return; + } + // This type is defined in JSIL.Core so we don't want to cause a name collision. if (!ShouldGenerateTypeDeclaration(typedef, makingSkeletons)) { declaredTypes.Add(typedef); @@ -1219,6 +1247,11 @@ protected void DeclareType ( TranslateInterface(context, astEmitter, output, typedef); return; } else if (typedef.IsEnum) { + if ((TypeUtil.IsEnum(typedef) & TypeUtil.EnumKind.ChangeToNumber) != 0) + { + return; + } + output.Comment("enum {0}", Util.DemangleCecilTypeName(typedef.FullName)); output.NewLine(); output.NewLine(); @@ -2416,7 +2449,7 @@ private JSExpression TranslateAttributeConstructorArgument ( ); } else if (ca.Type.FullName == "System.Type") { return new JSTypeOfExpression((TypeReference)ca.Value); - } else if (TypeUtil.IsEnum(ca.Type)) { + } else if (TypeUtil.IsEnum(ca.Type) > 0) { var longValue = Convert.ToInt64(ca.Value); var result = JSEnumLiteral.TryCreate( _TypeInfoProvider.GetExisting(ca.Type), @@ -2457,6 +2490,10 @@ private void TranslateCustomAttributes ( if (ShouldSkipMember(attribute.AttributeType)) continue; + if (IsAttributeIgnored(attribute.AttributeType.FullName)) + { + continue; + } if (!isFirst || standalone) output.NewLine(); @@ -2500,10 +2537,14 @@ private void TranslateParameterAttributes ( JavascriptAstEmitter astEmitter, JavascriptFormatter output ) { + if (!Configuration.CodeGenerator.EmitAllParameterNames.GetValueOrDefault(false)) + { + return; + } output.Indent(); foreach (var parameter in method.Parameters) { - if (!parameter.HasCustomAttributes && !Configuration.CodeGenerator.EmitAllParameterNames.GetValueOrDefault(false)) + if (!parameter.HasCustomAttributes) continue; output.NewLine(); diff --git a/JSIL/Configuration.cs b/JSIL/Configuration.cs index e3eb872f4..aedc2d616 100644 --- a/JSIL/Configuration.cs +++ b/JSIL/Configuration.cs @@ -47,6 +47,8 @@ public sealed class CodeGeneratorConfiguration { public bool? AutoGenerateEventAccessorsInSkeletons; public bool? AggressivelyUseElementProxies; public bool? EmitAllParameterNames; + public int? ChangeEnumToNumber; // 0 - disabled, 1 - with attribute only, 2 - all enums + public readonly List EmitAttributes = new List(); public void MergeInto (CodeGeneratorConfiguration result) { if (EliminateStructCopies.HasValue) @@ -89,6 +91,9 @@ public void MergeInto (CodeGeneratorConfiguration result) { result.AggressivelyUseElementProxies = AggressivelyUseElementProxies; if (EmitAllParameterNames.HasValue) result.EmitAllParameterNames = EmitAllParameterNames; + if (ChangeEnumToNumber.HasValue) + result.ChangeEnumToNumber = ChangeEnumToNumber; + result.EmitAttributes.AddRange(EmitAttributes); } } diff --git a/JSIL/ILBlockTranslator.cs b/JSIL/ILBlockTranslator.cs index 39be09dbd..b1da53c33 100644 --- a/JSIL/ILBlockTranslator.cs +++ b/JSIL/ILBlockTranslator.cs @@ -351,7 +351,7 @@ protected JSExpression Translate_UnaryOp (ILExpression node, JSUnaryOperator op) } // Insert correct casts when unary operators are applied to enums. - if (TypeUtil.IsEnum(innerType) && TypeUtil.IsEnum(node.InferredType ?? node.ExpectedType)) { + if (TypeUtil.IsEnum(innerType) > 0 && TypeUtil.IsEnum(node.InferredType ?? node.ExpectedType) > 0) { return JSCastExpression.New( new JSUnaryOperatorExpression( op, @@ -565,6 +565,8 @@ protected JSExpression DoMethodReplacement ( case "System.Boolean JSIL.Builtins::IsFalsy(System.Object)": return new JSUnaryOperatorExpression(JSOperator.LogicalNot, arguments.First(), TypeSystem.Boolean); + case "T JSIL.Verbatim::Expression(System.String)": + case "T JSIL.Verbatim::Expression(System.String,System.Object[])": case "System.Object JSIL.Verbatim::Expression(System.String)": case "System.Object JSIL.Verbatim::Expression(System.String,System.Object[])": { var expression = arguments[0] as JSStringLiteral; @@ -1731,7 +1733,7 @@ protected JSTernaryOperatorExpression Translate_TernaryOp (ILExpression node) { } protected JSExpression Translate_Mul (ILExpression node) { - if (TypeUtil.IsIntegral(node.ExpectedType)) { + if (node.ExpectedType != null && TypeUtil.IsIntegral(node.ExpectedType)) { var left = TranslateNode(node.Arguments[0]); var right = TranslateNode(node.Arguments[1]); var leftType = left.GetActualType(TypeSystem); diff --git a/JSIL/JavascriptAstEmitter.cs b/JSIL/JavascriptAstEmitter.cs index ebd2490fd..be2de8854 100644 --- a/JSIL/JavascriptAstEmitter.cs +++ b/JSIL/JavascriptAstEmitter.cs @@ -458,6 +458,12 @@ public void VisitNode (JSAsExpression ae) { } public void VisitNode (JSCastExpression ce) { + if ((TypeUtil.IsEnum(ce.NewType) & TypeUtil.EnumKind.ChangeToNumber) != 0) + { + Visit(ce.Expression); // no cast here, since Enum changed to JS number + return; + } + IncludeTypeParens.Push(false); try { WritePossiblyCachedTypeIdentifier(ce.NewType, ce.CachedTypeIndex); @@ -817,6 +823,20 @@ public void VisitNode (JSBooleanLiteral b) { } public void VisitNode (JSEnumLiteral enm) { + TypeUtil.EnumKind enumKind = TypeUtil.IsEnum(enm.EnumType); + if ((enumKind & TypeUtil.EnumKind.ChangeToNumber) != 0) { + if (enm.Names.Length == 1) { + Output.Comment(enm.EnumType.Name + "." + enm.Names[0]); + } + if ((enumKind & TypeUtil.EnumKind.FlagIsFlags) != 0) { + Output.WriteRaw("0x{0:X}", enm.Value); + } + else { + Output.Value(enm.Value); + } + return; + } + if (enm.CachedEnumType != null) Visit(enm.CachedEnumType); else @@ -915,7 +935,7 @@ public void VisitNode (JSIgnoredTypeReference itr) { } public void VisitNode (JSDefaultValueLiteral defaultValue) { - if (TypeUtil.IsEnum(defaultValue.Value)) { + if ((TypeUtil.IsEnum(defaultValue.Value) & TypeUtil.EnumKind.IsEnum) != 0) { EnumMemberInfo emi; var enumInfo = TypeInfo.Get(defaultValue.Value); @@ -1665,8 +1685,9 @@ private bool NeedTruncationForBinaryOperator (JSBinaryOperatorExpression bop, Ty public void VisitNode (JSBinaryOperatorExpression bop) { var resultType = bop.GetActualType(TypeSystem); + TypeReference resultTypeStripped = TypeUtil.StripNullable(resultType); bool needsCast = (bop.Operator is JSArithmeticOperator) && - TypeUtil.IsEnum(TypeUtil.StripNullable(resultType)); + (TypeUtil.IsEnum(resultTypeStripped) & TypeUtil.EnumKind.IsEnum) != 0; bool needsTruncation = NeedTruncationForBinaryOperator(bop, resultType); bool parens = NeedParensForBinaryOperator(bop); var parenCount = GetParenCountForTruncation(resultType); @@ -1675,7 +1696,7 @@ public void VisitNode (JSBinaryOperatorExpression bop) { if (bop.Operator is JSAssignmentOperator) throw new NotImplementedException("Truncation of assignment operations not implemented"); } else if (needsCast) { - Output.Identifier(TypeUtil.StripNullable(resultType), ReferenceContext); + Output.Identifier(resultTypeStripped, ReferenceContext); Output.WriteRaw(".$Cast"); } diff --git a/JSIL/JavascriptFormatter.cs b/JSIL/JavascriptFormatter.cs index 737bbaf9d..6c82b51ca 100644 --- a/JSIL/JavascriptFormatter.cs +++ b/JSIL/JavascriptFormatter.cs @@ -705,6 +705,12 @@ public void TypeReference (TypeReference type, TypeReferenceContext context) { } } + if ((TypeUtil.IsEnum(type) & TypeUtil.EnumKind.ChangeToNumber) != 0) + { + WriteRaw("$.Int32"); + return; + } + if (type.FullName == "JSIL.Proxy.AnyType") { Value("JSIL.AnyType"); return; @@ -862,6 +868,12 @@ protected void TypeIdentifier (TypeReference type, TypeReferenceContext context, return; } + if ((TypeUtil.IsEnum(type) & TypeUtil.EnumKind.ChangeToNumber) != 0) + { + WriteRaw("$jsilcore.System.Int32"); + return; + } + var typedef = type.Resolve(); if (typedef != null) { if (GetContainingAssemblyName(typedef) == Assembly.FullName) { diff --git a/JSIL/Transforms/CacheTypeExpressions.cs b/JSIL/Transforms/CacheTypeExpressions.cs index 0bc506568..9119e9c78 100644 --- a/JSIL/Transforms/CacheTypeExpressions.cs +++ b/JSIL/Transforms/CacheTypeExpressions.cs @@ -87,6 +87,9 @@ public bool IsCacheable (TypeReference type) { if (TypeUtil.IsOpenType(type)) return false; + if ((TypeUtil.IsEnum(type) & TypeUtil.EnumKind.ChangeToNumber) != 0) + return false; + return true; } diff --git a/JSIL/Transforms/IntroduceEnumCasts.cs b/JSIL/Transforms/IntroduceEnumCasts.cs index c80458711..b68877900 100644 --- a/JSIL/Transforms/IntroduceEnumCasts.cs +++ b/JSIL/Transforms/IntroduceEnumCasts.cs @@ -79,7 +79,7 @@ public static JSExpression CastToEnumType (JSExpression value, TypeReference typ public static bool IsNullableEnum (TypeReference tr) { var git = tr as GenericInstanceType; if ((git != null) && (git.Name == "Nullable`1")) { - if (TypeUtil.IsEnum(git.GenericArguments[0])) + if ((TypeUtil.IsEnum(git.GenericArguments[0]) & TypeUtil.EnumKind.IsEnum) != 0) return true; } @@ -89,7 +89,7 @@ public static bool IsNullableEnum (TypeReference tr) { public static bool IsEnumOrNullableEnum (TypeReference tr) { tr = TypeUtil.DereferenceType(tr, false); - if (TypeUtil.IsEnum(tr)) + if ((TypeUtil.IsEnum(tr) & TypeUtil.EnumKind.IsEnum) != 0) return true; return IsNullableEnum(tr); diff --git a/JSIL/Transforms/StaticAnalysis/EmulateStructAssignment.cs b/JSIL/Transforms/StaticAnalysis/EmulateStructAssignment.cs index 3118b06dd..21e516361 100644 --- a/JSIL/Transforms/StaticAnalysis/EmulateStructAssignment.cs +++ b/JSIL/Transforms/StaticAnalysis/EmulateStructAssignment.cs @@ -330,7 +330,7 @@ public void VisitNode (JSInvocationExpression invocation) { // before we call it. var thisReferenceType = thisReference.GetActualType(TypeSystem); - if (TypeUtil.IsStruct(thisReferenceType)) { + if (TypeUtil.IsStruct(thisReferenceType) && !TypeUtil.IsStructImmutable(thisReferenceType)) { if ((thisReference is JSVariable) || (thisReference is JSFieldAccess)) { var rre = ParentNode as JSResultReferenceExpression; var cloneExpr = new JSBinaryOperatorExpression( diff --git a/JSIL/TypeUtil.cs b/JSIL/TypeUtil.cs index ae0bd7d1b..0fe5c695e 100644 --- a/JSIL/TypeUtil.cs +++ b/JSIL/TypeUtil.cs @@ -75,7 +75,7 @@ public static bool IsStruct (TypeReference type) { type = DereferenceType(type); MetadataType etype = type.MetadataType; - if (IsEnum(type)) + if (IsEnum(type) > 0) return false; var git = type as GenericInstanceType; @@ -96,6 +96,27 @@ public static bool IsStruct (TypeReference type) { return (etype == MetadataType.ValueType); } + public static bool IsStructImmutable(TypeReference type) // much faster than: typeInfo = TypeInfo.GetTypeInformation(type) + typeInfo.IsImmutable + { + bool isImmutable = false; + TypeDefinition typeDef = type.Resolve(); + if (typeDef == null) + { + return false; + } + if (typeDef.CustomAttributes != null && + typeDef.CustomAttributes.Count > 0) + { // check the attribute first + isImmutable = typeDef.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "JSIL.Meta.JSImmutable") != null; + } + if (!isImmutable) + { // all fields are read-only + isImmutable = typeDef.Fields.All(fd => fd.IsStatic || fd.IsInitOnly); + } + + return isImmutable; + } + public static bool IsNumeric (TypeReference type) { type = DereferenceType(type); @@ -247,9 +268,32 @@ public static TypeReference StripNullable (TypeReference type) { return type; } - public static bool IsEnum (TypeReference type) { - var typedef = GetTypeDefinition(type); - return (typedef != null) && (typedef.IsEnum); + [Flags] + public enum EnumKind { + ChangeToNumber = 0x01, + IsEnum = 0x02, + + FlagIsFlags = 0x04 + }; + + internal static int s_ConfigurationChangeEnumToNumber = 0; // 0 - disabled, 1 - with attribute only, 2 - all enums + + public static EnumKind IsEnum(TypeReference type) { // checks if type is Enum and should be converted to JS number + var typedef = GetTypeDefinition(type); + bool isEnum = (typedef != null) && typedef.IsEnum; + EnumKind result = 0; + if (isEnum) + { + var attributes = typedef.CustomAttributes; + result = (s_ConfigurationChangeEnumToNumber == 2) || + (s_ConfigurationChangeEnumToNumber > 0 && + attributes.Count > 0 && + attributes.Any(ca => ca.AttributeType.FullName == "JSIL.Meta.JSChangeEnumToNumber")) ? EnumKind.ChangeToNumber : EnumKind.IsEnum; + result |= (attributes.Count > 0 && + attributes.Any(ca => ca.AttributeType.FullName == "System.FlagsAttribute")) ? EnumKind.FlagIsFlags : 0; + } + + return result; } public static bool IsBoolean (TypeReference type) { diff --git a/JSIL_NoXNA.sln b/JSIL_NoXNA.sln index 79896601f..4d6e081e7 100644 --- a/JSIL_NoXNA.sln +++ b/JSIL_NoXNA.sln @@ -1,6 +1,8 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2010 +# Visual Studio 2013 +VisualStudioVersion = 12.0.21005.1 +MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Compiler", "Compiler\Compiler.csproj", "{C7BF4561-20DD-4E49-8B5A-4E8AF032C47A}" ProjectSection(ProjectDependencies) = postProject {984CC812-9470-4A13-AFF9-CC44068D666C} = {984CC812-9470-4A13-AFF9-CC44068D666C} @@ -72,8 +74,7 @@ Global {DA03D241-B70C-44D7-A465-3CEB5A9416AE}.Debug|x86.Build.0 = Debug|x86 {DA03D241-B70C-44D7-A465-3CEB5A9416AE}.Release|.NET 4.5 x86.ActiveCfg = Release|.NET 4.5 x86 {DA03D241-B70C-44D7-A465-3CEB5A9416AE}.Release|.NET 4.5 x86.Build.0 = Release|.NET 4.5 x86 - {DA03D241-B70C-44D7-A465-3CEB5A9416AE}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DA03D241-B70C-44D7-A465-3CEB5A9416AE}.Release|Any CPU.Build.0 = Release|Any CPU + {DA03D241-B70C-44D7-A465-3CEB5A9416AE}.Release|Any CPU.ActiveCfg = Release|x86 {DA03D241-B70C-44D7-A465-3CEB5A9416AE}.Release|x86.ActiveCfg = Release|x86 {DA03D241-B70C-44D7-A465-3CEB5A9416AE}.Release|x86.Build.0 = Release|x86 {984CC812-9470-4A13-AFF9-CC44068D666C}.Debug|.NET 4.5 x86.ActiveCfg = Debug|Any CPU diff --git a/Libraries/JSIL.Bootstrap.js b/Libraries/JSIL.Bootstrap.js index db79f0ba6..82dcccb57 100644 --- a/Libraries/JSIL.Bootstrap.js +++ b/Libraries/JSIL.Bootstrap.js @@ -539,6 +539,13 @@ JSIL.ImplementExternals( } ); + $.Method({ Static: false, Public: true }, "GetType", + new JSIL.MethodSignature(mscorlib.TypeRef("System.Type"), []), + function () { + return this.__ThisType__; + } + ); + $.Method({Static: false, Public: true }, "toString", new JSIL.MethodSignature($.String, []), function () { diff --git a/Libraries/JSIL.Core.js b/Libraries/JSIL.Core.js index 039647dea..2fa3645e3 100644 --- a/Libraries/JSIL.Core.js +++ b/Libraries/JSIL.Core.js @@ -8412,6 +8412,37 @@ JSIL.Array.ShallowCopy = function (destination, source) { JSIL.Array.CopyTo(source, destination, 0); }; +JSIL.Array.FindIndex = function (array, predicate) { // implements: int System.Array.FindIndex(T[] array, Predicate match) + for (var i = 0, l = array.length; i < l; i++) { + if (predicate(array[i])) + return i; + } + return -1; +}; + +JSIL.Array.Find = function (array, predicate) { // implements: T System.Array.Find(T[] array, Predicate match) + for (var i = 0, l = array.length; i < l; i++) { + if (predicate(array[i])) + return array[i]; + } + return null; // use 'null' and not 'undefined' +}; + +JSIL.Array.ForEach = function (array, action) { // implements: void ForEach(T[] array, Action action) + for (var i = 0, l = array.length; i < l; i++) { + array[i] = action(array[i]); + } +}; + +JSIL.Array.ConvertAll = function (array, converter) { // implements: TOutput[] ConvertAll(TInput[] array, Converter converter) + var ctor = Object.getPrototypeOf(array).constructor; // create the array (support typed array) + var cloned = new ctor(array.length); + for (var i = 0, l = array.length; i < l; i++) { + cloned[i] = converter(array[i]); + } + return cloned; +}; + $jsilcore.CheckDelegateType = function (value) { if (value === null) return false; diff --git a/Libraries/JSIL.IO.js b/Libraries/JSIL.IO.js index c80468b39..2033dad73 100644 --- a/Libraries/JSIL.IO.js +++ b/Libraries/JSIL.IO.js @@ -885,7 +885,7 @@ JSIL.ImplementExternals("System.IO.BinaryWriter", function ($) { $.Method({Static:false, Public:true }, "Write", (new JSIL.MethodSignature(null, [$.Double], [])), function Write (value) { - throw new Error('Not implemented'); + this.$writeBytes($jsilcore.BytesFromDouble(value)); } ); @@ -934,7 +934,7 @@ JSIL.ImplementExternals("System.IO.BinaryWriter", function ($) { $.Method({Static:false, Public:true }, "Write", (new JSIL.MethodSignature(null, [$.Single], [])), function Write (value) { - throw new Error('Not implemented'); + this.$writeBytes($jsilcore.BytesFromSingle(value)); } ); diff --git a/Meta/Attributes.cs b/Meta/Attributes.cs index ef942fc3f..20f4e8dd5 100644 --- a/Meta/Attributes.cs +++ b/Meta/Attributes.cs @@ -101,6 +101,19 @@ public JSChangeToStaticMethod (string staticMethodName) { } } + /// + /// Specifies that uses of this enum should be replaced with corresponding number when translating code to javascript. + /// + [AttributeUsage( + AttributeTargets.Enum + )] + public sealed class JSChangeEnumToNumber : Attribute + { + public JSChangeEnumToNumber() + { + } + } + /// /// Specifies that, if overloaded, the correct overload of this method to invoke should be decided at runtime instead of compile time. /// diff --git a/Meta/Builtins.cs b/Meta/Builtins.cs index dd8e94770..d93a835cd 100644 --- a/Meta/Builtins.cs +++ b/Meta/Builtins.cs @@ -54,11 +54,11 @@ public static T CreateNamedFunction ( throw new NotImplementedException("Not available outside JS"); } - public static bool IsTruthy (dynamic value) { + public static bool IsTruthy (object valueExplicitCastToObject) { throw new NotImplementedException("Not available outside JS"); } - public static bool IsFalsy (dynamic value) { + public static bool IsFalsy (object valueExplicitCastToObject) { throw new NotImplementedException("Not available outside JS"); } diff --git a/Meta/Verbatim.cs b/Meta/Verbatim.cs index 3f5be2acb..fb4dfa349 100644 --- a/Meta/Verbatim.cs +++ b/Meta/Verbatim.cs @@ -1,9 +1,4 @@ using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Text; -using JSIL.Meta; namespace JSIL { public static class Verbatim { @@ -26,5 +21,28 @@ public static dynamic Expression (string javascript) { public static dynamic Expression (string javascript, params object[] variables) { return null; } + + /// + /// When running as C#, this method does nothing and returns null. + /// When running as JavaScript, the passed-in script code replaces this method call. + /// + /// The script expression. + /// The return type. + public static T Expression(string javascript) { + return default(T); + } + + /// + /// When running as C#, this method does nothing and returns null. + /// When running as JavaScript, the passed-in script code replaces this method call. + /// Variables can be referenced by index. '$0' is the first variable. + /// + /// The script expression. + /// The variables to insert into the expression. + /// The return type. + public static T Expression(string javascript, params object[] variables) + { + return default(T); + } } } diff --git a/Proxies/Array.cs b/Proxies/Array.cs index 7d32bae95..a267f377a 100644 --- a/Proxies/Array.cs +++ b/Proxies/Array.cs @@ -75,6 +75,36 @@ public static int IndexOf (T[] array, T value, int startIndex) { throw new InvalidOperationException(); } + [JSReplacement("JSIL.Array.Find($array, $match)")] + public static T Find(T[] array, Predicate match) + { + throw new InvalidOperationException(); + } + + [JSReplacement("JSIL.Array.FindIndex($array, $match)")] + public static int FindIndex(T[] array, Predicate match) + { + throw new InvalidOperationException(); + } + + [JSReplacement("JSIL.Array.ForEach($array, $action)")] + public static void ForEach(T[] array, Action action) + { + throw new InvalidOperationException(); + } + + [JSReplacement("JSIL.Array.ConvertAll($array, $converter)")] + public static TOutput[] ConvertAll(TInput[] array, Converter converter) + { + throw new InvalidOperationException(); + } + + [JSReplacement("Array.prototype.every.call($array, $match)")] + public static bool TrueForAll(T[] array, Predicate match) + { + throw new InvalidOperationException(); + } + [JSReplacement("JSIL.Array.Clone($this)")] public object Clone () { throw new InvalidOperationException(); @@ -104,6 +134,5 @@ public static void Sort (T[] array) { public System.Collections.IEnumerator GetEnumerator () { throw new InvalidOperationException(); } - } } diff --git a/Proxies/Numbers.cs b/Proxies/Numbers.cs index 32125ce70..3d27f415e 100644 --- a/Proxies/Numbers.cs +++ b/Proxies/Numbers.cs @@ -62,9 +62,28 @@ public string ToString (string format, IFormatProvider formatProvider) { throw new InvalidOperationException(); } + [JSReplacement("!isFinite($value)")] + public static bool IsInfinity(NumberProxy value) + { + throw new InvalidOperationException(); + } + [JSReplacement("isNaN($value)")] - public static bool IsNaN (NumberProxy value) { - throw new InvalidOperationException(); + public static bool IsNaN(NumberProxy value) + { + throw new InvalidOperationException(); + } + + [JSReplacement("($value == Infinity)")] + public static bool IsPositiveInfinity(NumberProxy value) + { + throw new InvalidOperationException(); + } + + [JSReplacement("($value == -Infinity)")] + public static bool IsNegativeInfinity(NumberProxy value) + { + throw new InvalidOperationException(); } [JSIsPure] diff --git a/Upstream/ILSpy b/Upstream/ILSpy index 4619a1384..461f6f109 160000 --- a/Upstream/ILSpy +++ b/Upstream/ILSpy @@ -1 +1 @@ -Subproject commit 4619a1384b8954e70b531228e3bc03f8562aa07a +Subproject commit 461f6f10930299943c6ecdc63defe516eab985cb