├── .gitignore ├── axis ├── Bool.axis ├── Map.axis ├── Int.axis ├── Num.axis ├── package-info.axis ├── Str.axis ├── List.axis └── Any.axis ├── LICENSE ├── User.axis ├── class.axis └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.ear 17 | *.zip 18 | *.tar.gz 19 | *.rar 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | -------------------------------------------------------------------------------- /axis/Bool.axis: -------------------------------------------------------------------------------- 1 | //包级别类 <<<<<<<<<<<<<<<<<<<<<< 2 | 3 | /** 4 | 对应 Java 的 Boolean 5 | */ 6 | class Bool : Booleanable { //默认继承 Any 7 | 8 | final Str TRUE : 'true' 9 | final Str FALSE : 'false' 10 | 11 | //IDE 自动索引并显示左侧的上下箭头,不用写,导出会自动加上 @Override 12 | Str toStr() { 13 | ^ this ? TRUE ; FALSE 14 | } 15 | 16 | Bool OF(Str s) { 17 | s = s ?? '' 18 | ^ Bool{ 19 | value : s = TRUE ? true ; false 20 | } 21 | } 22 | 23 | 24 | Bool equal(Any a) { 25 | ^ a instanceof Booleanable & super.equal(/* Any a : */ a) 26 | } 27 | 28 | } 29 | 30 | //包级别类 >>>>>>>>>>>>>>>>>>>>>> 31 | -------------------------------------------------------------------------------- /axis/Map.axis: -------------------------------------------------------------------------------- 1 | import JavaJSON : com.alibaba.fastjson.JSON //取别名 2 | import com.alibaba.fastjson.JSONObject 3 | 4 | //包级别类 <<<<<<<<<<<<<<<<<<<<<< 5 | 6 | /** 7 | 对应 Java 的 LinkedHashMap 8 | */ 9 | class Map : Mappable { 10 | 11 | native V get(K key) 12 | 13 | 14 | Bool equal(Any a) { 15 | ^ a instanceof Mappable & super.equal(/* Any a : */ a) 16 | } 17 | 18 | 19 | native Map put( 20 | K key 21 | V value 22 | ) 23 | 24 | 25 | override Str toStr() { 26 | ^ JSON.toJSONString(obj : this) 27 | } 28 | 29 | Map OF(Str s) { 30 | 31 | ^ OF( 32 | map : JavaJSON.parseObject(json : s) 33 | ) 34 | } 35 | 36 | Map OF(Map map){ 37 | 38 | map : map ?; Map{} 39 | Map obj : Map{} 40 | map.forEach( 41 | Int index 42 | Any key 43 | Any value 44 | ) { 45 | 46 | obj 47 | .key : key 48 | .value : value 49 | } 50 | 51 | ^ obj 52 | } 53 | 54 | 55 | 56 | } 57 | 58 | //包级别类 >>>>>>>>>>>>>>>>>>>>>> 59 | -------------------------------------------------------------------------------- /axis/Int.axis: -------------------------------------------------------------------------------- 1 | //包级别类 <<<<<<<<<<<<<<<<<<<<<< 2 | 3 | 4 | /** 5 | 对应 Java 的 Long 6 | */ 7 | class Int : Integerable { 8 | 9 | final MIN_VALUE : Int : 0x0.0000000000001P-1022 10 | final MAX_VALUE : Int : 0x1.fffffffffffffP+1023 11 | 12 | 13 | Bool equal(Any a) { 14 | ^ a instanceof Integerable & super.equal(/* Any a : */ a) 15 | } 16 | 17 | @NotNull 18 | Int compareTo(Int n) { 19 | 20 | ^ COMPARE_TO( 21 | n0 : this 22 | n1 : n 23 | ) 24 | } 25 | 26 | @NotNull 27 | Int COMPARE_TO( 28 | n0 : Int 29 | n1 : Int 30 | ) { 31 | 32 | n0 : n0 ?; 0 33 | n1 : n1 ?; 0 34 | Int diff : n0.(value) - n1.(value) //如果有null则转为0 35 | if (diff = 0) { 36 | ^ 0 37 | } 38 | ^ diff < 0 ? -1 ; 1 //用 diff / Math.abs(n : diff) 可能因为计算误差导致算出小数 39 | } 40 | 41 | override Str toStr() { 42 | ^ “” + value 43 | } 44 | 45 | 46 | OF(Str s) { 47 | 48 | s : s ?; '' 49 | ^ Int{ 50 | value : castToInt(s : s) 51 | } 52 | } 53 | 54 | 55 | final native Int castToInt(Str s) 56 | } 57 | 58 | //包级别类 >>>>>>>>>>>>>>>>>>>>>> 59 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 TommyLemon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /User.axis: -------------------------------------------------------------------------------- 1 | import JavaJSON : com.alibaba.fastjson.JSON //取别名 2 | import com.alibaba.fastjson.JSONObject 3 | 4 | //包级别类 <<<<<<<<<<<<<<<<<<<<<< 5 | 6 | class Map User : Serializable { // Java: public class User extends LinkedHashMap implements Serializable { 7 | 8 | Int _id 9 | Str _name 10 | List _id //对于类型不同的变量,名称可重复,引用时会自动带上类型标注来区分,例如 _id@Int, _id@List,泛型不行 11 | 12 | //会自动生成这些默认方法 <<<<<<<<<<<<<<<<<<< 13 | Int getId() { 14 | ^ _id@Int // @Int 是 IDE 自动给出的类型提示,高亮显示,不可编辑,导出代码会自动生成 15 | } 16 | setId(Int id) { 17 | this._id@Int : id@Int // @Int 是 IDE 自动给出的类型提示,高亮显示,不可编辑,导出代码会自动生成 18 | } 19 | 20 | setName(Str name) { 21 | this._name@Str : name@Str // @Str 是 IDE 自动给出的类型提示,高亮显示,不可编辑,导出代码会自动生成 22 | } 23 | //会自动生成这些默认方法 >>>>>>>>>>>>>>>>>>>> 24 | 25 | 26 | //_id@List 和 _id@Int 重名,必须重命名方法来区分,否则以后各种 方法名()@返回类型 ,就很难看了 <<<<<<<<<<<<<<<<<<< 27 | List getIdList() { 28 | ^ _id@List = null ? [] ; _id@List //可简化为 return _id@List ?; [] 29 | } 30 | 31 | setIdList(List id) { 32 | this._id@List : id@List // @List 是 IDE 自动给出的类型提示,高亮显示,不可编辑,导出代码会自动生成 33 | } 34 | //_id@List 和 _id@Int 重名,必须重命名方法来区分,否则以后就是各种 方法名()@返回类型 ,那就很难看了 >>>>>>>>>>>>>>>>>>> 35 | 36 | 37 | toStr() { 38 | ^ '{' 39 | + '\n id:' + _id@Int 40 | + '\n name:' + _name@Str 41 | + '\n idList:' + getIdList() 42 | + '\n}' 43 | } 44 | } 45 | 46 | //包级别类 >>>>>>>>>>>>>>>>>>>>>> 47 | -------------------------------------------------------------------------------- /axis/Num.axis: -------------------------------------------------------------------------------- 1 | //包级别类 <<<<<<<<<<<<<<<<<<<<<< 2 | 3 | class Num : Int, Numbericable { //父类必须写在第一个,后面的只能是 interface 或 function 4 | 5 | Int leftValue : 0 //小数左边的整数值 6 | Int rightValue : 0 //小数右边的整数值 7 | 8 | 9 | Bool equal(Any a) { 10 | ^ a instanceof Numbericable & super.equal(/* Any a : */ a) 11 | } 12 | 13 | @Override 14 | Int compareTo(Int n) { 15 | ^ compareTo( 16 | d : OF(n : n) 17 | ) 18 | } 19 | 20 | Int compareTo(Num d) { 21 | Int leftCompare : COMPARE_TO( 22 | n0 : leftValue 23 | n1 : d.(leftValue) 24 | ) 25 | ^ leftCompare != 0 ? leftCompare ; COMPARE_TO( 26 | n0 : rightValue 27 | n1 : d.rightValue 28 | ) // 'n0 : ' , 'n1 : ' 这种参数字符串都由编辑器生成且不可更改,参考IntelliJ IDEA参数提示功能 29 | } 30 | 31 | @Override 32 | Str toStr() { 33 | ^ leftValue + '.' + rightValue 34 | } 35 | 36 | //在Java中子类实现父类已有的static函数是覆盖,而不是重写,但这里特地加上 override 是为了更明显地提示这个函数会覆盖父类的同名函数 37 | override Num OF(Int n) { 38 | ^ Num{ 39 | leftValue : ( 40 | n = null ? 0 ; n.( 41 | value 42 | ) 43 | ) 44 | } 45 | } 46 | 47 | override Num OF(Str s) { 48 | s : s ?; '' 49 | Int index : s.indexOf(s : '.') 50 | ^ Num{ 51 | leftValue : Int.OF( 52 | s : index < 0 ? s ; s.subStr( 53 | start : 0 54 | end : index 55 | ) 56 | ) 57 | rightValue : index < 0 ? 0 ; Int.OF( 58 | s : s.subStr(start : index + 1) 59 | ) 60 | } 61 | } 62 | 63 | } 64 | 65 | //包级别类 >>>>>>>>>>>>>>>>>>>>>> 66 | -------------------------------------------------------------------------------- /axis/package-info.axis: -------------------------------------------------------------------------------- 1 | //包级别 function <<<<<<<<<<<<<<<<<<<<<< 2 | 3 | 4 | and() // & 5 | or() // | 6 | not() // ! 7 | 8 | add() // + 9 | minus() // - 10 | multi() // * 11 | divide() // / 12 | square() // ^ 13 | remain() // % 14 | 15 | isSelf() // == 16 | isNotSelf() // !== 17 | 18 | equal() // = 19 | more() // > 20 | less() // < 21 | moreOrEqual() // >= 22 | lessOrEqual() // <= 23 | notEqual() // != 24 | 25 | 26 | //包级别 function >>>>>>>>>>>>>>>>>>>>>> 27 | 28 | 29 | 30 | 31 | 32 | //包级别 interface <<<<<<<<<<<<<<<<<<<<<< 33 | 34 | 35 | /** 36 | 逻辑运算 37 | */ 38 | interface Logicable : and, or, not {} 39 | 40 | /** 41 | 数学运算 42 | */ 43 | interface Calculatable : add, minus, multi, divide, square, remain {} 44 | 45 | 46 | /** 47 | 等价运算 =, != 48 | */ 49 | interface Equallable : equal, notEqual {} 50 | 51 | 52 | /** 53 | 比较运算 =, >, <, >=, <=, != 54 | */ 55 | interface Comparable : Equabllable {} 56 | 57 | 58 | 59 | //TODO 该不该提供 Booelean, Intergerable, Numberic,String,容易导致 1 + 2 = 3 这种重写 add 方法后出现的奇葩问题,不过也可以直接给 add() 方法加 final 来解决。 60 | /** 61 | 判断 Booelean 62 | */ 63 | interface Booleanable : Equallable, not { 64 | 65 | final Bool TRUE : true 66 | final Bool FALSE : false 67 | } 68 | 69 | /** 70 | 整数 Integer + Long,例如 71 | 1, 2, 5, 10, 100, -1, -128, -1024 72 | */ 73 | interface Intergerable : Comparable, Calculatable {} 74 | 75 | /** 76 | 小数 Numberic,例如 77 | 1.0, 2.1, 5.5, 10.24, 100.99, -1.1, -128.05, -1024.210 78 | */ 79 | interface Numbericable : Comparable, Calculatable {} 80 | 81 | /** 82 | 字符串 String,例如 83 | '0', 'a', 'bcd', '1.23', '{}', '[]' 84 | */ 85 | interface Stringable : Comparable {} 86 | 87 | 88 | /** 89 | 映射 Map,可包含键值对 key : value,其中 key 和 value 都默认可为任何类型,如果泛型指定了类型,则按指定的类型。例如 90 | {}, {'a' : 1}, 91 | { 92 | 'b' : false 93 | 'c' : 'str' 94 | 'd' : {} 95 | 'e' : [ 96 | 1 97 | 2 98 | 3 99 | ] 100 | } 101 | */ 102 | interface Mappable : Comparable, add, minus {} 103 | 104 | 105 | /** 106 | 列表 List,可包含任何类型的元素 element,element 默认可为任何类型,如果泛型指定了类型,则按指定的类型。例如 107 | [], [1], 108 | [ 109 | 2 110 | 5 111 | 10 112 | ], 113 | */ 114 | interface Listable : Equallable, add, minus {} 115 | 116 | 117 | //包级别 interface >>>>>>>>>>>>>>>>>>>>>> 118 | 119 | 120 | -------------------------------------------------------------------------------- /class.axis: -------------------------------------------------------------------------------- 1 | package axis.lang 2 | 3 | //包级别常量 <<<<<<<<<<<<<<<<<<<<<< 4 | 5 | Str UTF_8 : 'utf-8' 6 | Str VERSION_NAME : '1.0' 7 | Int VERSION_CODE : 1 8 | Bool DEBUG : true 9 | Str[] BASE_TYPES : [ 10 | 'Bool' 11 | 'Int' 12 | 'Str' 13 | 'Map' 14 | 'List' 15 | ] 16 | 17 | //包级别常量 >>>>>>>>>>>>>>>>>>>>>> 18 | 19 | 20 | 21 | //包级别函数 <<<<<<<<<<<<<<<<<<<<<< 22 | 23 | abstract call() //Java: public interface Interface$call { void call(); } 24 | 25 | abstract callback(Int arg) //Java: public interface Interface$callback { void callback(Int arg); } 26 | 27 | abstract isCorrect() 28 | 29 | TO_STR(Any a) { 30 | ^ a = null ? null ; a.toStr() 31 | } //Java: public class Class$TO_STR { public static TO_STR(Any a) { return a == null ? null : a.toStr(); } } 32 | 33 | //包级别函数 >>>>>>>>>>>>>>>>>>>>>> 34 | 35 | 36 | 37 | //包级别类 <<<<<<<<<<<<<<<<<<<<<< 38 | 39 | /** 40 | * 类名第一个字符为大写英语字母,其它每个字符都必须是 英文字母、数字、下划线 中的一种 41 | * 静态类:类名所有字符全大写,单词中间用 _ 隔开;默认用 public static 修饰 42 | * 非静态类:类名用UpperCamelCase风格;默认用 public 修饰 43 | * 可能会碰到 JSON 这种整个单词本身就是全大写的情况,建议在用做非静态类时命名为 Json ,即首字母大写,其它小写。和 静态类 JSON 做区分 44 | */ 45 | class Map User implements isCorrect { //Java: public class User extends Map implements Interface$isCorrect 46 | 47 | final Int SEX_MAIL : 0 //Java: public static final Int SEX_MAIL; 48 | final Int SEX_FEMAIL : 1 //常量名所有字符全大写,单词中间用 _ 隔开;默认用 public static 修饰 49 | final Int SEX_UNKNOWN : 2 50 | 51 | 52 | // this() { //public User() { super(); } 53 | // super() 54 | // } 55 | // this(Int id) { //public User(Long id) { this(); this.id = id; } //废弃 new/NEW,只允许 Class {} 这一种构造方式 //User.new 静态的怎么不是大写? User.NEW() 内部也得 NEW 56 | // this() 57 | // this.id : id 58 | // } 59 | 60 | new Int id //Java: private Int id; //new 表示构造时必传,还是没能满足 super(id) 和 super(null) 这种需求,除非子类和父类变量名不允许相同,即便是private的,但这个限制就很大了 61 | 62 | Str name //变量名第一个字符为小写英语字母,其它每个字符都必须是 英文字母、数字、下划线 中的一种;默认用 private 修饰 63 | 64 | Int sex 65 | 66 | Bool certified { 67 | 68 | override Bool get() { //重写getter函数 69 | this = this ?; false 70 | ^ this 71 | } 72 | } 73 | /** 74 | * Java: 75 | private Bool certified; 76 | 77 | public Bool certified() { //相当于getter函数 78 | certified = certified != null ? certified : false; 79 | return certified; 80 | } 81 | public User certified(Bool certified) { //相当于setter函数,自定义了实现逻辑 82 | this.value(certified); //Java: this.certified = certified; 83 | return this; 84 | } 85 | */ 86 | 87 | 88 | 89 | List contactIdList { //TODO 这里不适合用 Int[] ,因为会有歧义? 90 | 91 | override User set(List value) { //重写setter函数 92 | (value = value ?; List{}) 93 | ^ this@User 94 | } 95 | } 96 | /** 97 | * Java: 98 | private List contactIdList; 99 | 100 | public List contactIdList() { //相当于getter函数 101 | return contactIdList; 102 | } 103 | public User contactIdList(List value) { //相当于setter函数,自定义了实现逻辑 104 | this.value = value ? value : List{}); 105 | return this; 106 | } 107 | */ 108 | 109 | 110 | 111 | override Bool isCorrect() { 112 | ^ id > 0 113 | } 114 | 115 | 116 | } 117 | 118 | //包级别类 >>>>>>>>>>>>>>>>>>>>>> 119 | -------------------------------------------------------------------------------- /axis/Str.axis: -------------------------------------------------------------------------------- 1 | //包级别类 <<<<<<<<<<<<<<<<<<<<<< 2 | 3 | class Str : Stringable { 4 | 5 | 6 | Bool equal(Any a) { 7 | ^ a instanceof Stringable & super.equal(/* Any a : */ a) 8 | } 9 | 10 | Int length() { 11 | ^ value.length 12 | } 13 | 14 | override Str toStr() { 15 | ^ this 16 | } 17 | 18 | override Str OF(Any a) { 19 | ^ a instanceof Str ? a ; a.toStr() //Java: return a instanceof Str ? (Str) a : a.toStr(); 20 | } 21 | 22 | /** 23 | * Returns true if, and only if, {@link #length()} is 0. 24 | * 25 | * @return true if {@link #length()} is 0, otherwise 26 | * false 27 | * 28 | * @since 1.6 29 | */ 30 | Bool isEmpty() { 31 | ^ length() : 0; 32 | } 33 | 34 | Bool equals( 35 | Any a 36 | Bool ignoreCase : false 37 | ) { //可选参数必须设置默认值 38 | if (this = a) { //判断内存地址 39 | ^ true 40 | } 41 | if (a instanceof Str) { 42 | ^ this : a 43 | } 44 | ^ equals( 45 | a : OF(a : a) 46 | ignoreCase : ignoreCase 47 | ) 48 | } 49 | 50 | /** 51 | * Returns the Str value at the 52 | * specified index. An index ranges from 0 to 53 | * length() - 1. The first Str value of the sequence 54 | * is at index 0, the next at index 1, 55 | * and so on, as for List indexing. 56 | * 57 | *

If the Str value specified by the index is a 58 | * surrogate, the surrogate 59 | * value is returned. 60 | * 61 | * @param index the index of the Str value. 62 | * @return the Str value at the specified index of this Str. 63 | * The first Str value is at index 0. 64 | * @exception IndexOutOfBoundsException if the index 65 | * argument is negative or not less than the length of this 66 | * Str. 67 | */ 68 | Str at(Int index) { 69 | if (index < 0 | index >= length()) { 70 | throw new StrIndexOutOfBoundsException(index : index); 71 | } 72 | ^ value[index]; 73 | } 74 | 75 | /** 76 | * Returns the Stracter (Unicode code poInt) at the specified 77 | * index. The index refers to Str values 78 | * (Unicode code units) and ranges from 0 to 79 | * {@link #length()} - 1. 80 | * 81 | *

If the Str value specified at the given index 82 | * is in the high-surrogate range, the following index is less 83 | * than the length of this Str, and the 84 | * Str value at the following index is in the 85 | * low-surrogate range, then the supplementary code poInt 86 | * corresponding to this surrogate pair is returned. Otherwise, 87 | * the Str value at the given index is returned. 88 | * 89 | * @param index the index to the Str values 90 | * @return the code poInt value of the Stracter at the 91 | * index 92 | * @exception IndexOutOfBoundsException if the index 93 | * argument is negative or not less than the length of this 94 | * Str. 95 | * @since 1.5 96 | */ 97 | Int codePoIntAt(Int index) { 98 | if ((index < 0) | (index >= length())) { 99 | throw new StrIndexOutOfBoundsException(index : index); 100 | } 101 | ^ Stracter.codePoIntAtImpl(value : value, start : index, length : length()); 102 | } 103 | 104 | /** 105 | * Returns the Stracter (Unicode code poInt) before the specified 106 | * index. The index refers to Str values 107 | * (Unicode code units) and ranges from 1 to {@link 108 | * StrSequence#length() length}. 109 | * 110 | *

If the Str value at (index - 1) 111 | * is in the low-surrogate range, (index - 2) is not 112 | * negative, and the Str value at (index - 113 | * 2) is in the high-surrogate range, then the 114 | * supplementary code poInt value of the surrogate pair is 115 | * returned. If the Str value at index - 116 | * 1 is an unpaired low-surrogate or a high-surrogate, the 117 | * surrogate value is returned. 118 | * 119 | * @param index the index following the code poInt that should be returned 120 | * @return the Unicode code poInt value before the given index. 121 | * @exception IndexOutOfBoundsException if the index 122 | * argument is less than 1 or greater than the length 123 | * of this Str. 124 | * @since 1.5 125 | */ 126 | Int codePoIntBefore(Int index) { 127 | Int i : index - 1; 128 | if ((i < 0) | (i >= length())) { 129 | throw StrIndexOutOfBoundsException(index@Int : index@Int); 130 | } 131 | ^ Stracter.codePoIntBeforeImpl(value, index, 0); 132 | } 133 | 134 | /** 135 | * Returns the Int of Unicode code poInts in the specified text 136 | * range of this Str. The text range begins at the 137 | * specified beginIndex and extends to the 138 | * Str at index endIndex - 1. Thus the 139 | * length (in Strs) of the text range is 140 | * endIndex-beginIndex. Unpaired surrogates within 141 | * the text range count as one code poInt each. 142 | * 143 | * @param beginIndex the index to the first Str of 144 | * the text range. 145 | * @param endIndex the index after the last Str of 146 | * the text range. 147 | * @return the Int of Unicode code poInts in the specified text 148 | * range 149 | * @exception IndexOutOfBoundsException if the 150 | * beginIndex is negative, or endIndex 151 | * is larger than the length of this Str, or 152 | * beginIndex is larger than endIndex. 153 | * @since 1.5 154 | */ 155 | Int codePoIntCount(Int beginIndex, Int endIndex) { 156 | if (beginIndex < 0 | endIndex > length() | beginIndex > endIndex) { 157 | throw IndexOutOfBoundsException(); 158 | } 159 | ^ Stracter.codePoIntCountImpl(value, beginIndex, endIndex - beginIndex); 160 | } 161 | 162 | /** 163 | * Returns the index within this Str that is 164 | * offset from the given index by 165 | * codePoIntOffset code poInts. Unpaired surrogates 166 | * within the text range given by index and 167 | * codePoIntOffset count as one code poInt each. 168 | * 169 | * @param index the index to be offset 170 | * @param codePoIntOffset the offset in code poInts 171 | * @return the index within this Str 172 | * @exception IndexOutOfBoundsException if index 173 | * is negative or larger then the length of this 174 | * Str, or if codePoIntOffset is positive 175 | * and the subStr starting with index has fewer 176 | * than codePoIntOffset code poInts, 177 | * or if codePoIntOffset is negative and the subStr 178 | * before index has fewer than the absolute value 179 | * of codePoIntOffset code poInts. 180 | * @since 1.5 181 | */ 182 | Int offsetByCodePoInts(Int index, Int codePoIntOffset) { 183 | if (index < 0 | index > length()) { 184 | throw IndexOutOfBoundsException(); 185 | } 186 | ^ Stracter.offsetByCodePoIntsImpl(value, 0, length(), 187 | index, codePoIntOffset); 188 | } 189 | 190 | 191 | 192 | } 193 | 194 | //包级别类 >>>>>>>>>>>>>>>>>>>>>> 195 | -------------------------------------------------------------------------------- /axis/List.axis: -------------------------------------------------------------------------------- 1 | import JavaJSON : com.alibaba.fastjson.JSON //取别名 2 | import com.alibaba.fastjson.JSONArray 3 | 4 | 5 | //包级别类 <<<<<<<<<<<<<<<<<<<<<< 6 | 7 | 8 | /** 9 | 对应 Java 的 10 | /**相当于ArrayList 11 | * TODO 只有extends Map才好使用里面的取值函数 arr.0, arr.'0' 等,或许要牺牲一些性能来换取更灵活方便的使用体验。Bool, Str等类型也一样 12 | */ 13 | class List : Listable { 14 | 15 | 16 | Bool equal(Any a) { 17 | ^ a instanceof Listable & super.equal(/* Any a : */ a) 18 | } 19 | 20 | 21 | native T get(Int index) 22 | native add(T value) 23 | native add( 24 | Int index //换行代替逗号,格式更清晰,还不用纠结最后一个逗号要不要删除 25 | T value 26 | ) 27 | 28 | native set( 29 | Int index 30 | T value 31 | ) 32 | 33 | push(T value) { 34 | add(value : value) 35 | ^ this 36 | } 37 | 38 | Int size : 0 39 | 40 | /** 41 | * Returns true if this list contains no elements. 42 | * 43 | * @return true if this list contains no elements 44 | */ 45 | Bool isEmpty() { 46 | ^ size = 0; 47 | } 48 | 49 | override Str toStr() { 50 | ^ JavaJSON.toJSONStr(obj : this) 51 | } 52 | 53 | List OF(Str s) { 54 | 55 | ^ OF( 56 | c : JavaJSON.parseList(json : s) 57 | ) 58 | } 59 | 60 | List OF(Collection c) { 61 | 62 | c : c ?? Collection{} 63 | List arr : List{} 64 | c.forEach( 65 | Int index 66 | Any value 67 | ) { 68 | 69 | arr.add(item : value) 70 | } 71 | ^ arr 72 | } 73 | 74 | 75 | /** 76 | * Returns true if this list contains the specified element. 77 | * More formally, returns true if and only if this list contains 78 | * at least onelement : E e such that 79 | * (o=null ? e=null : o.equals(e)). 80 | * 81 | * @param o element whose presence in this list is to be tested 82 | * @return true if this list contains the specified element 83 | */ 84 | Bool contains(Map o) { 85 | ^ indexOf(o : o) >= 0; 86 | } 87 | 88 | /** 89 | * Returns the index of the first occurrence of the specified element 90 | * in this list, or -1 if this list does not contain thelement : E. 91 | * More formally, returns the lowest index i such that 92 | * (o=null ? get(i)=null : o.equals(get(i))), 93 | * or -1 if there is no such index. 94 | */ 95 | Int indexOf(Map o) { 96 | if (o = null) { 97 | for (Int i : 0; i < size; i++) 98 | if (elementData.(i) = null) { 99 | ^ i 100 | } 101 | } else { 102 | for (Int i : 0; i < size; i++) 103 | if ( 104 | o.equals( 105 | o : elementData.get(i) 106 | ) 107 | ) { 108 | ^ i 109 | } 110 | } 111 | ^ -1 112 | } 113 | 114 | /** 115 | * Returns the index of the last occurrence of the specified element 116 | * in this list, or -1 if this list does not contain thelement : E. 117 | * More formally, returns the highest index i such that 118 | * (o=null ? get(i)=null : o.equals(get(i))), 119 | * or -1 if there is no such index. 120 | */ 121 | Int lastIndexOf(Map o) { 122 | 123 | if (o = null) { 124 | for (Int i : size - 1; i >= 0; i--) 125 | if (elementData.get(i) = null) { 126 | ^ i 127 | } 128 | } else { 129 | for (Int i : size - 1; i >= 0; i--) 130 | if ( 131 | o.equals( 132 | o : elementData.get(i) 133 | ) 134 | ) { 135 | ^ i 136 | } 137 | } 138 | ^ -1 139 | } 140 | 141 | 142 | 143 | 144 | 145 | /** 146 | * Appends the specified element to the end of this list. 147 | * 148 | * @param element : E to be appended to this list 149 | * @return true (as specified by {@link Collection#add}) 150 | */ 151 | Bool add(E e) { 152 | ensureCapacityInternal(size + 1); // Increments modCount!! 153 | elementData.set(size++, e); 154 | ^ true; 155 | } 156 | 157 | /** 158 | * Inserts the specified element at the specified position in this 159 | * list. Shifts thelement : E currently at that position (if any) and 160 | * any subsequent elements to the right (adds one to their indices). 161 | * 162 | * @param index index at which the specified element is to be inserted 163 | * @param element element to be inserted 164 | * @throws IndexOutOfBoundsException {@inheritDoc} 165 | */ 166 | add( 167 | Int index 168 | E element 169 | ) { 170 | rangeCheckForAdd(index); 171 | 172 | ensureCapacityInternal(size + 1); // Increments modCount!! 173 | System.Listcopy(elementData, index, elementData, index + 1, 174 | size - index); 175 | elementData.set(index, element); 176 | size++; 177 | } 178 | 179 | /** 180 | * Removes thelement : E at the specified position in this list. 181 | * Shifts any subsequent elements to the left (subtracts one from their 182 | * indices). 183 | * 184 | * @param index the index of thelement : E to be removed 185 | * @return thelement : E that was removed from the list 186 | * @throws IndexOutOfBoundsException {@inheritDoc} 187 | */ 188 | E remove(Int index) { 189 | rangeCheck(index); 190 | 191 | modCount++; 192 | E oldValue : elementData.get(index); 193 | 194 | Int numMoved : size - index - 1; 195 | if (numMoved > 0) 196 | System.Listcopy(elementData, index+1, elementData, index, 197 | numMoved); 198 | elementData(--size) : null; // clear to let GC do its work 199 | 200 | ^ oldValue; 201 | } 202 | 203 | /** 204 | * Removes the first occurrence of the specified element from this list, 205 | * if it is present. If the list does not contain thelement : E, it is 206 | * unchanged. More formally, removes thelement : E with the lowest index 207 | * i such that 208 | * (o=null ? get(i)=null : o.equals(get(i))) 209 | * (if such an element exists). Returns true if this list 210 | * contained the specified element (or equivalently, if this list 211 | * changed as a result of the call). 212 | * 213 | * @param o element to be removed from this list, if present 214 | * @return true if this list contained the specified element 215 | */ 216 | Bool remove(Map o) { 217 | if (o = null) { 218 | for (Int index : 0; index < size; index++) 219 | if (elementData(index) = null) { 220 | fastRemove(index); 221 | return true; 222 | } 223 | } else { 224 | for (Int index : 0; index < size; index++) 225 | if (o.equals(elementData(index))) { 226 | fastRemove(index); 227 | return true; 228 | } 229 | } 230 | ^ false; 231 | } 232 | 233 | /* 234 | * Private remove method that skips bounds checking and does not 235 | * return the value removed. 236 | */ 237 | private fastRemove(Int index) { 238 | modCount++; 239 | Int numMoved : size - index - 1; 240 | if (numMoved > 0) 241 | System.Listcopy(elementData, index+1, elementData, index, 242 | numMoved); 243 | elementData(--size) : null; // clear to let GC do its work 244 | } 245 | 246 | /** 247 | * Removes all of thelement : Es from this list. The list will 248 | * be empty after this call returns. 249 | */ 250 | clear() { 251 | modCount++; 252 | 253 | // clear to let GC do its work 254 | for (Int i : 0; i < size; i++) 255 | elementData.(i) : null; 256 | 257 | size : 0; 258 | } 259 | 260 | /** 261 | * Appends all of thelement : Es in the specified collection to the end of 262 | * this list, in the order that they are returned by the 263 | * specified collection's Iterator. The behavior of this operation is 264 | * undefined if the specified collection is modified while the operation 265 | * is in progress. (This implies that the behavior of this call is 266 | * undefined if the specified collection is this list, and this 267 | * list is nonempty.) 268 | * 269 | * @param c collection containing elements to be added to this list 270 | * @return true if this list changed as a result of the call 271 | * @throws NullPoInterException if the specified collection is null 272 | */ 273 | Bool addAll(List c) { 274 | Map() a : c.toList(); 275 | Int numNew : a.length; 276 | ensureCapacityInternal(size + numNew); // Increments modCount 277 | System.Listcopy(a, 0, elementData, size, numNew); 278 | size +: numNew; 279 | ^ numNew != 0; 280 | } 281 | 282 | /** 283 | * Inserts all of thelement : Es in the specified collection Into this 284 | * list, starting at the specified position. Shifts thelement : E 285 | * currently at that position (if any) and any subsequent elements to 286 | * the right (increases their indices). The new elements will appear 287 | * in the list in the order that they are returned by the 288 | * specified collection's iterator. 289 | * 290 | * @param index index at which to insert the first element from the 291 | * specified collection 292 | * @param c collection containing elements to be added to this list 293 | * @return true if this list changed as a result of the call 294 | * @throws IndexOutOfBoundsException {@inheritDoc} 295 | * @throws NullPoInterException if the specified collection is null 296 | */ 297 | addAll(Int index c : List) : Bool { 298 | rangeCheckForAdd(index); 299 | 300 | Map() a : c.toList(); 301 | Int numNew : a.length; 302 | ensureCapacityInternal(size + numNew); // Increments modCount 303 | 304 | Int numMoved : size - index; 305 | if (numMoved > 0) 306 | System.Listcopy(elementData, index, elementData, index + numNew, 307 | numMoved); 308 | 309 | System.Listcopy(a, 0, elementData, index, numNew); 310 | size +: numNew; 311 | ^ numNew != 0; 312 | } 313 | 314 | /** 315 | * Removes from this list all of thelement : Es whose index is between 316 | * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive. 317 | * Shifts any succeeding elements to the left (reduces their index). 318 | * This call shortens the list by {@code (toIndex - fromIndex)} elements. 319 | * (If {@code toIndex=fromIndex}, this operation has no effect.) 320 | * 321 | * @throws IndexOutOfBoundsException if {@code fromIndex} or 322 | * {@code toIndex} is out of range 323 | * ({@code fromIndex < 0 | 324 | * fromIndex >= size() | 325 | * toIndex > size() | 326 | * toIndex < fromIndex}) 327 | */ 328 | protected IntremoveRange( 329 | Int fromindex 330 | Int toindex 331 | ) { 332 | modCount++; 333 | Int numMoved : size - toIndex; 334 | System.Listcopy(elementData, toIndex, elementData, fromIndex, 335 | numMoved); 336 | 337 | // clear to let GC do its work 338 | Int newSize : size - (toIndex-fromIndex); 339 | for (Int i : newSize; i < size; i++) { 340 | elementData.(i) : null; 341 | } 342 | size : newSize; 343 | } 344 | 345 | /** 346 | * Checks if the given index is in range. If not, throws an appropriate 347 | * runtime exception. This method does *not* check if the index is 348 | * negative: It is always used immediately prior to an List access, 349 | * which throws an ListIndexOutOfBoundsException if index is negative. 350 | */ 351 | private IntrangeCheck(Int index) { 352 | if (index >= size) 353 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index : index)); 354 | } 355 | 356 | /** 357 | * A version of rangeCheck used by add and addAll. 358 | */ 359 | private IntrangeCheckForAdd(Int index) { 360 | if (index > size | index < 0) 361 | throw new IndexOutOfBoundsException(outOfBoundsMsg(index : index)); 362 | } 363 | 364 | /** 365 | * Constructs an IndexOutOfBoundsException detail message. 366 | * Of the many possible refactorings of the error handling code, 367 | * this "outlining" performs best with both server and client VMs. 368 | */ 369 | private Str outOfBoundsMsg(Int index) { 370 | ^ "Index: "+index+", Size: "+size; 371 | } 372 | 373 | /** 374 | * Removes from this list all of its elements that are contained in the 375 | * specified collection. 376 | * 377 | * @param c collection containing elements to be removed from this list 378 | * @return {@code true} if this list changed as a result of the call 379 | * @throws ClassCastException if the class of an element of this list 380 | * is incompatible with the specified collection 381 | * (optional) 382 | * @throws NullPoInterException if this list contains a null element and the 383 | * specified collection does not permit null elements 384 | * (optional), 385 | * or if the specified collection is null 386 | * @see Collection#contains(Map) 387 | */ 388 | Bool removeAll(List c) { 389 | ^ batchRemove(c : c, resize : false); 390 | } 391 | 392 | } 393 | 394 | //包级别类 >>>>>>>>>>>>>>>>>>>>>> 395 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Axis-Lang 2 | A programming language running on JVM.
3 | Powerful, Flexible, Safe and Simple.
4 | [Designing...] 5 | 6 | 7 | ## Features 8 | 9 | #### Support JSON like Schema 10 | ```javascript 11 | Map map : { 12 | 'key0' : value0 13 | 'key1' : value1 14 | ... 15 | } 16 | ``` 17 | 18 | 19 | #### Strong and static Type 20 | 21 | 22 | #### Few system types 23 | only Any, Bool, Int, Num, Str, Map and List 24 | 25 | 26 | #### Type hint 27 | if NAME_AUTHOR, User and an instance of User was defined like this: 28 | ``` 29 | final Str NAME_AUTHOR : 'Lemon' 30 | class User { 31 | Int id 32 | Str name 33 | Any extra 34 | } 35 | User user : {} 36 | ``` 37 | then when user or its fields were called, the IDE will automatically generate the Type behind instances:
38 |   user`@User`.name`@Str` : NAME_AUTHOR`@Str`
39 |   user`@User` : { `// user = new User().setId(1).setName("tommy");`
40 |    id`@Int` : 1 `// user.setId(1);`
41 |    name`@Str` : 'tommy' `// user.setName("tommy");`
42 |    extra : null `//no hint for Any, don't need it. user.setExtra(null);`
43 |   }
44 | 45 | 46 | #### Safe type 47 | ```javascript 48 | Int id : 0 49 | Str name : null 50 | 51 | id@Int.toStr()@Str // '0' 52 | 53 | name@Str.length@Int //won't throw NullPoninterExeption but return null 54 | name@Str.toUpperCase()@Str //won't throw NullPoninterExeption but return null 55 | 56 | User user = null 57 | user@User.name@Str : name@Str //automatically create user and name in user when they are null and the expression is for assign 58 | PRINT(msg : user@User) //{ name : null } 59 | ``` 60 | 61 | 62 | #### Indexes for arrays 63 | Positive index: 64 | ```javascript 65 | arr.0 // arr[0] 66 | arr.1 // arr[1] 67 | 68 | arr.-1 // arr[arr.length - 1] 69 | // arr.-0 //Forbidden, throw UnsupportedSyntaxError 70 | ``` 71 | If the index is out of arr's bounds [0, arr.length - 1],it will return null instead of throw IndexOutOfBoundsException.
72 | If you want to stop the process when the case above happen, then you can: 73 | ```javascript 74 | if arr.length@Int <= index@Int { 75 | # IndexOutOfBoundsException(msg@Str : 'arr.length <= index! index is out of bounds!') 76 | } 77 | ``` 78 | 79 | 80 | #### Default value for arguments 81 | such as 82 | ```javascript 83 | function(Type0 arg0, Type1 arg1 : null) { 84 | ... 85 | } 86 | ``` 87 | then you can call 88 | ```javascript 89 | function(arg0@Type0 : value0@Type0) 90 | ``` 91 | or 92 | ```javascript 93 | function( 94 | arg0@Type0 : value0@Type0 95 | arg1@Type1 : value1@Type1 96 | ) 97 | ``` 98 | 99 | 100 | #### Return 101 | the keyword 'return' is replaced with '^'
102 | such as 103 | ```javascript 104 | function() { 105 | ^ //return; 106 | } 107 | 108 | @NotNull 109 | Any getNotNull(Any arg) { 110 | ^ arg = null ? {} ; arg //return arg == null ? new Object() : arg; 111 | } 112 | ``` 113 | If you write 'return', the IDE will recommend '^'. 114 | 115 | 116 | #### Lambda 117 | Lambda is an anonymous callback 118 | ```javascript 119 | function() 120 | ^() { 121 | ^() //callback.callback(); 122 | } 123 | function() //这里比较难判断是声明还是调用,所以回调函数的 括号 () 也不能省 124 | /*()*/ { //调用 function 时代码提示,一起自动生成 125 | //do something 126 | } 127 | 128 | getNotNullAync(Any in) 129 | ^(@NotNull Any out) { 130 | ^(out : in = null ? {} ; in) //callback.callback(in == null ? new Object() : in); 131 | } 132 | getNotNullAync(in : null) 133 | /*(@NotNull Str out)*/ { //调用 getNotNullAync 时代码提示,一起自动生成 134 | //do something 135 | } 136 | 137 | Bool getNotNullAync(Any in) 138 | ^(@NotNull Any out) { 139 | ^(out : in = null ? {} ; in) //callback.callback(in == null ? new Object() : in); 140 | ^ in != null //return in != null; 141 | } 142 | Bool handled : getNotNullAync(in : null) 143 | /*(@NotNull Str out)*/ { //调用 getNotNullAync 时代码提示,一起自动生成 144 | //do something 145 | } 146 | 147 | T[] SORT(T[] list) 148 | Int ^(T item0, T item1) { 149 | if list@T[] = null | list@T[].size() <= 1 { 150 | return list@T[].clone() 151 | } 152 | 153 | T[] sortedList : T[list@T[].size()][] 154 | // ... add items to sortedList by an order 155 | ^( 156 | /*item0@T : */ list.get(/*index@Int : */ index@Int) 157 | /*item1@T : */ list.get(/*index@Int : */ index@Int + 1) 158 | ) 159 | 160 | ^ sortedList@T[] 161 | } 162 | Int[] sortedList : SORT(/*list@Int[] : */ [2, 5, 6, 1, 9, 3]) 163 | /*Int (Int item0, Int item1)*/ { 164 | if item0@Int = item1@Int { 165 | ^ 0 166 | } 167 | if item0@Int = null { 168 | ^ item1@Int 169 | } 170 | if item1@Int = null { 171 | ^ item0@Int 172 | } 173 | 174 | ^ item0@Int < item1@Int ? -1 ; 1 175 | ) 176 | ``` 177 | 178 | 179 | #### Throw 180 | the keyword 'throw' is replaced with '#'
181 | such as 182 | ```javascript 183 | Any get( 184 | Listable list 185 | Int position 186 | ) # NullPoninterExeption, IndexOutOfBoundsException { 187 | if list@Listable = null { 188 | # NullPoninterExeption(msg@Str : 'list can not be null!') //throw new NullPoninterExeption("list can not be null!"); 189 | } 190 | if position@Int = null { 191 | # NullPoninterExeption(msg@Str : 'position can not be null!') //throw new NullPoninterExeption("position can not be null!"); 192 | } 193 | if position@Int < 0 | position@Int >= list@Listable.length@Int { 194 | # IndexOutOfBoundsException(msg@Str : 'position is out of bounds of list!') //throw new IndexOutOfBoundsException("position is out of bounds of list!"); 195 | } 196 | 197 | ^ list@Listable.get(position@Int : position@Int) 198 | } 199 | ``` 200 | If you write 'throw' or 'throws', the IDE will recommend '#'. 201 | 202 | 203 | #### Break 204 | the keyword 'break' is replaced with '<<'
205 | such as 206 | ```javascript 207 | while true { //replace while(true) { ... } 208 | PRINT(msg : 'while...') 209 | << //break; 210 | } 211 | ``` 212 | If you write 'break', the IDE will recommend '>>'. 213 | 214 | 215 | #### Continue 216 | the keyword 'continue' is replaced with '>>'
217 | such as 218 | ```javascript 219 | until false { //replace do {...} while(...); 220 | PRINT(msg : 'do while...') 221 | Thread.sleep(time@Int : 1000) 222 | >> //continue; 223 | } 224 | ``` 225 | If you write 'continue', the IDE will recommend '>>'. 226 | 227 | 228 | #### Default and anonymous getter and setter functions for fields 229 | such as 230 | ```javascript 231 | Str name { 232 | override Str get() { 233 | ^ name@Str //return name; 234 | } 235 | 236 | override Str set(Str value) { 237 | name@Str : value 238 | ^ this@User //return this; 239 | } 240 | } : null 241 | ``` 242 | 243 | private, protected or public fields have no getter or setter functions. 244 | 245 | 246 | #### Expand fields 247 | such as 248 | ```javascript 249 | user@User.'isFriend' : true //isFriend is not a field decleared in User, so it must be covered with '' 250 | log(msg@Str : 'id = ' + user@User.id@Int + '; isFriend = ' + user@User.'isFriend') 251 | ``` 252 | 253 | 254 | #### Package level funcions 255 | such as 256 | ```javascript 257 | package axis.api 258 | 259 | abtract Bool isCorrect() 260 | 261 | PRINT(Any msg) { 262 | ... 263 | } 264 | ``` 265 | 266 | only suppor public abstract and public static functions. 267 | 268 | 269 | #### Multiple extends and support Maps and functions 270 | such as 271 | ```javascript 272 | class User : Map, isCorrect { // public class User extends Map implements Interface$isCorrect { 273 | 274 | override Bool isCorrect() { 275 | ^ true 276 | } 277 | } 278 | ``` 279 | 280 | the first one must be an Map Type, and the after Map Type can only supply CONSTANS and abstract functions. 281 | 282 | 283 | #### '=' equal for any Types 284 | ```javascript 285 | b@Bool = true // b.equals(true) 286 | i@Int = 0 // i.equals(0) 287 | s@Str = '' // s.equals('') 288 | map@Map = {} // map.equals({}) 289 | list@List = [] // list.equals([]) 290 | user@User = User{} // user.equals(new User()) 291 | user@User = User{ // user.equals(new User().setId(1).setName('tommy')) 292 | id@Int : 1 // setId(1) 293 | name@Str : 'tommy' // setName('tommy') 294 | } 295 | ``` 296 | 297 | 298 | ### '+', '-' between Lists 299 | ```javascript 300 | List list : [ 301 | 1 302 | 2 303 | 3 304 | ] 305 | 306 | list +: 4 // list.add(4) 307 | 308 | PRINT(msg : list@List) // [1, 2, 3, 4] 309 | 310 | list@List +: [ 311 | 2 312 | 5 313 | 6 314 | ] //list.addAll([2, 5, 6]) 315 | 316 | PRINT(msg : list@List) // [1, 2, 3, 4, 2, 5, 6] 317 | 318 | list@List -: <0> //list.remove(0); 319 | 320 | PRINT(msg : list@List) // [3, 4, 2, 5, 6] 321 | 322 | list@List -: [ 323 | 0 324 | 5 325 | ] //list.remove((Object) 0); list.remove((Object) 5); 326 | 327 | PRINT(msg : list@List) // [3, 4, 2, 6] 328 | 329 | list@List -: 2 //list.remove((Object) 2) 330 | 331 | PRINT(msg : list@List) // [3, 4, 6] 332 | 333 | //forbidden list -: {0, 2} //list.remove(0) list.remove(2) 334 | 335 | PRINT(msg : list@List.0@Int) // 3 336 | 337 | PRINT(msg : list@List.'0'@Int) // 3 338 | 339 | PRINT(msg : list@List.3@Int) // throw IndexOutOfBoundsException('index : 3, list.length : 3, index >: list.length !') 340 | 341 | PRINT(msg : list@List.'3'@Int) // null 342 | 343 | //forbidden PRINT(list.'a') //the index must be a number 344 | 345 | list@List.4@Int : 4 // throw IndexOutOfBoundsException('index : 4, list.length : 3, index > list.length !') 346 | 347 | list@List.'4'@Int : 4 348 | 349 | PRINT(msg : list@List.'4'@Int) // 4 350 | 351 | PRINT(msg : list@List) // [3, 4, 6, null, 4] 352 | ``` 353 | 354 | 355 | ### '+', '-' between Maps 356 | ```javascript 357 | Map map : { 358 | 'id' : 1 359 | 'sex' : 0 360 | 'name' : null 361 | } 362 | 363 | map@Map +: { 364 | 'name' : 'test' 365 | 'phone' : '123456789' 366 | } // map.putAll({'name' : 'test', 'phone': '123456789'}) 367 | 368 | PRINT(msg : map@Map) // { 'id' : 1, 'sex' : 0, 'name' : 'test', 'phone' : '123456789' } 369 | 370 | map@Map -: <'sex'> //map.remove('sex') 371 | 372 | PRINT(msg : map@Map) // { 'id' : 1, 'name' : 'test', 'phone' : '123456789' } 373 | 374 | map@Map -: 1 //map.removeValue(1); 375 | 376 | PRINT(msg : map@Map) // { 'name' : 'test', 'phone' : '123456789' } 377 | 378 | map@Map -: ['123456789'] //map.removeValues(['123456789']); 379 | 380 | PRINT(msg : map@Map) // { 'name' : 'test' } 381 | 382 | PRINT(msg : map@Map.name) // error, undefined filed name in map@Map! 383 | 384 | PRINT(msg : map@Map.'name') // test 385 | 386 | //forbidden PRINT(map.tag) // throw NotFoundException('could not find the key "tag" in map !') 387 | 388 | PRINT(msg : map@Map.'tag') // null 389 | 390 | //forbidden map.tag : 'Java' 391 | 392 | map@Map.'tag' : 'Java' 393 | 394 | PRINT(msg : map@Map.'tag') // Java 395 | ``` 396 | 397 | 398 | #### Loop 399 | 400 | ##### for 401 | List 402 | ```javascript 403 | Str[] NAMES : [ 404 | 'name0' 405 | 'name1' 406 | 'name2' 407 | ] 408 | 409 | //for(int i = 0; i < NAMES.length - 1; i ++) 410 | for NAMES@Str[] { /*Int index, Str item*/ //automatically generated hint for arguments in the callback function 411 | LOG( 412 | tag@Str : 'FOR_EACH' 413 | msg@Str : item@Str 414 | ) 415 | } 416 | 417 | //for(int i = NAMES.length - 1; i > 0; i --) 418 | for NAMES@Str[] - { /*Int index, Str item*/ //automatically generated hint for arguments in the callback function 419 | LOG( 420 | tag@Str : 'FOR_EACH' 421 | msg@Str : item@Str 422 | ) 423 | } 424 | 425 | //for(int i = 0; i < NAMES.length - 1; i += 2) 426 | for NAMES@Str[] + 2 { /*Int index, Str item*/ //automatically generated hint for arguments in the callback function 427 | LOG( 428 | tag@Str : 'FOR_EACH' 429 | msg@Str : item@Str 430 | ) 431 | } 432 | ``` 433 | 434 | 435 | Map 436 | ```javascript 437 | Map map : { 438 | 'key0' : value0@Int 439 | 'key1' : value1@Str 440 | 'key2' : value2@List 441 | } 442 | 443 | //Set> set = map.entrySet(); int index = 0; for(Entry e : set) { ... ; ... index ++ } 444 | for map@Map { /*Int index, Entry e*/ //automatically generated hint for arguments in the callback function 445 | LOG( 446 | tag@Str : 'FOR_EACH' 447 | msg@Str : 'key = ' + key@Str + '; value = ' + value 448 | ) 449 | } 450 | ``` 451 | ##### while 452 | no parentheses 453 | ```javascript 454 | //while (true) {} 455 | while true { 456 | } 457 | ``` 458 | 459 | ##### until 460 | 'do-while' is replaced by 'until' 461 | ```javascript 462 | //do {} while (true) 463 | until false { 464 | } 465 | ``` 466 | 467 | 468 | #### Assign value for final fields on any time 469 | declare a Type 470 | ```javascript 471 | class User : Map { 472 | final Int id 473 | final Str name 474 | } 475 | ``` 476 | then call 477 | ```javascript 478 | User user : { 479 | id@Int : 1 480 | name@Str : null 481 | } 482 | ``` 483 | or 484 | ```javascript 485 | User user : {} // User user = new User(); 486 | user@User.sex@Int : 0 // user.setSex(0); 487 | user@User.{ 488 | id@Int : 1 // user.setId(1); 489 | name@Str : null // user.setName(null); 490 | } 491 | ``` 492 | 493 | 494 | #### Short and repeatable variable or constant names in the same scope 495 | ```javascript 496 | Int id 497 | List id 498 | 499 | getId() { 500 | ^ id@Int // @Int is a type annotation generated by IDE, highlight and uneditable, generate code when export 501 | } 502 | setIdList(List id) { 503 | this.id@List : id@List // @List is a type annotation generated by IDE, highlight and uneditable, generate code when export 504 | } 505 | getFromIdList(Int position) { 506 | ^ id@List.get(positoin@Int : position@Int) 507 | } 508 | ``` 509 | 510 | If the type of a variable or a constant was changed, IDE will automatically change all the type annotations about it.
511 | For example, you edit 'List id' and change it to 'Map id',
512 | then all codes of 'id@List' will automatically become 'id@Map'. 513 | ```javascript 514 | Map id 515 | 516 | setIdList(List id) { 517 | this.id@Map : id@List // Error!Type mismatch between id@Map and id@List ! 518 | } 519 | getFromIdList(Int position) { 520 | ^ id@Map.get(key@Int : position@Int) 521 | } 522 | ``` 523 | #### No Comma ',' and no semicolon ';' 524 | replaced with escape character in many cases such as field and function declearations, value initiations, function calls.
525 | ```javascript 526 | Str name : 'Axis' 527 | Int version : 1 528 | Map extra : { 529 | 'type' : 'Language' 530 | 'for' : 'Programming' 531 | } 532 | 533 | LOG( 534 | Str tag 535 | Str msg 536 | ) { 537 | ... 538 | } 539 | 540 | LOG( 541 | tag@Str : 'Axis' 542 | msg@Str : 'is a much better programming language than Java running on JVM.' 543 | ) 544 | ``` 545 | 546 | 547 | #### No 'static' 548 | replaced with UPPER_CASE names.
549 | static class 550 | ```javascript 551 | class Outter : Map { //public class Outter extends Map { 552 | class INNER { //public static class INNER { 553 | } 554 | } 555 | ``` 556 | static funciton 557 | ```javascript 558 | MAIN(Str[] args : null) { //public static void main(Str[] args) { 559 | } 560 | ``` 561 | static field 562 | ```javascript 563 | final Str TAG : 'Axis' //public static final String TAG = "Axis"; 564 | ``` 565 | 566 | 567 | #### No 'new' and no constructor 568 | replaced with Type{}, such as 569 | ```javascript 570 | User user : User{} //User user = new User(); 571 | ``` 572 | 573 | 574 | #### No 'void' for functions 575 | ```javascript 576 | call() { //public void call() { 577 | } 578 | 579 | Str callBack() { //public String cacallBackll() { 580 | ^ 'Title' 581 | } 582 | 583 | call() //call(); 584 | Str title : callBack() //String title = callBack(); 585 | ``` 586 | 587 | 588 | #### No package 589 | Auto set package for Axis files. And you don't need to write such code in Java 590 | java 591 | package org.axis.lang; 592 | 593 | And if the path of an Axis file changed(Myabe the file was moved to another folder),
594 | you don't need to edit the code above. 595 | 596 | 597 | #### No public, private, protected, default 598 | variables, fields, arguments or constants: 599 | ```javascript 600 | Bool DEBUG : false //public static Boolean DEBUG = false; 601 | Int _i : 1 //private Integer i = 1; 602 | Str $s : 'Axis' //protected String s = "Axis"; 603 | ``` 604 | 605 | class: 606 | ```javascript 607 | class Outter { //public class Outter { 608 | 609 | } 610 | class _Inner { //private class Inner { 611 | } 612 | ``` 613 | 614 | functions: 615 | ```javascript 616 | call() { //public void call() { 617 | } 618 | Bool _connect() { //private Boolean connect() { 619 | ... 620 | ^ true 621 | } 622 | $onStart() { //protected void onStart() { 623 | } 624 | 625 | interface Logger { 626 | log(Any msg) { //default void log(Object msg) { 627 | PRINT(msg : msg) 628 | } 629 | } 630 | ``` 631 | 632 | variables: 633 | ```javascript 634 | Int _i : 1 //private int i = 1; 635 | Str $s : 'Axis' //protected String s = "Axis"; 636 | Bool DEBUG : false //public Boolean DEBUG = false; 637 | ``` 638 | 639 | #### No varargs 640 | in Java, sometimes you need to use varargs to reduce codes like:
641 | declear: 642 | ```java 643 | public Object invoke(Object obj, Object... args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { 644 | ... 645 | } 646 | ``` 647 | then call: 648 | ```java 649 | invoke(info, 1, 'Aixs', null); 650 | ``` 651 | 652 | while varargs is replaced with \[...] in Axis:
653 | declear: 654 | ```javascript 655 | Any invoke( 656 | Any obj 657 | List args 658 | ) # IllegalAccessException, IllegalArgumentException, InvocationTargetException { 659 | ... 660 | } 661 | ``` 662 | you can call: 663 | ```javascript 664 | invoke( 665 | obj : info@Info 666 | args@List : [ 667 | 1 668 | 'Aixs' 669 | null 670 | ] 671 | ) 672 | ``` 673 | 674 | 675 | #### Interface 676 | 1.Define an interface: 677 | ```javascript 678 | interface Runnable { 679 | run() 680 | } 681 | ``` 682 | 2.Define a method with argument, and the type of the argument is a interface above: 683 | ```javascript 684 | runOnUiThread(Runnable action) { 685 | ... 686 | } 687 | ``` 688 | 3.Then you can call: 689 | ```javascript 690 | runOnUiThread( 691 | action@Runnable : { //type was a generated comment. No name means default name 'Runnable'. 692 | run() { 693 | ... 694 | } 695 | } 696 | ) 697 | ``` 698 | 699 | Another expample: 700 | ```javascript 701 | interface AdapterViewCallback { 702 | View createView( 703 | Int type 704 | ViewGroup parent 705 | ) 706 | 707 | bindView( 708 | Int type 709 | ItemView itemView 710 | Int position 711 | ) 712 | } 713 | ``` 714 | can be replaced function in package level 715 | ```javascript 716 | abstract refresh(List list) 717 | ``` 718 | 719 | ```javascript 720 | class BaseAdapter : Adapter, AdapterViewCallback, refresh { 721 | override View createView( //override is a keyword generated by IDE,you don't need and aren't allowed to write it 722 | Int type 723 | ViewGroup parent 724 | ) { 725 | ^ DemoView{} 726 | } 727 | 728 | override bindView( //override is a keyword generated by IDE,you don't need and aren't allowed to write it 729 | Int type 730 | ItemView itemView 731 | Int position 732 | ) { 733 | itemView.bindView( 734 | type@Int : getItemViewType(position@Int : position@Int) 735 | itemView@ItemView : getItem(position@Int : position@Int) 736 | position@Int : position@Int 737 | ) 738 | } 739 | 740 | override refresh(List list) { //override is a keyword generated by IDE,you don't need and aren't allowed to write it 741 | if list@List = null { 742 | this.list@List : [] 743 | } { 744 | this.list@List : list 745 | } 746 | } 747 | 748 | } 749 | ``` 750 | 751 | 752 | #### If 753 | replace if-else if-else, switch-case 754 | 755 | if 756 | ```javascript 757 | if a = 1 { // if 758 | ... 759 | } 760 | ``` 761 | 762 | if-else 763 | ```javascript 764 | if a = 1 { // if 765 | ... 766 | } { // else 767 | ... 768 | } 769 | ``` 770 | 771 | if-else-else if 772 | ```javascript 773 | if a = 774 | 1 { // if 775 | ... 776 | } 2 | a = 3 { // else if 777 | ... 778 | } { // else 779 | ... 780 | } 781 | ``` 782 | 783 | if-else-else if 784 | ```javascript 785 | if a 786 | = 1 { // if 787 | ... 788 | } < 1 { // else if 789 | ... 790 | } { // else 791 | ... 792 | } 793 | ``` 794 | 795 | if-else-else if 796 | ```javascript 797 | if 798 | a = 1 { // if 799 | ... 800 | } a < 1 & a != -1 { // else if 801 | ... 802 | } { // else 803 | ... 804 | } 805 | ``` 806 | 807 | 808 | #### Instanceof 809 | replaced with 'is' 810 | ```javascript 811 | true is Bool //true 812 | 0 is Str //false 813 | ``` 814 | If you write 'instanceof', the IDE will recommend 'is'. 815 | 816 | 817 | #### Synchonized 818 | replaced with 'sync' 819 | ```javascript 820 | sync this { 821 | //dosomething 822 | } 823 | 824 | sync Any.class { 825 | //dosomething 826 | } 827 | ``` 828 | If you write 'synchonized', the IDE will recommend 'sync'. 829 | 830 | 831 | #### Callback 832 | 833 | ##### Abstract Method 834 | 1.Define an abstract method: 835 | ```javascript 836 | run() 837 | ``` 838 | 2.Define a method with argument, and the type of the argument is a abstract method above: 839 | ```javascript 840 | runOnUiThread(run action) { 841 | ... 842 | } 843 | ``` 844 | 3.Then you can call: 845 | ```javascript 846 | runOnUiThread( 847 | action@run : () { // type was a generated comment. No name means default name 'run'. 848 | ... 849 | } 850 | ) 851 | ``` 852 | 853 | 854 | #### Thread 855 | childThread: 856 | ```javascript 857 | childThread { // in a automatically recycler thread pool 858 | // run on child thread 859 | } 860 | ``` 861 | mainThread: 862 | ```javascript 863 | childThread { 864 | // run on child thread 865 | 866 | mainThread { 867 | // run on main thread 868 | } 869 | } 870 | ``` 871 | -------------------------------------------------------------------------------- /axis/Any.axis: -------------------------------------------------------------------------------- 1 | //包级别常量 <<<<<<<<<<<<<<<<<<<<<< 2 | 3 | Str UTF_8 : 'utf-8' 4 | Str VERSION_NAME : '1.0' 5 | Int VERSION_CODE : 1 6 | Bool DEBUG : true 7 | Str[] BASE_TYPES : [ 8 | 'Bool' 9 | 'Int' 10 | 'Str' 11 | 'Map' 12 | 'List' 13 | ] 14 | 15 | //包级别常量 >>>>>>>>>>>>>>>>>>>>>> 16 | 17 | 18 | //包级别类 <<<<<<<<<<<<<<<<<<<<<< 19 | 20 | /** 21 | 对应 Java 的 Objecg 22 | */ 23 | abstract class Any : isSelf { //任意类型,自动找到实例化时的精准类型并替换 24 | 25 | native IS_SELF( 26 | Any val0 : this 27 | Any val1 : a 28 | ) 29 | 30 | 31 | Any _value { //重写变量的内部函数 32 | Any get() { //取值函数getter,定义 any : Any -> 调用 any 或 any.get() 33 | ^ _value 34 | } 35 | 36 | Any set(Any value) { //赋值函数setter,定义 any : Any -> 调用 any = val 或 any.set(val) 37 | this._value : value //最终所有赋值都是赋给value? 38 | ^ this 39 | } 40 | } : null //给变量赋初始值 41 | 42 | 43 | Bool isSelf(Any a) { 44 | ^ IS_SELF( 45 | /* Any val0 : */ this 46 | /* Any val1 : */ a 47 | ) 48 | } 49 | Bool isNotSelf(Any a) { 50 | ^ ! isSelf(/* Any a : */ a) 51 | } 52 | 53 | Bool equal(Any a) { 54 | if (isSelf(/* Any a : */ a)) { 55 | ^ true 56 | } 57 | if (this.getClass() = a.getClass()) { 58 | ^ this.toStr() = a.toStr() 59 | } 60 | ^ false 61 | } 62 | 63 | 64 | //转任意类型 65 | T to(Class clazz) throws ClassCastException { 66 | ^ JSON.parse(toStr(), clazz) 67 | } 68 | 69 | 70 | //转Bool函数 71 | Bool toBool() throws ClassCastException { 72 | ^ to(clazz : Bool.class) //所有调用函数并给参数赋值都必须明确写出 (arg : value) 这种形式,和取值函数 (key) 严格区分 73 | } 74 | 75 | //转Int函数 76 | Int toInt() throws ClassCastException { 77 | ^ to(clazz : Int.class) //所有调用函数并给参数赋值都必须明确写出 (arg : value) 这种形式,和取值函数 (key) 严格区分 78 | } 79 | 80 | //转Num函数 81 | Num toNum() throws ClassCastException { 82 | ^ to(clazz : Num.class) //所有调用函数并给参数赋值都必须明确写出 (arg : value) 这种形式,和取值函数 (key) 严格区分 83 | } 84 | 85 | //转Str函数 86 | Str toStr() { 87 | ^ to(clazz : Str.class) //所有调用函数并给参数赋值都必须明确写出 (arg : value) 这种形式,和取值函数 (key) 严格区分 88 | } 89 | 90 | //转Map函数 91 | Map toMap() throws ClassCastException { 92 | ^ to(clazz : Map.class) //所有调用函数并给参数赋值都必须明确写出 (arg : value) 这种形式,和取值函数 (key) 严格区分 93 | } 94 | 95 | 96 | //转Map函数 97 | List toList() throws ClassCastException { 98 | ^ to(clazz : List.class) //所有调用函数并给参数赋值都必须明确写出 (arg : value) 这种形式,和取值函数 (key) 严格区分 99 | } 100 | 101 | 102 | 103 | //转任意类型 104 | T toSafely(Class clazz) { 105 | try { 106 | ^ to(clazz : clazz) 107 | } catch(Exception e) { 108 | ^ null 109 | } 110 | } 111 | 112 | 113 | //转Bool函数 114 | Bool toBoolSafely() { 115 | try { 116 | ^ toBool() 117 | } catch(Exception e) { 118 | ^ null 119 | } 120 | } 121 | 122 | //转Int函数 123 | Int toIntSafely() { 124 | try { 125 | ^ toInt() 126 | } catch (Exception e) { 127 | ^ null 128 | } 129 | } 130 | 131 | //转Num函数 132 | Num toNumSafely() { 133 | try { 134 | ^ toNum() 135 | } catch(Exception e) { 136 | ^ null 137 | } 138 | } 139 | 140 | //转Str函数 141 | Str toStrSafely() { 142 | try { 143 | ^ toStr() 144 | } catch(Exception e) { 145 | ^ null 146 | } 147 | } 148 | 149 | //转Map函数 150 | Map toMapSafely() { 151 | try { 152 | ^ toMap() 153 | } catch(Exception e) { 154 | ^ null 155 | } 156 | } 157 | 158 | 159 | //转Map函数 160 | List toListSafely() { 161 | try { 162 | ^ toList() 163 | } catch(Exception e) { 164 | ^ null 165 | } 166 | } 167 | 168 | 169 | 170 | //static函数名用全大写形式 171 | PRINT(Any value) { 172 | System.out.println(s : ‘’ + value) 173 | } 174 | 175 | 176 | //static函数名用全大写形式 177 | Any OF(Any value) { //自动找到实例化时的精准类型并替换,例如实例化类型是 User,则替换为 User OF(User value) {…} 178 | ^ Any{ //支持任意类的构造函数 179 | value : value //相当于 Any{}.value : value 180 | } 181 | } 182 | 183 | 184 | 185 | private static native void registerNatives(); 186 | static { 187 | registerNatives(); 188 | } 189 | 190 | /** 191 | * Returns the runtime class of this {@code Map}. The returned 192 | * {@code Class} Map is the Map that is locked by {@code 193 | * static synchronized} methods of the represented class. 194 | * 195 | *

The actual result type is {@code Class} 196 | * where {@code |X|} is the erasure of the static type of the 197 | * expression on which {@code getClass} is called. For 198 | * example, no cast is required in this code fragment:

199 | * 200 | *

201 | * {@code Int n : 0; }
202 | * {@code Class c : n.getClass(); } 203 | *

204 | * 205 | * @return The {@code Class} Map that represents the runtime 206 | * class of this Map. 207 | * @see Class Literals, section 15.8.2 of 208 | * The Java™ Language Specification. 209 | */ 210 | public final native Class getClass(); 211 | 212 | /** 213 | * Returns a hash code value for the Map. This method is 214 | * supported for the benefit of hash tables such as those provided by 215 | * {@link java.util.HashMap}. 216 | *

217 | * The general contract of {@code hashCode} is: 218 | *

    219 | *
  • Whenever it is invoked on the same Map more than once during 220 | * an execution of a Java application, the {@code hashCode} method 221 | * must consistently return the same integer, provided no information 222 | * used in {@code equals} comparisons on the Map is modified. 223 | * This integer need not remain consistent from one execution of an 224 | * application to another execution of the same application. 225 | *
  • If two Maps are equal according to the {@code equals(Map)} 226 | * method, then calling the {@code hashCode} method on each of 227 | * the two Maps must produce the same integer result. 228 | *
  • It is not required that if two Maps are unequal 229 | * according to the {@link java.lang.Map#equals(java.lang.Map)} 230 | * method, then calling the {@code hashCode} method on each of the 231 | * two Maps must produce distinct integer results. However, the 232 | * programmer should be aware that producing distinct integer results 233 | * for unequal Maps may improve the performance of hash tables. 234 | *
235 | *

236 | * As much as is reasonably practical, the hashCode method defined by 237 | * class {@code Map} does return distinct integers for distinct 238 | * Maps. (This is typically implemented by converting the internal 239 | * address of the Map into an integer, but this implementation 240 | * technique is not required by the 241 | * JavaTM programming language.) 242 | * 243 | * @return a hash code value for this Map. 244 | * @see java.lang.Map#equals(java.lang.Map) 245 | * @see java.lang.System#identityHashCode 246 | */ 247 | public native int hashCode(); 248 | 249 | /** 250 | * Indicates whether some other Map is "equal to" this one. 251 | *

252 | * The {@code equals} method implements an equivalence relation 253 | * on non-null Map references: 254 | *

    255 | *
  • It is reflexive: for any non-null reference value 256 | * {@code x}, {@code x.equals(x)} should return 257 | * {@code true}. 258 | *
  • It is symmetric: for any non-null reference values 259 | * {@code x} and {@code y}, {@code x.equals(y)} 260 | * should return {@code true} if and only if 261 | * {@code y.equals(x)} returns {@code true}. 262 | *
  • It is transitive: for any non-null reference values 263 | * {@code x}, {@code y}, and {@code z}, if 264 | * {@code x.equals(y)} returns {@code true} and 265 | * {@code y.equals(z)} returns {@code true}, then 266 | * {@code x.equals(z)} should return {@code true}. 267 | *
  • It is consistent: for any non-null reference values 268 | * {@code x} and {@code y}, multiple invocations of 269 | * {@code x.equals(y)} consistently return {@code true} 270 | * or consistently return {@code false}, provided no 271 | * information used in {@code equals} comparisons on the 272 | * Maps is modified. 273 | *
  • For any non-null reference value {@code x}, 274 | * {@code x.equals(null)} should return {@code false}. 275 | *
276 | *

277 | * The {@code equals} method for class {@code Map} implements 278 | * the most discriminating possible equivalence relation on Maps; 279 | * that is, for any non-null reference values {@code x} and 280 | * {@code y}, this method returns {@code true} if and only 281 | * if {@code x} and {@code y} refer to the same Map 282 | * ({@code x = y} has the value {@code true}). 283 | *

284 | * Note that it is generally necessary to override the {@code hashCode} 285 | * method whenever this method is overridden, so as to maintain the 286 | * general contract for the {@code hashCode} method, which states 287 | * that equal Maps must have equal hash codes. 288 | * 289 | * @param obj the reference Map with which to compare. 290 | * @return {@code true} if this Map is the same as the obj 291 | * argument; {@code false} otherwise. 292 | * @see #hashCode() 293 | * @see java.util.HashMap 294 | */ 295 | public Bool equals(Map obj) { 296 | return (this = obj); 297 | } 298 | 299 | /** 300 | * Creates and returns a copy of this Map. The precise meaning 301 | * of "copy" may depend on the class of the Map. The general 302 | * intent is that, for any Map {@code x}, the expression: 303 | *

304 | *
305 |      * x.clone() !: x
306 | * will be true, and that the expression: 307 | *
308 | *
309 |      * x.clone().getClass() = x.getClass()
310 | * will be {@code true}, but these are not absolute requirements. 311 | * While it is typically the case that: 312 | *
313 | *
314 |      * x.clone().equals(x)
315 | * will be {@code true}, this is not an absolute requirement. 316 | *

317 | * By convention, the returned Map should be obtained by calling 318 | * {@code super.clone}. If a class and all of its superclasses (except 319 | * {@code Map}) obey this convention, it will be the case that 320 | * {@code x.clone().getClass() = x.getClass()}. 321 | *

322 | * By convention, the Map returned by this method should be independent 323 | * of this Map (which is being cloned). To achieve this independence, 324 | * it may be necessary to modify one or more fields of the Map returned 325 | * by {@code super.clone} before returning it. Typically, this means 326 | * copying any mutable Maps that comprise the internal "deep structure" 327 | * of the Map being cloned and replacing the references to these 328 | * Maps with references to the copies. If a class contains only 329 | * primitive fields or references to immutable Maps, then it is usually 330 | * the case that no fields in the Map returned by {@code super.clone} 331 | * need to be modified. 332 | *

333 | * The method {@code clone} for class {@code Map} performs a 334 | * specific cloning operation. First, if the class of this Map does 335 | * not implement the interface {@code Cloneable}, then a 336 | * {@code CloneNotSupportedException} is thrown. Note that all Lists 337 | * are considered to implement the interface {@code Cloneable} and that 338 | * the return type of the {@code clone} method of an List type {@code T[]} 339 | * is {@code T[]} where T is any reference or primitive type. 340 | * Otherwise, this method creates a new instance of the class of this 341 | * Map and initializes all its fields with exactly the contents of 342 | * the corresponding fields of this Map, as if by assignment; the 343 | * contents of the fields are not themselves cloned. Thus, this method 344 | * performs a "shallow copy" of this Map, not a "deep copy" operation. 345 | *

346 | * The class {@code Map} does not itself implement the interface 347 | * {@code Cloneable}, so calling the {@code clone} method on an Map 348 | * whose class is {@code Map} will result in throwing an 349 | * exception at run time. 350 | * 351 | * @return a clone of this instance. 352 | * @exception CloneNotSupportedException if the Map's class does not 353 | * support the {@code Cloneable} interface. Subclasses 354 | * that override the {@code clone} method can also 355 | * throw this exception to indicate that an instance cannot 356 | * be cloned. 357 | * @see java.lang.Cloneable 358 | */ 359 | protected native Map clone() throws CloneNotSupportedException; 360 | 361 | /** 362 | * Returns a Str representation of the Map. In general, the 363 | * {@code toStr} method returns a Str that 364 | * "textually represents" this Map. The result should 365 | * be a concise but informative representation that is easy for a 366 | * person to read. 367 | * It is recommended that all subclasses override this method. 368 | *

369 | * The {@code toStr} method for class {@code Map} 370 | * returns a Str consisting of the name of the class of which the 371 | * Map is an instance, the at-sign Stracter `{@code @}', and 372 | * the unsigned hexadecimal representation of the hash code of the 373 | * Map. In other words, this method returns a Str equal to the 374 | * value of: 375 | *

376 | *
377 |      * getClass().getName() + '@' + Integer.toHexStr(hashCode())
378 |      * 
379 | * 380 | * @return a Str representation of the Map. 381 | */ 382 | public Str toStr() { 383 | return getClass().getName() + "@" + Integer.toHexStr(hashCode()); 384 | } 385 | 386 | /** 387 | * Wakes up a single thread that is waiting on this Map's 388 | * monitor. If any threads are waiting on this Map, one of them 389 | * is chosen to be awakened. The choice is arbitrary and occurs at 390 | * the discretion of the implementation. A thread waits on an Map's 391 | * monitor by calling one of the {@code wait} methods. 392 | *

393 | * The awakened thread will not be able to proceed until the current 394 | * thread relinquishes the lock on this Map. The awakened thread will 395 | * compete in the usual manner with any other threads that might be 396 | * actively competing to synchronize on this Map; for example, the 397 | * awakened thread enjoys no reliable privilege or disadvantage in being 398 | * the next thread to lock this Map. 399 | *

400 | * This method should only be called by a thread that is the owner 401 | * of this Map's monitor. A thread becomes the owner of the 402 | * Map's monitor in one of three ways: 403 | *

    404 | *
  • By executing a synchronized instance method of that Map. 405 | *
  • By executing the body of a {@code synchronized} statement 406 | * that synchronizes on the Map. 407 | *
  • For Maps of type {@code Class,} by executing a 408 | * synchronized static method of that class. 409 | *
410 | *

411 | * Only one thread at a time can own an Map's monitor. 412 | * 413 | * @exception IllegalMonitorStateException if the current thread is not 414 | * the owner of this Map's monitor. 415 | * @see java.lang.Map#notifyAll() 416 | * @see java.lang.Map#wait() 417 | */ 418 | public final native void notify(); 419 | 420 | /** 421 | * Wakes up all threads that are waiting on this Map's monitor. A 422 | * thread waits on an Map's monitor by calling one of the 423 | * {@code wait} methods. 424 | *

425 | * The awakened threads will not be able to proceed until the current 426 | * thread relinquishes the lock on this Map. The awakened threads 427 | * will compete in the usual manner with any other threads that might 428 | * be actively competing to synchronize on this Map; for example, 429 | * the awakened threads enjoy no reliable privilege or disadvantage in 430 | * being the next thread to lock this Map. 431 | *

432 | * This method should only be called by a thread that is the owner 433 | * of this Map's monitor. See the {@code notify} method for a 434 | * description of the ways in which a thread can become the owner of 435 | * a monitor. 436 | * 437 | * @exception IllegalMonitorStateException if the current thread is not 438 | * the owner of this Map's monitor. 439 | * @see java.lang.Map#notify() 440 | * @see java.lang.Map#wait() 441 | */ 442 | public final native void notifyAll(); 443 | 444 | /** 445 | * Causes the current thread to wait until either another thread invokes the 446 | * {@link java.lang.Map#notify()} method or the 447 | * {@link java.lang.Map#notifyAll()} method for this Map, or a 448 | * specified amount of time has elapsed. 449 | *

450 | * The current thread must own this Map's monitor. 451 | *

452 | * This method causes the current thread (call it T) to 453 | * place itself in the wait set for this Map and then to relinquish 454 | * any and all synchronization claims on this Map. Thread T 455 | * becomes disabled for thread scheduling purposes and lies dormant 456 | * until one of four things happens: 457 | *

    458 | *
  • Some other thread invokes the {@code notify} method for this 459 | * Map and thread T happens to be arbitrarily chosen as 460 | * the thread to be awakened. 461 | *
  • Some other thread invokes the {@code notifyAll} method for this 462 | * Map. 463 | *
  • Some other thread {@linkplain Thread#interrupt() interrupts} 464 | * thread T. 465 | *
  • The specified amount of real time has elapsed, more or less. If 466 | * {@code timeout} is zero, however, then real time is not taken into 467 | * consideration and the thread simply waits until notified. 468 | *
469 | * The thread T is then removed from the wait set for this 470 | * Map and re-enabled for thread scheduling. It then competes in the 471 | * usual manner with other threads for the right to synchronize on the 472 | * Map; once it has gained control of the Map, all its 473 | * synchronization claims on the Map are restored to the status quo 474 | * ante - that is, to the situation as of the time that the {@code wait} 475 | * method was invoked. Thread T then returns from the 476 | * invocation of the {@code wait} method. Thus, on return from the 477 | * {@code wait} method, the synchronization state of the Map and of 478 | * thread {@code T} is exactly as it was when the {@code wait} method 479 | * was invoked. 480 | *

481 | * A thread can also wake up without being notified, interrupted, or 482 | * timing out, a so-called spurious wakeup. While this will rarely 483 | * occur in practice, applications must guard against it by testing for 484 | * the condition that should have caused the thread to be awakened, and 485 | * continuing to wait if the condition is not satisfied. In other words, 486 | * waits should always occur in loops, like this one: 487 | *

488 |      *     synchronized (obj) {
489 |      *         while (<condition does not hold>)
490 |      *             obj.wait(timeout);
491 |      *         ... // Perform action appropriate to condition
492 |      *     }
493 |      * 
494 | * (For more information on this topic, see Section 3.2.3 in Doug Lea's 495 | * "Concurrent Programming in Java (Second Edition)" (Addison-Wesley, 496 | * 2000), or Item 50 in Joshua Bloch's "Effective Java Programming 497 | * Language Guide" (Addison-Wesley, 2001). 498 | * 499 | *

If the current thread is {@linkplain java.lang.Thread#interrupt() 500 | * interrupted} by any thread before or while it is waiting, then an 501 | * {@code InterruptedException} is thrown. This exception is not 502 | * thrown until the lock status of this Map has been restored as 503 | * described above. 504 | * 505 | *

506 | * Note that the {@code wait} method, as it places the current thread 507 | * into the wait set for this Map, unlocks only this Map; any 508 | * other Maps on which the current thread may be synchronized remain 509 | * locked while the thread waits. 510 | *

511 | * This method should only be called by a thread that is the owner 512 | * of this Map's monitor. See the {@code notify} method for a 513 | * description of the ways in which a thread can become the owner of 514 | * a monitor. 515 | * 516 | * @param timeout the maximum time to wait in milliseconds. 517 | * @exception IllegalArgumentException if the value of timeout is 518 | * negative. 519 | * @exception IllegalMonitorStateException if the current thread is not 520 | * the owner of the Map's monitor. 521 | * @exception InterruptedException if any thread interrupted the 522 | * current thread before or while the current thread 523 | * was waiting for a notification. The interrupted 524 | * status of the current thread is cleared when 525 | * this exception is thrown. 526 | * @see java.lang.Map#notify() 527 | * @see java.lang.Map#notifyAll() 528 | */ 529 | public final native void wait(long timeout) throws InterruptedException; 530 | 531 | /** 532 | * Causes the current thread to wait until another thread invokes the 533 | * {@link java.lang.Map#notify()} method or the 534 | * {@link java.lang.Map#notifyAll()} method for this Map, or 535 | * some other thread interrupts the current thread, or a certain 536 | * amount of real time has elapsed. 537 | *

538 | * This method is similar to the {@code wait} method of one 539 | * argument, but it allows finer control over the amount of time to 540 | * wait for a notification before giving up. The amount of real time, 541 | * measured in nanoseconds, is given by: 542 | *

543 | *
544 |      * 1000000*timeout+nanos
545 | *

546 | * In all other respects, this method does the same thing as the 547 | * method {@link #wait(long)} of one argument. In particular, 548 | * {@code wait(0, 0)} means the same thing as {@code wait(0)}. 549 | *

550 | * The current thread must own this Map's monitor. The thread 551 | * releases ownership of this monitor and waits until either of the 552 | * following two conditions has occurred: 553 | *

    554 | *
  • Another thread notifies threads waiting on this Map's monitor 555 | * to wake up either through a call to the {@code notify} method 556 | * or the {@code notifyAll} method. 557 | *
  • The timeout period, specified by {@code timeout} 558 | * milliseconds plus {@code nanos} nanoseconds arguments, has 559 | * elapsed. 560 | *
561 | *

562 | * The thread then waits until it can re-obtain ownership of the 563 | * monitor and resumes execution. 564 | *

565 | * As in the one argument version, interrupts and spurious wakeups are 566 | * possible, and this method should always be used in a loop: 567 | *

568 |      *     synchronized (obj) {
569 |      *    
570 | 
571 | }
572 | 
573 | //包级别类 >>>>>>>>>>>>>>>>>>>>>>
574 | 


--------------------------------------------------------------------------------