diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/command/visitors/FunctionCallExpressionTypeFinder.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/command/visitors/FunctionCallExpressionTypeFinder.java index f846bba1b8f2..6deb43a8dcce 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/command/visitors/FunctionCallExpressionTypeFinder.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/command/visitors/FunctionCallExpressionTypeFinder.java @@ -36,12 +36,14 @@ import io.ballerina.compiler.api.symbols.TypeSymbol; import io.ballerina.compiler.api.symbols.UnionTypeSymbol; import io.ballerina.compiler.api.symbols.VariableSymbol; +import io.ballerina.compiler.api.symbols.WorkerSymbol; import io.ballerina.compiler.syntax.tree.AssignmentStatementNode; import io.ballerina.compiler.syntax.tree.BinaryExpressionNode; import io.ballerina.compiler.syntax.tree.BlockStatementNode; import io.ballerina.compiler.syntax.tree.CheckExpressionNode; import io.ballerina.compiler.syntax.tree.ConditionalExpressionNode; import io.ballerina.compiler.syntax.tree.ErrorConstructorExpressionNode; +import io.ballerina.compiler.syntax.tree.ExplicitAnonymousFunctionExpressionNode; import io.ballerina.compiler.syntax.tree.ExplicitNewExpressionNode; import io.ballerina.compiler.syntax.tree.FailStatementNode; import io.ballerina.compiler.syntax.tree.FunctionArgumentNode; @@ -57,6 +59,7 @@ import io.ballerina.compiler.syntax.tree.MethodCallExpressionNode; import io.ballerina.compiler.syntax.tree.ModuleVariableDeclarationNode; import io.ballerina.compiler.syntax.tree.NamedArgumentNode; +import io.ballerina.compiler.syntax.tree.NamedWorkerDeclarationNode; import io.ballerina.compiler.syntax.tree.Node; import io.ballerina.compiler.syntax.tree.NodeVisitor; import io.ballerina.compiler.syntax.tree.ObjectFieldNode; @@ -402,6 +405,12 @@ public void visit(BlockStatementNode node) { node.parent().accept(this); } + @Override + public void visit(NamedWorkerDeclarationNode namedWorkerDeclarationNode) { + Optional symbol = semanticModel.symbol(namedWorkerDeclarationNode); + symbol.ifPresent(value -> checkAndSetTypeResult(((WorkerSymbol)value).returnType())); + } + @Override public void visit(ReturnStatementNode returnStatementNode) { this.semanticModel.typeOf(returnStatementNode).ifPresent(this::checkAndSetTypeResult); @@ -414,8 +423,6 @@ public void visit(ReturnStatementNode returnStatementNode) { if (resultFound && returnTypeSymbol.typeKind() == TypeDescKind.FUNCTION) { FunctionTypeSymbol functionTypeSymbol = (FunctionTypeSymbol) returnTypeSymbol; functionTypeSymbol.returnTypeDescriptor().ifPresentOrElse(this::checkAndSetTypeResult, this::resetResult); - } else { - resetResult(); } } @@ -512,6 +519,12 @@ public void visit(ImplicitAnonymousFunctionExpressionNode expr) { } } + @Override + public void visit(ExplicitAnonymousFunctionExpressionNode explicitAnonymousFunctionExpressionNode) { + Optional typeSymbol = semanticModel.typeOf(explicitAnonymousFunctionExpressionNode); + typeSymbol.ifPresent(this::checkAndSetTypeResult); + } + @Override public void visit(PanicStatementNode panicStatementNode) { checkAndSetTypeResult(semanticModel.types().ERROR); diff --git a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/CreateFunctionTest.java b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/CreateFunctionTest.java index a451910e5282..f43bd32095c5 100644 --- a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/CreateFunctionTest.java +++ b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/CreateFunctionTest.java @@ -186,6 +186,16 @@ public Object[][] dataProvider() { {"create_function_in_anonymous_function1.json"}, {"create_function_in_anonymous_function2.json"}, + + {"create_function_in_worker1.json"}, + {"create_function_in_worker2.json"}, + {"create_function_in_worker3.json"}, + {"create_function_in_worker4.json"}, + + {"create_function_in_explicit_anonymous_function1.json"}, + {"create_function_in_explicit_anonymous_function2.json"}, + {"create_function_in_explicit_anonymous_function3.json"}, + {"create_function_in_explicit_anonymous_function4.json"} }; } diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function1.json b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function1.json new file mode 100644 index 000000000000..4a8c71c24a41 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function1.json @@ -0,0 +1,57 @@ +{ + "position": { + "line": 4, + "character": 16 + }, + "source": "create_function_in_explicit_anonymous_function.bal", + "expected": [ + { + "title": "Create function 'foo(...)'", + "kind": "quickfix", + "edits": [ + { + "range": { + "start": { + "line": 19, + "character": 1 + }, + "end": { + "line": 19, + "character": 1 + } + }, + "newText": "\n\nfunction foo() returns int {\n return 0;\n}" + } + ], + "resolvable": true, + "data": { + "extName": "org.ballerinalang.langserver.codeaction.BallerinaCodeActionExtension", + "codeActionName": "Create Function", + "fileUri": "create_function_in_explicit_anonymous_function.bal", + "range": { + "start": { + "line": 4, + "character": 15 + }, + "end": { + "line": 4, + "character": 20 + } + }, + "actionData": { + "key": "node.range", + "value": { + "start": { + "line": 4.0, + "character": 15.0 + }, + "end": { + "line": 4.0, + "character": 20.0 + } + } + } + } + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function2.json b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function2.json new file mode 100644 index 000000000000..a5f597a29138 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function2.json @@ -0,0 +1,57 @@ +{ + "position": { + "line": 8, + "character": 10 + }, + "source": "create_function_in_explicit_anonymous_function.bal", + "expected": [ + { + "title": "Create function 'foo(...)'", + "kind": "quickfix", + "edits": [ + { + "range": { + "start": { + "line": 19, + "character": 1 + }, + "end": { + "line": 19, + "character": 1 + } + }, + "newText": "\n\nfunction foo(int i) {\n \n}" + } + ], + "resolvable": true, + "data": { + "extName": "org.ballerinalang.langserver.codeaction.BallerinaCodeActionExtension", + "codeActionName": "Create Function", + "fileUri": "create_function_in_explicit_anonymous_function.bal", + "range": { + "start": { + "line": 8, + "character": 8 + }, + "end": { + "line": 8, + "character": 15 + } + }, + "actionData": { + "key": "node.range", + "value": { + "start": { + "line": 8.0, + "character": 8.0 + }, + "end": { + "line": 8.0, + "character": 15.0 + } + } + } + } + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function3.json b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function3.json new file mode 100644 index 000000000000..0979e3fd65db --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function3.json @@ -0,0 +1,57 @@ +{ + "position": { + "line": 13, + "character": 17 + }, + "source": "create_function_in_explicit_anonymous_function.bal", + "expected": [ + { + "title": "Create function 'foo(...)'", + "kind": "quickfix", + "edits": [ + { + "range": { + "start": { + "line": 19, + "character": 1 + }, + "end": { + "line": 19, + "character": 1 + } + }, + "newText": "\n\nfunction foo() {\n \n}" + } + ], + "resolvable": true, + "data": { + "extName": "org.ballerinalang.langserver.codeaction.BallerinaCodeActionExtension", + "codeActionName": "Create Function", + "fileUri": "create_function_in_explicit_anonymous_function.bal", + "range": { + "start": { + "line": 13, + "character": 15 + }, + "end": { + "line": 13, + "character": 20 + } + }, + "actionData": { + "key": "node.range", + "value": { + "start": { + "line": 13.0, + "character": 15.0 + }, + "end": { + "line": 13.0, + "character": 20.0 + } + } + } + } + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function4.json b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function4.json new file mode 100644 index 000000000000..14e0b507940b --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_explicit_anonymous_function4.json @@ -0,0 +1,57 @@ +{ + "position": { + "line": 17, + "character": 17 + }, + "source": "create_function_in_explicit_anonymous_function.bal", + "expected": [ + { + "title": "Create function 'foo(...)'", + "kind": "quickfix", + "edits": [ + { + "range": { + "start": { + "line": 19, + "character": 1 + }, + "end": { + "line": 19, + "character": 1 + } + }, + "newText": "\n\nfunction foo() returns module1:TestRecord2 {\n return {};\n}" + } + ], + "resolvable": true, + "data": { + "extName": "org.ballerinalang.langserver.codeaction.BallerinaCodeActionExtension", + "codeActionName": "Create Function", + "fileUri": "create_function_in_explicit_anonymous_function.bal", + "range": { + "start": { + "line": 17, + "character": 15 + }, + "end": { + "line": 17, + "character": 20 + } + }, + "actionData": { + "key": "node.range", + "value": { + "start": { + "line": 17.0, + "character": 15.0 + }, + "end": { + "line": 17.0, + "character": 20.0 + } + } + } + } + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker1.json b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker1.json new file mode 100644 index 000000000000..91b39c7b4caa --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker1.json @@ -0,0 +1,57 @@ +{ + "position": { + "line": 4, + "character": 16 + }, + "source": "create_function_in_worker.bal", + "expected": [ + { + "title": "Create function 'foo(...)'", + "kind": "quickfix", + "edits": [ + { + "range": { + "start": { + "line": 19, + "character": 1 + }, + "end": { + "line": 19, + "character": 1 + } + }, + "newText": "\n\nfunction foo() returns int {\n return 0;\n}" + } + ], + "resolvable": true, + "data": { + "extName": "org.ballerinalang.langserver.codeaction.BallerinaCodeActionExtension", + "codeActionName": "Create Function", + "fileUri": "create_function_in_worker.bal", + "range": { + "start": { + "line": 4, + "character": 15 + }, + "end": { + "line": 4, + "character": 20 + } + }, + "actionData": { + "key": "node.range", + "value": { + "start": { + "line": 4.0, + "character": 15.0 + }, + "end": { + "line": 4.0, + "character": 20.0 + } + } + } + } + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker2.json b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker2.json new file mode 100644 index 000000000000..87ef73466419 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker2.json @@ -0,0 +1,57 @@ +{ + "position": { + "line": 8, + "character": 10 + }, + "source": "create_function_in_worker.bal", + "expected": [ + { + "title": "Create function 'foo(...)'", + "kind": "quickfix", + "edits": [ + { + "range": { + "start": { + "line": 19, + "character": 1 + }, + "end": { + "line": 19, + "character": 1 + } + }, + "newText": "\n\nfunction foo(int i) {\n \n}" + } + ], + "resolvable": true, + "data": { + "extName": "org.ballerinalang.langserver.codeaction.BallerinaCodeActionExtension", + "codeActionName": "Create Function", + "fileUri": "create_function_in_worker.bal", + "range": { + "start": { + "line": 8, + "character": 8 + }, + "end": { + "line": 8, + "character": 15 + } + }, + "actionData": { + "key": "node.range", + "value": { + "start": { + "line": 8.0, + "character": 8.0 + }, + "end": { + "line": 8.0, + "character": 15.0 + } + } + } + } + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker3.json b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker3.json new file mode 100644 index 000000000000..a57c1855fc2c --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker3.json @@ -0,0 +1,57 @@ +{ + "position": { + "line": 13, + "character": 17 + }, + "source": "create_function_in_worker.bal", + "expected": [ + { + "title": "Create function 'foo(...)'", + "kind": "quickfix", + "edits": [ + { + "range": { + "start": { + "line": 19, + "character": 1 + }, + "end": { + "line": 19, + "character": 1 + } + }, + "newText": "\n\nfunction foo() {\n \n}" + } + ], + "resolvable": true, + "data": { + "extName": "org.ballerinalang.langserver.codeaction.BallerinaCodeActionExtension", + "codeActionName": "Create Function", + "fileUri": "create_function_in_worker.bal", + "range": { + "start": { + "line": 13, + "character": 15 + }, + "end": { + "line": 13, + "character": 20 + } + }, + "actionData": { + "key": "node.range", + "value": { + "start": { + "line": 13.0, + "character": 15.0 + }, + "end": { + "line": 13.0, + "character": 20.0 + } + } + } + } + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker4.json b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker4.json new file mode 100644 index 000000000000..fbe259630b85 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/config/create_function_in_worker4.json @@ -0,0 +1,57 @@ +{ + "position": { + "line": 17, + "character": 17 + }, + "source": "create_function_in_worker.bal", + "expected": [ + { + "title": "Create function 'foo(...)'", + "kind": "quickfix", + "edits": [ + { + "range": { + "start": { + "line": 19, + "character": 1 + }, + "end": { + "line": 19, + "character": 1 + } + }, + "newText": "\n\nfunction foo() returns module1:TestRecord2 {\n return {};\n}" + } + ], + "resolvable": true, + "data": { + "extName": "org.ballerinalang.langserver.codeaction.BallerinaCodeActionExtension", + "codeActionName": "Create Function", + "fileUri": "create_function_in_worker.bal", + "range": { + "start": { + "line": 17, + "character": 15 + }, + "end": { + "line": 17, + "character": 20 + } + }, + "actionData": { + "key": "node.range", + "value": { + "start": { + "line": 17.0, + "character": 15.0 + }, + "end": { + "line": 17.0, + "character": 20.0 + } + } + } + } + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/source/create_function_in_explicit_anonymous_function.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/source/create_function_in_explicit_anonymous_function.bal new file mode 100644 index 000000000000..48e0ab89bfb9 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/source/create_function_in_explicit_anonymous_function.bal @@ -0,0 +1,20 @@ +import ballerina/module1; + +function createFunctionInWorker() { + var fn1 = function() returns int { + return foo(); + }; + + var fn2 = function() returns string { + foo(32); + return "bar"; + }; + + var fn3 = function() { + return foo(); + }; + + var fn4 = function() returns module1:TestRecord2 { + return foo(); + }; +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/source/create_function_in_worker.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/source/create_function_in_worker.bal new file mode 100644 index 000000000000..709711a300ef --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-function/source/create_function_in_worker.bal @@ -0,0 +1,20 @@ +import ballerina/module1; + +function createFunctionInWorker() { + worker A returns int { + return foo(); + } + + worker B returns string { + foo(32); + return "bar"; + } + + worker C { + return foo(); + } + + worker D returns module1:TestRecord2 { + return foo(); + } +}