Skip to content

PHP 7.4: tokenizing of typed properties #2413

@jrfnl

Description

@jrfnl

PHP 7.4 will contain the ability to declare typed properties. This RFC has already been implemented in the PHP 7.4 branch.

At this moment, these type declarations will tokenize as T_STRING with a potential nullable indicator tokenizing as T_INLINE_THEN.

I'm opening this issue to open the discussion on whether these type declarations need their own token in PHPCS and if so, what that token should be.

As for the nullable indicator, I would find it logical to adjust the tokenizer to tokenize those as T_NULLABLE, same as within function declaration statements.

Once it's clear how property type declarations will be tokenized, I foresee that the following additional changes will need to be made:

  • Adjust the File::getMemberProperties() method.
  • Adjust property docblock sniffs to allow finding the docblock of typed properties.
  • Check that other sniffs which deal with properties handle typed properties correctly by adding unit tests and if necessary, adjusting the code within the sniff.

Typed properties example code (example taken from the RFC):

class Example {
    // All types with the exception of "void" and "callable" are supported
    public int $scalarType;
    protected ClassName $classType;
    private ?ClassName $nullableClassType;
 
    // Types are also legal on static properties
    public static iterable $staticProp;
 
    // Types can also be used with the "var" notation
    var bool $flag;
 
    // Typed properties may have default values (more below)
    public string $str = "foo";
    public ?string $nullableStr = null;
 
    // The type applies to all properties in one declaration
    public float $x, $y;
    // equivalent to:
    public float $x;
    public float $y;
}

Token representation of the above example based on the current tokenization:
0 :: L001 :: C1 :: T_OPEN_TAG :: (5) :: <?php

1 :: L002 :: C1 :: T_WHITESPACE :: (0) ::

2 :: L003 :: C1 :: T_CLASS :: (5) :: class
3 :: L003 :: C6 :: T_WHITESPACE :: (1) ::
4 :: L003 :: C7 :: T_STRING :: (7) :: Example
5 :: L003 :: C14 :: T_WHITESPACE :: (1) ::
6 :: L003 :: C15 :: T_OPEN_CURLY_BRACKET :: (1) :: {
7 :: L003 :: C16 :: T_WHITESPACE :: (0) ::

8 :: L004 :: C1 :: T_WHITESPACE :: (4) ::
9 :: L004 :: C5 :: T_COMMENT :: (70) :: // All types with the exception of "void" and "callable" are supported

10 :: L005 :: C1 :: T_WHITESPACE :: (4) ::
11 :: L005 :: C5 :: T_PUBLIC :: (6) :: public
12 :: L005 :: C11 :: T_WHITESPACE :: (1) ::
13 :: L005 :: C12 :: T_STRING :: (3) :: int
14 :: L005 :: C15 :: T_WHITESPACE :: (1) ::
15 :: L005 :: C16 :: T_VARIABLE :: (11) :: $scalarType
16 :: L005 :: C27 :: T_SEMICOLON :: (1) :: ;
17 :: L005 :: C28 :: T_WHITESPACE :: (0) ::

18 :: L006 :: C1 :: T_WHITESPACE :: (4) ::
19 :: L006 :: C5 :: T_PROTECTED :: (9) :: protected
20 :: L006 :: C14 :: T_WHITESPACE :: (1) ::
21 :: L006 :: C15 :: T_STRING :: (9) :: ClassName
22 :: L006 :: C24 :: T_WHITESPACE :: (1) ::
23 :: L006 :: C25 :: T_VARIABLE :: (10) :: $classType
24 :: L006 :: C35 :: T_SEMICOLON :: (1) :: ;
25 :: L006 :: C36 :: T_WHITESPACE :: (0) ::

26 :: L007 :: C1 :: T_WHITESPACE :: (4) ::
27 :: L007 :: C5 :: T_PRIVATE :: (7) :: private
28 :: L007 :: C12 :: T_WHITESPACE :: (1) ::
29 :: L007 :: C13 :: T_INLINE_THEN :: (1) :: ?
30 :: L007 :: C14 :: T_STRING :: (9) :: ClassName
31 :: L007 :: C23 :: T_WHITESPACE :: (1) ::
32 :: L007 :: C24 :: T_VARIABLE :: (18) :: $nullableClassType
33 :: L007 :: C42 :: T_SEMICOLON :: (1) :: ;
34 :: L007 :: C43 :: T_WHITESPACE :: (0) ::

35 :: L008 :: C1 :: T_WHITESPACE :: (1) ::

36 :: L009 :: C1 :: T_WHITESPACE :: (4) ::
37 :: L009 :: C5 :: T_COMMENT :: (44) :: // Types are also legal on static properties

38 :: L010 :: C1 :: T_WHITESPACE :: (4) ::
39 :: L010 :: C5 :: T_PUBLIC :: (6) :: public
40 :: L010 :: C11 :: T_WHITESPACE :: (1) ::
41 :: L010 :: C12 :: T_STATIC :: (6) :: static
42 :: L010 :: C18 :: T_WHITESPACE :: (1) ::
43 :: L010 :: C19 :: T_STRING :: (8) :: iterable
44 :: L010 :: C27 :: T_WHITESPACE :: (1) ::
45 :: L010 :: C28 :: T_VARIABLE :: (11) :: $staticProp
46 :: L010 :: C39 :: T_SEMICOLON :: (1) :: ;
47 :: L010 :: C40 :: T_WHITESPACE :: (0) ::

48 :: L011 :: C1 :: T_WHITESPACE :: (1) ::

49 :: L012 :: C1 :: T_WHITESPACE :: (4) ::
50 :: L012 :: C5 :: T_COMMENT :: (49) :: // Types can also be used with the "var" notation

51 :: L013 :: C1 :: T_WHITESPACE :: (4) ::
52 :: L013 :: C5 :: T_VAR :: (3) :: var
53 :: L013 :: C8 :: T_WHITESPACE :: (1) ::
54 :: L013 :: C9 :: T_STRING :: (4) :: bool
55 :: L013 :: C13 :: T_WHITESPACE :: (1) ::
56 :: L013 :: C14 :: T_VARIABLE :: (5) :: $flag
57 :: L013 :: C19 :: T_SEMICOLON :: (1) :: ;
58 :: L013 :: C20 :: T_WHITESPACE :: (0) ::

59 :: L014 :: C1 :: T_WHITESPACE :: (1) ::

60 :: L015 :: C1 :: T_WHITESPACE :: (4) ::
61 :: L015 :: C5 :: T_COMMENT :: (56) :: // Typed properties may have default values (more below)

62 :: L016 :: C1 :: T_WHITESPACE :: (4) ::
63 :: L016 :: C5 :: T_PUBLIC :: (6) :: public
64 :: L016 :: C11 :: T_WHITESPACE :: (1) ::
65 :: L016 :: C12 :: T_STRING :: (6) :: string
66 :: L016 :: C18 :: T_WHITESPACE :: (1) ::
67 :: L016 :: C19 :: T_VARIABLE :: (4) :: $str
68 :: L016 :: C23 :: T_WHITESPACE :: (1) ::
69 :: L016 :: C24 :: T_EQUAL :: (1) :: =
70 :: L016 :: C25 :: T_WHITESPACE :: (1) ::
71 :: L016 :: C26 :: T_CONSTANT_ENCAPSED_STRING :: (5) :: "foo"
72 :: L016 :: C31 :: T_SEMICOLON :: (1) :: ;
73 :: L016 :: C32 :: T_WHITESPACE :: (0) ::

74 :: L017 :: C1 :: T_WHITESPACE :: (4) ::
75 :: L017 :: C5 :: T_PUBLIC :: (6) :: public
76 :: L017 :: C11 :: T_WHITESPACE :: (1) ::
77 :: L017 :: C12 :: T_INLINE_THEN :: (1) :: ?
78 :: L017 :: C13 :: T_STRING :: (6) :: string
79 :: L017 :: C19 :: T_WHITESPACE :: (1) ::
80 :: L017 :: C20 :: T_VARIABLE :: (12) :: $nullableStr
81 :: L017 :: C32 :: T_WHITESPACE :: (1) ::
82 :: L017 :: C33 :: T_EQUAL :: (1) :: =
83 :: L017 :: C34 :: T_WHITESPACE :: (1) ::
84 :: L017 :: C35 :: T_NULL :: (4) :: null
85 :: L017 :: C39 :: T_SEMICOLON :: (1) :: ;
86 :: L017 :: C40 :: T_WHITESPACE :: (0) ::

87 :: L018 :: C1 :: T_WHITESPACE :: (1) ::

88 :: L019 :: C1 :: T_WHITESPACE :: (4) ::
89 :: L019 :: C5 :: T_COMMENT :: (56) :: // The type applies to all properties in one declaration

90 :: L020 :: C1 :: T_WHITESPACE :: (4) ::
91 :: L020 :: C5 :: T_PUBLIC :: (6) :: public
92 :: L020 :: C11 :: T_WHITESPACE :: (1) ::
93 :: L020 :: C12 :: T_STRING :: (5) :: float
94 :: L020 :: C17 :: T_WHITESPACE :: (1) ::
95 :: L020 :: C18 :: T_VARIABLE :: (2) :: $x
96 :: L020 :: C20 :: T_COMMA :: (1) :: ,
97 :: L020 :: C21 :: T_WHITESPACE :: (1) ::
98 :: L020 :: C22 :: T_VARIABLE :: (2) :: $y
99 :: L020 :: C24 :: T_SEMICOLON :: (1) :: ;
100 :: L020 :: C25 :: T_WHITESPACE :: (0) ::

101 :: L021 :: C1 :: T_WHITESPACE :: (4) ::
102 :: L021 :: C5 :: T_COMMENT :: (17) :: // equivalent to:

103 :: L022 :: C1 :: T_WHITESPACE :: (4) ::
104 :: L022 :: C5 :: T_PUBLIC :: (6) :: public
105 :: L022 :: C11 :: T_WHITESPACE :: (1) ::
106 :: L022 :: C12 :: T_STRING :: (5) :: float
107 :: L022 :: C17 :: T_WHITESPACE :: (1) ::
108 :: L022 :: C18 :: T_VARIABLE :: (2) :: $x
109 :: L022 :: C20 :: T_SEMICOLON :: (1) :: ;
110 :: L022 :: C21 :: T_WHITESPACE :: (0) ::

111 :: L023 :: C1 :: T_WHITESPACE :: (4) ::
112 :: L023 :: C5 :: T_PUBLIC :: (6) :: public
113 :: L023 :: C11 :: T_WHITESPACE :: (1) ::
114 :: L023 :: C12 :: T_STRING :: (5) :: float
115 :: L023 :: C17 :: T_WHITESPACE :: (1) ::
116 :: L023 :: C18 :: T_VARIABLE :: (2) :: $y
117 :: L023 :: C20 :: T_SEMICOLON :: (1) :: ;
118 :: L023 :: C21 :: T_WHITESPACE :: (0) ::

119 :: L024 :: C1 :: T_CLOSE_CURLY_BRACKET :: (1) :: }
120 :: L024 :: C2 :: T_WHITESPACE :: (0) ::

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions