@ -365,7 +365,10 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
if ( type == "function" ) return cont ( functiondef ) ;
if ( type == "for" ) return cont ( pushlex ( "form" ) , forspec , statement , poplex ) ;
if ( type == "class" || ( isTS && value == "interface" ) ) { cx . marked = "keyword" ; return cont ( pushlex ( "form" ) , className , poplex ) ; }
if ( type == "class" || ( isTS && value == "interface" ) ) {
cx . marked = "keyword"
return cont ( pushlex ( "form" , type == "class" ? type : value ) , className , poplex )
}
if ( type == "variable" ) {
if ( isTS && value == "declare" ) {
cx . marked = "keyword"
@ -373,11 +376,11 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} else if ( isTS && ( value == "module" || value == "enum" || value == "type" ) && cx . stream . match ( /^\s*\w/ , false ) ) {
cx . marked = "keyword"
if ( value == "enum" ) return cont ( enumdef ) ;
else if ( value == "type" ) return cont ( type expr , expect ( "operator" ) , typeexpr , expect ( ";" ) ) ;
else if ( value == "type" ) return cont ( type nam e, expect ( "operator" ) , typeexpr , expect ( ";" ) ) ;
else return cont ( pushlex ( "form" ) , pattern , expect ( "{" ) , pushlex ( "}" ) , block , poplex , poplex )
} else if ( isTS && value == "namespace" ) {
cx . marked = "keyword"
return cont ( pushlex ( "form" ) , expression , block , poplex )
return cont ( pushlex ( "form" ) , expression , statement , poplex )
} else if ( isTS && value == "abstract" ) {
cx . marked = "keyword"
return cont ( statement )
@ -552,6 +555,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
} , proceed ) ;
}
if ( type == end || value == end ) return cont ( ) ;
if ( sep && sep . indexOf ( ";" ) > - 1 ) return pass ( what )
return cont ( expect ( end ) ) ;
}
return function ( type , value ) {
@ -570,7 +574,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function maybetype ( type , value ) {
if ( isTS ) {
if ( type == ":" ) return cont ( typeexpr ) ;
if ( type == ":" || value == "in" ) return cont ( typeexpr ) ;
if ( value == "?" ) return cont ( maybetype ) ;
}
}
@ -587,18 +591,19 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
}
function typeexpr ( type , value ) {
if ( value == "keyof" || value == "typeof" ) {
if ( value == "keyof" || value == "typeof" || value == "infer" ) {
cx . marked = "keyword"
return cont ( value == " keyof" ? typeexpr : expressionNoComma )
return cont ( value == " typeof" ? expressionNoComma : typeexpr )
}
if ( type == "variable" || value == "void" ) {
cx . marked = "type"
return cont ( afterType )
}
if ( value == "|" || value == "&" ) return cont ( typeexpr )
if ( type == "string" || type == "number" || type == "atom" ) return cont ( afterType ) ;
if ( type == "[" ) return cont ( pushlex ( "]" ) , commasep ( typeexpr , "]" , "," ) , poplex , afterType )
if ( type == "{" ) return cont ( pushlex ( "}" ) , commasep ( typeprop , "}" , ",;" ) , poplex , afterType )
if ( type == "(" ) return cont ( commasep ( typearg , ")" ) , maybeReturnType )
if ( type == "(" ) return cont ( commasep ( typearg , ")" ) , maybeReturnType , afterType )
if ( type == "<" ) return cont ( commasep ( typeexpr , ">" ) , typeexpr )
}
function maybeReturnType ( type ) {
@ -608,24 +613,28 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if ( type == "variable" || cx . style == "keyword" ) {
cx . marked = "property"
return cont ( typeprop )
} else if ( value == "?" ) {
} else if ( value == "?" || type == "number" || type == "string" ) {
return cont ( typeprop )
} else if ( type == ":" ) {
return cont ( typeexpr )
} else if ( type == "[" ) {
return cont ( expression , maybetype , expect ( "]" ) , typeprop )
return cont ( expect ( "variable" ) , maybetype , expect ( "]" ) , typeprop )
} else if ( type == "(" ) {
return pass ( functiondecl , typeprop )
}
}
function typearg ( type , value ) {
if ( type == "variable" && cx . stream . match ( /^\s*[?:]/ , false ) || value == "?" ) return cont ( typearg )
if ( type == ":" ) return cont ( typeexpr )
if ( type == "spread" ) return cont ( typearg )
return pass ( typeexpr )
}
function afterType ( type , value ) {
if ( value == "<" ) return cont ( pushlex ( ">" ) , commasep ( typeexpr , ">" ) , poplex , afterType )
if ( value == "|" || type == "." || value == "&" ) return cont ( typeexpr )
if ( type == "[" ) return cont ( expect( "]" ) , afterType )
if ( type == "[" ) return cont ( typeexpr, expect( "]" ) , afterType )
if ( value == "extends" || value == "implements" ) { cx . marked = "keyword" ; return cont ( typeexpr ) }
if ( value == "?" ) return cont ( typeexpr , expect ( ":" ) , typeexpr )
}
function maybeTypeArgs ( _ , value ) {
if ( value == "<" ) return cont ( pushlex ( ">" ) , commasep ( typeexpr , ">" ) , poplex , afterType )
@ -655,6 +664,7 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if ( type == "variable" ) cx . marked = "property" ;
if ( type == "spread" ) return cont ( pattern ) ;
if ( type == "}" ) return pass ( ) ;
if ( type == "[" ) return cont ( expression , expect ( ']' ) , expect ( ':' ) , proppattern ) ;
return cont ( expect ( ":" ) , pattern , maybeAssign ) ;
}
function eltpattern ( ) {
@ -671,25 +681,18 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
}
function forspec ( type , value ) {
if ( value == "await" ) return cont ( forspec ) ;
if ( type == "(" ) return cont ( pushlex ( ")" ) , forspec1 , expect( ")" ) , poplex) ;
if ( type == "(" ) return cont ( pushlex ( ")" ) , forspec1 , poplex) ;
}
function forspec1 ( type ) {
if ( type == "var" ) return cont ( vardef , expect ( ";" ) , forspec2 ) ;
if ( type == ";" ) return cont ( forspec2 ) ;
if ( type == "variable" ) return cont ( formaybeinof ) ;
return pass ( expression , expect ( ";" ) , forspec2 ) ;
}
function formaybeinof ( _type , value ) {
if ( value == "in" || value == "of" ) { cx . marked = "keyword" ; return cont ( expression ) ; }
return cont ( maybeoperatorComma , forspec2 ) ;
if ( type == "var" ) return cont ( vardef , forspec2 ) ;
if ( type == "variable" ) return cont ( forspec2 ) ;
return pass ( forspec2 )
}
function forspec2 ( type , value ) {
if ( type == ";" ) return cont ( forspec3 ) ;
if ( value == "in" || value == "of" ) { cx . marked = "keyword" ; return cont ( expression ) ; }
return pass ( expression , expect ( ";" ) , forspec3 ) ;
}
function forspec3 ( type ) {
if ( type != ")" ) cont ( expression ) ;
if ( type == ")" ) return cont ( )
if ( type == ";" ) return cont ( forspec2 )
if ( value == "in" || value == "of" ) { cx . marked = "keyword" ; return cont ( expression , forspec2 ) }
return pass ( expression , forspec2 )
}
function functiondef ( type , value ) {
if ( value == "*" ) { cx . marked = "keyword" ; return cont ( functiondef ) ; }
@ -697,10 +700,25 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if ( type == "(" ) return cont ( pushcontext , pushlex ( ")" ) , commasep ( funarg , ")" ) , poplex , mayberettype , statement , popcontext ) ;
if ( isTS && value == "<" ) return cont ( pushlex ( ">" ) , commasep ( typeparam , ">" ) , poplex , functiondef )
}
function functiondecl ( type , value ) {
if ( value == "*" ) { cx . marked = "keyword" ; return cont ( functiondecl ) ; }
if ( type == "variable" ) { register ( value ) ; return cont ( functiondecl ) ; }
if ( type == "(" ) return cont ( pushcontext , pushlex ( ")" ) , commasep ( funarg , ")" ) , poplex , mayberettype , popcontext ) ;
if ( isTS && value == "<" ) return cont ( pushlex ( ">" ) , commasep ( typeparam , ">" ) , poplex , functiondecl )
}
function typename ( type , value ) {
if ( type == "keyword" || type == "variable" ) {
cx . marked = "type"
return cont ( typename )
} else if ( value == "<" ) {
return cont ( pushlex ( ">" ) , commasep ( typeparam , ">" ) , poplex )
}
}
function funarg ( type , value ) {
if ( value == "@" ) cont ( expression , funarg )
if ( type == "spread" ) return cont ( funarg ) ;
if ( isTS && isModifier ( value ) ) { cx . marked = "keyword" ; return cont ( funarg ) ; }
if ( isTS && type == "this" ) return cont ( maybetype , maybeAssign )
return pass ( pattern , maybetype , maybeAssign ) ;
}
function classExpression ( type , value ) {
@ -731,13 +749,15 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
cx . marked = "property" ;
return cont ( isTS ? classfield : functiondef , classBody ) ;
}
if ( type == "number" || type == "string" ) return cont ( isTS ? classfield : functiondef , classBody ) ;
if ( type == "[" )
return cont ( expression , maybetype , expect ( "]" ) , isTS ? classfield : functiondef , classBody )
if ( value == "*" ) {
cx . marked = "keyword" ;
return cont ( classBody ) ;
}
if ( type == ";" ) return cont ( classBody ) ;
if ( isTS && type == "(" ) return pass ( functiondecl , classBody )
if ( type == ";" || type == "," ) return cont ( classBody ) ;
if ( type == "}" ) return cont ( ) ;
if ( value == "@" ) return cont ( expression , classBody )
}
@ -745,7 +765,8 @@ CodeMirror.defineMode("javascript", function(config, parserConfig) {
if ( value == "?" ) return cont ( classfield )
if ( type == ":" ) return cont ( typeexpr , maybeAssign )
if ( value == "=" ) return cont ( expressionNoComma )
return pass ( functiondef )
var context = cx . state . lexical . prev , isInterface = context && context . info == "interface"
return pass ( isInterface ? functiondecl : functiondef )
}
function afterExport ( type , value ) {
if ( value == "*" ) { cx . marked = "keyword" ; return cont ( maybeFrom , expect ( ";" ) ) ; }
@ -888,8 +909,6 @@ CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
CodeMirror . defineMIME ( "text/javascript" , "javascript" ) ;
CodeMirror . defineMIME ( "text/ecmascript" , "javascript" ) ;
CodeMirror . defineMIME ( "application/javascript" , "javascript" ) ;
CodeMirror . defineMIME ( "application/javascript;env=frontend" , "javascript" ) ;
CodeMirror . defineMIME ( "application/javascript;env=backend" , "javascript" ) ;
CodeMirror . defineMIME ( "application/x-javascript" , "javascript" ) ;
CodeMirror . defineMIME ( "application/ecmascript" , "javascript" ) ;
CodeMirror . defineMIME ( "application/json" , { name : "javascript" , json : true } ) ;