diff --git a/completion/context.cpp b/completion/context.cpp --- a/completion/context.cpp +++ b/completion/context.cpp @@ -663,6 +663,7 @@ case Parser::Token_UNSET: case Parser::Token_USE: case Parser::Token_VARIABLE: + case Parser::Token_VOID: case Parser::Token_WHILE: case Parser::Token_WHITESPACE: /// TODO: code completion after goto diff --git a/parser/php.g b/parser/php.g --- a/parser/php.g +++ b/parser/php.g @@ -237,7 +237,8 @@ INCLUDE ("include"), INCLUDE_ONCE ("include_once"), EVAL ("eval"), REQUIRE ("require"), REQUIRE_ONCE ("require_once"), NAMESPACE ("namespace"), NAMESPACE_C("__NAMESPACE__"), USE("use"), GOTO ("goto"), TRAIT ("trait"), INSTEADOF ("insteadof"), CALLABLE ("callable"), - ITERABLE ("iterable"), BOOL ("bool"), FLOAT ("float"), INT ("int"), STRING_TYPE ("string") ;; + ITERABLE ("iterable"), BOOL ("bool"), FLOAT ("float"), INT ("int"), STRING_TYPE ("string"), + VOID ("void") ;; -- casts: %token INT_CAST ("int cast"), DOUBLE_CAST ("double cast"), STRING_CAST ("string cast"), @@ -577,6 +578,7 @@ -- http://wiki.php.net/rfc/closures FUNCTION (isRef=BIT_AND|0) LPAREN parameters=parameterList RPAREN ( USE LPAREN lexicalVars=lexicalVarList RPAREN | 0) + ( COLON returnType=returnType | 0) LBRACE try/recover(functionBody=innerStatementList) RBRACE -> closure ;; @@ -874,7 +876,8 @@ ] ;; FUNCTION (BIT_AND | 0) functionName=identifier - LPAREN parameters=parameterList RPAREN LBRACE try/recover(functionBody=innerStatementList) RBRACE + LPAREN parameters=parameterList RPAREN (COLON returnType=returnType | 0) + LBRACE try/recover(functionBody=innerStatementList) RBRACE -> functionDeclarationStatement ;; (#parameters=parameter @ COMMA) | 0 @@ -896,6 +899,19 @@ ) -> parameterType ;; + (isNullable=QUESTION | 0) ( + objectType=namespacedIdentifier + | arrayType=ARRAY + | callableType=CALLABLE + | iterableType=ITERABLE + | boolType=BOOL + | floatType=FLOAT + | intType=INT + | stringType=STRING_TYPE + | voidType=VOID + ) +-> returnType ;; + value=commonScalar | constantOrClassConst=constantOrClassConst | PLUS plusValue=staticScalar @@ -973,6 +989,7 @@ | modifiers=optionalModifiers ( variable=classVariableDeclaration SEMICOLON | FUNCTION (BIT_AND | 0) methodName=identifier LPAREN parameters=parameterList RPAREN + ( COLON returnType=returnType | 0) methodBody=methodBody ) | USE #traits=namespacedIdentifier @ COMMA (imports=traitAliasDeclaration|SEMICOLON) diff --git a/parser/phplexer.cpp b/parser/phplexer.cpp --- a/parser/phplexer.cpp +++ b/parser/phplexer.cpp @@ -796,6 +796,8 @@ token = Parser::Token_INT; } else if (name.compare(QLatin1String("string"), Qt::CaseInsensitive) == 0) { token = Parser::Token_STRING_TYPE; + } else if (name.compare(QLatin1String("void"), Qt::CaseInsensitive) == 0) { + token = Parser::Token_VOID; } else { token = Parser::Token_STRING; } diff --git a/parser/test/lexertest.h b/parser/test/lexertest.h --- a/parser/test/lexertest.h +++ b/parser/test/lexertest.h @@ -66,6 +66,7 @@ void testBinaryNumber(); void testHexadecimalNumber(); void testTypeHintsOnFunction(); + void testReturnTypeHints(); void testExponentiation(); void testExceptionFinally(); void testEllipsis(); diff --git a/parser/test/lexertest.cpp b/parser/test/lexertest.cpp --- a/parser/test/lexertest.cpp +++ b/parser/test/lexertest.cpp @@ -458,6 +458,25 @@ COMPARE_TOKEN(ts, 24, Parser::Token_RBRACE, 1, 44, 1, 44); } +void LexerTest::testReturnTypeHints() +{ + QScopedPointer ts(tokenize(QStringLiteral("size(), 12); + + COMPARE_TOKEN(ts, 0, Parser::Token_OPEN_TAG, 0, 0, 0, 5); + COMPARE_TOKEN(ts, 1, Parser::Token_FUNCTION, 1, 0, 1, 7); + COMPARE_TOKEN(ts, 2, Parser::Token_WHITESPACE, 1, 8, 1, 8); + COMPARE_TOKEN(ts, 3, Parser::Token_STRING, 1, 9, 1, 9); + COMPARE_TOKEN(ts, 4, Parser::Token_LPAREN, 1, 10, 1, 10); + COMPARE_TOKEN(ts, 5, Parser::Token_RPAREN, 1, 11, 1, 11); + COMPARE_TOKEN(ts, 6, Parser::Token_COLON, 1, 12, 1, 12); + COMPARE_TOKEN(ts, 7, Parser::Token_WHITESPACE, 1, 13, 1, 13); + COMPARE_TOKEN(ts, 8, Parser::Token_STRING_TYPE, 1, 14, 1, 19); + COMPARE_TOKEN(ts, 9, Parser::Token_WHITESPACE, 1, 20, 1, 20); + COMPARE_TOKEN(ts, 10, Parser::Token_LBRACE, 1, 21, 1, 21); + COMPARE_TOKEN(ts, 11, Parser::Token_RBRACE, 1, 22, 1, 22); +} + void LexerTest::testExponentiation() { QScopedPointer ts(tokenize(QStringLiteral("