diff --git a/Foundation/CPArray/_CPJavaScriptArray.j b/Foundation/CPArray/_CPJavaScriptArray.j index 41653919b..454d5a670 100644 --- a/Foundation/CPArray/_CPJavaScriptArray.j +++ b/Foundation/CPArray/_CPJavaScriptArray.j @@ -360,4 +360,15 @@ var concat = Array.prototype.concat, @end -Array.prototype.isa = _CPJavaScriptArray; +if (Array.prototype.isa !== _CPJavaScriptArray) +{ + Object.defineProperties(Array.prototype, + { + isa: + { + value: _CPJavaScriptArray, + enumerable: false, + writable: true + } + }); +} diff --git a/Foundation/CPData.j b/Foundation/CPData.j index 1412e034a..78478cff3 100644 --- a/Foundation/CPData.j +++ b/Foundation/CPData.j @@ -214,5 +214,27 @@ @end -CFData.prototype.isa = CPData; -CFMutableData.prototype.isa = CPData; +if (CFData.prototype.isa !== CPData) +{ + Object.defineProperties(CFData.prototype, + { + isa: + { + value: CPData, + enumerable: false, + writable: true + } + }) +}; +if (CFMutableData.prototype.isa !== CPData) +{ + Object.defineProperties(CFMutableData.prototype, + { + isa: + { + value: CPData, + enumerable: false, + writable: true + } + }); +} diff --git a/Foundation/CPDate.j b/Foundation/CPDate.j index 000a2c849..79efc26ca 100644 --- a/Foundation/CPDate.j +++ b/Foundation/CPDate.j @@ -286,7 +286,18 @@ Date.parseISO8601 = function (date) return timestamp; }; -Date.prototype.isa = CPDate; +if (Date.prototype.isa !== CPDate) +{ + Object.defineProperties(Date.prototype, + { + isa: + { + value: CPDate, + enumerable: false, + writable: true + } + }); +} function _isNumberType(value) { diff --git a/Foundation/CPDictionary.j b/Foundation/CPDictionary.j index 1238f1e09..d2cd8f229 100755 --- a/Foundation/CPDictionary.j +++ b/Foundation/CPDictionary.j @@ -751,5 +751,27 @@ var CPDictionaryMaxDescriptionRecursion = 10; @end -CFDictionary.prototype.isa = CPDictionary; -CFMutableDictionary.prototype.isa = CPMutableDictionary; +if (CFDictionary.prototype.isa !== CPDictionary) +{ + Object.defineProperties(CFDictionary.prototype, + { + isa: + { + value: CPDictionary, + enumerable: false, + writable: true + } + }); +} +if (CFMutableDictionary.prototype.isa !== CPMutableDictionary) +{ + Object.defineProperties(CFMutableDictionary.prototype, + { + isa: + { + value: CPMutableDictionary, + enumerable: false, + writable: true + } + }); +} \ No newline at end of file diff --git a/Foundation/CPError.j b/Foundation/CPError.j index edc270514..8e120ca9d 100644 --- a/Foundation/CPError.j +++ b/Foundation/CPError.j @@ -166,5 +166,16 @@ var CPErrorCodeKey = @"CPErrorCodeKey", @end -CFError.prototype.isa = CPError; +if (CFError.prototype.isa !== CPError) +{ + Object.defineProperties(CFError.prototype, + { + isa: + { + value: CPError, + enumerable: false, + writable: true + } + }); +} diff --git a/Foundation/CPException.j b/Foundation/CPException.j index 70064a984..392cbe1b0 100755 --- a/Foundation/CPException.j +++ b/Foundation/CPException.j @@ -222,8 +222,30 @@ var CPExceptionNameKey = @"CPExceptionNameKey", // toll-free bridge Error to CPException // [CPException alloc] uses an objj_exception, which is a subclass of Error -Error.prototype.isa = CPException; -Error.prototype._userInfo = null; +if (Error.prototype.isa !== CPException) +{ + Object.defineProperties(Error.prototype, + { + isa: + { + value: CPException, + enumerable: false, + writable: true + } + }); +} +if (Error.prototype._userInfo !== null) +{ + Object.defineProperties(Error.prototype, + { + _userInfo: + { + value: null, + enumerable: false, + writable: true + } + }); +} [CPException initialize]; diff --git a/Foundation/CPNumber.j b/Foundation/CPNumber.j index 0a45c2bd2..c14caf47c 100644 --- a/Foundation/CPNumber.j +++ b/Foundation/CPNumber.j @@ -346,6 +346,29 @@ FIXME: Do we need this? @end -Number.prototype.isa = CPNumber; -Boolean.prototype.isa = CPNumber; +if (Number.prototype.isa !== CPNumber) +{ + Object.defineProperties(Number.prototype, + { + isa: + { + value: CPNumber, + enumerable: false, + writable: true + } + }); +} +if (Boolean.prototype.isa !== CPNumber) +{ + Object.defineProperties(Boolean.prototype, + { + isa: + { + value: CPNumber, + enumerable: false, + writable: true + } + }); +} + [CPNumber initialize]; diff --git a/Foundation/CPString.j b/Foundation/CPString.j index eeccf81b5..e642bab49 100644 --- a/Foundation/CPString.j +++ b/Foundation/CPString.j @@ -1010,4 +1010,15 @@ String.prototype.stripDiacritics = function() return output; }; -String.prototype.isa = CPString; +if (String.prototype.isa !== CPString) +{ + Object.defineProperties(String.prototype, + { + isa: + { + value: CPString, + enumerable: false, + writable: true + } + }) +}; diff --git a/Foundation/CPURL.j b/Foundation/CPURL.j index dd69280c5..8202fdbc8 100644 --- a/Foundation/CPURL.j +++ b/Foundation/CPURL.j @@ -260,4 +260,15 @@ var CPURLURLStringKey = @"CPURLURLStringKey", @end -CFURL.prototype.isa = [CPURL class]; +if (CFURL.prototype.isa !== CPURL) +{ + Object.defineProperties(CFURL.prototype, + { + isa: + { + value: CPURL, + enumerable: false, + writable: true + } + }) +}; diff --git a/Tests/Foundation/CPArrayTest.j b/Tests/Foundation/CPArrayTest.j index 828b70efe..850af1cbd 100644 --- a/Tests/Foundation/CPArrayTest.j +++ b/Tests/Foundation/CPArrayTest.j @@ -722,6 +722,22 @@ }]; } +// As we have a tool-free bridges between many classes and JavaScript types by setting the isa property +// on the type, for example Array and CPArray. Using the for...in enumeration the isa property should not +// be included in the loop as the property is now not enumerable. +- (void)testLoopingArrayWithForIn +{ + let array = @[@"a", @"b", @"c", @"d"], + i = 0; + + for (const element in array) { + i = i + 1; + element + element; // Remove warning that the variable is never read + } + + [self assert:i equals:4]; +} + @end @implementation AlwaysEqual : CPObject