From f781a9993ba0a9d7a0a12808b210ede8c2a0532f Mon Sep 17 00:00:00 2001 From: Arsen Nagdalian Date: Wed, 15 Jul 2020 19:40:21 +0300 Subject: [PATCH] Parser tests: add tests for contract description blocks --- .../psi/FunctionWithMultilineContract.kt | 13 ++ .../psi/FunctionWithMultilineContract.txt | 216 ++++++++++++++++++ .../FunctionWithTypeConstraintsAndContract.kt | 12 + ...FunctionWithTypeConstraintsAndContract.txt | 169 ++++++++++++++ .../psi/SimpleFunctionWithContract.kt | 3 + .../psi/SimpleFunctionWithContract.txt | 74 ++++++ .../kotlin/parsing/ParsingTestGenerated.java | 15 ++ 7 files changed, 502 insertions(+) create mode 100644 compiler/testData/psi/FunctionWithMultilineContract.kt create mode 100644 compiler/testData/psi/FunctionWithMultilineContract.txt create mode 100644 compiler/testData/psi/FunctionWithTypeConstraintsAndContract.kt create mode 100644 compiler/testData/psi/FunctionWithTypeConstraintsAndContract.txt create mode 100644 compiler/testData/psi/SimpleFunctionWithContract.kt create mode 100644 compiler/testData/psi/SimpleFunctionWithContract.txt diff --git a/compiler/testData/psi/FunctionWithMultilineContract.kt b/compiler/testData/psi/FunctionWithMultilineContract.kt new file mode 100644 index 00000000000..acbc8f4de7a --- /dev/null +++ b/compiler/testData/psi/FunctionWithMultilineContract.kt @@ -0,0 +1,13 @@ +fun baz(num: Int?, element: MyElement, block: () -> Unit): Int contract [ + callsInPlace(block, InvocationKind.EXACTLY_ONCE), + returns() implies (num != null), + returns() implies (element != null) +] { + require(num != null) + require(element != null) + block() + if (num >= 0) { + return 1; + } + return 0 +} \ No newline at end of file diff --git a/compiler/testData/psi/FunctionWithMultilineContract.txt b/compiler/testData/psi/FunctionWithMultilineContract.txt new file mode 100644 index 00000000000..591d4b89659 --- /dev/null +++ b/compiler/testData/psi/FunctionWithMultilineContract.txt @@ -0,0 +1,216 @@ +KtFile: FunctionWithMultilineContract.kt + PACKAGE_DIRECTIVE + + IMPORT_LIST + + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('baz') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('num') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + NULLABLE_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiElement(QUEST)('?') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('element') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('MyElement') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('block') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + FUNCTION_TYPE + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Unit') + PsiElement(RPAR)(')') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiWhiteSpace(' ') + PsiElement(contract)('contract') + PsiWhiteSpace(' ') + CONTRACT_EFFECT_LIST + PsiElement(LBRACKET)('[') + PsiWhiteSpace('\n ') + CONTRACT_EFFECT + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('callsInPlace') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + VALUE_ARGUMENT + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('block') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_ARGUMENT + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('InvocationKind') + PsiElement(DOT)('.') + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('EXACTLY_ONCE') + PsiElement(RPAR)(')') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + CONTRACT_EFFECT + BINARY_EXPRESSION + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('returns') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(IDENTIFIER)('implies') + PsiWhiteSpace(' ') + PARENTHESIZED + PsiElement(LPAR)('(') + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('num') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(EXCLEQ)('!=') + PsiWhiteSpace(' ') + NULL + PsiElement(null)('null') + PsiElement(RPAR)(')') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + CONTRACT_EFFECT + BINARY_EXPRESSION + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('returns') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(IDENTIFIER)('implies') + PsiWhiteSpace(' ') + PARENTHESIZED + PsiElement(LPAR)('(') + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('element') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(EXCLEQ)('!=') + PsiWhiteSpace(' ') + NULL + PsiElement(null)('null') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n') + PsiElement(RBRACKET)(']') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('require') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + VALUE_ARGUMENT + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('num') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(EXCLEQ)('!=') + PsiWhiteSpace(' ') + NULL + PsiElement(null)('null') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('require') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + VALUE_ARGUMENT + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('element') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(EXCLEQ)('!=') + PsiWhiteSpace(' ') + NULL + PsiElement(null)('null') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('block') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') + IF + PsiElement(if)('if') + PsiWhiteSpace(' ') + PsiElement(LPAR)('(') + CONDITION + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('num') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(GTEQ)('>=') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('0') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + THEN + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + RETURN + PsiElement(return)('return') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('1') + PsiElement(SEMICOLON)(';') + PsiWhiteSpace('\n ') + PsiElement(RBRACE)('}') + PsiWhiteSpace('\n ') + RETURN + PsiElement(return)('return') + PsiWhiteSpace(' ') + INTEGER_CONSTANT + PsiElement(INTEGER_LITERAL)('0') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/FunctionWithTypeConstraintsAndContract.kt b/compiler/testData/psi/FunctionWithTypeConstraintsAndContract.kt new file mode 100644 index 00000000000..206e01aa604 --- /dev/null +++ b/compiler/testData/psi/FunctionWithTypeConstraintsAndContract.kt @@ -0,0 +1,12 @@ +fun someFunctionWithTypeConstraints(arg: E?, block: () -> T): String + contract [ + returns() implies (arg != null), + callsInPlace(block, EXACTLY_ONCE), + ] + where T : MyClass, + E : MyOtherClass +{ + block() + arg ?: throw NullArgumentException() + return "some string" +} \ No newline at end of file diff --git a/compiler/testData/psi/FunctionWithTypeConstraintsAndContract.txt b/compiler/testData/psi/FunctionWithTypeConstraintsAndContract.txt new file mode 100644 index 00000000000..a9c98782be7 --- /dev/null +++ b/compiler/testData/psi/FunctionWithTypeConstraintsAndContract.txt @@ -0,0 +1,169 @@ +KtFile: FunctionWithTypeConstraintsAndContract.kt + PACKAGE_DIRECTIVE + + IMPORT_LIST + + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('someFunctionWithTypeConstraints') + TYPE_PARAMETER_LIST + PsiElement(LT)('<') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('T') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + TYPE_PARAMETER + PsiElement(IDENTIFIER)('E') + PsiElement(GT)('>') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('arg') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + NULLABLE_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('E') + PsiElement(QUEST)('?') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('block') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + FUNCTION_TYPE + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(ARROW)('->') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiElement(RPAR)(')') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiWhiteSpace('\n ') + PsiElement(contract)('contract') + PsiWhiteSpace(' ') + CONTRACT_EFFECT_LIST + PsiElement(LBRACKET)('[') + PsiWhiteSpace('\n ') + CONTRACT_EFFECT + BINARY_EXPRESSION + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('returns') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(IDENTIFIER)('implies') + PsiWhiteSpace(' ') + PARENTHESIZED + PsiElement(LPAR)('(') + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('arg') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(EXCLEQ)('!=') + PsiWhiteSpace(' ') + NULL + PsiElement(null)('null') + PsiElement(RPAR)(')') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + CONTRACT_EFFECT + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('callsInPlace') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + VALUE_ARGUMENT + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('block') + PsiElement(COMMA)(',') + PsiWhiteSpace(' ') + VALUE_ARGUMENT + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('EXACTLY_ONCE') + PsiElement(RPAR)(')') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + PsiElement(RBRACKET)(']') + PsiWhiteSpace('\n ') + PsiElement(where)('where') + PsiWhiteSpace(' ') + TYPE_CONSTRAINT_LIST + TYPE_CONSTRAINT + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('T') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('MyClass') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + TYPE_CONSTRAINT + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('E') + PsiWhiteSpace(' ') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('MyOtherClass') + PsiWhiteSpace('\n') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('block') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('arg') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(ELVIS)('?:') + PsiWhiteSpace(' ') + THROW + PsiElement(throw)('throw') + PsiWhiteSpace(' ') + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('NullArgumentException') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n ') + RETURN + PsiElement(return)('return') + PsiWhiteSpace(' ') + STRING_TEMPLATE + PsiElement(OPEN_QUOTE)('"') + LITERAL_STRING_TEMPLATE_ENTRY + PsiElement(REGULAR_STRING_PART)('some string') + PsiElement(CLOSING_QUOTE)('"') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/testData/psi/SimpleFunctionWithContract.kt b/compiler/testData/psi/SimpleFunctionWithContract.kt new file mode 100644 index 00000000000..c329ae2d0ba --- /dev/null +++ b/compiler/testData/psi/SimpleFunctionWithContract.kt @@ -0,0 +1,3 @@ +fun foo(s: String?) contract [returns() implies (s != null)] { + s ?: throw NullArgumentException() +} \ No newline at end of file diff --git a/compiler/testData/psi/SimpleFunctionWithContract.txt b/compiler/testData/psi/SimpleFunctionWithContract.txt new file mode 100644 index 00000000000..bb9de5ad318 --- /dev/null +++ b/compiler/testData/psi/SimpleFunctionWithContract.txt @@ -0,0 +1,74 @@ +KtFile: SimpleFunctionWithContract.kt + PACKAGE_DIRECTIVE + + IMPORT_LIST + + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('s') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + NULLABLE_TYPE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiElement(QUEST)('?') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + PsiElement(contract)('contract') + PsiWhiteSpace(' ') + CONTRACT_EFFECT_LIST + PsiElement(LBRACKET)('[') + CONTRACT_EFFECT + BINARY_EXPRESSION + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('returns') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(IDENTIFIER)('implies') + PsiWhiteSpace(' ') + PARENTHESIZED + PsiElement(LPAR)('(') + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('s') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(EXCLEQ)('!=') + PsiWhiteSpace(' ') + NULL + PsiElement(null)('null') + PsiElement(RPAR)(')') + PsiElement(RBRACKET)(']') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n ') + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('s') + PsiWhiteSpace(' ') + OPERATION_REFERENCE + PsiElement(ELVIS)('?:') + PsiWhiteSpace(' ') + THROW + PsiElement(throw)('throw') + PsiWhiteSpace(' ') + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('NullArgumentException') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiElement(RPAR)(')') + PsiWhiteSpace('\n') + PsiElement(RBRACE)('}') \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java index ba748440744..47fc3526d59 100644 --- a/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/parsing/ParsingTestGenerated.java @@ -380,6 +380,16 @@ public class ParsingTestGenerated extends AbstractParsingTest { runTest("compiler/testData/psi/FunctionTypes.kt"); } + @TestMetadata("FunctionWithMultilineContract.kt") + public void testFunctionWithMultilineContract() throws Exception { + runTest("compiler/testData/psi/FunctionWithMultilineContract.kt"); + } + + @TestMetadata("FunctionWithTypeConstraintsAndContract.kt") + public void testFunctionWithTypeConstraintsAndContract() throws Exception { + runTest("compiler/testData/psi/FunctionWithTypeConstraintsAndContract.kt"); + } + @TestMetadata("Functions.kt") public void testFunctions() throws Exception { runTest("compiler/testData/psi/Functions.kt"); @@ -620,6 +630,11 @@ public class ParsingTestGenerated extends AbstractParsingTest { runTest("compiler/testData/psi/SimpleExpressions.kt"); } + @TestMetadata("SimpleFunctionWithContract.kt") + public void testSimpleFunctionWithContract() throws Exception { + runTest("compiler/testData/psi/SimpleFunctionWithContract.kt"); + } + @TestMetadata("SimpleModifiers.kt") public void testSimpleModifiers() throws Exception { runTest("compiler/testData/psi/SimpleModifiers.kt");