diff --git a/grammars/php.cson b/grammars/php.cson index ab37dcbf..d3db4552 100644 --- a/grammars/php.cson +++ b/grammars/php.cson @@ -1,11 +1,18 @@ # Actual PHP grammar + +# NOTE: While the PHP manual documents the range of valid identifiers as [a-z_\x{7f}-\x{ff}][a-z0-9_\x{7f}-\x{ff}]*, +# due to a quirk with how PHP parses identifiers it looks at each _byte_ rather than _characters_. +# Therefore while سن is technically not in that range, its hex representation is `d8 b3 d9 86`, +# and PHP recognizes it as a valid identifier. To handle this behavior in Atom, we use the modified regex +# [a-z_\x{7f}-\x{7fffffff}][a-z0-9_\x{7f}-\x{7fffffff}]*. +# See https://github.com/atom/language-php/issues/301. 'scopeName': 'source.php' 'patterns': [ { 'include': '#comments' } { - 'begin': '(?i)^\\s*(interface)\\s+([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)\\s*(extends)?\\s*' + 'begin': '(?i)^\\s*(interface)\\s+([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)\\s*(extends)?\\s*' 'beginCaptures': '1': 'name': 'storage.type.interface.php' @@ -13,12 +20,12 @@ 'name': 'entity.name.type.interface.php' '3': 'name': 'storage.modifier.extends.php' - 'end': '(?i)((?:[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*\\s*,\\s*)*)([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)?\\s*(?:(?={)|$)' + 'end': '(?i)((?:[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*\\s*,\\s*)*)([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)?\\s*(?:(?={)|$)' 'endCaptures': '1': 'patterns': [ { - 'match': '(?i)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*' + 'match': '(?i)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*' 'name': 'entity.other.inherited-class.php' } { @@ -36,7 +43,7 @@ ] } { - 'begin': '(?i)^\\s*(trait)\\s+([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)' + 'begin': '(?i)^\\s*(trait)\\s+([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)' 'beginCaptures': '1': 'name': 'storage.type.trait.php' @@ -51,7 +58,7 @@ ] } { - 'match': '(?i)(?:^|(?<=<\\?php))\\s*(namespace)\\s+([a-z0-9_\\x{7f}-\\x{ff}\\\\]+)(?=\\s*;)' + 'match': '(?i)(?:^|(?<=<\\?php))\\s*(namespace)\\s+([a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]+)(?=\\s*;)' 'name': 'meta.namespace.php' 'captures': '1': @@ -77,7 +84,7 @@ 'include': '#comments' } { - 'match': '(?i)[a-z0-9_\\x{7f}-\\x{ff}\\\\]+' + 'match': '(?i)[a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]+' 'name': 'entity.name.type.namespace.php' 'captures': '0': @@ -141,8 +148,7 @@ 'match': '''(?xi) \\b(as) \\s+(final|abstract|public|private|protected|static) - \\s+([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) - \\b + \\s+([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) ''' 'captures': '1': @@ -155,8 +161,7 @@ { 'match': '''(?xi) \\b(as) - \\s+([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) - \\b + \\s+([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) ''' 'captures': '1': @@ -174,7 +179,7 @@ ] } { - 'match': '(?i)\\b(insteadof)\\s+([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)' + 'match': '(?i)\\b(insteadof)\\s+([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)' 'captures': '1': 'name': 'keyword.other.use-insteadof.php' @@ -196,7 +201,7 @@ ] } { - 'begin': '(?i)^\\s*(?:(abstract|final)\\s+)?(class)\\s+([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)' + 'begin': '(?i)^\\s*(?:(abstract|final)\\s+)?(class)\\s+([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)' 'beginCaptures': '1': 'name': 'storage.modifier.${1:/downcase}.php' @@ -219,11 +224,11 @@ '1': 'name': 'storage.modifier.extends.php' 'contentName': 'meta.other.inherited-class.php' - 'end': '(?i)(?=[^a-z0-9_\\x{7f}-\\x{ff}\\\\])' + 'end': '(?i)(?=[^a-z0-9_\\x{7f}-\\x{7fffffff}\\\\])' 'patterns': [ { - 'begin': '(?i)(?=\\\\?[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*\\\\)' - 'end': '(?i)([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)?(?=[^a-z0-9_\\x{7f}-\\x{ff}\\\\])' + 'begin': '(?i)(?=\\\\?[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*\\\\)' + 'end': '(?i)([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)?(?=[^a-z0-9_\\x{7f}-\\x{7fffffff}\\\\])' 'endCaptures': '1': 'name': 'entity.other.inherited-class.php' @@ -240,7 +245,7 @@ 'include': '#namespace' } { - 'match': '(?i)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*' + 'match': '(?i)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*' 'name': 'entity.other.inherited-class.php' } ] @@ -256,13 +261,13 @@ 'include': '#comments' } { - 'begin': '(?i)(?=[a-z0-9_\\x{7f}-\\x{ff}\\\\]+)' + 'begin': '(?i)(?=[a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]+)' 'contentName': 'meta.other.inherited-class.php' - 'end': '(?i)(?:\\s*(?:,|(?=[^a-z0-9_\\x{7f}-\\x{ff}\\\\\\s]))\\s*)' + 'end': '(?i)(?:\\s*(?:,|(?=[^a-z0-9_\\x{7f}-\\x{7fffffff}\\\\\\s]))\\s*)' 'patterns': [ { - 'begin': '(?i)(?=\\\\?[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*\\\\)' - 'end': '(?i)([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)?(?=[^a-z0-9_\\x{7f}-\\x{ff}\\\\])' + 'begin': '(?i)(?=\\\\?[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*\\\\)' + 'end': '(?i)([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)?(?=[^a-z0-9_\\x{7f}-\\x{7fffffff}\\\\])' 'endCaptures': '1': 'name': 'entity.other.inherited-class.php' @@ -279,7 +284,7 @@ 'include': '#namespace' } { - 'match': '(?i)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*' + 'match': '(?i)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*' 'name': 'entity.other.inherited-class.php' } ] @@ -348,10 +353,10 @@ } { 'match': '''(?xi) - ([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Exception class - ((?:\\s*\\|\\s*[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)*) # Optional additional exception classes + ([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Exception class + ((?:\\s*\\|\\s*[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)*) # Optional additional exception classes \\s* - ((\\$+)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Variable + ((\\$+)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Variable ''' 'captures': '1': @@ -359,7 +364,7 @@ '2': 'patterns': [ { - 'match': '(?i)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*' + 'match': '(?i)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*' 'name': 'support.class.exception.php' } { @@ -422,7 +427,7 @@ 'name': 'storage.modifier.reference.php' '3': 'name': 'punctuation.definition.variable.php' - 'match': '(?i)((&)?\\s*(\\$+)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)\\s*(?=,|\\))' + 'match': '(?i)((&)?\\s*(\\$+)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)\\s*(?=,|\\))' 'name': 'meta.function.closure.use.php' } ] @@ -436,7 +441,7 @@ (?i: (__(?:call|construct|debugInfo|destruct|get|set|isset|unset|toString| clone|set_state|sleep|wakeup|autoload|invoke|callStatic)) - |([a-zA-Z_\\x{7f}-\\x{ff}][a-zA-Z0-9_\\x{7f}-\\x{ff}]*) + |([a-zA-Z_\\x{7f}-\\x{7fffffff}][a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]*) ) \\s*(\\() ''' @@ -457,7 +462,7 @@ '5': 'name': 'punctuation.definition.parameters.begin.bracket.round.php' 'contentName': 'meta.function.parameters.php' - 'end': '(\\))(?:\\s*(:)\\s*([a-zA-Z_\\x{7f}-\\x{ff}][a-zA-Z0-9_\\x{7f}-\\x{ff}]*))?' + 'end': '(\\))(?:\\s*(:)\\s*([a-zA-Z_\\x{7f}-\\x{7fffffff}][a-zA-Z0-9_\\x{7f}-\\x{7fffffff}]*))?' 'endCaptures': '1': 'name': 'punctuation.definition.parameters.end.bracket.round.php' @@ -610,7 +615,7 @@ 'beginCaptures': '1': 'name': 'keyword.operator.type.php' - 'end': '(?=[^\\\\$a-z0-9_\\x{7f}-\\x{ff}])' + 'end': '(?=[^\\\\$a-z0-9_\\x{7f}-\\x{7fffffff}])' 'patterns': [ { 'include': '#class-name' @@ -629,13 +634,13 @@ 'name': 'keyword.control.goto.php' '2': 'name': 'support.other.php' - 'match': '(?i)(goto)\\s+([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)' + 'match': '(?i)(goto)\\s+([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)' } { 'captures': '1': 'name': 'entity.name.goto-label.php' - 'match': '(?i)^\\s*([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)\\s*:(?!:)' + 'match': '(?i)^\\s*([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)\\s*:(?!:)' } { 'include': '#string-backtick' @@ -1070,7 +1075,7 @@ # In PHP, any identifier which is not a variable is taken to be a constant. # However, if there is not a constant defined with the given name then a notice # is generated and the constant is assumed to have the value of its name. - 'match': '(?i)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*' + 'match': '(?i)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*' 'name': 'constant.other.php' } ] @@ -1086,7 +1091,7 @@ { 'begin': '''(?xi) (array) # Typehint - \\s+((&)?\\s*(\\$+)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Variable name with possible reference + \\s+((&)?\\s*(\\$+)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Variable name with possible reference \\s*(=)\\s*(array)\\s*(\\() # Default value ''' 'beginCaptures': @@ -1125,7 +1130,7 @@ { 'match': '''(?xi) (array|callable) # Typehint - \\s+((&)?\\s*(\\$+)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Variable name with possible reference + \\s+((&)?\\s*(\\$+)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Variable name with possible reference (?: # Optional default value \\s*(=)\\s* (?: @@ -1166,16 +1171,16 @@ } { 'begin': '''(?xi) - (\\\\?(?:[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*\\\\)*) # Optional namespace - ([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Typehinted class name - \\s+((&)?\\s*(\\.\\.\\.)?(\\$+)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Variable name with possible reference + (\\\\?(?:[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*\\\\)*) # Optional namespace + ([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Typehinted class name + \\s+((&)?\\s*(\\.\\.\\.)?(\\$+)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Variable name with possible reference ''' 'beginCaptures': '1': 'name': 'support.other.namespace.php' 'patterns': [ { - 'match': '(?i)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*' + 'match': '(?i)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*' 'name': 'storage.type.php' } { @@ -1221,14 +1226,14 @@ '4': 'name': 'punctuation.definition.variable.php' 'match': '''(?xi) - ((&)?\\s*(\\.\\.\\.)?(\\$+)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Variable name with possible reference + ((&)?\\s*(\\.\\.\\.)?(\\$+)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Variable name with possible reference \\s*(?=,|\\)|/[/*]|\\#|$) # A closing parentheses (end of argument list) or a comma or a comment ''' 'name': 'meta.function.parameter.no-default.php' } { 'begin': '''(?xi) - ((&)?\\s*(\\.\\.\\.)?(\\$+)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Variable name with possible reference + ((&)?\\s*(\\.\\.\\.)?(\\$+)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Variable name with possible reference \\s*(=)\\s* (?:(\\[)((?>[^\\[\\]]+|\\[\\g<6>\\])*)(\\]))? # Optional default type ''' @@ -1268,9 +1273,9 @@ # Functions in a user-defined namespace (overrides any built-ins) 'begin': '''(?xi) ( - \\\\?\\b # Optional root namespace - [a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]* # First namespace - (?:\\\\[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)+ # Additional namespaces + \\\\?(?)([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)\\s*(\\()' + 'begin': '(?i)(->)([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)\\s*(\\()' 'beginCaptures': '1': 'name': 'keyword.operator.class.php' @@ -2011,7 +2016,7 @@ 'name': 'variable.other.property.php' '3': 'name': 'punctuation.definition.variable.php' - 'match': '(?i)(->)((\\$+)?[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)?' + 'match': '(?i)(->)((\\$+)?[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)?' } ] 'parameter-default-types': @@ -2063,11 +2068,11 @@ } { 'begin': '''(?xi) - (?=[a-z0-9_\\x{7f}-\\x{ff}\\\\]+(::) - ([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)? + (?=[a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]+(::) + ([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)? ) ''' - 'end': '(?i)(::)([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)?' + 'end': '(?i)(::)([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)?' 'endCaptures': '1': 'name': 'keyword.operator.class.php' @@ -2111,7 +2116,7 @@ { # Tags followed by a type expression # - @ type - 'begin': '(@(?:global|param|property(-(read|write))?|return|throws|var))\\s+(?=[A-Za-z_\\x{7f}-\\x{ff}\\\\]|\\()' + 'begin': '(@(?:global|param|property(-(read|write))?|return|throws|var))\\s+(?=[A-Za-z_\\x{7f}-\\x{7fffffff}\\\\]|\\()' 'beginCaptures': '1': 'name': 'keyword.other.phpdoc.php' @@ -2149,7 +2154,7 @@ } ] 'php_doc_types': - 'match': '(?i)[a-z_\\x{7f}-\\x{ff}\\\\][a-z0-9_\\x{7f}-\\x{ff}\\\\]*(\\|[a-z_\\x{7f}-\\x{ff}\\\\][a-z0-9_\\x{7f}-\\x{ff}\\\\]*)*' + 'match': '(?i)[a-z_\\x{7f}-\\x{7fffffff}\\\\][a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]*(\\|[a-z_\\x{7f}-\\x{7fffffff}\\\\][a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]*)*' 'captures': '0': 'patterns': [ @@ -2197,7 +2202,7 @@ ] 'php_doc_types_array_single': # Singular type array: int[] - 'match': '(?i)([a-z_\\x{7f}-\\x{ff}\\\\][a-z0-9_\\x{7f}-\\x{ff}\\\\]*)(\\[\\])' + 'match': '(?i)([a-z_\\x{7f}-\\x{7fffffff}\\\\][a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]*)(\\[\\])' 'captures': '1': 'patterns': [ @@ -2292,7 +2297,7 @@ 'scope-resolution': 'patterns': [ { - 'match': '(?i)([a-z_\\x{7f}-\\x{ff}\\\\][a-z0-9_\\x{7f}-\\x{ff}\\\\]*)(?=\\s*::)' + 'match': '(?i)([a-z_\\x{7f}-\\x{7fffffff}\\\\][a-z0-9_\\x{7f}-\\x{7fffffff}\\\\]*)(?=\\s*::)' 'captures': '1': 'patterns': [ @@ -2309,7 +2314,7 @@ ] } { - 'begin': '(?i)(::)\\s*([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)\\s*(\\()' + 'begin': '(?i)(::)\\s*([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)\\s*(\\()' 'beginCaptures': '1': 'name': 'keyword.operator.class.php' @@ -2340,9 +2345,9 @@ 'match': '''(?xi) (::)\\s* (?: - ((\\$+)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Variable + ((\\$+)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Variable | - ([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*) # Constant + ([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*) # Constant )? ''' 'captures': @@ -3474,7 +3479,7 @@ 'beginCaptures': '1': 'name': 'keyword.other.use-as.php' - 'end': '(?i)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*' + 'end': '(?i)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*' 'endCaptures': '0': 'name': 'entity.other.alias.php' @@ -3490,11 +3495,11 @@ 'var_basic': 'patterns': [ { + 'match': '(?i)(\\$+)[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*' + 'name': 'variable.other.php' 'captures': '1': 'name': 'punctuation.definition.variable.php' - 'match': '(?i)(\\$+)[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*\\b' - 'name': 'variable.other.php' } ] 'var_global': @@ -3547,11 +3552,11 @@ 'name': 'punctuation.section.array.end.php' # Simple syntax: $foo, $foo[0], $foo[$bar], $foo->bar 'match': '''(?xi) - ((\\$)(?[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)) + ((\\$)(?[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)) (?: (->)(\\g) | - (\\[)(?:(\\d+)|((\\$)\\g)|([a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*))(\\]) + (\\[)(?:(\\d+)|((\\$)\\g)|([a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*))(\\]) )? ''' } @@ -3564,7 +3569,7 @@ '4': 'name': 'punctuation.definition.variable.php' # Simple syntax with braces: foo${bar}baz - 'match': '(?i)((\\${)(?[a-z_\\x{7f}-\\x{ff}][a-z0-9_\\x{7f}-\\x{ff}]*)(}))' + 'match': '(?i)((\\${)(?[a-z_\\x{7f}-\\x{7fffffff}][a-z0-9_\\x{7f}-\\x{7fffffff}]*)(}))' } ] 'variables': diff --git a/spec/php-spec.coffee b/spec/php-spec.coffee index 855b95c8..bae37bce 100644 --- a/spec/php-spec.coffee +++ b/spec/php-spec.coffee @@ -248,6 +248,36 @@ describe 'PHP grammar', -> expect(lines[1][4]).toEqual value: ':', scopes: ['source.php', 'keyword.operator.ternary.php'] expect(lines[1][8]).toEqual value: '?:', scopes: ['source.php', 'keyword.operator.ternary.php'] + describe 'identifiers', -> + it 'tokenizes identifiers with only letters', -> + {tokens} = grammar.tokenizeLine '$abc' + + expect(tokens[1]).toEqual value: 'abc', scopes: ['source.php', 'variable.other.php'] + + {tokens} = grammar.tokenizeLine '$aBc' + + expect(tokens[1]).toEqual value: 'aBc', scopes: ['source.php', 'variable.other.php'] + + it 'tokenizes identifiers with a combination of letters and numbers', -> + {tokens} = grammar.tokenizeLine '$a1B99c4' + + expect(tokens[1]).toEqual value: 'a1B99c4', scopes: ['source.php', 'variable.other.php'] + + it 'tokenizes identifiers that contain accents, umlauts, or similar', -> + {tokens} = grammar.tokenizeLine '$ßÄÖÜäöüàésF4s3' + + expect(tokens[1]).toEqual value: 'ßÄÖÜäöüàésF4s3', scopes: ['source.php', 'variable.other.php'] + + it 'tokenizes identifiers that contain Arabic', -> + {tokens} = grammar.tokenizeLine '$سن' + + expect(tokens[1]).toEqual value: 'سن', scopes: ['source.php', 'variable.other.php'] + + it 'tokenizes identifiers that contain emojis', -> + {tokens} = grammar.tokenizeLine '$🐘' + + expect(tokens[1]).toEqual value: '🐘', scopes: ['source.php', 'variable.other.php'] + it 'should tokenize $this', -> {tokens} = grammar.tokenizeLine '$this'