diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart index 0e2dbb5a83a..cd6d461f21a 100644 --- a/sdk/lib/html/dart2js/html_dart2js.dart +++ b/sdk/lib/html/dart2js/html_dart2js.dart @@ -6830,8 +6830,12 @@ class DomStringList extends Object with ListMixin, ImmutableListMixin JS("int", "#.length", this); - String operator[](int index) => JS("String", "#[#]", this, index); - + String operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("String", "#[#]", this, index); + } void operator[]=(int index, String value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -6843,6 +6847,31 @@ class DomStringList extends Object with ListMixin, ImmutableListMixin 0) { + return JS('String', '#[0]', this); + } + throw new StateError("No elements"); + } + + String get last { + int len = this.length; + if (len > 0) { + return JS('String', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + String get single { + int len = this.length; + if (len == 1) { + return JS('String', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + String elementAt(int index) => this[index]; // -- end List mixins. @DomName('DOMStringList.contains') @@ -9433,8 +9462,12 @@ class FileList extends Object with ListMixin, ImmutableListMixin imp @DocsEditable int get length => JS("int", "#.length", this); - File operator[](int index) => JS("File", "#[#]", this, index); - + File operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("File", "#[#]", this, index); + } void operator[]=(int index, File value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -9446,6 +9479,31 @@ class FileList extends Object with ListMixin, ImmutableListMixin imp throw new UnsupportedError("Cannot resize immutable List."); } + File get first { + if (this.length > 0) { + return JS('File', '#[0]', this); + } + throw new StateError("No elements"); + } + + File get last { + int len = this.length; + if (len > 0) { + return JS('File', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + File get single { + int len = this.length; + if (len == 1) { + return JS('File', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + File elementAt(int index) => this[index]; // -- end List mixins. @DomName('FileList.item') @@ -10230,8 +10288,12 @@ class HtmlAllCollection extends Object with ListMixin, ImmutableListMixin< @DocsEditable int get length => JS("int", "#.length", this); - Node operator[](int index) => JS("Node", "#[#]", this, index); - + Node operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("Node", "#[#]", this, index); + } void operator[]=(int index, Node value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -10243,6 +10305,31 @@ class HtmlAllCollection extends Object with ListMixin, ImmutableListMixin< throw new UnsupportedError("Cannot resize immutable List."); } + Node get first { + if (this.length > 0) { + return JS('Node', '#[0]', this); + } + throw new StateError("No elements"); + } + + Node get last { + int len = this.length; + if (len > 0) { + return JS('Node', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Node get single { + int len = this.length; + if (len == 1) { + return JS('Node', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Node elementAt(int index) => this[index]; // -- end List mixins. @DomName('HTMLAllCollection.item') @@ -10272,8 +10359,12 @@ class HtmlCollection extends Object with ListMixin, ImmutableListMixin JS("int", "#.length", this); - Node operator[](int index) => JS("Node", "#[#]", this, index); - + Node operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("Node", "#[#]", this, index); + } void operator[]=(int index, Node value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -10285,6 +10376,31 @@ class HtmlCollection extends Object with ListMixin, ImmutableListMixin 0) { + return JS('Node', '#[0]', this); + } + throw new StateError("No elements"); + } + + Node get last { + int len = this.length; + if (len > 0) { + return JS('Node', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Node get single { + int len = this.length; + if (len == 1) { + return JS('Node', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Node elementAt(int index) => this[index]; // -- end List mixins. @DomName('HTMLCollection.item') @@ -13811,8 +13927,12 @@ class MimeTypeArray extends Object with ListMixin, ImmutableListMixin< @DocsEditable int get length => JS("int", "#.length", this); - MimeType operator[](int index) => JS("MimeType", "#[#]", this, index); - + MimeType operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("MimeType", "#[#]", this, index); + } void operator[]=(int index, MimeType value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -13824,6 +13944,31 @@ class MimeTypeArray extends Object with ListMixin, ImmutableListMixin< throw new UnsupportedError("Cannot resize immutable List."); } + MimeType get first { + if (this.length > 0) { + return JS('MimeType', '#[0]', this); + } + throw new StateError("No elements"); + } + + MimeType get last { + int len = this.length; + if (len > 0) { + return JS('MimeType', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + MimeType get single { + int len = this.length; + if (len == 1) { + return JS('MimeType', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + MimeType elementAt(int index) => this[index]; // -- end List mixins. @DomName('MimeTypeArray.item') @@ -15018,8 +15163,12 @@ class NodeList extends Object with ListMixin, ImmutableListMixin imp @DocsEditable int get length => JS("int", "#.length", this); - Node operator[](int index) => JS("Node", "#[#]", this, index); - + Node operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("Node", "#[#]", this, index); + } void operator[]=(int index, Node value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -15031,6 +15180,31 @@ class NodeList extends Object with ListMixin, ImmutableListMixin imp throw new UnsupportedError("Cannot resize immutable List."); } + Node get first { + if (this.length > 0) { + return JS('Node', '#[0]', this); + } + throw new StateError("No elements"); + } + + Node get last { + int len = this.length; + if (len > 0) { + return JS('Node', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Node get single { + int len = this.length; + if (len == 1) { + return JS('Node', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Node elementAt(int index) => this[index]; // -- end List mixins. @JSName('item') @@ -15999,8 +16173,12 @@ class PluginArray extends Object with ListMixin, ImmutableListMixin JS("int", "#.length", this); - Plugin operator[](int index) => JS("Plugin", "#[#]", this, index); - + Plugin operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("Plugin", "#[#]", this, index); + } void operator[]=(int index, Plugin value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -16012,6 +16190,31 @@ class PluginArray extends Object with ListMixin, ImmutableListMixin 0) { + return JS('Plugin', '#[0]', this); + } + throw new StateError("No elements"); + } + + Plugin get last { + int len = this.length; + if (len > 0) { + return JS('Plugin', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Plugin get single { + int len = this.length; + if (len == 1) { + return JS('Plugin', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Plugin elementAt(int index) => this[index]; // -- end List mixins. @DomName('PluginArray.item') @@ -17654,8 +17857,12 @@ class SourceBufferList extends EventTarget with ListMixin, Immutab @DocsEditable int get length => JS("int", "#.length", this); - SourceBuffer operator[](int index) => JS("SourceBuffer", "#[#]", this, index); - + SourceBuffer operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("SourceBuffer", "#[#]", this, index); + } void operator[]=(int index, SourceBuffer value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -17667,6 +17874,31 @@ class SourceBufferList extends EventTarget with ListMixin, Immutab throw new UnsupportedError("Cannot resize immutable List."); } + SourceBuffer get first { + if (this.length > 0) { + return JS('SourceBuffer', '#[0]', this); + } + throw new StateError("No elements"); + } + + SourceBuffer get last { + int len = this.length; + if (len > 0) { + return JS('SourceBuffer', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + SourceBuffer get single { + int len = this.length; + if (len == 1) { + return JS('SourceBuffer', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + SourceBuffer elementAt(int index) => this[index]; // -- end List mixins. @JSName('addEventListener') @@ -17769,8 +18001,12 @@ class SpeechGrammarList extends Object with ListMixin, ImmutableL @DocsEditable int get length => JS("int", "#.length", this); - SpeechGrammar operator[](int index) => JS("SpeechGrammar", "#[#]", this, index); - + SpeechGrammar operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("SpeechGrammar", "#[#]", this, index); + } void operator[]=(int index, SpeechGrammar value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -17782,6 +18018,31 @@ class SpeechGrammarList extends Object with ListMixin, ImmutableL throw new UnsupportedError("Cannot resize immutable List."); } + SpeechGrammar get first { + if (this.length > 0) { + return JS('SpeechGrammar', '#[0]', this); + } + throw new StateError("No elements"); + } + + SpeechGrammar get last { + int len = this.length; + if (len > 0) { + return JS('SpeechGrammar', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + SpeechGrammar get single { + int len = this.length; + if (len == 1) { + return JS('SpeechGrammar', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + SpeechGrammar elementAt(int index) => this[index]; // -- end List mixins. @DomName('SpeechGrammarList.addFromString') @@ -19207,8 +19468,12 @@ class TextTrackCueList extends Object with ListMixin, ImmutableLis @DocsEditable int get length => JS("int", "#.length", this); - TextTrackCue operator[](int index) => JS("TextTrackCue", "#[#]", this, index); - + TextTrackCue operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("TextTrackCue", "#[#]", this, index); + } void operator[]=(int index, TextTrackCue value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -19220,6 +19485,31 @@ class TextTrackCueList extends Object with ListMixin, ImmutableLis throw new UnsupportedError("Cannot resize immutable List."); } + TextTrackCue get first { + if (this.length > 0) { + return JS('TextTrackCue', '#[0]', this); + } + throw new StateError("No elements"); + } + + TextTrackCue get last { + int len = this.length; + if (len > 0) { + return JS('TextTrackCue', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + TextTrackCue get single { + int len = this.length; + if (len == 1) { + return JS('TextTrackCue', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + TextTrackCue elementAt(int index) => this[index]; // -- end List mixins. @DomName('TextTrackCueList.getCueById') @@ -19247,8 +19537,12 @@ class TextTrackList extends EventTarget with ListMixin, ImmutableList @DocsEditable int get length => JS("int", "#.length", this); - TextTrack operator[](int index) => JS("TextTrack", "#[#]", this, index); - + TextTrack operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("TextTrack", "#[#]", this, index); + } void operator[]=(int index, TextTrack value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -19260,6 +19554,31 @@ class TextTrackList extends EventTarget with ListMixin, ImmutableList throw new UnsupportedError("Cannot resize immutable List."); } + TextTrack get first { + if (this.length > 0) { + return JS('TextTrack', '#[0]', this); + } + throw new StateError("No elements"); + } + + TextTrack get last { + int len = this.length; + if (len > 0) { + return JS('TextTrack', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + TextTrack get single { + int len = this.length; + if (len == 1) { + return JS('TextTrack', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + TextTrack elementAt(int index) => this[index]; // -- end List mixins. @JSName('addEventListener') @@ -19513,8 +19832,12 @@ class TouchList extends Object with ListMixin, ImmutableListMixin @DocsEditable int get length => JS("int", "#.length", this); - Touch operator[](int index) => JS("Touch", "#[#]", this, index); - + Touch operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("Touch", "#[#]", this, index); + } void operator[]=(int index, Touch value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -19526,6 +19849,31 @@ class TouchList extends Object with ListMixin, ImmutableListMixin throw new UnsupportedError("Cannot resize immutable List."); } + Touch get first { + if (this.length > 0) { + return JS('Touch', '#[0]', this); + } + throw new StateError("No elements"); + } + + Touch get last { + int len = this.length; + if (len > 0) { + return JS('Touch', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Touch get single { + int len = this.length; + if (len == 1) { + return JS('Touch', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Touch elementAt(int index) => this[index]; // -- end List mixins. @DomName('TouchList.item') @@ -21801,8 +22149,12 @@ class _ClientRectList extends Object with ListMixin, ImmutableListMixin JS("int", "#.length", this); - Rect operator[](int index) => JS("Rect", "#[#]", this, index); - + Rect operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("Rect", "#[#]", this, index); + } void operator[]=(int index, Rect value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -21814,6 +22166,31 @@ class _ClientRectList extends Object with ListMixin, ImmutableListMixin 0) { + return JS('Rect', '#[0]', this); + } + throw new StateError("No elements"); + } + + Rect get last { + int len = this.length; + if (len > 0) { + return JS('Rect', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Rect get single { + int len = this.length; + if (len == 1) { + return JS('Rect', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Rect elementAt(int index) => this[index]; // -- end List mixins. @DomName('ClientRectList.item') @@ -21842,8 +22219,12 @@ class _CssRuleList extends Object with ListMixin, ImmutableListMixin JS("int", "#.length", this); - CssRule operator[](int index) => JS("CssRule", "#[#]", this, index); - + CssRule operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("CssRule", "#[#]", this, index); + } void operator[]=(int index, CssRule value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -21855,6 +22236,31 @@ class _CssRuleList extends Object with ListMixin, ImmutableListMixin 0) { + return JS('CssRule', '#[0]', this); + } + throw new StateError("No elements"); + } + + CssRule get last { + int len = this.length; + if (len > 0) { + return JS('CssRule', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + CssRule get single { + int len = this.length; + if (len == 1) { + return JS('CssRule', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + CssRule elementAt(int index) => this[index]; // -- end List mixins. @DomName('CSSRuleList.item') @@ -21874,8 +22280,12 @@ class _CssValueList extends _CSSValue with ListMixin<_CSSValue>, ImmutableListMi @DocsEditable int get length => JS("int", "#.length", this); - _CSSValue operator[](int index) => JS("_CSSValue", "#[#]", this, index); - + _CSSValue operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("_CSSValue", "#[#]", this, index); + } void operator[]=(int index, _CSSValue value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -21887,6 +22297,31 @@ class _CssValueList extends _CSSValue with ListMixin<_CSSValue>, ImmutableListMi throw new UnsupportedError("Cannot resize immutable List."); } + _CSSValue get first { + if (this.length > 0) { + return JS('_CSSValue', '#[0]', this); + } + throw new StateError("No elements"); + } + + _CSSValue get last { + int len = this.length; + if (len > 0) { + return JS('_CSSValue', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + _CSSValue get single { + int len = this.length; + if (len == 1) { + return JS('_CSSValue', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + _CSSValue elementAt(int index) => this[index]; // -- end List<_CSSValue> mixins. @DomName('CSSValueList.item') @@ -21995,8 +22430,12 @@ class _EntryArray extends Object with ListMixin, ImmutableListMixin JS("int", "#.length", this); - Entry operator[](int index) => JS("Entry", "#[#]", this, index); - + Entry operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("Entry", "#[#]", this, index); + } void operator[]=(int index, Entry value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -22008,6 +22447,31 @@ class _EntryArray extends Object with ListMixin, ImmutableListMixin 0) { + return JS('Entry', '#[0]', this); + } + throw new StateError("No elements"); + } + + Entry get last { + int len = this.length; + if (len > 0) { + return JS('Entry', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Entry get single { + int len = this.length; + if (len == 1) { + return JS('Entry', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Entry elementAt(int index) => this[index]; // -- end List mixins. @DomName('EntryArray.item') @@ -22027,8 +22491,12 @@ class _EntryArraySync extends Object with ListMixin<_EntrySync>, ImmutableListMi @DocsEditable int get length => JS("int", "#.length", this); - _EntrySync operator[](int index) => JS("_EntrySync", "#[#]", this, index); - + _EntrySync operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("_EntrySync", "#[#]", this, index); + } void operator[]=(int index, _EntrySync value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -22040,6 +22508,31 @@ class _EntryArraySync extends Object with ListMixin<_EntrySync>, ImmutableListMi throw new UnsupportedError("Cannot resize immutable List."); } + _EntrySync get first { + if (this.length > 0) { + return JS('_EntrySync', '#[0]', this); + } + throw new StateError("No elements"); + } + + _EntrySync get last { + int len = this.length; + if (len > 0) { + return JS('_EntrySync', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + _EntrySync get single { + int len = this.length; + if (len == 1) { + return JS('_EntrySync', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + _EntrySync elementAt(int index) => this[index]; // -- end List<_EntrySync> mixins. @DomName('EntryArraySync.item') @@ -22102,8 +22595,12 @@ class _GamepadList extends Object with ListMixin, ImmutableListMixin JS("int", "#.length", this); - Gamepad operator[](int index) => JS("Gamepad", "#[#]", this, index); - + Gamepad operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("Gamepad", "#[#]", this, index); + } void operator[]=(int index, Gamepad value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -22115,6 +22612,31 @@ class _GamepadList extends Object with ListMixin, ImmutableListMixin 0) { + return JS('Gamepad', '#[0]', this); + } + throw new StateError("No elements"); + } + + Gamepad get last { + int len = this.length; + if (len > 0) { + return JS('Gamepad', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Gamepad get single { + int len = this.length; + if (len == 1) { + return JS('Gamepad', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Gamepad elementAt(int index) => this[index]; // -- end List mixins. @DomName('GamepadList.item') @@ -22197,8 +22719,12 @@ class _NamedNodeMap extends Object with ListMixin, ImmutableListMixin JS("int", "#.length", this); - Node operator[](int index) => JS("Node", "#[#]", this, index); - + Node operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("Node", "#[#]", this, index); + } void operator[]=(int index, Node value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -22210,6 +22736,31 @@ class _NamedNodeMap extends Object with ListMixin, ImmutableListMixin 0) { + return JS('Node', '#[0]', this); + } + throw new StateError("No elements"); + } + + Node get last { + int len = this.length; + if (len > 0) { + return JS('Node', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Node get single { + int len = this.length; + if (len == 1) { + return JS('Node', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Node elementAt(int index) => this[index]; // -- end List mixins. @DomName('NamedNodeMap.getNamedItem') @@ -22318,8 +22869,12 @@ class _SpeechInputResultList extends Object with ListMixin, I @DocsEditable int get length => JS("int", "#.length", this); - SpeechInputResult operator[](int index) => JS("SpeechInputResult", "#[#]", this, index); - + SpeechInputResult operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("SpeechInputResult", "#[#]", this, index); + } void operator[]=(int index, SpeechInputResult value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -22331,6 +22886,31 @@ class _SpeechInputResultList extends Object with ListMixin, I throw new UnsupportedError("Cannot resize immutable List."); } + SpeechInputResult get first { + if (this.length > 0) { + return JS('SpeechInputResult', '#[0]', this); + } + throw new StateError("No elements"); + } + + SpeechInputResult get last { + int len = this.length; + if (len > 0) { + return JS('SpeechInputResult', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + SpeechInputResult get single { + int len = this.length; + if (len == 1) { + return JS('SpeechInputResult', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + SpeechInputResult elementAt(int index) => this[index]; // -- end List mixins. @DomName('SpeechInputResultList.item') @@ -22350,8 +22930,12 @@ class _SpeechRecognitionResultList extends Object with ListMixin JS("int", "#.length", this); - SpeechRecognitionResult operator[](int index) => JS("SpeechRecognitionResult", "#[#]", this, index); - + SpeechRecognitionResult operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("SpeechRecognitionResult", "#[#]", this, index); + } void operator[]=(int index, SpeechRecognitionResult value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -22363,6 +22947,31 @@ class _SpeechRecognitionResultList extends Object with ListMixin 0) { + return JS('SpeechRecognitionResult', '#[0]', this); + } + throw new StateError("No elements"); + } + + SpeechRecognitionResult get last { + int len = this.length; + if (len > 0) { + return JS('SpeechRecognitionResult', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + SpeechRecognitionResult get single { + int len = this.length; + if (len == 1) { + return JS('SpeechRecognitionResult', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + SpeechRecognitionResult elementAt(int index) => this[index]; // -- end List mixins. @DomName('SpeechRecognitionResultList.item') @@ -22382,8 +22991,12 @@ class _StyleSheetList extends Object with ListMixin, ImmutableListMi @DocsEditable int get length => JS("int", "#.length", this); - StyleSheet operator[](int index) => JS("StyleSheet", "#[#]", this, index); - + StyleSheet operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return JS("StyleSheet", "#[#]", this, index); + } void operator[]=(int index, StyleSheet value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -22395,6 +23008,31 @@ class _StyleSheetList extends Object with ListMixin, ImmutableListMi throw new UnsupportedError("Cannot resize immutable List."); } + StyleSheet get first { + if (this.length > 0) { + return JS('StyleSheet', '#[0]', this); + } + throw new StateError("No elements"); + } + + StyleSheet get last { + int len = this.length; + if (len > 0) { + return JS('StyleSheet', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + StyleSheet get single { + int len = this.length; + if (len == 1) { + return JS('StyleSheet', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + StyleSheet elementAt(int index) => this[index]; // -- end List mixins. @DomName('StyleSheetList.item') diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart index e549cb6acde..a90bda181a9 100644 --- a/sdk/lib/html/dartium/html_dartium.dart +++ b/sdk/lib/html/dartium/html_dartium.dart @@ -7247,7 +7247,12 @@ class DomStringList extends NativeFieldWrapperClass1 with ListMixin, Imm @DocsEditable int get length native "DOMStringList_length_Getter"; - String operator[](int index) native "DOMStringList_item_Callback"; + String operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + String _nativeIndexedGetter(int index) native "DOMStringList_item_Callback"; void operator[]=(int index, String value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -7260,6 +7265,31 @@ class DomStringList extends NativeFieldWrapperClass1 with ListMixin, Imm throw new UnsupportedError("Cannot resize immutable List."); } + String get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + String get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + String get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + String elementAt(int index) => this[index]; // -- end List mixins. @DomName('DOMStringList.contains') @@ -9767,7 +9797,12 @@ class FileList extends NativeFieldWrapperClass1 with ListMixin, ImmutableL @DocsEditable int get length native "FileList_length_Getter"; - File operator[](int index) native "FileList_item_Callback"; + File operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + File _nativeIndexedGetter(int index) native "FileList_item_Callback"; void operator[]=(int index, File value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -9780,6 +9815,31 @@ class FileList extends NativeFieldWrapperClass1 with ListMixin, ImmutableL throw new UnsupportedError("Cannot resize immutable List."); } + File get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + File get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + File get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + File elementAt(int index) => this[index]; // -- end List mixins. @DomName('FileList.item') @@ -10613,7 +10673,12 @@ class HtmlAllCollection extends NativeFieldWrapperClass1 with ListMixin, I @DocsEditable int get length native "HTMLAllCollection_length_Getter"; - Node operator[](int index) native "HTMLAllCollection_item_Callback"; + Node operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Node _nativeIndexedGetter(int index) native "HTMLAllCollection_item_Callback"; void operator[]=(int index, Node value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -10626,6 +10691,31 @@ class HtmlAllCollection extends NativeFieldWrapperClass1 with ListMixin, I throw new UnsupportedError("Cannot resize immutable List."); } + Node get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Node get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Node get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Node elementAt(int index) => this[index]; // -- end List mixins. @DomName('HTMLAllCollection.item') @@ -10657,7 +10747,12 @@ class HtmlCollection extends NativeFieldWrapperClass1 with ListMixin, Immu @DocsEditable int get length native "HTMLCollection_length_Getter"; - Node operator[](int index) native "HTMLCollection_item_Callback"; + Node operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Node _nativeIndexedGetter(int index) native "HTMLCollection_item_Callback"; void operator[]=(int index, Node value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -10670,6 +10765,31 @@ class HtmlCollection extends NativeFieldWrapperClass1 with ListMixin, Immu throw new UnsupportedError("Cannot resize immutable List."); } + Node get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Node get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Node get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Node elementAt(int index) => this[index]; // -- end List mixins. @DomName('HTMLCollection.item') @@ -14792,7 +14912,12 @@ class MimeTypeArray extends NativeFieldWrapperClass1 with ListMixin, I @DocsEditable int get length native "DOMMimeTypeArray_length_Getter"; - MimeType operator[](int index) native "DOMMimeTypeArray_item_Callback"; + MimeType operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + MimeType _nativeIndexedGetter(int index) native "DOMMimeTypeArray_item_Callback"; void operator[]=(int index, MimeType value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -14805,6 +14930,31 @@ class MimeTypeArray extends NativeFieldWrapperClass1 with ListMixin, I throw new UnsupportedError("Cannot resize immutable List."); } + MimeType get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + MimeType get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + MimeType get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + MimeType elementAt(int index) => this[index]; // -- end List mixins. @DomName('MimeTypeArray.item') @@ -15965,7 +16115,12 @@ class NodeList extends NativeFieldWrapperClass1 with ListMixin, ImmutableL @DocsEditable int get length native "NodeList_length_Getter"; - Node operator[](int index) native "NodeList_item_Callback"; + Node operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Node _nativeIndexedGetter(int index) native "NodeList_item_Callback"; void operator[]=(int index, Node value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -15978,6 +16133,31 @@ class NodeList extends NativeFieldWrapperClass1 with ListMixin, ImmutableL throw new UnsupportedError("Cannot resize immutable List."); } + Node get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Node get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Node get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Node elementAt(int index) => this[index]; // -- end List mixins. @DomName('NodeList.item') @@ -17102,7 +17282,12 @@ class PluginArray extends NativeFieldWrapperClass1 with ListMixin, Immut @DocsEditable int get length native "DOMPluginArray_length_Getter"; - Plugin operator[](int index) native "DOMPluginArray_item_Callback"; + Plugin operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Plugin _nativeIndexedGetter(int index) native "DOMPluginArray_item_Callback"; void operator[]=(int index, Plugin value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -17115,6 +17300,31 @@ class PluginArray extends NativeFieldWrapperClass1 with ListMixin, Immut throw new UnsupportedError("Cannot resize immutable List."); } + Plugin get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Plugin get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Plugin get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Plugin elementAt(int index) => this[index]; // -- end List mixins. @DomName('PluginArray.item') @@ -18892,7 +19102,12 @@ class SourceBufferList extends EventTarget with ListMixin, Immutab @DocsEditable int get length native "SourceBufferList_length_Getter"; - SourceBuffer operator[](int index) native "SourceBufferList_item_Callback"; + SourceBuffer operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + SourceBuffer _nativeIndexedGetter(int index) native "SourceBufferList_item_Callback"; void operator[]=(int index, SourceBuffer value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -18905,6 +19120,31 @@ class SourceBufferList extends EventTarget with ListMixin, Immutab throw new UnsupportedError("Cannot resize immutable List."); } + SourceBuffer get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + SourceBuffer get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + SourceBuffer get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + SourceBuffer elementAt(int index) => this[index]; // -- end List mixins. @DomName('SourceBufferList.addEventListener') @@ -19045,7 +19285,12 @@ class SpeechGrammarList extends NativeFieldWrapperClass1 with ListMixin= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + SpeechGrammar _nativeIndexedGetter(int index) native "SpeechGrammarList_item_Callback"; void operator[]=(int index, SpeechGrammar value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -19058,6 +19303,31 @@ class SpeechGrammarList extends NativeFieldWrapperClass1 with ListMixin 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + SpeechGrammar get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + SpeechGrammar get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + SpeechGrammar elementAt(int index) => this[index]; // -- end List mixins. void addFromString(String string, [num weight]) { @@ -20752,7 +21022,12 @@ class TextTrackCueList extends NativeFieldWrapperClass1 with ListMixin= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + TextTrackCue _nativeIndexedGetter(int index) native "TextTrackCueList_item_Callback"; void operator[]=(int index, TextTrackCue value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -20765,6 +21040,31 @@ class TextTrackCueList extends NativeFieldWrapperClass1 with ListMixin 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + TextTrackCue get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + TextTrackCue get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + TextTrackCue elementAt(int index) => this[index]; // -- end List mixins. @DomName('TextTrackCueList.getCueById') @@ -20796,7 +21096,12 @@ class TextTrackList extends EventTarget with ListMixin, ImmutableList @DocsEditable int get length native "TextTrackList_length_Getter"; - TextTrack operator[](int index) native "TextTrackList_item_Callback"; + TextTrack operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + TextTrack _nativeIndexedGetter(int index) native "TextTrackList_item_Callback"; void operator[]=(int index, TextTrack value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -20809,6 +21114,31 @@ class TextTrackList extends EventTarget with ListMixin, ImmutableList throw new UnsupportedError("Cannot resize immutable List."); } + TextTrack get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + TextTrack get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + TextTrack get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + TextTrack elementAt(int index) => this[index]; // -- end List mixins. @DomName('TextTrackList.addEventListener') @@ -21057,7 +21387,12 @@ class TouchList extends NativeFieldWrapperClass1 with ListMixin, Immutabl @DocsEditable int get length native "TouchList_length_Getter"; - Touch operator[](int index) native "TouchList_item_Callback"; + Touch operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Touch _nativeIndexedGetter(int index) native "TouchList_item_Callback"; void operator[]=(int index, Touch value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -21070,6 +21405,31 @@ class TouchList extends NativeFieldWrapperClass1 with ListMixin, Immutabl throw new UnsupportedError("Cannot resize immutable List."); } + Touch get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Touch get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Touch get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Touch elementAt(int index) => this[index]; // -- end List mixins. @DomName('TouchList.item') @@ -23186,7 +23546,12 @@ class _ClientRectList extends NativeFieldWrapperClass1 with ListMixin, Imm @DocsEditable int get length native "ClientRectList_length_Getter"; - Rect operator[](int index) native "ClientRectList_item_Callback"; + Rect operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Rect _nativeIndexedGetter(int index) native "ClientRectList_item_Callback"; void operator[]=(int index, Rect value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -23199,6 +23564,31 @@ class _ClientRectList extends NativeFieldWrapperClass1 with ListMixin, Imm throw new UnsupportedError("Cannot resize immutable List."); } + Rect get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Rect get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Rect get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Rect elementAt(int index) => this[index]; // -- end List mixins. @DomName('ClientRectList.item') @@ -23235,7 +23625,12 @@ class _CssRuleList extends NativeFieldWrapperClass1 with ListMixin, Imm @DocsEditable int get length native "CSSRuleList_length_Getter"; - CssRule operator[](int index) native "CSSRuleList_item_Callback"; + CssRule operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + CssRule _nativeIndexedGetter(int index) native "CSSRuleList_item_Callback"; void operator[]=(int index, CssRule value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -23248,6 +23643,31 @@ class _CssRuleList extends NativeFieldWrapperClass1 with ListMixin, Imm throw new UnsupportedError("Cannot resize immutable List."); } + CssRule get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + CssRule get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + CssRule get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + CssRule elementAt(int index) => this[index]; // -- end List mixins. @DomName('CSSRuleList.item') @@ -23271,7 +23691,12 @@ class _CssValueList extends _CSSValue with ListMixin<_CSSValue>, ImmutableListMi @DocsEditable int get length native "CSSValueList_length_Getter"; - _CSSValue operator[](int index) native "CSSValueList_item_Callback"; + _CSSValue operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + _CSSValue _nativeIndexedGetter(int index) native "CSSValueList_item_Callback"; void operator[]=(int index, _CSSValue value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -23284,6 +23709,31 @@ class _CssValueList extends _CSSValue with ListMixin<_CSSValue>, ImmutableListMi throw new UnsupportedError("Cannot resize immutable List."); } + _CSSValue get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + _CSSValue get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + _CSSValue get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + _CSSValue elementAt(int index) => this[index]; // -- end List<_CSSValue> mixins. @DomName('CSSValueList.item') @@ -23572,7 +24022,12 @@ class _EntryArray extends NativeFieldWrapperClass1 with ListMixin, Immuta @DocsEditable int get length native "EntryArray_length_Getter"; - Entry operator[](int index) native "EntryArray_item_Callback"; + Entry operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Entry _nativeIndexedGetter(int index) native "EntryArray_item_Callback"; void operator[]=(int index, Entry value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -23585,6 +24040,31 @@ class _EntryArray extends NativeFieldWrapperClass1 with ListMixin, Immuta throw new UnsupportedError("Cannot resize immutable List."); } + Entry get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Entry get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Entry get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Entry elementAt(int index) => this[index]; // -- end List mixins. @DomName('EntryArray.item') @@ -23608,7 +24088,12 @@ class _EntryArraySync extends NativeFieldWrapperClass1 with ListMixin<_EntrySync @DocsEditable int get length native "EntryArraySync_length_Getter"; - _EntrySync operator[](int index) native "EntryArraySync_item_Callback"; + _EntrySync operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + _EntrySync _nativeIndexedGetter(int index) native "EntryArraySync_item_Callback"; void operator[]=(int index, _EntrySync value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -23621,6 +24106,31 @@ class _EntryArraySync extends NativeFieldWrapperClass1 with ListMixin<_EntrySync throw new UnsupportedError("Cannot resize immutable List."); } + _EntrySync get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + _EntrySync get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + _EntrySync get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + _EntrySync elementAt(int index) => this[index]; // -- end List<_EntrySync> mixins. @DomName('EntryArraySync.item') @@ -23705,7 +24215,12 @@ class _GamepadList extends NativeFieldWrapperClass1 with ListMixin, Imm @DocsEditable int get length native "GamepadList_length_Getter"; - Gamepad operator[](int index) native "GamepadList_item_Callback"; + Gamepad operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Gamepad _nativeIndexedGetter(int index) native "GamepadList_item_Callback"; void operator[]=(int index, Gamepad value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -23718,6 +24233,31 @@ class _GamepadList extends NativeFieldWrapperClass1 with ListMixin, Imm throw new UnsupportedError("Cannot resize immutable List."); } + Gamepad get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Gamepad get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Gamepad get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Gamepad elementAt(int index) => this[index]; // -- end List mixins. @DomName('GamepadList.item') @@ -23832,7 +24372,12 @@ class _NamedNodeMap extends NativeFieldWrapperClass1 with ListMixin, Immut @DocsEditable int get length native "NamedNodeMap_length_Getter"; - Node operator[](int index) native "NamedNodeMap_item_Callback"; + Node operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Node _nativeIndexedGetter(int index) native "NamedNodeMap_item_Callback"; void operator[]=(int index, Node value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -23845,6 +24390,31 @@ class _NamedNodeMap extends NativeFieldWrapperClass1 with ListMixin, Immut throw new UnsupportedError("Cannot resize immutable List."); } + Node get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Node get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Node get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Node elementAt(int index) => this[index]; // -- end List mixins. @DomName('NamedNodeMap.getNamedItem') @@ -23976,7 +24546,12 @@ class _SpeechInputResultList extends NativeFieldWrapperClass1 with ListMixin= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + SpeechInputResult _nativeIndexedGetter(int index) native "SpeechInputResultList_item_Callback"; void operator[]=(int index, SpeechInputResult value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -23989,6 +24564,31 @@ class _SpeechInputResultList extends NativeFieldWrapperClass1 with ListMixin 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + SpeechInputResult get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + SpeechInputResult get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + SpeechInputResult elementAt(int index) => this[index]; // -- end List mixins. @DomName('SpeechInputResultList.item') @@ -24012,7 +24612,12 @@ class _SpeechRecognitionResultList extends NativeFieldWrapperClass1 with ListMix @DocsEditable int get length native "SpeechRecognitionResultList_length_Getter"; - SpeechRecognitionResult operator[](int index) native "SpeechRecognitionResultList_item_Callback"; + SpeechRecognitionResult operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + SpeechRecognitionResult _nativeIndexedGetter(int index) native "SpeechRecognitionResultList_item_Callback"; void operator[]=(int index, SpeechRecognitionResult value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -24025,6 +24630,31 @@ class _SpeechRecognitionResultList extends NativeFieldWrapperClass1 with ListMix throw new UnsupportedError("Cannot resize immutable List."); } + SpeechRecognitionResult get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + SpeechRecognitionResult get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + SpeechRecognitionResult get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + SpeechRecognitionResult elementAt(int index) => this[index]; // -- end List mixins. @DomName('SpeechRecognitionResultList.item') @@ -24048,7 +24678,12 @@ class _StyleSheetList extends NativeFieldWrapperClass1 with ListMixin= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + StyleSheet _nativeIndexedGetter(int index) native "StyleSheetList_item_Callback"; void operator[]=(int index, StyleSheet value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -24061,6 +24696,31 @@ class _StyleSheetList extends NativeFieldWrapperClass1 with ListMixin 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + StyleSheet get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + StyleSheet get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + StyleSheet elementAt(int index) => this[index]; // -- end List mixins. @DomName('StyleSheetList.item') diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart index a2bba24eef1..711e3db7b64 100644 --- a/sdk/lib/svg/dart2js/svg_dart2js.dart +++ b/sdk/lib/svg/dart2js/svg_dart2js.dart @@ -3012,8 +3012,12 @@ class LengthList extends Object with ListMixin, ImmutableListMixin this.getItem(index); - + Length operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return this.getItem(index); + } void operator[]=(int index, Length value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -3027,6 +3031,31 @@ class LengthList extends Object with ListMixin, ImmutableListMixin 0) { + return JS('Length', '#[0]', this); + } + throw new StateError("No elements"); + } + + Length get last { + int len = this.length; + if (len > 0) { + return JS('Length', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Length get single { + int len = this.length; + if (len == 1) { + return JS('Length', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Length elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGLengthList.appendItem') @@ -3473,8 +3502,12 @@ class NumberList extends Object with ListMixin, ImmutableListMixin this.getItem(index); - + Number operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return this.getItem(index); + } void operator[]=(int index, Number value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -3488,6 +3521,31 @@ class NumberList extends Object with ListMixin, ImmutableListMixin 0) { + return JS('Number', '#[0]', this); + } + throw new StateError("No elements"); + } + + Number get last { + int len = this.length; + if (len > 0) { + return JS('Number', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Number get single { + int len = this.length; + if (len == 1) { + return JS('Number', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Number elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGNumberList.appendItem') @@ -4165,8 +4223,12 @@ class PathSegList extends Object with ListMixin, ImmutableListMixin this.getItem(index); - + PathSeg operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return this.getItem(index); + } void operator[]=(int index, PathSeg value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -4180,6 +4242,31 @@ class PathSegList extends Object with ListMixin, ImmutableListMixin 0) { + return JS('PathSeg', '#[0]', this); + } + throw new StateError("No elements"); + } + + PathSeg get last { + int len = this.length; + if (len > 0) { + return JS('PathSeg', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + PathSeg get single { + int len = this.length; + if (len == 1) { + return JS('PathSeg', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + PathSeg elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGPathSegList.appendItem') @@ -4887,8 +4974,12 @@ class StringList extends Object with ListMixin, ImmutableListMixin this.getItem(index); - + String operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return this.getItem(index); + } void operator[]=(int index, String value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -4902,6 +4993,31 @@ class StringList extends Object with ListMixin, ImmutableListMixin 0) { + return JS('String', '#[0]', this); + } + throw new StateError("No elements"); + } + + String get last { + int len = this.length; + if (len > 0) { + return JS('String', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + String get single { + int len = this.length; + if (len == 1) { + return JS('String', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + String elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGStringList.appendItem') @@ -5882,8 +5998,12 @@ class TransformList extends Object with ListMixin, ImmutableListMixin @DocsEditable final int numberOfItems; - Transform operator[](int index) => this.getItem(index); - + Transform operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return this.getItem(index); + } void operator[]=(int index, Transform value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -5897,6 +6017,31 @@ class TransformList extends Object with ListMixin, ImmutableListMixin throw new UnsupportedError("Cannot resize immutable List."); } + Transform get first { + if (this.length > 0) { + return JS('Transform', '#[0]', this); + } + throw new StateError("No elements"); + } + + Transform get last { + int len = this.length; + if (len > 0) { + return JS('Transform', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Transform get single { + int len = this.length; + if (len == 1) { + return JS('Transform', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Transform elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGTransformList.appendItem') @@ -6238,8 +6383,12 @@ class _ElementInstanceList extends Object with ListMixin, Immut @DocsEditable int get length => JS("int", "#.length", this); - ElementInstance operator[](int index) => this.item(index); - + ElementInstance operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return this.item(index); + } void operator[]=(int index, ElementInstance value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -6251,6 +6400,31 @@ class _ElementInstanceList extends Object with ListMixin, Immut throw new UnsupportedError("Cannot resize immutable List."); } + ElementInstance get first { + if (this.length > 0) { + return JS('ElementInstance', '#[0]', this); + } + throw new StateError("No elements"); + } + + ElementInstance get last { + int len = this.length; + if (len > 0) { + return JS('ElementInstance', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + ElementInstance get single { + int len = this.length; + if (len == 1) { + return JS('ElementInstance', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + ElementInstance elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGElementInstanceList.item') diff --git a/sdk/lib/svg/dartium/svg_dartium.dart b/sdk/lib/svg/dartium/svg_dartium.dart index 3310b73a22e..dbe50825722 100644 --- a/sdk/lib/svg/dartium/svg_dartium.dart +++ b/sdk/lib/svg/dartium/svg_dartium.dart @@ -3273,7 +3273,12 @@ class LengthList extends NativeFieldWrapperClass1 with ListMixin, Immuta @DocsEditable int get numberOfItems native "SVGLengthList_numberOfItems_Getter"; - Length operator[](int index) native "SVGLengthList_item_Callback"; + Length operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Length _nativeIndexedGetter(int index) native "SVGLengthList_item_Callback"; void operator[]=(int index, Length value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -3288,6 +3293,31 @@ class LengthList extends NativeFieldWrapperClass1 with ListMixin, Immuta throw new UnsupportedError("Cannot resize immutable List."); } + Length get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Length get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Length get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Length elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGLengthList.appendItem') @@ -3811,7 +3841,12 @@ class NumberList extends NativeFieldWrapperClass1 with ListMixin, Immuta @DocsEditable int get numberOfItems native "SVGNumberList_numberOfItems_Getter"; - Number operator[](int index) native "SVGNumberList_item_Callback"; + Number operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Number _nativeIndexedGetter(int index) native "SVGNumberList_item_Callback"; void operator[]=(int index, Number value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -3826,6 +3861,31 @@ class NumberList extends NativeFieldWrapperClass1 with ListMixin, Immuta throw new UnsupportedError("Cannot resize immutable List."); } + Number get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Number get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Number get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Number elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGNumberList.appendItem') @@ -4776,7 +4836,12 @@ class PathSegList extends NativeFieldWrapperClass1 with ListMixin, Immu @DocsEditable int get numberOfItems native "SVGPathSegList_numberOfItems_Getter"; - PathSeg operator[](int index) native "SVGPathSegList_item_Callback"; + PathSeg operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + PathSeg _nativeIndexedGetter(int index) native "SVGPathSegList_item_Callback"; void operator[]=(int index, PathSeg value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -4791,6 +4856,31 @@ class PathSegList extends NativeFieldWrapperClass1 with ListMixin, Immu throw new UnsupportedError("Cannot resize immutable List."); } + PathSeg get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + PathSeg get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + PathSeg get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + PathSeg elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGPathSegList.appendItem') @@ -5595,7 +5685,12 @@ class StringList extends NativeFieldWrapperClass1 with ListMixin, Immuta @DocsEditable int get numberOfItems native "SVGStringList_numberOfItems_Getter"; - String operator[](int index) native "SVGStringList_item_Callback"; + String operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + String _nativeIndexedGetter(int index) native "SVGStringList_item_Callback"; void operator[]=(int index, String value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -5610,6 +5705,31 @@ class StringList extends NativeFieldWrapperClass1 with ListMixin, Immuta throw new UnsupportedError("Cannot resize immutable List."); } + String get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + String get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + String get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + String elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGStringList.appendItem') @@ -6679,7 +6799,12 @@ class TransformList extends NativeFieldWrapperClass1 with ListMixin, @DocsEditable int get numberOfItems native "SVGTransformList_numberOfItems_Getter"; - Transform operator[](int index) native "SVGTransformList_item_Callback"; + Transform operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Transform _nativeIndexedGetter(int index) native "SVGTransformList_item_Callback"; void operator[]=(int index, Transform value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -6694,6 +6819,31 @@ class TransformList extends NativeFieldWrapperClass1 with ListMixin, throw new UnsupportedError("Cannot resize immutable List."); } + Transform get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Transform get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Transform get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Transform elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGTransformList.appendItem') @@ -7089,7 +7239,12 @@ class _ElementInstanceList extends NativeFieldWrapperClass1 with ListMixin= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + ElementInstance _nativeIndexedGetter(int index) native "SVGElementInstanceList_item_Callback"; void operator[]=(int index, ElementInstance value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -7102,6 +7257,31 @@ class _ElementInstanceList extends NativeFieldWrapperClass1 with ListMixin 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + ElementInstance get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + ElementInstance get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + ElementInstance elementAt(int index) => this[index]; // -- end List mixins. @DomName('SVGElementInstanceList.item') diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart index 851be055ed0..c9735cebd79 100644 --- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart +++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart @@ -199,8 +199,12 @@ class SqlResultSetRowList extends Object with ListMixin, ImmutableListMixin @DocsEditable int get length => JS("int", "#.length", this); - Map operator[](int index) => this.item(index); - + Map operator[](int index) { + if (JS("bool", "# >>> 0 !== # || # >= #", index, + index, index, length)) + throw new RangeError.range(index, 0, length); + return this.item(index); + } void operator[]=(int index, Map value) { throw new UnsupportedError("Cannot assign element of immutable List."); } @@ -212,6 +216,31 @@ class SqlResultSetRowList extends Object with ListMixin, ImmutableListMixin throw new UnsupportedError("Cannot resize immutable List."); } + Map get first { + if (this.length > 0) { + return JS('Map', '#[0]', this); + } + throw new StateError("No elements"); + } + + Map get last { + int len = this.length; + if (len > 0) { + return JS('Map', '#[#]', this, len - 1); + } + throw new StateError("No elements"); + } + + Map get single { + int len = this.length; + if (len == 1) { + return JS('Map', '#[0]', this); + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Map elementAt(int index) => this[index]; // -- end List mixins. @DomName('SQLResultSetRowList.item') diff --git a/sdk/lib/web_sql/dartium/web_sql_dartium.dart b/sdk/lib/web_sql/dartium/web_sql_dartium.dart index c7c3bc00c1e..c72e56f7532 100644 --- a/sdk/lib/web_sql/dartium/web_sql_dartium.dart +++ b/sdk/lib/web_sql/dartium/web_sql_dartium.dart @@ -217,7 +217,12 @@ class SqlResultSetRowList extends NativeFieldWrapperClass1 with ListMixin, @DocsEditable int get length native "SQLResultSetRowList_length_Getter"; - Map operator[](int index) native "SQLResultSetRowList_item_Callback"; + Map operator[](int index) { + if (index < 0 || index >= length) + throw new RangeError.range(index, 0, length); + return _nativeIndexedGetter(index); + } + Map _nativeIndexedGetter(int index) native "SQLResultSetRowList_item_Callback"; void operator[]=(int index, Map value) { throw new UnsupportedError("Cannot assign element of immutable List."); @@ -230,6 +235,31 @@ class SqlResultSetRowList extends NativeFieldWrapperClass1 with ListMixin, throw new UnsupportedError("Cannot resize immutable List."); } + Map get first { + if (this.length > 0) { + return this[0]; + } + throw new StateError("No elements"); + } + + Map get last { + int len = this.length; + if (len > 0) { + return this[len - 1]; + } + throw new StateError("No elements"); + } + + Map get single { + int len = this.length; + if (len == 1) { + return this[0]; + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + Map elementAt(int index) => this[index]; // -- end List mixins. @DomName('SQLResultSetRowList.item') diff --git a/tests/html/node_test.dart b/tests/html/node_test.dart index c8a009cdc3a..083478f87b0 100644 --- a/tests/html/node_test.dart +++ b/tests/html/node_test.dart @@ -118,6 +118,17 @@ main() { expect(makeNodeWithChildren().nodes, isNodeList); }); + test('indexer', () { + var node = new DivElement(); + expect(() { + node.nodes[0]; + }, throwsRangeError); + + expect(() { + node.nodes[-1]; + }, throwsRangeError); + }); + test('first', () { var node = makeNodeWithChildren(); expect(node.nodes.first, isText); diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py index 6adefadaa43..abc3ff360ed 100644 --- a/tools/dom/scripts/systemhtml.py +++ b/tools/dom/scripts/systemhtml.py @@ -712,19 +712,22 @@ class Dart2JSBackend(HtmlDartGenerator): 'CustomIndexedSetter' in ext_attrs) if has_indexed_getter: + indexed_getter = ('JS("%s", "#[#]", this, index)' % + self.SecureOutputType(element_type)); + elif any(op.id == 'getItem' for op in self._interface.operations): + indexed_getter = 'this.getItem(index)' + elif any(op.id == 'item' for op in self._interface.operations): + indexed_getter = 'this.item(index)' + + if indexed_getter: self._members_emitter.Emit( '\n' - ' $TYPE operator[](int index) => ' - 'JS("$TYPE", "#[#]", this, index);\n', - TYPE=self.SecureOutputType(element_type)) - else: - if any(op.id == 'getItem' for op in self._interface.operations): - indexed_getter = 'this.getItem(index)' - elif any(op.id == 'item' for op in self._interface.operations): - indexed_getter = 'this.item(index)' - self._members_emitter.Emit( - '\n' - ' $TYPE operator[](int index) => $INDEXED_GETTER;\n', + ' $TYPE operator[](int index) {\n' + ' if (JS("bool", "# >>> 0 !== # || # >= #", index,\n' + ' index, index, length))\n' + ' throw new RangeError.range(index, 0, length);\n' + ' return $INDEXED_GETTER;\n' + ' }', INDEXED_GETTER=indexed_getter, TYPE=self.SecureOutputType(element_type)) diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py index 4c618543fa8..2c955bdbecc 100644 --- a/tools/dom/scripts/systemnative.py +++ b/tools/dom/scripts/systemnative.py @@ -428,7 +428,12 @@ class DartiumBackend(HtmlDartGenerator): else: self._members_emitter.Emit( '\n' - ' $TYPE operator[](int index) native "$(INTERFACE)_item_Callback";\n', + ' $TYPE operator[](int index) {\n' + ' if (index < 0 || index >= length)\n' + ' throw new RangeError.range(index, 0, length);\n' + ' return _nativeIndexedGetter(index);\n' + ' }\n' + ' $TYPE _nativeIndexedGetter(int index) native "$(INTERFACE)_item_Callback";\n', TYPE=self.SecureOutputType(element_type), INTERFACE=self._interface.id) diff --git a/tools/dom/templates/immutable_list_mixin.darttemplate b/tools/dom/templates/immutable_list_mixin.darttemplate index e9bffe58e45..fc48b499079 100644 --- a/tools/dom/templates/immutable_list_mixin.darttemplate +++ b/tools/dom/templates/immutable_list_mixin.darttemplate @@ -12,4 +12,41 @@ $if DEFINE_LENGTH_SETTER } $endif + $E get first { + if (this.length > 0) { +$if DART2JS + return JS('$E', '#[0]', this); +$else + return this[0]; +$endif + } + throw new StateError("No elements"); + } + + $E get last { + int len = this.length; + if (len > 0) { +$if DART2JS + return JS('$E', '#[#]', this, len - 1); +$else + return this[len - 1]; +$endif + } + throw new StateError("No elements"); + } + + $E get single { + int len = this.length; + if (len == 1) { +$if DART2JS + return JS('$E', '#[0]', this); +$else + return this[0]; +$endif + } + if (len == 0) throw new StateError("No elements"); + throw new StateError("More than one element"); + } + + $E elementAt(int index) => this[index]; // -- end List<$E> mixins.