lib/rouge/lexers/php.rb in rouge-3.17.0 vs lib/rouge/lexers/php.rb in rouge-3.18.0
- old
+ new
@@ -27,11 +27,11 @@
@funcnamehighlighting = bool_option(:funcnamehighlighting) { true }
@disabledmodules = list_option(:disabledmodules)
end
def self.builtins
- load File.join(__dir__, 'php/builtins.rb')
+ load File.join(Lexers::BASE_DIR, 'php/builtins.rb')
self.builtins
end
def builtins
return [] unless @funcnamehighlighting
@@ -61,20 +61,27 @@
# pass
end
end
def self.keywords
+ # (echo parent ; echo self ; sed -nE 's/<ST_IN_SCRIPTING>"((__)?[[:alpha:]_]+(__)?)".*/\1/p' zend_language_scanner.l | tr '[A-Z]' '[a-z]') | sort -u | grep -Fwv -e isset -e unset -e empty -e const -e use -e function -e namespace
+ # - isset, unset and empty are actually keywords (directly handled by PHP's lexer but let's pretend these are functions, you use them like so)
+ # - self and parent are kind of keywords, they are not handled by PHP's lexer
+ # - use, const, namespace and function are handled by specific rules to highlight what's next to the keyword
+ # - class is also listed here, in addition to the rule below, to handle anonymous classes
@keywords ||= Set.new %w(
- and E_PARSE old_function E_ERROR or as E_WARNING parent eval
- PHP_OS break exit case extends PHP_VERSION cfunction FALSE
- print for require continue foreach require_once declare return
- default static do switch die stdClass echo else TRUE elseif
- var empty if xor enddeclare include virtual endfor include_once
- while endforeach global __FILE__ endif list __LINE__ endswitch
- new __sleep endwhile not array __wakeup E_ALL NULL final
- php_user_filter interface implements public private protected
- abstract clone try catch finally throw this use namespace yield
+ old_function cfunction
+ __class__ __dir__ __file__ __function__ __halt_compiler
+ __line__ __method__ __namespace__ __trait__ abstract and
+ array as break callable case catch class clone continue
+ declare default die do echo else elseif enddeclare
+ endfor endforeach endif endswitch endwhile eval exit
+ extends final finally fn for foreach global goto if
+ implements include include_once instanceof insteadof
+ interface list new or parent print private protected
+ public require require_once return self static switch
+ throw trait try var while xor yield
)
end
def self.detect?(text)
return true if text.shebang?('php')
@@ -83,102 +90,109 @@
end
state :root do
# some extremely rough heuristics to decide whether to start inline or not
rule(/\s*(?=<)/m) { delegate parent; push :template }
- rule(/[^$]+(?=<\?(php|=))/) { delegate parent; push :template }
+ rule(/[^$]+(?=<\?(php|=))/i) { delegate parent; push :template }
rule(//) { push :template; push :php }
end
state :template do
- rule %r/<\?(php|=)?/, Comment::Preproc, :php
+ rule %r/<\?(php|=)?/i, Comment::Preproc, :php
rule(/.*?(?=<\?)|.*/m) { delegate parent }
end
state :php do
rule %r/\?>/, Comment::Preproc, :pop!
# heredocs
- rule %r/<<<('?)(#{id})\1\n.*?\n\s*\2;?/im, Str::Heredoc
+ rule %r/<<<(["']?)(#{id})\1\n.*?\n\s*\2;?/im, Str::Heredoc
rule %r/\s+/, Text
rule %r/#.*?$/, Comment::Single
rule %r(//.*?$), Comment::Single
rule %r(/\*\*(?!/).*?\*/)m, Comment::Doc
rule %r(/\*.*?\*/)m, Comment::Multiline
-
+
rule %r/(->|::)(\s*)(#{id})/ do
groups Operator, Text, Name::Attribute
end
- rule %r/[~!%^&*+=\|:.<>\/?@-]+/, Operator
+ rule %r/(void|\??(int|float|bool|string|iterable|self|callable))\b/i, Keyword::Type
+ rule %r/[~!%^&*+=\|:.<>\/@-]+/, Operator
+ rule %r/\?/, Operator
rule %r/[\[\]{}();,]/, Punctuation
- rule %r/(class|interface|trait)(\s+)(#{nsid})/ do
+ rule %r/(class|interface|trait)(\s+)(#{nsid})/i do
groups Keyword::Declaration, Text, Name::Class
end
- rule %r/(use)(\s+)(function|const|)(\s*)(#{nsid})/ do
+ rule %r/(use)(\s+)(function|const|)(\s*)(#{nsid})/i do
groups Keyword::Namespace, Text, Keyword::Namespace, Text, Name::Namespace
push :use
end
- rule %r/(namespace)(\s+)(#{nsid})/ do
+ rule %r/(namespace)(\s+)(#{nsid})/i do
groups Keyword::Namespace, Text, Name::Namespace
end
# anonymous functions
- rule %r/(function)(\s*)(?=\()/ do
+ rule %r/(function)(\s*)(?=\()/i do
groups Keyword, Text
end
# named functions
- rule %r/(function)(\s+)(&?)(\s*)/ do
+ rule %r/(function)(\s+)(&?)(\s*)/i do
groups Keyword, Text, Operator, Text
push :funcname
end
rule %r/(const)(\s+)(#{id})/i do
groups Keyword, Text, Name::Constant
end
- rule %r/(true|false|null)\b/, Keyword::Constant
+ rule %r/stdClass\b/i, Name::Class
+ rule %r/(true|false|null)\b/i, Keyword::Constant
+ rule %r/(E|PHP)(_[[:upper:]]+)+\b/, Keyword::Constant
rule %r/\$\{\$+#{id}\}/i, Name::Variable
rule %r/\$+#{id}/i, Name::Variable
+ rule %r/(yield)([ \n\r\t]+)(from)/i do
+ groups Keyword, Text, Keyword
+ end
# may be intercepted for builtin highlighting
rule %r/\\?#{nsid}/i do |m|
- name = m[0]
+ name = m[0].downcase
if self.class.keywords.include? name
token Keyword
elsif self.builtins.include? name
token Name::Builtin
else
token Name::Other
end
end
- rule %r/(\d+\.\d*|\d*\.\d+)(e[+-]?\d+)?/i, Num::Float
- rule %r/\d+e[+-]?\d+/i, Num::Float
- rule %r/0[0-7]+/, Num::Oct
- rule %r/0x[a-f0-9]+/i, Num::Hex
- rule %r/\d+/, Num::Integer
+ rule %r/(\d[_\d]*)?\.(\d[_\d]*)?(e[+-]?\d[_\d]*)?/i, Num::Float
+ rule %r/0[0-7][0-7_]*/, Num::Oct
+ rule %r/0b[01][01_]*/i, Num::Bin
+ rule %r/0x[a-f0-9][a-f0-9_]*/i, Num::Hex
+ rule %r/\d[_\d]*/, Num::Integer
rule %r/'([^'\\]*(?:\\.[^'\\]*)*)'/, Str::Single
rule %r/`([^`\\]*(?:\\.[^`\\]*)*)`/, Str::Backtick
rule %r/"/, Str::Double, :string
end
-
+
state :use do
- rule %r/(\s+)(as)(\s+)(#{id})/ do
+ rule %r/(\s+)(as)(\s+)(#{id})/i do
groups Text, Keyword, Text, Name
:pop!
end
rule %r/\\\{/, Operator, :uselist
rule %r/;/, Punctuation, :pop!
end
-
+
state :uselist do
rule %r/\s+/, Text
rule %r/,/, Operator
rule %r/\}/, Operator, :pop!
- rule %r/(as)(\s+)(#{id})/ do
+ rule %r/(as)(\s+)(#{id})/i do
groups Keyword, Text, Name
end
rule %r/#{id}/, Name::Namespace
end
@@ -187,10 +201,11 @@
end
state :string do
rule %r/"/, Str::Double, :pop!
rule %r/[^\\{$"]+/, Str::Double
- rule %r/\\([nrt\"$\\]|[0-7]{1,3}|x[0-9A-Fa-f]{1,2})/,
+ rule %r/\\u\{[0-9a-fA-F]+\}/, Str::Escape
+ rule %r/\\([efrntv\"$\\]|[0-7]{1,3}|[xX][0-9a-fA-F]{1,2})/,
Str::Escape
rule %r/\$#{id}(\[\S+\]|->#{id})?/, Name::Variable
rule %r/\{\$\{/, Str::Interpol, :interp_double
rule %r/\{(?=\$)/, Str::Interpol, :interp_single