import java.lang { JStringBuilder=StringBuilder, JCharacter=Character { toChars, charCount } } """Builder utility for constructing [[strings|String]] by incrementally appending strings or characters. value builder = StringBuilder(); builder.append("hello"); builder.appendCharacter(' '); builder.append("world"); String hello = builder.string; //hello world""" tagged("Strings") shared native final class StringBuilder() satisfies List<Character> { "The number characters in the current content, that is, the [[size|String.size]] of the produced [[string]]." shared actual native Integer size; shared actual native Integer? lastIndex; "The resulting string. If no characters have been appended, the empty string." shared actual native String string; shared actual native Iterator<Character> iterator(); "Returns a string of the given [[length]] containing the characters beginning at the given [[index]]." shared native String substring(Integer index, Integer length); shared actual native Character? getFromFirst(Integer index); "Append the characters in the given [[string]]." shared native StringBuilder append(String string); "Append the characters in the given [[strings]]." shared native StringBuilder appendAll({String*} strings) { for (s in strings) { append(s); } return this; } "Prepend the characters in the given [[string]]." shared native StringBuilder prepend(String string); "Prepend the characters in the given [[strings]]." shared native StringBuilder prependAll({String*} strings) { for (s in strings) { prepend(s); } return this; } "Append the given [[character]]." shared native StringBuilder appendCharacter(Character character); "Prepend the given [[character]]." shared native StringBuilder prependCharacter(Character character); "Append a newline character." shared native StringBuilder appendNewline() => appendCharacter('\n'); "Append a space character." shared native StringBuilder appendSpace() => appendCharacter(' '); "Remove all content and return to initial state." shared native StringBuilder clear(); "Insert a [[string]] at the specified [[index]]." shared native StringBuilder insert(Integer index, String string); "Insert a [[character]] at the specified [[index]]." shared native StringBuilder insertCharacter (Integer index, Character character) ; "Replaces the specified [[number of characters|length]] from the current content, starting at the specified [[index]], with the given [[string]]. If `length` is nonpositive, nothing is replaced." shared native StringBuilder replace (Integer index, Integer length, String string); "Deletes the specified [[number of characters|length]] from the current content, starting at the specified [[index]]. If `length` is nonpositive, nothing is deleted." shared native StringBuilder delete(Integer index, Integer length/*=1*/); "Deletes the specified [[number of characters|length]] from the start of the string. If `length` is nonpositive, nothing is deleted." shared native StringBuilder deleteInitial(Integer length); "Deletes the specified [[number of characters|length]] from the end of the string. If `length` is nonpositive, nothing is deleted." shared native StringBuilder deleteTerminal(Integer length); "Reverses the order of the current characters." shared native StringBuilder reverseInPlace(); shared actual native Boolean equals(Object that); shared actual native Integer hash; } shared native("jvm") final class StringBuilder() satisfies List<Character> { value builder = JStringBuilder(); shared actual native("jvm") Integer size => builder.codePointCount(0, builder.length()); shared actual native("jvm") Integer? lastIndex => if (builder.length() == 0) then null else builder.length() - 1; shared actual native("jvm") String string => builder.string; shared actual native("jvm") Iterator<Character> iterator() { object stringBuilderIterator satisfies Iterator<Character> { variable Integer offset = 0; shared actual Character|Finished next() { if (offset < builder.length()) { Integer codePoint = builder.codePointAt(offset); offset += charCount(codePoint); return codePoint.character; } else { return finished; } } } return stringBuilderIterator; } shared native("jvm") String substring(Integer index, Integer length) { "index must not be negative" assert (index>=0); "index must not be greater than size" assert(index<=size); "index+length must not be greater than size" assert (index+length<=size); if (length>0) { Integer start = startIndex(index); Integer end = endIndex(start, length); return builder.substring(start, end); } else { return ""; } } shared actual native("jvm") Character? getFromFirst(Integer index) => if (index<0 || index>size) then null else builder.codePointAt(startIndex(index)).character; shared native("jvm") StringBuilder append(String string) { builder.append(string); return this; } shared native("jvm") StringBuilder prepend(String string) { builder.insert(0, string); return this; } shared native("jvm") StringBuilder appendCharacter(Character character) { builder.appendCodePoint(character.integer); return this; } shared native("jvm") StringBuilder prependCharacter(Character character) { builder.insert(0, toChars(character.integer)); return this; } shared native("jvm") StringBuilder clear() { builder.setLength(0); return this; } shared native("jvm") StringBuilder insert(Integer index, String string) { "index must not be negative" assert (index>=0); "index must not be greater than size" assert(index<=size); builder.insert(startIndex(index), string); return this; } shared native("jvm") StringBuilder insertCharacter (Integer index, Character character) { "index must not be negative" assert (index>=0); "index must not be greater than size" assert(index<=size); builder.insert(startIndex(index), toChars(character.integer)); return this; } shared native("jvm") StringBuilder replace (Integer index, Integer length, String string) { "index must not be negative" assert (index>=0); "index must not be greater than size" assert(index<=size); "index+length must not be greater than size" assert (index+length<=size); if (!string.empty) { Integer len = (length<0) then 0 else length; Integer start = startIndex(index); Integer end = endIndex(start, len); builder.replace(start, end, string); } return this; } shared native("jvm") StringBuilder delete(Integer index, Integer length) { "index must not be negative" assert (index>=0); "index must not be greater than size" assert(index<=size); "index+length must not be greater than size" assert (index+length<=size); if (length>0) { Integer start = startIndex(index); Integer end = endIndex(start, length); builder.delete(start, end); } return this; } shared native("jvm") StringBuilder deleteInitial(Integer length) { "length must not be greater than size" assert (length<=size); if (length>0) { builder.delete(0, startIndex(length)); } return this; } shared native("jvm") StringBuilder deleteTerminal(Integer length) { "length must not be greater than size" assert (length<=size); if (length>0) { Integer start = startIndex(size - length); builder.delete(start, builder.length()); } return this; } shared native("jvm") StringBuilder reverseInPlace() { builder.reverse(); return this; } shared actual native("jvm") Boolean equals(Object that) => builder.equals(that); shared actual native("jvm") Integer hash => builder.hash; Integer startIndex(Integer index) => builder.offsetByCodePoints(0, index); Integer endIndex(Integer start, Integer length) => builder.offsetByCodePoints(start, length); } shared native("js") final class StringBuilder() satisfies List<Character> { variable String str = ""; shared actual native("js") Integer size => str.size; shared actual native("js") Integer? lastIndex => if (str.size == 0) then null else str.size - 1; shared actual native("js") String string => str; shared actual native("js") Iterator<Character> iterator() => str.iterator(); shared native("js") String substring(Integer index, Integer length) { "index must not be negative" assert (index>=0); "index must not be greater than size" assert(index<=size); "index+length must not be greater than size" assert (index+length<=size); return if (length>0) then str[index..length] else ""; } shared actual native("js") Character? getFromFirst(Integer index) => if (index<0 || index>size) then null else str.getFromFirst(index); shared native("js") StringBuilder append(String string) { str = str + string; return this; } shared native("js") StringBuilder prepend(String string) { str = string + str; return this; } shared native("js") StringBuilder appendCharacter(Character character) { str = str + character.string; return this; } shared native("js") StringBuilder prependCharacter(Character character) { str = character.string + str; return this; } shared native("js") StringBuilder clear() { str = ""; return this; } shared native("js") StringBuilder insert(Integer index, String string) { "index must not be negative" assert (index>=0); "index must not be greater than size" assert(index<=size); str = str[0:index] + string + str[index...]; return this; } shared native("js") StringBuilder insertCharacter (Integer index, Character character) => insert(index, character.string); shared native("js") StringBuilder replace (Integer index, Integer length, String string) { "index must not be negative" assert (index>=0); "index must not be greater than size" assert(index<=size); "index+length must not be greater than size" assert (index+length<=size); if (!string.empty) { str = str[0:index] + string + str[index+length...]; } return this; } shared native("js") StringBuilder delete(Integer index, Integer length) { "index must not be negative" assert (index>=0); "index must not be greater than size" assert(index<=size); "index+length must not be greater than size" assert (index+length<=size); if (length>0) { str = str[0:index] + str[index+length...]; } return this; } shared native("js") StringBuilder deleteInitial(Integer length) { "length must not be greater than size" assert (length<=size); if (length>0) { str = str[length...]; } return this; } shared native("js") StringBuilder deleteTerminal(Integer length) { "length must not be greater than size" assert (length<=size); if (length>0) { str = str[0:size-length]; } return this; } shared native("js") StringBuilder reverseInPlace() { str = str.reversed; return this; } shared actual native("js") Boolean equals(Object that) => str.equals(that); shared actual native("js") Integer hash => str.hash; }