Allow type constraints on opaque type aliases
Allows some syntax that is ignored at runtime; only used ahead of time by the type checker.
Esse commit está contido em:
+3592
-3642
Diferenças do arquivo suprimidas por serem muito extensas
Carregar Diff
@@ -0,0 +1,10 @@
|
||||
<?hh
|
||||
|
||||
type Foo = int;
|
||||
newtype fbid as int = int;
|
||||
|
||||
function f(fbid $x) {
|
||||
echo $x;
|
||||
echo "\n";
|
||||
}
|
||||
f(4);
|
||||
@@ -0,0 +1 @@
|
||||
4
|
||||
@@ -0,0 +1,3 @@
|
||||
<?hh
|
||||
|
||||
type Foo as int = int;
|
||||
@@ -0,0 +1 @@
|
||||
HipHop Fatal error: syntax error, unexpected T_AS, expecting '=' in %s on line 3
|
||||
@@ -407,7 +407,7 @@ BACKQUOTE_CHARS ("{"*([^$`\\{]|("\\"{ANY_CHAR}))|{BACKQUOTE_LITERAL_DOLLAR})
|
||||
|
||||
<ST_IN_SCRIPTING>"shape" { HH_ONLY_KEYWORD(T_SHAPE); }
|
||||
<ST_IN_SCRIPTING>"type" { HH_ONLY_KEYWORD(T_UNRESOLVED_TYPE); }
|
||||
<ST_IN_SCRIPTING>"newtype" { HH_ONLY_KEYWORD(T_UNRESOLVED_TYPE); }
|
||||
<ST_IN_SCRIPTING>"newtype" { HH_ONLY_KEYWORD(T_UNRESOLVED_NEWTYPE); }
|
||||
|
||||
<ST_IN_SCRIPTING>">>" {
|
||||
if (_scanner->getLookaheadLtDepth() < 2) {
|
||||
|
||||
@@ -190,7 +190,9 @@
|
||||
YYTOKEN(402, T_SHAPE),
|
||||
YYTOKEN(403, T_TYPE),
|
||||
YYTOKEN(404, T_UNRESOLVED_TYPE),
|
||||
YYTOKEN(405, T_COMPILER_HALT_OFFSET)
|
||||
YYTOKEN(405, T_NEWTYPE),
|
||||
YYTOKEN(406, T_UNRESOLVED_NEWTYPE),
|
||||
YYTOKEN(407, T_COMPILER_HALT_OFFSET)
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -224,5 +226,5 @@ typedef struct YYLTYPE
|
||||
#define YYTOKEN_MIN 258
|
||||
#endif
|
||||
#ifndef YYTOKEN_MAX
|
||||
#define YYTOKEN_MAX 405
|
||||
#define YYTOKEN_MAX 407
|
||||
#endif
|
||||
|
||||
@@ -793,6 +793,8 @@ static int yylex(YYSTYPE *token, HPHP::Location *loc, Parser *_p) {
|
||||
%token T_SHAPE
|
||||
%token T_TYPE
|
||||
%token T_UNRESOLVED_TYPE
|
||||
%token T_NEWTYPE
|
||||
%token T_UNRESOLVED_NEWTYPE
|
||||
|
||||
%token T_COMPILER_HALT_OFFSET
|
||||
|
||||
@@ -813,7 +815,7 @@ top_statement:
|
||||
| function_declaration_statement { _p->nns(); $$ = $1;}
|
||||
| class_declaration_statement { _p->nns(); $$ = $1;}
|
||||
| trait_declaration_statement { _p->nns(); $$ = $1;}
|
||||
| hh_typedef_statement { $$ = $1; }
|
||||
| hh_type_alias_statement { $$ = $1; }
|
||||
| T_HALT_COMPILER '(' ')' ';' { _p->onHaltCompiler();
|
||||
_p->finiParseTree();
|
||||
YYACCEPT;}
|
||||
@@ -1850,6 +1852,7 @@ xhp_bareword:
|
||||
| T_TRAIT_C { $$ = $1;}
|
||||
| T_INSTEADOF { $$ = $1;}
|
||||
| T_TYPE { $$ = $1;}
|
||||
| T_NEWTYPE { $$ = $1;}
|
||||
| T_SHAPE { $$ = $1;}
|
||||
;
|
||||
|
||||
@@ -2327,11 +2330,21 @@ class_constant:
|
||||
* mode, but simplify down to the original thing
|
||||
*/
|
||||
|
||||
hh_typedef_statement:
|
||||
hh_opt_constraint:
|
||||
/* empty */
|
||||
| T_AS hh_type
|
||||
;
|
||||
|
||||
hh_type_alias_statement:
|
||||
T_TYPE hh_name_with_typevar
|
||||
'=' hh_type ';' { only_in_hh_syntax(_p);
|
||||
'=' hh_type ';' { only_in_hh_syntax(_p);
|
||||
_p->onTypedef($$, $2, $4);
|
||||
_p->popTypeScope(); }
|
||||
| T_NEWTYPE hh_name_with_typevar
|
||||
hh_opt_constraint
|
||||
'=' hh_type ';' { only_in_hh_syntax(_p);
|
||||
_p->onTypedef($$, $2, $5);
|
||||
_p->popTypeScope(); }
|
||||
;
|
||||
|
||||
hh_name_with_type: /* foo -> int foo */
|
||||
|
||||
@@ -79004,7 +79004,7 @@ YY_RULE_SETUP
|
||||
case 112:
|
||||
YY_RULE_SETUP
|
||||
#line 410 "hphp.ll"
|
||||
{ HH_ONLY_KEYWORD(T_UNRESOLVED_TYPE); }
|
||||
{ HH_ONLY_KEYWORD(T_UNRESOLVED_NEWTYPE); }
|
||||
YY_BREAK
|
||||
case 113:
|
||||
YY_RULE_SETUP
|
||||
|
||||
@@ -380,6 +380,7 @@ bool Scanner::tryParseShapeMemberList(TokenStore::iterator& pos) {
|
||||
|
||||
static bool isUnresolved(int tokid) {
|
||||
return tokid == T_UNRESOLVED_LT ||
|
||||
tokid == T_UNRESOLVED_NEWTYPE ||
|
||||
tokid == T_UNRESOLVED_TYPE;
|
||||
}
|
||||
|
||||
@@ -407,12 +408,13 @@ int Scanner::getNextToken(ScannerToken &t, Location &l) {
|
||||
}
|
||||
|
||||
switch (tokid) {
|
||||
case T_UNRESOLVED_NEWTYPE:
|
||||
case T_UNRESOLVED_TYPE: {
|
||||
auto pos = m_lookahead.begin();
|
||||
auto typePos = pos;
|
||||
nextLookahead(pos);
|
||||
if (pos->t == T_STRING) {
|
||||
typePos->t = T_TYPE;
|
||||
typePos->t = tokid == T_UNRESOLVED_TYPE ? T_TYPE : T_NEWTYPE;
|
||||
} else {
|
||||
typePos->t = T_STRING;
|
||||
}
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário