webidl.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. // CodeMirror, copyright (c) by Marijn Haverbeke and others
  2. // Distributed under an MIT license: https://codemirror.net/LICENSE
  3. ;(function (mod) {
  4. if (typeof exports == 'object' && typeof module == 'object')
  5. // CommonJS
  6. mod(require('../../lib/codemirror'))
  7. else if (typeof define == 'function' && define.amd)
  8. // AMD
  9. define(['../../lib/codemirror'], mod)
  10. // Plain browser env
  11. else mod(CodeMirror)
  12. })(function (CodeMirror) {
  13. 'use strict'
  14. function wordRegexp(words) {
  15. return new RegExp('^((' + words.join(')|(') + '))\\b')
  16. }
  17. var builtinArray = [
  18. 'Clamp',
  19. 'Constructor',
  20. 'EnforceRange',
  21. 'Exposed',
  22. 'ImplicitThis',
  23. 'Global',
  24. 'PrimaryGlobal',
  25. 'LegacyArrayClass',
  26. 'LegacyUnenumerableNamedProperties',
  27. 'LenientThis',
  28. 'NamedConstructor',
  29. 'NewObject',
  30. 'NoInterfaceObject',
  31. 'OverrideBuiltins',
  32. 'PutForwards',
  33. 'Replaceable',
  34. 'SameObject',
  35. 'TreatNonObjectAsNull',
  36. 'TreatNullAs',
  37. 'EmptyString',
  38. 'Unforgeable',
  39. 'Unscopeable',
  40. ]
  41. var builtins = wordRegexp(builtinArray)
  42. var typeArray = [
  43. 'unsigned',
  44. 'short',
  45. 'long', // UnsignedIntegerType
  46. 'unrestricted',
  47. 'float',
  48. 'double', // UnrestrictedFloatType
  49. 'boolean',
  50. 'byte',
  51. 'octet', // Rest of PrimitiveType
  52. 'Promise', // PromiseType
  53. 'ArrayBuffer',
  54. 'DataView',
  55. 'Int8Array',
  56. 'Int16Array',
  57. 'Int32Array',
  58. 'Uint8Array',
  59. 'Uint16Array',
  60. 'Uint32Array',
  61. 'Uint8ClampedArray',
  62. 'Float32Array',
  63. 'Float64Array', // BufferRelatedType
  64. 'ByteString',
  65. 'DOMString',
  66. 'USVString',
  67. 'sequence',
  68. 'object',
  69. 'RegExp',
  70. 'Error',
  71. 'DOMException',
  72. 'FrozenArray', // Rest of NonAnyType
  73. 'any', // Rest of SingleType
  74. 'void', // Rest of ReturnType
  75. ]
  76. var types = wordRegexp(typeArray)
  77. var keywordArray = [
  78. 'attribute',
  79. 'callback',
  80. 'const',
  81. 'deleter',
  82. 'dictionary',
  83. 'enum',
  84. 'getter',
  85. 'implements',
  86. 'inherit',
  87. 'interface',
  88. 'iterable',
  89. 'legacycaller',
  90. 'maplike',
  91. 'partial',
  92. 'required',
  93. 'serializer',
  94. 'setlike',
  95. 'setter',
  96. 'static',
  97. 'stringifier',
  98. 'typedef', // ArgumentNameKeyword except
  99. // "unrestricted"
  100. 'optional',
  101. 'readonly',
  102. 'or',
  103. ]
  104. var keywords = wordRegexp(keywordArray)
  105. var atomArray = [
  106. 'true',
  107. 'false', // BooleanLiteral
  108. 'Infinity',
  109. 'NaN', // FloatLiteral
  110. 'null', // Rest of ConstValue
  111. ]
  112. var atoms = wordRegexp(atomArray)
  113. CodeMirror.registerHelper('hintWords', 'webidl', builtinArray.concat(typeArray).concat(keywordArray).concat(atomArray))
  114. var startDefArray = ['callback', 'dictionary', 'enum', 'interface']
  115. var startDefs = wordRegexp(startDefArray)
  116. var endDefArray = ['typedef']
  117. var endDefs = wordRegexp(endDefArray)
  118. var singleOperators = /^[:<=>?]/
  119. var integers = /^-?([1-9][0-9]*|0[Xx][0-9A-Fa-f]+|0[0-7]*)/
  120. var floats = /^-?(([0-9]+\.[0-9]*|[0-9]*\.[0-9]+)([Ee][+-]?[0-9]+)?|[0-9]+[Ee][+-]?[0-9]+)/
  121. var identifiers = /^_?[A-Za-z][0-9A-Z_a-z-]*/
  122. var identifiersEnd = /^_?[A-Za-z][0-9A-Z_a-z-]*(?=\s*;)/
  123. var strings = /^"[^"]*"/
  124. var multilineComments = /^\/\*.*?\*\//
  125. var multilineCommentsStart = /^\/\*.*/
  126. var multilineCommentsEnd = /^.*?\*\//
  127. function readToken(stream, state) {
  128. // whitespace
  129. if (stream.eatSpace()) return null
  130. // comment
  131. if (state.inComment) {
  132. if (stream.match(multilineCommentsEnd)) {
  133. state.inComment = false
  134. return 'comment'
  135. }
  136. stream.skipToEnd()
  137. return 'comment'
  138. }
  139. if (stream.match('//')) {
  140. stream.skipToEnd()
  141. return 'comment'
  142. }
  143. if (stream.match(multilineComments)) return 'comment'
  144. if (stream.match(multilineCommentsStart)) {
  145. state.inComment = true
  146. return 'comment'
  147. }
  148. // integer and float
  149. if (stream.match(/^-?[0-9\.]/, false)) {
  150. if (stream.match(integers) || stream.match(floats)) return 'number'
  151. }
  152. // string
  153. if (stream.match(strings)) return 'string'
  154. // identifier
  155. if (state.startDef && stream.match(identifiers)) return 'def'
  156. if (state.endDef && stream.match(identifiersEnd)) {
  157. state.endDef = false
  158. return 'def'
  159. }
  160. if (stream.match(keywords)) return 'keyword'
  161. if (stream.match(types)) {
  162. var lastToken = state.lastToken
  163. var nextToken = (stream.match(/^\s*(.+?)\b/, false) || [])[1]
  164. if (lastToken === ':' || lastToken === 'implements' || nextToken === 'implements' || nextToken === '=') {
  165. // Used as identifier
  166. return 'builtin'
  167. } else {
  168. // Used as type
  169. return 'variable-3'
  170. }
  171. }
  172. if (stream.match(builtins)) return 'builtin'
  173. if (stream.match(atoms)) return 'atom'
  174. if (stream.match(identifiers)) return 'variable'
  175. // other
  176. if (stream.match(singleOperators)) return 'operator'
  177. // unrecognized
  178. stream.next()
  179. return null
  180. }
  181. CodeMirror.defineMode('webidl', function () {
  182. return {
  183. startState: function () {
  184. return {
  185. // Is in multiline comment
  186. inComment: false,
  187. // Last non-whitespace, matched token
  188. lastToken: '',
  189. // Next token is a definition
  190. startDef: false,
  191. // Last token of the statement is a definition
  192. endDef: false,
  193. }
  194. },
  195. token: function (stream, state) {
  196. var style = readToken(stream, state)
  197. if (style) {
  198. var cur = stream.current()
  199. state.lastToken = cur
  200. if (style === 'keyword') {
  201. state.startDef = startDefs.test(cur)
  202. state.endDef = state.endDef || endDefs.test(cur)
  203. } else {
  204. state.startDef = false
  205. }
  206. }
  207. return style
  208. },
  209. }
  210. })
  211. CodeMirror.defineMIME('text/x-webidl', 'webidl')
  212. })