Java: Improved generics (#2812)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
diff --git a/components/prism-java.js b/components/prism-java.js
index 16a3346..86f1844 100644
--- a/components/prism-java.js
+++ b/components/prism-java.js
@@ -62,7 +62,7 @@
alias: 'punctuation'
},
'generics': {
- pattern: /<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,
+ pattern: /<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,
inside: {
'class-name': className,
'keyword': keywords,
diff --git a/components/prism-java.min.js b/components/prism-java.min.js
index 21a5b50..26a914f 100644
--- a/components/prism-java.min.js
+++ b/components/prism-java.min.js
@@ -1 +1 @@
-!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n="(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",a={pattern:RegExp(n+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{"class-name":[a,{pattern:RegExp(n+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=())])"),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(\:\:\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<(?:[\w\s,.&?]|<[\w\s,.&?]*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!<keyword>)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(/<keyword>/g,function(){return t.source})),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism);
\ No newline at end of file
+!function(e){var t=/\b(?:abstract|assert|boolean|break|byte|case|catch|char|class|const|continue|default|do|double|else|enum|exports|extends|final|finally|float|for|goto|if|implements|import|instanceof|int|interface|long|module|native|new|non-sealed|null|open|opens|package|permits|private|protected|provides|public|record|requires|return|sealed|short|static|strictfp|super|switch|synchronized|this|throw|throws|to|transient|transitive|try|uses|var|void|volatile|while|with|yield)\b/,n="(^|[^\\w.])(?:[a-z]\\w*\\s*\\.\\s*)*(?:[A-Z]\\w*\\s*\\.\\s*)*",a={pattern:RegExp(n+"[A-Z](?:[\\d_A-Z]*[a-z]\\w*)?\\b"),lookbehind:!0,inside:{namespace:{pattern:/^[a-z]\w*(?:\s*\.\s*[a-z]\w*)*(?:\s*\.)?/,inside:{punctuation:/\./}},punctuation:/\./}};e.languages.java=e.languages.extend("clike",{"class-name":[a,{pattern:RegExp(n+"[A-Z]\\w*(?=\\s+\\w+\\s*[;,=())])"),lookbehind:!0,inside:a.inside}],keyword:t,function:[e.languages.clike.function,{pattern:/(\:\:\s*)[a-z_]\w*/,lookbehind:!0}],number:/\b0b[01][01_]*L?\b|\b0x(?:\.[\da-f_p+-]+|[\da-f_]+(?:\.[\da-f_p+-]+)?)\b|(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?\d[\d_]*)?[dfl]?/i,operator:{pattern:/(^|[^.])(?:<<=?|>>>?=?|->|--|\+\+|&&|\|\||::|[?:~]|[-+*/%&|^!=<>]=?)/m,lookbehind:!0}}),e.languages.insertBefore("java","string",{"triple-quoted-string":{pattern:/"""[ \t]*[\r\n](?:(?:"|"")?(?:\\.|[^"\\]))*"""/,greedy:!0,alias:"string"}}),e.languages.insertBefore("java","class-name",{annotation:{pattern:/(^|[^.])@\w+(?:\s*\.\s*\w+)*/,lookbehind:!0,alias:"punctuation"},generics:{pattern:/<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&)|<(?:[\w\s,.?]|&(?!&))*>)*>)*>)*>/,inside:{"class-name":a,keyword:t,punctuation:/[<>(),.:]/,operator:/[?&|]/}},namespace:{pattern:RegExp("(\\b(?:exports|import(?:\\s+static)?|module|open|opens|package|provides|requires|to|transitive|uses|with)\\s+)(?!<keyword>)[a-z]\\w*(?:\\.[a-z]\\w*)*\\.?".replace(/<keyword>/g,function(){return t.source})),lookbehind:!0,inside:{punctuation:/\./}}})}(Prism);
\ No newline at end of file
diff --git a/tests/languages/java/generics_feature.test b/tests/languages/java/generics_feature.test
index 12d9fb6..7944a7e 100644
--- a/tests/languages/java/generics_feature.test
+++ b/tests/languages/java/generics_feature.test
@@ -2,19 +2,30 @@ public class Solo<T extends com.foo.Foo.Bar> {}
Solo<Integer> val = new Solo<>();
Duo<Double, Character> dual = new Duo<Double, Character>(12.2585, 'C');
+List<?> list
+List<? extends Number> nums = ints;
+List<? super Integer> list
+Entry<String, String> pair = Entry.<String>twice("Hello");
+
+public class Entry<KeyType, ValueType> {}
+class D <T extends A & B & C> {}
+
+public <T extends Throwable> void throwMeConditional(boolean conditional, T exception) throws T {}
+
+<T> T instantiateElementType(List<T> arg) {}
+
+// not generics
+if (a<6&&b>6){}
+
----------------------------------------------------
[
["keyword", "public"],
["keyword", "class"],
- ["class-name", [
- "Solo"
- ]],
+ ["class-name", ["Solo"]],
["generics", [
["punctuation", "<"],
- ["class-name", [
- "T"
- ]],
+ ["class-name", ["T"]],
["keyword", "extends"],
["class-name", [
["namespace", [
@@ -32,22 +43,16 @@ Duo<Double, Character> dual = new Duo<Double, Character>(12.2585, 'C');
["punctuation", "{"],
["punctuation", "}"],
- ["class-name", [
- "Solo"
- ]],
+ ["class-name", ["Solo"]],
["generics", [
["punctuation", "<"],
- ["class-name", [
- "Integer"
- ]],
+ ["class-name", ["Integer"]],
["punctuation", ">"]
]],
" val ",
["operator", "="],
["keyword", "new"],
- ["class-name", [
- "Solo"
- ]],
+ ["class-name", ["Solo"]],
["generics", [
["punctuation", "<"],
["punctuation", ">"]
@@ -56,35 +61,23 @@ Duo<Double, Character> dual = new Duo<Double, Character>(12.2585, 'C');
["punctuation", ")"],
["punctuation", ";"],
- ["class-name", [
- "Duo"
- ]],
+ ["class-name", ["Duo"]],
["generics", [
["punctuation", "<"],
- ["class-name", [
- "Double"
- ]],
+ ["class-name", ["Double"]],
["punctuation", ","],
- ["class-name", [
- "Character"
- ]],
+ ["class-name", ["Character"]],
["punctuation", ">"]
]],
" dual ",
["operator", "="],
["keyword", "new"],
- ["class-name", [
- "Duo"
- ]],
+ ["class-name", ["Duo"]],
["generics", [
["punctuation", "<"],
- ["class-name", [
- "Double"
- ]],
+ ["class-name", ["Double"]],
["punctuation", ","],
- ["class-name", [
- "Character"
- ]],
+ ["class-name", ["Character"]],
["punctuation", ">"]
]],
["punctuation", "("],
@@ -92,7 +85,146 @@ Duo<Double, Character> dual = new Duo<Double, Character>(12.2585, 'C');
["punctuation", ","],
["string", "'C'"],
["punctuation", ")"],
- ["punctuation", ";"]
+ ["punctuation", ";"],
+
+ ["class-name", ["List"]],
+ ["generics", [
+ ["punctuation", "<"],
+ ["operator", "?"],
+ ["punctuation", ">"]
+ ]],
+ " list\r\n",
+
+ ["class-name", ["List"]],
+ ["generics", [
+ ["punctuation", "<"],
+ ["operator", "?"],
+ ["keyword", "extends"],
+ ["class-name", ["Number"]],
+ ["punctuation", ">"]
+ ]],
+ " nums ",
+ ["operator", "="],
+ " ints",
+ ["punctuation", ";"],
+
+ ["class-name", ["List"]],
+ ["generics", [
+ ["punctuation", "<"],
+ ["operator", "?"],
+ ["keyword", "super"],
+ ["class-name", ["Integer"]],
+ ["punctuation", ">"]
+ ]],
+ " list\r\n",
+
+ ["class-name", ["Entry"]],
+ ["generics", [
+ ["punctuation", "<"],
+ ["class-name", ["String"]],
+ ["punctuation", ","],
+ ["class-name", ["String"]],
+ ["punctuation", ">"]
+ ]],
+ " pair ",
+ ["operator", "="],
+ ["class-name", ["Entry"]],
+ ["punctuation", "."],
+ ["generics", [
+ ["punctuation", "<"],
+ ["class-name", ["String"]],
+ ["punctuation", ">"]
+ ]],
+ ["function", "twice"],
+ ["punctuation", "("],
+ ["string", "\"Hello\""],
+ ["punctuation", ")"],
+ ["punctuation", ";"],
+
+ ["keyword", "public"],
+ ["keyword", "class"],
+ ["class-name", ["Entry"]],
+ ["generics", [
+ ["punctuation", "<"],
+ ["class-name", ["KeyType"]],
+ ["punctuation", ","],
+ ["class-name", ["ValueType"]],
+ ["punctuation", ">"]
+ ]],
+ ["punctuation", "{"],
+ ["punctuation", "}"],
+
+ ["keyword", "class"],
+ ["class-name", ["D"]],
+ ["generics", [
+ ["punctuation", "<"],
+ ["class-name", ["T"]],
+ ["keyword", "extends"],
+ ["class-name", ["A"]],
+ ["operator", "&"],
+ ["class-name", ["B"]],
+ ["operator", "&"],
+ ["class-name", ["C"]],
+ ["punctuation", ">"]
+ ]],
+ ["punctuation", "{"],
+ ["punctuation", "}"],
+
+ ["keyword", "public"],
+ ["generics", [
+ ["punctuation", "<"],
+ ["class-name", ["T"]],
+ ["keyword", "extends"],
+ ["class-name", ["Throwable"]],
+ ["punctuation", ">"]
+ ]],
+ ["keyword", "void"],
+ ["function", "throwMeConditional"],
+ ["punctuation", "("],
+ ["keyword", "boolean"],
+ " conditional",
+ ["punctuation", ","],
+ ["class-name", ["T"]],
+ " exception",
+ ["punctuation", ")"],
+ ["keyword", "throws"],
+ ["class-name", ["T"]],
+ ["punctuation", "{"],
+ ["punctuation", "}"],
+
+ ["generics", [
+ ["punctuation", "<"],
+ ["class-name", ["T"]],
+ ["punctuation", ">"]
+ ]],
+ ["class-name", ["T"]],
+ ["function", "instantiateElementType"],
+ ["punctuation", "("],
+ ["class-name", ["List"]],
+ ["generics", [
+ ["punctuation", "<"],
+ ["class-name", ["T"]],
+ ["punctuation", ">"]
+ ]],
+ " arg",
+ ["punctuation", ")"],
+ ["punctuation", "{"],
+ ["punctuation", "}"],
+
+ ["comment", "// not generics"],
+
+ ["keyword", "if"],
+ ["punctuation", "("],
+ "a",
+ ["operator", "<"],
+ ["number", "6"],
+ ["operator", "&&"],
+ "b",
+ ["operator", ">"],
+ ["number", "6"],
+ ["punctuation", ")"],
+ ["punctuation", "{"],
+ ["punctuation", "}"]
]
----------------------------------------------------