diff --git a/PHP/PHP Source.sublime-syntax b/PHP/PHP Source.sublime-syntax
index 0853cc6fb33..e0ab8889ebb 100644
--- a/PHP/PHP Source.sublime-syntax
+++ b/PHP/PHP Source.sublime-syntax
@@ -2,6 +2,7 @@
---
name: PHP Source
hidden: true
+version: 2
scope: source.php
variables:
identifier_start: '[[:alpha:]_]'
@@ -9,6 +10,7 @@ variables:
path: '\\?({{identifier}}\\)*{{identifier}}'
regex_modifier: '[eimsuxADJSUX]*'
sql_indicator: \s*(?:SELECT|INSERT|UPDATE|DELETE|CREATE|REPLACE|ALTER)\b
+ visibility_modifier: '\b(?:var|public|private|protected)\b'
contexts:
main:
@@ -69,10 +71,10 @@ contexts:
- include: expressions
block:
- - match: '\}'
+ - match: \}
scope: punctuation.section.block.end.php
pop: true
- - match: '\{'
+ - match: \{
scope: punctuation.section.block.begin.php
push: block
- include: embedded-html
@@ -111,6 +113,7 @@ contexts:
- include: statements
expressions:
+ - include: attributes
- include: comments
- match: (?i)\b((?:require|include)(?:_once)?)\b\s*
captures:
@@ -134,7 +137,7 @@ contexts:
\b(?xi:
break | case | continue | declare | default | die | do | else |
elseif | enddeclare | endfor | endforeach | endif | endswitch | endwhile | exit |
- for | foreach | if | return | switch | use | while
+ for | foreach | if | match | return | switch | use | while
)\b
scope: keyword.control.php
- match: \b(catch)\b\s*(\()
@@ -143,6 +146,7 @@ contexts:
2: punctuation.section.group.begin.php
push:
- meta_scope: meta.catch.php
+ - include: attributes
- include: comments
- include: identifier-parts-as-path
- match: \)
@@ -327,25 +331,76 @@ contexts:
pop: true
- include: expressions
+ type-hint:
+ # https://wiki.php.net/rfc/union_types_v2
+ - match: '(?=(?:\?\s*)?{{path}})'
+ push:
+ - match: \?
+ scope: storage.type.nullable.php
+ - match: \|
+ scope: punctuation.separator.type.php
+ # note that
+ # - "callable" and "void" are not allowed in property type
+ # - "false" and "null" are only working in unioned type
+ # but we allow them as general types for simplifying syntax definition
+ - match: |-
+ \b(?xi:
+ array | bool | callable | double | float | int | iterable |
+ object | string | false | null | void | parent | self | static | mixed
+ )\b
+ scope: storage.type.php
+ - include: class-builtin
+ - include: identifier-parts-as-path
+ - match: '(\\)?({{identifier}})(?!\\)'
+ scope: meta.path.php
+ captures:
+ 1: punctuation.separator.namespace.php
+ 2: support.class.php
+ - match: ''
+ pop: true
+
+ attributes:
+ # https://wiki.php.net/rfc/attributes_v2
+ # https://wiki.php.net/rfc/attribute_amendments
+ # https://wiki.php.net/rfc/shorter_attribute_syntax
+ - match: '@@(?=[\\\w])'
+ scope: punctuation.definition.attribute.php
+ push:
+ - meta_scope: meta.attribute.php
+ - include: class-name
+ - match: \(
+ scope: punctuation.section.group.begin.php
+ set:
+ - meta_scope: meta.attribute.php meta.function-call.php meta.group.php
+ - match: \)
+ scope: meta.function-call.php meta.group.php punctuation.section.group.end.php
+ pop: true
+ - match: ','
+ scope: punctuation.separator.php
+ - include: function-call-named-parameters
+ - include: expressions
+ - match: ''
+ pop: true
+
class-builtin:
- match: |-
(?xi)(\\)?\b(
- AMQPConnection | AMQPExchange | AMQPQueue | APCIterator | AppendIterator | ArrayAccess | ArrayIterator | ArrayObject |
- BadFunctionCallException | BadMethodCallException | CachingIterator | Collator | Countable | DOMAttr | DOMCharacterData | DOMComment |
+ AMQPConnection | AMQPExchange | AMQPQueue | APCIterator | AppendIterator | ArgumentCountError | ArithmeticError | ArrayAccess | ArrayIterator | ArrayObject |
+ AssertionError | Attribute | BadFunctionCallException | BadMethodCallException | CachingIterator | Collator | CompileError | Countable | DivisionByZeroError | DOMAttr | DOMCharacterData | DOMComment |
DOMDocument | DOMDocumentFragment | DOMElement | DOMEntityReference | DOMImplementation | DOMNamedNodeMap | DOMNode | DOMNodelist |
- DOMProcessingInstruction | DOMText | DOMXPath | DateInterval | DatePeriod | DateTime | DateTimeZone | DirectoryIterator |
+ DOMProcessingInstruction | DOMText | DOMXPath | DateInterval | DatePeriod | DateTime | DateTimeImmutable | DateTimeInterface | DateTimeZone | DirectoryIterator |
DomAttribute | DomDocument | DomDocumentType | DomElement | DomNode | DomProcessingInstruction | DomXsltStylesheet | DomainException |
- EmptyIterator | ErrorException | Exception | FilesystemIterator | FilterIterator | GlobIterator | Gmagick | GmagickDraw |
+ EmptyIterator | Error | ErrorException | Exception | FilesystemIterator | FilterIterator | GlobIterator | Gmagick | GmagickDraw |
GmagickPixel | HaruAnnotation | HaruDestination | HaruDoc | HaruEncoder | HaruFont | HaruImage | HaruOutline |
HaruPage | HttpDeflateStream | HttpInflateStream | HttpMessage | HttpQueryString | HttpRequest | HttpRequestPool | HttpResponse |
- Imagick | ImagickDraw | ImagickPixel | ImagickPixelIterator | InfiniteIterator | IntlDateFormatter | InvalidArgumentException | Iterator |
+ Imagick | ImagickDraw | ImagickPixel | ImagickPixelIterator | InfiniteIterator | InternalIterator | IntlDateFormatter | InvalidArgumentException | Iterator |
IteratorAggregate | IteratorIterator | JsonException | JsonSerializable | KTaglib_ID3v2_AttachedPictureFrame | KTaglib_ID3v2_Frame | KTaglib_ID3v2_Tag | KTaglib_MPEG_AudioProperties |
KTaglib_MPEG_File | KTaglib_Tag | LengthException | LimitIterator | Locale | LogicException | Memcache | Memcached |
MessageFormatter | Mongo | MongoBinData | MongoCode | MongoCollection | MongoCursor | MongoDB | MongoDBRef |
MongoDate | MongoGridFS | MongoGridFSCursor | MongoGridFSFile | MongoGridfsFile | MongoId | MongoInt32 | MongoInt64 |
MongoRegex | MongoTimestamp | MultipleIterator | NoRewindIterator | Normalizer | NumberFormatter | OCI-Collection | OCI-Lob |
- OutOfBoundsException | OutOfRangeException | OuterIterator | OverflowException | PDO | PDOStatement | ParentIterator | Phar |
- PharData | PharFileInfo | RRDCreator | RRDGraph | RRDUpdater | RangeException | RecursiveArrayIterator | RecursiveCachingIterator |
+ OutOfBoundsException | OutOfRangeException | OuterIterator | OverflowException | PDO | PDOStatement | ParentIterator | ParseError | Phar |
+ PharData | PharFileInfo | PhpCompilerAttribute | PhpToken | RRDCreator | RRDGraph | RRDUpdater | RangeException | RecursiveArrayIterator | RecursiveCachingIterator |
RecursiveDirectoryIterator | RecursiveFilterIterator | RecursiveIterator | RecursiveIteratorIterator | RecursiveRegexIterator | RecursiveTreeIterator | Reflection | ReflectionClass |
ReflectionExtension | ReflectionFunction | ReflectionFunctionAbstract | ReflectionMethod | ReflectionObject | ReflectionParameter | ReflectionProperty | Reflector |
RegexIterator | ResourceBundle | RuntimeException | SAMConnection | SAMMessage | SCA | SCA_LocalProxy | SCA_SoapProxy |
@@ -355,11 +410,10 @@ contexts:
SeekableIterator | Serializable | SimpleXMLElement | SimpleXMLIterator | SoapClient | SoapFault | SoapHeader | SoapParam |
SoapServer | SoapVar | SphinxClient | SplBool | SplDoublyLinkedList | SplEnum | SplFileInfo | SplFileObject |
SplFixedArray | SplFloat | SplHeap | SplInt | SplMaxHeap | SplMinHeap | SplObjectStorage | SplObserver |
- SplPriorityQueue | SplQueue | SplStack | SplString | SplSubject | SplTempFileObject | Swish | SwishResult |
- SwishResults | SwishSearch | TokyoTyrant | TokyoTyrantQuery | TokyoTyrantTable | Transliterator | Traversable | UnderflowException |
- UnexpectedValueException | V8Js | V8JsException | XMLReader | XMLWriter | XSLTProcessor | ZipArchive | finfo |
- mysqli | mysqli_driver | mysqli_result | mysqli_stmt | mysqli_warning | stdClass | streamWrapper | tidy |
- tidyNode
+ SplPriorityQueue | SplQueue | SplStack | SplString | SplSubject | SplTempFileObject | Stringable | Swish | SwishResult |
+ SwishResults | SwishSearch | TokyoTyrant | TokyoTyrantQuery | TokyoTyrantTable | Transliterator | Traversable | TypeError | UnderflowException |
+ UnexpectedValueException | UnhandledMatchError | V8Js | V8JsException | ValueError | WeakMap | WeakReference | XMLReader | XMLWriter | XSLTProcessor | ZipArchive |
+ finfo | mysqli | mysqli_driver | mysqli_result | mysqli_stmt | mysqli_warning | stdClass | streamWrapper | tidy | tidyNode
)\b
captures:
1: punctuation.separator.namespace.php
@@ -384,6 +438,7 @@ contexts:
pop: true
use-statement-common:
+ - include: attributes
- include: comments
- match: (?i)\bas\b
scope: keyword.other.use-as.php
@@ -393,6 +448,7 @@ contexts:
use-statement-identifier-class-def:
- match: '(?={{path}})'
push:
+ - include: attributes
- include: comments
# We are going to assume the alias is for a class so that the identifier
# gets put into the index. This will be incorrect sometimes (because it
@@ -401,6 +457,7 @@ contexts:
- match: '(?i)\b(as)\b'
scope: keyword.other.use-as.php
push:
+ - include: attributes
- include: comments
- match: '{{identifier}}'
scope: entity.name.class.php
@@ -423,11 +480,11 @@ contexts:
- meta_content_scope: meta.use.php
- match: (?=;|$\n)
pop: true
- - match: '\{'
- scope: punctuation.section.block.php
+ - match: \{
+ scope: punctuation.section.block.begin.php
push:
- - match: '\}'
- scope: punctuation.section.block.php
+ - match: \}
+ scope: punctuation.section.block.end.php
pop: true
- include: use-statement-common
- include: use-statement-identifier-class-def
@@ -437,10 +494,12 @@ contexts:
use-statement-identifier-function-def:
- match: '(?={{path}})'
push:
+ - include: attributes
- include: comments
- match: '(?i)\b(as)\b'
scope: keyword.other.use-as.php
push:
+ - include: attributes
- include: comments
- match: '{{identifier}}'
scope: entity.name.function.php
@@ -463,11 +522,11 @@ contexts:
- meta_content_scope: meta.use.php
- match: (?=;|$\n)
pop: true
- - match: '\{'
- scope: punctuation.section.block.php
+ - match: \{
+ scope: punctuation.section.block.begin.php
push:
- - match: '\}'
- scope: punctuation.section.block.php
+ - match: \}
+ scope: punctuation.section.block.end.php
pop: true
- include: use-statement-common
- include: use-statement-identifier-function-def
@@ -478,11 +537,11 @@ contexts:
- meta_content_scope: meta.use.php
- match: (?=;|$\n)
pop: true
- - match: '\{'
- scope: punctuation.section.block.php
+ - match: \{
+ scope: punctuation.section.block.begin.php
push:
- - match: '\}'
- scope: punctuation.section.block.php
+ - match: \}
+ scope: punctuation.section.block.end.php
pop: true
- include: use-statement-common
- include: identifier-constant-pop
@@ -498,12 +557,12 @@ contexts:
push: class-definition
class-definition:
- - meta_scope: meta.class.php
- match: "(?=;)"
pop: true
- - match: '\{'
- scope: meta.block.php punctuation.section.block.php
+ - match: \{
+ scope: meta.block.php punctuation.section.block.begin.php
set: class-body
+ - include: attributes
- include: comments
- match: (?i)(extends)\b\s*
captures:
@@ -511,6 +570,7 @@ contexts:
push:
- match: '(?=implements)'
pop: true
+ - include: attributes
- include: comments
- match: '(?={{path}})'
set:
@@ -529,6 +589,7 @@ contexts:
captures:
1: storage.modifier.implements.php
push:
+ - include: attributes
- include: comments
- match: '(?={{path}})'
push:
@@ -547,10 +608,11 @@ contexts:
pop: true
class-body:
- - meta_content_scope: meta.class.php meta.block.php
+ - meta_scope: meta.class.php meta.block.php
+ - include: attributes
- include: comments
- - match: '\}'
- scope: meta.class.php meta.block.php punctuation.section.block.php
+ - match: \}
+ scope: punctuation.section.block.end.php
pop: true
- match: (?i)\b(use)\b\s*
captures:
@@ -559,13 +621,14 @@ contexts:
- meta_scope: meta.use.php
- match: (?=;|(?:^\s*$))
pop: true
- - match: '\{'
- scope: punctuation.section.block.php
+ - match: \{
+ scope: punctuation.section.block.begin.php
set:
- meta_scope: meta.use.php meta.block.php
- - match: '}'
- scope: punctuation.section.block.php
+ - match: \}
+ scope: punctuation.section.block.end.php
pop: true
+ - include: attributes
- include: comments
- match: \b(as)\b
scope: keyword.other.use-as.php
@@ -583,6 +646,7 @@ contexts:
1: punctuation.separator.namespace.php
- match: ''
pop: true
+ - include: attributes
- include: comments
- include: class-builtin
- match: (?={{path}})
@@ -600,32 +664,45 @@ contexts:
typed-property:
# https://wiki.php.net/rfc/typed_properties_v2
- - match: (?=\b(?:var|public|private|protected|static)\b)
+ - match: (?=\b(?:{{visibility_modifier}}|static)\b)
push:
- match: (?=\b(?:const|function)\b)
pop: true
- - match: \b(?:var|public|private|protected|static)\b
+ - match: \b(?:{{visibility_modifier}}|static)\b
scope: storage.modifier.php
- - match: '(?:(\?)\s*)?({{identifier}})'
- captures:
- 1: storage.type.nullable.php
- 2: support.class.php
- pop: true
+ - include: type-hint
# Exit on unexpected content
- match: (?=\S)
pop: true
function:
- - match: (?i)(?=(?:\b(?:final|abstract|var|public|private|protected|static)\s+)*\bfunction\b\s*(&\s*)?{{identifier_start}})
+ - match: (?i)(?=(?:\b(?:final|abstract|{{visibility_modifier}}|static)\s+)*\bfunction\b\s*(&\s*)?{{identifier_start}})
push:
- meta_content_scope: meta.function.php
+ - include: attributes
- include: comments
- - match: '(?i)\b(final|abstract|var|public|private|protected|static)\b'
+ - match: '(?i)\b(final|abstract|{{visibility_modifier}}|static)\b'
scope: storage.modifier.php
- match: (?i)\bfunction\b
scope: storage.type.function.php
- match: '&'
scope: storage.modifier.reference.php
+ # https://wiki.php.net/rfc/constructor_promotion
+ - match: __construct\b
+ scope: entity.name.function.php support.function.magic.php
+ push:
+ - match: (?=\()
+ set:
+ - match: \(
+ scope: punctuation.section.group.begin.php
+ set:
+ - meta_scope: meta.function.parameters.php meta.group.php
+ - match: '{{visibility_modifier}}'
+ scope: storage.modifier.php
+ - include: function-parameters
+ # Exit on unexpected content
+ - match: (?=\S)
+ pop: true
- match: '(__(?:callStatic|call|construct|destruct|get|set|isset|unset|toString|clone|set_state|sleep|wakeup|autoload|invoke|debugInfo))\b'
scope: entity.name.function.php support.function.magic.php
- match: '{{identifier}}'
@@ -668,6 +745,7 @@ contexts:
- match: '(?=;|,|\)|\s*\?>)'
pop: 2
- include: expressions
+ - include: attributes
- include: comments
- match: (?=\S)
fail: arrow-function-branch
@@ -689,18 +767,18 @@ contexts:
set: function-parameters
function-parameters:
- - meta_content_scope: meta.function.parameters.php meta.group.php
- - match: '\)'
+ - meta_scope: meta.function.parameters.php meta.group.php
+ - match: \)
scope: punctuation.section.group.end.php
set:
- - meta_content_scope: meta.function.php
+ - meta_scope: meta.function.php
- match: '\b(use)\b\s*(\()'
scope: meta.function.closure.use.php
captures:
1: keyword.other.function.use.php
2: punctuation.section.group.begin.php
set: function-use
- - match: '(?=:)'
+ - match: (?=:)
set: function-return-type
- match: \{
scope: meta.block.php punctuation.section.block.begin.php
@@ -708,16 +786,14 @@ contexts:
# Exit on unexpected content
- match: (?=\S)
pop: true
+ - include: attributes
- include: comments
- match: \b(array|callable|int|string|bool|float|object)\b
scope: storage.type.php
# Class name type hint
- - match: '{{identifier}}'
- scope: meta.path.php support.class.php
+ - include: type-hint
- match: '\.\.\.'
scope: keyword.operator.spread.php
- - match: '\?'
- scope: storage.type.nullable.php
- match: '&'
scope: storage.modifier.reference.php
- match: (\$+){{identifier}}
@@ -729,17 +805,18 @@ contexts:
- match: '='
scope: keyword.operator.assignment.php
push:
- - match: '(?=,|\))'
+ - match: (?=,|\))
pop: true
- include: expressions
function-use:
- - meta_content_scope: meta.function.closure.use.php
+ - meta_scope: meta.function.closure.use.php
+ - include: attributes
- include: comments
- - match: '\)'
+ - match: \)
scope: punctuation.section.group.end.php
set:
- - meta_content_scope: meta.function.php
+ - meta_scope: meta.function.php
- match: '(?=:)'
set: function-return-type
- match: \{
@@ -758,7 +835,7 @@ contexts:
scope: punctuation.separator.php
function-return-type:
- - meta_content_scope: meta.function.return-type.php
+ - meta_scope: meta.function.return-type.php
- match: '(?=;)'
pop: true
- match: \{
@@ -766,28 +843,18 @@ contexts:
set: function-body
- match: ':'
scope: punctuation.separator.php
- - match: '\?'
- scope: storage.type.nullable.php
- - match: \b(array|callable|int|string|bool|float|object)\b
- scope: storage.type.php
- - include: class-builtin
- - include: identifier-parts-as-path
- - match: '(\\)?({{identifier}})(?!\\)'
- scope: meta.path.php
- captures:
- 1: punctuation.separator.namespace.php
- 2: support.class.php
+ - include: type-hint
# Exit on unexpected content
- match: (?=\S)
pop: true
function-body:
- - meta_content_scope: meta.function.php meta.block.php
+ - meta_scope: meta.function.php meta.block.php
- match: \}
- scope: meta.function.php meta.block.php punctuation.section.block.end.php
+ scope: punctuation.section.block.end.php
pop: true
- include: embedded-html
- - match: '\{'
+ - match: \{
scope: punctuation.section.block.begin.php
push: block
- include: statements
@@ -951,7 +1018,7 @@ contexts:
CURLSSH_AUTH_NONE | CURLSSH_AUTH_PASSWORD | CURLSSH_AUTH_PUBLICKEY | CURLVERSION_NOW | CURL_HTTP_VERSION_1_0 | CURL_HTTP_VERSION_1_1 | CURL_HTTP_VERSION_NONE | CURL_IPRESOLVE_V4 |
CURL_IPRESOLVE_V6 | CURL_IPRESOLVE_WHATEVER | CURL_NETRC_IGNORED | CURL_NETRC_OPTIONAL | CURL_NETRC_REQUIRED | CURL_PUSH_DENY | CURL_PUSH_OK | CURL_TIMECOND_IFMODSINCE |
CURL_TIMECOND_IFUNMODSINCE | CURL_TIMECOND_LASTMOD | CURL_VERSION_IPV6 | CURL_VERSION_KERBEROS4 | CURL_VERSION_LIBZ | CURL_VERSION_SSL | DNS_A | DNS_A6 |
- DNS_AAAA | DNS_ALL | DNS_ANY | DNS_CNAME | DNS_HINFO | DNS_MX | DNS_NAPTR | DNS_NS |
+ DNS_AAAA | DNS_ALL | DNS_ANY | DNS_CAA | DNS_CNAME | DNS_HINFO | DNS_MX | DNS_NAPTR | DNS_NS |
DNS_PTR | DNS_SOA | DNS_SRV | DNS_TXT | DOMSTRING_SIZE_ERR | DOM_HIERARCHY_REQUEST_ERR | DOM_INDEX_SIZE_ERR | DOM_INUSE_ATTRIBUTE_ERR |
DOM_INVALID_ACCESS_ERR | DOM_INVALID_CHARACTER_ERR | DOM_INVALID_MODIFICATION_ERR | DOM_INVALID_STATE_ERR | DOM_NAMESPACE_ERR | DOM_NOT_FOUND_ERR | DOM_NOT_SUPPORTED_ERR | DOM_NO_DATA_ALLOWED_ERR |
DOM_NO_MODIFICATION_ALLOWED_ERR | DOM_PHP_ERR | DOM_SYNTAX_ERR | DOM_VALIDATION_ERR | DOM_WRONG_DOCUMENT_ERR | FILEINFO_CONTINUE | FILEINFO_DEVICES | FILEINFO_MIME |
@@ -961,7 +1028,7 @@ contexts:
FILTER_FLAG_ENCODE_LOW | FILTER_FLAG_HOST_REQUIRED | FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6 | FILTER_FLAG_NONE | FILTER_FLAG_NO_ENCODE_QUOTES | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE |
FILTER_FLAG_PATH_REQUIRED | FILTER_FLAG_QUERY_REQUIRED | FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_STRIP_BACKTICK | FILTER_FLAG_STRIP_HIGH | FILTER_FLAG_STRIP_LOW | FILTER_FORCE_ARRAY | FILTER_NULL_ON_FAILURE |
FILTER_REQUIRE_ARRAY | FILTER_REQUIRE_SCALAR | FILTER_SANITIZE_EMAIL | FILTER_SANITIZE_ENCODED | FILTER_SANITIZE_FULL_SPECIAL_CHARS | FILTER_SANITIZE_MAGIC_QUOTES | FILTER_SANITIZE_NUMBER_FLOAT | FILTER_SANITIZE_NUMBER_INT |
- FILTER_SANITIZE_SPECIAL_CHARS | FILTER_SANITIZE_STRING | FILTER_SANITIZE_STRIPPED | FILTER_SANITIZE_URL | FILTER_UNSAFE_RAW | FILTER_VALIDATE_BOOLEAN | FILTER_VALIDATE_EMAIL | FILTER_VALIDATE_FLOAT |
+ FILTER_SANITIZE_SPECIAL_CHARS | FILTER_SANITIZE_STRING | FILTER_SANITIZE_STRIPPED | FILTER_SANITIZE_URL | FILTER_UNSAFE_RAW | FILTER_VALIDATE_BOOL | FILTER_VALIDATE_BOOLEAN | FILTER_VALIDATE_EMAIL | FILTER_VALIDATE_FLOAT |
FILTER_VALIDATE_INT | FILTER_VALIDATE_IP | FILTER_VALIDATE_REGEXP | FILTER_VALIDATE_URL | FNM_CASEFOLD | FNM_NOESCAPE | FNM_PATHNAME | FNM_PERIOD |
FORCE_DEFLATE | FORCE_GZIP | GLOB_AVAILABLE_FLAGS | GLOB_BRACE | GLOB_ERR | GLOB_MARK | GLOB_NOCHECK | GLOB_NOESCAPE |
GLOB_NOSORT | GLOB_ONLYDIR | ICONV_IMPL | ICONV_MIME_DECODE_CONTINUE_ON_ERROR | ICONV_MIME_DECODE_STRICT | ICONV_VERSION | IMAGETYPE_BMP | IMAGETYPE_COUNT |
@@ -1029,7 +1096,7 @@ contexts:
1: punctuation.separator.namespace.php
- match: |-
(\\)?\b(?x:
- T_ABSTRACT | T_AND_EQUAL | T_ARRAY | T_ARRAY_CAST | T_AS | T_BAD_CHARACTER | T_BOOLEAN_AND | T_BOOLEAN_OR |
+ T_ABSTRACT | T_AND_EQUAL | T_ARRAY | T_ARRAY_CAST | T_AS | T_ATTRIBUTE | T_BAD_CHARACTER | T_BOOLEAN_AND | T_BOOLEAN_OR |
T_BOOL_CAST | T_BREAK | T_CASE | T_CATCH | T_CHARACTER | T_CLASS | T_CLASS_C | T_CLONE |
T_CLOSE_TAG | T_COMMENT | T_CONCAT_EQUAL | T_CONST | T_CONSTANT_ENCAPSED_STRING | T_CONTINUE | T_CURLY_OPEN | T_DEC |
T_DECLARE | T_DEFAULT | T_DIR | T_DIV_EQUAL | T_DNUMBER | T_DO | T_DOC_COMMENT | T_DOLLAR_OPEN_CURLY_BRACES |
@@ -1059,8 +1126,7 @@ contexts:
# any built-in function names should not be highlighted specially
- match: '(?={{path}}\\{{identifier}}\s*\()'
push:
- - meta_scope: meta.function-call.php
- - meta_content_scope: meta.path.php
+ - meta_scope: meta.function-call.php meta.path.php
- include: identifier-parts
- match: '{{identifier}}(?=\s*\()'
scope: variable.function.php
@@ -1091,18 +1157,27 @@ contexts:
- match: '{{identifier}}'
scope: variable.function.php
function-call-parameters:
- - match: \s*(\()
- scope: meta.function-call.php
- captures:
- 1: meta.group.php punctuation.section.group.begin.php
+ - match: \(
+ scope: punctuation.section.group.begin.php
set:
- - meta_content_scope: meta.function-call.php meta.group.php
+ - meta_scope: meta.function-call.php meta.group.php
- match: \)
- scope: meta.function-call.php meta.group.php punctuation.section.group.end.php
+ scope: punctuation.section.group.end.php
set: after-function-call
- match: ','
scope: punctuation.separator.php
+ - include: function-call-named-parameters
- include: expressions
+ function-call-named-parameters:
+ # https://wiki.php.net/rfc/named_params
+ - match: ({{identifier}})\s*(:)(?!:)
+ captures:
+ 1: variable.parameter.named.php
+ 2: punctuation.definition.variable.php
+ push:
+ - include: expressions
+ - match: ''
+ pop: true
heredoc:
- match: (?=<<<\s*'?({{identifier}})'?\s*$)
push:
@@ -1309,24 +1384,25 @@ contexts:
(?=
\${{identifier}}
(?:
- ->{{identifier}}
+ \??->{{identifier}}
|
\[ ( \d+ | \$?{{identifier}} ) \]
)
)
)
push:
- - match: (->)({{identifier}})
+ - match: (\??)(->)({{identifier}})
captures:
- 1: punctuation.accessor.arrow.php
- 2: variable.other.member.php
+ 1: punctuation.accessor.nullsafe.php
+ 2: punctuation.accessor.arrow.php
+ 3: variable.other.member.php
pop: true
- match: '\['
- scope: meta.item-access.php punctuation.section.brackets.begin.php
+ scope: punctuation.section.brackets.begin.php
set:
- - meta_content_scope: meta.item-access.arguments.php
+ - meta_scope: meta.item-access.arguments.php
- match: '\]'
- scope: meta.item-access.php punctuation.section.brackets.end.php
+ scope: punctuation.section.brackets.end.php
pop: true
- include: numbers
- include: variables
@@ -1369,28 +1445,31 @@ contexts:
- match: '\b(?!_)(?:\d|_(?!_))+\b'
scope: constant.numeric.integer.decimal.php
object:
- - match: '(->)(\$?\{)'
+ - match: (\??)(->)(\$?\{)
captures:
- 1: punctuation.accessor.arrow.php
- 2: punctuation.definition.variable.php
+ 1: punctuation.accessor.nullsafe.php
+ 2: punctuation.accessor.arrow.php
+ 3: punctuation.definition.variable.php
push:
- match: '(\})'
captures:
1: punctuation.definition.variable.php
set: after-identifier
- include: expressions
- - match: (->)({{identifier}})(?=\s*\()
+ - match: (\??)(->)({{identifier}})(?=\s*\()
scope: meta.function-call.method.php
captures:
- 1: punctuation.accessor.arrow.php
- 2: variable.function.php
+ 1: punctuation.accessor.nullsafe.php
+ 2: punctuation.accessor.arrow.php
+ 3: variable.function.php
push: function-call-parameters
- include: function-call-static
- - match: (->)((\$+)?{{identifier}})?
+ - match: (\??)(->)((\$+)?{{identifier}})?
captures:
- 1: punctuation.accessor.arrow.php
- 2: variable.other.member.php
- 3: punctuation.definition.variable.php
+ 1: punctuation.accessor.nullsafe.php
+ 2: punctuation.accessor.arrow.php
+ 3: variable.other.member.php
+ 4: punctuation.definition.variable.php
push: after-identifier
- match: '(::)({{identifier}})?'
captures:
@@ -1439,7 +1518,7 @@ contexts:
- match: \*/
scope: punctuation.definition.comment.end.php
pop: true
- - match: ^\s*(\*)\s*(@access)\s+((var|public|private|protected)|(.+))\s*$
+ - match: ^\s*(\*)\s*(@access)\s+(({{visibility_modifier}})|(.+))\s*$
captures:
1: punctuation.definition.comment.php
2: keyword.other.phpdoc.php
@@ -1923,7 +2002,7 @@ contexts:
\b(?xi:
abs | acos | acosh | asin | asinh | atan | atan2 | atanh |
base_convert | bindec | ceil | cos | cosh | decbin | dechex | decoct |
- deg2rad | exp | expm1 | floor | fmod | getrandmax | hexdec | hypot |
+ deg2rad | exp | expm1 | fdiv | floor | fmod | getrandmax | hexdec | hypot |
intdiv | is_finite | is_infinite | is_nan | lcg_value | log | log10 | log1p |
max | min | mt_getrandmax | mt_rand | mt_srand | octdec | pi | pow |
rad2deg | rand | round | sin | sinh | sqrt | srand | tan |
@@ -2276,8 +2355,8 @@ contexts:
lcfirst | levenshtein | localeconv | ltrim | md5 | md5_file | metaphone | money_format |
nl2br | nl_langinfo | number_format | ord | parse_str | print | printf | quoted_printable_decode |
quoted_printable_encode | quotemeta | rtrim | setlocale | sha1 | sha1_file | similar_text | soundex |
- sprintf | sscanf | str_getcsv | str_ireplace | str_pad | str_repeat | str_replace | str_rot13 |
- str_shuffle | str_split | str_word_count | strcasecmp | strchr | strcmp | strcoll | strcspn |
+ sprintf | sscanf | str_contains | str_ends_with | str_getcsv | str_ireplace | str_pad | str_repeat | str_replace | str_rot13 |
+ str_shuffle | str_split | str_starts_with | str_word_count | strcasecmp | strchr | strcmp | strcoll | strcspn |
strip_tags | stripcslashes | stripos | stripslashes | stristr | strlen | strnatcasecmp | strnatcmp |
strncasecmp | strncmp | strpbrk | strpos | strrchr | strrev | strripos | strrpos |
strspn | strstr | strtok | strtolower | strtoupper | strtr | substr | substr_compare |
@@ -2314,7 +2393,7 @@ contexts:
scope: support.function.url.php
- match: |-
\b(?xi:
- boolval | debug_zval_dump | doubleval | empty | floatval | get_defined_vars | get_resource_type | gettype |
+ boolval | debug_zval_dump | doubleval | empty | floatval | get_debug_type | get_defined_vars | get_resource_id | get_resource_type | gettype |
import_request_variables | intval | is_array | is_bool | is_callable | is_countable | is_double | is_float |
is_int | is_integer | is_iterable | is_long | is_null | is_numeric | is_object | is_real |
is_resource | is_scalar | is_string | isset | print_r | serialize | settype | strval |
diff --git a/PHP/PHP.sublime-completions b/PHP/PHP.sublime-completions
index d3f930383ac..0ddd2a29a01 100644
--- a/PHP/PHP.sublime-completions
+++ b/PHP/PHP.sublime-completions
@@ -4991,6 +4991,12 @@
"kind": "function",
"details": "Sets version number for a FDF file"
},
+ {
+ "trigger": "fdiv()",
+ "contents": "fdiv(${1:dividend}, ${2:divisor})",
+ "kind": "function",
+ "details": "Float division."
+ },
{
"trigger": "feof()",
"contents": "feof(${1:handle})",
@@ -5746,6 +5752,12 @@
"kind": "function",
"details": "Gets the name of the owner of the current PHP script"
},
+ {
+ "trigger": "get_debug_type()",
+ "contents": "get_debug_type(${1:variable})",
+ "kind": "function",
+ "details": "Gets the debug type (type hint) of a variable."
+ },
{
"trigger": "get_declared_classes()",
"contents": "get_declared_classes()",
@@ -5848,6 +5860,12 @@
"kind": "function",
"details": "Alias of get_included_files()"
},
+ {
+ "trigger": "get_resource_id()",
+ "contents": "get_resource_id(${1:handle})",
+ "kind": "function",
+ "details": "Get the resource ID."
+ },
{
"trigger": "get_resource_type()",
"contents": "get_resource_type(${1:handle})",
@@ -21197,6 +21215,18 @@
"kind": "function",
"details": "Gets the current stomp extension version"
},
+ {
+ "trigger": "str_contains()",
+ "contents": "str_contains(${1:haystack}, ${2:needle})",
+ "kind": "function",
+ "details": "Checks if a string is contained in another string."
+ },
+ {
+ "trigger": "str_ends_with()",
+ "contents": "str_ends_with(${1:haystack}, ${2:needle})",
+ "kind": "function",
+ "details": "Checks if a string is ended with another string."
+ },
{
"trigger": "str_getcsv()",
"contents": "str_getcsv(${1:input})",
@@ -21245,6 +21275,12 @@
"kind": "function",
"details": "Convert a string to an array"
},
+ {
+ "trigger": "str_starts_with()",
+ "contents": "str_starts_with(${1:haystack}, ${2:needle})",
+ "kind": "function",
+ "details": "Checks if a string is started with another string."
+ },
{
"trigger": "str_word_count()",
"contents": "str_word_count(${1:string})",
diff --git a/PHP/PHP.sublime-syntax b/PHP/PHP.sublime-syntax
index 46e8d14c2cf..3c9ad5096ce 100644
--- a/PHP/PHP.sublime-syntax
+++ b/PHP/PHP.sublime-syntax
@@ -1,6 +1,7 @@
%YAML 1.2
---
name: PHP
+version: 2
file_extensions:
- php
- php3
diff --git a/PHP/Snippets/fn(-).sublime-snippet b/PHP/Snippets/fn(-).sublime-snippet
new file mode 100644
index 00000000000..48fa6a54818
--- /dev/null
+++ b/PHP/Snippets/fn(-).sublime-snippet
@@ -0,0 +1,7 @@
+
+
+ $0]]>
+ fn
+ source.php - string - comment
+ fn …
+
diff --git a/PHP/Snippets/match{-}.sublime-snippet b/PHP/Snippets/match{-}.sublime-snippet
new file mode 100644
index 00000000000..a71e30e49f8
--- /dev/null
+++ b/PHP/Snippets/match{-}.sublime-snippet
@@ -0,0 +1,10 @@
+
+
+ ${3:to},$5
+ default => ${4:null},
+}$0]]>
+ match
+ source.php - string - comment
+ match …
+
diff --git a/PHP/tests/syntax_test_php.php b/PHP/tests/syntax_test_php.php
index 6dae1bf02f6..444e5c60e12 100644
--- a/PHP/tests/syntax_test_php.php
+++ b/PHP/tests/syntax_test_php.php
@@ -102,7 +102,7 @@
// ^ punctuation.separator.namespace
// ^^^^^^ support.other.namespace
// ^ punctuation.separator.namespace
-// ^ punctuation.section.block
+// ^ punctuation.section.block.begin
// ^^^^^^ support.class.php - constant.other - entity.name - support.function.php - support.other.namespace
// ^ punctuation.separator
// ^^^^^^ support.class.php - constant.other - entity.name - support.function.php - support.other.namespace
@@ -110,7 +110,7 @@
// ^^^^^^ support.class.php - constant.other - entity.name - support.function.php - support.other.namespace
// ^^ keyword.other.use-as
// ^ entity.name.class
-// ^ punctuation.section.block
+// ^ punctuation.section.block.end
// ^ punctuation.terminator.expression.php - meta.use
use function some\nspace\{fn_d, fn_e, fn_f as fn_g};
@@ -122,7 +122,7 @@
// ^ punctuation.separator.namespace
// ^^^^^^ support.other.namespace
// ^ punctuation.separator.namespace
-// ^ punctuation.section.block
+// ^ punctuation.section.block.begin
// ^^^^ support.function.php - constant.other - entity.name - support.class.php - support.other.namespace
// ^ punctuation.separator
// ^^^^ support.function.php - constant.other - entity.name - support.class.php - support.other.namespace
@@ -130,7 +130,7 @@
// ^^^^ support.function.php - constant.other - entity.name - support.class.php - support.other.namespace
// ^^ keyword.other.use-as
// ^^^^ entity.name.function
-// ^ punctuation.section.block
+// ^ punctuation.section.block.end
// ^ punctuation.terminator.expression.php - meta.use
@@ -143,7 +143,7 @@
// ^ punctuation.separator.namespace
// ^^^^^^ support.other.namespace
// ^ punctuation.separator.namespace
-// ^ punctuation.section.block
+// ^ punctuation.section.block.begin
// ^^^^^^ constant.other - support.function.php - entity.name - support.class.php - support.other.namespace
// ^ punctuation.separator
// ^^^^^^ constant.other - support.function.php - entity.name - support.class.php - support.other.namespace
@@ -151,7 +151,7 @@
// ^^^^^^ constant.other - support.function.php - entity.name - support.class.php - support.other.namespace
// ^ punctuation.separator
// ^^^^^^ constant.other - support.function.php - entity.name - support.class.php - support.other.namespace
-// ^ punctuation.section.block
+// ^ punctuation.section.block.end
// ^ punctuation.terminator.expression.php - meta.use
@@ -265,10 +265,137 @@ function foo(?stinrg ...$args) {}
// ^ punctuation.section.brackets.begin.php
// ^ punctuation.section.brackets.end.php
-$var->meth()[10];
-// ^^^^ meta.item-access
-// ^ punctuation.section.brackets.begin.php
-// ^ punctuation.section.brackets.end.php
+$var?->meth()[10];
+// ^ punctuation.accessor.nullsafe
+// ^^ punctuation.accessor.arrow
+// ^^^^ meta.item-access
+// ^ punctuation.section.brackets.begin
+// ^ punctuation.section.brackets.end
+
+@@@@@@@@@@ExampleAttribute
+// <- keyword.operator.error-control
+//^^^^^^ keyword.operator.error-control
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^^ meta.path
+@@WithoutArgument
+//^^^^^^^^^^^^^^^ meta.attribute
+// <- punctuation.definition.attribute
+// ^^^^^^^^^^^^^^ meta.path
+@@WithoutArgument()
+//^^^^^^^^^^^^^^^^^ meta.attribute
+// <- punctuation.definition.attribute
+// ^^^^^^^^^^^^^^ meta.path
+@@SingleArgument(0)
+//^^^^^^^^^^^^^^^^^ meta.attribute
+// <- punctuation.definition.attribute
+// ^^^^^^^^^^^^^ meta.path
+@@FewArguments('Hello', 'World')
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute
+// <- punctuation.definition.attribute
+// ^^^^^^^^^^^ meta.path
+// ^^^^^^^ string.quoted
+// ^^^^^^^ string.quoted
+@@FewArguments(PDO::class, PHP_VERSION_ID)
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute
+// <- punctuation.definition.attribute
+// ^^^^^^^^^^^ meta.path
+// ^^^ support.class
+// ^^ punctuation.accessor
+// ^^^^^^^^^^^^^^ support.constant
+@@\My\Attributes\FewArguments("foo", "bar")
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute
+// <- punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.path
+// ^^^^^ string.quoted
+// ^^^^^ string.quoted
+/** docblock */
+// <- comment.block
+@@BitShiftExample(4 >> 1, 4 << 1)
+//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute
+// <- punctuation.definition.attribute
+// ^^ keyword.operator.bitwise
+// ^^ keyword.operator.bitwise
+function foo() {}
+// <- storage.type.function
+
+@@JoinTable(
+//^^^^^^^^^^ meta.attribute
+// <- punctuation.definition.attribute
+//^^^^^^^^^ support.class
+ "User_Group",
+// ^^^^^^^^^^^^ string.quoted.double
+ @@JoinColumn("User_id", "id"),
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^ support.class
+ @@JoinColumn("Group_id", "id"),
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^ support.class
+)
+// <- meta.attribute
+// ^ - meta.attribute
+function foo() {}
+// <- storage.type.function
+
+@@ExampleAttribute
+//^^^^^^^^^^^^^^^^ meta.attribute
+// <- punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^ meta.path
+class Foo
+{
+ @@ExampleAttribute
+// ^^^^^^^^^^^^^^^^^^ meta.attribute
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^^ meta.path
+ public const FOO = 'foo';
+
+ @@ExampleAttribute
+// ^^^^^^^^^^^^^^^^^^ meta.attribute
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^^ meta.path
+ public $x;
+
+ @@ExampleAttribute // comment
+// ^^^^^^^^^^^^^^^^^^ meta.attribute
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^^ meta.path
+// ^^^^^^^^^^ comment
+ public function foo(@@ExampleAttribute \Foo\Bar $bar) { }
+// ^^^^^^^^^^^^^^^^^^ meta.attribute
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^^ meta.path
+// ^^^^^^^^ meta.path
+// ^^^^ variable.parameter
+
+ @@Route("/api/posts/{id}", methods: ["GET", "HEAD"])
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.attribute
+// ^^ punctuation.definition.attribute
+// ^^^^^ meta.path
+// ^ punctuation.section.group.begin
+// ^ punctuation.separator
+// ^^^^^^^ variable.parameter.named
+// ^ punctuation.definition.variable
+// ^ punctuation.section.group.end
+ public function show(int $id) { }
+}
+
+$object = new @@ExampleAttribute class () { };
+// ^^^^^^^^^^^^^^^^^^ meta.attribute
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^^ meta.path
+// ^^^^^ storage.type
+
+$f2 = @@ExampleAttribute function () { };
+// ^^^^^^^^^^^^^^^^^^ meta.attribute
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^^ meta.path
+// ^^^^^^^^ storage.type
+
+$f3 = @@ExampleAttribute fn () => 1;
+// ^^^^^^^^^^^^^^^^^^ meta.attribute
+// ^^ punctuation.definition.attribute
+// ^^^^^^^^^^^^^^^^ meta.path
+// ^^ storage.type
+// ^^ punctuation.definition.arrow-function
/**
No longer a phpdoc comment since no leading *
@@ -610,6 +737,16 @@ class ClassName extends /* */ \MyNamespace\Foo implements \MyNamespace\Baz {
// ^^^^^^^^^^^^^^^^ entity.other.inherited-class
// ^ punctuation.separator.namespace
// ^ punctuation.separator.namespace
+
+ public function __construct(private \MyNamespace\Foo $val = DEFAULT_VALUE) {
+// ^^^^^^^^^^^ entity.name.function support.function.magic
+// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ meta.function.parameters
+// ^^^^^^^ storage.modifier
+// ^^^^^^^^^^^^^^^^ meta.path
+// ^^^^ variable.parameter
+// ^ keyword.operator.assignment
+// ^^^^^^^^^^^^^ constant.other
+ }
}
interface MyInter {}
@@ -707,17 +844,35 @@ interface MyInter2 extends \MyNamespace\Foo {
// ^^^^^^^^^ variable.function
// ^^ meta.group meta.group
-$object->property::method();
-// ^^ punctuation.accessor.arrow
-// ^^ punctuation.accessor.double-colon
-// ^^^^^^ meta.function-call.static variable.function
-// ^^ meta.group
+$object?->property::method();
+// ^ punctuation.accessor.nullsafe
+// ^^ punctuation.accessor.arrow
+// ^^ punctuation.accessor.double-colon
+// ^^^^^^ meta.function-call.static variable.function
+// ^^ meta.group
+
+$country = $session?->user?->getAddress()?->country;
+// ^ punctuation.accessor.nullsafe
+// ^^ punctuation.accessor.arrow
+// ^ punctuation.accessor.nullsafe
+// ^^ punctuation.accessor.arrow
+// ^ punctuation.accessor.nullsafe
+// ^^ punctuation.accessor.arrow
+
+null?->foo(bar())->baz();
+// ^ punctuation.accessor.nullsafe
+// ^^ punctuation.accessor.arrow
strval($foo);
//^^^^^^^^^^ meta.function-call
//^^^^ support.function.var - variable.function
// ^^^^^^ meta.group
+array_slice($array, $offset, $length, preserve_keys: true);
+// ^^^^^^^^^^^^^ variable.parameter.named
+// ^ punctuation.definition.variable
+// ^^^^ constant.language
+
$test = new Test1;
// ^ keyword.other.new.php
// ^^^^^ meta.path
@@ -728,8 +883,8 @@ interface MyInter2 extends \MyNamespace\Foo {
// ^ storage.type.class.php
// ^^ meta.class.php
// ^^ meta.block.php
-// ^ punctuation.section.block.php - meta.class meta.class
-// ^ punctuation.section.block.php
+// ^ punctuation.section.block.begin.php - meta.class meta.class
+// ^ punctuation.section.block.end.php
$anon = new class($param1, $param2) extends Test1 implements Countable {};
// ^ keyword.other.new.php
@@ -798,6 +953,53 @@ function nullableObjectReturnType(?int $param1): ?object {}
// ^ storage.type.nullable.php
// ^ storage.type.php
+ function unionTypeFunction(
+// ^ storage.type.function.php
+// ^ entity.name.function.php
+ Foo|\Foo\Bar|?int $param1,
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ punctuation.separator.namespace
+// ^^^ support.other.namespace
+// ^ punctuation.separator.namespace
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ storage.type.nullable
+// ^^^ storage.type
+// ^ punctuation.definition.variable
+// ^^^^^^ variable.parameter
+ Foo|\Foo\Bar|?int $param2,
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ punctuation.separator.namespace
+// ^^^ support.other.namespace
+// ^ punctuation.separator.namespace
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ storage.type.nullable
+// ^^^ storage.type
+// ^ punctuation.definition.variable
+// ^^^^^^ variable.parameter
+ string $param3,
+// ^^^^^^ storage.type
+// ^ punctuation.definition.variable
+// ^^^^^^ variable.parameter
+ $param4
+// ^ punctuation.definition.variable
+// ^^^^^^ variable.parameter
+ ): Foo|\Foo\Bar|?int|static {}
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ punctuation.separator.namespace
+// ^^^ support.other.namespace
+// ^ punctuation.separator.namespace
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ storage.type.nullable
+// ^^^ storage.type
+// ^ punctuation.separator.type
+// ^^^^^^ storage.type
+
$test = "\0 \12 \345g \x0f \u{a} \u{9999} \u{999}";
// ^^ constant.character.escape.octal.php
// ^^^ constant.character.escape.octal.php
@@ -917,7 +1119,7 @@ class B
Z {
// ^^^ meta.use
// ^ meta.path
-// ^ meta.block punctuation.section.block
+// ^ meta.block punctuation.section.block.begin
X::method1 as another1;
// ^^^^^^^^^^^^^^^^^^^^^^^ meta.use meta.block
// ^^ punctuation.accessor
@@ -927,18 +1129,25 @@ class B
X::method2 as another2;
// ^ keyword.other.use-as
} protected $pro1;
-// ^ meta.use meta.block punctuation.section.block
+// ^ meta.use meta.block punctuation.section.block.end
// ^ - meta.use
// ^ storage.modifier
- public static ?Foo $str = '';
+ public static ?Foo|\My\Bar|int $str = '';
// ^^^^^^ storage.modifier
// ^^^^^^ storage.modifier
// ^ storage.type.nullable
// ^^^ support.class
-// ^ punctuation.definition.variable
-// ^^^ variable.other
-// ^ keyword.operator.assignment
+// ^ punctuation.separator.type
+// ^ punctuation.separator.namespace
+// ^^ support.other.namespace
+// ^ punctuation.separator.namespace
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^^^ storage.type
+// ^ punctuation.definition.variable
+// ^^^ variable.other
+// ^ keyword.operator.assignment
public const STR_1 = '';
// ^^^^^^ storage.modifier
@@ -951,11 +1160,56 @@ class B
// ^^^^^ constant
// ^ keyword.operator.assignment
- public function abc(callable $var, int $var2, string $var3)
-// ^^^ entity.name.function
-// ^ storage.type
-// ^ storage.type
-// ^ storage.type
+ public function abc(
+// ^ storage.type.function.php
+// ^ entity.name.function.php
+ Foo|\Foo\Bar|?int $param1,
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ punctuation.separator.namespace
+// ^^^ support.other.namespace
+// ^ punctuation.separator.namespace
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ storage.type.nullable
+// ^^^ storage.type
+// ^ punctuation.definition.variable
+// ^^^^^^ variable.parameter
+ Foo|\Foo\Bar|?int $param2,
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ punctuation.separator.namespace
+// ^^^ support.other.namespace
+// ^ punctuation.separator.namespace
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ storage.type.nullable
+// ^^^ storage.type
+// ^ punctuation.definition.variable
+// ^^^^^^ variable.parameter
+ callable $param3,
+// ^^^^^^^^ storage.type
+// ^ punctuation.definition.variable
+// ^^^^^^ variable.parameter
+ mixed $param3,
+// ^^^^^ storage.type
+// ^ punctuation.definition.variable
+// ^^^^^^ variable.parameter
+ $param4
+// ^ punctuation.definition.variable
+// ^^^^^^ variable.parameter
+ ): Foo|\Foo\Bar|?int|static {}
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ punctuation.separator.namespace
+// ^^^ support.other.namespace
+// ^ punctuation.separator.namespace
+// ^^^ support.class
+// ^ punctuation.separator.type
+// ^ storage.type.nullable
+// ^^^ storage.type
+// ^ punctuation.separator.type
+// ^^^^^^ storage.type
{
echo B::class;
// ^ constant.class
@@ -1204,6 +1458,24 @@ function generate2()
//^^^^^^^ keyword.control.php - entity.name.label.php
}
+$statement = match ($this->lexer->lookahead['type']) {
+// ^^^^^ keyword.control
+ Lexer::T_UPDATE => $this->UpdateStatement(),
+// ^^^^^ support.class
+// ^^ punctuation.accessor.double-colon
+// ^^^^^^^^ constant.other.class
+// ^^ keyword.operator.key
+// ^^^^^ variable.language
+// ^^ punctuation.accessor.arrow
+// ^^^^^^^^^^^^^^^ variable.function
+// ^^ meta.group
+ Lexer::T_DELETE => $this->DeleteStatement(),
+// ^^ keyword.operator.key
+ default => $this->syntaxError('UPDATE or DELETE'),
+// ^^^^^^^ keyword.control
+// ^^ keyword.operator.key
+};
+
$non_sql = "NO SELECT HIGHLIGHTING!";
// ^ string.quoted.double punctuation.definition.string.begin - meta.string-contents
// ^^^^^^^^^^^^^^^^^^^^^^^ meta.string-contents