diff --git a/README.md b/README.md
index f3c11d242898..2277447e3aa0 100644
--- a/README.md
+++ b/README.md
@@ -9,8 +9,7 @@
# The Ballerina programming language
-[Ballerina](https://ballerina.io/) is a statically typed, open-source cloud-native programming language developed
-and supported by [WSO2](https://wso2.com/).
+[Ballerina](https://ballerina.io/) is an open-source cloud-native programming language optimized for integration. It is developed and supported by [WSO2](https://wso2.com/).
With Ballerina, you could easily develop microservices, API endpoints and integrations,
and any other application for the cloud. Additionally, Ballerina has all the general-purpose
@@ -34,18 +33,6 @@ Extensible metadata enables easy integration of Ballerina programs with cloud pl
You could directly generate Docker and Kubernetes artifacts straight away from
the source code.
-## Get started
-
-You can use one of the following options to try out Ballerina.
-
-* [Set up Ballerina](https://ballerina.io/learn/get-started/)
-* [Ballerina Playground](https://play.ballerina.io/)
-
-You can use the following resources to learn Ballerina.
-
-* [Ballerina by Example](https://ballerina.io/learn/by-example/)
-* [Ballerina learn pages and guides](https://ballerina.io/learn/)
-
## Download and install
For instructions on downloading and installing, see [Ballerina Downloads](https://ballerina.io/downloads/).
@@ -58,13 +45,20 @@ For more installation options, see [Installation options](https://ballerina.io/d
Try out Ballerina's development capabilities using the [Ballerina extension for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=WSO2.ballerina).
+## Get started
+
+You can use the following resources to learn Ballerina.
+
+* [Ballerina by Example](https://ballerina.io/learn/by-example/)
+* [Ballerina learn pages and guides](https://ballerina.io/learn/)
+
## Report issues and security flaws
>**Tip:** If you are unsure whether you have found a bug, search the existing issues in the GitHub repo and raise it in the [Ballerina Discord](https://discord.com/invite/wAJYFbMrG2) or [Stack Overflow](https://stackoverflow.com/questions/tagged/ballerina).
- - Language, Tooling, Ballerina library, Website: ballerina-lang repo
- - Extended library: ballerina-extended-library repo
- - Security flaw: send an email to security@ballerina.io. For details, see the security policy.
+ - Language, Tooling, Website: ballerina-lang repo
+ - Ballerina library: ballerina-lang repo
+ - Security flaw: send an email to security@ballerina.io. For details, see the security policy.
## Contribute to Ballerina
@@ -79,7 +73,6 @@ Ballerina code is distributed under [Apache license 2.0](https://github.com/ball
## Useful links
-* Join [Ballerina-Dev](https://groups.google.com/g/ballerina-dev) group for technical discussions related to the Ballerina project.
* Chat live with us on our [Discord community](https://discord.com/invite/wAJYFbMrG2).
* Post technical questions on the Stack Overflow with the [#ballerina](https://stackoverflow.com/questions/tagged/ballerina) tag.
* For more details on how to engage with the community, see [Community](https://ballerina.io/community/).
diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/RuntimeRegistry.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/RuntimeRegistry.java
index 1a3ec5d602ca..9ce89176033f 100644
--- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/RuntimeRegistry.java
+++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/RuntimeRegistry.java
@@ -17,6 +17,7 @@
package io.ballerina.runtime.internal.scheduling;
import io.ballerina.runtime.api.async.Callback;
+import io.ballerina.runtime.api.utils.TypeUtils;
import io.ballerina.runtime.api.values.BError;
import io.ballerina.runtime.api.values.BFunctionPointer;
import io.ballerina.runtime.api.values.BObject;
@@ -91,7 +92,8 @@ private synchronized void invokeStopHandlerFunction(Strand strand, Scheduler sch
BFunctionPointer, ?> bFunctionPointer = stopHandlerStack.pop();
StopHandlerCallback callback = new StopHandlerCallback(strand, scheduler);
final FutureValue future = scheduler.createFuture(strand, callback, null,
- ((BFunctionType) bFunctionPointer.getType()).retType, null, strand.getMetadata());
+ ((BFunctionType) TypeUtils.getImpliedType(bFunctionPointer.getType())).retType, null,
+ strand.getMetadata());
scheduler.scheduleLocal(new Object[]{strand}, bFunctionPointer, strand, future);
}
diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java
index 08c6734549fa..80c1ac6512f0 100644
--- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java
+++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AbstractArrayValue.java
@@ -151,7 +151,7 @@ public void setLength(long length) {
int newLength = (int) length;
checkFixedLength(length);
rangeCheck(length, size);
- fillerValueCheck(newLength, size);
+ fillerValueCheck(newLength, size, newLength);
resizeInternalArray(newLength);
fillValues(newLength);
size = newLength;
@@ -193,9 +193,9 @@ public Type getIteratorNextReturnType() {
* helper methods that are visible to the implementation classes.
*/
- protected abstract void fillValues(int newLength);
+ protected abstract void fillValues(int index);
- protected abstract void fillerValueCheck(int newLength, int size2);
+ protected abstract void fillerValueCheck(int index, int size, int expectedLength);
protected abstract void resizeInternalArray(int newLength);
diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java
index a241fdede542..59543d47ce2b 100644
--- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java
+++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ArrayValueImpl.java
@@ -1105,7 +1105,7 @@ protected void rangeCheck(long index, int size) {
}
@Override
- protected void fillerValueCheck(int index, int size) {
+ protected void fillerValueCheck(int index, int size, int expectedLength) {
// if the elementType doesn't have an implicit initial value & if the insertion is not a consecutive append
// to the array, then an exception will be thrown.
if (arrayType.hasFillerValue()) {
@@ -1113,7 +1113,7 @@ protected void fillerValueCheck(int index, int size) {
}
if (index > size) {
throw ErrorHelper.getRuntimeException(ErrorReasons.ILLEGAL_LIST_INSERTION_ERROR,
- ErrorCodes.ILLEGAL_ARRAY_INSERTION, size, index + 1);
+ ErrorCodes.ILLEGAL_ARRAY_INSERTION, size, expectedLength);
}
}
@@ -1172,7 +1172,7 @@ private void prepareForAdd(long index, Object value, Type sourceType, int curren
int intIndex = (int) index;
rangeCheck(index, size);
- fillerValueCheck(intIndex, size);
+ fillerValueCheck(intIndex, size, intIndex + 1);
ensureCapacity(intIndex + 1, currentArraySize);
fillValues(intIndex);
resetSize(intIndex);
diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java
index a16a44309c8a..1283cf5a11cc 100644
--- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java
+++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TupleValueImpl.java
@@ -671,9 +671,9 @@ protected void rangeCheck(long index, int size) {
}
@Override
- protected void fillerValueCheck(int index, int size) {
+ protected void fillerValueCheck(int index, int size, int expectedLength) {
// if there has been values added beyond the current index, that means filler values
- // has already been checked. Therefore no need to check again.
+ // has already been checked. Therefore, no need to check again.
if (this.size >= index) {
return;
}
@@ -682,7 +682,7 @@ protected void fillerValueCheck(int index, int size) {
// to the array, then an exception will be thrown.
if (!TypeChecker.hasFillerValue(this.tupleType.getRestType()) && (index > size)) {
throw ErrorHelper.getRuntimeException(ErrorReasons.ILLEGAL_LIST_INSERTION_ERROR,
- ErrorCodes.ILLEGAL_TUPLE_INSERTION, size, index + 1);
+ ErrorCodes.ILLEGAL_TUPLE_INSERTION, size, expectedLength);
}
}
@@ -759,7 +759,7 @@ private void prepareForAdd(long index, Object value, int currentArraySize) {
TypeChecker.getType(value)));
}
- fillerValueCheck(intIndex, size);
+ fillerValueCheck(intIndex, size, intIndex + 1);
ensureCapacity(intIndex + 1, currentArraySize);
fillValues(intIndex);
resetSize(intIndex);
diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/RunNativeImageTestTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/RunNativeImageTestTask.java
index be9e151fc2fb..8ea430c39458 100644
--- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/RunNativeImageTestTask.java
+++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/RunNativeImageTestTask.java
@@ -471,15 +471,15 @@ private int runTestSuiteWithNativeImage(Package currentPackage, Target target,
if (nativeImageCommand == null) {
throw new ProjectException("GraalVM installation directory not found. Set GRAALVM_HOME as an " +
"environment variable\nHINT: To install GraalVM, follow the link: " +
- "https://ballerina.io/learn/build-a-native-executable/#configure-graalvm");
+ "https://ballerina.io/learn/build-the-executable-locally/#configure-graalvm");
}
nativeImageCommand += File.separator + BIN_DIR_NAME + File.separator
+ (OS.contains("win") ? "native-image.cmd" : "native-image");
File commandExecutable = Paths.get(nativeImageCommand).toFile();
if (!commandExecutable.exists()) {
- throw new ProjectException("Cannot find '" + commandExecutable.getName() + "' in the GRAALVM_HOME. " +
- "Install it using: gu install native-image");
+ throw new ProjectException("Cannot find '" + commandExecutable.getName() + "' in the GRAALVM_HOME/bin "
+ + "directory. Install it using: gu install native-image");
}
} catch (ProjectException e) {
throw createLauncherException(e.getMessage());
diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DocumentContext.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DocumentContext.java
index 5616ad48e8fe..c4a7ef1b98f5 100644
--- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DocumentContext.java
+++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DocumentContext.java
@@ -58,7 +58,7 @@ class DocumentContext {
private NodeCloner nodeCloner;
private final DocumentId documentId;
private final String name;
- private final String content;
+ private String content;
private boolean disableSyntaxTree = false;
private DocumentContext(DocumentId documentId, String name, String content, boolean disableSyntaxTree) {
@@ -187,4 +187,11 @@ private void reportSyntaxDiagnostics(PackageID pkgID, SyntaxTree tree, BLangDiag
DocumentContext duplicate() {
return new DocumentContext(this.documentId, this.name, syntaxTree().toSourceCode(), false);
}
+
+ void shrink() {
+ if (this.compilationUnit != null) {
+ this.compilationUnit.topLevelNodes.clear();
+ }
+ this.content = null;
+ }
}
diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBackend.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBackend.java
index a974c477f490..ec1fdadad1bf 100644
--- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBackend.java
+++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBackend.java
@@ -176,6 +176,9 @@ private void performCodeGen() {
moduleDiagnostics.add(
new PackageDiagnostic(diagnostic, moduleContext.descriptor(), moduleContext.project()));
}
+
+ //TODO: remove this once ballerina-lang#41407 is fixed
+ ModuleContext.shrinkDocuments(moduleContext);
}
// add compilation diagnostics
diagnostics.addAll(moduleDiagnostics);
@@ -553,15 +556,15 @@ private Path emitGraalExecutable(Path executableFilePath) {
if (nativeImageCommand == null) {
throw new ProjectException("GraalVM installation directory not found. Set GRAALVM_HOME as an " +
"environment variable\nHINT: To install GraalVM, follow the link: " +
- "https://ballerina.io/learn/build-a-native-executable/#configure-graalvm");
+ "https://ballerina.io/learn/build-the-executable-locally/#configure-graalvm");
}
nativeImageCommand += File.separator + BIN_DIR_NAME + File.separator
+ (OS.contains("win") ? "native-image.cmd" : "native-image");
File commandExecutable = Paths.get(nativeImageCommand).toFile();
if (!commandExecutable.exists()) {
- throw new ProjectException("cannot find '" + commandExecutable.getName() + "' in the GRAALVM_HOME. " +
- "Install it using: gu install native-image");
+ throw new ProjectException("cannot find '" + commandExecutable.getName() + "' in the GRAALVM_HOME/bin " +
+ "directory. Install it using: gu install native-image");
}
String graalVMBuildOptions = project.buildOptions().graalVMBuildOptions();
diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleContext.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleContext.java
index 2ce415bc1db6..6578b424fdc8 100644
--- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleContext.java
+++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleContext.java
@@ -560,6 +560,11 @@ static void loadPlatformSpecificCodeInternal(ModuleContext moduleContext, Compil
// TODO implement
}
+ //TODO: should be removed once we properly fix ballerina-lang#41407
+ static void shrinkDocuments(ModuleContext moduleContext) {
+ moduleContext.srcDocContextMap.values().forEach(DocumentContext::shrink);
+ }
+
Optional moduleMdContext() {
return Optional.ofNullable(this.moduleMdContext);
}
diff --git a/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticErrorCode.java b/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticErrorCode.java
index bc0fcf61bcbf..19fa61f3a08d 100644
--- a/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticErrorCode.java
+++ b/compiler/ballerina-lang/src/main/java/org/ballerinalang/util/diagnostic/DiagnosticErrorCode.java
@@ -814,7 +814,8 @@ public enum DiagnosticErrorCode implements DiagnosticCode {
INVALID_QUERY_CONSTRUCT_TYPE("BCE4055", "invalid.error.query.construct.type"),
CANNOT_USE_ALTERNATE_WAIT_ACTION_WITHIN_MULTIPLE_WAIT_ACTION("BCE4056",
"cannot.use.alternate.wait.action.within.multiple.wait.action"),
- EXPRESSION_OF_FUTURE_TYPE_EXPECTED("BCE4057", "future.expression.expected")
+ EXPRESSION_OF_FUTURE_TYPE_EXPECTED("BCE4057", "future.expression.expected"),
+ INSTANTIATION_ERROR("BCE4058", "instantiation.error")
;
private String diagnosticId;
diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/CodeGenerator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/CodeGenerator.java
index a3cd78e0a0db..40b9848ef08b 100644
--- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/CodeGenerator.java
+++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/CodeGenerator.java
@@ -98,11 +98,11 @@ private CompiledJarFile generate(BPackageSymbol packageSymbol) {
HashMap originalIdentifierMap = JvmDesugarPhase.encodeModuleIdentifiers(packageSymbol.bir);
// TODO Get-rid of the following assignment
- packageSymbol.compiledJarFile = jvmPackageGen.generate(packageSymbol.bir, true);
+ CompiledJarFile compiledJarFile = jvmPackageGen.generate(packageSymbol.bir, true);
//Revert encoding identifier names
JvmDesugarPhase.replaceEncodedModuleIdentifiers(packageSymbol.bir, originalIdentifierMap);
- return packageSymbol.compiledJarFile;
+ return compiledJarFile;
}
private void populateExternalMap(JvmPackageGen jvmPackageGen) {
diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java
index 3fb27f038d47..a7496256d9e3 100644
--- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java
+++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/JMethodResolver.java
@@ -47,6 +47,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Executable;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
@@ -897,6 +898,10 @@ private Executable resolveMethod(Class> clazz, String name, Class>... paramT
private List getExecutables(Class> clazz, String methodName, JMethodKind kind) {
if (kind == JMethodKind.CONSTRUCTOR) {
+ if (Modifier.isAbstract(clazz.getModifiers())) {
+ throw new JInteropException(DiagnosticErrorCode.INSTANTIATION_ERROR,
+ "'" + clazz.getName() + "' is abstract, and cannot be instantiated");
+ }
return Arrays.asList(getConstructors(clazz));
} else {
List list = new ArrayList<>();
diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java
index 6fe4551aa68d..076565007e74 100644
--- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java
+++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/AnnotationDesugar.java
@@ -840,7 +840,7 @@ private BLangLambdaFunction addReturnAndDefineLambda(BLangFunction function, BLa
BInvokableSymbol lambdaFunctionSymbol = createInvokableSymbol(function, pkgID, owner);
BLangLambdaFunction lambdaFunction = desugar.createLambdaFunction(function, lambdaFunctionSymbol, env);
- lambdaFunction.capturedClosureEnv = env.createClone();
+ lambdaFunction.capturedClosureEnv = env;
pkgNode.functions.add(function);
pkgNode.topLevelNodes.add(function);
diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java
index b2585c126b53..edf0e7add015 100644
--- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java
+++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureDesugar.java
@@ -1415,6 +1415,7 @@ public void visit(BLangLambdaFunction bLangLambdaFunction) {
boolean isWorker = bLangLambdaFunction.function.flagSet.contains(Flag.WORKER);
bLangLambdaFunction.enclMapSymbols = collectClosureMapSymbols(symbolEnv, enclInvokable, isWorker);
}
+ bLangLambdaFunction.capturedClosureEnv = null;
result = bLangLambdaFunction;
}
diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java
index 38a81d2fd0f7..cb167d786dd7 100644
--- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java
+++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/ClosureGenerator.java
@@ -551,7 +551,7 @@ private BLangExpression createClosureForDefaultValue(String closureName, String
BLangReturn returnStmt = ASTBuilderUtil.createReturnStmt(function.pos, (BLangBlockFunctionBody) function.body);
returnStmt.expr = varNode.expr;
BLangLambdaFunction lambdaFunction = createLambdaFunction(function);
- lambdaFunction.capturedClosureEnv = env.createClone();
+ lambdaFunction.capturedClosureEnv = env;
BInvokableSymbol varSymbol = createSimpleVariable(function, lambdaFunction, false);
env.enclPkg.symbol.scope.define(function.symbol.name, function.symbol);
env.enclPkg.functions.add(function);
diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java
index ede19f45b6d4..20deedc98a6f 100644
--- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java
+++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/desugar/Desugar.java
@@ -6222,7 +6222,7 @@ private BLangNode rewriteObjectMemberAccessAsField(BLangFieldBasedAccess fieldAc
BLangLambdaFunction lambdaFunction = (BLangLambdaFunction) TreeBuilder.createLambdaFunctionNode();
lambdaFunction.function = func;
- lambdaFunction.capturedClosureEnv = env.createClone();
+ lambdaFunction.capturedClosureEnv = env;
env.enclPkg.functions.add(func);
env.enclPkg.topLevelNodes.add(func);
//env.enclPkg.lambdaFunctions.add(lambdaFunction);
@@ -7809,6 +7809,7 @@ public void visit(BLangLambdaFunction bLangLambdaFunction) {
funcSymbol.addAnnotation(this.strandAnnotAttachement.annotationAttachmentSymbol);
funcSymbol.schedulerPolicy = SchedulerPolicy.ANY;
}
+ bLangLambdaFunction.capturedClosureEnv = null;
result = bLangLambdaFunction;
}
diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/symbols/BPackageSymbol.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/symbols/BPackageSymbol.java
index ed1b8b5dc725..19ac138d2fb4 100644
--- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/symbols/BPackageSymbol.java
+++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/symbols/BPackageSymbol.java
@@ -23,7 +23,6 @@
import org.ballerinalang.model.symbols.SymbolKind;
import org.ballerinalang.model.symbols.SymbolOrigin;
import org.ballerinalang.repository.CompiledPackage;
-import org.wso2.ballerinalang.compiler.CompiledJarFile;
import org.wso2.ballerinalang.compiler.bir.model.BIRNode;
import org.wso2.ballerinalang.compiler.semantics.model.types.BPackageType;
import org.wso2.ballerinalang.compiler.util.Name;
@@ -56,9 +55,6 @@ public class BPackageSymbol extends BTypeSymbol {
public BIRNode.BIRPackage bir; // TODO try to remove this
public BIRPackageFile birPackageFile;
- // kep code generated jar binary content in memory
- public CompiledJarFile compiledJarFile;
-
// TODO Refactor following two flags
public boolean entryPointExists = false;
diff --git a/compiler/ballerina-lang/src/main/resources/compiler.properties b/compiler/ballerina-lang/src/main/resources/compiler.properties
index 000855ebbddb..738ca3841df4 100644
--- a/compiler/ballerina-lang/src/main/resources/compiler.properties
+++ b/compiler/ballerina-lang/src/main/resources/compiler.properties
@@ -1575,6 +1575,9 @@ error.unsupported.primitive.type.reason=\
error.method.signature.not.match=\
'{ballerina/jballerina.java}'METHOD_SIGNATURE_DOES_NOT_MATCH ''{0}''
+error.instantiation.error=\
+ '{ballerina/jballerina.java}'INSTANTIATION_ERROR ''{0}''
+
error.invalid.attribute.reference=\
invalid attribute reference
diff --git a/compiler/ballerina-parser/src/test/resources/expressions/object-constructor/object_constructor_assert_10.json b/compiler/ballerina-parser/src/test/resources/expressions/object-constructor/object_constructor_assert_10.json
index c68a2c7d374b..987ebde619d8 100644
--- a/compiler/ballerina-parser/src/test/resources/expressions/object-constructor/object_constructor_assert_10.json
+++ b/compiler/ballerina-parser/src/test/resources/expressions/object-constructor/object_constructor_assert_10.json
@@ -145,7 +145,7 @@
"leadingMinutiae": [
{
"kind": "WHITESPACE_MINUTIAE",
- "value": " "
+ "value": " "
}
],
"trailingMinutiae": [
@@ -203,7 +203,7 @@
"leadingMinutiae": [
{
"kind": "WHITESPACE_MINUTIAE",
- "value": " "
+ "value": " "
}
]
}
diff --git a/compiler/ballerina-parser/src/test/resources/expressions/object-constructor/object_constructor_source_10.bal b/compiler/ballerina-parser/src/test/resources/expressions/object-constructor/object_constructor_source_10.bal
index f5f93c0c3adc..139b64d604cd 100644
--- a/compiler/ballerina-parser/src/test/resources/expressions/object-constructor/object_constructor_source_10.bal
+++ b/compiler/ballerina-parser/src/test/resources/expressions/object-constructor/object_constructor_source_10.bal
@@ -1,5 +1,5 @@
public function main() {
foo(object {
- int i = 1;
- });
+ int i = 1;
+ });
}
diff --git a/distribution/zip/jballerina/bin/bal.bat b/distribution/zip/jballerina/bin/bal.bat
index c87ace5a0322..4108114a6540 100644
--- a/distribution/zip/jballerina/bin/bal.bat
+++ b/distribution/zip/jballerina/bin/bal.bat
@@ -34,7 +34,7 @@ rem ----- if JAVA_HOME is not set we're not happy ------------------------------
:checkJava
set BALLERINA_HOME=%~sdp0..
-if exist %BALLERINA_HOME%\..\..\dependencies\jdk-17.0.7+7-jree (
+if exist %BALLERINA_HOME%\..\..\dependencies\jdk-17.0.7+7-jre (
set "JAVA_HOME=%BALLERINA_HOME%\..\..\dependencies\jdk-17.0.7+7-jre"
)
diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Pop.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Pop.java
index 84a25ee23bc9..df573d7c0e6b 100644
--- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Pop.java
+++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/Pop.java
@@ -18,10 +18,13 @@
package org.ballerinalang.langlib.array;
+import io.ballerina.runtime.api.types.ArrayType;
+import io.ballerina.runtime.api.types.Type;
import io.ballerina.runtime.api.utils.TypeUtils;
import io.ballerina.runtime.api.values.BArray;
import static org.ballerinalang.langlib.array.utils.ArrayUtils.checkIsArrayOnlyOperation;
+import static org.ballerinalang.langlib.array.utils.ArrayUtils.checkIsClosedArray;
/**
* Native implementation of lang.array:pop((any|error)[]).
@@ -39,7 +42,11 @@ public class Pop {
private static final String FUNCTION_SIGNATURE = "pop()";
public static Object pop(BArray arr) {
- checkIsArrayOnlyOperation(TypeUtils.getImpliedType(arr.getType()), FUNCTION_SIGNATURE);
+ Type type = TypeUtils.getImpliedType(arr.getType());
+ checkIsArrayOnlyOperation(type, FUNCTION_SIGNATURE);
+ checkIsClosedArray((ArrayType) type, FUNCTION_SIGNATURE);
return arr.shift(arr.size() - 1);
}
+
+ private Pop() {}
}
diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/SetLength.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/SetLength.java
index cb67ee5006c5..d85908a7f2b8 100644
--- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/SetLength.java
+++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/SetLength.java
@@ -35,4 +35,6 @@ public class SetLength {
public static void setLength(BArray arr, long i) {
arr.setLength(i);
}
+
+ private SetLength() {}
}
diff --git a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/ArrayUtils.java b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/ArrayUtils.java
index 3b77683ca726..6f5c627b64b0 100644
--- a/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/ArrayUtils.java
+++ b/langlib/lang.array/src/main/java/org/ballerinalang/langlib/array/utils/ArrayUtils.java
@@ -86,6 +86,12 @@ public static void checkIsArrayOnlyOperation(Type arrType, String op) {
}
}
+ public static void checkIsClosedArray(ArrayType arrType, String op) {
+ if (arrType.getState() == ArrayType.ArrayState.CLOSED) {
+ throw createOpNotSupportedError(arrType, op);
+ }
+ }
+
public static BError createOpNotSupportedError(Type type, String op) {
return ErrorCreator.createError(getModulePrefixedReason(ARRAY_LANG_LIB,
OPERATION_NOT_SUPPORTED_IDENTIFIER),
diff --git a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java
index 9566cf30e95f..f07bd8627f67 100644
--- a/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java
+++ b/langlib/langlib-test/src/test/java/org/ballerinalang/langlib/test/LangLibArrayTest.java
@@ -600,7 +600,9 @@ public Object[] testFunctions() {
"testModificationWithinEvery",
"testArrSortWithNamedArgs1",
"testArrSortWithNamedArgs2",
- "testArrSortWithNamedArgs3"
+ "testArrSortWithNamedArgs3",
+ "testArrayPop",
+ "testSetLengthNegative"
};
}
}
diff --git a/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal b/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal
index fc775c52bf20..e1810ae806b5 100644
--- a/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal
+++ b/langlib/langlib-test/src/test/resources/test-src/arraylib_test.bal
@@ -1788,3 +1788,47 @@ function testPushWithErrorConstructorExpr() {
assertTrue(e is Error);
assertValueEquality("e2", e.message());
}
+
+function testArrayPop() {
+ int[] arr1 = [1, 2];
+ assertValueEquality(arr1.pop(), 2);
+ assertValueEquality(arr1, [1]);
+
+ int[2] arr2 = [1, 2];
+ int|error result = trap array:pop(arr2);
+ assertTrue(result is error);
+ if (result is error) {
+ assertValueEquality("{ballerina/lang.array}OperationNotSupported", result.message());
+ assertValueEquality("pop() not supported on type 'int[2]'",
+ checkpanic result.detail()["message"]);
+ }
+
+ int[] arr = arr2;
+ result = trap arr.pop();
+ assertTrue(result is error);
+ if (result is error) {
+ assertValueEquality("{ballerina/lang.array}OperationNotSupported", result.message());
+ assertValueEquality("pop() not supported on type 'int[2]'",
+ checkpanic result.detail()["message"]);
+ }
+}
+
+function testSetLengthNegative() {
+ string:Char[] arr = ["a","b"];
+ error? result = trap arr.setLength(5);
+ assertTrue(result is error);
+ if (result is error) {
+ assertValueEquality("{ballerina/lang.array}IllegalListInsertion", result.message());
+ assertValueEquality("array of length 2 cannot be expanded into array of length 5 without filler values",
+ checkpanic result.detail()["message"]);
+ }
+
+ [string:Char...] tup = ["a","b"];
+ result = trap tup.setLength(10);
+ assertTrue(result is error);
+ if (result is error) {
+ assertValueEquality("{ballerina/lang.array}IllegalListInsertion", result.message());
+ assertValueEquality("tuple of length 2 cannot be expanded into tuple of length 10 without filler values",
+ checkpanic result.detail()["message"]);
+ }
+}
diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/references/ReferencesUtil.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/references/ReferencesUtil.java
index 622d0601548d..5e64c7abe5a6 100644
--- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/references/ReferencesUtil.java
+++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/references/ReferencesUtil.java
@@ -17,6 +17,7 @@
import io.ballerina.compiler.api.SemanticModel;
import io.ballerina.compiler.api.symbols.Symbol;
+import io.ballerina.compiler.syntax.tree.ModulePartNode;
import io.ballerina.compiler.syntax.tree.NonTerminalNode;
import io.ballerina.compiler.syntax.tree.SyntaxKind;
import io.ballerina.projects.Document;
@@ -24,6 +25,7 @@
import io.ballerina.projects.Project;
import io.ballerina.tools.diagnostics.Location;
import io.ballerina.tools.text.LinePosition;
+import io.ballerina.tools.text.TextRange;
import org.ballerinalang.langserver.common.utils.CommonUtil;
import org.ballerinalang.langserver.common.utils.PathUtil;
import org.ballerinalang.langserver.common.utils.PositionUtil;
@@ -120,7 +122,22 @@ public static Optional getSymbolAtCursor(PositionedOperationContext cont
return Optional.empty();
}
+ Document document = srcFile.get();
Position position = context.getCursorPosition();
+ TextRange range = TextRange.from(
+ document.textDocument().textPositionFrom(PositionUtil.getLinePosition(position)), 0);
+ NonTerminalNode nonTerminalNode = ((ModulePartNode) document.syntaxTree().rootNode()).findNode(range);
+ SyntaxKind parentKind = nonTerminalNode.parent().kind();
+
+ if (parentKind == SyntaxKind.TYPE_PARAMETER || parentKind == SyntaxKind.STREAM_TYPE_PARAMS) {
+ if (nonTerminalNode.lineRange().endLine().offset() == position.getCharacter()) {
+ // When there is a type parameter and cursor is at the end of the type parameter, semantic API does not
+ // provide the correct symbol. Therefore, here we search for the symbol at (col - 1).
+ return semanticModel.get().symbol(document,
+ LinePosition.from(position.getLine(), position.getCharacter() - 1));
+ }
+ }
+
Optional symbolAtCursor = semanticModel.get().symbol(srcFile.get(),
LinePosition.from(position.getLine(), position.getCharacter()));
diff --git a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/definition/DefinitionTest.java b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/definition/DefinitionTest.java
index 08c7780bbfee..892cafafd8af 100644
--- a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/definition/DefinitionTest.java
+++ b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/definition/DefinitionTest.java
@@ -151,7 +151,8 @@ protected Object[][] testDataProvider() throws IOException {
{"def_annotation_on_obj_func_config1.json", "project"},
{"def_typereference.json", "project"},
{"def_typereference2.json", "project"},
- {"def_typereference3.json", "project"}
+ {"def_typereference3.json", "project"},
+ {"defProject15.json", "project"},
};
}
diff --git a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/rename/ProjectRenameTest.java b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/rename/ProjectRenameTest.java
index 12c0e2b5d647..cf490722901b 100644
--- a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/rename/ProjectRenameTest.java
+++ b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/rename/ProjectRenameTest.java
@@ -54,6 +54,7 @@ private Object[][] testDataProvider() {
// Negative/invalid cases
{"rename_keyword_result1.json", "kw"},
{"rename_invalid_token_result1.json", "token"},
+ {"rename_table_row_type_and_stream_type.json", "Student"},
};
}
diff --git a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/rename/RenameTest.java b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/rename/RenameTest.java
index ddbe2bb71462..11923e7911f8 100644
--- a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/rename/RenameTest.java
+++ b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/rename/RenameTest.java
@@ -77,6 +77,12 @@ public Object[][] testDataProvider() {
{"rename_self.json", "this"},
{"rename_invalid_qname_ref.json", "io"},
// {"rename_resource_method_path_segment.json", "path1"} //TODO: Fix #41041
+
+ {"rename_table_row_type_parameter1.json", "Student"},
+ {"rename_table_row_type_parameter2.json", "Student"},
+ {"rename_table_row_type_parameter3.json", "Student"},
+ {"rename_stream_type_parameter.json", "Student"},
+ {"rename_map_type_parameter.json", "Student"},
};
}
}
diff --git a/language-server/modules/langserver-core/src/test/resources/definition/expected/project/defProject15.json b/language-server/modules/langserver-core/src/test/resources/definition/expected/project/defProject15.json
new file mode 100644
index 000000000000..abe51a94884d
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/definition/expected/project/defProject15.json
@@ -0,0 +1,24 @@
+{
+ "source": {
+ "file": "projectls/defmodsource6.bal"
+ },
+ "position": {
+ "line": 3,
+ "character": 19
+ },
+ "result": [
+ {
+ "range": {
+ "start": {
+ "line": 9,
+ "character": 12
+ },
+ "end": {
+ "line": 9,
+ "character": 17
+ }
+ },
+ "uri": "projectls/modules/lsmod3/lsmod3.bal"
+ }
+ ]
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/definition/sources/projectls/defmodsource6.bal b/language-server/modules/langserver-core/src/test/resources/definition/sources/projectls/defmodsource6.bal
new file mode 100644
index 000000000000..c002065b5d3c
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/definition/sources/projectls/defmodsource6.bal
@@ -0,0 +1,6 @@
+import projectls.lsmod3;
+
+function foo() {
+ table tHuman = table [{id: 1, name: "Jane"}];
+}
+
diff --git a/language-server/modules/langserver-core/src/test/resources/definition/sources/projectls/modules/lsmod3/lsmod3.bal b/language-server/modules/langserver-core/src/test/resources/definition/sources/projectls/modules/lsmod3/lsmod3.bal
index 81f65bb8da58..e210999d68fb 100644
--- a/language-server/modules/langserver-core/src/test/resources/definition/sources/projectls/modules/lsmod3/lsmod3.bal
+++ b/language-server/modules/langserver-core/src/test/resources/definition/sources/projectls/modules/lsmod3/lsmod3.bal
@@ -6,3 +6,8 @@ public function mod3Function1() {
public type MyType lsmod1:MyType;
public type MyType2 MyType;
+
+public type Human record {|
+ readonly int id;
+ string name;
+|};
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/expected/project/rename_table_row_type_and_stream_type.json b/language-server/modules/langserver-core/src/test/resources/rename/expected/project/rename_table_row_type_and_stream_type.json
new file mode 100644
index 000000000000..85b26cc4f006
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/expected/project/rename_table_row_type_and_stream_type.json
@@ -0,0 +1,54 @@
+{
+ "source": {
+ "file": "main.bal"
+ },
+ "position": {
+ "line": 19,
+ "character": 23
+ },
+ "prepareRename": {
+ "valid": true
+ },
+ "result": {
+ "changes": {
+ "modules/module2/types.bal": [{
+ "range": {
+ "start": {
+ "line": 2,
+ "character": 12
+ },
+ "end": {
+ "line": 2,
+ "character": 17
+ }
+ },
+ "newText": "Student"
+ }],
+ "main.bal": [{
+ "range": {
+ "start": {
+ "line": 18,
+ "character": 19
+ },
+ "end": {
+ "line": 18,
+ "character": 24
+ }
+ },
+ "newText": "Student"
+ }, {
+ "range": {
+ "start": {
+ "line": 19,
+ "character": 18
+ },
+ "end": {
+ "line": 19,
+ "character": 23
+ }
+ },
+ "newText": "Student"
+ }]
+ }
+ }
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_map_type_parameter.json b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_map_type_parameter.json
new file mode 100644
index 000000000000..7d2f8265f1c3
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_map_type_parameter.json
@@ -0,0 +1,44 @@
+{
+ "source": {
+ "file": "rename_map_type_parameter.bal"
+ },
+ "position": {
+ "line": 6,
+ "character": 14
+ },
+ "prepareRename": {
+ "valid": true
+ },
+ "result": {
+ "changes": {
+ "rename_map_type_parameter.bal": [
+ {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 5
+ },
+ "end": {
+ "line": 0,
+ "character": 11
+ }
+ },
+ "newText": "Student"
+ },
+ {
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 8
+ },
+ "end": {
+ "line": 6,
+ "character": 14
+ }
+ },
+ "newText": "Student"
+ }
+ ]
+ }
+ }
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_stream_type_parameter.json b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_stream_type_parameter.json
new file mode 100644
index 000000000000..f08f38ba0b68
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_stream_type_parameter.json
@@ -0,0 +1,57 @@
+{
+ "source": {
+ "file": "rename_stream_type_parameter.bal"
+ },
+ "position": {
+ "line": 7,
+ "character": 17
+ },
+ "prepareRename": {
+ "valid": true
+ },
+ "result": {
+ "changes": {
+ "rename_stream_type_parameter.bal": [
+ {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 5
+ },
+ "end": {
+ "line": 0,
+ "character": 11
+ }
+ },
+ "newText": "Student"
+ },
+ {
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 4
+ },
+ "end": {
+ "line": 6,
+ "character": 10
+ }
+ },
+ "newText": "Student"
+ },
+ {
+ "range": {
+ "start": {
+ "line": 7,
+ "character": 11
+ },
+ "end": {
+ "line": 7,
+ "character": 17
+ }
+ },
+ "newText": "Student"
+ }
+ ]
+ }
+ }
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_table_row_type_parameter1.json b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_table_row_type_parameter1.json
new file mode 100644
index 000000000000..33a03123149c
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_table_row_type_parameter1.json
@@ -0,0 +1,44 @@
+{
+ "source": {
+ "file": "rename_table_row_type_parameter1.bal"
+ },
+ "position": {
+ "line": 6,
+ "character": 16
+ },
+ "prepareRename": {
+ "valid": true
+ },
+ "result": {
+ "changes": {
+ "rename_table_row_type_parameter1.bal": [
+ {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 5
+ },
+ "end": {
+ "line": 0,
+ "character": 11
+ }
+ },
+ "newText": "Student"
+ },
+ {
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 10
+ },
+ "end": {
+ "line": 6,
+ "character": 16
+ }
+ },
+ "newText": "Student"
+ }
+ ]
+ }
+ }
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_table_row_type_parameter2.json b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_table_row_type_parameter2.json
new file mode 100644
index 000000000000..e0c14a558e61
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_table_row_type_parameter2.json
@@ -0,0 +1,70 @@
+{
+ "source": {
+ "file": "rename_table_row_type_parameter2.bal"
+ },
+ "position": {
+ "line": 7,
+ "character": 16
+ },
+ "prepareRename": {
+ "valid": true
+ },
+ "result": {
+ "changes": {
+ "rename_table_row_type_parameter2.bal": [
+ {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 5
+ },
+ "end": {
+ "line": 0,
+ "character": 11
+ }
+ },
+ "newText": "Student"
+ },
+ {
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 4
+ },
+ "end": {
+ "line": 6,
+ "character": 10
+ }
+ },
+ "newText": "Student"
+ },
+ {
+ "range": {
+ "start": {
+ "line": 7,
+ "character": 10
+ },
+ "end": {
+ "line": 7,
+ "character": 16
+ }
+ },
+ "newText": "Student"
+ },
+ {
+ "range": {
+ "start": {
+ "line": 8,
+ "character": 11
+ },
+ "end": {
+ "line": 8,
+ "character": 17
+ }
+ },
+ "newText": "Student"
+ }
+ ]
+ }
+ }
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_table_row_type_parameter3.json b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_table_row_type_parameter3.json
new file mode 100644
index 000000000000..70ebeacb467a
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/expected/single/rename_table_row_type_parameter3.json
@@ -0,0 +1,44 @@
+{
+ "source": {
+ "file": "rename_table_row_type_parameter1.bal"
+ },
+ "position": {
+ "line": 6,
+ "character": 13
+ },
+ "prepareRename": {
+ "valid": true
+ },
+ "result": {
+ "changes": {
+ "rename_table_row_type_parameter1.bal": [
+ {
+ "range": {
+ "start": {
+ "line": 0,
+ "character": 5
+ },
+ "end": {
+ "line": 0,
+ "character": 11
+ }
+ },
+ "newText": "Student"
+ },
+ {
+ "range": {
+ "start": {
+ "line": 6,
+ "character": 10
+ },
+ "end": {
+ "line": 6,
+ "character": 16
+ }
+ },
+ "newText": "Student"
+ }
+ ]
+ }
+ }
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/sources/project/main.bal b/language-server/modules/langserver-core/src/test/resources/rename/sources/project/main.bal
index 4c143350cad3..816fd0bcd572 100644
--- a/language-server/modules/langserver-core/src/test/resources/rename/sources/project/main.bal
+++ b/language-server/modules/langserver-core/src/test/resources/rename/sources/project/main.bal
@@ -15,4 +15,7 @@ public function main() {
int localInt = module1:gInt;
module2:setName(fname = "John", lname = "Doe");
+
+ stream s = new;
+ table tHuman = table [{id: 1, name: "Jane"}];
}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/sources/project/modules/module2/types.bal b/language-server/modules/langserver-core/src/test/resources/rename/sources/project/modules/module2/types.bal
index e267324e7d5f..c03e271fb9e7 100644
--- a/language-server/modules/langserver-core/src/test/resources/rename/sources/project/modules/module2/types.bal
+++ b/language-server/modules/langserver-core/src/test/resources/rename/sources/project/modules/module2/types.bal
@@ -1 +1,6 @@
public type Mod1Error error;
+
+public type Human record {|
+ readonly int id;
+ string name;
+|};
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_map_type_parameter.bal b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_map_type_parameter.bal
new file mode 100644
index 000000000000..04dace1d2832
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_map_type_parameter.bal
@@ -0,0 +1,8 @@
+type Person record {|
+ readonly int id;
+ string name;
+|};
+
+function foo() {
+ map m = new;
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_stream_type_parameter.bal b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_stream_type_parameter.bal
new file mode 100644
index 000000000000..8bd2017f31d4
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_stream_type_parameter.bal
@@ -0,0 +1,9 @@
+type Person record {|
+ readonly int id;
+ string name;
+|};
+
+function foo() {
+ Person p = { id: 1, name: "foo" };
+ stream s = new;
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_table_row_type_parameter1.bal b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_table_row_type_parameter1.bal
new file mode 100644
index 000000000000..2c2d75d578ef
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_table_row_type_parameter1.bal
@@ -0,0 +1,8 @@
+type Person record {|
+ readonly int id;
+ string name;
+|};
+
+function foo() {
+ table tHuman = table [{id: 1, name: "Jane"}];
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_table_row_type_parameter2.bal b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_table_row_type_parameter2.bal
new file mode 100644
index 000000000000..14931acdb3b9
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_table_row_type_parameter2.bal
@@ -0,0 +1,10 @@
+type Person record {|
+ readonly int id;
+ string name;
+|};
+
+function foo() {
+ Person p = { id: 1, name: "foo" };
+ table tHuman = table [{id: 1, name: "Jane"}];
+ stream s = new;
+}
diff --git a/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_table_row_type_parameter3.bal b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_table_row_type_parameter3.bal
new file mode 100644
index 000000000000..2c2d75d578ef
--- /dev/null
+++ b/language-server/modules/langserver-core/src/test/resources/rename/sources/single/rename_table_row_type_parameter3.bal
@@ -0,0 +1,8 @@
+type Person record {|
+ readonly int id;
+ string name;
+|};
+
+function foo() {
+ table tHuman = table [{id: 1, name: "Jane"}];
+}
diff --git a/misc/ballerina-bindgen/src/main/java/org/ballerinalang/bindgen/model/JClass.java b/misc/ballerina-bindgen/src/main/java/org/ballerinalang/bindgen/model/JClass.java
index 54f15dd6e318..45ddd6866929 100644
--- a/misc/ballerina-bindgen/src/main/java/org/ballerinalang/bindgen/model/JClass.java
+++ b/misc/ballerina-bindgen/src/main/java/org/ballerinalang/bindgen/model/JClass.java
@@ -131,7 +131,7 @@ private void populateConstructors(Constructor[] constructors) {
}
}
tempList.sort(Comparator.comparing(JConstructor::getParamTypes));
- for (JConstructor constructor:tempList) {
+ for (JConstructor constructor : tempList) {
JConstructor jConstructor = new JConstructor(constructor.getConstructor(), env,
this, "new" + shortClassName + i);
if (modulesFlag) {
diff --git a/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingOptions.java b/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingOptions.java
index 214b8eb4405e..938ebeb76881 100644
--- a/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingOptions.java
+++ b/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingOptions.java
@@ -30,17 +30,20 @@ public class FormattingOptions {
private boolean lineWrapping;
+ private int continuationIndent;
+
private ForceFormattingOptions forceFormattingOptions;
private ImportFormattingOptions importFormattingOptions;
private FormattingOptions(int tabSize, String wsCharacter, int columnLimit, boolean lineWrapping,
- ForceFormattingOptions forceFormattingOptions,
+ int continuationIndent, ForceFormattingOptions forceFormattingOptions,
ImportFormattingOptions importFormattingOptions) {
this.tabSize = tabSize;
this.wsCharacter = wsCharacter;
this.columnLimit = columnLimit;
this.lineWrapping = lineWrapping;
+ this.continuationIndent = continuationIndent;
this.forceFormattingOptions = forceFormattingOptions;
this.importFormattingOptions = importFormattingOptions;
}
@@ -140,6 +143,10 @@ public void setLineWrapping(boolean lineWrapping) {
this.lineWrapping = lineWrapping;
}
+ public int getContinuationIndent() {
+ return continuationIndent;
+ }
+
public ForceFormattingOptions getForceFormattingOptions() {
return forceFormattingOptions;
}
@@ -162,6 +169,7 @@ public static class FormattingOptionsBuilder {
private String wsCharacter = " ";
private int columnLimit = 120;
private boolean lineWrapping = false;
+ private int continuationIndent = 2;
private ForceFormattingOptions forceFormattingOptions = ForceFormattingOptions.builder().build();
private ImportFormattingOptions importFormattingOptions = ImportFormattingOptions.builder().build();
@@ -198,8 +206,8 @@ public FormattingOptions.FormattingOptionsBuilder setImportFormattingOptions(
}
public FormattingOptions build() {
- return new FormattingOptions(tabSize, wsCharacter, columnLimit, lineWrapping, forceFormattingOptions,
- importFormattingOptions);
+ return new FormattingOptions(tabSize, wsCharacter, columnLimit, lineWrapping, continuationIndent,
+ forceFormattingOptions, importFormattingOptions);
}
}
}
diff --git a/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingTreeModifier.java b/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingTreeModifier.java
index 6526e00fadbe..185d1094f875 100644
--- a/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingTreeModifier.java
+++ b/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingTreeModifier.java
@@ -365,10 +365,10 @@ public FunctionSignatureNode transform(FunctionSignatureNode functionSignatureNo
Token openPara = formatToken(functionSignatureNode.openParenToken(), 0, parenTrailingNL);
// Start a new indentation of two tabs for the parameters.
- indent(2);
+ indent(options.getContinuationIndent());
SeparatedNodeList parameters =
formatSeparatedNodeList(functionSignatureNode.parameters(), 0, 0, 0, 0, 0, 0, true);
- unindent(2);
+ unindent(options.getContinuationIndent());
Token closePara;
ReturnTypeDescriptorNode returnTypeDesc = null;
@@ -1062,8 +1062,15 @@ public ReturnStatementNode transform(ReturnStatementNode returnStatementNode) {
public FunctionCallExpressionNode transform(FunctionCallExpressionNode functionCallExpressionNode) {
NameReferenceNode functionName = formatNode(functionCallExpressionNode.functionName(), 0, 0);
Token functionCallOpenPara = formatToken(functionCallExpressionNode.openParenToken(), 0, 0);
+ int prevIndentation = env.currentIndentation;
+ if (functionCallExpressionNode.arguments().size() > 0) {
+ if (!isScopedFunctionArgument(functionCallExpressionNode.arguments().get(0))) {
+ indent(options.getContinuationIndent());
+ }
+ }
SeparatedNodeList arguments = formatSeparatedNodeList(functionCallExpressionNode
- .arguments(), 0, 0, 0, 0);
+ .arguments(), 0, 0, 0, 0, true);
+ env.currentIndentation = prevIndentation;
Token functionCallClosePara = formatToken(functionCallExpressionNode.closeParenToken(),
env.trailingWS, env.trailingNL);
@@ -1836,6 +1843,9 @@ public MarkdownCodeLineNode transform(MarkdownCodeLineNode markdownCodeLineNode)
@Override
public PositionalArgumentNode transform(PositionalArgumentNode positionalArgumentNode) {
+ if (env.lineLength != 0 && isScopedFunctionArgument(positionalArgumentNode)) {
+ env.currentIndentation = env.lineLength;
+ }
ExpressionNode expression = formatNode(positionalArgumentNode.expression(), env.trailingWS, env.trailingNL);
return positionalArgumentNode.modify()
.withExpression(expression)
@@ -4472,10 +4482,14 @@ private void preserveIndentation(boolean value) {
*/
private int getPreservedIndentation(Token token) {
int position = token.lineRange().startLine().offset();
- int offset = position % 4;
+ int tabSize = options.getTabSize();
+ int offset = position % tabSize;
+ if (env.currentIndentation % tabSize == 0 && env.currentIndentation > position) {
+ return env.currentIndentation;
+ }
if (offset != 0) {
if (offset > 2) {
- position = position + 4 - offset;
+ position = position + tabSize - offset;
} else {
position = position - offset;
}
@@ -4713,4 +4727,15 @@ private NodeList sortAndGroupImportDeclarationNodes(
imports.addAll(thirdPartyImportNodes.stream().collect(Collectors.toList()));
return NodeFactory.createNodeList(imports);
}
+
+ private boolean isScopedFunctionArgument(FunctionArgumentNode functionArgumentNode) {
+ if (functionArgumentNode.parent().kind() == SyntaxKind.FUNCTION_CALL &&
+ functionArgumentNode.children().size() > 0) {
+ SyntaxKind kind = functionArgumentNode.children().get(0).kind();
+ if (kind == SyntaxKind.OBJECT_CONSTRUCTOR || kind == SyntaxKind.MAPPING_CONSTRUCTOR) {
+ return true;
+ }
+ }
+ return false;
+ }
}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/misc/linebreaks/assert/line_breaks_3.bal b/misc/formatter/modules/formatter-core/src/test/resources/misc/linebreaks/assert/line_breaks_3.bal
index 2ae7f56b3534..6ce4f5736fdd 100644
--- a/misc/formatter/modules/formatter-core/src/test/resources/misc/linebreaks/assert/line_breaks_3.bal
+++ b/misc/formatter/modules/formatter-core/src/test/resources/misc/linebreaks/assert/line_breaks_3.bal
@@ -1,7 +1,7 @@
public function foo() {
(
) y = ()
-;
+ ;
var x = ();
int
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/misc/linebreaks/assert/line_breaks_4.bal b/misc/formatter/modules/formatter-core/src/test/resources/misc/linebreaks/assert/line_breaks_4.bal
index c314dd697088..cbf973139ef2 100644
--- a/misc/formatter/modules/formatter-core/src/test/resources/misc/linebreaks/assert/line_breaks_4.bal
+++ b/misc/formatter/modules/formatter-core/src/test/resources/misc/linebreaks/assert/line_breaks_4.bal
@@ -1,7 +1,7 @@
public function foo() {
foreach string animal in animals {
match
- animal
+ animal
{
"Mouse" =>
{
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_2.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_2.bal
new file mode 100644
index 000000000000..d4b192fb7f58
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_2.bal
@@ -0,0 +1,13 @@
+import ballerina/io;
+
+function calculateTotalInvoiceAmount(int customerId, string invoiceDate,
+ decimal[] itemPrices, boolean isTaxable) returns decimal {
+ decimal totalAmount = 0.0;
+ return totalAmount;
+}
+
+public function main() {
+ decimal invoiceAmount = calculateTotalInvoiceAmount(12345, "2023-09-13",
+ [25.99, 19.95, 12.49, 7.99, 34.50], true);
+ io:println(invoiceAmount);
+}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_3.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_3.bal
new file mode 100644
index 000000000000..b4570806ec28
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_3.bal
@@ -0,0 +1,21 @@
+function calculate() returns int {
+ int result = subtract(add([21, 45, 6, 12, 67, 89], [1, 5, 6, 9]),
+ add([11, 12, 13, 14, 15, 16, 17, 18, 19, 20],
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]));
+ return result;
+}
+
+function add(int[] a, int[] b) returns int {
+ int sum = 0;
+ foreach int n in a {
+ sum += n;
+ }
+ foreach int n in b {
+ sum += n;
+ }
+ return sum;
+}
+
+function subtract(int x, int y) returns int {
+ return x - y;
+}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_4.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_4.bal
new file mode 100644
index 000000000000..b7be24b37726
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_4.bal
@@ -0,0 +1,13 @@
+type SourcePatient record {
+ string message;
+ string detail;
+ string cause;
+};
+
+function foo(string m, int c, int t, string d, string cause) {
+}
+
+function bar(SourcePatient sourcePatient, int errorCode, int errorType) {
+ return foo(sourcePatient.message, errorCode, errorType, sourcePatient.detail,
+ sourcePatient.cause);
+}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_5.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_5.bal
new file mode 100644
index 000000000000..061faf40c6f2
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_5.bal
@@ -0,0 +1,32 @@
+public function main() {
+ foo(object {
+ int i = 1;
+ }, a,
+ b);
+}
+
+public function bar() {
+ bar(t1, object {
+ int i = 1;
+ }, t2, t3);
+}
+
+public function baz() {
+ baz(t1, t2, object {
+ int i = 1;
+ int y = 2;
+ },
+ b,
+ c,
+ d);
+}
+
+public function fox() {
+ foz(t1,
+ object {
+ int i = 1;
+ },
+ b,
+ c,
+ d);
+}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_6.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_6.bal
new file mode 100644
index 000000000000..5f3cb33a835a
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/assert/call_statement_6.bal
@@ -0,0 +1,21 @@
+function processEmployeeInfo(string firstName, string lastName, string department, string jobTitle,
+ int employeeId, float salary) {
+}
+
+function foo() {
+ string firstName = "John";
+ string lastName = "Doe";
+ string department = "Engineering";
+ string jobTitle = "Software Engineer";
+ int employeeId = 1001;
+ float salary = 75000.0;
+
+ processEmployeeInfo(
+ firstName,
+ lastName,
+ department,
+ jobTitle,
+ employeeId,
+ salary
+ );
+}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_2.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_2.bal
new file mode 100644
index 000000000000..fe29d6cb3bdd
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_2.bal
@@ -0,0 +1,13 @@
+import ballerina/io;
+
+function calculateTotalInvoiceAmount(int customerId, string invoiceDate,
+ decimal[] itemPrices, boolean isTaxable) returns decimal {
+ decimal totalAmount = 0.0;
+ return totalAmount;
+}
+
+public function main() {
+ decimal invoiceAmount = calculateTotalInvoiceAmount ( 12345, "2023-09-13",
+ [25.99, 19.95, 12.49, 7.99, 34.50], true ) ;
+ io:println ( invoiceAmount ) ;
+}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_3.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_3.bal
new file mode 100644
index 000000000000..a64ab1eecd1b
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_3.bal
@@ -0,0 +1,21 @@
+function calculate() returns int {
+ int result = subtract(add([21, 45, 6, 12, 67, 89], [1,5,6,9]),
+ add([11,12,13,14,15,16,17,18,19,20],
+ [1,2,3,4,5,6,7,8,9,10]));
+ return result;
+}
+
+function add(int[] a, int[] b) returns int {
+ int sum = 0;
+ foreach int n in a {
+ sum += n;
+ }
+ foreach int n in b {
+ sum += n;
+ }
+ return sum;
+}
+
+function subtract(int x, int y) returns int {
+ return x - y;
+}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_4.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_4.bal
new file mode 100644
index 000000000000..46a52510845b
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_4.bal
@@ -0,0 +1,13 @@
+type SourcePatient record {
+ string message;
+ string detail;
+ string cause;
+};
+
+function foo(string m, int c, int t, string d, string cause) {
+}
+
+function bar(SourcePatient sourcePatient, int errorCode, int errorType) {
+ return foo(sourcePatient.message, errorCode, errorType, sourcePatient.detail,
+ sourcePatient.cause);
+}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_5.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_5.bal
new file mode 100644
index 000000000000..4b94f5bbf6cd
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_5.bal
@@ -0,0 +1,32 @@
+public function main() {
+ foo(object {
+ int i = 1;
+ }, a,
+ b);
+}
+
+public function bar() {
+ bar(t1, object {
+ int i = 1;
+ }, t2, t3);
+}
+
+public function baz() {
+ baz(t1, t2, object {
+ int i = 1;
+ int y = 2;
+ },
+ b,
+ c,
+ d);
+}
+
+public function fox() {
+ foz(t1,
+ object {
+ int i = 1;
+ },
+ b,
+ c,
+ d);
+}
diff --git a/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_6.bal b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_6.bal
new file mode 100644
index 000000000000..1601f40175a2
--- /dev/null
+++ b/misc/formatter/modules/formatter-core/src/test/resources/statements/call/source/call_statement_6.bal
@@ -0,0 +1,21 @@
+function processEmployeeInfo(string firstName, string lastName, string department, string jobTitle,
+ int employeeId, float salary) {
+}
+
+function foo() {
+ string firstName = "John";
+ string lastName = "Doe";
+ string department = "Engineering";
+ string jobTitle = "Software Engineer";
+ int employeeId = 1001;
+ float salary = 75000.0;
+
+ processEmployeeInfo(
+ firstName,
+ lastName,
+ department,
+ jobTitle,
+ employeeId,
+ salary
+ );
+}
diff --git a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java b/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java
index dd9722b53eb8..e29f1801e14e 100644
--- a/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java
+++ b/tests/jballerina-integration-test/src/test/java/org/ballerinalang/test/packaging/ModuleExecutionFlowTests.java
@@ -140,6 +140,8 @@ public void testStopHandlerExecution() throws BallerinaTestException {
LogLeecher infoLeecher1 = new LogLeecher("Stopped stopHandlerFunc3");
LogLeecher infoLeecher2 = new LogLeecher("Stopped stopHandlerFunc2");
LogLeecher infoLeecher3 = new LogLeecher("Stopped stopHandlerFunc1");
+ LogLeecher infoLeecher4 = new LogLeecher("Stopped inlineStopHandler");
+ serverInstance.addLogLeecher(infoLeecher4);
serverInstance.addLogLeecher(infoLeecher1);
serverInstance.addLogLeecher(infoLeecher2);
serverInstance.addLogLeecher(infoLeecher3);
diff --git a/tests/jballerina-integration-test/src/test/resources/packaging/stop_handler_execution/main.bal b/tests/jballerina-integration-test/src/test/resources/packaging/stop_handler_execution/main.bal
index 41637860fe75..54bd4a2819be 100644
--- a/tests/jballerina-integration-test/src/test/resources/packaging/stop_handler_execution/main.bal
+++ b/tests/jballerina-integration-test/src/test/resources/packaging/stop_handler_execution/main.bal
@@ -22,19 +22,19 @@ int count = 0;
function stopHandlerFunc1() returns error? {
incrementCount();
- assertCount(5);
+ assertCount(6);
println("Stopped stopHandlerFunc1");
}
function stopHandlerFunc2() returns error? {
incrementCount();
- assertCount(4);
+ assertCount(5);
println("Stopped stopHandlerFunc2");
}
function stopHandlerFunc3() returns error? {
incrementCount();
- assertCount(3);
+ assertCount(4);
println("Stopped stopHandlerFunc3");
}
@@ -49,6 +49,12 @@ public function main() {
incrementCount();
assertCount(2);
runtime:onGracefulStop(stopHandlerFunc3);
+ runtime:StopHandler inlineStopHandler = function() returns error? {
+ incrementCount();
+ assertCount(3);
+ println("Stopped inlineStopHandler");
+ };
+ runtime:onGracefulStop(inlineStopHandler);
runtime:sleep(3);
}
diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/AbstractClass.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/AbstractClass.java
new file mode 100644
index 000000000000..34a5b4681be2
--- /dev/null
+++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/AbstractClass.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved.
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ballerinalang.nativeimpl.jvm.tests;
+
+import io.ballerina.runtime.api.values.BString;
+
+/**
+ * This class contains abstract methods required for interoperability testing.
+ *
+ * @since 2201.9.0
+ */
+public abstract class AbstractClass {
+
+ public abstract BString getMessage();
+}
diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/ClassWithDefaultConstructor.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/ClassWithDefaultConstructor.java
index b81e4f01f7b2..3c4320bd9d63 100644
--- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/ClassWithDefaultConstructor.java
+++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/ClassWithDefaultConstructor.java
@@ -17,12 +17,15 @@
*/
package org.ballerinalang.nativeimpl.jvm.tests;
+import io.ballerina.runtime.api.utils.StringUtils;
+import io.ballerina.runtime.api.values.BString;
+
/**
* This class is used for Java interoperability tests.
*
* @since 1.0.0
*/
-public class ClassWithDefaultConstructor {
+public class ClassWithDefaultConstructor extends AbstractClass {
private int a;
public ClassWithDefaultConstructor() {
@@ -32,4 +35,9 @@ public ClassWithDefaultConstructor() {
public Integer getValue() {
return a;
}
+
+ @Override
+ public BString getMessage() {
+ return StringUtils.fromString("Hello from Java!");
+ }
}
diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/Interface.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/Interface.java
new file mode 100644
index 000000000000..b81b3b4ad6e2
--- /dev/null
+++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/nativeimpl/jvm/tests/Interface.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved.
+ *
+ * WSO2 LLC. licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ballerinalang.nativeimpl.jvm.tests;
+
+import io.ballerina.runtime.api.values.BString;
+
+/**
+ * This is an interface used for interoperability testing.
+ *
+ * @since 2201.9.0
+ */
+public interface Interface {
+
+ BString getMessage();
+}
diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/InstanceMethodTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/InstanceMethodTest.java
index 8cd9ab6dd04c..01dc960316ca 100644
--- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/InstanceMethodTest.java
+++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/InstanceMethodTest.java
@@ -286,6 +286,11 @@ public Object[] unionWithErrorTestFunctions() {
};
}
+ @Test
+ public void testInteropCallToAbstractClassMethod() {
+ BRunUtil.invoke(result, "testInteropCallToAbstractClassMethod");
+ }
+
@AfterClass
public void tearDown() {
result = null;
diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java
index c73e6c70a6bf..a3381dab4d75 100644
--- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java
+++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/javainterop/basic/NegativeValidationTest.java
@@ -539,4 +539,17 @@ public void testMethodSignatureNotMatch17() {
"no return type expected but found 'error''",
"method_sig_not_match17.bal", 19, 1);
}
+
+ @Test
+ public void testAbstractClassInstantiationError() {
+ String path = "test-src/javainterop/negative/instantiation_error.bal";
+ CompileResult compileResult = BCompileUtil.compile(path);
+ Assert.assertEquals(compileResult.getDiagnostics().length, 2);
+ BAssertUtil.validateError(compileResult, 0, "{ballerina/jballerina.java}INSTANTIATION_ERROR" +
+ " ''org.ballerinalang.nativeimpl.jvm.tests.AbstractClass' is abstract, " +
+ "and cannot be instantiated'", 19, 1);
+ BAssertUtil.validateError(compileResult, 1, "{ballerina/jballerina.java}INSTANTIATION_ERROR" +
+ " ''org.ballerinalang.nativeimpl.jvm.tests.Interface' is abstract, and cannot be instantiated'",
+ 23, 1);
+ }
}
diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/record/RecordAssignabilityTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/record/RecordAssignabilityTest.java
index f985d7c68353..56c42e8fe54b 100644
--- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/record/RecordAssignabilityTest.java
+++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/record/RecordAssignabilityTest.java
@@ -20,6 +20,8 @@
import org.ballerinalang.test.BCompileUtil;
import org.ballerinalang.test.BRunUtil;
import org.ballerinalang.test.CompileResult;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
@@ -31,7 +33,12 @@
*/
public class RecordAssignabilityTest {
- private final CompileResult result = BCompileUtil.compile("test-src/record/record_assignability.bal");
+ private CompileResult result;
+
+ @BeforeClass
+ public void setup() {
+ result = BCompileUtil.compile("test-src/record/record_assignability.bal");
+ }
@DataProvider
public static Object[] recordAssignabilityTestFunctions() {
@@ -95,4 +102,9 @@ public void testRecordAssignabilityNegative() {
"found 'record {| readonly int? b; int...; |}'", 70, 33);
assertEquals(negativeResult.getErrorCount(), i);
}
+
+ @AfterClass
+ public void tearDown() {
+ result = null;
+ }
}
diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/runtime/api/RuntimeAPITest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/runtime/api/RuntimeAPITest.java
index 19480a6932ef..7ca9edaca1d8 100644
--- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/runtime/api/RuntimeAPITest.java
+++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/runtime/api/RuntimeAPITest.java
@@ -45,7 +45,6 @@ public Object[] packageNameProvider() {
"invalid_values",
"async",
"utils",
- "stop_handler",
"identifier_utils",
"environment"
};
diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/basic/instance_method_tests.bal b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/basic/instance_method_tests.bal
index 47f8269d41c8..86c9789a7892 100644
--- a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/basic/instance_method_tests.bal
+++ b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/basic/instance_method_tests.bal
@@ -267,6 +267,21 @@ public function testBalEnvAcceptingMethodRetType(handle receiver) {
test:assertEquals(mapResult, {"a":10,"b":12.5});
}
+public function testInteropCallToAbstractClassMethod() {
+ handle receiver = getConstructor();
+ string message = getMessage(receiver);
+ test:assertEquals(message, "Hello from Java!");
+}
+
+function getMessage(handle receiver) returns string = @java:Method {
+ name: "getMessage",
+ 'class:"org/ballerinalang/nativeimpl/jvm/tests/AbstractClass"
+} external;
+
+function getConstructor() returns handle = @java:Constructor {
+ 'class: "org.ballerinalang.nativeimpl.jvm.tests.ClassWithDefaultConstructor"
+} external;
+
function assertEquals(anydata|error expected, anydata|error actual) {
if isEqual(actual, expected) {
return;
diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/instantiation_error.bal b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/instantiation_error.bal
new file mode 100644
index 000000000000..864f055cf3d3
--- /dev/null
+++ b/tests/jballerina-unit-test/src/test/resources/test-src/javainterop/negative/instantiation_error.bal
@@ -0,0 +1,25 @@
+// Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved.
+//
+// WSO2 LLC. licenses this file to you under the Apache License,
+// Version 2.0 (the "License"); you may not use this file except
+// in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+import ballerina/jballerina.java;
+
+function getAbstractClass() returns handle = @java:Constructor {
+ 'class: "org.ballerinalang.nativeimpl.jvm.tests.AbstractClass"
+} external;
+
+function getInterface() returns handle = @java:Constructor {
+ 'class: "org.ballerinalang.nativeimpl.jvm.tests.Interface"
+} external;
diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/Ballerina.toml b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/Ballerina.toml
deleted file mode 100644
index 1b09d3767f68..000000000000
--- a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/Ballerina.toml
+++ /dev/null
@@ -1,4 +0,0 @@
-[package]
-org= "testorg"
-name="stop_handler"
-version= "1.0.0"
diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal
deleted file mode 100644
index 5660560faa34..000000000000
--- a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/main.bal
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright (c) 2022 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
-//
-// WSO2 Inc. licenses this file to you under the Apache License,
-// Version 2.0 (the "License"); you may not use this file except
-// in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-import ballerina/lang.runtime;
-import ballerina/test;
-
-import stop_handler.moduleA;
-
-function stopHandlerFunc1() returns error? {
- runtime:sleep(1);
- moduleA:incrementCount();
- moduleA:assertCount(10);
-}
-
-function stopHandlerFunc2() returns error? {
- moduleA:incrementCount();
- moduleA:assertCount(9);
-}
-
-function stopHandlerFunc3() returns error? {
- runtime:sleep(0.5);
- moduleA:incrementCount();
- moduleA:assertCount(7);
-}
-
-function stopHandlerFunc4() returns error? {
- runtime:sleep(1.5);
- moduleA:incrementCount();
- moduleA:assertCount(8);
-}
-
-function init() {
- moduleA:incrementCount();
- moduleA:assertCount(1);
- runtime:onGracefulStop(stopHandlerFunc1);
- runtime:onGracefulStop(stopHandlerFunc2);
- runtime:onGracefulStop(stopHandlerFunc4);
-}
-
-final moduleA:ListenerObj lo = new moduleA:ListenerObj("ModDyncListener");
-
-public function main() {
- moduleA:incrementCount();
- moduleA:assertCount(2);
- runtime:registerListener(lo);
- runtime:onGracefulStop(stopHandlerFunc3);
-
- checkpanic lo.'start();
- error? v = lo.gracefulStop();
- if (v is error) {
- test:assertEquals(v.message(), "listener in main stopped");
- }
- runtime:deregisterListener(lo);
- moduleA:main();
-}
diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal
deleted file mode 100644
index 088aca81c2b2..000000000000
--- a/tests/jballerina-unit-test/src/test/resources/test-src/runtime/api/stop_handler/modules/moduleA/main.bal
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright (c) 2022 WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
-//
-// WSO2 Inc. licenses this file to you under the Apache License,
-// Version 2.0 (the "License"); you may not use this file except
-// in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied. See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-import ballerina/lang.runtime;
-import ballerina/test;
-
-int count = 0;
-
-function stopHandlerFunc1() returns error? {
- runtime:sleep(1);
- incrementCount();
- assertCount(11);
-}
-
-function stopHandlerFunc2() returns error? {
- incrementCount();
- assertCount(6);
-}
-
-function init() {
- runtime:onGracefulStop(stopHandlerFunc1);
-}
-
-public class ListenerObj {
-
- *runtime:DynamicListener;
- private string name = "";
-
- public function init(string name) {
- self.name = name;
- }
-
- public function 'start() returns error? {
- if (self.name == "ModDyncListener") {
- incrementCount();
- assertCount(3);
- }
- }
-
- public function gracefulStop() returns error? {
- if (self.name == "ModDyncListener") {
- runtime:sleep(1.5);
- incrementCount();
- assertCount(4);
- return error("listener in main stopped");
- } else if (self.name == "ModDyncListenerA") {
- return error("listener in moduleA stopped");
- }
- }
-
- public function immediateStop() {
- }
-
- public function attach(service object {} s, string[]|string? name = ()) returns error? {
- }
-
- public function detach(service object {} s) returns error? {
- }
-}
-
-final ListenerObj lo = new ListenerObj("ModDyncListenerA");
-
-public function main() {
- incrementCount();
- assertCount(5);
- runtime:registerListener(lo);
- runtime:onGracefulStop(stopHandlerFunc2);
-
- checkpanic lo.'start();
- error? v = lo.gracefulStop();
- if (v is error) {
- test:assertEquals(v.message(), "listener in moduleA stopped");
- }
- runtime:deregisterListener(lo);
-}
-
-public function incrementCount() {
- count += 1;
-}
-
-public function assertCount(int val) {
- test:assertEquals(count, val);
-}