diff --git a/.github/workflows/daily_build.yml b/.github/workflows/daily_build.yml index f861e10a339f..f23d9a6f55fe 100644 --- a/.github/workflows/daily_build.yml +++ b/.github/workflows/daily_build.yml @@ -15,11 +15,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Initialize sub-modules run: git submodule update --init @@ -34,7 +34,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '17.0.7' + java-version: '21.0.3' distribution: 'graalvm' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -69,11 +69,11 @@ jobs: with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Initialize sub-modules run: git submodule update --init diff --git a/.github/workflows/daily_spec_conformance_test_runner.yml b/.github/workflows/daily_spec_conformance_test_runner.yml index 5b19e8f092db..7b506a45f943 100644 --- a/.github/workflows/daily_spec_conformance_test_runner.yml +++ b/.github/workflows/daily_spec_conformance_test_runner.yml @@ -17,7 +17,7 @@ jobs: with: ref: spec-conformance-test-runner - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: "temurin" diff --git a/.github/workflows/nightly_publish_timestamped_release.yml b/.github/workflows/nightly_publish_timestamped_release.yml index 653d06697230..38f23702422d 100644 --- a/.github/workflows/nightly_publish_timestamped_release.yml +++ b/.github/workflows/nightly_publish_timestamped_release.yml @@ -21,11 +21,11 @@ jobs: with: ref: ${{ matrix.branch }} - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Initialize Sub Modules run: git submodule update --init diff --git a/.github/workflows/observe_package_push.yaml b/.github/workflows/observe_package_push.yaml index 7740cd92010a..f6077c169a4b 100644 --- a/.github/workflows/observe_package_push.yaml +++ b/.github/workflows/observe_package_push.yaml @@ -17,11 +17,11 @@ jobs: fetch-depth: 0 - name: Checkout Tag run: git checkout ${{ github.event.inputs.repoTag }} - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Build with Gradle env: diff --git a/.github/workflows/publish_release.yml b/.github/workflows/publish_release.yml index bf1d51fc6df5..ed20a92395cd 100644 --- a/.github/workflows/publish_release.yml +++ b/.github/workflows/publish_release.yml @@ -9,11 +9,11 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Set version env variable run: | echo "VERSION=$(./gradlew properties | grep ^version: | cut -d\ -f2 | sed 's@-SNAPSHOT@@')" >> $GITHUB_ENV diff --git a/.github/workflows/publish_timestamped_release.yml b/.github/workflows/publish_timestamped_release.yml index 489a1168d272..303a6a7f5ca5 100644 --- a/.github/workflows/publish_timestamped_release.yml +++ b/.github/workflows/publish_timestamped_release.yml @@ -16,11 +16,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Checkout To Lang Branch run: | diff --git a/.github/workflows/pull_request_full_build.yml b/.github/workflows/pull_request_full_build.yml index db3abe3141bd..3dfb0af42d50 100644 --- a/.github/workflows/pull_request_full_build.yml +++ b/.github/workflows/pull_request_full_build.yml @@ -19,11 +19,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Checkout To Lang Branch run: | @@ -66,11 +66,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Setup NodeJs uses: actions/setup-node@v4 @@ -93,12 +93,6 @@ jobs: do git clone https://github.com/ballerina-platform/${module_name}.git; \ done -# - name: Checkout non-default branch -# run: | -# for module_name in $(jq -r '.standard_library| .[] | select(.level==${{ matrix.level }}) | .name' extensions.json); do \ -# cd $module_name && git fetch origin && git checkout -t origin/java_17_migration && cd ..; \ -# done - - name: Update Lang Version in Module run: | for module_name in $(jq -r '.standard_library| .[] | select(.level==${{ matrix.level }}) | .name' extensions.json); do \ @@ -133,11 +127,11 @@ jobs: with: repository: 'ballerina-platform/ballerina-distribution' - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Download Ballerina Lang Artifacts uses: actions/download-artifact@v4 diff --git a/.github/workflows/pull_request_ubuntu_build.yml b/.github/workflows/pull_request_ubuntu_build.yml index 405e9ff2d968..9b4f27ed476f 100644 --- a/.github/workflows/pull_request_ubuntu_build.yml +++ b/.github/workflows/pull_request_ubuntu_build.yml @@ -30,11 +30,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Initialize sub-modules run: git submodule update --init @@ -49,7 +49,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '17.0.7' + java-version: '21.0.3' distribution: 'graalvm' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -88,11 +88,11 @@ jobs: with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Initialize sub-modules run: git submodule update --init diff --git a/.github/workflows/pull_request_windows_build.yml b/.github/workflows/pull_request_windows_build.yml index 3f5f87f11f2c..3f3a03b0b111 100644 --- a/.github/workflows/pull_request_windows_build.yml +++ b/.github/workflows/pull_request_windows_build.yml @@ -30,11 +30,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: configure Pagefile uses: al-cheb/configure-pagefile-action@v1.4 @@ -56,7 +56,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '17.0.7' + java-version: '21.0.3' distribution: 'graalvm' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/push_master.yml b/.github/workflows/push_master.yml index 962eef94076a..67dfa66c8724 100644 --- a/.github/workflows/push_master.yml +++ b/.github/workflows/push_master.yml @@ -19,11 +19,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Initialize sub-modules run: git submodule update --init @@ -38,7 +38,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '17.0.7' + java-version: '21.0.3' distribution: 'graalvm' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -63,11 +63,11 @@ jobs: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: configure Pagefile uses: al-cheb/configure-pagefile-action@v1.4 @@ -89,7 +89,7 @@ jobs: - name: Setup GraalVM uses: graalvm/setup-graalvm@v1 with: - java-version: '17.0.7' + java-version: '21.0.3' distribution: 'graalvm' components: 'native-image' github-token: ${{ secrets.GITHUB_TOKEN }} @@ -113,11 +113,11 @@ jobs: with: fetch-depth: 0 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Initialize sub-modules run: git submodule update --init diff --git a/.github/workflows/trivy-scan.yml b/.github/workflows/trivy-scan.yml index e9bee7d70e53..8a9caaddc065 100644 --- a/.github/workflows/trivy-scan.yml +++ b/.github/workflows/trivy-scan.yml @@ -12,11 +12,11 @@ jobs: steps: - name: Checkout Repository uses: actions/checkout@v4 - - name: Set up JDK 17 + - name: Set up JDK 21 uses: actions/setup-java@v4 with: distribution: 'temurin' - java-version: '17.0.7' + java-version: '21.0.3' - name: Initialize sub-modules run: git submodule update --init diff --git a/ballerina-shell/modules/shell-cli/spotbugs-exclude.xml b/ballerina-shell/modules/shell-cli/spotbugs-exclude.xml index 20d3d2c13706..40131734062f 100644 --- a/ballerina-shell/modules/shell-cli/spotbugs-exclude.xml +++ b/ballerina-shell/modules/shell-cli/spotbugs-exclude.xml @@ -21,6 +21,10 @@ - + + + + + diff --git a/ballerina-shell/modules/shell-core/src/main/java/io/ballerina/shell/invoker/ShellSnippetsInvoker.java b/ballerina-shell/modules/shell-core/src/main/java/io/ballerina/shell/invoker/ShellSnippetsInvoker.java index 19543b828c74..18b4f7af90d1 100644 --- a/ballerina-shell/modules/shell-core/src/main/java/io/ballerina/shell/invoker/ShellSnippetsInvoker.java +++ b/ballerina-shell/modules/shell-core/src/main/java/io/ballerina/shell/invoker/ShellSnippetsInvoker.java @@ -29,14 +29,14 @@ import io.ballerina.projects.JarResolver; import io.ballerina.projects.JvmTarget; import io.ballerina.projects.Module; +import io.ballerina.projects.Package; import io.ballerina.projects.PackageCompilation; import io.ballerina.projects.Project; import io.ballerina.projects.directory.SingleFileProject; import io.ballerina.projects.util.ProjectUtils; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.values.BFuture; -import io.ballerina.runtime.internal.scheduling.Scheduler; -import io.ballerina.runtime.internal.scheduling.Strand; +import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.internal.BalRuntime; +import io.ballerina.runtime.internal.scheduling.ClassloaderRuntime; import io.ballerina.shell.DiagnosticReporter; import io.ballerina.shell.exceptions.InvokerException; import io.ballerina.shell.exceptions.InvokerPanicException; @@ -51,18 +51,12 @@ import java.io.IOException; import java.io.PrintStream; import java.io.StringWriter; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; import java.nio.charset.Charset; -import java.nio.file.Path; import java.util.Arrays; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.Set; -import java.util.function.Function; /** * Invoker that invokes a command to evaluate a list of snippets. @@ -91,12 +85,6 @@ public abstract class ShellSnippetsInvoker extends DiagnosticReporter { private static final String TEMP_FILE_SUFFIX = ".bal"; /* Error type codes */ private static final String MODULE_NOT_FOUND_CODE = "BCE2003"; - - /** - * Scheduler used to run the init and main methods - * of the generated classes. - */ - private final Scheduler scheduler; /** * File object that is used to create projects and write. * Depending on USE_TEMP_FILE flag, this may be either a file in cwd @@ -105,7 +93,7 @@ public abstract class ShellSnippetsInvoker extends DiagnosticReporter { private File bufferFile; protected ShellSnippetsInvoker() { - this.scheduler = new Scheduler(false); + } /** @@ -350,8 +338,11 @@ private boolean containsModuleNotFoundError(PackageCompilation compilation) { protected void executeProject(ClassLoadContext context, String templateName) throws InvokerException { Project project = getProject(context, templateName); PackageCompilation compilation = compile(project); - JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(compilation, JvmTarget.JAVA_17); - executeProject(jBallerinaBackend); + JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(compilation, JvmTarget.JAVA_21); + Package pkg = project.currentPackage(); + io.ballerina.runtime.api.Module module = new io.ballerina.runtime.api.Module(pkg + .packageOrg().value(), pkg.packageName().value(), pkg.packageVersion().toString()); + executeProject(jBallerinaBackend, module); } /** @@ -360,36 +351,23 @@ protected void executeProject(ClassLoadContext context, String templateName) thr * The process is run and the stdout is collected and printed. * * @param jBallerinaBackend Backed to use. - * @throws InvokerException If execution failed. + * @param module Module to execute. */ - protected void executeProject(JBallerinaBackend jBallerinaBackend) throws InvokerException { + protected void executeProject(JBallerinaBackend jBallerinaBackend, io.ballerina.runtime.api.Module module) + throws InvokerPanicException { if (bufferFile == null) { throw new UnsupportedOperationException("Buffer file must be set before execution"); } PrintStream errorStream = getErrorStream(); try { - // Main method class name is file name without extension - String fileName = bufferFile.getName(); - String mainMethodClassName = fileName.substring(0, fileName.length() - TEMP_FILE_SUFFIX.length()); - JarResolver jarResolver = jBallerinaBackend.jarResolver(); ClassLoader classLoader = jarResolver.getClassLoaderWithRequiredJarFilesForExecution(); - // First run configure initialization - // TODO: (#28662) After configurables can be supported, change this to that file location - invokeMethodDirectly(classLoader, CONFIGURE_INIT_CLASS_NAME, CONFIGURE_INIT_METHOD_NAME, - new Class[]{Map.class, String[].class, Path[].class, String.class}, - new Object[]{new HashMap<>(), new String[]{}, new Path[]{}, null}); - // Initialize the module - invokeScheduledMethod(classLoader, MODULE_INIT_CLASS_NAME, MODULE_INIT_METHOD_NAME); - // Start the module - invokeScheduledMethod(classLoader, MODULE_INIT_CLASS_NAME, MODULE_START_METHOD_NAME); - // Then call run method - Object failErrorMessage = invokeScheduledMethod(classLoader, mainMethodClassName, MODULE_RUN_METHOD_NAME); + Object failErrorMessage = this.callRun(classLoader, module); if (failErrorMessage != null) { errorStream.println("fail: " + failErrorMessage); } - } catch (InvokerPanicException panicError) { + } catch (Throwable panicError) { List stacktrace = Arrays.stream(panicError.getCause().getStackTrace()) .filter(element -> !(element.toString().contains(MODULE_STATEMENT_METHOD_NAME) || element.toString().contains(MODULE_RUN_METHOD_NAME))) @@ -405,103 +383,40 @@ protected void executeProject(JBallerinaBackend jBallerinaBackend) throws Invoke /* Invocation methods */ /** - * Invokes a method that is in the given class. - * The method must be a static method accepting only one parameter, a {@link Strand}. + * Invokes a run function. * * @param classLoader Class loader to find the class. - * @param className Class name with the method. - * @param methodName Method name to invoke. - * @return The result of the invocation. - * @throws InvokerException If invocation failed. */ - protected Object invokeScheduledMethod(ClassLoader classLoader, String className, String methodName) - throws InvokerException { + protected Object callRun(ClassLoader classLoader, io.ballerina.runtime.api.Module module) + throws InvokerPanicException { + BalRuntime runtime = new ClassloaderRuntime(module, classLoader); + Object result; try { - addDebugDiagnostic(String.format("Running %s.%s on schedule", className, methodName)); - - // Get class and method references - Class clazz = classLoader.loadClass(className); - Method method = clazz.getDeclaredMethod(methodName, Strand.class); - Function methodInvocation = createInvokerCallback(method); - - // Schedule and run the function and return if result is valid - BFuture out = scheduler.schedule(new Object[1], methodInvocation, null, null, null, - PredefinedTypes.TYPE_ERROR, null, null); - scheduler.start(); - - Object result = out.getResult(); - Throwable panic = out.getPanic(); - - if (panic != null) { - // Unexpected runtime error - throw new InvokerPanicException(panic); + // Initialize the module + result = runtime.init(); + if (result instanceof Throwable throwable) { + throw new InvokerPanicException(throwable); } + // Start the module + result = runtime.start(); if (result instanceof Throwable throwable) { - // Function returned error (panic) throw new InvokerPanicException(throwable); } - return result; - } catch (ClassNotFoundException e) { - addErrorDiagnostic(className + " class not found: " + e.getMessage()); - throw new InvokerException(e); - } catch (NoSuchMethodException e) { - addErrorDiagnostic(methodName + " method not found: " + e.getMessage()); - throw new InvokerException(e); - } - } - - /** - * Invokes a method that is in the given class. - * This is directly invoked without scheduling. - * The method must be a static method accepting the given parameters. - * - * @param classLoader Class loader to find the class. - * @param className Class name with the method. - * @param methodName Method name to invoke. - * @param argTypes Types of arguments. - * @param args Arguments to provide. - * @return The result of the invocation. - * @throws InvokerException If invocation failed. - */ - protected Object invokeMethodDirectly(ClassLoader classLoader, String className, String methodName, - Class[] argTypes, Object[] args) throws InvokerException { - try { - // Get class and method references - addDebugDiagnostic(String.format("Running %s.%s directly", className, methodName)); - Class clazz = classLoader.loadClass(className); - Method method = clazz.getDeclaredMethod(methodName, argTypes); - return method.invoke(null, args); - } catch (ClassNotFoundException e) { - addErrorDiagnostic(className + " class not found: " + e.getMessage()); - throw new InvokerException(e); - } catch (NoSuchMethodException e) { - addErrorDiagnostic(methodName + " method not found: " + e.getMessage()); - throw new InvokerException(e); - } catch (IllegalAccessException e) { - addErrorDiagnostic(methodName + " illegal access: " + e.getMessage()); - throw new InvokerException(e); - } catch (InvocationTargetException e) { - addErrorDiagnostic(methodName + " exception at target: " + e.getTargetException()); - throw new InvokerException(e); - } - } - - /** - * Creates a callback to the method to directly call it with given params. - * - * @param method Method to create invocation. - * @return Created callback. - */ - private Function createInvokerCallback(Method method) { - return (params) -> { + // Then call run method + result = runtime.callFunction(module, MODULE_RUN_METHOD_NAME, null); + if (result instanceof Throwable throwable) { + throw new InvokerPanicException(throwable); + } + } catch (Throwable throwable) { + throw new InvokerPanicException(throwable); + } finally { try { - return method.invoke(null, params); - } catch (InvocationTargetException e) { - return e.getTargetException(); - } catch (IllegalAccessException e) { - throw new RuntimeException("Error while invoking function.", e); + runtime.stop(); + } catch (BError ignored) { + // stop errors are ignored } - }; + } + return result; } /* Util methods */ diff --git a/ballerina-shell/modules/shell-core/src/main/java/io/ballerina/shell/invoker/classload/ClassLoadInvoker.java b/ballerina-shell/modules/shell-core/src/main/java/io/ballerina/shell/invoker/classload/ClassLoadInvoker.java index 4617ea0bf74d..1ba5c5a142d1 100644 --- a/ballerina-shell/modules/shell-core/src/main/java/io/ballerina/shell/invoker/classload/ClassLoadInvoker.java +++ b/ballerina-shell/modules/shell-core/src/main/java/io/ballerina/shell/invoker/classload/ClassLoadInvoker.java @@ -185,7 +185,7 @@ public void initialize() throws InvokerException { anyTypeSymbol = runFunctionType.returnTypeDescriptor().orElseThrow(); } } - JBallerinaBackend.from(compilation, JvmTarget.JAVA_17); + JBallerinaBackend.from(compilation, JvmTarget.JAVA_21); this.initialized.set(true); addDebugDiagnostic("Added initial identifiers: " + initialIdentifiers); } diff --git a/ballerina-shell/modules/shell-core/src/test/java/io/ballerina/shell/test/evaluator/base/TestInvoker.java b/ballerina-shell/modules/shell-core/src/test/java/io/ballerina/shell/test/evaluator/base/TestInvoker.java index 86b23ef6ca5c..2b9345d3db08 100644 --- a/ballerina-shell/modules/shell-core/src/test/java/io/ballerina/shell/test/evaluator/base/TestInvoker.java +++ b/ballerina-shell/modules/shell-core/src/test/java/io/ballerina/shell/test/evaluator/base/TestInvoker.java @@ -18,7 +18,8 @@ package io.ballerina.shell.test.evaluator.base; -import io.ballerina.shell.exceptions.InvokerException; +import io.ballerina.runtime.api.Module; +import io.ballerina.shell.exceptions.InvokerPanicException; import io.ballerina.shell.invoker.classload.ClassLoadInvoker; import java.io.ByteArrayOutputStream; @@ -40,12 +41,11 @@ public TestInvoker() { } @Override - protected Object invokeScheduledMethod(ClassLoader classLoader, String className, String methodName) - throws InvokerException { + protected Object callRun(ClassLoader classLoader, Module module) throws InvokerPanicException { PrintStream stdOut = System.out; try { System.setOut(stdOutMock); - return super.invokeScheduledMethod(classLoader, className, methodName); + return super.callRun(classLoader, module); } finally { System.setOut(stdOut); } diff --git a/bvm/ballerina-profiler/build.gradle b/bvm/ballerina-profiler/build.gradle index 936ad3d5e1ca..73c28703e22f 100644 --- a/bvm/ballerina-profiler/build.gradle +++ b/bvm/ballerina-profiler/build.gradle @@ -27,7 +27,6 @@ configurations { dependencies { implementation libs.ow2.asm implementation libs.ow2.asm.commons - implementation libs.gson implementation libs.commons.io implementation project(':identifier-util') implementation project(':ballerina-runtime') diff --git a/bvm/ballerina-profiler/spotbugs-exclude.xml b/bvm/ballerina-profiler/spotbugs-exclude.xml index ec6fc1f4f90c..278d84be7f6d 100644 --- a/bvm/ballerina-profiler/spotbugs-exclude.xml +++ b/bvm/ballerina-profiler/spotbugs-exclude.xml @@ -24,4 +24,8 @@ + + + + diff --git a/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/Profiler.java b/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/Profiler.java index 2f35ad7a84ec..8507b16f7235 100644 --- a/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/Profiler.java +++ b/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/Profiler.java @@ -76,7 +76,7 @@ public Profiler(long profilerStartTime) { private void addShutdownHookAndCleanup() { // Add a shutdown hook to stop the profiler and parse the output when the program is closed. - Runtime.getRuntime().addShutdownHook(new Thread(() -> { + Runtime.getRuntime().addShutdownHook(Thread.ofVirtual().unstarted(() -> { try { long profilerTotalTime = TimeUnit.MILLISECONDS.convert(System.nanoTime(), TimeUnit.NANOSECONDS) - profilerStartTime; diff --git a/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/runtime/ProfileAnalyzer.java b/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/runtime/ProfileAnalyzer.java index a704a6ccfbb5..aed05b35a0f6 100644 --- a/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/runtime/ProfileAnalyzer.java +++ b/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/runtime/ProfileAnalyzer.java @@ -18,7 +18,6 @@ package io.ballerina.runtime.profiler.runtime; -import io.ballerina.runtime.internal.scheduling.State; import io.ballerina.runtime.internal.scheduling.Strand; import java.io.FileWriter; @@ -74,9 +73,7 @@ public Data start(Strand strand, String className, String methodName) { } public void stop(Strand strand, Data data) { - if (strand.getState().equals(State.RUNNABLE)) { - data.stop(String.valueOf(strand.getId())); - } + data.stop(String.valueOf(strand.getId())); strand.setProperty(STRAND_PROFILER_STACK_PROPERTY, data.stackKey.substring(0, data.stackKey.length() - data.stackIndex.length())); } @@ -106,7 +103,8 @@ private void printProfilerOutput(String dataStream) { private void addProfilerShutDownHook() { // add a shutdown hook to stop the profiler and parse the output when the program is closed - Runtime.getRuntime().addShutdownHook(new Thread(() -> { + + Runtime.getRuntime().addShutdownHook(Thread.ofVirtual().unstarted(() -> { ProfileAnalyzer profiler = ProfileAnalyzer.getInstance(); profiler.printProfilerOutput(profiler.getProfileStackString()); })); diff --git a/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/ui/JsonParser.java b/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/ui/JsonParser.java index 3ab992b17baf..52834d466d71 100644 --- a/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/ui/JsonParser.java +++ b/bvm/ballerina-profiler/src/main/java/io/ballerina/runtime/profiler/ui/JsonParser.java @@ -18,17 +18,20 @@ package io.ballerina.runtime.profiler.ui; -import com.google.gson.Gson; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; +import io.ballerina.runtime.api.values.BArray; +import io.ballerina.runtime.internal.json.JsonInternalUtils; +import io.ballerina.runtime.internal.types.BArrayType; +import io.ballerina.runtime.internal.values.BmpStringValue; import java.io.FileWriter; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_JSON; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_STRING; import static io.ballerina.runtime.profiler.util.Constants.OUT_STREAM; import static io.ballerina.runtime.profiler.util.Constants.PERFORMANCE_JSON; @@ -56,13 +59,13 @@ public void initializeCPUParser(String cpuFilePath) { } } - private int getTotalTime(JsonObject node) { + private int getTotalTime(Data node) { int totalTime = 0; - JsonArray children = node.getAsJsonArray("children"); + List children = node.children; if (children != null) { for (int i = 0; i < children.size(); i++) { - if (children.get(i).getAsJsonObject().get(VALUE_KEY).getAsInt() != -1) { - totalTime += children.get(i).getAsJsonObject().get(VALUE_KEY).getAsInt(); + if (children.get(i).value != -1) { + totalTime += children.get(i).value; } } } @@ -87,13 +90,9 @@ private void analyseStackTraceItems(StackTraceItem stackTraceItem, Data output) } private void writeToValueJson(Data output) { - Gson gson = new Gson(); - String json = gson.toJson(output); - JsonObject jsonObject = gson.fromJson(json, JsonObject.class); - int totalTime = getTotalTime(jsonObject); - jsonObject.remove(VALUE_KEY); - jsonObject.addProperty(VALUE_KEY, totalTime); - writePerformanceJson(jsonObject.toString()); + int totalTime = getTotalTime(output); + output.value = totalTime; + writePerformanceJson(output.toString()); } private Data populateChildNodes(StackTraceItem stackTraceItem, Data current, String stackTrace) { @@ -109,12 +108,14 @@ private Data populateChildNodes(StackTraceItem stackTraceItem, Data current, Str } private List populateStackTraceItems(String jsonInput) { - Gson gson = new Gson(); - JsonArray jsonArr = gson.fromJson(jsonInput, JsonArray.class); - List stackTraceItems = new ArrayList<>(); - for (JsonElement jsonElement : jsonArr) { - StackTraceItem person = gson.fromJson(jsonElement, StackTraceItem.class); - stackTraceItems.add(person); + Object jsonObj = io.ballerina.runtime.internal.json.JsonParser.parse(jsonInput, TYPE_JSON); + BArray arr = (BArray) jsonObj; + ArrayList stackTraceItems = new ArrayList<>(); + for (int i = 0; i < arr.getLength(); i++) { + Map arrItem = (Map) arr.get(i); + stackTraceItems.add(new StackTraceItem(Integer.parseInt(arrItem.get(new BmpStringValue("time")).toString()), + List.of(JsonInternalUtils.convertJSONToBArray(arrItem.get(new BmpStringValue("stackTrace")), + new BArrayType(TYPE_STRING)).getStringArray()))); } return stackTraceItems; } @@ -151,5 +152,20 @@ private static class Data { this.value = value; this.children = children; } + + @Override + public String toString() { + StringBuilder text = new StringBuilder(); + text.append("{").append("\"name\":\"").append(this.name).append("\",\"value\":"). + append(this.value).append(",\"children\":["); + for (Data child : children) { + text.append(child.toString()).append(","); + } + if (!children.isEmpty()) { + text.deleteCharAt(text.length() - 1); + } + text.append("]}"); + return text.toString(); + } } } diff --git a/bvm/ballerina-profiler/src/main/java/module-info.java b/bvm/ballerina-profiler/src/main/java/module-info.java index 15468516fdd5..4e69b807623d 100644 --- a/bvm/ballerina-profiler/src/main/java/module-info.java +++ b/bvm/ballerina-profiler/src/main/java/module-info.java @@ -3,5 +3,4 @@ requires org.apache.commons.io; requires io.ballerina.runtime; requires io.ballerina.identifier; - requires com.google.gson; } diff --git a/bvm/ballerina-rt/build.gradle b/bvm/ballerina-rt/build.gradle index 3a154c91c299..5d0623d9c4f6 100644 --- a/bvm/ballerina-rt/build.gradle +++ b/bvm/ballerina-rt/build.gradle @@ -54,7 +54,6 @@ dependencies { dist project(path: ':ballerina-lang:query', configuration: 'distributionBirJar') dist project(path: ':ballerina-lang:transaction', configuration: 'distributionBirJar') dist project(path: ':ballerina-lang:regexp', configuration: 'distributionBirJar') -// dist project(path: ':metrics-extensions:ballerina-prometheus-extension', configuration: 'distributionBirJar') // Lang libs dist project(':ballerina-lang:internal') @@ -129,6 +128,10 @@ dependencies { } +configurations.configureEach { + transitive = false +} + jar { duplicatesStrategy = DuplicatesStrategy.EXCLUDE dependsOn configurations.dist diff --git a/bvm/ballerina-runtime/README.md b/bvm/ballerina-runtime/README.md index af50e366168c..6b0526f3512d 100644 --- a/bvm/ballerina-runtime/README.md +++ b/bvm/ballerina-runtime/README.md @@ -48,7 +48,7 @@ Ballerina runtime API will contain the following sub packages. | **Package** | **Description** | |---------------------------------------|--------------------------------------------------| | io.ballerina.runtime.api | Basic runtime constructs | -| io.ballerina.runtime.api.async | Handle Ballerina asynchronous related constructs | +| io.ballerina.runtime.api.concurrent | Handle Ballerina asynchronous related constructs | | io.ballerina.runtime.api.constants | Runtime constants | | io.ballerina.runtime.api.creators | APIs to create types, values, etc. | | io.ballerina.runtime.api.flags | Runtime flags | @@ -103,9 +103,9 @@ The following table summarizes how Ballerina types are mapped to corresponding J | io.ballerina.runtime.api.Environment | Developers can use this as the first argument of an interop method, Ballerina will inject an instance of `Environment` class when calling. That instance can be used to communicate with the currently executing Ballerina runtime. With `Environment` instance, you can get interop Ballerina function name, path parameters, strand id, strand metadata, current module, current runtime, etc. | | io.ballerina.runtime.api.Future | This will contain the future value once we call the Ballerina method from API asynchronously. | | io.ballerina.runtime.api.Module | Represent Java runtime module. | -| io.ballerina.runtime.api.PredefinedTypes | Contains predefined types. | +| io.ballerina.runtime.api.types.PredefinedTypes | Contains predefined types. | | io.ballerina.runtime.api.Runtime | An instance of the current runtime can be obtained through an `Environment` instance. This will contain APIs to call Ballerina object methods asynchronously. | -| io.ballerina.runtime.api.TypeTags | Contains runtime type tags. | +| io.ballerina.runtime.api.types.TypeTags | Contains runtime type tags. | ## Create a Ballerina value @@ -187,7 +187,6 @@ public function main() { ```java class Test { public static BString callPlay(Environment env, BObject object, BString bString) { - Future future = env.markAsync(); env.getRuntime().invokeMethodAsyncConcurrently(object, "play", "play", null, new Callback() { @Override diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Environment.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Environment.java index 3ac70f918518..73b523cec7ca 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Environment.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Environment.java @@ -17,10 +17,10 @@ */ package io.ballerina.runtime.api; -import io.ballerina.runtime.api.async.StrandMetadata; +import io.ballerina.runtime.api.repository.Repository; import io.ballerina.runtime.api.types.Parameter; -import java.util.Optional; +import java.util.function.Supplier; /** * When this class is used as the first argument of an interop method, Ballerina will inject an instance of @@ -45,14 +45,13 @@ public abstract class Environment { public abstract Parameter[] getFunctionPathParameters(); /** - * Mark the current executing strand as async. Execution of Ballerina code after the current - * interop will stop until given Ballerina Future is completed. However the java thread will not be blocked - * and will be reused for running other Ballerina code in the meantime. Therefore callee of this method - * must return as soon as possible to avoid starvation of Ballerina code execution. + * Yield the current execution and run some operation so other non isolated functions can run in asynchronously. * - * @return {@link Future} which will resume the current strand when completed. + * @param supplier operation to be executed. + * @param supplier type. + * @return results supplied by this supplier. */ - public abstract Future markAsync(); + public abstract T yieldAndRun(Supplier supplier); /** * Gets an instance of Ballerina runtime. @@ -81,30 +80,28 @@ public abstract class Environment { * * @return Optional strand name. */ - public abstract Optional getStrandName(); - - /** - * Gets {@link StrandMetadata}. - * - * @return metadata of the strand. - */ - public abstract StrandMetadata getStrandMetadata(); + public abstract String getStrandName(); /** * Sets given local key value pair in strand. * * @param key string key - * @param value value to be store in the strand + * @param value value to be stored in the strand */ public abstract void setStrandLocal(String key, Object value); /** - * Gets the value stored in the strand on given key. + * Gets the value stored in the strand on a given key. * * @param key key * @return value stored in the strand. */ public abstract Object getStrandLocal(String key); + /** + * Gets the current environment repository. + * + * @return repository. + */ public abstract Repository getRepository(); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Module.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Module.java index 4573b76c3d0e..79ae48530c56 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Module.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Module.java @@ -62,11 +62,6 @@ public String getName() { return name; } - @Deprecated - public String getVersion() { - return majorVersion; - } - public String getMajorVersion() { return majorVersion; } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Runtime.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Runtime.java index 186331ad0e6d..d241d690ea1f 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Runtime.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Runtime.java @@ -17,17 +17,10 @@ package io.ballerina.runtime.api; -import io.ballerina.runtime.api.async.Callback; -import io.ballerina.runtime.api.async.StrandMetadata; -import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.concurrent.StrandMetadata; import io.ballerina.runtime.api.values.BFunctionPointer; -import io.ballerina.runtime.api.values.BFuture; import io.ballerina.runtime.api.values.BObject; import io.ballerina.runtime.internal.BalRuntime; -import io.ballerina.runtime.internal.scheduling.Scheduler; -import io.ballerina.runtime.internal.scheduling.Strand; - -import java.util.Map; /** * External API to be used by the interop users to control Ballerina runtime behavior. @@ -36,24 +29,11 @@ */ public abstract class Runtime { - // TODO: remove this with https://github.com/ballerina-platform/ballerina-lang/issues/40175 - /** - * Gets the instance of Ballerina runtime. - * - * @return Ballerina runtime instance. - * @deprecated use {@link Environment#getRuntime()} instead. - */ - @Deprecated(forRemoval = true) - public static Runtime getCurrentRuntime() { - Strand strand = Scheduler.getStrand(); - return new BalRuntime(strand.scheduler, null); - } - /** * Returns an instance of Ballerina runtime for the given module. * - * @param module Module instance. - * @return Ballerina runtime instance. + * @param module Module instance. + * @return Ballerina runtime instance. */ public static Runtime from(Module module) { return new BalRuntime(module); @@ -62,12 +42,12 @@ public static Runtime from(Module module) { /** * Performs the module initialization. */ - public abstract void init(); + public abstract Object init(); /** - * Starts the listening phase. + * Start the listening phase. */ - public abstract void start(); + public abstract Object start(); /** * Gracefully shuts down the Ballerina runtime. @@ -77,115 +57,42 @@ public static Runtime from(Module module) { public abstract void stop(); /** - * Invoke Object method asynchronously and sequentially. This method will ensure that the object methods are - * invoked in the same thread where other object methods are executed. So, the methods will be executed - * sequentially per object level. + * call a Ballerina function. * - * @param object Object Value. - * @param methodName Name of the method. - * @param strandName Name for newly created strand which is used to execute the function pointer. This is - * optional and can be null. - * @param metadata Meta data of new strand. - * @param callback Callback which will get notified once the method execution is done. - * @param properties Set of properties for strand. - * @param returnType Expected return type of this method. - * @param args Ballerina function arguments. - * @return {@link BFuture} containing return value for executing this method. - *

- * This method needs to be called if object.getType().isIsolated() or - * object.getType().isIsolated(methodName) returns false. + * @param module Module of the function. + * @param functionName Name of the function. + * @param metadata Meta data of new strand. + * @param args Arguments of the Ballerina function. */ - public abstract BFuture invokeMethodAsyncSequentially(BObject object, String methodName, String strandName, - StrandMetadata metadata, Callback callback, Map properties, - Type returnType, Object... args); + public abstract Object callFunction(Module module, String functionName, StrandMetadata metadata, + Object... args); /** - * Invoke Object method asynchronously and concurrently. Caller needs to ensure that no data race is possible for - * the mutable state with given object method and with arguments. So, the method can be concurrently run with - * different os threads. + * Call a Ballerina object method. * - * @param object Object Value. - * @param methodName Name of the method. - * @param strandName Name for newly created strand which is used to execute the function pointer. This is - * optional and can be null. - * @param metadata Meta data of new strand. - * @param callback Callback which will get notified once the method execution is done. - * @param properties Set of properties for strand. - * @param returnType Expected return type of this method. - * @param args Ballerina function arguments. - * @return {@link BFuture} containing return value for executing this method. - *

- * This method needs to be called if both object.getType().isIsolated() and - * object.getType().isIsolated(methodName) returns true. + * @param object Object Value. + * @param methodName Name of the method. + * @param metadata Meta data of new strand. + * @param args Arguments of the Ballerina function. */ - public abstract BFuture invokeMethodAsyncConcurrently(BObject object, String methodName, String strandName, - StrandMetadata metadata, Callback callback, Map properties, - Type returnType, Object... args); + public abstract Object callMethod(BObject object, String methodName, StrandMetadata metadata, + Object... args); /** - * Invoke Object method asynchronously. This will schedule the function and block the strand. - * This API checks whether the object or object method is isolated. So, if an object method is isolated, method - * will be concurrently executed in different os threads. - *

- * Caller needs to ensure that no data race is possible for the mutable state with given arguments. So, the - * method can be concurrently run with different os threads. - * - * @param object Object Value. - * @param methodName Name of the method. - * @param strandName Name for newly creating strand which is used to execute the function pointer. This is - * optional and can be null. - * @param metadata Meta data of new strand. - * @param callback Callback which will get notify once method execution done. - * @param properties Set of properties for strand - * @param returnType Expected return type of this method - * @param args Ballerina function arguments. - * @return {@link BFuture} containing return value for executing this method. - * @deprecated If caller can ensure that given object and object method is isolated and no data race is possible - * for the mutable state with given arguments, use @invokeMethodAsyncConcurrently - * otherwise @invokeMethodAsyncSequentially . - *

- * We can decide the object method isolation if and only if both object.getType().isIsolated() and - * object.getType().isIsolated(methodName) returns true. + * Register a Ballerina listener object in runtime. + * @param listener Ballerina Listener object. */ - @Deprecated - public abstract BFuture invokeMethodAsync(BObject object, String methodName, String strandName, - StrandMetadata metadata, Callback callback, - Map properties, Type returnType, Object... args); + public abstract void registerListener(BObject listener); /** - * Invoke Object method asynchronously. This will schedule the function and block the strand. - * - * @param object Object Value. - * @param methodName Name of the method. - * @param strandName Name for newly created strand which is used to execute the function pointer. This is optional - * and can be null. - * @param metadata Meta data of new strand. - * @param callback Callback which will get notified once the method execution is done. - * @param args Ballerina function arguments. - * @return the result of the function invocation. - * @deprecated If caller can ensure that given object and object method is isolated and no data race is possible - * for the mutable state with given arguments, use @invokeMethodAsyncConcurrently - * otherwise @invokeMethodAsyncSequentially . - *

- * We can decide the object method isolation if both object.getType().isIsolated() and - * object.getType().isIsolated(methodName) returns true. + * Deregister a Ballerina listener object in runtime. + * @param listener Ballerina Listener object. */ - @Deprecated - public abstract Object invokeMethodAsync(BObject object, String methodName, String strandName, - StrandMetadata metadata, Callback callback, Object... args); - - public abstract void registerListener(BObject listener); - public abstract void deregisterListener(BObject listener); - public abstract void registerStopHandler(BFunctionPointer stopHandler); - /** - * Invoke a Ballerina function pointer asynchronously. - * - * @param functionName Name of the function which needs to be invoked. - * @param callback Callback which will get notified once the function execution is done. - * @param args Arguments of the Ballerina function. + * Register a stop handler function in runtime. + * @param stopHandler Ballerina stop handler function. */ - public abstract void invokeMethodAsync(String functionName, Callback callback, Object... args); + public abstract void registerStopHandler(BFunctionPointer stopHandler); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/async/Callback.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/async/Callback.java deleted file mode 100644 index daea9f7c8a2a..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/async/Callback.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.api.async; - -import io.ballerina.runtime.api.values.BError; - -/** - * This interface represents a callback to report back a success or a - * failure state back to the originator. - * - * @since 0.995.0 - */ -public interface Callback { - - /** - * This should be called when you want to notify that your operation - * is done successfully. - * @param result the result to be reported when the operation succeeds - */ - void notifySuccess(Object result); - - /** - * This should be called to notify the listener that your operation - * failed with a specific error. - * - * @param error the error to be reported when the operation fails - */ - void notifyFailure(BError error); - -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/async/StrandMetadata.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/async/StrandMetadata.java deleted file mode 100644 index 26384fd48bbe..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/async/StrandMetadata.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2020, 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. - */ -package io.ballerina.runtime.api.async; - -/** - * Holds metadata of a Ballerina strand. - * - * @since 2.0.0 - */ - -public class StrandMetadata { - - /** - * Organization name of module the strand was initiated. - */ - private final String moduleOrg; - - /** - * Name of module the strand was initiated. - */ - private final String moduleName; - - /** - * Version of module the strand was initiated. - */ - private final String moduleVersion; - - /** - * Type name if the strand was initiated inside type. - */ - private final String typeName; - - /** - * Parent function name where the strand was initiated. - */ - private final String parentFunctionName; - - public StrandMetadata(String moduleOrg, String moduleName, String moduleVersion, String typeName, - String parentFunctionName) { - this.moduleOrg = moduleOrg; - this.moduleName = moduleName; - this.moduleVersion = moduleVersion; - this.typeName = typeName; - this.parentFunctionName = parentFunctionName; - } - - public StrandMetadata(String moduleOrg, String moduleName, String moduleVersion, String parentFunctionName) { - this(moduleOrg, moduleName, moduleVersion, null, parentFunctionName); - } - - /** - * Gets the organization name of module the strand was initiated. - * - * @return Strand module org name. - */ - public String getModuleOrg() { - return moduleOrg; - } - - /** - * Gets the name of module the strand was initiated. - * - * @return Strand module name. - */ - public String getModuleName() { - return moduleName; - } - - /** - * Gets the version of module the strand was initiated. - * - * @return Strand module version. - */ - public String getModuleVersion() { - return moduleVersion; - } - - /** - * Gets the type name if the strand was initiated inside type. - * - * @return Strand type name. - */ - public String getTypeName() { - return typeName; - } - - /** - * Gets the parent function name where the strand was initiated. - * - * @return Strand parent function name. - */ - public String getParentFunctionName() { - return parentFunctionName; - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Future.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/concurrent/StrandMetadata.java similarity index 59% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Future.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/concurrent/StrandMetadata.java index c853eba37eaf..46490a1f3774 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Future.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/concurrent/StrandMetadata.java @@ -11,19 +11,20 @@ * 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 + * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ +package io.ballerina.runtime.api.concurrent; -package io.ballerina.runtime.api; +import java.util.Map; /** - * A future that will resume the underling strand when completed. + * Holds metadata of a Ballerina strand. * + * @param isConcurrentSafe indicates if the strand is safely executed with concurrent access + * @param properties a map containing additional properties or metadata for the strand * @since 2.0.0 */ -public abstract class Future { - - public abstract void complete(Object returnValue); +public record StrandMetadata(boolean isConcurrentSafe, Map properties) { } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/ErrorCreator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/ErrorCreator.java index 386a27c17b7d..d16eef3f0148 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/ErrorCreator.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/ErrorCreator.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.api.creators; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.constants.TypeConstants; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BError; @@ -27,7 +27,7 @@ import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.types.BErrorType; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import io.ballerina.runtime.internal.values.ErrorValue; import io.ballerina.runtime.internal.values.MapValueImpl; import io.ballerina.runtime.internal.values.MappingInitialValueEntry; @@ -223,7 +223,7 @@ public static BError createDistinctError(String typeIdName, Module typeIdPkg, BS @Deprecated public static BError createDistinctError(String typeIdName, Module typeIdPkg, BString message, BError cause) { - MapValueImpl details = new MapValueImpl<>(PredefinedTypes.TYPE_ERROR_DETAIL); + MapValueImpl details = new MapValueImpl<>(PredefinedTypes.TYPE_ERROR_DETAIL); return new ErrorValue(new BErrorType(TypeConstants.ERROR, PredefinedTypes.TYPE_ERROR.getPackage(), TypeChecker.getType(details)), message, cause, details, typeIdName, typeIdPkg); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/ValueCreator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/ValueCreator.java index 2ae086cf7621..498d1b600e3a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/ValueCreator.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/creators/ValueCreator.java @@ -46,14 +46,13 @@ import io.ballerina.runtime.api.values.BXmlItem; import io.ballerina.runtime.api.values.BXmlQName; import io.ballerina.runtime.api.values.BXmlSequence; -import io.ballerina.runtime.internal.DecimalValueKind; -import io.ballerina.runtime.internal.JsonDataSource; -import io.ballerina.runtime.internal.ValueUtils; -import io.ballerina.runtime.internal.XmlFactory; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.json.JsonDataSource; +import io.ballerina.runtime.internal.utils.RuntimeUtils; +import io.ballerina.runtime.internal.utils.ValueUtils; import io.ballerina.runtime.internal.values.ArrayValue; import io.ballerina.runtime.internal.values.ArrayValueImpl; import io.ballerina.runtime.internal.values.DecimalValue; +import io.ballerina.runtime.internal.values.DecimalValueKind; import io.ballerina.runtime.internal.values.FPValue; import io.ballerina.runtime.internal.values.HandleValue; import io.ballerina.runtime.internal.values.ListInitialValueEntry; @@ -67,6 +66,7 @@ import io.ballerina.runtime.internal.values.XmlItem; import io.ballerina.runtime.internal.values.XmlQName; import io.ballerina.runtime.internal.values.XmlSequence; +import io.ballerina.runtime.internal.xml.XmlFactory; import java.io.InputStream; import java.math.BigDecimal; @@ -320,8 +320,8 @@ public static BDecimal createDecimalValue(String value, DecimalValueKind valueKi * @param type {@code FunctionType} of the function pointer * @return function pointer */ - public static BFunctionPointer createFPValue(Function function, FunctionType type) { - return new FPValue<>(function, type, null, false); + public static BFunctionPointer createFPValue(Function function, FunctionType type) { + return new FPValue(function, type, null, false); } /** @@ -332,9 +332,8 @@ public static BDecimal createDecimalValue(String value, DecimalValueKind valueKi * @param strandName name for newly creating strand which is used to run the function pointer * @return function pointer */ - public static BFunctionPointer createFPValue(Function function, - FunctionType type, String strandName) { - return new FPValue<>(function, type, strandName, false); + public static BFunctionPointer createFPValue(Function function, FunctionType type, String strandName) { + return new FPValue(function, type, strandName, false); } // TODO: remove this with https://github.com/ballerina-platform/ballerina-lang/issues/40175 @@ -759,6 +758,17 @@ public static BMap createMapValue(Type mapType, BMapInitialValu return new MapValueImpl<>(mapType, keyValues); } + /** + * Create a runtime map value with given initial values and given type. + * + * @param recordType record type + * @param keyValues initial map values to be populated + * @return map value + */ + public static BMap createMapValue(RecordType recordType, BMapInitialValueEntry[] keyValues) { + return new MapValueImpl<>(recordType, keyValues); + } + /** * Create a runtime map value with given initial values and given map type. * diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/launch/LaunchListener.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/launch/LaunchListener.java deleted file mode 100644 index bb4953d1f8e2..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/launch/LaunchListener.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.api.launch; - -/** - * This represents the Java SPI interface for listening Launcher events. - * - * @since 1.0 - */ -public interface LaunchListener { - - /** - * This is called before running the services or main. - * - * @param service A flag to indicate whether the program is a service. - */ - void beforeRunProgram(boolean service); - - /** - * This is called after running the services or main. - * - * @param service A flag to indicate whether the program is a service. - */ - void afterRunProgram(boolean service); - -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Artifact.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/repository/Artifact.java similarity index 96% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Artifact.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/repository/Artifact.java index c8e8127386f8..e6645d898858 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Artifact.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/repository/Artifact.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.ballerina.runtime.api; +package io.ballerina.runtime.api.repository; import java.util.Map; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Node.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/repository/Node.java similarity index 96% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Node.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/repository/Node.java index 8d2bd96209d7..31d56ab0d42e 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Node.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/repository/Node.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.ballerina.runtime.api; +package io.ballerina.runtime.api.repository; import java.util.Map; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Repository.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/repository/Repository.java similarity index 96% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Repository.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/repository/Repository.java index af4f803c91c6..f34bae67398f 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/Repository.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/repository/Repository.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package io.ballerina.runtime.api; +package io.ballerina.runtime.api.repository; import java.util.List; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/FunctionType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/FunctionType.java index 94410bea3242..71d61b808959 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/FunctionType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/FunctionType.java @@ -24,12 +24,6 @@ */ public interface FunctionType extends AnnotatableType { - /* - * @deprecated use {@link #getParameters()} instead. - */ - @Deprecated - Type[] getParameterTypes(); - Type getReturnType(); @Override diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/PredefinedTypes.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/PredefinedTypes.java similarity index 92% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/PredefinedTypes.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/PredefinedTypes.java index 3d0c7e49e7d5..6541d6aa9811 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/PredefinedTypes.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/PredefinedTypes.java @@ -15,36 +15,10 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.api; +package io.ballerina.runtime.api.types; +import io.ballerina.runtime.api.Module; import io.ballerina.runtime.api.constants.TypeConstants; -import io.ballerina.runtime.api.types.AnyType; -import io.ballerina.runtime.api.types.AnydataType; -import io.ballerina.runtime.api.types.ArrayType; -import io.ballerina.runtime.api.types.BooleanType; -import io.ballerina.runtime.api.types.ByteType; -import io.ballerina.runtime.api.types.DecimalType; -import io.ballerina.runtime.api.types.ErrorType; -import io.ballerina.runtime.api.types.FloatType; -import io.ballerina.runtime.api.types.FutureType; -import io.ballerina.runtime.api.types.HandleType; -import io.ballerina.runtime.api.types.IntegerType; -import io.ballerina.runtime.api.types.IteratorType; -import io.ballerina.runtime.api.types.JsonType; -import io.ballerina.runtime.api.types.MapType; -import io.ballerina.runtime.api.types.NeverType; -import io.ballerina.runtime.api.types.NullType; -import io.ballerina.runtime.api.types.ReadonlyType; -import io.ballerina.runtime.api.types.RecordType; -import io.ballerina.runtime.api.types.ServiceType; -import io.ballerina.runtime.api.types.StreamType; -import io.ballerina.runtime.api.types.StringType; -import io.ballerina.runtime.api.types.Type; -import io.ballerina.runtime.api.types.TypedescType; -import io.ballerina.runtime.api.types.UnionType; -import io.ballerina.runtime.api.types.XmlAttributesType; -import io.ballerina.runtime.api.types.XmlType; -import io.ballerina.runtime.internal.IteratorUtils; import io.ballerina.runtime.internal.types.BAnyType; import io.ballerina.runtime.internal.types.BAnydataType; import io.ballerina.runtime.internal.types.BArrayType; @@ -70,6 +44,7 @@ import io.ballerina.runtime.internal.types.BUnionType; import io.ballerina.runtime.internal.types.BXmlAttributesType; import io.ballerina.runtime.internal.types.BXmlType; +import io.ballerina.runtime.internal.utils.IteratorUtils; import io.ballerina.runtime.internal.values.ReadOnlyUtils; import java.util.ArrayList; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/TypeTags.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/TypeTags.java similarity index 99% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/TypeTags.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/TypeTags.java index 94882acdee29..ebd78439ded5 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/TypeTags.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/types/TypeTags.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.api; +package io.ballerina.runtime.api.types; /** * This class contains tag values of each type in Ballerina. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/JsonUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/JsonUtils.java index e0f6b1d6ed55..2cc7b5ffc1e9 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/JsonUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/JsonUtils.java @@ -17,15 +17,16 @@ */ package io.ballerina.runtime.api.utils; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.JsonType; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.StructureType; import io.ballerina.runtime.api.types.TableType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BIterator; @@ -33,14 +34,13 @@ import io.ballerina.runtime.api.values.BRefValue; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTable; -import io.ballerina.runtime.internal.JsonGenerator; -import io.ballerina.runtime.internal.JsonInternalUtils; -import io.ballerina.runtime.internal.JsonParser; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.commons.TypeValuePair; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; -import io.ballerina.runtime.internal.values.ErrorValue; +import io.ballerina.runtime.internal.json.JsonGenerator; +import io.ballerina.runtime.internal.json.JsonInternalUtils; +import io.ballerina.runtime.internal.json.JsonParser; import java.io.IOException; import java.io.InputStream; @@ -242,7 +242,7 @@ public static void serialize(Object json, OutputStream out) throws BError { gen.serialize(json); gen.flush(); } catch (IOException e) { - throw new ErrorValue(StringUtils.fromString(e.getMessage()), e); + throw ErrorCreator.createError(StringUtils.fromString(e.getMessage()), e); } } @@ -259,7 +259,7 @@ public static void serialize(Object json, OutputStream out, Charset charset) thr gen.serialize(json); gen.flush(); } catch (IOException e) { - throw new ErrorValue(StringUtils.fromString(e.getMessage()), e); + throw ErrorCreator.createError(StringUtils.fromString(e.getMessage()), e); } } @@ -275,7 +275,7 @@ public static void serialize(Object json, Writer writer) throws BError { gen.serialize(json); gen.flush(); } catch (IOException e) { - throw new ErrorValue(StringUtils.fromString(e.getMessage()), e); + throw ErrorCreator.createError(StringUtils.fromString(e.getMessage()), e); } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/StringUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/StringUtils.java index 44e6f75ab783..e18c94b9ed49 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/StringUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/StringUtils.java @@ -16,17 +16,17 @@ */ package io.ballerina.runtime.api.utils; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BString; -import io.ballerina.runtime.internal.JsonGenerator; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; +import io.ballerina.runtime.internal.json.JsonGenerator; import io.ballerina.runtime.internal.values.ArrayValue; import io.ballerina.runtime.internal.values.ArrayValueImpl; import io.ballerina.runtime.internal.values.BmpStringValue; @@ -48,9 +48,9 @@ import static io.ballerina.runtime.internal.errors.ErrorReasons.INDEX_OUT_OF_RANGE_ERROR_IDENTIFIER; import static io.ballerina.runtime.internal.errors.ErrorReasons.STRING_OPERATION_ERROR; import static io.ballerina.runtime.internal.errors.ErrorReasons.getModulePrefixedReason; -import static io.ballerina.runtime.internal.util.StringUtils.getExpressionStringVal; -import static io.ballerina.runtime.internal.util.StringUtils.getStringVal; -import static io.ballerina.runtime.internal.util.StringUtils.parseExpressionStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getExpressionStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.parseExpressionStringVal; /** * Common utility methods used for String manipulation. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java index 71fc7f2c8a9d..381a970f38e5 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/TypeUtils.java @@ -17,33 +17,33 @@ */ package io.ballerina.runtime.api.utils; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.ReferenceType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.types.BArrayType; import io.ballerina.runtime.internal.types.BFiniteType; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANY; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANYDATA; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_BOOLEAN; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_BYTE; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_DECIMAL; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ERROR; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_FLOAT; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_FUTURE; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_INT; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_JSON; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_MAP; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_NEVER; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_NULL; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_STREAM; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_STRING; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_TYPEDESC; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_XML; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_XML_ATTRIBUTES; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ANY; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ANYDATA; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_BOOLEAN; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_BYTE; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_DECIMAL; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ERROR; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_FLOAT; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_FUTURE; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_INT; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_JSON; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_MAP; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_NEVER; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_NULL; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_STREAM; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_STRING; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_TYPEDESC; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_XML; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_XML_ATTRIBUTES; /** * This class contains various methods to manipulate {@link Type}s in Ballerina. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/ValueUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/ValueUtils.java index b5c1cc3f2cd2..930d501c080b 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/ValueUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/ValueUtils.java @@ -21,8 +21,8 @@ import io.ballerina.runtime.api.types.AnydataType; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BError; -import io.ballerina.runtime.internal.JsonParser; -import io.ballerina.runtime.internal.ValueConverter; +import io.ballerina.runtime.internal.json.JsonParser; +import io.ballerina.runtime.internal.utils.ValueConverter; import java.io.InputStream; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/XmlUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/XmlUtils.java index 3f65db5552a8..153102b05825 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/XmlUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/utils/XmlUtils.java @@ -22,9 +22,9 @@ import io.ballerina.runtime.api.values.BTable; import io.ballerina.runtime.api.values.BXml; import io.ballerina.runtime.api.values.BXmlQName; -import io.ballerina.runtime.internal.XmlFactory; -import io.ballerina.runtime.internal.XmlValidator; import io.ballerina.runtime.internal.values.TableValueImpl; +import io.ballerina.runtime.internal.xml.XmlFactory; +import io.ballerina.runtime.internal.xml.XmlValidator; import java.io.InputStream; import java.io.Reader; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BDecimal.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BDecimal.java index c50eb32f9cb9..ede0ab23be57 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BDecimal.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BDecimal.java @@ -19,8 +19,8 @@ package io.ballerina.runtime.api.values; import io.ballerina.runtime.api.types.Type; -import io.ballerina.runtime.internal.DecimalValueKind; import io.ballerina.runtime.internal.values.DecimalValue; +import io.ballerina.runtime.internal.values.DecimalValueKind; import java.math.BigDecimal; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BFunctionPointer.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BFunctionPointer.java index b3217917096a..c018f7f0cc79 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BFunctionPointer.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BFunctionPointer.java @@ -17,57 +17,26 @@ */ package io.ballerina.runtime.api.values; -import io.ballerina.runtime.api.async.StrandMetadata; - -import java.util.function.Function; +import io.ballerina.runtime.api.Runtime; /** *

* Ballerina runtime value representation of a function pointer. *

* - * @param the type of the input to the function - * @param the type of the result of the function * * @since 1.1.0 */ -public interface BFunctionPointer extends BValue { +public interface BFunctionPointer extends BValue { /** * Execute the {@code Function} with given parameter array. Method can be used to call function pointer from * ballerina. This will directly invoke the function pointer without using ballerina scheduler. If function * pointer can have async code, then need to use @asyncCall method. * + * @param runtime Current Runtime * @param t {@code Function to be executed} * @return The result of the executed function. */ - R call(T t); - - /** - * Schedule and asynchronously execute the {@code Function} with given parameter array. Method can be used to - * call function pointer from native function. This supports function pointers with async ballerina code. - * - * @param args Function arguments. - * @param metaData meta data for newly creating strand which is used to execute the function pointer. - * @return Future value received from invoking asynchronous function. - */ - BFuture asyncCall(Object[] args, StrandMetadata metaData); - - /** - * Schedule and asynchronously execute the {@code Function} with given parameter array. Method can be used to - * call function pointer from native function. This supports function pointers with async ballerina code. - * - * @param args Function arguments. - * @param resultHandleFunction Function used to process the result received after execution of function. - * @param metaData meta data for newly creating strand which is used to execute the function pointer. - * @return Future value received from invoking asynchronous function. - */ - BFuture asyncCall(Object[] args, Function resultHandleFunction, StrandMetadata metaData); - - /** - * Returns the {@code Function} the FP is pointed to. - * - * @return {@code Function} - */ - Function getFunction(); + Object call(Runtime runtime, Object... t); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BFuture.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BFuture.java index 4997c9b9d61e..937929174875 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BFuture.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BFuture.java @@ -17,17 +17,14 @@ */ package io.ballerina.runtime.api.values; -import io.ballerina.runtime.api.async.Callback; -import io.ballerina.runtime.internal.scheduling.Strand; - /** - *

- * Represent a Ballerina future in Java. - *

- * - * @since 1.1.0 - */ -public interface BFuture extends BValue { + *

+ * Represent a Ballerina future in Java. + *

+ * + * @since 1.1.0 + */ + public interface BFuture extends BValue { /** * Abort execution of the Ballerina strand that the future is attached. @@ -35,22 +32,12 @@ public interface BFuture extends BValue { */ void cancel(); - // TODO: remove this with https://github.com/ballerina-platform/ballerina-lang/issues/40175 - /** - * Returns the strand that the future is attached to. - * - * @return strand - * @deprecated - */ - @Deprecated(since = "2201.6.0", forRemoval = true) - Strand getStrand(); - - /** - * Returns the result value of the future. - * - * @return result value - */ - Object getResult(); + /** + * Returns the result value of the future. + * + * @return result value + */ + Object get(); /** * Returns completion status of the Ballerina strand that the future is attached. @@ -59,17 +46,10 @@ public interface BFuture extends BValue { */ boolean isDone(); - /** - * Returns {@code Throwable} if the attached strand panic. - * - * @return panic error or null if not panic occurred - */ - Throwable getPanic(); - - /** - * Returns {@link Callback} listening on the completion of this future. - * - * @return registered {@link Callback} - */ - Callback getCallback(); -} + /** + * Returns whether the future is completed with panic. + * + * @return true if future is completed with panic otherwise false + */ + boolean isPanic(); + } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BNever.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BNever.java new file mode 100644 index 000000000000..eeeecf4050fe --- /dev/null +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BNever.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://wso2.com) + * + * Licensed 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 io.ballerina.runtime.api.values; + +import io.ballerina.runtime.api.types.PredefinedTypes; +import io.ballerina.runtime.api.types.Type; + +import java.util.Map; + +/** + * Ballerina runtime value representation of a singleton never value. + * @since 2201.11.0 + */ +public class BNever implements BValue { + + private static final BNever NEVER = new BNever(); + + private BNever() { + } + + public static Object getValue() { + return NEVER; + } + + @Override + public String toString() { + return "()"; + } + + @Override + public Object copy(Map refs) { + return null; + } + + @Override + public Object frozenCopy(Map refs) { + return null; + } + + @Override + public String stringValue(BLink parent) { + return ""; + } + + @Override + public String expressionStringValue(BLink parent) { + return ""; + } + + @Override + public Type getType() { + return PredefinedTypes.TYPE_NEVER; + } +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BObject.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BObject.java index 09720948fe33..24de5baa4b41 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BObject.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/api/values/BObject.java @@ -66,8 +66,7 @@ default Type getOriginalType() { boolean getBooleanValue(BString fieldName); - @SuppressWarnings("rawtypes") - BMap getMapValue(BString fieldName); + BMap getMapValue(BString fieldName); BObject getObjectValue(BString fieldName); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BLock.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BLock.java deleted file mode 100644 index b717de1bfeeb..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BLock.java +++ /dev/null @@ -1,73 +0,0 @@ -/* -* Copyright (c) 2019, 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. -*/ -package io.ballerina.runtime.internal; - -import io.ballerina.runtime.internal.scheduling.State; -import io.ballerina.runtime.internal.scheduling.Strand; - -import java.util.ArrayDeque; - -/** - * {@code VarLock} represents lock object for variables in jvm. - * - * @since 1.0.0 - */ -public class BLock { - - private final ArrayDeque current; - - private final ArrayDeque waitingForLock; - - public BLock() { - this.current = new ArrayDeque<>(); - this.waitingForLock = new ArrayDeque<>(); - } - - public synchronized boolean lock(Strand strand) { - if (isLockFree() || lockedBySameContext(strand)) { - this.current.offerLast(strand); - strand.acquiredLockCount++; - return true; - } - - this.waitingForLock.offerLast(strand); - - // Strand state change - strand.setState(State.BLOCK_AND_YIELD); - strand.blockedOnExtern = false; - return false; - } - - public synchronized void unlock() { - //current cannot be empty as unlock cannot be called without lock being called first. - Strand removedStrand = this.current.removeLast(); - removedStrand.acquiredLockCount--; - if (!waitingForLock.isEmpty()) { - Strand strand = this.waitingForLock.removeFirst(); - strand.scheduler.unblockStrand(strand); - } - } - - public boolean isLockFree() { - return this.current.isEmpty(); - } - - public boolean lockedBySameContext(Strand ctx) { - return this.current.getLast() == ctx; - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BLockStore.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BLockStore.java deleted file mode 100644 index 15ef82e435b3..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BLockStore.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2020, 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. - */ - -package io.ballerina.runtime.internal; - -import io.ballerina.runtime.api.creators.ErrorCreator; -import io.ballerina.runtime.internal.errors.ErrorReasons; -import io.ballerina.runtime.internal.scheduling.Strand; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * - * @since 1.2.0 - */ -public class BLockStore { - - /** - * The map of locks inferred. - */ - private final Map globalLockMap; - - public BLockStore() { - globalLockMap = new ConcurrentHashMap<>(); - } - - public void addLockToMap(String lockName) { - globalLockMap.put(lockName, new BLock()); - } - - public BLock getLockFromMap(String lockName) { - return globalLockMap.computeIfAbsent(lockName, (k) -> new BLock()); - } - - public void panicIfInLock(Strand strand) { - if (strand.acquiredLockCount > 0) { - throw ErrorCreator.createError(ErrorReasons.ASYNC_CALL_INSIDE_LOCK); - } - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalEnvironment.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalEnvironment.java index 6827567e2064..5064959fa791 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalEnvironment.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalEnvironment.java @@ -20,13 +20,12 @@ import io.ballerina.runtime.api.Environment; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.Repository; -import io.ballerina.runtime.api.async.StrandMetadata; +import io.ballerina.runtime.api.repository.Repository; import io.ballerina.runtime.api.types.Parameter; -import io.ballerina.runtime.internal.scheduling.State; +import io.ballerina.runtime.internal.repository.RepositoryImpl; import io.ballerina.runtime.internal.scheduling.Strand; -import java.util.Optional; +import java.util.function.Supplier; /** * When {@link Environment} is used as the first argument of an interop method, Ballerina will inject an instance @@ -37,133 +36,65 @@ public class BalEnvironment extends Environment { private final Strand strand; - private BalFuture future; - private Module currentModule; - private String funcName; - private Parameter[] funcPathParams; - private Repository repository; + private final Module currentModule; + private final String funcName; + private final Parameter[] funcPathParams; + private final Repository repository; - public BalEnvironment(Strand strand) { - this.strand = strand; - } - - public BalEnvironment(Strand strand, Module currentModule) { + public BalEnvironment(Strand strand, Module currentModule, String funcName, Parameter[] funcPathParams) { this.strand = strand; this.currentModule = currentModule; - future = new BalFuture(this.strand); - this.repository = new RepositoryImpl(); - } - - public BalEnvironment(Strand strand, Module currentModule, String funcName, Parameter[] funcPathParams) { - this(strand, currentModule); this.funcName = funcName; this.funcPathParams = funcPathParams; this.repository = new RepositoryImpl(); } - /** - * Returns the Ballerina function name for the corresponding external interop method. - * - * @return function name - */ + @Override public String getFunctionName() { return funcName; } - /** - * Returns an array consisting of the path parameters of the resource function defined as external. - * - * @return array of {@link Parameter} - */ @Override public Parameter[] getFunctionPathParameters() { return funcPathParams; } - /** - * Mark the current executing strand as async. Execution of Ballerina code after the current - * interop will stop until given BalFuture is completed. However the java thread will not be blocked - * and will be reused for running other Ballerina code in the meantime. Therefore callee of this method - * must return as soon as possible to avoid starvation of ballerina code execution. - * - * @return BalFuture which will resume the current strand when completed. - */ @Override - public BalFuture markAsync() { - strand.blockedOnExtern = true; - strand.setState(State.BLOCK_AND_YIELD); - return future; + public T yieldAndRun(Supplier supplier) { + try { + strand.yield(); + return supplier.get(); + } finally { + strand.resume(); + } } - /** - * Gets an instance of Ballerina runtime. - * - * @return Ballerina runtime instance. - */ @Override public BalRuntime getRuntime() { - return new BalRuntime(strand.scheduler, currentModule); + return strand.scheduler.runtime; } - /** - * Gets current module {@link Module}. - * - * @return module of the environment. - */ @Override public Module getCurrentModule() { return currentModule; } - /** - * Gets the strand id. This will be generated on strand initialization. - * - * @return Strand id. - */ @Override public int getStrandId() { return strand.getId(); } - /** - * Gets the strand name. This will be optional. Strand name can be either name given in strand annotation or async - * call or function pointer variable name. - * - * @return Optional strand name. - */ - @Override - public Optional getStrandName() { - return strand.getName(); - } - - /** - * Gets {@link StrandMetadata}. - * - * @return metadata of the strand. - */ @Override - public StrandMetadata getStrandMetadata() { - return strand.getMetadata(); + public String getStrandName() { + return strand.name; } - /** - * Sets given local key value pair in strand. - * - * @param key string key - * @param value value to be store in the strand - */ @Override public void setStrandLocal(String key, Object value) { strand.setProperty(key, value); } - /** - * Gets the value stored in the strand on given key. - * - * @param key key - * @return value stored in the strand. - */ @Override public Object getStrandLocal(String key) { return strand.getProperty(key); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalFuture.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalFuture.java deleted file mode 100644 index aa9dd15ef414..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalFuture.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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 io.ballerina.runtime.internal; - -import io.ballerina.runtime.api.Future; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.creators.ErrorCreator; -import io.ballerina.runtime.api.utils.StringUtils; -import io.ballerina.runtime.internal.scheduling.Strand; -import io.ballerina.runtime.internal.values.MapValueImpl; - -import java.util.concurrent.atomic.AtomicBoolean; - -/** - * A future that will resume the underling strand when completed. - * - * @since 2201.6.0 - */ -public class BalFuture extends Future { - private final Strand strand; - private final AtomicBoolean visited = new AtomicBoolean(); - - public BalFuture(Strand strand) { - this.strand = strand; - } - - @Override - public void complete(Object returnValue) { - if (visited.getAndSet(true)) { - throw ErrorCreator.createError(StringUtils.fromString("cannot complete the same future twice."), - new MapValueImpl<>(PredefinedTypes.TYPE_ERROR_DETAIL)); - } - strand.returnValue = returnValue; - strand.scheduler.unblockStrand(strand); - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalRuntime.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalRuntime.java index e721fbc45b07..17f3cdb14cc8 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalRuntime.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalRuntime.java @@ -20,18 +20,11 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.Runtime; -import io.ballerina.runtime.api.async.Callback; -import io.ballerina.runtime.api.async.StrandMetadata; +import io.ballerina.runtime.api.concurrent.StrandMetadata; import io.ballerina.runtime.api.creators.ErrorCreator; -import io.ballerina.runtime.api.types.ObjectType; -import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.StringUtils; -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.BFuture; import io.ballerina.runtime.api.values.BObject; import io.ballerina.runtime.internal.configurable.providers.ConfigDetails; import io.ballerina.runtime.internal.errors.ErrorCodes; @@ -40,19 +33,14 @@ import io.ballerina.runtime.internal.scheduling.AsyncUtils; import io.ballerina.runtime.internal.scheduling.RuntimeRegistry; import io.ballerina.runtime.internal.scheduling.Scheduler; -import io.ballerina.runtime.internal.scheduling.Strand; -import io.ballerina.runtime.internal.scheduling.SyncCallback; import io.ballerina.runtime.internal.values.FutureValue; -import io.ballerina.runtime.internal.values.ObjectValue; -import io.ballerina.runtime.internal.values.ValueCreator; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.nio.file.Path; import java.util.HashMap; import java.util.Map; -import java.util.concurrent.CountDownLatch; -import java.util.function.Function; +import java.util.concurrent.CompletableFuture; import static io.ballerina.identifier.Utils.encodeNonFunctionIdentifier; import static io.ballerina.runtime.api.constants.RuntimeConstants.ANON_ORG; @@ -67,36 +55,33 @@ */ public class BalRuntime extends Runtime { - private final Scheduler scheduler; - private final Module module; - private boolean moduleInitialized = false; - private boolean moduleStarted = false; - private boolean moduleStopped = false; - private Thread schedulerThread = null; + public final Scheduler scheduler; + public final Module rootModule; + public final RuntimeRegistry runtimeRegistry; + private final CompletableFuture stopFuture = new CompletableFuture<>(); + public boolean moduleInitialized = false; + public boolean moduleStarted = false; + public boolean moduleStopped = false; - public BalRuntime(Scheduler scheduler, Module module) { - this.scheduler = scheduler; - this.module = module; - } - - public BalRuntime(Module module) { - this.scheduler = new Scheduler(true); - this.module = module; + public BalRuntime(Module rootModule) { + this.scheduler = new Scheduler(this); + this.rootModule = rootModule; + this.runtimeRegistry = new RuntimeRegistry(this.scheduler); } @Override - public void init() { - if (moduleInitialized) { - throw ErrorHelper.getRuntimeException(ErrorCodes.FUNCTION_ALREADY_CALLED, "init"); - } + public Object init() { + handleAlreadyCalled(moduleInitialized, "init"); try { - invokeConfigInit(); - schedulerThread = new Thread(scheduler::start); - schedulerThread.start(); - invokeMethodSync("$moduleInit"); - moduleInitialized = true; + this.invokeConfigInit(); + FutureValue future = scheduler.startIsolatedFunction(rootModule, "$moduleInit", + new StrandMetadata(true, null)); + Object result = AsyncUtils.getFutureResult(future.completableFuture); + this.moduleInitialized = true; + return result; } catch (ClassNotFoundException e) { - throw ErrorCreator.createError(StringUtils.fromString(String.format("module '%s' does not exist", module))); + throw ErrorCreator.createError(StringUtils.fromString(String.format("module '%s' does not exist", + rootModule))); } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { throw ErrorCreator.createError(StringUtils.fromString("error occurred while initializing the ballerina " + "module due to " + e.getMessage()), e); @@ -104,288 +89,142 @@ public void init() { } @Override - public void start() { - if (!moduleInitialized) { - throw ErrorHelper.getRuntimeException(ErrorCodes.INVALID_FUNCTION_INVOCATION_BEFORE_MODULE_INIT, "start"); - } - if (moduleStarted) { - throw ErrorHelper.getRuntimeException(ErrorCodes.FUNCTION_ALREADY_CALLED, "start"); - } - invokeMethodSync("$moduleStart"); - moduleStarted = true; - } - - @Override - public void invokeMethodAsync(String functionName, Callback callback, Object... args) { - if (!moduleInitialized) { - throw ErrorHelper.getRuntimeException(ErrorCodes.INVALID_FUNCTION_INVOCATION_BEFORE_MODULE_INIT, - functionName); - } - invokeMethod(functionName, callback, PredefinedTypes.TYPE_ANY, functionName, args); + public Object start() { + handleCallBeforeModuleInit("start"); + handleAlreadyCalled(moduleStarted, "start"); + Object result = this.scheduler.callFunction(rootModule, "$moduleStart", null); + this.moduleStarted = true; + return result; } @Override public void stop() { - if (!moduleInitialized) { - throw ErrorHelper.getRuntimeException(ErrorCodes.INVALID_FUNCTION_INVOCATION_BEFORE_MODULE_INIT, "stop"); - } - if (moduleStopped) { - throw ErrorHelper.getRuntimeException(ErrorCodes.FUNCTION_ALREADY_CALLED, "stop"); - } + handleCallBeforeModuleInit("stop"); + handleAlreadyCalled(moduleStopped, "stop"); try { - scheduler.poison(); - schedulerThread.join(); - invokeModuleStop(); - moduleStopped = true; - } catch (InterruptedException | ClassNotFoundException | NoSuchMethodException | InvocationTargetException | + this.gracefulExit(); + this.invokeModuleStop(); + this.moduleStopped = true; + } catch (ClassNotFoundException | NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { throw ErrorCreator.createError(StringUtils.fromString("error occurred during module stop due to " + e.getMessage()), e); } } - /** - * Invoke Object method asynchronously and sequentially. This method will ensure that the object methods are - * invoked in the same thread where other object methods are executed. So, the methods will be executed - * sequentially per object level. - * - * @param object Object Value. - * @param methodName Name of the method. - * @param strandName Name for newly created strand which is used to execute the function pointer. This is - * optional and can be null. - * @param metadata Meta data of new strand. - * @param callback Callback which will get notified once the method execution is done. - * @param properties Set of properties for strand. - * @param returnType Expected return type of this method. - * @param args Ballerina function arguments. - * @return {@link BFuture} containing return value for executing this method. - *

- * This method needs to be called if object.getType().isIsolated() or - * object.getType().isIsolated(methodName) returns false. - */ @Override - public BFuture invokeMethodAsyncSequentially(BObject object, String methodName, String strandName, - StrandMetadata metadata, - Callback callback, Map properties, - Type returnType, Object... args) { - try { - validateArgs(object, methodName); - ObjectValue objectVal = (ObjectValue) object; - FutureValue future = scheduler.createFuture(null, callback, properties, returnType, strandName, metadata); - AsyncUtils.getArgsWithDefaultValues(scheduler, objectVal, methodName, new Callback() { - @Override - public void notifySuccess(Object result) { - Function func = getFunction((Object[]) result, objectVal, methodName); - scheduler.scheduleToObjectGroup(new Object[1], func, future); - } + public Object callFunction(Module module, String functionName, StrandMetadata metadata, Object... args) { + this.handleCallBeforeModuleInit(functionName); + this.validateArgs(module, functionName); + return this.scheduler.callFunction(module, functionName, metadata, args); + } - @Override - public void notifyFailure(BError error) { - callback.notifyFailure(error); - } - }, args); - return future; - } catch (BError e) { - callback.notifyFailure(e); - } catch (Throwable e) { - callback.notifyFailure(ErrorCreator.createError(StringUtils.fromString(e.getMessage()))); - } - return null; + @Override + public Object callMethod(BObject object, String methodName, StrandMetadata metadata, Object... args) { + this.handleCallBeforeModuleInit(object, methodName); + this.validateArgs(object, methodName); + return this.scheduler.callMethod(object, methodName, metadata, args); } - /** - * Invoke Object method asynchronously and concurrently. Caller needs to ensure that no data race is possible for - * the mutable state with given object method and with arguments. So, the method can be concurrently run with - * different os threads. - * - * @param object Object Value. - * @param methodName Name of the method. - * @param strandName Name for newly created strand which is used to execute the function pointer. This is - * optional and can be null. - * @param metadata Meta data of new strand. - * @param callback Callback which will get notified once the method execution is done. - * @param properties Set of properties for strand. - * @param returnType Expected return type of this method. - * @param args Ballerina function arguments. - * @return {@link BFuture} containing return value for executing this method. - *

- * This method needs to be called if both object.getType().isIsolated() and - * object.getType().isIsolated(methodName) returns true. - */ @Override - public BFuture invokeMethodAsyncConcurrently(BObject object, String methodName, String strandName, - StrandMetadata metadata, - Callback callback, Map properties, - Type returnType, Object... args) { - try { - validateArgs(object, methodName); - ObjectValue objectVal = (ObjectValue) object; - FutureValue future = scheduler.createFuture(null, callback, properties, returnType, strandName, metadata); - AsyncUtils.getArgsWithDefaultValues(scheduler, objectVal, methodName, new Callback() { - @Override - public void notifySuccess(Object result) { - Function func = getFunction((Object[]) result, objectVal, methodName); - scheduler.schedule(new Object[1], func, future); - } + public void registerListener(BObject listener) { + this.handleCallBeforeModuleInit("registerListener"); + this.runtimeRegistry.registerListener(listener); + } - @Override - public void notifyFailure(BError error) { - callback.notifyFailure(error); - } - }, args); - return future; - } catch (BError e) { - callback.notifyFailure(e); - } catch (Throwable e) { - callback.notifyFailure(ErrorCreator.createError(StringUtils.fromString(e.getMessage()))); - } - return null; + @Override + public void deregisterListener(BObject listener) { + this.handleCallBeforeModuleInit("deregisterListener"); + this.runtimeRegistry.deregisterListener(listener); } - /** - * Invoke Object method asynchronously. This will schedule the function and block the strand. - * This API checks whether the object or object method is isolated. So, if an object method is isolated, method - * will be concurrently executed in different os threads. - *

- * Caller needs to ensure that no data race is possible for the mutable state with given arguments. So, the - * method can be concurrently run with different os threads. - * - * @param object Object Value. - * @param methodName Name of the method. - * @param strandName Name for newly creating strand which is used to execute the function pointer. This is - * optional and can be null. - * @param metadata Meta data of new strand. - * @param callback Callback which will get notify once method execution done. - * @param properties Set of properties for strand - * @param returnType Expected return type of this method - * @param args Ballerina function arguments. - * @return {@link BFuture} containing return value for executing this method. - * @deprecated If caller can ensure that given object and object method is isolated and no data race is possible - * for the mutable state with given arguments, use @invokeMethodAsyncConcurrently - * otherwise @invokeMethodAsyncSequentially . - *

- * We can decide the object method isolation if and only if both object.getType().isIsolated() and - * object.getType().isIsolated(methodName) returns true. - */ @Override - @Deprecated - public BFuture invokeMethodAsync(BObject object, String methodName, String strandName, StrandMetadata metadata, - Callback callback, Map properties, - Type returnType, Object... args) { - try { - validateArgs(object, methodName); - ObjectValue objectVal = (ObjectValue) object; - ObjectType objectType = (ObjectType) TypeUtils.getImpliedType(objectVal.getType()); - boolean isIsolated = objectType.isIsolated() && objectType.isIsolated(methodName); - FutureValue future = scheduler.createFuture(null, callback, properties, returnType, strandName, metadata); - AsyncUtils.getArgsWithDefaultValues(scheduler, objectVal, methodName, new Callback() { - @Override - public void notifySuccess(Object result) { - Function func = getFunction((Object[]) result, objectVal, methodName); - if (isIsolated) { - scheduler.schedule(new Object[1], func, future); - } else { - scheduler.scheduleToObjectGroup(new Object[1], func, future); - } - } + public void registerStopHandler(BFunctionPointer stopHandler) { + this.handleCallBeforeModuleInit("registerStopHandler"); + this.runtimeRegistry.registerStopHandler(stopHandler); + } - @Override - public void notifyFailure(BError error) { - callback.notifyFailure(error); - } - }, args); - return future; - } catch (BError e) { - callback.notifyFailure(e); + + @SuppressWarnings("unused") + /* + * Used for codegen wait for listeners + */ + public void waitOnListeners(boolean listenerDeclarationFound) { + if (!listenerDeclarationFound && this.runtimeRegistry.listenerQueue.isEmpty()) { + return; + } + try { + this.stopFuture.get(); } catch (Throwable e) { - callback.notifyFailure(ErrorCreator.createError(StringUtils.fromString(e.getMessage()))); + throw ErrorCreator.createError(e); } - return null; } - /** - * Invoke Object method asynchronously. This will schedule the function and block the strand. - * - * @param object Object Value. - * @param methodName Name of the method. - * @param strandName Name for newly created strand which is used to execute the function pointer. This is optional - * and can be null. - * @param metadata Meta data of new strand. - * @param callback Callback which will get notified once the method execution is done. - * @param args Ballerina function arguments. - * @return the result of the function invocation. - * @deprecated If caller can ensure that given object and object method is isolated and no data race is possible - * for the mutable state with given arguments, use @invokeMethodAsyncConcurrently - * otherwise @invokeMethodAsyncSequentially . - *

- * We can decide the object method isolation if both object.getType().isIsolated() and - * object.getType().isIsolated(methodName) returns true. - */ - @Override - @Deprecated - public Object invokeMethodAsync(BObject object, String methodName, String strandName, StrandMetadata metadata, - Callback callback, Object... args) { - return invokeMethodAsync(object, methodName, strandName, metadata, callback, null, - PredefinedTypes.TYPE_NULL, args); + public void gracefulExit() { + this.stopFuture.complete(null); } - private void validateArgs(BObject object, String methodName) { - if (object == null) { - throw ErrorCreator.createError(StringUtils.fromString("object cannot be null")); - } - if (methodName == null) { - throw ErrorCreator.createError(StringUtils.fromString("method name cannot be null")); - } + private void invokeConfigInit() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, + IllegalAccessException { + Class configClass = loadClass(CONFIGURATION_CLASS_NAME); + ConfigDetails configDetails = LaunchUtils.getConfigurationDetails(); + String funcName = Utils.encodeFunctionIdentifier("$configureInit"); + Method method = configClass.getDeclaredMethod(funcName, Map.class, String[].class, Path[].class, String.class + , BalRuntime.class); + method.invoke(null, new HashMap<>(), new String[]{}, configDetails.paths, configDetails.configContent, this); } - @Override - public void registerListener(BObject listener) { - scheduler.getRuntimeRegistry().registerListener(listener); + private void handleCallBeforeModuleInit(String functionName) { + if (!moduleInitialized) { + throw ErrorHelper.getRuntimeException(ErrorCodes.INVALID_FUNCTION_INVOCATION_BEFORE_MODULE_INIT, + functionName); + } } - @Override - public void deregisterListener(BObject listener) { - scheduler.getRuntimeRegistry().deregisterListener(listener); + private void handleCallBeforeModuleInit(BObject object, String methodName) { + if (!moduleInitialized) { + throw ErrorHelper.getRuntimeException(ErrorCodes.INVALID_FUNCTION_INVOCATION_BEFORE_MODULE_INIT, + object.getOriginalType().getName() + ":" + methodName); + } } - @Override - public void registerStopHandler(BFunctionPointer stopHandler) { - scheduler.getRuntimeRegistry().registerStopHandler(stopHandler); + private void handleAlreadyCalled(boolean isAlreadyCalled, String functionName) { + if (isAlreadyCalled) { + throw ErrorHelper.getRuntimeException(ErrorCodes.FUNCTION_ALREADY_CALLED, functionName); + } } - private Function getFunction(Object[] argsWithDefaultValues, - ObjectValue objectVal, String methodName) { - Function func; - if (argsWithDefaultValues.length == 1) { - func = o -> objectVal.call((Strand) ((o)[0]), methodName, argsWithDefaultValues[0]); - } else { - func = o -> objectVal.call((Strand) ((o)[0]), methodName, argsWithDefaultValues); + private void validateArgs(Module module, String functionName) { + if (module == null) { + throw ErrorCreator.createError(StringUtils.fromString("module cannot be null")); + } + if (functionName == null) { + throw ErrorCreator.createError(StringUtils.fromString("function name cannot be null")); } - return func; } - private void invokeConfigInit() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, - IllegalAccessException { - Class configClass = loadClass(CONFIGURATION_CLASS_NAME); - ConfigDetails configDetails = LaunchUtils.getConfigurationDetails(); - String funcName = Utils.encodeFunctionIdentifier("$configureInit"); - Method method = configClass.getDeclaredMethod(funcName, Map.class, String[].class, Path[].class, String.class); - method.invoke(null, new HashMap<>(), new String[]{}, configDetails.paths, configDetails.configContent); + private void validateArgs(BObject object, String methodName) { + if (object == null) { + throw ErrorCreator.createError(StringUtils.fromString("object cannot be null")); + } + if (methodName == null) { + throw ErrorCreator.createError(StringUtils.fromString("method name cannot be null")); + } } - private void invokeModuleStop() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, + Object invokeModuleStop() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException { Class configClass = loadClass(MODULE_INIT_CLASS_NAME); - Method method = configClass.getDeclaredMethod("$currentModuleStop", RuntimeRegistry.class); - method.invoke(null, scheduler.getRuntimeRegistry()); + Method method = configClass.getDeclaredMethod("$currentModuleStop", BalRuntime.class); + return method.invoke(null, this); } - private Class loadClass(String className) throws ClassNotFoundException { - String name = getFullQualifiedClassName(this.module, className); + protected Class loadClass(String className) throws ClassNotFoundException { + String name = getFullQualifiedClassName(this.rootModule, className); return Class.forName(name); } - private static String getFullQualifiedClassName(Module module, String className) { + protected static String getFullQualifiedClassName(Module module, String className) { String orgName = module.getOrg(); String packageName = module.getName(); if (!DOT.equals(packageName)) { @@ -396,30 +235,4 @@ private static String getFullQualifiedClassName(Module module, String className) } return className; } - - private void invokeMethodSync(String functionName) { - final CountDownLatch latch = new CountDownLatch(1); - SyncCallback callback = new SyncCallback(latch); - invokeMethod(functionName, callback, PredefinedTypes.TYPE_NULL, functionName, new Object[1]); - try { - latch.await(); - } catch (InterruptedException e) { - throw ErrorCreator.createError(e); - } - if (callback.initError != null) { - throw callback.initError; - } - } - - private void invokeMethod(String functionName, Callback callback, Type returnType, String strandName, - Object... args) { - ValueCreator valueCreator = ValueCreator.getValueCreator(ValueCreator.getLookupKey(module.getOrg(), - module.getName(), module.getMajorVersion(), module.isTestPkg())); - Function func = o -> valueCreator.call((Strand) (o[0]), functionName, args); - FutureValue future = scheduler.createFuture(null, callback, null, returnType, strandName, null); - Object[] argsWithStrand = new Object[args.length + 1]; - argsWithStrand[0] = future.strand; - System.arraycopy(args, 0, argsWithStrand, 1, args.length); - scheduler.schedule(argsWithStrand, func, future); - } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ColumnDefinition.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ColumnDefinition.java deleted file mode 100644 index 873b8f306a3f..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ColumnDefinition.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.internal; - -/** - * This wraps the column name and type of a selected result set from a data source. - * - * @since 0.995.0 - */ -public class ColumnDefinition { - - protected String name; - protected int mappedTypeTag; - - public ColumnDefinition(String name, int mappedType) { - this.name = name; - this.mappedTypeTag = mappedType; - } - - public String getName() { - return name; - } - - public int getTypeTag() { - return mappedTypeTag; - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/DataIterator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/DataIterator.java deleted file mode 100644 index 363946a5e56b..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/DataIterator.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.internal; - -import io.ballerina.runtime.internal.types.BStructureType; -import io.ballerina.runtime.internal.values.DecimalValue; -import io.ballerina.runtime.internal.values.MapValue; - -import java.util.List; - -/** - * This interface represents an data iterator operations. - * Each data source need to implement their own implementation by implementing this interface. - * Known implementations: {@code SQLDataIterator} - * - * @since 0.995.0 - */ -public interface DataIterator { - - boolean next(); - - void close(); - - void reset(); - - String getString(int columnIndex); - - Long getInt(int columnIndex); - - Double getFloat(int columnIndex); - - Boolean getBoolean(int columnIndex); - - String getBlob(int columnIndex); - - DecimalValue getDecimal(int columnIndex); - - Object[] getStruct(int columnIndex); - - Object[] getArray(int columnIndex); - - MapValue generateNext(); - - List getColumnDefinitions(); - - BStructureType getStructType(); -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/Lists.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/Lists.java deleted file mode 100644 index 2a545f6b5739..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/Lists.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2019, 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. - * - */ - -package io.ballerina.runtime.internal; - -import io.ballerina.runtime.api.TypeTags; -import io.ballerina.runtime.api.utils.TypeUtils; -import io.ballerina.runtime.internal.types.BArrayType; -import io.ballerina.runtime.internal.values.ArrayValue; - -/** - * Common utility methods used for List manipulation. - * - * @since 0.995.0 - */ -public final class Lists { - - private Lists() { - } - - public static Object get(ArrayValue array, long index) { - if (array.getType().getTag() != TypeTags.ARRAY_TAG) { - return array.getRefValue(index); - } - - return switch (TypeUtils.getImpliedType(((BArrayType) array.getType()).getElementType()).getTag()) { - case TypeTags.BOOLEAN_TAG -> array.getBoolean(index); - case TypeTags.BYTE_TAG -> (long) array.getByte(index); - case TypeTags.FLOAT_TAG -> array.getFloat(index); - case TypeTags.DECIMAL_TAG -> array.getRefValue(index); - case TypeTags.INT_TAG -> array.getInt(index); - case TypeTags.STRING_TAG -> array.getString(index); - default -> array.getRefValue(index); - }; - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java index cc3e8e8fdc1c..4705c4ead712 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeChecker.java @@ -18,15 +18,15 @@ package io.ballerina.runtime.internal; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.ArrayType.ArrayState; import io.ballerina.runtime.api.types.Field; import io.ballerina.runtime.api.types.FunctionType; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.MethodType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.types.XmlNodeType; import io.ballerina.runtime.api.utils.StringUtils; @@ -62,8 +62,10 @@ import io.ballerina.runtime.internal.types.BTypedescType; import io.ballerina.runtime.internal.types.BUnionType; import io.ballerina.runtime.internal.types.BXmlType; +import io.ballerina.runtime.internal.utils.ErrorUtils; import io.ballerina.runtime.internal.values.ArrayValue; import io.ballerina.runtime.internal.values.DecimalValue; +import io.ballerina.runtime.internal.values.DecimalValueKind; import io.ballerina.runtime.internal.values.ErrorValue; import io.ballerina.runtime.internal.values.HandleValue; import io.ballerina.runtime.internal.values.MapValue; @@ -94,23 +96,6 @@ import java.util.Optional; import java.util.Set; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANY; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANYDATA; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_BOOLEAN; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_BYTE; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_DECIMAL; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_FLOAT; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_INT; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_INT_SIGNED_16; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_INT_SIGNED_32; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_INT_SIGNED_8; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_INT_UNSIGNED_16; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_INT_UNSIGNED_32; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_INT_UNSIGNED_8; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_JSON; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_NULL; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_READONLY_JSON; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_STRING; import static io.ballerina.runtime.api.constants.RuntimeConstants.BALLERINA_BUILTIN_PKG_PREFIX; import static io.ballerina.runtime.api.constants.RuntimeConstants.BBYTE_MAX_VALUE; import static io.ballerina.runtime.api.constants.RuntimeConstants.BBYTE_MIN_VALUE; @@ -124,12 +109,29 @@ import static io.ballerina.runtime.api.constants.RuntimeConstants.UNSIGNED16_MAX_VALUE; import static io.ballerina.runtime.api.constants.RuntimeConstants.UNSIGNED32_MAX_VALUE; import static io.ballerina.runtime.api.constants.RuntimeConstants.UNSIGNED8_MAX_VALUE; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ANY; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ANYDATA; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_BOOLEAN; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_BYTE; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_DECIMAL; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_FLOAT; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_INT; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_INT_SIGNED_16; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_INT_SIGNED_32; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_INT_SIGNED_8; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_INT_UNSIGNED_16; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_INT_UNSIGNED_32; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_INT_UNSIGNED_8; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_JSON; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_NULL; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_READONLY_JSON; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_STRING; import static io.ballerina.runtime.api.utils.TypeUtils.getImpliedType; import static io.ballerina.runtime.api.utils.TypeUtils.isValueType; -import static io.ballerina.runtime.internal.CloneUtils.getErrorMessage; import static io.ballerina.runtime.internal.TypeConverter.ERROR_MESSAGE_UNION_END; import static io.ballerina.runtime.internal.TypeConverter.ERROR_MESSAGE_UNION_SEPARATOR; import static io.ballerina.runtime.internal.TypeConverter.ERROR_MESSAGE_UNION_START; +import static io.ballerina.runtime.internal.utils.CloneUtils.getErrorMessage; /** * Responsible for performing runtime type checking. @@ -2453,7 +2455,7 @@ private static boolean checkIsLikeTupleType(Object sourceValue, BTupleType targe return true; } - static boolean isByteLiteral(long longValue) { + public static boolean isByteLiteral(long longValue) { return (longValue >= BBYTE_MIN_VALUE && longValue <= BBYTE_MAX_VALUE); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeConverter.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeConverter.java index 82f3ffbdb370..b107a4f617d3 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeConverter.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TypeConverter.java @@ -17,16 +17,16 @@ */ package io.ballerina.runtime.internal; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.Field; import io.ballerina.runtime.api.types.FiniteType; import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.ReferenceType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; @@ -52,6 +52,7 @@ import io.ballerina.runtime.internal.types.BTypeReferenceType; import io.ballerina.runtime.internal.types.BTypedescType; import io.ballerina.runtime.internal.types.BUnionType; +import io.ballerina.runtime.internal.utils.ErrorUtils; import io.ballerina.runtime.internal.values.ArrayValue; import io.ballerina.runtime.internal.values.DecimalValue; import io.ballerina.runtime.internal.values.MapValueImpl; @@ -67,9 +68,9 @@ import java.util.Set; import java.util.function.Supplier; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_STRING; import static io.ballerina.runtime.api.constants.RuntimeConstants.BINT_MAX_VALUE_DOUBLE_RANGE_MAX; import static io.ballerina.runtime.api.constants.RuntimeConstants.BINT_MIN_VALUE_DOUBLE_RANGE_MIN; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_STRING; import static io.ballerina.runtime.internal.TypeChecker.anyToSigned16; import static io.ballerina.runtime.internal.TypeChecker.anyToSigned32; import static io.ballerina.runtime.internal.TypeChecker.anyToSigned8; @@ -100,11 +101,11 @@ public final class TypeConverter { private static final String POSITIVE_INFINITY = "Infinity"; private static final String NEGATIVE_INFINITY = "-Infinity"; - static final byte MAX_CONVERSION_ERROR_COUNT = 20; - static final byte MAX_DISPLAYED_SOURCE_VALUE_LENGTH = 20; - static final String ERROR_MESSAGE_UNION_START = "{"; - static final String ERROR_MESSAGE_UNION_END = "}"; - static final String ERROR_MESSAGE_UNION_SEPARATOR = "or"; + public static final byte MAX_CONVERSION_ERROR_COUNT = 20; + public static final byte MAX_DISPLAYED_SOURCE_VALUE_LENGTH = 20; + public static final String ERROR_MESSAGE_UNION_START = "{"; + public static final String ERROR_MESSAGE_UNION_END = "}"; + public static final String ERROR_MESSAGE_UNION_SEPARATOR = "or"; public static Object convertValues(Type targetType, Object inputValue) { Type inputType = TypeChecker.getType(inputValue); @@ -1236,7 +1237,7 @@ public static Type resolveMatchingTypeForUnion(Object value, Type targetUnionTyp private TypeConverter() { } - static List getXmlTargetTypes(Type targetType) { + public static List getXmlTargetTypes(Type targetType) { List xmlTargetTypes = new ArrayList<>(); return switch (targetType.getTag()) { case TypeTags.XML_TAG, TypeTags.XML_PI_TAG, TypeTags.XML_COMMENT_TAG, TypeTags.XML_ELEMENT_TAG, diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/annotation/JavaSpiService.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/annotation/JavaSpiService.java deleted file mode 100644 index cc20bd0708d3..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/annotation/JavaSpiService.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2019, 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. - * - */ -package io.ballerina.runtime.internal.annotation; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Used to mark a class as Java SPI service. This can be used from an annotation - * processor to auto generate the service files. - * - * @since 0.94 - */ -@Target(ElementType.TYPE) -@Retention(RetentionPolicy.SOURCE) -public @interface JavaSpiService { - - /** - * Represents the name of interface this service is exposing. - * - * @return the interface name - */ - String value(); - -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/CliSpec.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/CliSpec.java index 4f6bd7ebd631..584a9912c98a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/CliSpec.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/CliSpec.java @@ -18,13 +18,13 @@ package io.ballerina.runtime.internal.cli; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/CliUtil.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/CliUtil.java index d677e3b42be0..74795aea33a2 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/CliUtil.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/CliUtil.java @@ -18,10 +18,10 @@ package io.ballerina.runtime.internal.cli; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/Option.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/Option.java index 5f7e41eb8cb1..22412d34dfd9 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/Option.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/cli/Option.java @@ -19,13 +19,13 @@ package io.ballerina.runtime.internal.cli; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BMap; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/ConfigResolver.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/ConfigResolver.java index 2261fe6e8895..6ae42da0f486 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/ConfigResolver.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/ConfigResolver.java @@ -20,10 +20,10 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.ReferenceType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.configurable.exceptions.ConfigException; import io.ballerina.runtime.internal.diagnostics.RuntimeDiagnosticLog; import io.ballerina.runtime.internal.errors.ErrorCodes; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/ConfigUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/ConfigUtils.java index 4c559b4594cf..670ffbe02458 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/ConfigUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/ConfigUtils.java @@ -16,8 +16,8 @@ package io.ballerina.runtime.internal.configurable.providers; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/cli/CliProvider.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/cli/CliProvider.java index 003998ff95d3..33cdb575226b 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/cli/CliProvider.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/cli/CliProvider.java @@ -19,10 +19,10 @@ package io.ballerina.runtime.internal.configurable.providers.cli; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.internal.TypeConverter; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/env/EnvVarProvider.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/env/EnvVarProvider.java index 78cc5992c94f..d8959794442d 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/env/EnvVarProvider.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/env/EnvVarProvider.java @@ -17,10 +17,10 @@ package io.ballerina.runtime.internal.configurable.providers.env; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.internal.TypeConverter; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/ConfigValueCreator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/ConfigValueCreator.java index 7c2c7164b131..a8c1f5c2672f 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/ConfigValueCreator.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/ConfigValueCreator.java @@ -18,7 +18,6 @@ package io.ballerina.runtime.internal.configurable.providers.toml; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.ArrayType; @@ -31,6 +30,7 @@ import io.ballerina.runtime.api.types.TableType; import io.ballerina.runtime.api.types.TupleType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; @@ -65,11 +65,11 @@ import java.util.Map; import java.util.Optional; -import static io.ballerina.runtime.internal.ValueUtils.createReadOnlyXmlValue; import static io.ballerina.runtime.internal.configurable.providers.toml.Utils.getEffectiveType; import static io.ballerina.runtime.internal.configurable.providers.toml.Utils.getValueFromKeyValueNode; import static io.ballerina.runtime.internal.configurable.providers.toml.Utils.isSimpleType; import static io.ballerina.runtime.internal.configurable.providers.toml.Utils.isXMLType; +import static io.ballerina.runtime.internal.utils.ValueUtils.createReadOnlyXmlValue; /** * Value creator to create values for structured configurable values from TOML nodes. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/TomlConstants.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/TomlConstants.java index 7d28f92110cd..79397ccd0d9b 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/TomlConstants.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/TomlConstants.java @@ -18,7 +18,7 @@ package io.ballerina.runtime.internal.configurable.providers.toml; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import java.nio.file.Path; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/TomlProvider.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/TomlProvider.java index 949ebf33b0d1..e2f093d59947 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/TomlProvider.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/TomlProvider.java @@ -19,7 +19,6 @@ package io.ballerina.runtime.internal.configurable.providers.toml; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.ArrayType; @@ -31,6 +30,7 @@ import io.ballerina.runtime.api.types.TableType; import io.ballerina.runtime.api.types.TupleType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.internal.TypeConverter; @@ -68,7 +68,6 @@ import java.util.Optional; import java.util.Set; -import static io.ballerina.runtime.internal.ValueUtils.createReadOnlyXmlValue; import static io.ballerina.runtime.internal.configurable.providers.toml.Utils.checkEffectiveTomlType; import static io.ballerina.runtime.internal.configurable.providers.toml.Utils.getEffectiveType; import static io.ballerina.runtime.internal.configurable.providers.toml.Utils.getLineRange; @@ -87,7 +86,8 @@ import static io.ballerina.runtime.internal.errors.ErrorCodes.CONFIG_TOML_TABLE_KEY_NOT_PROVIDED; import static io.ballerina.runtime.internal.errors.ErrorCodes.CONFIG_TOML_UNUSED_VALUE; import static io.ballerina.runtime.internal.errors.ErrorCodes.CONFIG_TYPE_NOT_SUPPORTED; -import static io.ballerina.runtime.internal.util.RuntimeUtils.isByteLiteral; +import static io.ballerina.runtime.internal.utils.RuntimeUtils.isByteLiteral; +import static io.ballerina.runtime.internal.utils.ValueUtils.createReadOnlyXmlValue; /** * Toml value provider for configurable implementation. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/Utils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/Utils.java index 86d2615bc0b5..4d0a4f47f1fc 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/Utils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/configurable/providers/toml/Utils.java @@ -19,8 +19,6 @@ package io.ballerina.runtime.internal.configurable.providers.toml; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.flags.SymbolFlags; @@ -28,10 +26,12 @@ import io.ballerina.runtime.api.types.FiniteType; import io.ballerina.runtime.api.types.IntersectableReferenceType; import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.types.ReferenceType; import io.ballerina.runtime.api.types.TupleType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BMapInitialValueEntry; @@ -66,12 +66,12 @@ import java.util.Set; import static io.ballerina.identifier.Utils.decodeIdentifier; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANYDATA; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_READONLY_ANYDATA; -import static io.ballerina.runtime.internal.ValueUtils.createReadOnlyXmlValue; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ANYDATA; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_READONLY_ANYDATA; import static io.ballerina.runtime.internal.configurable.providers.toml.TomlConstants.CONFIG_FILE_NAME; import static io.ballerina.runtime.internal.errors.ErrorCodes.CONFIG_TYPE_NOT_SUPPORTED; import static io.ballerina.runtime.internal.errors.ErrorCodes.CONFIG_UNION_VALUE_AMBIGUOUS_TARGET; +import static io.ballerina.runtime.internal.utils.ValueUtils.createReadOnlyXmlValue; /** * Util methods required for configurable variables. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/errors/ErrorHelper.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/errors/ErrorHelper.java index f28cbc6167a5..dd2c05d33d83 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/errors/ErrorHelper.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/errors/ErrorHelper.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.internal.errors; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BMap; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonDataSource.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonDataSource.java similarity index 97% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonDataSource.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonDataSource.java index e43579211667..6962c6d1347e 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonDataSource.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonDataSource.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.json; import java.io.IOException; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonGenerator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonGenerator.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonGenerator.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonGenerator.java index b9b11d98dad3..1cce229bcef8 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonGenerator.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonGenerator.java @@ -15,11 +15,12 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.json; -import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.values.ArrayValue; import io.ballerina.runtime.internal.values.DecimalValue; import io.ballerina.runtime.internal.values.MapValueImpl; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonInternalUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonInternalUtils.java similarity index 99% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonInternalUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonInternalUtils.java index f056abddc30d..0fe77bbde9da 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonInternalUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonInternalUtils.java @@ -16,17 +16,17 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.json; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.Field; import io.ballerina.runtime.api.types.JsonType; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.StructureType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; @@ -35,6 +35,8 @@ import io.ballerina.runtime.api.values.BRefValue; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTable; +import io.ballerina.runtime.internal.TypeChecker; +import io.ballerina.runtime.internal.TypeConverter; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.errors.ErrorReasons; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonParser.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonParser.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonParser.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonParser.java index 80a73363a64d..401a3a83eb48 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/JsonParser.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/JsonParser.java @@ -16,10 +16,8 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.json; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; @@ -28,10 +26,12 @@ import io.ballerina.runtime.api.types.Field; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.types.TableType; import io.ballerina.runtime.api.types.TupleType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.JsonUtils; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; @@ -40,6 +40,8 @@ import io.ballerina.runtime.api.values.BListInitialValueEntry; import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.internal.TypeChecker; +import io.ballerina.runtime.internal.TypeConverter; import io.ballerina.runtime.internal.commons.TypeValuePair; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; @@ -49,6 +51,9 @@ import io.ballerina.runtime.internal.types.BIntersectionType; import io.ballerina.runtime.internal.types.BMapType; import io.ballerina.runtime.internal.types.BRecordType; +import io.ballerina.runtime.internal.utils.CloneUtils; +import io.ballerina.runtime.internal.utils.ValueConverter; +import io.ballerina.runtime.internal.utils.ValueUtils; import io.ballerina.runtime.internal.values.ArrayValue; import io.ballerina.runtime.internal.values.ArrayValueImpl; import io.ballerina.runtime.internal.values.DecimalValue; @@ -75,8 +80,8 @@ import static io.ballerina.runtime.api.creators.ErrorCreator.createError; import static io.ballerina.runtime.api.utils.JsonUtils.NonStringValueProcessingMode.FROM_JSON_DECIMAL_STRING; import static io.ballerina.runtime.api.utils.JsonUtils.NonStringValueProcessingMode.FROM_JSON_FLOAT_STRING; -import static io.ballerina.runtime.internal.ErrorUtils.createConversionError; -import static io.ballerina.runtime.internal.ValueUtils.createRecordValueWithDefaultValues; +import static io.ballerina.runtime.internal.utils.ErrorUtils.createConversionError; +import static io.ballerina.runtime.internal.utils.ValueUtils.createRecordValueWithDefaultValues; /** * This class represents a {@link InputStream} parser which creates a value of the given target type diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ParserException.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/ParserException.java similarity index 95% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ParserException.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/ParserException.java index 5597e2cc6bad..0b7340b7f007 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ParserException.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/ParserException.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.json; /** * Represents a parser related exception. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/StateMachine.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/StateMachine.java similarity index 99% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/StateMachine.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/StateMachine.java index c605927b1e28..66450a1ccaa8 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/StateMachine.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/StateMachine.java @@ -16,7 +16,7 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.json; import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.creators.ErrorCreator; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TableJsonDataSource.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/TableJsonDataSource.java similarity index 97% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TableJsonDataSource.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/TableJsonDataSource.java index 80132514c4ae..da34291ad572 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TableJsonDataSource.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/json/TableJsonDataSource.java @@ -15,12 +15,12 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.json; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; @@ -28,6 +28,7 @@ import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTable; +import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.types.BArrayType; import io.ballerina.runtime.internal.types.BMapType; import io.ballerina.runtime.internal.values.ArrayValue; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/launch/LaunchUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/launch/LaunchUtils.java index d7c8f54b025b..98d3610a17e9 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/launch/LaunchUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/launch/LaunchUtils.java @@ -19,7 +19,6 @@ package io.ballerina.runtime.internal.launch; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.launch.LaunchListener; import io.ballerina.runtime.internal.configurable.ConfigMap; import io.ballerina.runtime.internal.configurable.ConfigProvider; import io.ballerina.runtime.internal.configurable.ConfigResolver; @@ -31,7 +30,7 @@ import io.ballerina.runtime.internal.configurable.providers.toml.TomlFileProvider; import io.ballerina.runtime.internal.diagnostics.RuntimeDiagnosticLog; import io.ballerina.runtime.internal.troubleshoot.StrandDump; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import sun.misc.Signal; import java.io.File; @@ -42,7 +41,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.ServiceLoader; import java.util.Set; import static io.ballerina.runtime.api.constants.RuntimeConstants.DOT; @@ -65,14 +63,10 @@ public final class LaunchUtils { private LaunchUtils() { } - public static void startListenersAndSignalHandler(boolean isService) { - // starts all listeners - startListeners(isService); - - // start TRAP signal handler which produces the strand dump - startTrapSignalHandler(); - } - + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle trap signals for strand dump. + */ public static void startTrapSignalHandler() { try { Signal.handle(new Signal("TRAP"), signal -> outStream.println(StrandDump.getStrandDump())); @@ -82,16 +76,10 @@ public static void startTrapSignalHandler() { } } - public static void startListeners(boolean isService) { - ServiceLoader listeners = ServiceLoader.load(LaunchListener.class); - listeners.forEach(listener -> listener.beforeRunProgram(isService)); - } - - public static void stopListeners(boolean isService) { - ServiceLoader listeners = ServiceLoader.load(LaunchListener.class); - listeners.forEach(listener -> listener.afterRunProgram(isService)); - } - + @SuppressWarnings("unused") + /* + * Used for codegen adding module configurable data. + */ public static void addModuleConfigData(Map configurationData, Module m, VariableKey[] variableKeys) { VariableKey[] currKeys = configurationData.get(m); @@ -106,6 +94,10 @@ public static void addModuleConfigData(Map configurationD configurationData.put(m, mergedKeyArray); } + @SuppressWarnings("unused") + /* + * Used for codegen initialize configurable variables. + */ public static void initConfigurableVariables(Module rootModule, Map configurationData, String[] args, Path[] configFilePaths, String configContent) { @@ -158,6 +150,10 @@ private static String populateConfigDetails(List paths, Map globalLockMap; + + private final ReentrantReadWriteLock storeLock; + + public BLockStore() { + this.globalLockMap = new HashMap<>(); + this.storeLock = new ReentrantReadWriteLock(); + } + + /* + This is code generated method to get Ballerina lock and lock. + */ + @SuppressWarnings("unused") + public void lock(Strand strand, String lockName) { + try { + strand.yield(); + getLockFromMap(lockName).lock(); + strand.acquiredLockCount++; + } finally { + strand.resume(); + } + } + + /* + This is code generated method to get Ballerina lock and unlock. + */ + @SuppressWarnings("unused") + public void unlock(Strand strand, String lockName) { + try { + strand.yield(); + getLockFromMap(lockName).unlock(); + strand.acquiredLockCount--; + } finally { + strand.resume(); + } + } + + + /* + This is code generated method check and panic before async call if strand is in lock + */ + @SuppressWarnings("unused") + public void panicIfInLock(Strand strand) { + if (strand.acquiredLockCount > 0) { + throw ErrorCreator.createError(ErrorReasons.ASYNC_CALL_INSIDE_LOCK); + } + } + + private ReentrantLock getLockFromMap(String lockName) { + ReentrantLock lock; + try { + storeLock.readLock().lock(); + lock = globalLockMap.get(lockName); + } finally { + storeLock.readLock().unlock(); + } + if (lock != null) { + return lock; + } + return addLockToMap(lockName); + } + + private ReentrantLock addLockToMap(String lockName) { + try { + storeLock.writeLock().lock(); + return globalLockMap.computeIfAbsent(lockName, k -> new ReentrantLock()); + } finally { + storeLock.writeLock().unlock(); + } + } +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/RepositoryImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/repository/RepositoryImpl.java similarity index 96% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/RepositoryImpl.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/repository/RepositoryImpl.java index 002c04780501..f737e17bd7d5 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/RepositoryImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/repository/RepositoryImpl.java @@ -14,11 +14,11 @@ * limitations under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.repository; -import io.ballerina.runtime.api.Artifact; -import io.ballerina.runtime.api.Node; -import io.ballerina.runtime.api.Repository; +import io.ballerina.runtime.api.repository.Artifact; +import io.ballerina.runtime.api.repository.Node; +import io.ballerina.runtime.api.repository.Repository; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BObject; import io.ballerina.runtime.internal.types.BServiceType; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncFunctionCallback.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncFunctionCallback.java deleted file mode 100644 index e2efb600c53d..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncFunctionCallback.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2020, 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. - */ - -package io.ballerina.runtime.internal.scheduling; - -import io.ballerina.runtime.api.async.Callback; -import io.ballerina.runtime.internal.values.FutureValue; - -/** - * The callback implementation to handle non-blocking native function behaviour. - * - * @since 2.0.0 - */ - -public abstract class AsyncFunctionCallback implements Callback { - - private FutureValue future; - private final Strand strand; - - public AsyncFunctionCallback(Strand strand) { - this.strand = strand; - } - - public void setReturnValues(Object returnValue) { - strand.returnValue = returnValue; - strand.scheduler.unblockStrand(strand); - } - - public Object getFutureResult() { - return future.result; - } - - public void setFuture(FutureValue future) { - this.future = future; - } - -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncUtils.java index 945f60e47513..cc4ab7517707 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/AsyncUtils.java @@ -18,36 +18,20 @@ package io.ballerina.runtime.internal.scheduling; -import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; -import io.ballerina.runtime.api.async.Callback; -import io.ballerina.runtime.api.async.StrandMetadata; import io.ballerina.runtime.api.creators.ErrorCreator; -import io.ballerina.runtime.api.types.FunctionType; -import io.ballerina.runtime.api.types.MethodType; -import io.ballerina.runtime.api.types.ObjectType; -import io.ballerina.runtime.api.types.Parameter; -import io.ballerina.runtime.api.types.RemoteMethodType; -import io.ballerina.runtime.api.types.ResourceMethodType; import io.ballerina.runtime.api.utils.StringUtils; -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; -import io.ballerina.runtime.internal.types.BFunctionType; -import io.ballerina.runtime.internal.types.BServiceType; +import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.internal.utils.ErrorUtils; import io.ballerina.runtime.internal.values.FutureValue; -import io.ballerina.runtime.internal.values.ValueCreator; +import io.ballerina.runtime.internal.values.MapValue; import java.util.ArrayList; -import java.util.HashMap; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicInteger; -import java.util.function.BiConsumer; -import java.util.function.Consumer; -import java.util.function.Function; import java.util.function.Supplier; /** @@ -55,279 +39,168 @@ */ public final class AsyncUtils { - /** - * Block the current strand to execute asynchronously. - * - * @return Future object to unblock the strand. - */ - public static CompletableFuture markAsync() { - Strand strand = Scheduler.getStrand(); - strand.blockedOnExtern = true; - strand.setState(State.BLOCK_AND_YIELD); - CompletableFuture future = new CompletableFuture<>(); - future.whenComplete(new Unblocker(strand)); - return future; - } - - /** - * Invoke Function Pointer asynchronously. This will schedule the function and block the strand. - * - * @param func Function Pointer to be invoked. - * @param strandName Name for newly creating strand which is used to execute the function pointer. This is - * optional and can be null. - * @param metadata Meta data of new strand. - * @param args Ballerina function arguments. - * @param resultHandleFunction Function used to process the result received after execution of function. - * @param scheduler The scheduler for invoking functions - * @return Future Value - */ - public static FutureValue invokeFunctionPointerAsync(BFunctionPointer func, String strandName, - StrandMetadata metadata, Object[] args, - Function resultHandleFunction, - Scheduler scheduler) { - Strand parent = Scheduler.getStrand(); - AsyncFunctionCallback callback = new AsyncFunctionCallback(parent) { - @Override - public void notifySuccess(Object result) { - setReturnValues(resultHandleFunction.apply(getFutureResult())); - } - - @Override - public void notifyFailure(BError error) { - handleRuntimeErrors(parent, error); - } - }; - BFunctionType funcType = (BFunctionType) TypeUtils.getImpliedType(func.getType()); - blockStrand(parent); - FutureValue future = scheduler.createFuture(parent, null, null, funcType.retType, strandName, metadata); - AsyncUtils.getArgsWithDefaultValues(scheduler, func, new Callback() { - @Override - public void notifySuccess(Object result) { - invokeFunctionPointerAsync(func, parent, future, (Object[]) result, callback, scheduler); - } - - @Override - public void notifyFailure(BError error) { - callback.notifyFailure(error); - } - }, args); - return future; - } - - /** - * Invoke Function Pointer asynchronously given number of times. This will schedule the function and block the - * strand. This method can be used with collection of data where we need to invoke the function pointer for each - * item of the collection. - * - * @param func Function Pointer to be invoked. - * @param strandName Name for newly creating strand which is used to execute the function pointer. This is - * optional and can be null. - * @param metadata Meta data of new strand. - * @param noOfIterations Number of iterations need to call the function pointer. - * @param argsSupplier Supplier provides dynamic arguments to function pointer execution in each iteration. - * @param futureResultConsumer Consumer used to process the future value received after execution of function. - * Future value result will have the return object of the function pointer. - * @param returnValueSupplier Suppler used to set the final return value for the parent function invocation. - * @param scheduler The scheduler for invoking functions - */ - public static void invokeFunctionPointerAsyncIteratively(BFunctionPointer func, String strandName, - StrandMetadata metadata, int noOfIterations, - Supplier argsSupplier, - Consumer futureResultConsumer, - Supplier returnValueSupplier, - Scheduler scheduler) { - if (noOfIterations <= 0) { - return; - } - Strand parent = Scheduler.getStrand(); - blockStrand(parent); - AtomicInteger callCount = new AtomicInteger(0); - BFunctionType funcType = (BFunctionType) TypeUtils.getImpliedType(func.getType()); - scheduleNextFunction(func, funcType, parent, strandName, metadata, noOfIterations, callCount, argsSupplier, - futureResultConsumer, returnValueSupplier, scheduler); - - } - - public static void getArgsWithDefaultValues(Scheduler scheduler, BObject object, - String methodName, Callback callback, Object... args) { - ObjectType objectType = (ObjectType) TypeUtils.getImpliedType(object.getType()); - Module module = objectType.getPackage(); - if (args.length == 0 || module == null) { - callback.notifySuccess(args); - return; + public static Object handleNonIsolatedStrand(Strand strand, Supplier resultSupplier) { + // This check required for non strand Threads. + boolean runnable = strand.isRunnable(); + if (runnable) { + strand.yield(); } - ValueCreator valueCreator = ValueCreator.getValueCreator(ValueCreator.getLookupKey(module, module.isTestPkg())); - FunctionType functionType = getObjectMethodType(methodName, objectType); - if (functionType == null) { - throw ErrorCreator.createError(StringUtils.fromString("No such method: " + methodName)); + Object result = resultSupplier.get(); + if (runnable) { + strand.resume(); } - Parameter[] parameters = functionType.getParameters(); - getArgsWithDefaultValues(scheduler, callback, valueCreator, 0, args, parameters, new ArrayList<>()); + return result; } - private static void getArgsWithDefaultValues(Scheduler scheduler, BFunctionPointer func, Callback callback, - Object... args) { - FunctionType functionType = (FunctionType) TypeUtils.getImpliedType(func.getType()); - Module module = functionType.getPackage(); - if (args.length == 0 || module == null) { - callback.notifySuccess(args); - return; - } - ValueCreator valueCreator = ValueCreator.getValueCreator(ValueCreator.getLookupKey(module, false)); - Parameter[] parameters = functionType.getParameters(); - getArgsWithDefaultValues(scheduler, callback, valueCreator, 0, args, parameters, new ArrayList<>()); - } - - private static void getArgsWithDefaultValues(Scheduler scheduler, Callback callback, ValueCreator valueCreator, - int startArg, Object[] args, Parameter[] parameters, - List argsWithDefaultValues) { - int paramCount = startArg / 2; - Parameter parameter; - if (!((Boolean) args[startArg + 1]) && (paramCount < parameters.length) && - ((parameter = parameters[paramCount]).isDefault)) { - // If argument not provided and parameter has default value we call default value function to get the value - callDefaultValueFunction(scheduler, callback, valueCreator, startArg, args, parameters, - argsWithDefaultValues, parameter); - return; + @SuppressWarnings("unused") + /* + * Used for codegen wait for future. + */ + public static Object handleWait(Strand strand, FutureValue future) { + future.strand.checkStrandCancelled(); + if (future.getAndSetWaited()) { + return ErrorUtils.createWaitOnSameFutureError(); } - - // Else use user given argument value. - argsWithDefaultValues.add(args[startArg]); - getNextDefaultParamValue(scheduler, callback, valueCreator, startArg, args, parameters, - argsWithDefaultValues); + return handleWait(strand, future.completableFuture); } - private static void getNextDefaultParamValue(Scheduler scheduler, Callback callback, ValueCreator valueCreator, - int startArg, Object[] args, Parameter[] parameters, - List argsWithDefaultValues) { - int nextArgCount = startArg + 2; - if (nextArgCount == args.length) { - // Once all arguments are processed notify the call back - callback.notifySuccess(argsWithDefaultValues.toArray()); - } else { - // Process next parameter with arguments - getArgsWithDefaultValues(scheduler, callback, valueCreator, nextArgCount, args, parameters, - argsWithDefaultValues); + public static Object handleWait(Strand strand, CompletableFuture completableFuture) { + if (strand.isIsolated) { + return getFutureResult(completableFuture); } + return handleNonIsolatedStrand(strand, () -> getFutureResult(completableFuture)); } - private static void callDefaultValueFunction(Scheduler scheduler, Callback callback, ValueCreator valueCreator, - int startArg, Object[] args, Parameter[] parameters, - List argsWithDefaultValues, - Parameter parameter) { - String funcName = parameter.defaultFunctionName; - Function defaultFunc = o -> valueCreator.call((Strand) (((Object[]) o)[0]), funcName, - argsWithDefaultValues.toArray()); - Callback defaultFunctionCallback = new Callback() { - @Override - public void notifySuccess(Object result) { - argsWithDefaultValues.add(result); - getNextDefaultParamValue(scheduler, callback, valueCreator, startArg, args, parameters, - argsWithDefaultValues); - } - @Override - public void notifyFailure(BError error) { - callback.notifyFailure(error); + @SuppressWarnings("unused") + /* + * Used for codegen wait for any of future from given list. + */ + public static Object handleWaitAny(Strand strand, List futures) { + CompletableFuture[] cFutures = new CompletableFuture[futures.size()]; + for (int i = 0; i < futures.size(); i++) { + FutureValue future = futures.get(i); + future.strand.checkStrandCancelled(); + if (future.getAndSetWaited()) { + return ErrorUtils.createWaitOnSameFutureError(); } - }; - FutureValue future = scheduler.createFuture(null, defaultFunctionCallback, null, null, funcName, null); - scheduler.schedule(args, defaultFunc, future); + cFutures[i] = future.completableFuture; + } + return handleWaitAny(strand, cFutures); } - private static MethodType getObjectMethodType(String methodName, ObjectType objectType) { - Map methodTypesMap = new HashMap<>(); - if (objectType.getTag() == TypeTags.SERVICE_TAG) { - BServiceType serviceType = (BServiceType) objectType; - ResourceMethodType[] resourceMethods = serviceType.getResourceMethods(); - for (ResourceMethodType resourceMethodType : resourceMethods) { - methodTypesMap.put(resourceMethodType.getName(), resourceMethodType); - } - RemoteMethodType[] remoteMethodTypes = serviceType.getRemoteMethods(); - for (RemoteMethodType remoteMethodType : remoteMethodTypes) { - methodTypesMap.put(remoteMethodType.getName(), remoteMethodType); + @SuppressWarnings("unused") + /* + * Used for codegen wait for all futures from given list. + */ + public static void handleWaitMultiple(Strand strand, Map futureMap, + MapValue target) { + Collection futures = futureMap.values(); + List> cFutures = new ArrayList<>(); + List alreadyWaitedKeys = new ArrayList<>(); + for (Map.Entry entry : futureMap.entrySet()) { + FutureValue future = entry.getValue(); + future.strand.checkStrandCancelled(); + if (!future.getAndSetWaited()) { + cFutures.add(future.completableFuture); + } else { + alreadyWaitedKeys.add(entry.getKey()); } } - MethodType[] objectTypeMethods = objectType.getMethods(); - for (MethodType methodType : objectTypeMethods) { - methodTypesMap.put(methodType.getName(), methodType); + if (strand.isIsolated) { + waitForAllFutureResult(cFutures.toArray(new CompletableFuture[0])); + getAllFutureResult(futureMap, alreadyWaitedKeys, target); } - return methodTypesMap.get(methodName); + handleNonIsolatedStrand(strand, () -> { + waitForAllFutureResult(cFutures.toArray(new CompletableFuture[0])); + getAllFutureResult(futureMap, alreadyWaitedKeys, target); + return null; + }); } - private static void scheduleNextFunction(BFunctionPointer func, BFunctionType funcType, Strand parent, - String strandName, StrandMetadata metadata, int noOfIterations, - AtomicInteger callCount, Supplier argsSupplier, - Consumer futureResultConsumer, - Supplier returnValueSupplier, Scheduler scheduler) { - AsyncFunctionCallback callback = new AsyncFunctionCallback(parent) { - @Override - public void notifySuccess(Object result) { - futureResultConsumer.accept(getFutureResult()); - if (callCount.incrementAndGet() != noOfIterations) { - scheduleNextFunction(func, funcType, parent, strandName, metadata, noOfIterations, callCount, - argsSupplier, futureResultConsumer, returnValueSupplier, scheduler); + public static Object handleWaitAny(Strand strand, CompletableFuture[] cFutures) { + Object result; + if (strand.isIsolated) { + result = getAnyFutureResult(cFutures); + } else { + result = handleNonIsolatedStrand(strand, () -> getAnyFutureResult(cFutures)); + } + if (cFutures.length > 1 && result instanceof BError) { + List> nonErrorFutures = new ArrayList<>(); + for (CompletableFuture completableFuture : cFutures) { + if (completableFuture.isDone()) { + result = getFutureResult(completableFuture); + if (!(result instanceof BError)) { + return result; + } } else { - setReturnValues(returnValueSupplier.get()); + nonErrorFutures.add(completableFuture); } } - - @Override - public void notifyFailure(BError error) { - handleRuntimeErrors(parent, error); - } - }; - AsyncUtils.getArgsWithDefaultValues(scheduler, func, new Callback() { - @Override - public void notifySuccess(Object result) { - FutureValue future = scheduler.createFuture(parent, null, null, funcType.retType, strandName, metadata); - invokeFunctionPointerAsync(func, parent, future, (Object[]) result, callback, scheduler); + if (!nonErrorFutures.isEmpty()) { + return handleWaitAny(strand, nonErrorFutures.toArray(new CompletableFuture[0])); } - @Override - public void notifyFailure(BError error) { - handleRuntimeErrors(parent, error); - } - }, argsSupplier.get()); - } - - private static void invokeFunctionPointerAsync(BFunctionPointer func, Strand parent, - FutureValue future, Object[] args, - AsyncFunctionCallback callback, Scheduler scheduler) { - future.callback = callback; - callback.setFuture(future); - Object[] argsWithStrand = new Object[args.length + 1]; - System.arraycopy(args, 0, argsWithStrand, 1, args.length); - argsWithStrand[0] = future.strand; - scheduler.scheduleLocal(argsWithStrand, func, parent, future); + } + return result; } - private static void blockStrand(Strand strand) { - if (!strand.blockedOnExtern) { - strand.blockedOnExtern = true; - strand.setState(State.BLOCK_AND_YIELD); - strand.returnValue = null; + public static Object getFutureResult(CompletableFuture completableFuture) throws BError { + try { + return completableFuture.get(); + } catch (Throwable e) { + if (e.getCause() instanceof BError bError) { + throw bError; + } + throw ErrorCreator.createError(e); } } - private static void handleRuntimeErrors(Strand parent, BError error) { - parent.panic = error; - parent.scheduler.unblockStrand(parent); + public static Object getAnyFutureResult(CompletableFuture[] cFutures) { + int fSize = cFutures.length; + CompletableFuture resultFuture = new CompletableFuture<>(); + AtomicInteger count = new AtomicInteger(); + for (CompletableFuture f : cFutures) { + f.whenComplete((result, ex) -> { + if (ex != null) { + resultFuture.completeExceptionally(ex); + return; + } + if (count.incrementAndGet() < fSize && result instanceof BError) { + return; + } + resultFuture.complete(result); + }); + } + CompletableFuture anyFuture = CompletableFuture.anyOf(resultFuture, CompletableFuture.allOf(cFutures)); + Object r = getFutureResult(anyFuture); + if (r != null) { + return r; + } + return getFutureResult(resultFuture); } - private static class Unblocker implements BiConsumer { - - private final Strand strand; - - public Unblocker(Strand strand) { - this.strand = strand; + private static void getAllFutureResult(Map futureMap, List alreadyWaitedKeys, + MapValue target) { + for (Map.Entry entry : futureMap.entrySet()) { + FutureValue future = entry.getValue(); + String key = entry.getKey(); + if (alreadyWaitedKeys.contains(key)) { + target.put(StringUtils.fromString(key), ErrorUtils.createWaitOnSameFutureError()); + } else { + target.put(StringUtils.fromString(key), getFutureResult(future.completableFuture)); + } } + } - @Override - public void accept(Object returnValue, Throwable throwable) { - if (throwable == null) { - this.strand.returnValue = returnValue; - this.strand.scheduler.unblockStrand(strand); - } + public static void waitForAllFutureResult(CompletableFuture[] futures) { + CompletableFuture failure = new CompletableFuture<>(); + for (CompletableFuture f : futures) { + f.exceptionally(ex -> { + failure.completeExceptionally(ex); + return null; + }); } + CompletableFuture future = CompletableFuture.anyOf(failure, CompletableFuture.allOf(futures)); + getFutureResult(future); } private AsyncUtils() { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/BLangThreadFactory.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/BLangThreadFactory.java deleted file mode 100644 index ff458fac4afe..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/BLangThreadFactory.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.internal.scheduling; - -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * {@code BLangThreadFactory} creates a thread factory with a given prefix. - * - * @since 1.0.0 - */ -public class BLangThreadFactory implements ThreadFactory { - - private final AtomicInteger threadNumber = new AtomicInteger(1); - private final ThreadGroup group; - private final String namePrefix; - - public BLangThreadFactory(ThreadGroup group, String namePrefix) { - this.group = group; - this.namePrefix = namePrefix + "-"; - } - - public BLangThreadFactory(String namePrefix) { - this(Thread.currentThread().getThreadGroup(), namePrefix); - } - - @Override - public Thread newThread(Runnable r) { - Thread t = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0); - if (t.isDaemon()) { - t.setDaemon(false); - } - if (t.getPriority() != Thread.NORM_PRIORITY) { - t.setPriority(Thread.NORM_PRIORITY); - } - return t; - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/ClassloaderRuntime.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/ClassloaderRuntime.java new file mode 100644 index 000000000000..6fec4cc46231 --- /dev/null +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/ClassloaderRuntime.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (http://wso2.com) + * + * Licensed 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 io.ballerina.runtime.internal.scheduling; + +import io.ballerina.runtime.api.Module; +import io.ballerina.runtime.internal.BalRuntime; +import io.ballerina.runtime.internal.values.ValueCreator; + +/** + * This class represents the Ballerina runtime that is created using a classloader for internal purposes. + * + * @since 2201.11.0 + */ +public class ClassloaderRuntime extends BalRuntime { + + private final ClassLoader classLoader; + + public ClassloaderRuntime(Module module, ClassLoader classLoader) { + super(module); + this.classLoader = classLoader; + } + + @Override + protected Class loadClass(String className) throws ClassNotFoundException { + String name = getFullQualifiedClassName(rootModule, className); + return Class.forName(name, true, classLoader); + } + + @Override + public void stop() { + super.stop(); + ValueCreator.removeValueCreator(rootModule); + } +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/FunctionFrame.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/FunctionFrame.java deleted file mode 100644 index 5748977130ff..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/FunctionFrame.java +++ /dev/null @@ -1,33 +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. - */ - -package io.ballerina.runtime.internal.scheduling; - -/** - * This abstract class represents the function frame which saves the existing - * state when a function yields. - * - * @since 2201.2.0 - */ -public abstract class FunctionFrame { - - public String yieldLocation; - - public String yieldStatus; - -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/ItemGroup.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/ItemGroup.java deleted file mode 100644 index 5ad72bfd838f..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/ItemGroup.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) (2019-2022), 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 io.ballerina.runtime.internal.scheduling; - -import java.util.Stack; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReentrantLock; - -/** - * Represents a group of {@link SchedulerItem} that should run on same thread. - * - * @since 0.995.0 - */ -public class ItemGroup { - - private static final AtomicInteger nextItemGroupId = new AtomicInteger(0); - - private final int id; - - /** - * Keep the list of items that should run on same thread. - * Using a stack to get advantage of the locality. - */ - Stack items = new Stack<>(); - - /** - * Indicates this item is already in runnable list/executing or not. - */ - AtomicBoolean scheduled = new AtomicBoolean(false); - - private final ReentrantLock groupLock = new ReentrantLock(); - - public static final ItemGroup POISON_PILL = new ItemGroup(); - - public ItemGroup(SchedulerItem item) { - this(); - items.push(item); - } - - public ItemGroup() { - this.id = nextItemGroupId.incrementAndGet(); - } - - public void add(SchedulerItem item) { - items.push(item); - } - - public SchedulerItem get() { - return items.pop(); - } - - public void lock() { - this.groupLock.lock(); - } - - public void unlock() { - this.groupLock.unlock(); - } - - public int getId() { - return id; - } - - public static int getCreatedStrandGroupCount() { - return nextItemGroupId.get(); - } - - public boolean isScheduled() { - return scheduled.get(); - } -} 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 1b916ae629df..e5860dd51757 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 @@ -16,24 +16,14 @@ */ 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; -import io.ballerina.runtime.internal.types.BFunctionType; -import io.ballerina.runtime.internal.util.RuntimeUtils; -import io.ballerina.runtime.internal.values.FutureValue; +import io.ballerina.runtime.internal.utils.RuntimeUtils; +import io.ballerina.runtime.internal.values.ObjectValue; -import java.io.PrintStream; +import java.util.ArrayDeque; import java.util.Deque; -import java.util.Iterator; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentLinkedDeque; -import java.util.function.Function; - -import static io.ballerina.runtime.api.values.BError.ERROR_PRINT_PREFIX; +import java.util.concurrent.locks.ReentrantLock; /** * The registry for runtime dynamic listeners and stop handlers. @@ -42,112 +32,50 @@ */ public class RuntimeRegistry { - private final Scheduler scheduler; - private final Set listenerSet = ConcurrentHashMap.newKeySet(); - private final Deque> stopHandlerStack = new ConcurrentLinkedDeque<>(); - - private static final PrintStream outStream = System.err; + public final Scheduler scheduler; + public final Deque listenerQueue = new ArrayDeque<>(); + private final Deque stopHandlerQueue = new ArrayDeque<>(); + private final ReentrantLock listenerLock = new ReentrantLock(); + private final ReentrantLock stopHandlerLock = new ReentrantLock(); public RuntimeRegistry(Scheduler scheduler) { this.scheduler = scheduler; } - public synchronized void registerListener(BObject listener) { - listenerSet.add(listener); - scheduler.setImmortal(true); - } - - public synchronized void deregisterListener(BObject listener) { - listenerSet.remove(listener); - if (!scheduler.isListenerDeclarationFound() && listenerSet.isEmpty()) { - scheduler.setImmortal(false); + public void registerListener(BObject listener) { + try { + listenerLock.lock(); + listenerQueue.add(listener); + } finally { + listenerLock.unlock(); } } - public synchronized void registerStopHandler(BFunctionPointer stopHandler) { - stopHandlerStack.push(stopHandler); - } - - public synchronized void gracefulStop(Strand strand) { - Scheduler currentScheduler = strand.scheduler; - Iterator iterator = listenerSet.iterator(); - invokeListenerGracefulStop(strand, currentScheduler, iterator); - } - - private synchronized void invokeListenerGracefulStop(Strand strand, Scheduler scheduler, - Iterator iterator) { - if (iterator.hasNext()) { - ListenerCallback callback = new ListenerCallback(strand, scheduler, iterator); - BObject listener = iterator.next(); - Function func = o -> listener.call((Strand) (o)[0], "gracefulStop"); - scheduler.schedule(new Object[1], func, null, callback, null, null, - null, strand.getMetadata()); - } else { - invokeStopHandlerFunction(strand, scheduler); + public void deregisterListener(BObject listener) { + try { + listenerLock.lock(); + listenerQueue.remove(listener); + } finally { + listenerLock.unlock(); } } - private synchronized void invokeStopHandlerFunction(Strand strand, Scheduler scheduler) { - if (stopHandlerStack.isEmpty()) { - return; + public void registerStopHandler(BFunctionPointer stopHandler) { + try { + stopHandlerLock.lock(); + stopHandlerQueue.push(stopHandler); + } finally { + stopHandlerLock.unlock(); } - BFunctionPointer bFunctionPointer = stopHandlerStack.pop(); - StopHandlerCallback callback = new StopHandlerCallback(strand, scheduler); - final FutureValue future = scheduler.createFuture(strand, callback, null, - ((BFunctionType) TypeUtils.getImpliedType(bFunctionPointer.getType())).retType, null, - strand.getMetadata()); - scheduler.scheduleLocal(new Object[]{strand}, bFunctionPointer, strand, future); } - /** - * The callback implementation for runtime dynamic listeners. - */ - public class ListenerCallback implements Callback { - - private final Iterator iterator; - private final Strand strand; - private final Scheduler scheduler; - - ListenerCallback(Strand strand, Scheduler scheduler, Iterator iterator) { - this.strand = strand; - this.scheduler = scheduler; - this.iterator = iterator; - } + public void gracefulStop(Strand strand) { + while (!listenerQueue.isEmpty()) { + RuntimeUtils.handleErrorResult(((ObjectValue) listenerQueue.pollFirst()).call(strand, "gracefulStop")); - @Override - public void notifySuccess(Object result) { - RuntimeUtils.handleRuntimeErrorReturns(result); - invokeListenerGracefulStop(strand, scheduler, iterator); } - - @Override - public void notifyFailure(BError error) { - outStream.println(ERROR_PRINT_PREFIX + error.getPrintableStackTrace()); - } - } - - /** - * The callback implementation for stop handlers. - */ - public class StopHandlerCallback implements Callback { - - private final Strand strand; - private final Scheduler scheduler; - - StopHandlerCallback(Strand strand, Scheduler scheduler) { - this.strand = strand; - this.scheduler = scheduler; - } - - @Override - public void notifySuccess(Object result) { - RuntimeUtils.handleRuntimeErrorReturns(result); - invokeStopHandlerFunction(strand, scheduler); - } - - @Override - public void notifyFailure(BError error) { - outStream.println(ERROR_PRINT_PREFIX + error.getPrintableStackTrace()); + while (!stopHandlerQueue.isEmpty()) { + RuntimeUtils.handleErrorResult(stopHandlerQueue.pollFirst().call(scheduler.runtime)); } } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java index a2d081f95ff9..a7b657dceba5 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Scheduler.java @@ -17,36 +17,36 @@ package io.ballerina.runtime.internal.scheduling; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.async.Callback; -import io.ballerina.runtime.api.async.StrandMetadata; -import io.ballerina.runtime.api.constants.RuntimeConstants; +import io.ballerina.runtime.api.Module; +import io.ballerina.runtime.api.concurrent.StrandMetadata; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.FunctionType; +import io.ballerina.runtime.api.types.MethodType; +import io.ballerina.runtime.api.types.ObjectType; +import io.ballerina.runtime.api.types.Parameter; +import io.ballerina.runtime.api.types.RemoteMethodType; +import io.ballerina.runtime.api.types.ResourceMethodType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; +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.internal.errors.ErrorReasons; -import io.ballerina.runtime.internal.util.RuntimeUtils; -import io.ballerina.runtime.internal.values.ChannelDetails; +import io.ballerina.runtime.api.values.BNever; +import io.ballerina.runtime.api.values.BObject; +import io.ballerina.runtime.internal.BalRuntime; +import io.ballerina.runtime.internal.types.BFunctionType; +import io.ballerina.runtime.internal.types.BServiceType; +import io.ballerina.runtime.internal.utils.ErrorUtils; +import io.ballerina.runtime.internal.values.FPValue; import io.ballerina.runtime.internal.values.FutureValue; +import io.ballerina.runtime.internal.values.ObjectValue; +import io.ballerina.runtime.internal.values.ValueCreator; -import java.io.PrintStream; import java.util.HashMap; import java.util.Map; -import java.util.Set; -import java.util.Stack; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.LinkedBlockingDeque; -import java.util.concurrent.Semaphore; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; +import java.util.concurrent.locks.ReentrantLock; import java.util.function.Function; -import static io.ballerina.runtime.internal.scheduling.ItemGroup.POISON_PILL; - /** * Strand scheduler for JBallerina. * @@ -54,510 +54,405 @@ */ public class Scheduler { - private static final PrintStream ERR = System.err; - - /** - * Scheduler does not get killed if the immortal value is true. Specific to services. - */ - private volatile boolean immortal; - private boolean listenerDeclarationFound; - /** - * Strands that are ready for execution. - */ - private final BlockingQueue runnableList = new LinkedBlockingDeque<>(); - - private static final ThreadLocal STRAND_HOLDER = ThreadLocal.withInitial(StrandHolder::new); - private static final ConcurrentHashMap CURRENT_STRANDS = new ConcurrentHashMap<>(); - private final Strand previousStrand; - - private final AtomicInteger totalStrands = new AtomicInteger(); - - private static final String POOL_SIZE_CONF = System.getenv(RuntimeConstants.BALLERINA_MAX_POOL_SIZE_ENV_VAR); - - /** - * This can be changed by setting the BALLERINA_MAX_POOL_SIZE system variable. - * Default is 100. - */ - private final int numThreads; - - private static int poolSize = Runtime.getRuntime().availableProcessors() * 2; - - private Semaphore mainBlockSem; - private final RuntimeRegistry runtimeRegistry; - private final AtomicReference objectGroup = new AtomicReference<>(); - private static Strand daemonStrand = null; - - public static void setDaemonStrand(Strand strand) { - daemonStrand = strand; - } + public final ReentrantLock globalNonIsolatedLock = new ReentrantLock(); - public static Strand getDaemonStrand() { - return daemonStrand; - } + private static final ThreadLocal strandHolder = ThreadLocal.withInitial(StrandHolder::new); - public Scheduler(boolean immortal) { - this(getPoolSize(), immortal); - } + public final BalRuntime runtime; - public Scheduler(int numThreads, boolean immortal) { - this.numThreads = numThreads; - this.immortal = immortal; - this.runtimeRegistry = new RuntimeRegistry(this); - this.previousStrand = numThreads == 1 ? STRAND_HOLDER.get().strand : null; - ItemGroup group = new ItemGroup(); - objectGroup.set(group); + public Scheduler(BalRuntime runtime) { + this.runtime = runtime; } public static Strand getStrand() { - Strand strand = STRAND_HOLDER.get().strand; - if (strand == null) { - throw new IllegalStateException("strand is not accessible from non-strand-worker threads"); + return strandHolder.get().strand; + } + public Object callFunction(Module module, String functionName, StrandMetadata metadata, Object... args) { + Strand parentStrand = Scheduler.getStrand(); + if (parentStrand != null) { + boolean runnable = parentStrand.isRunnable(); + if (!runnable) { + parentStrand.resume(); + } + ValueCreatorAndFunctionType functionType = getGetValueCreatorAndFunctionType(module, functionName); + Object[] argsWithDefaultValues = getArgsWithDefaultValues(functionType.valueCreator(), + functionType.functionType(), parentStrand, args); + Object result = functionType.valueCreator().call(parentStrand, functionName, argsWithDefaultValues); + if (!runnable) { + parentStrand.yield(); + } + return result; + } + if (metadata != null && metadata.isConcurrentSafe()) { + return AsyncUtils.getFutureResult( + startIsolatedFunction(module, functionName, metadata, args).completableFuture); } - return strand; + return AsyncUtils.getFutureResult(startNonIsolatedFunction(module, functionName, metadata, args) + .completableFuture); } - public static Strand getStrandNoException() { - // issue #22871 is opened to fix this - return STRAND_HOLDER.get().strand; + public Object callMethod(BObject object, String methodName, StrandMetadata metadata, Object... args) { + Strand parentStrand = Scheduler.getStrand(); + if (parentStrand != null) { + boolean runnable = parentStrand.isRunnable(); + if (!runnable) { + parentStrand.resume(); + } + ObjectType objectType = (ObjectType) TypeUtils.getImpliedType(object.getOriginalType()); + MethodType methodType = getObjectMethodType(methodName, objectType); + Object[] argsWithDefaultValues = getArgsWithDefaultValues(objectType, methodType, parentStrand, args); + Object result = ((ObjectValue) object).call(parentStrand, methodName, argsWithDefaultValues); + if (!runnable) { + parentStrand.yield(); + } + return result; + } + if (metadata != null && metadata.isConcurrentSafe()) { + return AsyncUtils.getFutureResult(startIsolatedMethod(object, methodName, metadata, args) + .completableFuture); + } + return AsyncUtils.getFutureResult(startNonIsolatedMethod(object, methodName, metadata, args) + .completableFuture); } - public static Map getCurrentStrands() { - return new HashMap<>(CURRENT_STRANDS); + public Object callFP(FPValue fp, StrandMetadata metadata, Object... args) { + Strand parentStrand = Scheduler.getStrand(); + if (parentStrand != null) { + boolean runnable = parentStrand.isRunnable(); + if (!runnable) { + parentStrand.resume(); + } + FunctionType functionType = (FunctionType) TypeUtils.getImpliedType(TypeUtils.getType(fp)); + Object[] argsWithDefaultValues = getArgsWithDefaultValues(parentStrand, args, functionType); + Object[] argsWithStrand = getArgsWithStrand(parentStrand, argsWithDefaultValues); + Object result = fp.function.apply(argsWithStrand); + if (!runnable) { + parentStrand.yield(); + } + return result; + } + if (metadata != null && metadata.isConcurrentSafe()) { + return AsyncUtils.getFutureResult(startIsolatedFP(fp, metadata, args).completableFuture); + } + return AsyncUtils.getFutureResult(startNonIsolatedFP(fp, metadata, args).completableFuture); } - /** - * Schedules given function by creating a new strand group. - * - * @param params parameters to underlying function. - * @param fp function pointer to be executed. - * @param parent parent of the new Strand that get created here. - * @param returnType return type of the function. - * @param strandName name for new strand - * @param metadata meta data of new strand - * @return {@link FutureValue} reference to the given function pointer invocation. + @SuppressWarnings("unused") + /* + * Used for codegen isolated function pointer start call */ - public FutureValue scheduleFunction(Object[] params, - BFunctionPointer fp, Strand parent, Type returnType, - String strandName, StrandMetadata metadata) { - return schedule(params, fp.getFunction(), parent, null, null, returnType, strandName, metadata); - } - - public FutureValue scheduleFunction(Object[] params, - BFunctionPointer fp, Strand parent, Type returnType, - String strandName, StrandMetadata metadata , Callback callback) { - return schedule(params, fp.getFunction(), parent, callback, null, returnType, strandName, metadata); + public FutureValue startIsolatedWorker(FPValue fp, Strand parentStrand, Type returnType, String strandName, + WorkerChannelMap workerChannelMap, Object[] args) { + FutureValue future = createFuture(parentStrand, strandName, true, returnType, + null, workerChannelMap); + args[0] = future.strand; + Thread.startVirtualThread(() -> { + try { + strandHolder.get().strand = future.strand; + Object result = fp.function.apply(args); + future.completableFuture.complete(result); + } catch (Throwable t) { + future.completableFuture.completeExceptionally(ErrorUtils.createErrorFromThrowable(t)); + } + }).setName(future.strand.name); + return future; } - /** - * Schedules given function to the callers strand group. - * - * @param params parameters to underlying function. - * @param fp function to be executed. - * @param parent parent of the new Strand that get created here. - * @param returnType return type of the function. - * @param strandName name for new strand - * @param metadata meta data of new strand - * @return {@link FutureValue} reference to the given function invocation. + @SuppressWarnings("unused") + /* + * Used for codegen non isolated function pointer start call */ - public FutureValue scheduleLocal(Object[] params, BFunctionPointer fp, Strand parent, Type returnType, - String strandName, StrandMetadata metadata) { - FutureValue future = createFuture(parent, null, null, returnType, strandName, metadata); - return scheduleLocal(params, fp, parent, future); + public FutureValue startNonIsolatedWorker(FPValue fp, Strand parentStrand, Type returnType, String strandName, + WorkerChannelMap workerChannelMap, Object[] args) { + FutureValue future = createFuture(parentStrand, strandName, false, returnType, null, workerChannelMap); + args[0] = future.strand; + Thread.startVirtualThread(() -> { + try { + future.strand.resume(); + strandHolder.get().strand = future.strand; + Object result = fp.function.apply(args); + future.completableFuture.complete(result); + } catch (Throwable t) { + future.completableFuture.completeExceptionally(ErrorUtils.createErrorFromThrowable(t)); + } finally { + future.strand.done(); + } + }).setName(future.strand.name); + return future; } - public FutureValue scheduleLocal(Object[] params, BFunctionPointer fp, - Strand parent, FutureValue future) { - params[0] = future.strand; - SchedulerItem item = new SchedulerItem(fp.getFunction(), params, future); - future.strand.schedulerItem = item; - totalStrands.incrementAndGet(); - future.strand.strandGroup = parent.strandGroup; - addToRunnableList(item, parent.strandGroup); + public FutureValue startIsolatedFunction(Module module, String functionName, StrandMetadata metadata, + Object... args) { + ValueCreator valueCreator = ValueCreator.getValueCreator(ValueCreator.getLookupKey(module.getOrg(), + module.getName(), module.getMajorVersion(), module.isTestPkg())); + FunctionType functionType = valueCreator.getFunctionType(functionName); + FutureValue future = createFutureWithMetadata(null, functionName, true, functionType.getReturnType(), + metadata, null); + Object[] argsWithDefaultValues = getArgsWithDefaultValues(valueCreator, functionType, future.strand, args); + Thread.startVirtualThread(() -> { + try { + strandHolder.get().strand = future.strand; + Object result = valueCreator.call(future.strand, functionName, argsWithDefaultValues); + future.completableFuture.complete(result); + } catch (Throwable t) { + future.completableFuture.completeExceptionally(ErrorUtils.createErrorFromThrowable(t)); + } + }).setName(future.strand.name); return future; } - public FutureValue scheduleToObjectGroup(Object[] params, Function function, Strand parent, - Callback callback, Map properties, Type returnType, - String strandName, StrandMetadata metadata) { - FutureValue future = createFuture(parent, callback, properties, returnType, strandName, metadata); - return scheduleToObjectGroup(params, function, future); + private FutureValue startIsolatedMethod(BObject object, String methodName, StrandMetadata metadata, + Object... args) { + String strandName = getStrandName(object, methodName); + ObjectType objectType = (ObjectType) TypeUtils.getImpliedType(object.getOriginalType()); + MethodType methodType = getObjectMethodType(methodName, objectType); + FutureValue future = createFutureWithMetadata(null, strandName, true, methodType.getReturnType(), metadata, + null); + Object[] argsWithDefaultValues = getArgsWithDefaultValues(objectType, methodType, future.strand, args); + Thread.startVirtualThread(() -> { + try { + strandHolder.get().strand = future.strand; + Object result = ((ObjectValue) object).call(future.strand, methodName, argsWithDefaultValues); + future.completableFuture.complete(result); + } catch (Throwable t) { + future.completableFuture.completeExceptionally(ErrorUtils.createErrorFromThrowable(t)); + } + }).setName(future.strand.name); + return future; } - public FutureValue scheduleToObjectGroup(Object[] params, Function function, - FutureValue future) { - params[0] = future.strand; - SchedulerItem item = new SchedulerItem(function, params, future); - future.strand.schedulerItem = item; - totalStrands.incrementAndGet(); - ItemGroup group = objectGroup.get(); - future.strand.strandGroup = group; - addToRunnableList(item, group); + private FutureValue startIsolatedFP(FPValue fp, StrandMetadata metadata, Object... args) { + BFunctionType functionType = (BFunctionType) fp.getType(); + FutureValue future = createFutureWithMetadata(null, fp.getName(), true, functionType.getReturnType(), + metadata, null); + Object[] argsWithDefaultValues = getArgsWithDefaultValues(future.strand, args, functionType); + Object[] argsWithStrand = getArgsWithStrand(future.strand, argsWithDefaultValues); + Thread.startVirtualThread(() -> { + try { + strandHolder.get().strand = future.strand; + Object result = fp.function.apply(argsWithStrand); + future.completableFuture.complete(result); + } catch (Throwable t) { + future.completableFuture.completeExceptionally(ErrorUtils.createErrorFromThrowable(t)); + } + }).setName(future.strand.name); return future; } - /** - * Add a task to the runnable list, which will eventually be executed by the Scheduler. - * - * @param params parameters to be passed to the function - * @param function function to be executed - * @param parent parent strand that makes the request to schedule another - * @param callback to notify any listener when ever the execution of the given function is finished - * @param properties request properties which requires for co-relation - * @param returnType return type of the scheduled function - * @param strandName name for new strand - * @param metadata meta data of new strand - * @return Reference to the scheduled task - */ - public FutureValue schedule(Object[] params, Function function, Strand parent, Callback callback, - Map properties, Type returnType, String strandName, - StrandMetadata metadata) { - FutureValue future = createFuture(parent, callback, properties, returnType, strandName, metadata); - return schedule(params, function, future); - } - /** - * Add a task to the runnable list, which will eventually be executed by the Scheduler. - * - * @param params parameters to be passed to the function - * @param function function to be executed - * @param parent parent strand that makes the request to schedule another - * @param callback to notify any listener when ever the execution of the given function is finished - * @param strandName name for new strand - * @param metadata meta data of new strand - * @return Reference to the scheduled task - */ - public FutureValue schedule(Object[] params, Function function, Strand parent, Callback callback, - String strandName, StrandMetadata metadata) { - FutureValue future = createFuture(parent, callback, null, PredefinedTypes.TYPE_NULL, strandName, metadata); - return schedule(params, function, future); - } - public FutureValue schedule(Object[] params, Function function, FutureValue future) { - params[0] = future.strand; - SchedulerItem item = new SchedulerItem(function, params, future); - future.strand.schedulerItem = item; - totalStrands.incrementAndGet(); - ItemGroup group = new ItemGroup(item); - future.strand.strandGroup = group; - group.scheduled.set(true); - runnableList.add(group); + private FutureValue startNonIsolatedFunction(Module module, String functionName, StrandMetadata metadata, + Object... args) { + ValueCreator valueCreator = ValueCreator.getValueCreator(ValueCreator.getLookupKey(module)); + FunctionType functionType = valueCreator.getFunctionType(functionName); + FutureValue future = + createFutureWithMetadata(null, functionName, false, functionType.getReturnType(), metadata, null); + Object[] argsWithDefaultValues = getArgsWithDefaultValues(valueCreator, functionType, future.strand, args); + Thread.startVirtualThread(() -> { + try { + future.strand.resume(); + strandHolder.get().strand = future.strand; + Object result = valueCreator.call(future.strand, functionName, argsWithDefaultValues); + future.completableFuture.complete(result); + } catch (Throwable t) { + future.completableFuture.completeExceptionally(ErrorUtils.createErrorFromThrowable(t)); + } finally { + future.strand.done(); + } + }).setName(future.strand.name); return future; } - /** - * Add a void returning task to the runnable list, which will eventually be executed by the Scheduler. - * - * @param params parameters to be passed to the function - * @param consumer consumer to be executed - * @param parent parent strand that makes the request to schedule another - * @param callback to notify any listener when ever the execution of the given function is finished - * @param strandName name for new strand - * @param metadata meta data of new strand - * @return Reference to the scheduled task - */ - @Deprecated - public FutureValue schedule(Object[] params, Consumer consumer, Strand parent, Callback callback, - String strandName, StrandMetadata metadata) { - FutureValue future = createFuture(parent, callback, null, PredefinedTypes.TYPE_NULL, strandName, metadata); - params[0] = future.strand; - SchedulerItem item = new SchedulerItem(consumer, params, future); - future.strand.schedulerItem = item; - totalStrands.incrementAndGet(); - ItemGroup group = new ItemGroup(item); - future.strand.strandGroup = group; - group.scheduled.set(true); - runnableList.add(group); + private FutureValue startNonIsolatedMethod(BObject object, String methodName, StrandMetadata metadata, + Object... args) { + String strandName = getStrandName(object, methodName); + ObjectType objectType = (ObjectType) TypeUtils.getImpliedType(object.getOriginalType()); + MethodType methodType = getObjectMethodType(methodName, objectType); + FutureValue future = createFutureWithMetadata(null, strandName, false, methodType.getReturnType(), metadata, + null); + Object[] argsWithDefaultValues = getArgsWithDefaultValues(objectType, methodType, future.strand, args); + Thread.startVirtualThread(() -> { + try { + future.strand.resume(); + strandHolder.get().strand = future.strand; + Object result = ((ObjectValue) object).call(future.strand, methodName, argsWithDefaultValues); + future.completableFuture.complete(result); + } catch (Throwable t) { + future.completableFuture.completeExceptionally(ErrorUtils.createErrorFromThrowable(t)); + } finally { + future.strand.done(); + } + }).setName(future.strand.name); return future; } - public void start() { - this.mainBlockSem = new Semaphore(-(numThreads - 1)); - for (int i = 0; i < numThreads - 1; i++) { - new Thread(this::runSafely, "jbal-strand-exec-" + i).start(); - } - this.runSafely(); - try { - this.mainBlockSem.acquire(); - } catch (InterruptedException e) { - RuntimeUtils.printCrashLog(e); - } + private FutureValue startNonIsolatedFP(FPValue fp, StrandMetadata metadata, Object... args) { + BFunctionType functionType = (BFunctionType) fp.getType(); + String strandName = getStrandName("$anon", fp.getName()); + FutureValue future = createFutureWithMetadata(null, strandName, true, functionType.getReturnType(), metadata, + null); + Object[] argsWithDefaultValues = getArgsWithDefaultValues(future.strand, args, functionType); + Object[] argsWithStrand = getArgsWithStrand(future.strand, argsWithDefaultValues); + Thread.startVirtualThread(() -> { + try { + future.strand.resume(); + strandHolder.get().strand = future.strand; + Object result = fp.function.apply(argsWithStrand); + future.completableFuture.complete(result); + } catch (Throwable t) { + future.completableFuture.completeExceptionally(ErrorUtils.createErrorFromThrowable(t)); + } finally { + future.strand.done(); + } + }).setName(future.strand.name); + return future; } - /** - * Defensive programming to prevent unforeseen errors. - */ - private void runSafely() { - try { - run(); - } catch (Throwable t) { - RuntimeUtils.printCrashLog(t); + private Object[] getArgsWithDefaultValues(Strand parentStrand, Object[] args, FunctionType functionType) { + Module module = functionType.getPackage(); + if (module == null) { + return args; } - } - - /** - * Executes tasks that are submitted to the Scheduler. - */ - private void run() { - while (true) { - SchedulerItem item; - ItemGroup group; + ValueCreator valueCreator = ValueCreator.getValueCreator(ValueCreator.getLookupKey(module)); + return getArgsWithDefaultValues(valueCreator, functionType, parentStrand, args); + } + + /* + Only use for tests + */ + public FutureValue startNonIsolatedWorker(Function function, Strand parentStrand, Type returnType, + String strandName, StrandMetadata metadata, Object[] args) { + FutureValue future = createFutureWithMetadata(parentStrand, strandName, false, returnType, metadata, null); + Object[] argsWithStrand = getArgsWithStrand(future.strand, args); + Thread.startVirtualThread(() -> { try { - group = runnableList.take(); - } catch (InterruptedException ignored) { - continue; + future.strand.resume(); + strandHolder.get().strand = future.strand; + Object result = function.apply(argsWithStrand); + future.completableFuture.complete(result); + } catch (Throwable t) { + future.completableFuture.completeExceptionally(ErrorUtils.createErrorFromThrowable(t)); + } finally { + future.strand.done(); } + }).setName(strandName); + return future; + } - if (group == POISON_PILL) { - this.mainBlockSem.release(); - break; - } + private ValueCreatorAndFunctionType getGetValueCreatorAndFunctionType(Module module, String functionName) { - boolean isItemsEmpty = group.items.isEmpty(); - while (!isItemsEmpty) { - Object result = null; - Throwable panic = null; - - item = group.get(); - - try { - STRAND_HOLDER.get().strand = item.future.strand; - result = item.execute(); - } catch (Throwable e) { - panic = createError(e); - notifyChannels(item, panic); - - if (!(panic instanceof BError)) { - RuntimeUtils.printCrashLog(panic); - } - // Please refer #18763. - // This logs cases where errors have occurred while strand is blocked. - if (item.isYielded()) { - RuntimeUtils.printCrashLog(panic); - } - } finally { - STRAND_HOLDER.get().strand = previousStrand; - } - postProcess(item, result, panic); - group.lock(); - if ((isItemsEmpty = group.items.isEmpty())) { - group.scheduled.set(false); - } - group.unlock(); - } + ValueCreator valueCreator; + FunctionType functionType; + try { + valueCreator = ValueCreator.getValueCreator(ValueCreator.getLookupKey(module.getOrg(), + module.getName(), module.getMajorVersion(), false)); + functionType = valueCreator.getFunctionType(functionName); + } catch (BError error) { + valueCreator = ValueCreator.getValueCreator(ValueCreator.getLookupKey(module.getOrg(), + module.getName(), module.getMajorVersion(), true)); + functionType = valueCreator.getFunctionType(functionName); } + return new ValueCreatorAndFunctionType(valueCreator, functionType); } - /** - * Processes the item after executing for notifying blocked items etc. - */ - private void postProcess(SchedulerItem item, Object result, Throwable panic) { - switch (item.getState()) { - case BLOCK_AND_YIELD: - item.future.strand.lock(); - // need to recheck due to concurrency, unblockStrand() may have changed state - if (item.getState().getStatus() == State.YIELD.getStatus()) { - reschedule(item); - item.future.strand.unlock(); - break; - } - item.parked = true; - item.future.strand.unlock(); - break; - case BLOCK_ON_AND_YIELD: - WaitContext waitContext = item.future.strand.waitContext; - waitContext.lock(); - waitContext.intermediate = false; - if (waitContext.runnable) { - waitContext.completed = true; - reschedule(item); - } - waitContext.unLock(); - break; - case YIELD: - reschedule(item); - break; - case RUNNABLE: - item.future.result = result; - item.future.isDone = true; - item.future.panic = panic; - // TODO clean, better move it to future value itself - if (item.future.callback != null) { - if (item.future.panic != null) { - item.future.callback.notifyFailure(ErrorCreator.createError(panic)); - if (item.future.strand.currentTrxContext != null) { - item.future.strand.currentTrxContext.notifyLocalRemoteParticipantFailure(); - } - } else { - item.future.callback.notifySuccess(result); - } - } - - Strand justCompleted = item.future.strand; - assert !justCompleted.getState().equals(State.DONE) : "Can't be completed twice"; - - justCompleted.setState(State.DONE); - - for (WaitContext ctx : justCompleted.waitingContexts) { - ctx.lock(); - if (!ctx.completed) { - if ((item.future.panic != null && ctx.handlePanic()) || ctx.waitCompleted(result)) { - if (ctx.intermediate) { - ctx.runnable = true; - } else { - ctx.completed = true; - reschedule(ctx.schedulerItem); - } - } - } - ctx.unLock(); - } - - cleanUp(justCompleted); - - int strandsLeft = totalStrands.decrementAndGet(); - if (strandsLeft == 0) { - // (number of started stands - finished stands) = 0, all the work is done - assert runnableList.isEmpty(); - - gracefulExit(); - } - break; - default: - assert false : "illegal strand state during execute " + item.getState(); - } - } + private record ValueCreatorAndFunctionType(ValueCreator valueCreator, FunctionType functionType) { - public void setImmortal(boolean immortal) { - this.immortal = immortal; } - private Throwable createError(Throwable t) { - if (t instanceof StackOverflowError) { - BError error = ErrorCreator.createError(ErrorReasons.STACK_OVERFLOW_ERROR); - error.setStackTrace(t.getStackTrace()); - return error; - } else if (t instanceof OutOfMemoryError) { - BError error = ErrorCreator.createError(ErrorReasons.JAVA_OUT_OF_MEMORY_ERROR, - StringUtils.fromString(t.getMessage())); - error.setStackTrace(t.getStackTrace()); - return error; - } - return t; - } + private Object[] getArgsWithDefaultValues(ObjectType objectType, MethodType methodType, Strand strand, + Object... args) { - public void unblockStrand(Strand strand) { - strand.lock(); - if (strand.schedulerItem.parked) { - strand.schedulerItem.parked = false; - reschedule(strand.schedulerItem); - } else { - // item not returned to scheduler, yet. - // scheduler will simply reschedule since this is already unlocked. - strand.setState(State.YIELD); - } - strand.unlock(); + Module module = objectType.getPackage(); + ValueCreator valueCreator = ValueCreator.getValueCreator(ValueCreator.getLookupKey(module)); + return getArgsWithDefaultValues(valueCreator, methodType, strand, args); } - private void cleanUp(Strand justCompleted) { - justCompleted.frames = null; - justCompleted.waitingContexts = null; - - CURRENT_STRANDS.remove(justCompleted.getId()); - //TODO: more cleanup , eg channels + private Object[] getArgsWithDefaultValues(ValueCreator valueCreator, FunctionType functionType, Strand strand, + Object... args) { + Parameter[] parameters = functionType.getParameters(); + if (args.length == 0 && parameters.length == 0) { + return new Object[]{}; + } + int length = functionType.getRestType() == null ? parameters.length : parameters.length + 1; + if (length < args.length) { + length = args.length; + } + Object[] argsWithDefaultValues = new Object[length]; + System.arraycopy(args, 0, argsWithDefaultValues, 0, args.length); + for (int i = 0; i < parameters.length; i++) { + Parameter parameter = parameters[i]; + if (parameter.isDefault && (args.length <= i || args[i] == BNever.getValue())) { + Object defaultValue = valueCreator.call(strand, parameter.defaultFunctionName, argsWithDefaultValues); + argsWithDefaultValues[i] = defaultValue; + } + } + return argsWithDefaultValues; } - private void notifyChannels(SchedulerItem item, Throwable panic) { - Set channels = item.future.strand.channelDetails; - - for (ChannelDetails details : channels) { - WorkerDataChannel wdChannel; - - if (details.channelInSameStrand) { - wdChannel = item.future.strand.wdChannels.getWorkerDataChannel(details.name); - } else { - wdChannel = item.future.strand.parent.wdChannels.getWorkerDataChannel(details.name); + public MethodType getObjectMethodType(String methodName, ObjectType objectType) { + Map methodTypesMap = new HashMap<>(); + if (objectType.getTag() == TypeTags.SERVICE_TAG) { + BServiceType serviceType = (BServiceType) objectType; + ResourceMethodType[] resourceMethods = serviceType.getResourceMethods(); + for (ResourceMethodType resourceMethodType : resourceMethods) { + methodTypesMap.put(resourceMethodType.getName(), resourceMethodType); } - - if (details.send) { - wdChannel.setSendPanic(panic); - } else { - wdChannel.setReceiverPanic(panic); + RemoteMethodType[] remoteMethodTypes = serviceType.getRemoteMethods(); + for (RemoteMethodType remoteMethodType : remoteMethodTypes) { + methodTypesMap.put(remoteMethodType.getName(), remoteMethodType); } } - } - - private void reschedule(SchedulerItem item) { - if (!item.getState().equals(State.RUNNABLE)) { - ItemGroup group = item.future.strand.strandGroup; - item.setState(State.RUNNABLE); - addToRunnableList(item, group); + MethodType[] objectTypeMethods = objectType.getMethods(); + for (MethodType methodType : objectTypeMethods) { + methodTypesMap.put(methodType.getName(), methodType); + } + MethodType methodType = methodTypesMap.get(methodName); + if (methodType != null) { + return methodType; } + throw ErrorCreator.createError(StringUtils.fromString("No such method: " + methodName)); } - private void addToRunnableList(SchedulerItem item, ItemGroup group) { - group.lock(); - group.add(item); - // Group maybe not picked by any thread at the moment because, - // 1) All items are blocked. - // 2) All others have finished - // In this case we need to put it back in the runnable list. - if (group.scheduled.compareAndSet(false, true)) { - runnableList.add(group); + public FutureValue createFutureWithMetadata(Strand parentStrand, String strandName, boolean isIsolated, + Type constraint, StrandMetadata metadata, + WorkerChannelMap workerChannelMap) { + if (metadata != null) { + return createFuture(parentStrand, strandName, isIsolated, constraint, metadata.properties(), + workerChannelMap); } - group.unlock(); + return createFuture(parentStrand, strandName, isIsolated, constraint, null, workerChannelMap); } - - public FutureValue createFuture(Strand parent, Callback callback, Map properties, - Type constraint, String name, StrandMetadata metadata) { - Strand newStrand = new Strand(name, metadata, this, parent, properties, parent != null ? - parent.currentTrxContext : null); - CURRENT_STRANDS.put(newStrand.getId(), newStrand); - return createFuture(parent, callback, constraint, newStrand); + public FutureValue createFuture(Strand parentStrand, String strandName, boolean isIsolated, Type constraint, + Map properties, WorkerChannelMap workerChannelMap) { + return createFuture(constraint, createStrand(parentStrand, strandName, isIsolated, properties, + workerChannelMap)); } - private FutureValue createFuture(Strand parent, Callback callback, Type constraint, Strand newStrand) { - FutureValue future = new FutureValue(newStrand, callback, constraint); - future.strand.frames = new Stack<>(); - return future; + private Strand createStrand(Strand parentStrand, String strandName, boolean isIsolated, + Map properties, WorkerChannelMap workerChannelMap) { + return new Strand(this, strandName, parentStrand, isIsolated, properties, workerChannelMap, + parentStrand != null ? parentStrand.currentTrxContext : null); } - public void poison() { - for (int i = 0; i < numThreads; i++) { - runnableList.add(POISON_PILL); - } + private FutureValue createFuture(Type constraint, Strand newStrand) { + return new FutureValue(newStrand, constraint); } - public void setListenerDeclarationFound(boolean listenerDeclarationFound) { - this.listenerDeclarationFound = listenerDeclarationFound; - if (listenerDeclarationFound) { - setImmortal(true); + private static String getStrandName(String functionName, String strandName) { + if (strandName == null) { + strandName = functionName; } + return strandName; } - public boolean isListenerDeclarationFound() { - return listenerDeclarationFound; + private static String getStrandName(BObject bObject, String methodName) { + return bObject.getOriginalType().getName() + ":" + methodName; } - public RuntimeRegistry getRuntimeRegistry() { - return runtimeRegistry; - } - - private static int getPoolSize() { - try { - if (POOL_SIZE_CONF != null) { - poolSize = Integer.parseInt(POOL_SIZE_CONF); - } - } catch (Throwable t) { - // Log and continue with default - ERR.println("ballerina: error occurred in scheduler while reading system variable:" + - RuntimeConstants.BALLERINA_MAX_POOL_SIZE_ENV_VAR + ", " + t.getMessage()); - } - return poolSize; - } - - public void gracefulExit() { - if (!this.immortal) { - this.poison(); - } + private static Object[] getArgsWithStrand(Strand parentStrand, Object[] args) { + Object[] argsWithStrand = new Object[args.length + 1]; + System.arraycopy(args, 0, argsWithStrand, 1, args.length); + argsWithStrand[0] = parentStrand; + return argsWithStrand; } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/SchedulerItem.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/SchedulerItem.java deleted file mode 100644 index d58c6e5807c3..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/SchedulerItem.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) (2019-2022), 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 io.ballerina.runtime.internal.scheduling; - -import io.ballerina.runtime.internal.values.FutureValue; - -import java.util.function.Consumer; -import java.util.function.Function; - -/** - * Represents an executable item in Scheduler. - * - * @since 0.995.0 - */ -class SchedulerItem { - private final Function function; - private final Object[] params; - final FutureValue future; - boolean parked; - - public SchedulerItem(Function function, Object[] params, FutureValue future) { - this.future = future; - this.function = function; - this.params = params; - } - - @Deprecated - public SchedulerItem(Consumer consumer, Object[] params, FutureValue future) { - this.future = future; - this.function = val -> { - consumer.accept(val); - return null; - }; - this.params = params; - } - - public Object execute() { - return this.function.apply(this.params); - } - - public boolean isYielded() { - return this.future.strand.isYielded(); - } - - public State getState() { - return this.future.strand.getState(); - } - - public void setState(State state) { - this.future.strand.setState(state); - } - - @Override - public String toString() { - return future == null ? "POISON_PILL" : String.valueOf(future.strand.hashCode()); - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/State.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/State.java deleted file mode 100644 index fa88e1592eb7..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/State.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.internal.scheduling; - -/** - * Maintains the Strand state. - * - * @since 1.0.0 - */ -public enum State { - RUNNABLE(1), - YIELD(1 << 1), - BLOCK_AND_YIELD(YIELD.status | (1 << 2)), - BLOCK_ON_AND_YIELD(BLOCK_AND_YIELD.status | (1 << 3)), - DONE(1 << 4); - - private final int status; - - public int getStatus() { - return status; - } - - State(int status) { - this.status = status; - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java index f107be50f6e8..214bd2d5a852 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/Strand.java @@ -18,40 +18,16 @@ package io.ballerina.runtime.internal.scheduling; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.async.StrandMetadata; -import io.ballerina.runtime.api.creators.ErrorCreator; -import io.ballerina.runtime.api.utils.StringUtils; -import io.ballerina.runtime.api.values.BError; -import io.ballerina.runtime.api.values.BMap; -import io.ballerina.runtime.api.values.BString; -import io.ballerina.runtime.internal.TypeChecker; -import io.ballerina.runtime.internal.values.ChannelDetails; -import io.ballerina.runtime.internal.values.ErrorValue; -import io.ballerina.runtime.internal.values.FutureValue; -import io.ballerina.runtime.internal.values.MapValue; +import io.ballerina.runtime.internal.utils.ErrorUtils; import io.ballerina.runtime.transactions.TransactionLocalContext; -import java.util.ArrayList; -import java.util.Collections; -import java.util.ConcurrentModificationException; import java.util.HashMap; -import java.util.HashSet; -import java.util.List; import java.util.Map; -import java.util.Optional; -import java.util.Set; +import java.util.Objects; import java.util.Stack; import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import static io.ballerina.runtime.api.constants.RuntimeConstants.CURRENT_TRANSACTION_CONTEXT_PROPERTY; -import static io.ballerina.runtime.internal.scheduling.State.BLOCK_AND_YIELD; -import static io.ballerina.runtime.internal.scheduling.State.BLOCK_ON_AND_YIELD; -import static io.ballerina.runtime.internal.scheduling.State.DONE; -import static io.ballerina.runtime.internal.scheduling.State.RUNNABLE; -import static io.ballerina.runtime.internal.scheduling.State.YIELD; /** * Strand base class used with jvm code generation for functions. @@ -60,81 +36,46 @@ */ public class Strand { - private static final AtomicInteger nextStrandId = new AtomicInteger(0); - private final int id; - private final String name; - private final StrandMetadata metadata; + private static final AtomicInteger nextStrandId = new AtomicInteger(0); + private Map globalProps; - public Stack frames; - public int resumeIndex; - public int functionInvocation; - public Object returnValue; - public BError panic; + public final String name; + public final boolean isIsolated; + public boolean cancelled; public Scheduler scheduler; - public Strand parent; - public WDChannels wdChannels; - public FlushDetail flushDetail; - public boolean blockedOnExtern; - public Set channelDetails; - public Set dependants; - public boolean cancel; - public int acquiredLockCount; - - SchedulerItem schedulerItem; - List waitingContexts; - WaitContext waitContext; - ItemGroup strandGroup; - - private Map globalProps; public TransactionLocalContext currentTrxContext; public Stack trxContexts; - private State state; - private final ReentrantLock strandLock; - public BMap workerReceiveMap = null; - public int channelCount = 0; - - public Strand() { - this.id = -1; - this.strandLock = null; - this.name = null; - this.metadata = null; - this.state = RUNNABLE; - } + public WorkerChannelMap workerChannelMap; + public int acquiredLockCount; - public Strand(String name, StrandMetadata metadata, Scheduler scheduler, Strand parent, - Map properties) { + public Strand(Scheduler scheduler, String strandName, Strand parent, boolean isIsolated, + Map properties, WorkerChannelMap workerChannelMap) { this.id = nextStrandId.incrementAndGet(); + this.name = Objects.requireNonNullElse(strandName, "$anon"); this.scheduler = scheduler; - this.wdChannels = new WDChannels(); - this.channelDetails = new HashSet<>(); - this.state = RUNNABLE; - this.dependants = new HashSet<>(); - this.strandLock = new ReentrantLock(); - this.waitingContexts = new ArrayList<>(); - this.name = name; - this.metadata = metadata; this.trxContexts = new Stack<>(); - this.parent = parent; - - //TODO: improve by using a copy on write map #26710 + this.isIsolated = isIsolated; if (properties != null) { this.globalProps = properties; - } else if (parent != null) { + } else if (parent != null && parent.globalProps != null) { this.globalProps = new HashMap<>(parent.globalProps); } else { this.globalProps = new HashMap<>(); } + this.workerChannelMap = workerChannelMap; } - public Strand(String name, StrandMetadata metadata, Scheduler scheduler, Strand parent, - Map properties, TransactionLocalContext currentTrxContext) { - this(name, metadata, scheduler, parent, properties); + + public Strand(Scheduler scheduler, String strandName, Strand parent, boolean isIsolated, + Map properties, WorkerChannelMap workerChannelMap, + TransactionLocalContext currentTrxContext) { + this(scheduler, strandName, parent, isIsolated, properties, workerChannelMap); if (currentTrxContext != null) { this.trxContexts = parent.trxContexts; this.trxContexts.push(currentTrxContext); this.currentTrxContext = currentTrxContext; } else { - Object currentContext = globalProps.get(CURRENT_TRANSACTION_CONTEXT_PROPERTY); + Object currentContext = this.getProperty(CURRENT_TRANSACTION_CONTEXT_PROPERTY); if (currentContext != null) { TransactionLocalContext branchedContext = createTrxContextBranch((TransactionLocalContext) currentContext, this.id); @@ -143,10 +84,31 @@ public Strand(String name, StrandMetadata metadata, Scheduler scheduler, Strand } } - public static int getCreatedStrandCount() { - return nextStrandId.get(); + public void resume() { + checkStrandCancelled(); + if (!this.isIsolated && !scheduler.globalNonIsolatedLock.isHeldByCurrentThread()) { + this.scheduler.globalNonIsolatedLock.lock(); + } + } + + public void yield() { + checkStrandCancelled(); + if (!this.isIsolated && scheduler.globalNonIsolatedLock.isHeldByCurrentThread()) { + this.scheduler.globalNonIsolatedLock.unlock(); + } + } + + public void done() { + if (!this.isIsolated && scheduler.globalNonIsolatedLock.isHeldByCurrentThread()) { + this.scheduler.globalNonIsolatedLock.unlock(); + } + } + + public boolean isRunnable() { + return this.isIsolated || this.scheduler.globalNonIsolatedLock.isHeldByCurrentThread(); } + private TransactionLocalContext createTrxContextBranch(TransactionLocalContext currentTrxContext, int strandName) { TransactionLocalContext trxCtx = TransactionLocalContext @@ -163,18 +125,6 @@ private TransactionLocalContext createTrxContextBranch(TransactionLocalContext c return trxCtx; } - public void handleChannelError(ChannelDetails[] channels, ErrorValue error) { - for (ChannelDetails channelDetails : channels) { - WorkerDataChannel channel = getWorkerDataChannel(channelDetails); - - if (channelDetails.send) { - channel.setSendError(error); - } else { - channel.setReceiveError(error); - } - } - } - public Object getProperty(String key) { return this.globalProps.get(key); } @@ -187,18 +137,13 @@ public boolean isInTransaction() { return this.currentTrxContext != null && this.currentTrxContext.isTransactional(); } - @Deprecated - public void removeLocalTransactionContext() { - this.currentTrxContext = null; - } - public void removeCurrentTrxContext() { if (!this.trxContexts.isEmpty()) { this.currentTrxContext = this.trxContexts.pop(); - globalProps.put(CURRENT_TRANSACTION_CONTEXT_PROPERTY, this.currentTrxContext); + this.globalProps.put(CURRENT_TRANSACTION_CONTEXT_PROPERTY, this.currentTrxContext); return; } - globalProps.remove(CURRENT_TRANSACTION_CONTEXT_PROPERTY); + this.globalProps.remove(CURRENT_TRANSACTION_CONTEXT_PROPERTY); this.currentTrxContext = null; } @@ -207,341 +152,16 @@ public void setCurrentTransactionContext(TransactionLocalContext ctx) { this.trxContexts.push(this.currentTrxContext); } this.currentTrxContext = ctx; - globalProps.putIfAbsent(CURRENT_TRANSACTION_CONTEXT_PROPERTY, this.currentTrxContext); - } - - public ErrorValue handleFlush(ChannelDetails[] channels) throws Throwable { - try { - if (flushDetail == null) { - this.flushDetail = new FlushDetail(channels); - } - this.flushDetail.flushLock.lock(); - if (flushDetail.inProgress) { - // this is a reschedule when flush is completed - if (this.flushDetail.panic != null) { - throw this.flushDetail.panic; - } - ErrorValue result = this.flushDetail.result; - cleanUpFlush(channels); - return result; - } else { - //this can be another flush in the same worker - this.flushDetail.panic = null; - this.flushDetail.result = null; - this.flushDetail.flushChannels = channels; - } - - for (ChannelDetails channel : channels) { - ErrorValue error = getWorkerDataChannel(channel).flushChannel(this); - if (error != null) { - cleanUpFlush(channels); - return error; - } else if (this.flushDetail.flushedCount == this.flushDetail.flushChannels.length) { - // flush completed - cleanUpFlush(channels); - return null; - } - } - flushDetail.inProgress = true; - this.setState(BLOCK_AND_YIELD); - return null; - } finally { - this.flushDetail.flushLock.unlock(); - } - } - - private void cleanUpFlush(ChannelDetails[] channels) { - this.flushDetail.inProgress = false; - this.flushDetail.flushedCount = 0; - this.flushDetail.result = null; - this.flushDetail.flushLock.unlock(); - for (ChannelDetails channel : channels) { - getWorkerDataChannel(channel).removeFlushWait(); - } - this.flushDetail.flushLock.lock(); - } - - public void handleWaitMultiple(Map keyValues, MapValue target) - throws Throwable { - WaitContext ctx = new WaitMultipleContext(this.schedulerItem); - ctx.waitCount.set(keyValues.size()); - ctx.lock(); - for (Map.Entry entry : keyValues.entrySet()) { - FutureValue future = entry.getValue(); - // need to lock the future's strand since we cannot have a parallel state change - future.strand.lock(); - if (future.isDone) { - if (future.panic != null) { - ctx.completed = true; - ctx.waitCount.set(0); - this.setState(RUNNABLE); - future.strand.unlock(); - ctx.unLock(); - throw future.panic; - } - if (future.hasWaited() && target.getNativeData(entry.getKey()) == null) { - target.put(StringUtils.fromString(entry.getKey()), createWaitOnSameFutureError()); - } else { - future.setWaited(true); - target.addNativeData(entry.getKey(), true); - target.put(StringUtils.fromString(entry.getKey()), future.result); - } - ctx.waitCount.decrementAndGet(); - } else { - this.setState(BLOCK_ON_AND_YIELD); - entry.getValue().strand.waitingContexts.add(ctx); - } - future.strand.unlock(); - } - - if (!this.isBlocked()) { - ctx.waitCount.set(0); - ctx.completed = true; - } else { - this.waitContext = ctx; - ctx.intermediate = true; - } - ctx.unLock(); - } - - public WaitResult handleWaitAny(List futures) throws Throwable { - WaitResult waitResult = new WaitResult(false, null); - WaitContext ctx = new WaitAnyContext(this.schedulerItem); - ctx.lock(); - ctx.waitCount.set(futures.size()); - Object error = null; - int waitedCount = 0; - for (FutureValue future : futures) { - // need to lock the future's strand since we cannot have a parallel state change - try { - future.strand.lock(); - if (future.isDone) { - if (future.panic != null) { - ctx.completed = true; - ctx.unLock(); - throw future.panic; - } - if (future.hasWaited()) { - waitedCount++; - } - boolean isErrorResult = TypeChecker.checkIsType(future.result, PredefinedTypes.TYPE_ERROR); - if (isErrorResult) { - ctx.waitCount.decrementAndGet(); - // if error, should wait for other futures as well - error = future.result; - } - if (!(future.hasWaited() || isErrorResult)) { - waitResult = new WaitResult(true, future.result); - future.setWaited(true); - break; - } - future.setWaited(true); - } else { - future.strand.waitingContexts.add(ctx); - } - } finally { - future.strand.unlock(); - } - } - if (waitedCount == futures.size()) { - waitResult = new WaitResult(true, createWaitOnSameFutureError()); - } else if (waitResult.done) { - ctx.completed = true; - } else if (ctx.waitCount.get() == 0) { - ctx.completed = true; - // all futures have error result - waitResult = new WaitResult(true, error); - } else { - this.waitContext = ctx; - this.setState(BLOCK_ON_AND_YIELD); - } - ctx.unLock(); - - return waitResult; - } - - private BError createWaitOnSameFutureError() { - return ErrorCreator.createError(StringUtils.fromString("multiple waits on the same future is not allowed")); - } - - public void updateChannelDetails(ChannelDetails[] channels) { - Collections.addAll(this.channelDetails, channels); - } - - private WorkerDataChannel getWorkerDataChannel(ChannelDetails channel) { - WorkerDataChannel dataChannel; - if (channel.channelInSameStrand) { - dataChannel = this.wdChannels.getWorkerDataChannel(channel.name); - } else { - dataChannel = this.parent.wdChannels.getWorkerDataChannel(channel.name); - } - return dataChannel; - } - - public void setState(State state) { - this.lock(); - this.state = state; - this.unlock(); - } - - public State getState() { - return this.state; - } - - public boolean isBlocked() { - return (this.state.getStatus() & BLOCK_AND_YIELD.getStatus()) == BLOCK_AND_YIELD.getStatus(); - } - - public boolean isBlockedOn() { - return (this.state.getStatus() & BLOCK_ON_AND_YIELD.getStatus()) == BLOCK_ON_AND_YIELD.getStatus(); - } - - public boolean isYielded() { - return (this.state.getStatus() & YIELD.getStatus()) == YIELD.getStatus(); - } - - public boolean isBlockedOnExtern() { - return blockedOnExtern; - } - - public void lock() { - this.strandLock.lock(); - } - - public void unlock() { - this.strandLock.unlock(); + this.globalProps.putIfAbsent(CURRENT_TRANSACTION_CONTEXT_PROPERTY, this.currentTrxContext); } public int getId() { - return id; - } - - public ItemGroup getStrandGroup() { - return strandGroup; + return this.id; } - /** - * Gets the strand name. This will be optional. Strand name can be either name given in strand annotation or async - * call or function pointer variable name. - * - * @return Optional strand name. - */ - public Optional getName() { - return Optional.ofNullable(name); - } - - /** - * Gets @{@link StrandMetadata}. - * - * @return metadata of the strand. - */ - public StrandMetadata getMetadata() { - return metadata; - } - - public String dumpState() { - StringBuilder strandInfo = new StringBuilder("\tstrand " + this.id); - if (this.name != null && this.getName().isPresent()) { - strandInfo.append(" \"").append(this.getName().get()).append("\""); - } - - strandInfo.append(" ["); - StrandMetadata strandMetadata = this.metadata; - if (strandMetadata == null) { - strandInfo.append("N/A"); - } else { - strandInfo.append(strandMetadata.getModuleOrg()).append(".").append(strandMetadata.getModuleName()) - .append(".").append(strandMetadata.getModuleVersion()).append(":") - .append(strandMetadata.getParentFunctionName()); - } - if (this.parent != null) { - strandInfo.append("][").append(this.parent.getId()); - } - strandInfo.append("] ["); - - String closingBracketWithNewLines = "]\n\n"; - if (this.isYielded()) { - getInfoFromYieldedState(strandInfo, closingBracketWithNewLines); - } else if (this.getState().equals(DONE)) { - strandInfo.append(DONE).append(closingBracketWithNewLines); - } else { - strandInfo.append(RUNNABLE).append(closingBracketWithNewLines); - } - - return strandInfo.toString(); - } - - private void getInfoFromYieldedState(StringBuilder strandInfo, String closingBracketWithNewLines) { - Stack strandFrames = this.frames; - if ((strandFrames == null) || (strandFrames.isEmpty())) { - // this means the strand frames is changed, hence the state is runnable - strandInfo.append(RUNNABLE).append(closingBracketWithNewLines); - return; - } - - StringBuilder frameStackTrace = new StringBuilder(); - String stringPrefix = "\t\tat\t"; - String yieldStatus = "BLOCKED"; - boolean noPickedYieldStatus = true; - try { - for (FunctionFrame frame : strandFrames) { - if (noPickedYieldStatus) { - yieldStatus = frame.yieldStatus; - noPickedYieldStatus = false; - } - String yieldLocation = frame.yieldLocation; - frameStackTrace.append(stringPrefix).append(yieldLocation); - frameStackTrace.append("\n"); - stringPrefix = "\t\t \t"; - } - } catch (ConcurrentModificationException ce) { - // this exception can be thrown when frames get added or removed while it is being iterated - // that means now the strand state is changed from yielded state to runnable state - strandInfo.append(RUNNABLE).append(closingBracketWithNewLines); - return; - } - if (!this.isYielded()) { - strandInfo.append(RUNNABLE).append(closingBracketWithNewLines); - return; - } - strandInfo.append(yieldStatus).append("]:\n"); - strandInfo.append(frameStackTrace).append("\n"); - } - - /** - * Class to hold flush action related details. - * - * 0.995.0 - */ - public static class FlushDetail { - public ChannelDetails[] flushChannels; - public int flushedCount; - public Lock flushLock; - public ErrorValue result; - public boolean inProgress; - public Throwable panic; - - public FlushDetail(ChannelDetails[] flushChannels) { - this.flushChannels = flushChannels; - this.flushedCount = 0; - this.flushLock = new ReentrantLock(); - this.result = null; - this.inProgress = false; - } - } - - /** - * Holds both waiting state and result. - * - * 0.995.0 - */ - public static class WaitResult { - public boolean done; - public Object result; - - public WaitResult(boolean done, Object result) { - this.done = done; - this.result = result; + public void checkStrandCancelled() { + if (this.cancelled) { + throw ErrorUtils.createCancelledFutureError(); } } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/SyncCallback.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/SyncCallback.java deleted file mode 100644 index 34b6987c7c08..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/SyncCallback.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (http://wso2.com) - * - * Licensed 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 io.ballerina.runtime.internal.scheduling; - -import io.ballerina.runtime.api.async.Callback; -import io.ballerina.runtime.api.values.BError; - -import java.util.concurrent.CountDownLatch; - -/** - * This class used to handle ballerina function invocation synchronously. - * - * @since 2201.9.1 - */ -public class SyncCallback implements Callback { - - public CountDownLatch latch; - public BError initError; - - public SyncCallback(CountDownLatch latch) { - this.latch = latch; - } - - @Override - public void notifySuccess(Object result) { - latch.countDown(); - } - - @Override - public void notifyFailure(BError error) { - latch.countDown(); - initError = error; - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WDChannels.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WDChannels.java deleted file mode 100644 index f00a5c9a40b3..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WDChannels.java +++ /dev/null @@ -1,180 +0,0 @@ -/* -* Copyright (c) 2019, 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. -*/ -package io.ballerina.runtime.internal.scheduling; - -import io.ballerina.runtime.api.creators.ValueCreator; -import io.ballerina.runtime.api.types.Type; -import io.ballerina.runtime.api.utils.StringUtils; -import io.ballerina.runtime.api.values.BMap; -import io.ballerina.runtime.api.values.BString; -import io.ballerina.runtime.internal.ErrorUtils; -import io.ballerina.runtime.internal.values.ChannelDetails; -import io.ballerina.runtime.internal.values.ErrorValue; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import static io.ballerina.runtime.internal.scheduling.State.BLOCK_AND_YIELD; - -/** - * This represents a worker data channel holder that is created for each strand to hold channels required. - * - * @since 0.995.0 - */ -public class WDChannels { - - private Map wDChannels; - private final List errors = new ArrayList<>(); - - // A worker receive field for multiple receive action. - public record ReceiveField(String fieldName, String channelName) { - } - - //TODO try to generalize this to a normal data channel, in that case we won't need these classes. - public synchronized WorkerDataChannel getWorkerDataChannel(String name) { - if (this.wDChannels == null) { - this.wDChannels = new HashMap<>(); - } - WorkerDataChannel channel = this.wDChannels.get(name); - if (channel == null) { - channel = new WorkerDataChannel(name); - this.wDChannels.put(name, channel); - } - return channel; - } - - public Object receiveDataMultipleChannels(Strand strand, ReceiveField[] receiveFields, Type targetType) - throws Throwable { - if (strand.workerReceiveMap == null) { - strand.workerReceiveMap = ValueCreator.createMapValue(targetType); - } - for (ReceiveField field : receiveFields) { - WorkerDataChannel channel = getWorkerDataChannel(field.channelName()); - WorkerDataChannel.State state = channel.getState(); - Object result = null; - switch (state) { - case OPEN: - result = channel.tryTakeData(strand, true); - break; - case AUTO_CLOSED: - result = ErrorUtils.createNoMessageError(field.channelName()); - break; - case CLOSED: - continue; - } - checkAndPopulateResult(strand, field, result, channel); - } - return clearResultCache(strand, receiveFields); - } - - private void checkAndPopulateResult(Strand strand, ReceiveField field, Object result, WorkerDataChannel channel) { - if (result == null) { - strand.setState(BLOCK_AND_YIELD); - return; - } - result = getResultValue(result); - strand.workerReceiveMap.populateInitialValue(StringUtils.fromString(field.fieldName()), result); - channel.close(); - ++strand.channelCount; - } - - private Object clearResultCache(Strand strand, ReceiveField[] receiveFields) { - if (strand.channelCount != receiveFields.length) { - return null; - } - BMap map = strand.workerReceiveMap; - strand.workerReceiveMap = null; - strand.channelCount = 0; - strand.setState(State.RUNNABLE); - return map; - } - - public Object receiveDataAlternateChannels(Strand strand, String[] channels) throws Throwable { - Object result = null; - boolean allChannelsClosed = true; - for (String channelName : channels) { - WorkerDataChannel channel = getWorkerDataChannel(channelName); - WorkerDataChannel.State state = channel.getState(); - if (state == WorkerDataChannel.State.OPEN) { - allChannelsClosed = false; - result = handleResultForOpenChannel(strand, channels, channel); - } else if (state == WorkerDataChannel.State.AUTO_CLOSED) { - errors.add((ErrorValue) ErrorUtils.createNoMessageError(channelName)); - } - } - return processResulAndError(strand, channels, result, allChannelsClosed); - } - - private Object handleResultForOpenChannel(Strand strand, String[] channels, WorkerDataChannel channel) - throws Throwable { - Object result = channel.tryTakeData(strand, true); - if (result == null) { - return null; - } - Object resultValue = getResultValue(result); - if (resultValue instanceof ErrorValue errorValue) { - errors.add(errorValue); - channel.close(); - return null; - } - closeChannels(channels); - return result; - } - - private static Object getResultValue(Object result) { - if (result instanceof WorkerDataChannel.WorkerResult workerResult) { - return workerResult.value; - } - return result; - } - - private Object processResulAndError(Strand strand, String[] channels, Object result, boolean allChannelsClosed) { - if (result == null) { - if (errors.size() == channels.length) { - result = errors.get(errors.size() - 1); - } else if (!allChannelsClosed) { - strand.setState(BLOCK_AND_YIELD); - } - } else { - strand.setState(State.RUNNABLE); - } - return getResultValue(result); - } - - private void closeChannels(String[] channels) { - for (String channelName : channels) { - WorkerDataChannel channel = getWorkerDataChannel(channelName); - channel.close(); - channel.callCount = 2; - } - } - - public synchronized void removeCompletedChannels(Strand strand, String channelName) { - if (this.wDChannels != null) { - WorkerDataChannel channel = this.wDChannels.get(channelName); - // callCount is incremented to 2 when the message passing is completed. - if (channel != null && channel.callCount == 2) { - this.wDChannels.remove(channelName); - strand.channelDetails.remove(new ChannelDetails(channelName, true, false)); - } - } - } - -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WaitAnyContext.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WaitAnyContext.java deleted file mode 100644 index 750d3540b4b4..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WaitAnyContext.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.internal.scheduling; - -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.internal.TypeChecker; - -/** - * WaitContext for Wait for any action. - * - * @since 1.0.0 - */ -public class WaitAnyContext extends WaitContext { - - WaitAnyContext(SchedulerItem schedulerItem) { - super(schedulerItem); - } - - @Override - boolean handlePanic() { - waitCount.set(0); - return true; - } - - @Override - boolean waitCompleted(Object result) { - if (TypeChecker.checkIsType(result, PredefinedTypes.TYPE_ERROR)) { - return waitCount.decrementAndGet() == 0; - } - return true; - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WaitContext.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WaitContext.java deleted file mode 100644 index 7fba62f2581b..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WaitContext.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.internal.scheduling; - -import java.util.concurrent.atomic.AtomicInteger; -import java.util.concurrent.locks.ReentrantLock; - -/** - * This context is shared among the strands to notify that a - * certain strand is waiting on another strand. - * - * @since 1.0.0 - */ -public abstract class WaitContext { - - SchedulerItem schedulerItem; - boolean runnable; - boolean completed; - boolean intermediate; - private final ReentrantLock contextLock; - AtomicInteger waitCount; - - - WaitContext(SchedulerItem schedulerItem) { - this.schedulerItem = schedulerItem; - this.contextLock = new ReentrantLock(); - this.waitCount = new AtomicInteger(); - this.intermediate = true; - } - - void lock() { - this.contextLock.lock(); - } - - void unLock() { - this.contextLock.unlock(); - } - - abstract boolean handlePanic(); - - abstract boolean waitCompleted(Object result); -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WaitMultipleContext.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WaitMultipleContext.java deleted file mode 100644 index cee19b56db05..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WaitMultipleContext.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.internal.scheduling; - -/** - * WaitContext for Wait for all action. - * - * @since 1.0.0 - */ -public class WaitMultipleContext extends WaitContext { - - WaitMultipleContext(SchedulerItem schedulerItem) { - super(schedulerItem); - } - - @Override - boolean handlePanic() { - waitCount.set(0); - return true; - } - - @Override - boolean waitCompleted(Object result) { - return waitCount.decrementAndGet() == 0; - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerChannel.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerChannel.java new file mode 100644 index 000000000000..d84f2f7d90bf --- /dev/null +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerChannel.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 io.ballerina.runtime.internal.scheduling; + +import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.internal.utils.ErrorUtils; + +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * This represents a worker channel that is created for each worker to worker interaction. + * + * @since 2201.11.0 + */ + +public class WorkerChannel { + + private final String name; + private final AtomicInteger doneCount; + private final CompletableFuture resultFuture; + private final CompletableFuture receiveFuture; + private boolean cancel; + + public WorkerChannel(String name) { + this.name = name; + this.resultFuture = new CompletableFuture<>(); + this.receiveFuture = new CompletableFuture<>(); + this.doneCount = new AtomicInteger(2); + this.cancel = false; + } + + public Object read() { + if (cancel) { + throw ErrorUtils.createCancelledFutureError(); + } + try { + return AsyncUtils.getFutureResult(resultFuture); + } finally { + receiveFuture.complete(null); + } + } + + public void write(Object result) { + if (cancel) { + throw ErrorUtils.createCancelledFutureError(); + } + resultFuture.complete(result); + } + + public void panicOnSend(BError error) { + if (resultFuture.isDone()) { + return; + } + resultFuture.completeExceptionally(error); + } + + public void panicOnReceive(BError error) { + if (receiveFuture.isDone()) { + return; + } + receiveFuture.completeExceptionally(error); + } + + public void errorOnSend(String channelKey, Object returnValue) { + if (resultFuture.isDone()) { + return; + } + BError bError; + if (returnValue instanceof BError error) { + bError = error; + } else { + bError = ErrorUtils.createNoMessageError(channelKey); + } + resultFuture.complete(bError); + } + + public void errorOnReceive(String channelKey, Object returnValue) { + if (receiveFuture.isDone()) { + return; + } + BError bError; + if (returnValue instanceof BError error) { + bError = error; + } else { + bError = ErrorUtils.createNoMessageError(channelKey); + } + receiveFuture.complete(bError); + } + + public boolean isWritten() { + return resultFuture.isDone(); + } + + public boolean isReceived() { + return receiveFuture.isDone(); + } + + public boolean done() { + return doneCount.incrementAndGet() == 0; + } + + public void cancel() { + this.cancel = true; + } + + public String getName() { + return name; + } + + public CompletableFuture getResultFuture() { + return resultFuture; + } + + public CompletableFuture getReceiveFuture() { + return receiveFuture; + } +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerChannelMap.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerChannelMap.java new file mode 100644 index 000000000000..a59f850c60ad --- /dev/null +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerChannelMap.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 io.ballerina.runtime.internal.scheduling; + +import io.ballerina.runtime.api.values.BError; + +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantReadWriteLock; + +/** + * This class stores {@link WorkerChannel} reference to unique channel key. + * + * @since 2201.11.0 + */ + +public class WorkerChannelMap { + + private final Map channelMap = new HashMap<>(); + private final ReentrantReadWriteLock channelMapLock = new ReentrantReadWriteLock(); + + public void addChannelKeys(String[] channelKeys) { + try { + channelMapLock.writeLock().lock(); + for (String channelKey : channelKeys) { + WorkerChannel workerChannel = channelMap.get(channelKey); + if (workerChannel == null) { + workerChannel = new WorkerChannel(channelKey); + channelMap.put(channelKey, workerChannel); + } + } + } finally { + channelMapLock.writeLock().unlock(); + } + } + + public WorkerChannel get(String channelKey) { + try { + channelMapLock.readLock().lock(); + return channelMap.get(channelKey); + } finally { + channelMapLock.readLock().unlock(); + } + } + + public void panicSendWorkerChannels(String channelKey, BError error) { + try { + channelMapLock.writeLock().lock(); + WorkerChannel workerChannel = channelMap.get(channelKey); + workerChannel.panicOnSend(error); + if (workerChannel.done()) { + channelMap.remove(channelKey); + } + } finally { + channelMapLock.writeLock().unlock(); + } + } + + public void panicReceiveWorkerChannels(String channelKey, BError error) { + try { + channelMapLock.writeLock().lock(); + WorkerChannel workerChannel = channelMap.get(channelKey); + workerChannel.panicOnReceive(error); + if (workerChannel.done()) { + channelMap.remove(channelKey); + } + } finally { + channelMapLock.writeLock().unlock(); + } + } + + public void completeSendWorkerChannels(String channelKey, Object returnValue) { + try { + channelMapLock.writeLock().lock(); + WorkerChannel workerChannel = channelMap.get(channelKey); + workerChannel.errorOnSend(channelKey, returnValue); + if (workerChannel.done()) { + channelMap.remove(channelKey); + } + } finally { + channelMapLock.writeLock().unlock(); + } + } + + public void completeReceiveWorkerChannels(String channelKey, Object returnValue) { + try { + channelMapLock.writeLock().lock(); + WorkerChannel workerChannel = channelMap.get(channelKey); + workerChannel.errorOnReceive(channelKey, returnValue); + if (workerChannel.done()) { + channelMap.remove(channelKey); + } + } finally { + channelMapLock.writeLock().unlock(); + } + } + + public void cancel() { + try { + channelMapLock.writeLock().lock(); + channelMap.values().forEach(WorkerChannel::cancel); + } finally { + channelMapLock.writeLock().unlock(); + } + } +} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerDataChannel.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerDataChannel.java deleted file mode 100644 index c4ada8ee3efa..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerDataChannel.java +++ /dev/null @@ -1,400 +0,0 @@ -/* - * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). - * - * 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 io.ballerina.runtime.internal.scheduling; - -import io.ballerina.runtime.internal.ErrorUtils; -import io.ballerina.runtime.internal.values.ErrorValue; - -import java.util.LinkedList; -import java.util.Queue; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -import static io.ballerina.runtime.internal.scheduling.State.BLOCK_AND_YIELD; - -/** - * This represents a worker data channel that is created for each worker to - * worker interaction for each function call. - * - * @since 0.995.0 - */ -public class WorkerDataChannel { - - private Strand receiver; - private WaitingSender waitingSender; - private WaitingSender flushSender; - private ErrorValue error; - private Throwable panic; - private int senderCounter; - private int receiverCounter; - private boolean reschedule; - - private final Lock channelLock; - - protected String chnlName; - protected int callCount = 0; - - @SuppressWarnings("rawtypes") - private final Queue channel = new LinkedList<>(); - private State state; - - public WorkerDataChannel() { - this.channelLock = new ReentrantLock(); - this.senderCounter = 0; - this.receiverCounter = 0; - this.state = State.OPEN; - } - - public WorkerDataChannel(String channelName) { - this(); - this.chnlName = channelName; - } - - public void acquireChannelLock() { - this.channelLock.lock(); - } - - public void releaseChannelLock() { - this.channelLock.unlock(); - } - - public boolean isClosed() { - return this.state == State.CLOSED || this.state == State.AUTO_CLOSED; - } - - private void close(State state) { - try { - acquireChannelLock(); - this.state = state; - if (this.receiver != null) { - this.receiver.scheduler.unblockStrand(this.receiver); - this.receiver = null; - } - } finally { - releaseChannelLock(); - } - } - - public State getState() { - return this.state; - } - - public enum State { - OPEN, AUTO_CLOSED, CLOSED - } - - @SuppressWarnings("rawtypes") - public void sendData(Object data, Strand sender) { - if (isClosed()) { - callCount++; - return; - } - try { - acquireChannelLock(); - this.channel.add(new WorkerResult(data)); - this.senderCounter++; - if (this.receiver != null && receiver.scheduler != null) { - this.receiver.scheduler.unblockStrand(this.receiver); - this.receiver = null; - } - callCount++; - } finally { - releaseChannelLock(); - } - } - - public void autoClose() { - close(State.AUTO_CLOSED); - } - - public void close() { - close(State.CLOSED); - } - - /** - * Put data for sync send. - * - * @param data - data to be sent over the channel - * @param strand - sending strand, that will be paused - * @return error if receiver already in error state, else null - * @throws Throwable panic - */ - public Object syncSendData(Object data, Strand strand) throws Throwable { - try { - acquireChannelLock(); - if (!reschedule) { - // this is a new message, not a reschedule - this.channel.add(new WorkerResult(data, true)); - this.senderCounter++; - this.waitingSender = new WaitingSender(strand, -1); - - if (this.receiver != null) { - // multiple checks are added to make sure this is - this.receiver.scheduler.unblockStrand(this.receiver); - this.receiver = null; - } else if (this.panic != null) { - Throwable panic = this.panic; - this.panic = null; - throw panic; - } else if (this.error != null) { - ErrorValue ret = this.error; - this.waitingSender = null; - return ret; - } - - reschedule = true; - strand.setState(BLOCK_AND_YIELD); - return null; - } - - reschedule = false; - if (this.panic != null && this.channel.peek() != null) { - Throwable e = this.panic; - callCount++; - throw e; - } else if (this.error != null && this.channel.peek() != null) { - ErrorValue ret = this.error; - this.waitingSender = null; - callCount++; - return ret; - } - - // sync send done - callCount++; - return null; - } finally { - releaseChannelLock(); - } - } - - @SuppressWarnings("rawtypes") - public Object tryTakeData(Strand strand) throws Throwable { - return tryTakeData(strand, false); - } - - public Object tryTakeData(Strand strand, boolean isMultiple) throws Throwable { - try { - acquireChannelLock(); - if (isClosed()) { - return ErrorUtils.createNoMessageError(chnlName); - } - WorkerResult result = this.channel.peek(); - if (result != null) { - this.receiverCounter++; - this.channel.remove(); - - if (result.isSync) { - // sync sender will pick the this.error as result, which is null - if (this.waitingSender != null) { - Strand waiting = this.waitingSender.waitingStrand; - waiting.scheduler.unblockStrand(waiting); - this.waitingSender = null; - } - } else if (this.flushSender != null && this.flushSender.flushCount == this.receiverCounter) { - this.flushSender.waitingStrand.flushDetail.flushLock.lock(); - this.flushSender.waitingStrand.flushDetail.flushedCount++; - if (this.flushSender.waitingStrand.flushDetail.flushedCount == - this.flushSender.waitingStrand.flushDetail.flushChannels.length && - this.flushSender.waitingStrand.isBlocked()) { - //will continue if this is a sync wait, will try to flush again if blocked on flush - this.flushSender.waitingStrand.scheduler.unblockStrand(this.flushSender.waitingStrand); - - } - this.flushSender.waitingStrand.flushDetail.flushLock.unlock(); - this.flushSender = null; - } - callCount++; - return isMultiple ? result : result.value; - } else if (this.panic != null && this.senderCounter == this.receiverCounter + 1) { - this.receiverCounter++; - callCount++; - throw this.panic; - } else if (this.error != null && this.senderCounter == this.receiverCounter + 1) { - this.receiverCounter++; - callCount++; - return error; - } else { - this.receiver = strand; - if (!isMultiple) { - strand.setState(BLOCK_AND_YIELD); - } - return null; - } - } finally { - releaseChannelLock(); - } - } - - /** - * Set the state as error if the receiving worker is in error state. - * - * @param error the BError of the receiving worker - */ - public void setSendError(ErrorValue error) { - acquireChannelLock(); - this.error = error; - this.senderCounter++; - if (this.receiver != null) { - this.receiver.scheduler.unblockStrand(this.receiver); - this.receiver = null; - } - releaseChannelLock(); - } - - /** - * Method to set receiver errors. - * - * @param error to be set - */ - public void setReceiveError(ErrorValue error) { - acquireChannelLock(); - this.error = error; - this.receiverCounter++; - if (this.flushSender != null) { - this.flushSender.waitingStrand.flushDetail.flushLock.lock(); - Strand flushStrand = this.flushSender.waitingStrand; - if (flushStrand.isBlocked()) { - flushStrand.flushDetail.result = error; - flushStrand.scheduler.unblockStrand(flushStrand); - } - this.flushSender.waitingStrand.flushDetail.flushLock.unlock(); - this.flushSender = null; - } else if (this.waitingSender != null) { - Strand waiting = this.waitingSender.waitingStrand; - waiting.scheduler.unblockStrand(waiting); - this.waitingSender = null; - } - releaseChannelLock(); - } - - /** - * Method to flush channel. - * - * @param strand waiting for flush - * @return error or null - * @throws Throwable panic - */ - public ErrorValue flushChannel(Strand strand) throws Throwable { - acquireChannelLock(); - try { - if (this.panic != null) { - throw this.panic; - } else if (this.error != null) { - return this.error; - } else if (this.receiverCounter == this.senderCounter) { - strand.flushDetail.flushLock.lock(); - strand.flushDetail.flushedCount++; - strand.flushDetail.flushLock.unlock(); - return null; - } - this.flushSender = new WaitingSender(strand, this.senderCounter); - return null; - } finally { - releaseChannelLock(); - } - } - - public void removeFlushWait() { - acquireChannelLock(); - this.flushSender = null; - releaseChannelLock(); - } - - /** - * Method to set sender panics. - * - * @param panic to be set - */ - public void setSendPanic(Throwable panic) { - try { - acquireChannelLock(); - this.panic = panic; - this.senderCounter++; - if (this.receiver != null) { - this.receiver.scheduler.unblockStrand(this.receiver); - this.receiver = null; - } - } finally { - releaseChannelLock(); - } - } - - /** - * Method to set receiver panics. - * - * @param panic to be set - */ - public void setReceiverPanic(Throwable panic) { - acquireChannelLock(); - this.panic = panic; - this.receiverCounter++; - if (this.flushSender != null) { - this.flushSender.waitingStrand.flushDetail.flushLock.lock(); - Strand flushStrand = this.flushSender.waitingStrand; - this.flushSender.waitingStrand.flushDetail.panic = panic; - if (flushStrand.isBlocked()) { - flushStrand.scheduler.unblockStrand(flushStrand); - } - this.flushSender.waitingStrand.flushDetail.flushLock.unlock(); - this.flushSender = null; - } else if (this.waitingSender != null) { - Strand waiting = this.waitingSender.waitingStrand; - waiting.scheduler.unblockStrand(waiting); - this.waitingSender = null; - } - releaseChannelLock(); - } - - /** - * This represents a worker result value. This is done as a value to be used in the - * queues used for worker communication. In this way, the queue can distinguish the - * case of a value not there when the peek, by returning null, and then, if they - * return a WorkerResult, the value inside it can be either null or not to mention - * Ballerina null value and non-null value. - */ - public static class WorkerResult { - - public Object value; - public boolean isSync; - - public WorkerResult(Object value) { - this.value = value; - } - - public WorkerResult(Object value, boolean sync) { - this.value = value; - this.isSync = sync; - } - - } - - /** - * This represents the sender of the channel. If the sender is available, then we assume it is waiting for the - * data retrieval. Upon fetching data, it will be resumed if a sync send or will try to flush. - */ - public static class WaitingSender { - - public Strand waitingStrand; - public int flushCount; - - public WaitingSender(Strand strand, int flushCount) { - this.waitingStrand = strand; - this.flushCount = flushCount; - } - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerUtils.java index 44f5091d9431..8ce61df47bc1 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/scheduling/WorkerUtils.java @@ -1,46 +1,234 @@ /* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.internal.scheduling; - -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.internal.TypeChecker; -import io.ballerina.runtime.internal.values.ChannelDetails; + * Copyright (c) 2019, 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. + */ + + package io.ballerina.runtime.internal.scheduling; + +import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.creators.ValueCreator; +import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.RecordType; +import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; +import io.ballerina.runtime.api.utils.StringUtils; +import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.api.values.BMap; +import io.ballerina.runtime.api.values.BMapInitialValueEntry; +import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.internal.values.ErrorValue; -import io.ballerina.runtime.internal.values.RefValue; - -/** - * Worker related utility methods for jBallerina runtime. - * - * @since 0.995.0 - */ -public final class WorkerUtils { - - /** - * Notify worker data channels if this is a error return in a union type. - * @param value return value - * @param strand current strand - * @param channels worker date channels that current worker interacts - */ - public static void handleWorkerError(RefValue value, Strand strand, ChannelDetails[] channels) { - if (TypeChecker.checkIsType(value, PredefinedTypes.TYPE_ERROR)) { - strand.handleChannelError(channels, (ErrorValue) value); - } - } + +import java.util.Map; +import java.util.concurrent.CompletableFuture; + + + /** + * This represents a worker channel that is created for each worker to worker interaction. + * + * @since 2201.11.0 + */ + + public final class WorkerUtils { + + /* + * Used to codegen worker async send. + */ + @SuppressWarnings("unused") + public static void asyncSend(WorkerChannelMap workerChannelMap, String channelKey, Object result) { + WorkerChannel channel = workerChannelMap.get(channelKey); + channel.write(result); + } + + /* + * Used to codegen worker sync send. + */ + @SuppressWarnings("unused") + public static Object syncSend(Strand strand, WorkerChannelMap workerChannelMap, String channelKey, Object result) { + WorkerChannel channel = workerChannelMap.get(channelKey); + channel.write(result); + Object waitResult = AsyncUtils.handleWait(strand, channel.getReceiveFuture()); + if (waitResult instanceof BError error) { + return error; + } + return null; + + } + + public static Object flush(Strand strand, WorkerChannelMap workerChannelMap, String[] workerChannelKeys) { + CompletableFuture[] futures = new CompletableFuture[workerChannelKeys.length]; + WorkerChannel[] channels = new WorkerChannel[workerChannelKeys.length]; + for (int i = 0; i < workerChannelKeys.length; i++) { + WorkerChannel channel = workerChannelMap.get(workerChannelKeys[i]); + futures[i] = channel.getReceiveFuture(); + channels[i] = channel; + } + if (strand.isIsolated) { + AsyncUtils.waitForAllFutureResult(futures); + } else { + AsyncUtils.handleNonIsolatedStrand(strand, () -> { + AsyncUtils.waitForAllFutureResult(futures); + return null; + }); + } + + for (WorkerChannel channel : channels) { + Object result = channel.getReceiveFuture().resultNow(); + if (result instanceof ErrorValue errorValue) { + return errorValue; + } + } + return null; + } + + public static Object receive(Strand strand, WorkerChannelMap workerChannelMap, String channelKey) { + WorkerChannel channel = workerChannelMap.get(channelKey); + if (strand.isIsolated) { + return channel.read(); + } + return AsyncUtils.handleNonIsolatedStrand(strand, channel::read); + } + + /* + * Used to codegen worker alternative receive action. + */ + @SuppressWarnings("unused") + public static Object alternateReceive(Strand strand, WorkerChannelMap workerChannelMap, + String[] workerChannelKeys) { + WorkerChannel[] channels = new WorkerChannel[workerChannelKeys.length]; + int count = 0; + for (String workerChanelKey : workerChannelKeys) { + channels[count++] = workerChannelMap.get(workerChanelKey); + } + CompletableFuture[] futures = new CompletableFuture[channels.length]; + for (int i = 0; i < channels.length; i++) { + futures[i] = channels[i].getResultFuture(); + } + return getAlternativeReceiveResult(strand, futures, channels); + } + + /* + * Used to codegen worker multiple receive action. + */ + @SuppressWarnings({"unused", "unchecked"}) + public static BMap multipleReceive(Strand strand, WorkerChannelMap workerChannelMap, + Map channelFieldNameMap, Type targetType) { + WorkerChannel[] channels = new WorkerChannel[channelFieldNameMap.size()]; + int count = 0; + for (Map.Entry entry : channelFieldNameMap.entrySet()) { + channels[count++] = workerChannelMap.get(entry.getValue()); + } + CompletableFuture[] futures = new CompletableFuture[channels.length]; + for (int i = 0; i < channels.length; i++) { + futures[i] = channels[i].getResultFuture(); + } + if (strand.isIsolated) { + AsyncUtils.waitForAllFutureResult(futures); + return getMultipleReceiveResult(workerChannelMap, channelFieldNameMap, targetType, channels); + } + return (BMap) AsyncUtils.handleNonIsolatedStrand(strand, + () -> { + AsyncUtils.waitForAllFutureResult(futures); + return getMultipleReceiveResult(workerChannelMap, channelFieldNameMap, targetType, channels); + }); + } + + /* + * Used to codegen adding worker channels. + */ + @SuppressWarnings("unused") + public static void addWorkerChannels(WorkerChannelMap workerChannelMap, String[] workerChannelKeys) { + workerChannelMap.addChannelKeys(workerChannelKeys); + } + + /* + * Used to codegen handle worker return. + */ + @SuppressWarnings("unused") + public static void completedWorkerChannels(WorkerChannelMap workerChannelMap, + Object returnValue, String[] sendWorkerChannelKeys, + String[] receiveWorkerChannelKeys) { + if (sendWorkerChannelKeys == null && receiveWorkerChannelKeys == null) { + return; + } + + if (sendWorkerChannelKeys != null) { + for (String channelKey : sendWorkerChannelKeys) { + workerChannelMap.completeSendWorkerChannels(channelKey, returnValue); + } + } + if (receiveWorkerChannelKeys != null) { + for (String channelKey : receiveWorkerChannelKeys) { + workerChannelMap.completeReceiveWorkerChannels(channelKey, returnValue); + } + } + } + + /* + * Used to codegen handle worker panic. + */ + @SuppressWarnings("unused") + public static void completeWorkerChannelsWithPanic(WorkerChannelMap workerChannelMap, Throwable throwable, + String[] sendWorkerChannelKeys, + String[] receiveWorkerChannelKeys) { + if (sendWorkerChannelKeys == null && receiveWorkerChannelKeys == null) { + return; + } + BError error; + if (throwable instanceof BError bError) { + error = bError; + } else { + error = ErrorCreator.createError(throwable); + } + if (sendWorkerChannelKeys != null) { + for (String channelKey : sendWorkerChannelKeys) { + workerChannelMap.panicSendWorkerChannels(channelKey, error); + } + } + if (receiveWorkerChannelKeys != null) { + for (String channelKey : receiveWorkerChannelKeys) { + workerChannelMap.panicReceiveWorkerChannels(channelKey, error); + } + } + } + + private static Object getAlternativeReceiveResult(Strand strand, CompletableFuture[] completableFutures, + WorkerChannel[] channels) { + Object result = AsyncUtils.handleWaitAny(strand, completableFutures); + for (WorkerChannel channel : channels) { + channel.read(); + } + return result; + } + + private static BMap getMultipleReceiveResult(WorkerChannelMap workerChannelMap, + Map channelFieldNameMap, + Type targetType, WorkerChannel[] channels) { + int count = 0; + BMapInitialValueEntry[] initialValueEntries = new BMapInitialValueEntry[channels.length]; + for (Map.Entry entry : channelFieldNameMap.entrySet()) { + WorkerChannel channel = workerChannelMap.get(entry.getValue()); + initialValueEntries[count++] = ValueCreator.createKeyFieldEntry(StringUtils.fromString(entry.getKey()), + channel.read()); + } + if (targetType.getTag() == TypeTags.RECORD_TYPE_TAG) { + return ValueCreator.createMapValue((RecordType) targetType, initialValueEntries); + } + return ValueCreator.createMapValue((MapType) targetType, initialValueEntries); + } private WorkerUtils() {} } + diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/troubleshoot/StrandDump.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/troubleshoot/StrandDump.java index 10b83c05004d..08dc8d7e545a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/troubleshoot/StrandDump.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/troubleshoot/StrandDump.java @@ -18,17 +18,22 @@ package io.ballerina.runtime.internal.troubleshoot; -import io.ballerina.runtime.internal.scheduling.Scheduler; -import io.ballerina.runtime.internal.scheduling.Strand; +import com.sun.management.HotSpotDiagnosticMXBean; +import java.io.File; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.nio.file.Files; +import java.nio.file.Paths; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.HashSet; +import java.util.Set; +import java.util.regex.Pattern; + +import javax.management.MBeanServer; -import static io.ballerina.runtime.internal.scheduling.ItemGroup.getCreatedStrandGroupCount; /** * Used to get the status of current Ballerina strands. @@ -36,67 +41,103 @@ * @since 2201.2.0 */ public final class StrandDump { + private static final String HOT_SPOT_BEAN_NAME = "com.sun.management:type=HotSpotDiagnostic"; + private static final String WORKING_DIR = System.getProperty("user.dir") + "/"; + private static final String FILENAME = "threadDump" + LocalDateTime.now(); + private static final String VIRTUAL_THREAD_IDENTIFIER = "virtual"; + private static final String ISOLATED_WORKER_IDENTIFIER = "io.ballerina.runtime.internal.scheduling." + + "Scheduler.lambda$startIsolatedWorker"; + private static final String NON_ISOLATED_WORKER_IDENTIFIER = "io.ballerina.runtime.internal.scheduling." + + "Scheduler.lambda$startNonIsolatedWorker"; + private static final String JAVA_TRACE_PATTERN = "java\\.|\\.java(?::\\d+)?"; // .java, java., .java:(any number) + private static final String BAL_TRACE_PATTERN = "\\.bal:\\d+"; // .bal:(any number) + private static volatile HotSpotDiagnosticMXBean hotSpotDiagnosticMXBean; public static String getStrandDump() { - Map availableStrands = Scheduler.getCurrentStrands(); - int createdStrandGroupCount = getCreatedStrandGroupCount(); - int createdStrandCount = Strand.getCreatedStrandCount(); - int availableStrandCount = availableStrands.size(); - Map> availableStrandGroups = new HashMap<>(); - populateAvailableStrandGroups(availableStrands, availableStrandGroups); - - String strandDumpOutput = generateOutput(availableStrandGroups, availableStrandCount, createdStrandGroupCount, - createdStrandCount); - cleanUp(availableStrands, availableStrandGroups); - return strandDumpOutput; + String dump; + try { + getStrandDump(WORKING_DIR + FILENAME); + dump = new String(Files.readAllBytes(Paths.get(FILENAME))); + File fileObj = new File(FILENAME); + fileObj.delete(); + } catch (Exception e) { + return "Error occurred during strand dump generation"; + } + return generateOutput(dump); } - private static String generateOutput(Map> availableStrandGroups, int availableStrandCount, - int createdStrandGroupCount, int createdStrandCount) { + private static String generateOutput(String dump) { + String[] dumpItems = dump.split("\\n\\n"); + int id = 0; + Set isolatedWorkerList = new HashSet<>(); + Set nonIsolatedWorkerList = new HashSet<>(); + ArrayList> balTraces = new ArrayList<>(); + Pattern javaPattern = Pattern.compile(JAVA_TRACE_PATTERN); + Pattern balPattern = Pattern.compile(BAL_TRACE_PATTERN); + for (String item : dumpItems) { + String[] lines = item.split("\\n"); + String[] subitems = lines[0].split("\" "); + ArrayList balTraceItems = new ArrayList<>(); + boolean balStrand = false; + if (subitems.length > 1 && subitems[1].equals(VIRTUAL_THREAD_IDENTIFIER)) { + balTraceItems.add("\tStrand " + lines[0].replace(VIRTUAL_THREAD_IDENTIFIER, ":") + "\n\t\tat"); + String prefix = " "; + for (String line : lines) { + if (!javaPattern.matcher(line).find() && !line.contains("\" " + VIRTUAL_THREAD_IDENTIFIER)) { + balTraceItems.add(prefix + line + "\n"); + prefix = "\t\t "; + if (balPattern.matcher(line).find()) { + balStrand = true; + } + } else { + if (line.contains(ISOLATED_WORKER_IDENTIFIER)) { + isolatedWorkerList.add(id); + } else if (line.contains(NON_ISOLATED_WORKER_IDENTIFIER)) { + nonIsolatedWorkerList.add(id); + } + } + } + if (balStrand) { + balTraces.add(balTraceItems); + } else { + isolatedWorkerList.remove(id); + nonIsolatedWorkerList.remove(id); + } + id++; + } + } StringBuilder outputStr = new StringBuilder("Ballerina Strand Dump ["); DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"); LocalDateTime localDateTime = LocalDateTime.now(); outputStr.append(dateTimeFormatter.format(localDateTime)); - outputStr.append("]\n===========================================\n\n"); - outputStr.append("Total strand group count \t:\t").append(createdStrandGroupCount).append("\n"); - outputStr.append("Total strand count \t:\t").append(createdStrandCount).append("\n"); - outputStr.append("Active strand group count\t:\t").append(availableStrandGroups.size()).append("\n"); - outputStr.append("Active strand count \t:\t").append(availableStrandCount).append("\n\n"); - availableStrandGroups.forEach((strandGroupId, strandList) -> { - outputStr.append("group ").append(strandGroupId).append(" [").append(strandList.get(0)).append("]: [") - .append(strandList.size() - 1).append("]\n"); - strandList.subList(1, strandList.size()).forEach(outputStr::append); - }); - outputStr.append("===========================================\n"); + outputStr.append("]\n===============================================================\n\n"); + outputStr.append("Total Strand count \t\t\t:\t").append(balTraces.size()).append("\n\n"); + outputStr.append("Total Isolated Worker count \t\t:\t").append(isolatedWorkerList.size()).append("\n\n"); + outputStr.append("Total Non Isolated Worker count \t\t:\t").append(nonIsolatedWorkerList.size()). + append("\n\n"); + outputStr.append("================================================================\n"); + outputStr.append("\nIsolated Workers:\n\n"); + for (int strandId: isolatedWorkerList) { + balTraces.get(strandId).forEach(outputStr::append); + outputStr.append("\n"); + } + outputStr.append("Non Isolated Workers:\n\n"); + for (int strandId: nonIsolatedWorkerList) { + balTraces.get(strandId).forEach(outputStr::append); + outputStr.append("\n"); + } return outputStr.toString(); } - private static void populateAvailableStrandGroups(Map availableStrands, - Map> availableStrandGroups) { - for (Strand strand : availableStrands.values()) { - int strandGroupId = strand.getStrandGroup().getId(); - String strandState = strand.dumpState(); - availableStrandGroups.computeIfAbsent(strandGroupId, k -> { - ArrayList strandDataList = new ArrayList<>(); - strandDataList.add(getStrandGroupStatus(strand.getStrandGroup().isScheduled())); - return strandDataList; - }).add(strandState); + private static void getStrandDump(String fileName) throws IOException { + if (hotSpotDiagnosticMXBean == null) { + hotSpotDiagnosticMXBean = getHotSpotDiagnosticMXBean(); } + hotSpotDiagnosticMXBean.dumpThreads(fileName, HotSpotDiagnosticMXBean.ThreadDumpFormat.TEXT_PLAIN); } - private static void cleanUp(Map availableStrands, - Map> availableStrandGroups) { - availableStrands.clear(); - availableStrandGroups.clear(); + private static HotSpotDiagnosticMXBean getHotSpotDiagnosticMXBean() throws IOException { + MBeanServer mBeanServer = ManagementFactory.getPlatformMBeanServer(); + return ManagementFactory.newPlatformMXBeanProxy(mBeanServer, HOT_SPOT_BEAN_NAME, HotSpotDiagnosticMXBean.class); } - - private static String getStrandGroupStatus(boolean isStrandGroupScheduled) { - if (isStrandGroupScheduled) { - return "RUNNABLE"; - } else { - return "QUEUED"; - } - } - - private StrandDump() {} } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnyType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnyType.java index 6c9dfbbd046f..feb9d147bf7c 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnyType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnyType.java @@ -18,13 +18,13 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.AnyType; import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.RefValue; import java.util.Optional; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnydataType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnydataType.java index 7d006df8e080..0bc38e99f4fb 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnydataType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BAnydataType.java @@ -18,12 +18,12 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.AnydataType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.RefValue; /** diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java index d73fb58f5a82..a399bcddf71a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BArrayType.java @@ -17,11 +17,11 @@ */ package io.ballerina.runtime.internal.types; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.values.ArrayValue; import io.ballerina.runtime.internal.values.ArrayValueImpl; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BBooleanType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BBooleanType.java index 28031b69e41e..6fd5b0afb07d 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BBooleanType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BBooleanType.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.BooleanType; +import io.ballerina.runtime.api.types.TypeTags; /** * {@code BBooleanType} represents boolean type in Ballerina. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BByteType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BByteType.java index 8e5cda22dfbc..97aca3f82894 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BByteType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BByteType.java @@ -19,8 +19,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.ByteType; +import io.ballerina.runtime.api.types.TypeTags; /** * {@code BByteType} represents byte type in Ballerina. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BDecimalType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BDecimalType.java index a5af3b4d220a..d1bf252d0f0b 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BDecimalType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BDecimalType.java @@ -19,8 +19,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.DecimalType; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.DecimalValue; import java.math.BigDecimal; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BErrorType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BErrorType.java index 59cf32500a3d..8c1002def149 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BErrorType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BErrorType.java @@ -19,11 +19,11 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.ErrorType; import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.ErrorValue; import java.util.Optional; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFiniteType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFiniteType.java index 3ca2ae443844..de03a587aa95 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFiniteType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFiniteType.java @@ -18,9 +18,9 @@ package io.ballerina.runtime.internal.types; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.FiniteType; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.values.RefValue; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFloatType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFloatType.java index 2ef0d084d3e9..50450df52beb 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFloatType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFloatType.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.FloatType; +import io.ballerina.runtime.api.types.TypeTags; /** * {@code BFloatType} represents a integer which is a 32-bit floating-point number according to the diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFunctionType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFunctionType.java index 9916e0ba4da4..dbef43081922 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFunctionType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFunctionType.java @@ -19,12 +19,12 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.FunctionType; import io.ballerina.runtime.api.types.Parameter; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import java.util.Arrays; @@ -71,8 +71,6 @@ public BFunctionType(Module pkg, Parameter[] parameters, Type restType, Type ret this.flags = flags; } - @Deprecated - @Override public Type[] getParameterTypes() { Type[] types = new Type[parameters.length]; for (int i = 0; i < parameters.length; i++) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFutureType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFutureType.java index df747fc1865c..3eb490648562 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFutureType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BFutureType.java @@ -18,10 +18,10 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.types.FutureType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.TypeChecker; /** diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BHandleType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BHandleType.java index 89b5482936bf..ed1065c1df9e 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BHandleType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BHandleType.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.HandleType; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.RefValue; /** diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIntegerType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIntegerType.java index d8e290013da6..d8ec02af768b 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIntegerType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIntegerType.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.IntegerType; +import io.ballerina.runtime.api.types.TypeTags; /** * {@code BIntegerType} represents an integer which is a 32-bit signed number. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIntersectionType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIntersectionType.java index c2112f4a4578..f9cf98a079df 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIntersectionType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIntersectionType.java @@ -18,12 +18,12 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.IntersectableReferenceType; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import java.util.ArrayList; import java.util.Arrays; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIteratorType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIteratorType.java index 13d870f510b6..5f4a3dde387a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIteratorType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BIteratorType.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.IteratorType; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.IteratorValue; /** diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BJsonType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BJsonType.java index 382a5d4b66f8..f8ea801b62ce 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BJsonType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BJsonType.java @@ -18,12 +18,12 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.JsonType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.MapValueImpl; /** diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BMapType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BMapType.java index c69aaa56c144..fa47a26e06fc 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BMapType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BMapType.java @@ -18,12 +18,12 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.internal.values.MapValueImpl; import io.ballerina.runtime.internal.values.ReadOnlyUtils; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNetworkObjectType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNetworkObjectType.java index a0666927a833..c289e0bffd88 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNetworkObjectType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNetworkObjectType.java @@ -52,11 +52,10 @@ public void setResourceMethods(ResourceMethodType[] resourceMethods) { public RemoteMethodType[] getRemoteMethods() { if (remoteMethods == null) { RemoteMethodType[] funcs = getRemoteMethods(getMethods()); - synchronized (this) { - if (remoteMethods == null) { - remoteMethods = funcs; - } + if (remoteMethods == null) { + remoteMethods = funcs; } + } return remoteMethods; } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNeverType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNeverType.java index 9f0d4da9901b..f57eedcc6dcf 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNeverType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNeverType.java @@ -18,9 +18,9 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.types.NeverType; +import io.ballerina.runtime.api.types.TypeTags; /** * {@code BNeverType} represents the type of a {@code Never}. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNullType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNullType.java index 702133228119..9070784980fc 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNullType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BNullType.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.NullType; +import io.ballerina.runtime.api.types.TypeTags; /** * {@code BNullType} represents the type of a {@code NullLiteral}. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BObjectType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BObjectType.java index a4e609158587..05cd15e570fc 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BObjectType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BObjectType.java @@ -19,7 +19,6 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.Field; @@ -29,11 +28,12 @@ import io.ballerina.runtime.api.types.ResourceMethodType; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeIdSet; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BObject; -import io.ballerina.runtime.internal.ValueUtils; import io.ballerina.runtime.internal.scheduling.Scheduler; import io.ballerina.runtime.internal.scheduling.Strand; +import io.ballerina.runtime.internal.utils.ValueUtils; import java.lang.reflect.Array; import java.util.ArrayList; @@ -42,7 +42,7 @@ import java.util.Optional; import java.util.StringJoiner; -import static io.ballerina.runtime.api.TypeTags.SERVICE_TAG; +import static io.ballerina.runtime.api.types.TypeTags.SERVICE_TAG; /** * {@code BObjectType} represents a user defined object type in Ballerina. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BParameterizedType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BParameterizedType.java index ca8a47508c11..9ab78cf7271c 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BParameterizedType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BParameterizedType.java @@ -18,9 +18,9 @@ package io.ballerina.runtime.internal.types; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.ParameterizedType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; /** * {@code ParameterizedType} represents the parameterized type in dependently-typed functions. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BReadonlyType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BReadonlyType.java index 8fb84c638a1e..c945f4941839 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BReadonlyType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BReadonlyType.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.ReadonlyType; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.RefValue; /** diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BRecordType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BRecordType.java index 27b9286de00e..2af42d5596d2 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BRecordType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BRecordType.java @@ -20,7 +20,6 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.flags.TypeFlags; @@ -28,18 +27,17 @@ import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BFunctionPointer; import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BString; -import io.ballerina.runtime.internal.ValueUtils; import io.ballerina.runtime.internal.scheduling.Scheduler; import io.ballerina.runtime.internal.values.MapValue; import io.ballerina.runtime.internal.values.MapValueImpl; import io.ballerina.runtime.internal.values.ReadOnlyUtils; import java.util.HashMap; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; @@ -58,7 +56,7 @@ public class BRecordType extends BStructureType implements RecordType { private IntersectionType immutableType; private IntersectionType intersectionType = null; - private final Map> defaultValues = new LinkedHashMap<>(); + private final Map defaultValues = new LinkedHashMap<>(); /** * Create a {@code BRecordType} which represents the user defined record type. @@ -129,13 +127,12 @@ public V getZeroValue() { return (V) ValueCreator.createReadonlyRecordValue(this.pkg, typeName, new HashMap<>()); } BMap recordValue = ValueCreator.createRecordValue(this.pkg, typeName); - ValueUtils.populateDefaultValues(recordValue, this, new HashSet<>()); if (defaultValues.isEmpty()) { return (V) recordValue; } - for (Map.Entry> field : defaultValues.entrySet()) { + for (Map.Entry field : defaultValues.entrySet()) { recordValue.put(StringUtils.fromString(field.getKey()), - field.getValue().call(new Object[] {Scheduler.getStrand()})); + field.getValue().call(Scheduler.getStrand().scheduler.runtime)); } return (V) recordValue; } @@ -213,11 +210,11 @@ public int getTypeFlags() { return typeFlags; } - public void setDefaultValue(String fieldName, BFunctionPointer defaultValue) { + public void setDefaultValue(String fieldName, BFunctionPointer defaultValue) { defaultValues.put(fieldName, defaultValue); } - public Map> getDefaultValues() { + public Map getDefaultValues() { return defaultValues; } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BServiceType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BServiceType.java index 2a0a074eee8a..2834b873c348 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BServiceType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BServiceType.java @@ -17,8 +17,8 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.types.ServiceType; +import io.ballerina.runtime.api.types.TypeTags; /** * {@code BServiceType} represents a service object in Ballerina. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BStreamType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BStreamType.java index 049ba7f16452..494dc1d54642 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BStreamType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BStreamType.java @@ -19,11 +19,11 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.StreamType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.StreamValue; import java.util.Objects; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BStringType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BStringType.java index 34be4d3d188f..0211eef19b38 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BStringType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BStringType.java @@ -18,9 +18,9 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.RuntimeConstants; import io.ballerina.runtime.api.types.StringType; +import io.ballerina.runtime.api.types.TypeTags; /** * {@code BStringType} represents a String type in ballerina. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTableType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTableType.java index 1aae344cfd3e..14c7d2b803e2 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTableType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTableType.java @@ -17,11 +17,11 @@ */ package io.ballerina.runtime.internal.types; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.TableType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.ReadOnlyUtils; import io.ballerina.runtime.internal.values.TableValue; import io.ballerina.runtime.internal.values.TableValueImpl; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTupleType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTupleType.java index 21fb42a59f92..e4758fd5e8b8 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTupleType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTupleType.java @@ -19,11 +19,11 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.TupleType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.values.ReadOnlyUtils; import io.ballerina.runtime.internal.values.TupleValueImpl; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BType.java index 5d2aba9ddc8f..d6cd9c996ba3 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BType.java @@ -18,10 +18,10 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.internal.TypeChecker; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java index 4d228b2d78f6..cc2e78d6a319 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypeReferenceType.java @@ -20,11 +20,11 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.IntersectableReferenceType; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import java.util.Objects; import java.util.Optional; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypedescType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypedescType.java index a6988bc263cb..411d75cf9662 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypedescType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BTypedescType.java @@ -19,10 +19,10 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.TypedescType; import io.ballerina.runtime.internal.values.TypedescValue; import io.ballerina.runtime.internal.values.TypedescValueImpl; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BUnionType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BUnionType.java index 3f957eac231a..4fe1f164c653 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BUnionType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BUnionType.java @@ -18,12 +18,12 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.flags.TypeFlags; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.SelectivelyImmutableReferenceType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.internal.TypeChecker; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlAttributesType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlAttributesType.java index d9edf897051a..629be337797f 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlAttributesType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlAttributesType.java @@ -18,7 +18,7 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.XmlAttributesType; /** diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlType.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlType.java index c48c9d085594..05e1cde6985c 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlType.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/types/BXmlType.java @@ -18,10 +18,10 @@ package io.ballerina.runtime.internal.types; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.XmlType; import io.ballerina.runtime.internal.values.ReadOnlyUtils; import io.ballerina.runtime.internal.values.XmlSequence; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/AnnotationUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/AnnotationUtils.java similarity index 82% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/AnnotationUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/AnnotationUtils.java index 78e81eb271b1..00b7d37b44f4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/AnnotationUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/AnnotationUtils.java @@ -15,16 +15,17 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.MethodType; import io.ballerina.runtime.api.types.ResourceMethodType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.internal.scheduling.Scheduler; import io.ballerina.runtime.internal.scheduling.Strand; import io.ballerina.runtime.internal.types.BAnnotatableType; import io.ballerina.runtime.internal.types.BMethodType; @@ -101,7 +102,7 @@ public static void processObjectCtorAnnotations(BObjectType bType, if (globalAnnotMap.containsKey(annotationKey)) { Object annot = globalAnnotMap.get(annotationKey); // If annotations are already set via desugard service-decl, skip. - Object annotValue = ((FPValue) annot).call(new Object[]{strand}); + Object annotValue = ((FPValue) annot).call(Scheduler.getStrand().scheduler.runtime); bType.setAnnotations((MapValue) annotValue); } for (MethodType attachedFunction : bType.getMethods()) { @@ -120,9 +121,8 @@ private static void processObjectMethodLambdaAnnotation(MapValue) ((FPValue) globalAnnotMap.get(annotationKey)) - .call(new Object[]{strand})); + .setAnnotations((MapValue) ((FPValue) globalAnnotMap.get(annotationKey)) + .call(Scheduler.getStrand().scheduler.runtime)); } } @@ -133,36 +133,12 @@ private static void processObjectMethodLambdaAnnotation(MapValue fpValue, - MapValue globalAnnotMap, String name) { + public static void processFPValueAnnotations(FPValue fpValue, MapValue globalAnnotMap, + String name) { BAnnotatableType type = (BAnnotatableType) fpValue.getType(); BString nameKey = StringUtils.fromString(name); if (globalAnnotMap.containsKey(nameKey)) { type.setAnnotations((MapValue) globalAnnotMap.get(nameKey)); } } - - /** - * Returns true if given {@link FPValue} is annotated to be run concurrently. - * - * @param fpValue function pointer to be invoked - * @return true if should run concurrently - */ - public static boolean isConcurrent(FPValue fpValue) { - return fpValue.isConcurrent; - } - - /** - * Returns strand name of given {@link FPValue}. - * - * @param fpValue function pointer to be invoked - * @param defaultName default strand name - * @return annotated strand name - */ - public static String getStrandName(FPValue fpValue, String defaultName) { - if (fpValue.strandName != null) { - return fpValue.strandName; - } - return defaultName; - } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalStringUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/BalStringUtils.java similarity index 96% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalStringUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/BalStringUtils.java index fb6d5c4540c6..6a6e087d9c14 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BalStringUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/BalStringUtils.java @@ -16,17 +16,19 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.MapType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.internal.TypeChecker; +import io.ballerina.runtime.internal.TypeConverter; import io.ballerina.runtime.internal.types.BArrayType; import io.ballerina.runtime.internal.types.BMapType; import io.ballerina.runtime.internal.types.BTableType; @@ -35,15 +37,16 @@ import io.ballerina.runtime.internal.values.ArrayValueImpl; import io.ballerina.runtime.internal.values.MapValueImpl; import io.ballerina.runtime.internal.values.TableValueImpl; +import io.ballerina.runtime.internal.xml.XmlFactory; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANYDATA; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ANYDATA; import static io.ballerina.runtime.api.utils.StringUtils.fromString; -import static io.ballerina.runtime.internal.util.StringUtils.parseExpressionStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.parseExpressionStringVal; /** * Common utility methods used for Ballerina expression syntax manipulation. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/CloneUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/CloneUtils.java similarity index 97% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/CloneUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/CloneUtils.java index 3a41e8eefb85..9f9b718da505 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/CloneUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/CloneUtils.java @@ -16,7 +16,7 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BError; @@ -87,7 +87,7 @@ public static BError createConversionError(Object value, Type targetType, List errors, int maxErrorCount) { + public static String getErrorMessage(List errors, int maxErrorCount) { StringBuilder errorMsg = new StringBuilder(); int totalErrorCount = errors.size(); int tabs = 0; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/CompatibilityChecker.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/CompatibilityChecker.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/CompatibilityChecker.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/CompatibilityChecker.java index f0f1507122bc..e8efa2609140 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/CompatibilityChecker.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/CompatibilityChecker.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal.util; +package io.ballerina.runtime.internal.utils; import java.io.PrintStream; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/CycleUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/CycleUtils.java similarity index 97% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/CycleUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/CycleUtils.java index 545f89c4efbf..0977f7c8d0aa 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/CycleUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/CycleUtils.java @@ -15,7 +15,7 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; import io.ballerina.runtime.api.values.BLink; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/DefaultLogFormatter.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/DefaultLogFormatter.java similarity index 97% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/DefaultLogFormatter.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/DefaultLogFormatter.java index a2c91cccf61b..c7a8adfa48cd 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/DefaultLogFormatter.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/DefaultLogFormatter.java @@ -16,7 +16,7 @@ * under the License. */ -package io.ballerina.runtime.internal.util; +package io.ballerina.runtime.internal.utils; import java.io.PrintWriter; import java.io.StringWriter; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ErrorUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ErrorUtils.java similarity index 88% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ErrorUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ErrorUtils.java index 447cd9772637..52fab8c498d0 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ErrorUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ErrorUtils.java @@ -15,14 +15,16 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.errors.ErrorReasons; @@ -189,10 +191,34 @@ public static BError createInvalidFractionDigitsError() { ErrorHelper.getErrorDetails(ErrorCodes.INVALID_FRACTION_DIGITS)); } - public static BError createNoMessageError(String chnlName) { - String[] splitWorkers = chnlName.split(":")[0].split("->"); + public static BError createNoMessageError(String channelKey) { + String[] splitWorkers = channelKey.split(":")[0].split("->"); return createError(BALLERINA_LANG_ERROR_PKG_ID, "NoMessage", ErrorReasons.NO_MESSAGE_ERROR, null, ErrorHelper.getErrorDetails(ErrorCodes.NO_MESSAGE_ERROR, StringUtils.fromString(splitWorkers[0]), StringUtils.fromString(splitWorkers[1]))); } + + public static BError createWaitOnSameFutureError() { + return ErrorCreator.createError(StringUtils.fromString("multiple waits on the same future is not allowed")); + } + + public static BError createErrorFromThrowable(Throwable t) { + if (t instanceof BError error) { + return error; + } + if (t.getCause() instanceof BError error) { + return error; + } + BError error; + if (t instanceof StackOverflowError) { + error = ErrorCreator.createError(ErrorReasons.STACK_OVERFLOW_ERROR); + } else if (t instanceof OutOfMemoryError) { + error = ErrorCreator.createError(ErrorReasons.JAVA_OUT_OF_MEMORY_ERROR, + StringUtils.fromString(t.getMessage())); + } else { + error = ErrorCreator.createError(t); + } + error.setStackTrace(t.getStackTrace()); + return error; + } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/FloatUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/FloatUtils.java similarity index 96% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/FloatUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/FloatUtils.java index ac1af0ccb240..3816425567d4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/FloatUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/FloatUtils.java @@ -16,7 +16,7 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BString; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/IteratorUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/IteratorUtils.java similarity index 97% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/IteratorUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/IteratorUtils.java index 867b0a355c9d..81e84a8ee550 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/IteratorUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/IteratorUtils.java @@ -16,7 +16,7 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.flags.SymbolFlags; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/LargeStructureUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/LargeStructureUtils.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/LargeStructureUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/LargeStructureUtils.java index 252b866237a0..06507e72c758 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/LargeStructureUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/LargeStructureUtils.java @@ -16,7 +16,7 @@ * under the License. */ -package io.ballerina.runtime.internal.util; +package io.ballerina.runtime.internal.utils; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BMap; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/MapUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/MapUtils.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/MapUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/MapUtils.java index 2b062de290e8..2ae27c4cd2cb 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/MapUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/MapUtils.java @@ -15,16 +15,17 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.Field; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BString; +import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.types.BMapType; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/MathUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/MathUtils.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/MathUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/MathUtils.java index 1c0d1b21b77d..5d551d8e777c 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/MathUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/MathUtils.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.utils.StringUtils; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/RuntimeUtils.java similarity index 66% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/RuntimeUtils.java index a89fae22b26b..2b5a1d09c9ab 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/RuntimeUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/RuntimeUtils.java @@ -16,24 +16,18 @@ * under the License. */ -package io.ballerina.runtime.internal.util; +package io.ballerina.runtime.internal.utils; import io.ballerina.identifier.Utils; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; -import io.ballerina.runtime.api.types.Type; -import io.ballerina.runtime.api.utils.StringUtils; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BValue; -import io.ballerina.runtime.internal.ErrorUtils; -import io.ballerina.runtime.internal.TypeConverter; import io.ballerina.runtime.internal.diagnostics.RuntimeDiagnosticLog; -import io.ballerina.runtime.internal.types.BArrayType; -import io.ballerina.runtime.internal.values.ArrayValue; -import io.ballerina.runtime.internal.values.ArrayValueImpl; +import io.ballerina.runtime.internal.scheduling.AsyncUtils; import io.ballerina.runtime.internal.values.ErrorValue; +import io.ballerina.runtime.internal.values.FutureValue; import io.ballerina.runtime.internal.values.MapValueImpl; import java.io.PrintStream; @@ -59,50 +53,9 @@ public final class RuntimeUtils { private static final String CRASH_LOGGER = "b7a.log.crash"; private static final PrintStream errStream = System.err; public static final String USER_DIR = System.getProperty("user.dir"); - public static final String TEMP_DIR = System.getProperty("java.io.tmpdir"); private static final Logger crashLogger = Logger.getLogger(CRASH_LOGGER); private static ConsoleHandler handler; - /** - * Used to handle rest args passed in to the main method. - * - * @param args args from main method - * @param index starting index of var args - * @param type array type - * @return ArrayValue - */ - public static ArrayValue createVarArgsArray(String[] args, int index, BArrayType type) { - - ArrayValue array = new ArrayValueImpl(type); - for (int i = index; i < args.length; i++) { - addToArray(type.getElementType(), args[i], array); - } - return array; - } - - public static void addToArray(Type type, String value, ArrayValue array) { - // TODO: need to add parsing logic for ref values for both var args and other args as well. - switch (type.getTag()) { - case TypeTags.STRING_TAG: - array.add(array.size(), StringUtils.fromString(value)); - break; - case TypeTags.INT_TAG: - array.add(array.size(), (long) TypeConverter.convertValues(type, value)); - break; - case TypeTags.FLOAT_TAG: - array.add(array.size(), (double) TypeConverter.convertValues(type, value)); - break; - case TypeTags.BOOLEAN_TAG: - array.add(array.size(), (boolean) TypeConverter.convertValues(type, value)); - break; - case TypeTags.BYTE_TAG: - array.add(array.size(), (int) TypeConverter.convertValues(type, value)); - break; - default: - array.append(value); - } - } - /** * Check a given int value is within ballerina byte value range. * @@ -110,60 +63,70 @@ public static void addToArray(Type type, String value, ArrayValue array) { * @return true if within byte value range */ public static boolean isByteLiteral(int intValue) { - return (intValue >= BBYTE_MIN_VALUE && intValue <= BBYTE_MAX_VALUE); } - /** - * Keep a function parameter info, required for argument parsing. + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle future value in main method. */ - public static class ParamInfo { - String name; - boolean hasDefaultable; - Type type; - - public ParamInfo(boolean hasDefaultable, String name, Type type) { - this.name = name; - this.hasDefaultable = hasDefaultable; - this.type = type; + public static void handleFutureAndExit(FutureValue future) { + try { + Object result = AsyncUtils.getFutureResult(future.completableFuture); + if (result instanceof ErrorValue error) { + errStream.println("error: " + error.getPrintableError()); + Runtime.getRuntime().exit(1); + } + } catch (ErrorValue error) { + printToConsole(error); + Runtime.getRuntime().exit(1); } } - public static void handleBErrorAndExit(Throwable throwable) { - if (throwable instanceof ErrorValue errorValue) { - printToConsole(errorValue); - } - Runtime.getRuntime().exit(1); - } - public static void handleAllRuntimeErrorsAndExit(Throwable throwable) { - handleAllRuntimeErrors(throwable); - Runtime.getRuntime().exit(1); + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle future value in tests. + */ + public static boolean handleFutureAndReturnIsPanic(FutureValue future) { + try { + handleErrorResult(AsyncUtils.getFutureResult(future.completableFuture)); + } catch (ErrorValue error) { + printToConsole(error); + return true; + } + return false; } - public static void handleAllRuntimeErrors(Throwable throwable) { - if (throwable instanceof ErrorValue errorValue) { - printToConsole(errorValue); - } else { - logBadSad(throwable); + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle future value in init and stop methods. + */ + public static void handleFuture(FutureValue future) { + try { + handleErrorResult(AsyncUtils.getFutureResult(future.completableFuture)); + } catch (ErrorValue error) { + printToConsole(error); } } - private static void printToConsole(ErrorValue throwable) { - errStream.println("error: " + throwable.getPrintableStackTrace()); + @SuppressWarnings("unused") + /* + * Used for codegen. This will handle throwable in main method. + */ + public static void handleThrowable(Throwable throwable) { + logBadSad(throwable); + Runtime.getRuntime().exit(1); } - public static void handleRuntimeReturnValues(Object returnValue) { - if (returnValue instanceof ErrorValue errorValue) { + public static void handleErrorResult(Object result) { + if (result instanceof ErrorValue errorValue) { errStream.println("error: " + errorValue.getPrintableError()); - Runtime.getRuntime().exit(1); } } - public static void handleRuntimeErrorReturns(Object returnValue) { - if (returnValue instanceof ErrorValue errorValue) { - errStream.println("error: " + errorValue.getPrintableError()); - } + private static void printToConsole(ErrorValue throwable) { + errStream.println("error: " + throwable.getPrintableStackTrace()); } public static void handleDiagnosticErrors(RuntimeDiagnosticLog diagnosticLog) { @@ -173,19 +136,6 @@ public static void handleDiagnosticErrors(RuntimeDiagnosticLog diagnosticLog) { } } - public static void handleInvalidOption(String arg) { - handleUsageError("value for option '--' () should be in KEY=VALUE format but was " + arg); - } - - public static void handleInvalidConfig() { - handleUsageError("value for option 'config' is missing"); - } - - public static void handleUsageError(String errorMsg) { - errStream.println("ballerina: " + errorMsg); - Runtime.getRuntime().exit(1); - } - public static void logBadSad(Throwable throwable) { // These errors are unhandled errors in JVM, hence logging them to bre log. errStream.println(INTERNAL_ERROR_MESSAGE); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/StringUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/StringUtils.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/StringUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/StringUtils.java index fa44bae7cf50..94dba9a34a70 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/util/StringUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/StringUtils.java @@ -16,21 +16,19 @@ * under the License. */ -package io.ballerina.runtime.internal.util; +package io.ballerina.runtime.internal.utils; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.MethodType; import io.ballerina.runtime.api.types.ObjectType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BRefValue; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BValue; -import io.ballerina.runtime.internal.BalStringUtils; -import io.ballerina.runtime.internal.CycleUtils; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.regexp.RegExpFactory; import io.ballerina.runtime.internal.scheduling.Scheduler; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TableUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/TableUtils.java similarity index 95% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TableUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/TableUtils.java index cd4bade3c1c5..86db615cef2d 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TableUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/TableUtils.java @@ -15,13 +15,14 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BRefValue; +import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.values.ArrayValue; @@ -32,8 +33,8 @@ import java.util.Map; -import static io.ballerina.runtime.internal.CycleUtils.Node; import static io.ballerina.runtime.internal.errors.ErrorReasons.TABLE_KEY_CYCLIC_VALUE_REFERENCE_ERROR; +import static io.ballerina.runtime.internal.utils.CycleUtils.Node; /** * This class contains the utility methods required by the table implementation. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ValueComparisonUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ValueComparisonUtils.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ValueComparisonUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ValueComparisonUtils.java index 13f1010ceabc..48f33fda34ab 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ValueComparisonUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ValueComparisonUtils.java @@ -16,18 +16,20 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; -import io.ballerina.runtime.api.TypeTags; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BError; +import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.values.DecimalValue; +import io.ballerina.runtime.internal.values.DecimalValueKind; import io.ballerina.runtime.internal.values.TupleValueImpl; import java.util.PrimitiveIterator; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_NULL; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_NULL; /** * Class @{@link ValueComparisonUtils} provides utils to compare Ballerina Values. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ValueConverter.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ValueConverter.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ValueConverter.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ValueConverter.java index d29f432d9712..ec772ed9b133 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ValueConverter.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ValueConverter.java @@ -16,9 +16,8 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.AnydataType; @@ -30,6 +29,7 @@ import io.ballerina.runtime.api.types.TableType; import io.ballerina.runtime.api.types.TupleType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.TypedescType; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; @@ -42,6 +42,8 @@ import io.ballerina.runtime.api.values.BTable; import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.api.values.BXml; +import io.ballerina.runtime.internal.TypeChecker; +import io.ballerina.runtime.internal.TypeConverter; import io.ballerina.runtime.internal.commons.TypeValuePair; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; @@ -65,7 +67,7 @@ import java.util.Set; import static io.ballerina.runtime.api.creators.ErrorCreator.createError; -import static io.ballerina.runtime.internal.ErrorUtils.createConversionError; +import static io.ballerina.runtime.internal.utils.ErrorUtils.createConversionError; /** * Responsible for performing the conversion of values between subtypes of {@link AnydataType} at runtime. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ValueUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ValueUtils.java similarity index 76% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ValueUtils.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ValueUtils.java index 82b4bb194a99..e2701a607244 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/ValueUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/utils/ValueUtils.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.utils; import io.ballerina.runtime.api.Module; import io.ballerina.runtime.api.creators.TypeCreator; @@ -32,8 +32,8 @@ import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.api.values.BValue; import io.ballerina.runtime.api.values.BXml; +import io.ballerina.runtime.internal.TypeConverter; import io.ballerina.runtime.internal.scheduling.Scheduler; -import io.ballerina.runtime.internal.scheduling.State; import io.ballerina.runtime.internal.scheduling.Strand; import io.ballerina.runtime.internal.types.BRecordType; import io.ballerina.runtime.internal.values.MapValue; @@ -41,7 +41,6 @@ import io.ballerina.runtime.internal.values.TypedescValueImpl; import io.ballerina.runtime.internal.values.ValueCreator; -import java.io.PrintStream; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -55,8 +54,6 @@ */ public final class ValueUtils { - private static final PrintStream errStream = System.err; - /** * Create a record value using the given package ID and record type name. * @@ -104,54 +101,53 @@ private static BMap getPopulatedRecordValue(ValueCreator valueC Set providedFields) { MapValue recordValue = valueCreator.createRecordValue(recordTypeName); BRecordType type = (BRecordType) TypeUtils.getImpliedType(recordValue.getType()); - return populateDefaultValues(recordValue, type, providedFields); + return populateDefaultValues(valueCreator, recordValue, type, providedFields); } private static BMap getPopulatedRecordValue(ValueCreator valueCreator, String recordTypeName, List notProvidedFields) { MapValue recordValue = valueCreator.createRecordValue(recordTypeName); BRecordType type = (BRecordType) TypeUtils.getImpliedType(recordValue.getType()); - return populateDefaultValues(recordValue, type, notProvidedFields); + return populateDefaultValues(valueCreator, recordValue, type, notProvidedFields); } - public static BMap populateDefaultValues(BMap recordValue, BRecordType type, + public static BMap populateDefaultValues(ValueCreator valueCreator, + BMap recordValue, BRecordType type, Set providedFields) { - Map> defaultValues = type.getDefaultValues(); + Map defaultValues = type.getDefaultValues(); if (defaultValues.isEmpty()) { return recordValue; } defaultValues = getNonProvidedDefaultValues(defaultValues, providedFields); - return populateRecordDefaultValues(recordValue, defaultValues); + return populateRecordDefaultValues(valueCreator, recordValue, defaultValues); } - public static BMap populateDefaultValues(BMap recordValue, BRecordType type, + public static BMap populateDefaultValues(ValueCreator valueCreator, + BMap recordValue, BRecordType type, List notProvidedFieldNames) { - Map> defaultValues = type.getDefaultValues(); + Map defaultValues = type.getDefaultValues(); if (defaultValues.isEmpty()) { return recordValue; } defaultValues = getNonProvidedDefaultValues(defaultValues, notProvidedFieldNames); - return populateRecordDefaultValues(recordValue, defaultValues); + return populateRecordDefaultValues(valueCreator, recordValue, defaultValues); } - private static BMap populateRecordDefaultValues( - BMap recordValue, Map> defaultValues) { - Strand strand = Scheduler.getStrandNoException(); - if (strand == null) { - // Create a dummy strand only for keep frames. - strand = new Strand(); - } - for (Map.Entry> field : defaultValues.entrySet()) { + private static BMap populateRecordDefaultValues(ValueCreator valueCreator, + BMap recordValue, + Map defaultValues) { + for (Map.Entry field : defaultValues.entrySet()) { recordValue.populateInitialValue(StringUtils.fromString(field.getKey()), - field.getValue().call(new Object[]{strand})); + field.getValue().call(valueCreator.runtime)); } return recordValue; } - private static Map> getNonProvidedDefaultValues( - Map> defaultValues, Set providedFields) { - Map> result = new HashMap<>(); - for (Map.Entry> entry : defaultValues.entrySet()) { + private static Map getNonProvidedDefaultValues( + Map defaultValues, Set providedFields) { + Map result = new HashMap<>(); + for (Map.Entry entry : defaultValues.entrySet()) { if (!providedFields.contains(entry.getKey())) { result.put(entry.getKey(), entry.getValue()); } @@ -159,9 +155,9 @@ private static BMap populateRecordDefaultValues( return result; } - private static Map> getNonProvidedDefaultValues( - Map> defaultValues, List notProvidedFieldNames) { - Map> result = new HashMap<>(); + private static Map getNonProvidedDefaultValues( + Map defaultValues, List notProvidedFieldNames) { + Map result = new HashMap<>(); for (String notProvidedFieldName : notProvidedFieldNames) { result.put(notProvidedFieldName, defaultValues.get(notProvidedFieldName)); } @@ -245,7 +241,7 @@ public static BMap createRecordValue(BMap reco * @return value of the object. */ public static BObject createObjectValue(Module packageId, String objectTypeName, Object... fieldValues) { - Strand currentStrand = Scheduler.getStrandNoException(); + Strand currentStrand = Scheduler.getStrand(); Object[] fields = new Object[fieldValues.length]; // Adding boolean values for each arg for (int i = 0, j = 0; i < fieldValues.length; i++) { @@ -254,55 +250,24 @@ public static BObject createObjectValue(Module packageId, String objectTypeName, return createObjectValue(currentStrand, packageId, objectTypeName, fields); } - /** - * Create object value with strand, package ID, object type name and given field values. - * - * @param currentStrand current strand. - * @param packageId the package ID that the object type resides. - * @param objectTypeName name of the object type. - * @param fieldValues values to be used for fields when creating the object value instance. - * @return value of the object. - */ public static BObject createObjectValue(Strand currentStrand, Module packageId, String objectTypeName, - Object[] fieldValues) { + Object[] fieldValues) { // This method duplicates the createObjectValue with referencing the issue in runtime API getting strand io.ballerina.runtime.internal.values.ValueCreator - valueCreator = io.ballerina.runtime.internal.values.ValueCreator.getValueCreator(ValueCreator + valueCreator = io.ballerina.runtime.internal.values.ValueCreator.getValueCreator(ValueCreator .getLookupKey(packageId, false)); - // Here the variables are initialized with default values - Scheduler scheduler = null; - State prevState = State.RUNNABLE; - boolean prevBlockedOnExtern = false; - try { - // Check for non-blocking call - if (currentStrand != null) { - scheduler = currentStrand.scheduler; - prevBlockedOnExtern = currentStrand.blockedOnExtern; - prevState = currentStrand.getState(); - currentStrand.blockedOnExtern = false; - currentStrand.setState(State.RUNNABLE); - } - try { - return valueCreator.createObjectValue(objectTypeName, scheduler, currentStrand, - null, fieldValues); - } catch (BError e) { - // If object type definition not found, get it from test module. - String testLookupKey = ValueCreator.getLookupKey(packageId, true); - if (ValueCreator.containsValueCreator(testLookupKey)) { - valueCreator = ValueCreator.getValueCreator(testLookupKey); - return valueCreator.createObjectValue(objectTypeName, scheduler, currentStrand, - null, fieldValues); - } - throw e; - } - } finally { - if (currentStrand != null) { - currentStrand.blockedOnExtern = prevBlockedOnExtern; - currentStrand.setState(prevState); + return valueCreator.createObjectValue(objectTypeName, currentStrand, fieldValues); + } catch (BError e) { + // If object type definition not found, get it from test module. + String testLookupKey = ValueCreator.getLookupKey(packageId, true); + if (ValueCreator.containsValueCreator(testLookupKey)) { + valueCreator = ValueCreator.getValueCreator(testLookupKey); + return valueCreator.createObjectValue(objectTypeName, currentStrand, fieldValues); } + throw e; } } 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 ab80640c69d0..4768e51ecd52 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 @@ -17,16 +17,16 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; -import io.ballerina.runtime.internal.IteratorUtils; -import io.ballerina.runtime.internal.JsonGenerator; import io.ballerina.runtime.internal.errors.ErrorHelper; +import io.ballerina.runtime.internal.json.JsonGenerator; import io.ballerina.runtime.internal.types.BTupleType; import io.ballerina.runtime.internal.types.BUnionType; +import io.ballerina.runtime.internal.utils.IteratorUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; 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 e983854997ef..ad1896b75e76 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 @@ -17,13 +17,13 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.RuntimeConstants; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.ArrayType.ArrayState; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; @@ -34,13 +34,13 @@ import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.api.values.BValue; -import io.ballerina.runtime.internal.CycleUtils; import io.ballerina.runtime.internal.TypeChecker; -import io.ballerina.runtime.internal.ValueConverter; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.errors.ErrorReasons; import io.ballerina.runtime.internal.types.BArrayType; +import io.ballerina.runtime.internal.utils.CycleUtils; +import io.ballerina.runtime.internal.utils.ValueConverter; import java.io.IOException; import java.io.OutputStream; @@ -54,12 +54,12 @@ import java.util.stream.IntStream; import static io.ballerina.runtime.api.constants.RuntimeConstants.ARRAY_LANG_LIB; -import static io.ballerina.runtime.internal.ValueUtils.getTypedescValue; import static io.ballerina.runtime.internal.errors.ErrorReasons.INDEX_OUT_OF_RANGE_ERROR_IDENTIFIER; import static io.ballerina.runtime.internal.errors.ErrorReasons.INHERENT_TYPE_VIOLATION_ERROR_IDENTIFIER; import static io.ballerina.runtime.internal.errors.ErrorReasons.getModulePrefixedReason; -import static io.ballerina.runtime.internal.util.StringUtils.getExpressionStringVal; -import static io.ballerina.runtime.internal.util.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getExpressionStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.ValueUtils.getTypedescValue; /** *

diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AttributeMapValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AttributeMapValueImpl.java index ea3b593194ef..ca62b3ea88cb 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AttributeMapValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/AttributeMapValueImpl.java @@ -17,13 +17,13 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BString; -import io.ballerina.runtime.internal.XmlValidator; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.types.BMapType; +import io.ballerina.runtime.internal.xml.XmlValidator; import javax.xml.XMLConstants; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ChannelDetails.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ChannelDetails.java deleted file mode 100644 index 1bbbba69adbc..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ChannelDetails.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2019, 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. - */ -package io.ballerina.runtime.internal.values; - -/** - * Represents a channel info. - * - * @since 0.995.0 - */ -public class ChannelDetails { - - public String name; - public boolean channelInSameStrand; - public boolean send; - - public ChannelDetails(String name, boolean channelInSameStrand, boolean send) { - this.name = name; - this.channelInSameStrand = channelInSameStrand; - this.send = send; - } - - @Override - public String toString() { - return name; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public boolean equals(Object o) { - return (o instanceof ChannelDetails channelDetails) && (channelDetails.name.equals(this.name)); - } -} diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/DecimalValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/DecimalValue.java index 2771264baf37..ec48ef7789af 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/DecimalValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/DecimalValue.java @@ -18,17 +18,16 @@ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.constants.RuntimeConstants; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BDecimal; import io.ballerina.runtime.api.values.BLink; -import io.ballerina.runtime.internal.DecimalValueKind; -import io.ballerina.runtime.internal.ErrorUtils; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.errors.ErrorReasons; +import io.ballerina.runtime.internal.utils.ErrorUtils; import java.math.BigDecimal; import java.math.MathContext; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/DecimalValueKind.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/DecimalValueKind.java similarity index 95% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/DecimalValueKind.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/DecimalValueKind.java index 275b86ef1bdf..cc77a215e4f4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/DecimalValueKind.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/DecimalValueKind.java @@ -16,7 +16,7 @@ * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.values; /** * Possible kinds of a decimal value. diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ErrorValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ErrorValue.java index dd534b85352e..f8cd391a127a 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ErrorValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ErrorValue.java @@ -19,22 +19,24 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.TypeId; +import io.ballerina.runtime.api.types.TypeTags; +import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BLink; +import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BRefValue; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.api.values.BValue; -import io.ballerina.runtime.internal.CycleUtils; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.types.BErrorType; import io.ballerina.runtime.internal.types.BTypeIdSet; +import io.ballerina.runtime.internal.utils.CycleUtils; import java.io.PrintStream; import java.io.PrintWriter; @@ -42,17 +44,18 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.StringJoiner; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_MAP; import static io.ballerina.runtime.api.constants.RuntimeConstants.BLANG_SRC_FILE_SUFFIX; import static io.ballerina.runtime.api.constants.RuntimeConstants.DOT; import static io.ballerina.runtime.api.constants.RuntimeConstants.MODULE_INIT_CLASS_NAME; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_MAP; import static io.ballerina.runtime.internal.TypeChecker.isEqual; -import static io.ballerina.runtime.internal.util.StringUtils.getExpressionStringVal; -import static io.ballerina.runtime.internal.util.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getExpressionStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getStringVal; /** *

@@ -72,7 +75,7 @@ public class ErrorValue extends BError implements RefValue { private BTypedesc typedesc; private final BString message; private final BError cause; - private final Object details; + private final BMap details; private static final String GENERATED_CLASS_TEXTS_REGEX = "\\$value\\$|\\$split\\$\\d|lambdas.\\$_generated\\d*"; private static final String GENERATE_PKG_INIT = "___init_"; @@ -87,12 +90,17 @@ public ErrorValue(BString message) { message, null, new MapValueImpl<>(PredefinedTypes.TYPE_ERROR_DETAIL)); } - public ErrorValue(BString message, Object details) { + public ErrorValue(BString message, BMap details) { this(new BErrorType(TypeConstants.ERROR, PredefinedTypes.TYPE_ERROR.getPackage(), TypeChecker.getType(details)), message, null, details); } - public ErrorValue(Type type, BString message, BError cause, Object details) { + public ErrorValue(BString message, BError cause) { + this(new BErrorType(TypeConstants.ERROR, PredefinedTypes.TYPE_ERROR.getPackage(), TYPE_MAP), message, cause, + null); + } + + public ErrorValue(Type type, BString message, BError cause, BMap details) { super(message); this.type = type; this.message = message; @@ -100,7 +108,7 @@ public ErrorValue(Type type, BString message, BError cause, Object details) { this.details = details; } - public ErrorValue(Type type, BString message, BError cause, Object details, + public ErrorValue(Type type, BString message, BError cause, BMap details, String typeIdName, Module typeIdPkg) { super(message); this.type = type; @@ -115,11 +123,12 @@ public ErrorValue(Type type, BString message, BError cause, Object details, @Override public String stringValue(BLink parent) { CycleUtils.Node linkParent = new CycleUtils.Node(this, parent); + BString errMessage = Objects.requireNonNullElse(message, StringUtils.fromString("")); if (isEmptyDetail()) { - return "error" + getModuleNameToString() + "(" + ((StringValue) message).informalStringValue(linkParent) + return "error" + getModuleNameToString() + "(" + ((StringValue) errMessage).informalStringValue(linkParent) + getCauseToString(linkParent) + ")"; } - return "error" + getModuleNameToString() + "(" + ((StringValue) message).informalStringValue(linkParent) + + return "error" + getModuleNameToString() + "(" + ((StringValue) errMessage).informalStringValue(linkParent) + getCauseToString(linkParent) + getDetailsToString(linkParent) + ")"; } @@ -439,8 +448,8 @@ private Optional filterStackTraceElement(StackTraceElement st // the stack frames which have compiler added method names return Optional.empty(); } - return Optional.of( - new StackTraceElement(cleanupClassName(className), methodName, fileName, stackFrame.getLineNumber())); + return Optional.of(new StackTraceElement(cleanupClassName(className), methodName, fileName, + stackFrame.getLineNumber())); } private String cleanupClassName(String className) { diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FPValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FPValue.java index beedcc984d45..35dd9a28be60 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FPValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FPValue.java @@ -17,74 +17,43 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.async.StrandMetadata; +import io.ballerina.runtime.api.Runtime; import io.ballerina.runtime.api.constants.RuntimeConstants; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BFunctionPointer; -import io.ballerina.runtime.api.values.BFuture; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BTypedesc; -import io.ballerina.runtime.internal.scheduling.AsyncUtils; -import io.ballerina.runtime.internal.scheduling.Scheduler; +import io.ballerina.runtime.internal.BalRuntime; import java.util.Map; -import java.util.function.Consumer; import java.util.function.Function; /** *

* Ballerina runtime value representation of a function pointer. *

- *

- * Note: This is an internal API and may change in future versions. - *

- * - * @param the type of the input to the function - * @param the type of the result of the function * * @since 0.995.0 */ -public class FPValue implements BFunctionPointer, RefValue { +public class FPValue implements BFunctionPointer, RefValue { final Type type; private BTypedesc typedesc; - Function function; - public boolean isConcurrent; - public String strandName; + public Function function; + public boolean isIsolated; + public String name; - @Deprecated - public FPValue(Function function, Type type, String strandName, boolean isConcurrent) { + public FPValue(Function function, Type type, String name, boolean isIsolated) { this.function = function; this.type = type; - this.strandName = strandName; - this.isConcurrent = isConcurrent; - } - - @Override - public R call(T t) { - return this.function.apply(t); - } - - @Override - public BFuture asyncCall(Object[] args, StrandMetadata metaData) { - return this.asyncCall(args, o -> o, metaData); + this.name = name; + this.isIsolated = isIsolated; } @Override - public BFuture asyncCall(Object[] args, Function resultHandleFunction, - StrandMetadata metaData) { - return AsyncUtils.invokeFunctionPointerAsync((BFunctionPointer) this, this.strandName, metaData, - args, resultHandleFunction, Scheduler.getStrand().scheduler); - } - - @Override - public Function getFunction() { - return this.function; - } - - @Deprecated - public Consumer getConsumer() { - return val -> this.function.apply(val); + public Object call(Runtime runtime, Object... t) { + BalRuntime balRuntime = (BalRuntime) runtime; + return balRuntime.scheduler.callFP(this, null, t); } @Override @@ -124,6 +93,10 @@ public BTypedesc getTypedesc() { return typedesc; } + public String getName() { + return name; + } + @Override public String toString() { return RuntimeConstants.EMPTY; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FutureValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FutureValue.java index 44a9c34da136..7dda2fecd950 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FutureValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/FutureValue.java @@ -17,17 +17,21 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.async.Callback; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BFuture; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BTypedesc; +import io.ballerina.runtime.internal.scheduling.AsyncUtils; +import io.ballerina.runtime.internal.scheduling.Scheduler; import io.ballerina.runtime.internal.scheduling.Strand; import io.ballerina.runtime.internal.types.BFutureType; -import io.ballerina.runtime.internal.util.StringUtils; +import io.ballerina.runtime.internal.utils.StringUtils; import java.util.Map; import java.util.StringJoiner; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicBoolean; /** *

@@ -41,41 +45,36 @@ */ public class FutureValue implements BFuture, RefValue { - private BTypedesc typedesc; + public Strand strand; + Type type; + public final CompletableFuture completableFuture; + private final BTypedesc typedesc; + private final AtomicBoolean waited; + + public FutureValue(Strand strand, Type constraint) { + this.strand = strand; + this.type = new BFutureType(constraint); + this.typedesc = new TypedescValueImpl(this.type); + this.completableFuture = new CompletableFuture<>(); + this.waited = new AtomicBoolean(); + } + + @Override + public String stringValue(BLink parent) { + StringJoiner sj = new StringJoiner(",", "{", "}"); + boolean isDone = completableFuture.isDone(); + sj.add("isDone:" + completableFuture.isDone()); + Object result = completableFuture.getNow(null); + if (isDone) { + if (result instanceof BError error) { + sj.add("panic:" + error.getLocalizedMessage()); + } else { + sj.add("result:" + StringUtils.getStringVal(completableFuture.getNow(null), parent)); + } + } + return "future " + sj; + } - public Strand strand; - - public Object result; - - public boolean isDone; - - public Throwable panic; - - public Callback callback; - - private boolean waited; - - Type type; - - @Deprecated - public FutureValue(Strand strand, Callback callback, Type constraint) { - this.strand = strand; - this.callback = callback; - this.type = new BFutureType(constraint); - } - - @Override - public String stringValue(BLink parent) { - StringJoiner sj = new StringJoiner(",", "{", "}"); - sj.add("isDone:" + isDone); - if (isDone) { - sj.add("result:" + StringUtils.getStringVal(result, parent)); - } - if (panic != null) { - sj.add("panic:" + panic.getLocalizedMessage()); - } - return "future " + sj; - } @Override public String expressionStringValue(BLink parent) { @@ -97,74 +96,48 @@ public Object frozenCopy(Map refs) { throw new UnsupportedOperationException(); } - @Override - public BTypedesc getTypedesc() { - if (this.typedesc == null) { - this.typedesc = new TypedescValueImpl(this.type); - } - return typedesc; - } - - @Override - public void cancel() { - this.strand.cancel = true; - } - - /** - * Returns the strand that the future is attached to. - * @return {@code Strand} - */ - @Override - public Strand getStrand() { - return this.strand; - } - - /** - * Returns the result value of the future. - * @return result value - */ - @Override - public Object getResult() { - return this.result; - } - - /** - * Returns completion status of the {@code Strand} that the future is attached. - * @return true if future is completed - */ - @Override - public boolean isDone() { - return this.isDone; - } - - /** - * Returns {@code Throwable} if the attached strand panic. - * @return panic error or null if not panic occurred - */ - @Override - public Throwable getPanic() { - return this.panic; - } - - /** - * {@code CallableUnitCallback} listening on the completion of this future. - * @return registered {@code CallableUnitCallback} - */ - @Override - public Callback getCallback() { - return this.callback; - } + @Override + public BTypedesc getTypedesc() { + return typedesc; + } + + @Override + public void cancel() { + this.strand.cancelled = true; + if (this.strand.workerChannelMap != null) { + this.strand.workerChannelMap.cancel(); + } + } + + /** + * Returns the result value of the future. + * @return result value + */ + @Override + public Object get() { + return AsyncUtils.handleWait(Scheduler.getStrand(), this.completableFuture); + } + + /** + * Returns completion status of the {@code Strand} that the future is attached. + * @return true if future is completed + */ + @Override + public boolean isDone() { + return completableFuture.isDone(); + } @Override public String toString() { return stringValue(null); } - public boolean hasWaited() { - return waited; - } + @Override + public boolean isPanic() { + return completableFuture.isCompletedExceptionally(); + } - public void setWaited(boolean waited) { - this.waited = waited; - } -} + public boolean getAndSetWaited() { + return waited.getAndSet(true); + } + } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/HandleValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/HandleValue.java index 42f5ce5c100f..c0aff83e5122 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/HandleValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/HandleValue.java @@ -17,7 +17,7 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BHandle; import io.ballerina.runtime.api.values.BLink; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/IteratorValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/IteratorValue.java index 8004a431ad5f..6934af3536ce 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/IteratorValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/IteratorValue.java @@ -17,7 +17,7 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BIterator; import io.ballerina.runtime.api.values.BLink; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/MapValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/MapValueImpl.java index 53b0e46f92f2..ebbdce07f208 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/MapValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/MapValueImpl.java @@ -17,11 +17,11 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.Field; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BError; @@ -34,20 +34,20 @@ import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.api.values.BValue; -import io.ballerina.runtime.internal.CycleUtils; -import io.ballerina.runtime.internal.IteratorUtils; -import io.ballerina.runtime.internal.JsonGenerator; -import io.ballerina.runtime.internal.JsonInternalUtils; -import io.ballerina.runtime.internal.MapUtils; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; +import io.ballerina.runtime.internal.json.JsonGenerator; +import io.ballerina.runtime.internal.json.JsonInternalUtils; import io.ballerina.runtime.internal.scheduling.Scheduler; import io.ballerina.runtime.internal.types.BField; import io.ballerina.runtime.internal.types.BMapType; import io.ballerina.runtime.internal.types.BRecordType; import io.ballerina.runtime.internal.types.BTupleType; import io.ballerina.runtime.internal.types.BUnionType; +import io.ballerina.runtime.internal.utils.CycleUtils; +import io.ballerina.runtime.internal.utils.IteratorUtils; +import io.ballerina.runtime.internal.utils.MapUtils; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -66,15 +66,15 @@ import static io.ballerina.runtime.api.constants.RuntimeConstants.MAP_LANG_LIB; import static io.ballerina.runtime.api.utils.TypeUtils.getImpliedType; -import static io.ballerina.runtime.internal.JsonInternalUtils.mergeJson; import static io.ballerina.runtime.internal.TypeChecker.isEqual; -import static io.ballerina.runtime.internal.ValueUtils.getTypedescValue; import static io.ballerina.runtime.internal.errors.ErrorCodes.INVALID_READONLY_VALUE_UPDATE; import static io.ballerina.runtime.internal.errors.ErrorReasons.INVALID_UPDATE_ERROR_IDENTIFIER; import static io.ballerina.runtime.internal.errors.ErrorReasons.MAP_KEY_NOT_FOUND_ERROR; import static io.ballerina.runtime.internal.errors.ErrorReasons.getModulePrefixedReason; -import static io.ballerina.runtime.internal.util.StringUtils.getExpressionStringVal; -import static io.ballerina.runtime.internal.util.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.json.JsonInternalUtils.mergeJson; +import static io.ballerina.runtime.internal.utils.StringUtils.getExpressionStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.ValueUtils.getTypedescValue; import static io.ballerina.runtime.internal.values.ReadOnlyUtils.handleInvalidUpdate; /** @@ -313,9 +313,9 @@ public void setTypeForcefully(Type type) { } protected void populateInitialValues(BMapInitialValueEntry[] initialValues) { - Map> defaultValues = new HashMap<>(); - if (type.getTag() == TypeTags.RECORD_TYPE_TAG) { - defaultValues.putAll(((BRecordType) type).getDefaultValues()); + Map defaultValues = new HashMap<>(); + if (referredType.getTag() == TypeTags.RECORD_TYPE_TAG) { + defaultValues.putAll(((BRecordType) referredType).getDefaultValues()); } for (BMapInitialValueEntry initialValue : initialValues) { @@ -337,10 +337,10 @@ protected void populateInitialValues(BMapInitialValueEntry[] initialValues) { } } - for (Map.Entry> entry : defaultValues.entrySet()) { + for (Map.Entry entry : defaultValues.entrySet()) { String key = entry.getKey(); - BFunctionPointer value = entry.getValue(); - populateInitialValue((K) new BmpStringValue(key), (V) value.call(new Object[]{Scheduler.getStrand()})); + populateInitialValue((K) new BmpStringValue(key), + (V) entry.getValue().call(Scheduler.getStrand().scheduler.runtime, new Object[]{})); } } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ObjectValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ObjectValue.java index 6a2116b51041..2dbe41561ef1 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ObjectValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ObjectValue.java @@ -33,9 +33,7 @@ */ public interface ObjectValue extends BObject { - @Override Object call(Strand strand, String funcName, Object... args); - @Override BFuture start(Strand strand, String funcName, Object... args); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ReadOnlyUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ReadOnlyUtils.java index 9b46eba3d30c..c9ba580378da 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ReadOnlyUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ReadOnlyUtils.java @@ -19,8 +19,6 @@ import io.ballerina.identifier.Utils; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.TypeConstants; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.flags.SymbolFlags; @@ -28,9 +26,11 @@ import io.ballerina.runtime.api.types.Field; import io.ballerina.runtime.api.types.IntersectableReferenceType; import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.ReferenceType; import io.ballerina.runtime.api.types.SelectivelyImmutableReferenceType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BFunctionPointer; import io.ballerina.runtime.internal.TypeChecker; @@ -234,7 +234,7 @@ private static BIntersectionType setImmutableIntersectionType(Type type, Set> field : origRecordType.getDefaultValues() + for (Map.Entry field : origRecordType.getDefaultValues() .entrySet()) { immutableRecordType.setDefaultValue(field.getKey(), field.getValue()); } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpAtomQuantifier.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpAtomQuantifier.java index 21a3bef34c66..0ab09925fe7d 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpAtomQuantifier.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpAtomQuantifier.java @@ -21,7 +21,7 @@ import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.internal.regexp.RegExpFactory; -import static io.ballerina.runtime.internal.util.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getStringVal; /** *

diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpCommonValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpCommonValue.java index 1b460f8e276d..aa790ee4bf74 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpCommonValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpCommonValue.java @@ -17,7 +17,7 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BTypedesc; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpDisjunction.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpDisjunction.java index 54cde1be1df8..8f2a32084878 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpDisjunction.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpDisjunction.java @@ -21,7 +21,7 @@ import java.util.StringJoiner; -import static io.ballerina.runtime.internal.util.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getStringVal; /** *

diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpValue.java index da45d3856a1e..c9a4fd8f30c7 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/RegExpValue.java @@ -15,7 +15,7 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BRegexpValue; @@ -25,7 +25,7 @@ import java.util.Objects; import java.util.Set; -import static io.ballerina.runtime.internal.ValueUtils.getTypedescValue; +import static io.ballerina.runtime.internal.utils.ValueUtils.getTypedescValue; /** *

diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StreamValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StreamValue.java index bf0eb2d4a2ca..7f6d1ed45728 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StreamValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StreamValue.java @@ -23,8 +23,8 @@ import io.ballerina.runtime.api.values.BObject; import io.ballerina.runtime.api.values.BStream; import io.ballerina.runtime.api.values.BTypedesc; -import io.ballerina.runtime.internal.IteratorUtils; import io.ballerina.runtime.internal.types.BStreamType; +import io.ballerina.runtime.internal.utils.IteratorUtils; import java.util.Map; import java.util.UUID; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StreamingJsonValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StreamingJsonValue.java index e532436f0c9e..be4449349c57 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StreamingJsonValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StreamingJsonValue.java @@ -17,12 +17,12 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BStreamingJson; -import io.ballerina.runtime.internal.JsonDataSource; -import io.ballerina.runtime.internal.JsonGenerator; -import io.ballerina.runtime.internal.JsonInternalUtils; +import io.ballerina.runtime.internal.json.JsonDataSource; +import io.ballerina.runtime.internal.json.JsonGenerator; +import io.ballerina.runtime.internal.json.JsonInternalUtils; import io.ballerina.runtime.internal.types.BArrayType; import io.ballerina.runtime.internal.types.BMapType; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StringValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StringValue.java index a96fcacd5a07..3898b3aa8ca4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StringValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/StringValue.java @@ -17,7 +17,7 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BString; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TableValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TableValueImpl.java index 305586506362..c027da267680 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TableValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TableValueImpl.java @@ -17,12 +17,12 @@ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.Field; import io.ballerina.runtime.api.types.TableType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; @@ -33,9 +33,6 @@ import io.ballerina.runtime.api.values.BRefValue; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; -import io.ballerina.runtime.internal.CycleUtils; -import io.ballerina.runtime.internal.IteratorUtils; -import io.ballerina.runtime.internal.TableUtils; import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; @@ -46,6 +43,9 @@ import io.ballerina.runtime.internal.types.BTupleType; import io.ballerina.runtime.internal.types.BTypeReferenceType; import io.ballerina.runtime.internal.types.BUnionType; +import io.ballerina.runtime.internal.utils.CycleUtils; +import io.ballerina.runtime.internal.utils.IteratorUtils; +import io.ballerina.runtime.internal.utils.TableUtils; import java.util.AbstractMap; import java.util.ArrayList; @@ -67,14 +67,14 @@ import static io.ballerina.runtime.api.constants.RuntimeConstants.TABLE_LANG_LIB; import static io.ballerina.runtime.api.utils.TypeUtils.getImpliedType; import static io.ballerina.runtime.internal.TypeChecker.isEqual; -import static io.ballerina.runtime.internal.ValueUtils.getTypedescValue; import static io.ballerina.runtime.internal.errors.ErrorReasons.INHERENT_TYPE_VIOLATION_ERROR_IDENTIFIER; import static io.ballerina.runtime.internal.errors.ErrorReasons.OPERATION_NOT_SUPPORTED_ERROR; import static io.ballerina.runtime.internal.errors.ErrorReasons.TABLE_HAS_A_VALUE_FOR_KEY_ERROR; import static io.ballerina.runtime.internal.errors.ErrorReasons.TABLE_KEY_NOT_FOUND_ERROR; import static io.ballerina.runtime.internal.errors.ErrorReasons.getModulePrefixedReason; -import static io.ballerina.runtime.internal.util.StringUtils.getExpressionStringVal; -import static io.ballerina.runtime.internal.util.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getExpressionStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.ValueUtils.getTypedescValue; /** * The runtime representation of table. @@ -199,10 +199,8 @@ public Object frozenCopy(Map refs) { } protected void handleFrozenTableValue() { - synchronized (this) { - if (this.tableType.isReadOnly()) { - ReadOnlyUtils.handleInvalidUpdate(TABLE_LANG_LIB); - } + if (this.tableType.isReadOnly()) { + ReadOnlyUtils.handleInvalidUpdate(TABLE_LANG_LIB); } } 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 922b1ce59a21..b6db397f4617 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 @@ -17,10 +17,10 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.TupleType; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; @@ -31,12 +31,12 @@ import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.api.values.BValue; -import io.ballerina.runtime.internal.CycleUtils; import io.ballerina.runtime.internal.TypeChecker; -import io.ballerina.runtime.internal.ValueConverter; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.errors.ErrorReasons; +import io.ballerina.runtime.internal.utils.CycleUtils; +import io.ballerina.runtime.internal.utils.ValueConverter; import java.io.IOException; import java.io.OutputStream; @@ -48,13 +48,13 @@ import java.util.stream.IntStream; import static io.ballerina.runtime.api.constants.RuntimeConstants.ARRAY_LANG_LIB; -import static io.ballerina.runtime.internal.ValueUtils.getTypedescValue; import static io.ballerina.runtime.internal.errors.ErrorReasons.INDEX_OUT_OF_RANGE_ERROR_IDENTIFIER; import static io.ballerina.runtime.internal.errors.ErrorReasons.INHERENT_TYPE_VIOLATION_ERROR_IDENTIFIER; import static io.ballerina.runtime.internal.errors.ErrorReasons.OPERATION_NOT_SUPPORTED_IDENTIFIER; import static io.ballerina.runtime.internal.errors.ErrorReasons.getModulePrefixedReason; -import static io.ballerina.runtime.internal.util.StringUtils.getExpressionStringVal; -import static io.ballerina.runtime.internal.util.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getExpressionStringVal; +import static io.ballerina.runtime.internal.utils.StringUtils.getStringVal; +import static io.ballerina.runtime.internal.utils.ValueUtils.getTypedescValue; /** *

diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java index 39dc6347600a..043ab88d84d3 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/TypedescValueImpl.java @@ -17,9 +17,9 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BInitialValueEntry; import io.ballerina.runtime.api.values.BLink; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ValueCreator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ValueCreator.java index b61540d7beaa..bb807e10c0c8 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ValueCreator.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/ValueCreator.java @@ -19,12 +19,13 @@ import io.ballerina.runtime.api.Module; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.FunctionType; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BError; import io.ballerina.runtime.api.values.BObject; import io.ballerina.runtime.api.values.BString; -import io.ballerina.runtime.internal.scheduling.Scheduler; +import io.ballerina.runtime.internal.BalRuntime; import io.ballerina.runtime.internal.scheduling.Strand; import java.util.HashMap; @@ -47,6 +48,12 @@ public abstract class ValueCreator { private static final Map runtimeValueCreators = new HashMap<>(); + public final BalRuntime runtime; + + protected ValueCreator(BalRuntime runtime) { + this.runtime = runtime; + } + public static void addValueCreator(String orgName, String moduleName, String moduleVersion, boolean isTestPkg, ValueCreator valueCreator) { String key = getLookupKey(orgName, moduleName, moduleVersion, isTestPkg); @@ -59,6 +66,10 @@ public static void addValueCreator(String orgName, String moduleName, String mod runtimeValueCreators.put(key, valueCreator); } + public static String getLookupKey(Module module) { + return getLookupKey(module.getOrg(), module.getName(), module.getMajorVersion(), module.isTestPkg()); + } + public static String getLookupKey(Module module, boolean isTestPkg) { return getLookupKey(module.getOrg(), module.getName(), module.getMajorVersion(), isTestPkg); } @@ -92,6 +103,11 @@ public static ValueCreator getValueCreator(String key) { return runtimeValueCreators.get(key); } + public static void removeValueCreator(Module rootModule) { + String key = getLookupKey(rootModule, false); + runtimeValueCreators.remove(key); + } + public Object call(Strand strand, String funcName, Object... args) throws BError { throw new ErrorValue(StringUtils.fromString("No such method: " + funcName)); } @@ -102,12 +118,13 @@ public static boolean containsValueCreator(String key) { public abstract MapValue createRecordValue(String recordTypeName) throws BError; - public abstract BObject createObjectValue(String objectTypeName, Scheduler scheduler, Strand parent, - Map properties, Object[] args) throws BError; + public abstract BObject createObjectValue(String objectTypeName, Strand parent, Object[] args) throws BError; public abstract BError createErrorValue(String errorTypeName, BString message, BError cause, Object details) throws BError; public abstract Type getAnonType(int typeHash, String typeShape) throws BError; + public abstract FunctionType getFunctionType(String functionName) throws BError; + } diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlComment.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlComment.java index 00cab7fe4d6b..1e67f4aa3bca 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlComment.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlComment.java @@ -17,7 +17,7 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.XmlNodeType; import io.ballerina.runtime.api.values.BLink; import org.apache.axiom.om.OMNode; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlItem.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlItem.java index 10d35118e3a2..602186748313 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlItem.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlItem.java @@ -16,8 +16,8 @@ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.XmlNodeType; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BError; @@ -27,12 +27,12 @@ import io.ballerina.runtime.api.values.BXml; import io.ballerina.runtime.api.values.BXmlItem; import io.ballerina.runtime.api.values.BXmlSequence; -import io.ballerina.runtime.internal.BallerinaXmlSerializer; -import io.ballerina.runtime.internal.XmlFactory; -import io.ballerina.runtime.internal.XmlValidator; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.errors.ErrorReasons; +import io.ballerina.runtime.internal.xml.BallerinaXmlSerializer; +import io.ballerina.runtime.internal.xml.XmlFactory; +import io.ballerina.runtime.internal.xml.XmlValidator; import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMException; import org.apache.axiom.om.OMNode; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlNonElementItem.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlNonElementItem.java index 8a404e5b755e..ac102cdbfcd2 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlNonElementItem.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlNonElementItem.java @@ -24,9 +24,9 @@ import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BXml; import io.ballerina.runtime.api.values.BXmlNonElementItem; -import io.ballerina.runtime.internal.BallerinaXmlSerializer; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; +import io.ballerina.runtime.internal.xml.BallerinaXmlSerializer; import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMFactory; import org.apache.axiom.om.OMNode; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlPi.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlPi.java index 8ece7823964d..b829b82237c4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlPi.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlPi.java @@ -17,7 +17,7 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.XmlNodeType; import io.ballerina.runtime.api.values.BLink; import org.apache.axiom.om.OMNode; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlQName.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlQName.java index d4cc801acc11..6b495deb68f4 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlQName.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlQName.java @@ -17,7 +17,7 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.values.BLink; import io.ballerina.runtime.api.values.BString; @@ -27,7 +27,7 @@ import java.util.Map; import java.util.Objects; -import static io.ballerina.runtime.internal.ValueUtils.getTypedescValue; +import static io.ballerina.runtime.internal.utils.ValueUtils.getTypedescValue; /** *

diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlSequence.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlSequence.java index f024b023c122..5343f2eb6d93 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlSequence.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlSequence.java @@ -16,11 +16,11 @@ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.constants.RuntimeConstants; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.types.XmlNodeType; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; @@ -29,13 +29,13 @@ import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BXml; import io.ballerina.runtime.api.values.BXmlSequence; -import io.ballerina.runtime.internal.CycleUtils; -import io.ballerina.runtime.internal.IteratorUtils; -import io.ballerina.runtime.internal.XmlFactory; import io.ballerina.runtime.internal.errors.ErrorCodes; import io.ballerina.runtime.internal.errors.ErrorHelper; import io.ballerina.runtime.internal.types.BArrayType; import io.ballerina.runtime.internal.types.BUnionType; +import io.ballerina.runtime.internal.utils.CycleUtils; +import io.ballerina.runtime.internal.utils.IteratorUtils; +import io.ballerina.runtime.internal.xml.XmlFactory; import java.util.ArrayList; import java.util.HashSet; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlText.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlText.java index 5103c770ebe3..dd1ff14d75a8 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlText.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlText.java @@ -17,7 +17,7 @@ */ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.XmlNodeType; import io.ballerina.runtime.api.values.BXml; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlValue.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlValue.java index 23443629ca47..30c606d8c4b2 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlValue.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/values/XmlValue.java @@ -16,8 +16,8 @@ package io.ballerina.runtime.internal.values; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.ErrorCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.XmlNodeType; import io.ballerina.runtime.api.utils.StringUtils; @@ -27,8 +27,8 @@ import io.ballerina.runtime.api.values.BTypedesc; import io.ballerina.runtime.api.values.BXml; import io.ballerina.runtime.api.values.BXmlQName; -import io.ballerina.runtime.internal.BallerinaXmlSerializer; -import io.ballerina.runtime.internal.IteratorUtils; +import io.ballerina.runtime.internal.utils.IteratorUtils; +import io.ballerina.runtime.internal.xml.BallerinaXmlSerializer; import java.io.OutputStream; import java.util.List; @@ -36,7 +36,7 @@ import javax.xml.namespace.QName; -import static io.ballerina.runtime.internal.ValueUtils.getTypedescValue; +import static io.ballerina.runtime.internal.utils.ValueUtils.getTypedescValue; /** * {@code BXML} represents an XML in Ballerina. An XML could be one of: diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BallerinaXmlSerializer.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/BallerinaXmlSerializer.java similarity index 99% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BallerinaXmlSerializer.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/BallerinaXmlSerializer.java index cdce109da43a..2003aea3e180 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/BallerinaXmlSerializer.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/BallerinaXmlSerializer.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.xml; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BXml; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TableOmDataSource.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/TableOmDataSource.java similarity index 98% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TableOmDataSource.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/TableOmDataSource.java index 0178af2e19b5..aa8fe2fd8a75 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/TableOmDataSource.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/TableOmDataSource.java @@ -15,12 +15,12 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.xml; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.Field; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BArray; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/XmlFactory.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/XmlFactory.java similarity index 99% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/XmlFactory.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/XmlFactory.java index 096f3c8f40c6..54d02df83796 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/XmlFactory.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/XmlFactory.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.xml; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.types.XmlNodeType; @@ -25,6 +25,7 @@ import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BXml; import io.ballerina.runtime.api.values.BXmlQName; +import io.ballerina.runtime.internal.TypeChecker; import io.ballerina.runtime.internal.values.TableValueImpl; import io.ballerina.runtime.internal.values.XmlComment; import io.ballerina.runtime.internal.values.XmlItem; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/XmlTreeBuilder.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/XmlTreeBuilder.java similarity index 99% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/XmlTreeBuilder.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/XmlTreeBuilder.java index 922215fee5c4..7d8786231423 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/XmlTreeBuilder.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/XmlTreeBuilder.java @@ -15,7 +15,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.xml; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.utils.StringUtils; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/XmlValidator.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/XmlValidator.java similarity index 99% rename from bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/XmlValidator.java rename to bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/XmlValidator.java index 0d9e69977bd8..99f7b117ddbb 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/XmlValidator.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/internal/xml/XmlValidator.java @@ -14,7 +14,7 @@ * specific language governing permissions and limitations * under the License. */ -package io.ballerina.runtime.internal; +package io.ballerina.runtime.internal.xml; import io.ballerina.runtime.api.creators.ErrorCreator; import io.ballerina.runtime.api.utils.StringUtils; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/ObserveUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/ObserveUtils.java index 759bf3f0210b..685add2c9219 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/ObserveUtils.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/ObserveUtils.java @@ -19,8 +19,8 @@ import io.ballerina.runtime.api.Environment; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.types.ObjectType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.utils.TypeUtils; import io.ballerina.runtime.api.values.BObject; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/tracer/BSpan.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/tracer/BSpan.java index 8350ce227bb4..1b9ecc424ceb 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/tracer/BSpan.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/observability/tracer/BSpan.java @@ -17,10 +17,10 @@ */ package io.ballerina.runtime.observability.tracer; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.utils.StringUtils; import io.ballerina.runtime.api.values.BMap; import io.ballerina.runtime.api.values.BMapInitialValueEntry; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionConstants.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionConstants.java index e8cfd5af24ac..d5bc81e01c54 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionConstants.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionConstants.java @@ -71,6 +71,7 @@ public final class TransactionConstants { public static final String ANN_NAME_TRX_PARTICIPANT_CONFIG = "Participant"; public static final String TIMESTAMP_OBJECT_VALUE_FIELD = "timeValue"; + public static final int DEFAULT_TRX_AUTO_COMMIT_TIMEOUT = 120; public static final int DEFAULT_TRX_CLEANUP_TIMEOUT = 600; diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionResourceManager.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionResourceManager.java index aaa870d8298e..dc44d816da2c 100644 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionResourceManager.java +++ b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionResourceManager.java @@ -18,10 +18,9 @@ package io.ballerina.runtime.transactions; import com.atomikos.icatch.jta.UserTransactionManager; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.async.StrandMetadata; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BFunctionPointer; import io.ballerina.runtime.api.values.BString; @@ -29,7 +28,7 @@ import io.ballerina.runtime.internal.configurable.VariableKey; import io.ballerina.runtime.internal.scheduling.Scheduler; import io.ballerina.runtime.internal.scheduling.Strand; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -59,12 +58,9 @@ import javax.transaction.xa.XAResource; import javax.transaction.xa.Xid; -import static io.ballerina.runtime.api.constants.RuntimeConstants.BALLERINA_BUILTIN_PKG_PREFIX; import static io.ballerina.runtime.transactions.TransactionConstants.DEFAULT_TRX_AUTO_COMMIT_TIMEOUT; import static io.ballerina.runtime.transactions.TransactionConstants.DEFAULT_TRX_CLEANUP_TIMEOUT; import static io.ballerina.runtime.transactions.TransactionConstants.TRANSACTION_PACKAGE_ID; -import static io.ballerina.runtime.transactions.TransactionConstants.TRANSACTION_PACKAGE_NAME; -import static io.ballerina.runtime.transactions.TransactionConstants.TRANSACTION_PACKAGE_VERSION; import static javax.transaction.xa.XAResource.TMFAIL; import static javax.transaction.xa.XAResource.TMNOFLAGS; import static javax.transaction.xa.XAResource.TMSUCCESS; @@ -78,13 +74,6 @@ public class TransactionResourceManager { private static TransactionResourceManager transactionResourceManager = null; private static UserTransactionManager userTransactionManager = null; - - private static final StrandMetadata COMMIT_METADATA = new StrandMetadata(BALLERINA_BUILTIN_PKG_PREFIX, - TRANSACTION_PACKAGE_NAME, - TRANSACTION_PACKAGE_VERSION, "onCommit"); - private static final StrandMetadata ROLLBACK_METADATA = new StrandMetadata(BALLERINA_BUILTIN_PKG_PREFIX, - TRANSACTION_PACKAGE_NAME, - TRANSACTION_PACKAGE_VERSION, "onRollback"); private static final String ATOMIKOS_LOG_BASE_PROPERTY = "com.atomikos.icatch.log_base_dir"; private static final String ATOMIKOS_LOG_NAME_PROPERTY = "com.atomikos.icatch.log_base_name"; private static final String ATOMIKOS_REGISTERED_PROPERTY = "com.atomikos.icatch.registered"; @@ -96,8 +85,8 @@ public class TransactionResourceManager { private Map trxRegistry; private Map xidRegistry; - private final Map>> committedFuncRegistry = new HashMap<>(); - private final Map>> abortedFuncRegistry = new HashMap<>(); + private final Map> committedFuncRegistry = new HashMap<>();; + private final Map> abortedFuncRegistry = new HashMap<>();; private final Set failedResourceParticipantSet = new ConcurrentSkipListSet<>(); private final Set failedLocalParticipantSet = new ConcurrentSkipListSet<>(); @@ -254,7 +243,7 @@ public void register(String transactionId, String transactionBlockId, BallerinaT * @param transactionBlockId the block id of the transaction * @param fpValue the function pointer for the committed function */ - public void registerCommittedFunction(String transactionBlockId, BFunctionPointer fpValue) { + public void registerCommittedFunction(String transactionBlockId, BFunctionPointer fpValue) { if (fpValue != null) { committedFuncRegistry.computeIfAbsent(transactionBlockId, list -> new ArrayList<>()).add(fpValue); } @@ -266,7 +255,7 @@ public void registerCommittedFunction(String transactionBlockId, BFunctionPointe * @param transactionBlockId the block id of the transaction * @param fpValue the function pointer for the aborted function */ - public void registerAbortedFunction(String transactionBlockId, BFunctionPointer fpValue) { + public void registerAbortedFunction(String transactionBlockId, BFunctionPointer fpValue) { if (fpValue != null) { abortedFuncRegistry.computeIfAbsent(transactionBlockId, list -> new ArrayList<>()).add(fpValue); } @@ -527,7 +516,7 @@ public void notifyTransactionAbort(String transactionBlockId) { * @return Array of rollback handlers */ public BArray getRegisteredRollbackHandlerList() { - List> abortFunctions = + List abortFunctions = abortedFuncRegistry.get(Scheduler.getStrand().currentTrxContext.getGlobalTransactionId()); if (abortFunctions != null && !abortFunctions.isEmpty()) { Collections.reverse(abortFunctions); @@ -543,7 +532,7 @@ public BArray getRegisteredRollbackHandlerList() { * @return Array of commit handlers */ public BArray getRegisteredCommitHandlerList() { - List> commitFunctions = + List commitFunctions = committedFuncRegistry.get(Scheduler.getStrand().currentTrxContext.getGlobalTransactionId()); if (commitFunctions != null && !commitFunctions.isEmpty()) { Collections.reverse(commitFunctions); diff --git a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionUtils.java b/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionUtils.java deleted file mode 100644 index 33b0f88edcdc..000000000000 --- a/bvm/ballerina-runtime/src/main/java/io/ballerina/runtime/transactions/TransactionUtils.java +++ /dev/null @@ -1,135 +0,0 @@ -/* -* Copyright (c) 2019, 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. -*/ -package io.ballerina.runtime.transactions; - -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.async.Callback; -import io.ballerina.runtime.api.async.StrandMetadata; -import io.ballerina.runtime.api.creators.ErrorCreator; -import io.ballerina.runtime.api.utils.StringUtils; -import io.ballerina.runtime.api.values.BError; -import io.ballerina.runtime.internal.scheduling.Scheduler; -import io.ballerina.runtime.internal.scheduling.Strand; -import io.ballerina.runtime.internal.values.FutureValue; -import io.ballerina.runtime.internal.values.MapValue; -import io.ballerina.runtime.internal.values.ObjectValue; - -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.concurrent.CountDownLatch; -import java.util.function.Function; - -import static io.ballerina.runtime.api.constants.RuntimeConstants.BALLERINA_BUILTIN_PKG_PREFIX; -import static io.ballerina.runtime.transactions.TransactionConstants.COORDINATOR_ABORT_TRANSACTION; -import static io.ballerina.runtime.transactions.TransactionConstants.TRANSACTION_BLOCK_CLASS_NAME; -import static io.ballerina.runtime.transactions.TransactionConstants.TRANSACTION_PACKAGE_FQN; -import static io.ballerina.runtime.transactions.TransactionConstants.TRANSACTION_PACKAGE_NAME; -import static io.ballerina.runtime.transactions.TransactionConstants.TRANSACTION_PACKAGE_VERSION; - -/** - * Utility methods used in transaction handling. - * - * @since 1.0 - */ -public final class TransactionUtils { - - private static final StrandMetadata TRX_METADATA = new StrandMetadata(BALLERINA_BUILTIN_PKG_PREFIX, - TRANSACTION_PACKAGE_NAME, - TRANSACTION_PACKAGE_VERSION, "onAbort"); - - private TransactionUtils() { - } - - public static void notifyTransactionAbort(Strand strand, String globalTransactionId, String transactionBlockId) { - executeFunction(strand.scheduler, TransactionUtils.class.getClassLoader(), TRANSACTION_PACKAGE_FQN, - TRANSACTION_BLOCK_CLASS_NAME, COORDINATOR_ABORT_TRANSACTION, globalTransactionId, - TRX_METADATA, globalTransactionId, transactionBlockId); - } - - /** - * This method will execute Ballerina util function blocking manner. - * - * @param scheduler current scheduler - * @param classLoader normal classLoader - * @param packageName packageName - * @param className which the function resides/ or file name - * @param methodName to be invokable unit - * @param strandName name for newly creating strand which is used to execute the function pointer. - * @param metaData meta data of new strand. - * @param paramValues to be passed to invokable unit - * @return return values - */ - public static Object executeFunction(Scheduler scheduler, ClassLoader classLoader, String packageName, - String className, String methodName, String strandName, - StrandMetadata metaData, Object... paramValues) { - try { - Class clazz = classLoader.loadClass(packageName + "." + className); - int paramCount = paramValues.length + 1; - Class[] jvmParamTypes = new Class[paramCount]; - Object[] jvmArgs = new Object[paramCount]; - jvmParamTypes[0] = Strand.class; - jvmArgs[0] = scheduler; - for (int i = 0, j = 1; i < paramValues.length; i++) { - jvmArgs[j] = paramValues[i]; - jvmParamTypes[j++] = getJvmType(paramValues[i]); - } - Method method = clazz.getDeclaredMethod(methodName, jvmParamTypes); - Function func = args -> { - try { - return method.invoke(null, args); - } catch (IllegalAccessException | InvocationTargetException e) { - throw ErrorCreator.createError(StringUtils.fromString( - methodName + " function invocation failed: " + e.getMessage())); - } - }; - CountDownLatch completeFunction = new CountDownLatch(1); - FutureValue futureValue = scheduler.schedule(jvmArgs, func, null, new Callback() { - @Override - public void notifySuccess(Object result) { - completeFunction.countDown(); - } - - @Override - public void notifyFailure(BError error) { - completeFunction.countDown(); - } - }, new HashMap<>(), PredefinedTypes.TYPE_ANY, strandName, metaData); - completeFunction.await(); - return futureValue.result; - } catch (NoSuchMethodException | ClassNotFoundException | InterruptedException e) { - throw ErrorCreator.createError(StringUtils.fromString("invocation failed: " + e.getMessage())); - } - } - - private static Class getJvmType(Object paramValue) { - if (paramValue instanceof MapValue) { - return MapValue.class; - } else if (paramValue instanceof ObjectValue) { - return ObjectValue.class; - } else if (paramValue instanceof Boolean) { - return boolean.class; - } else if (paramValue instanceof String) { - return String.class; - } else { - // This is done temporarily, until blocks are added here for all possible cases. - throw new RuntimeException("unknown param type: " + paramValue.getClass()); - } - } - -} diff --git a/bvm/ballerina-runtime/src/main/java/module-info.java b/bvm/ballerina-runtime/src/main/java/module-info.java index 32a43bd94043..d09fee04a70a 100644 --- a/bvm/ballerina-runtime/src/main/java/module-info.java +++ b/bvm/ballerina-runtime/src/main/java/module-info.java @@ -1,5 +1,4 @@ module io.ballerina.runtime { - uses io.ballerina.runtime.api.launch.LaunchListener; requires java.xml; requires org.apache.commons.text; requires axiom.api; @@ -18,14 +17,14 @@ requires java.naming; requires io.ballerina.identifier; requires jdk.unsupported; + requires jdk.management; // API exports exports io.ballerina.runtime.api; - exports io.ballerina.runtime.api.async; + exports io.ballerina.runtime.api.concurrent; exports io.ballerina.runtime.api.constants; exports io.ballerina.runtime.api.creators; exports io.ballerina.runtime.api.flags; - exports io.ballerina.runtime.api.launch; exports io.ballerina.runtime.api.types; exports io.ballerina.runtime.api.utils; exports io.ballerina.runtime.api.values; @@ -38,39 +37,29 @@ exports io.ballerina.runtime.transactions; // export only for Langlib , Cli and Testerina - exports io.ballerina.runtime.internal to io.ballerina.testerina.core, io.ballerina.testerina.runtime, - io.ballerina.lang, io.ballerina.lang.map, io.ballerina.lang.test, io.ballerina.lang.array, - io.ballerina.lang.table, io.ballerina.lang.value, io.ballerina.lang.xml, ballerina.debug.adapter.core, - io.ballerina.cli, io.ballerina.lang.integer, io.ballerina.lang.bool, io.ballerina.lang.decimal, - io.ballerina.lang.floatingpoint, io.ballerina.lang.internal, io.ballerina.lang.function, - io.ballerina.lang.regexp, io.ballerina.runtime.profiler; exports io.ballerina.runtime.internal.commons to io.ballerina.lang.value; exports io.ballerina.runtime.internal.launch to io.ballerina.testerina.runtime, ballerina.test.listener, io.ballerina.cli, org.ballerinalang.debugadapter.runtime; - exports io.ballerina.runtime.internal.scheduling to io.ballerina.java, - io.ballerina.lang.array, io.ballerina.lang.error, io.ballerina.lang.internal, io.ballerina.lang.map, - io.ballerina.lang.table, io.ballerina.lang.transaction, io.ballerina.lang.value, io.ballerina.lang.xml, - io.ballerina.testerina.core, io.ballerina.testerina.runtime, io.ballerina.shell, - org.ballerinalang.debugadapter.runtime, io.ballerina.lang.function, io.ballerina.runtime.profiler; - exports io.ballerina.runtime.internal.util to io.ballerina.testerina.runtime, io.ballerina.lang, - io.ballerina.lang.integer, io.ballerina.lang.floatingpoint, io.ballerina.lang.array, - io.ballerina.lang.table, io.ballerina.java, io.ballerina.lang.map, io.ballerina.lang.string, - io.ballerina.lang.xml, io.ballerina.lang.bool, io.ballerina.lang.error, io.ballerina.lang.internal, - io.ballerina.lang.value, io.ballerina.cli; exports io.ballerina.runtime.internal.errors to io.ballerina.lang.value, io.ballerina.lang.integer, io.ballerina.java, io.ballerina.lang.internal, io.ballerina.lang.array, io.ballerina.lang.bool, io.ballerina.lang.floatingpoint, io.ballerina.lang.map, io.ballerina.lang.string, io.ballerina.lang.table, io.ballerina.lang.xml, io.ballerina.testerina.core, io.ballerina.cli, io.ballerina.lang.decimal, org.ballerinalang.debugadapter.runtime, io.ballerina.lang.function, io.ballerina.lang.regexp; - exports io.ballerina.runtime.internal.values to io.ballerina.testerina.core, io.ballerina.testerina.runtime, - io.ballerina.lang.xml, org.ballerinalang.debugadapter.runtime, io.ballerina.lang.query, - io.ballerina.lang.function, io.ballerina.lang.regexp, io.ballerina.lang.value, io.ballerina.lang.internal, io.ballerina.lang.array; exports io.ballerina.runtime.internal.configurable to io.ballerina.lang.internal; exports io.ballerina.runtime.internal.types to io.ballerina.lang.typedesc, io.ballerina.testerina.runtime, - org.ballerinalang.debugadapter.runtime, io.ballerina.lang.function, io.ballerina.lang.regexp, io.ballerina.testerina.core; + org.ballerinalang.debugadapter.runtime, io.ballerina.lang.function, io.ballerina.lang.regexp, io.ballerina.testerina.core, + io.ballerina.runtime.profiler; exports io.ballerina.runtime.observability.metrics.noop; exports io.ballerina.runtime.observability.tracer.noop; exports io.ballerina.runtime.internal.regexp; exports io.ballerina.runtime.internal.configurable.providers to org.ballerinalang.debugadapter.runtime; + exports io.ballerina.runtime.internal.scheduling to ballerina.debug.adapter.core, io.ballerina.cli, io.ballerina.cli.utils, io.ballerina.java, io.ballerina.lang, io.ballerina.lang.array, io.ballerina.lang.bool, io.ballerina.lang.decimal, io.ballerina.lang.error, io.ballerina.lang.floatingpoint, io.ballerina.lang.function, io.ballerina.lang.integer, io.ballerina.lang.internal, io.ballerina.lang.map, io.ballerina.lang.regexp, io.ballerina.lang.table, io.ballerina.lang.test, io.ballerina.lang.transaction, io.ballerina.lang.value, io.ballerina.lang.xml, io.ballerina.log.api, io.ballerina.runtime.profiler, io.ballerina.shell, io.ballerina.testerina.core, io.ballerina.testerina.runtime, org.ballerinalang.debugadapter.runtime; + exports io.ballerina.runtime.internal.json to ballerina.debug.adapter.core, io.ballerina.cli, io.ballerina.lang, io.ballerina.lang.array, io.ballerina.lang.bool, io.ballerina.lang.decimal, io.ballerina.lang.floatingpoint, io.ballerina.lang.function, io.ballerina.lang.integer, io.ballerina.lang.internal, io.ballerina.lang.map, io.ballerina.lang.regexp, io.ballerina.lang.table, io.ballerina.lang.test, io.ballerina.lang.value, io.ballerina.lang.xml, io.ballerina.runtime.profiler, io.ballerina.shell, io.ballerina.testerina.core, io.ballerina.testerina.runtime, org.ballerinalang.debugadapter.runtime; + exports io.ballerina.runtime.internal.utils to ballerina.debug.adapter.core, io.ballerina.cli, io.ballerina.java, io.ballerina.lang, io.ballerina.lang.array, io.ballerina.lang.bool, io.ballerina.lang.decimal, io.ballerina.lang.error, io.ballerina.lang.floatingpoint, io.ballerina.lang.function, io.ballerina.lang.integer, io.ballerina.lang.internal, io.ballerina.lang.map, io.ballerina.lang.regexp, io.ballerina.lang.string, io.ballerina.lang.table, io.ballerina.lang.test, io.ballerina.lang.value, io.ballerina.lang.xml, io.ballerina.runtime.profiler, io.ballerina.shell, io.ballerina.testerina.core, io.ballerina.testerina.runtime, org.ballerinalang.debugadapter.runtime; + exports io.ballerina.runtime.internal.xml to ballerina.debug.adapter.core, io.ballerina.cli, io.ballerina.lang, io.ballerina.lang.array, io.ballerina.lang.bool, io.ballerina.lang.decimal, io.ballerina.lang.floatingpoint, io.ballerina.lang.function, io.ballerina.lang.integer, io.ballerina.lang.internal, io.ballerina.lang.map, io.ballerina.lang.regexp, io.ballerina.lang.table, io.ballerina.lang.test, io.ballerina.lang.value, io.ballerina.lang.xml, io.ballerina.runtime.profiler, io.ballerina.shell, io.ballerina.testerina.core, io.ballerina.testerina.runtime, org.ballerinalang.debugadapter.runtime; + exports io.ballerina.runtime.internal.values to ballerina.debug.adapter.core, io.ballerina.cli, io.ballerina.lang, io.ballerina.lang.array, io.ballerina.lang.bool, io.ballerina.lang.decimal, io.ballerina.lang.floatingpoint, io.ballerina.lang.function, io.ballerina.lang.integer, io.ballerina.lang.internal, io.ballerina.lang.map, io.ballerina.lang.query, io.ballerina.lang.regexp, io.ballerina.lang.table, io.ballerina.lang.test, io.ballerina.lang.value, io.ballerina.lang.xml, io.ballerina.runtime.profiler, io.ballerina.shell, io.ballerina.testerina.core, io.ballerina.testerina.runtime, org.ballerinalang.debugadapter.runtime; + exports io.ballerina.runtime.internal to ballerina.debug.adapter.core, io.ballerina.cli, io.ballerina.cli.utils, io.ballerina.java, io.ballerina.lang, io.ballerina.lang.array, io.ballerina.lang.bool, io.ballerina.lang.decimal, io.ballerina.lang.error, io.ballerina.lang.floatingpoint, io.ballerina.lang.function, io.ballerina.lang.integer, io.ballerina.lang.internal, io.ballerina.lang.map, io.ballerina.lang.regexp, io.ballerina.lang.table, io.ballerina.lang.test, io.ballerina.lang.transaction, io.ballerina.lang.value, io.ballerina.lang.xml, io.ballerina.log.api, io.ballerina.runtime.profiler, io.ballerina.shell, io.ballerina.testerina.core, io.ballerina.testerina.runtime, org.ballerinalang.debugadapter.runtime; + exports io.ballerina.runtime.api.repository; + exports io.ballerina.runtime.internal.repository to ballerina.debug.adapter.core, io.ballerina.cli, io.ballerina.cli.utils, io.ballerina.java, io.ballerina.lang, io.ballerina.lang.array, io.ballerina.lang.bool, io.ballerina.lang.decimal, io.ballerina.lang.error, io.ballerina.lang.floatingpoint, io.ballerina.lang.function, io.ballerina.lang.integer, io.ballerina.lang.internal, io.ballerina.lang.map, io.ballerina.lang.regexp, io.ballerina.lang.table, io.ballerina.lang.test, io.ballerina.lang.transaction, io.ballerina.lang.value, io.ballerina.lang.xml, io.ballerina.log.api, io.ballerina.runtime.profiler, io.ballerina.shell, io.ballerina.testerina.core, io.ballerina.testerina.runtime, org.ballerinalang.debugadapter.runtime; } diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/RuntimeUtilTests.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/RuntimeUtilTests.java index 2d862f8909be..512f180cf4b9 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/RuntimeUtilTests.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/RuntimeUtilTests.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.test; -import io.ballerina.runtime.internal.util.CompatibilityChecker; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.CompatibilityChecker; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/TestUtils.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/TestUtils.java index d215c5470de0..236871517167 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/TestUtils.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/TestUtils.java @@ -18,11 +18,11 @@ package io.ballerina.runtime.test; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.internal.configurable.VariableKey; import io.ballerina.runtime.internal.types.BIntersectionType; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import java.nio.file.Path; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/api/IntersectionTypeApiTests.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/api/IntersectionTypeApiTests.java index 4c6897c19065..60c9d2cc2f7a 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/api/IntersectionTypeApiTests.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/api/IntersectionTypeApiTests.java @@ -19,13 +19,13 @@ package io.ballerina.runtime.test.api; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; -import io.ballerina.runtime.api.TypeTags; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.ErrorType; import io.ballerina.runtime.api.types.IntersectionType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; +import io.ballerina.runtime.api.types.TypeTags; import io.ballerina.runtime.internal.types.BIntersectionType; import io.ballerina.runtime.internal.types.BType; import io.ballerina.runtime.internal.values.ReadOnlyUtils; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/cli/OperandTest.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/cli/OperandTest.java index ccc16d1a27d4..bbc96040f882 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/cli/OperandTest.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/cli/OperandTest.java @@ -18,8 +18,8 @@ package io.ballerina.runtime.test.cli; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BDecimal; import io.ballerina.runtime.api.values.BError; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/CliProviderTest.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/CliProviderTest.java index 71a55055055e..30677030c234 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/CliProviderTest.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/CliProviderTest.java @@ -19,10 +19,10 @@ package io.ballerina.runtime.test.config; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.FiniteType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.utils.StringUtils; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/ConfigTest.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/ConfigTest.java index 9807d9640e7e..582b2e300e5d 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/ConfigTest.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/ConfigTest.java @@ -19,12 +19,12 @@ package io.ballerina.runtime.test.config; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.flags.SymbolFlags; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.Field; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.types.TableType; import io.ballerina.runtime.api.types.TupleType; @@ -53,8 +53,8 @@ import java.util.Map; import java.util.Set; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANYDATA; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_STRING; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ANYDATA; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_STRING; import static io.ballerina.runtime.test.TestUtils.getConfigPath; import static io.ballerina.runtime.test.TestUtils.getConfigPathForNegativeCases; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/EnvProviderTest.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/EnvProviderTest.java index 4f8b57d9034f..72427ac81021 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/EnvProviderTest.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/EnvProviderTest.java @@ -17,10 +17,10 @@ package io.ballerina.runtime.test.config; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.FiniteType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.utils.StringUtils; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/TomlProviderTest.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/TomlProviderTest.java index 3ab6dbf9311c..8c4559c5a0dd 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/TomlProviderTest.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/TomlProviderTest.java @@ -19,13 +19,13 @@ package io.ballerina.runtime.test.config; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.ArrayType; import io.ballerina.runtime.api.types.FiniteType; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.TupleType; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.utils.StringUtils; @@ -53,12 +53,12 @@ import java.util.Set; import java.util.function.Function; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANYDATA; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_BYTE; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_DECIMAL; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_FLOAT; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_INT; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_STRING; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ANYDATA; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_BYTE; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_DECIMAL; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_FLOAT; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_INT; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_STRING; import static io.ballerina.runtime.api.utils.StringUtils.fromString; import static io.ballerina.runtime.test.TestUtils.getConfigPath; import static io.ballerina.runtime.test.TestUtils.getIntersectionType; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/CliProviderNegativeTest.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/CliProviderNegativeTest.java index 9e6df0f45410..6ebb29f76e23 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/CliProviderNegativeTest.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/CliProviderNegativeTest.java @@ -19,12 +19,12 @@ package io.ballerina.runtime.test.config.negative; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.FiniteType; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.utils.StringUtils; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/ConfigNegativeTest.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/ConfigNegativeTest.java index a3a2fc0cd202..cef5471d541b 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/ConfigNegativeTest.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/ConfigNegativeTest.java @@ -19,9 +19,9 @@ package io.ballerina.runtime.test.config.negative; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.internal.configurable.ConfigResolver; import io.ballerina.runtime.internal.configurable.VariableKey; @@ -42,7 +42,7 @@ import java.util.Map; import java.util.Set; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_STRING; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_STRING; import static io.ballerina.runtime.test.TestUtils.getConfigPathForNegativeCases; /** diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/EnvProviderNegativeTest.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/EnvProviderNegativeTest.java index 46aa7e3fbfa0..54cd0db505ff 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/EnvProviderNegativeTest.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/EnvProviderNegativeTest.java @@ -17,12 +17,12 @@ package io.ballerina.runtime.test.config.negative; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.types.FiniteType; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.Type; import io.ballerina.runtime.api.types.UnionType; import io.ballerina.runtime.api.values.BDecimal; diff --git a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/TomlProviderNegativeTest.java b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/TomlProviderNegativeTest.java index 253b87ce7efb..a4d9fd911b17 100644 --- a/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/TomlProviderNegativeTest.java +++ b/bvm/ballerina-runtime/src/test/java/io/ballerina/runtime/test/config/negative/TomlProviderNegativeTest.java @@ -19,7 +19,6 @@ package io.ballerina.runtime.test.config.negative; import io.ballerina.runtime.api.Module; -import io.ballerina.runtime.api.PredefinedTypes; import io.ballerina.runtime.api.creators.TypeCreator; import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.flags.SymbolFlags; @@ -28,6 +27,7 @@ import io.ballerina.runtime.api.types.FiniteType; import io.ballerina.runtime.api.types.IntersectionType; import io.ballerina.runtime.api.types.MapType; +import io.ballerina.runtime.api.types.PredefinedTypes; import io.ballerina.runtime.api.types.RecordType; import io.ballerina.runtime.api.types.TableType; import io.ballerina.runtime.api.types.TupleType; @@ -50,7 +50,7 @@ import java.util.Map; import java.util.Set; -import static io.ballerina.runtime.api.PredefinedTypes.TYPE_ANYDATA; +import static io.ballerina.runtime.api.types.PredefinedTypes.TYPE_ANYDATA; import static io.ballerina.runtime.api.utils.StringUtils.fromString; import static io.ballerina.runtime.test.TestUtils.getConfigPath; import static io.ballerina.runtime.test.TestUtils.getConfigPathForNegativeCases; diff --git a/cli/ballerina-cli/spotbugs-exclude.xml b/cli/ballerina-cli/spotbugs-exclude.xml index 2984f3595788..2e9430172f44 100644 --- a/cli/ballerina-cli/spotbugs-exclude.xml +++ b/cli/ballerina-cli/spotbugs-exclude.xml @@ -98,4 +98,8 @@ + + + + diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/CommandUtil.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/CommandUtil.java index 7e2025aa2346..4612aa39de6c 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/CommandUtil.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/CommandUtil.java @@ -36,6 +36,7 @@ import io.ballerina.projects.Settings; import io.ballerina.projects.bala.BalaProject; import io.ballerina.projects.internal.bala.BalToolJson; +import io.ballerina.projects.internal.bala.BalaJson; import io.ballerina.projects.internal.bala.DependencyGraphJson; import io.ballerina.projects.internal.bala.ModuleDependency; import io.ballerina.projects.internal.bala.PackageJson; @@ -81,6 +82,7 @@ import java.util.stream.Stream; import static io.ballerina.cli.launcher.LauncherUtils.createLauncherException; +import static io.ballerina.projects.util.ProjectConstants.BALA_JSON; import static io.ballerina.projects.util.ProjectConstants.BAL_TOOL_JSON; import static io.ballerina.projects.util.ProjectConstants.BAL_TOOL_TOML; import static io.ballerina.projects.util.ProjectConstants.DEPENDENCIES_TOML; @@ -210,8 +212,10 @@ private static void addModules(Path balaPath, Path projectPath, String packageNa Gson gson = new Gson(); Path packageJsonPath = balaPath.resolve(PACKAGE_JSON); Path dependencyGraphJsonPath = balaPath.resolve(DEPENDENCY_GRAPH_JSON); - Path balToolJsonPath = balaPath.resolve(TOOL_DIR).resolve(ProjectConstants.BAL_TOOL_JSON); + Path balToolJsonPath = balaPath.resolve(TOOL_DIR).resolve(BAL_TOOL_JSON); PackageJson templatePackageJson = null; + BalaJson templateBalaJson = null; + Path balaJsonPath = balaPath.resolve(BALA_JSON); DependencyGraphJson templateDependencyGraphJson = null; BalToolJson templateBalToolJson = null; @@ -226,6 +230,17 @@ private static void addModules(Path balaPath, Path projectPath, String packageNa getRuntime().exit(1); } + try (InputStream inputStream = new FileInputStream(String.valueOf(balaJsonPath))) { + Reader fileReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + templateBalaJson = gson.fromJson(fileReader, BalaJson.class); + } catch (IOException e) { + printError(errStream, + "Error while reading the bala.json file: " + e.getMessage(), + null, + false); + getRuntime().exit(1); + } + if (dependencyGraphJsonPath.toFile().exists()) { try (InputStream inputStream = new FileInputStream(String.valueOf(dependencyGraphJsonPath))) { Reader fileReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); @@ -261,7 +276,7 @@ private static void addModules(Path balaPath, Path projectPath, String packageNa Path ballerinaToml = projectPath.resolve(ProjectConstants.BALLERINA_TOML); Files.createDirectories(projectPath); Files.createFile(ballerinaToml); - writeBallerinaToml(ballerinaToml, templatePackageJson, packageName, platform); + writeBallerinaToml(ballerinaToml, templatePackageJson, templateBalaJson, packageName, platform); if (dependencyGraphJsonPath.toFile().exists()) { // Create Dependencies.toml @@ -278,12 +293,15 @@ private static void addModules(Path balaPath, Path projectPath, String packageNa copyToolDependencies(projectPath, balaPath.resolve(TOOL_DIR).resolve(LIBS_DIR)); } - // Create Package.md - Path packageMDFilePath = balaPath.resolve("docs") - .resolve(ProjectConstants.PACKAGE_MD_FILE_NAME); - Path toPackageMdPath = projectPath.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME); - if (Files.exists(packageMDFilePath)) { - Files.copy(packageMDFilePath, toPackageMdPath, StandardCopyOption.REPLACE_EXISTING); + // Create README.md + Path toPackageMdPath = projectPath.resolve(ProjectConstants.README_MD_FILE_NAME); + Path docFilePath = balaPath.resolve("docs").resolve(ProjectConstants.PACKAGE_MD_FILE_NAME); + if (templatePackageJson.getReadme() != null) { + // New bala structure + docFilePath = balaPath.resolve(templatePackageJson.getReadme()); + } + if (Files.exists(docFilePath)) { + Files.copy(docFilePath, toPackageMdPath, StandardCopyOption.REPLACE_EXISTING); } // Create default .gitignore @@ -299,6 +317,16 @@ private static void addModules(Path balaPath, Path projectPath, String packageNa try (Stream pathStream = Files.list(modulesRoot)) { modulesList = pathStream.toList(); } + copyIcon(balaPath, projectPath); + copyPlatformLibraries(balaPath, projectPath); + copyIncludeFiles(balaPath, projectPath, templatePackageJson); + + Map otherModulesMap = new HashMap<>(); + if (templatePackageJson.getModules() != null) { + otherModulesMap = templatePackageJson.getModules().stream().collect( + Collectors.toMap(PackageManifest.Module::name, PackageManifest.Module::readme)); + } + for (Path moduleRoot : modulesList) { Path moduleDir = Optional.of(moduleRoot.getFileName()).get(); Path destDir; @@ -311,17 +339,20 @@ private static void addModules(Path balaPath, Path projectPath, String packageNa } Files.walkFileTree(moduleRoot, new FileUtils.Copy(moduleRoot, destDir, templatePkgName, packageName)); - // Copy Module.md + // Copy README.md Path moduleMdSource = moduleMdDirRoot.resolve(moduleDir).resolve(ProjectConstants.MODULE_MD_FILE_NAME); + + if (templatePackageJson.getReadme() != null) { + String moduleName = Optional.of(moduleRoot.getFileName()).get().toString(); + if (otherModulesMap.containsKey(moduleName)) { + moduleMdSource = balaPath.resolve(otherModulesMap.get(moduleName)); + } + } if (Files.exists(moduleMdSource)) { - Files.copy(moduleMdSource, destDir.resolve(ProjectConstants.MODULE_MD_FILE_NAME), + Files.copy(moduleMdSource, destDir.resolve(ProjectConstants.README_MD_FILE_NAME), StandardCopyOption.REPLACE_EXISTING); } } - - copyIcon(balaPath, projectPath); - copyPlatformLibraries(balaPath, projectPath); - copyIncludeFiles(balaPath, projectPath, templatePackageJson); } private static void copyIcon(Path balaPath, Path projectPath) { @@ -468,7 +499,7 @@ private static void pullPackageFromRemote(String orgName, String packageName, St RepoUtils.getBallerinaVersion(), false); } - public static void writeBallerinaToml(Path balTomlPath, PackageJson packageJson, + public static void writeBallerinaToml(Path balTomlPath, PackageJson packageJson, BalaJson balaJson, String packageName, String platform) throws IOException { @@ -478,16 +509,6 @@ public static void writeBallerinaToml(Path balTomlPath, PackageJson packageJson, Files.writeString(balTomlPath, "\nname = \"" + packageName + "\"", StandardOpenOption.APPEND); Files.writeString(balTomlPath, "\nversion = \"" + packageJson.getVersion() + "\"", StandardOpenOption.APPEND); - List newModuleNames = packageJson.getExport().stream().map(module -> - module.replaceFirst(packageJson.getName(), packageName)).toList(); - - StringJoiner stringJoiner = new StringJoiner(","); - for (String newModuleName : newModuleNames) { - stringJoiner.add("\"" + newModuleName + "\""); - } - - Files.writeString(balTomlPath, "\nexport = [" + stringJoiner + "]" - .replaceFirst(packageJson.getName(), packageName), StandardOpenOption.APPEND); Files.writeString(balTomlPath, "\ndistribution = \"" + packageJson.getBallerinaVersion() + "\"", StandardOpenOption.APPEND); @@ -501,6 +522,31 @@ public static void writeBallerinaToml(Path balTomlPath, PackageJson packageJson, Files.writeString(balTomlPath, "\n\n[build-options]", StandardOpenOption.APPEND); Files.writeString(balTomlPath, "\nobservabilityIncluded = true\n", StandardOpenOption.APPEND); + StringJoiner stringJoiner = new StringJoiner("\n"); + if ("2.0.0".equals(balaJson.getBala_version())) { + List newModuleNames = packageJson.getExport().stream().map(module -> + module.replaceFirst(packageJson.getName(), packageName)).toList(); + + for (String newModuleName : newModuleNames) { + if (newModuleName.equals(packageName)) { + continue; + } + stringJoiner.add("\n[[package.modules]]"); + stringJoiner.add("name = \"" + newModuleName.replaceFirst(packageJson.getName(), packageName) + "\""); + stringJoiner.add("export = true"); + } + } else { + for (PackageManifest.Module module : packageJson.getModules()) { + stringJoiner.add("\n[[package.modules]]"); + stringJoiner.add("name = \"" + module.name().replaceFirst(packageJson.getName(), packageName) + "\""); + stringJoiner.add("export = true"); + } + } + + if (!stringJoiner.toString().isEmpty()) { + Files.writeString(balTomlPath, stringJoiner + "\n", StandardOpenOption.APPEND); + } + JsonArray platformLibraries = packageJson.getPlatformDependencies(); if (platformLibraries == null) { return; @@ -967,9 +1013,10 @@ private static void initLibPackage(Path path, String packageName) throws IOExcep Files.writeString(ballerinaToml, defaultManifest); - // Create Package.md - String packageMd = FileUtils.readFileAsString(NEW_CMD_DEFAULTS + "/Package.md"); - write(path.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME), packageMd.getBytes(StandardCharsets.UTF_8)); + // Create README.md + String packageMd = FileUtils.readFileAsString(NEW_CMD_DEFAULTS + "/" + + ProjectConstants.README_MD_FILE_NAME); + write(path.resolve(ProjectConstants.README_MD_FILE_NAME), packageMd.getBytes(StandardCharsets.UTF_8)); } /** @@ -990,7 +1037,7 @@ private static void initToolPackage(Path path, String packageName) throws IOExce .replace(DIST_VERSION, RepoUtils.getBallerinaShortVersion()); Files.writeString(ballerinaToml, defaultManifest); - Path balToolToml = path.resolve(ProjectConstants.BAL_TOOL_TOML); + Path balToolToml = path.resolve(BAL_TOOL_TOML); Files.createFile(balToolToml); String balToolManifest = FileUtils.readFileAsString(NEW_CMD_DEFAULTS + "/" + "manifest-tool.toml"); @@ -1188,7 +1235,7 @@ static boolean pullDependencyPackages(String orgName, String packageName, String return true; } if (!hasProvidedPlatformDeps(balaProject.currentPackage())) { - JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_17); + JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_21); Collection backendDiagnostics = jBallerinaBackend.diagnosticResult().diagnostics(false); if (!backendDiagnostics.isEmpty()) { printDiagnostics(backendDiagnostics); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/DeprecateCommand.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/DeprecateCommand.java index 0fd0360d1e4c..5dcf47e28795 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/DeprecateCommand.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/DeprecateCommand.java @@ -170,7 +170,7 @@ private void deprecateInCentral(String packageInfo) { settings.getCentral().getReadTimeout(), settings.getCentral().getWriteTimeout(), settings.getCentral().getCallTimeout(), settings.getCentral().getMaxRetries()); client.deprecatePackage(packageValue, deprecationMsg, - JvmTarget.JAVA_17.code(), + JvmTarget.JAVA_21.code(), RepoUtils.getBallerinaVersion(), this.undoFlag); } catch (CentralClientException e) { String errorMessage = e.getMessage(); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PackCommand.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PackCommand.java index ae00426a7e89..c3e5a6b82433 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PackCommand.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PackCommand.java @@ -14,9 +14,12 @@ import io.ballerina.projects.Project; import io.ballerina.projects.ProjectException; import io.ballerina.projects.directory.BuildProject; +import io.ballerina.projects.internal.ProjectDiagnosticErrorCode; import io.ballerina.projects.util.ProjectConstants; +import io.ballerina.projects.util.ProjectUtils; import io.ballerina.toml.semantic.TomlType; import io.ballerina.toml.semantic.ast.TomlTableNode; +import io.ballerina.tools.diagnostics.Diagnostic; import org.wso2.ballerinalang.util.RepoUtils; import picocli.CommandLine; @@ -24,6 +27,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import static io.ballerina.cli.cmd.Constants.PACK_COMMAND; import static io.ballerina.projects.internal.ManifestBuilder.getStringValueFromTomlTableNode; @@ -249,6 +253,12 @@ public void execute() { // Check package files are modified after last build boolean isPackageModified = isProjectUpdated(project); + Optional deprecatedDocWarning = ProjectUtils.getProjectLoadingDiagnostic().stream().filter( + diagnostic -> diagnostic.diagnosticInfo().code().equals( + ProjectDiagnosticErrorCode.DEPRECATED_DOC_FILE.diagnosticId())).findAny(); + + deprecatedDocWarning.ifPresent(this.errStream::println); + TaskExecutor taskExecutor = new TaskExecutor.TaskBuilder() .addTask(new CleanTargetDirTask(isPackageModified, buildOptions.enableCache()), isSingleFileBuild) .addTask(new RunBuildToolsTask(outStream), isSingleFileBuild) diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java index e1c14d6cf94c..cb8a385edf1a 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/cmd/PushCommand.java @@ -192,7 +192,7 @@ public void execute() { if (!FileUtils.getExtension(balaPath).equals("bala")) { throw new ProjectException("file provided is not a bala file: " + balaPath + "."); } - validatePackageMdAndBalToml(balaPath); + validateReadmeAndBalToml(balaPath); pushBalaToCustomRepo(balaPath); return; } @@ -216,7 +216,7 @@ public void execute() { if (!FileUtils.getExtension(balaPath).equals("bala")) { throw new ProjectException("file provided is not a bala file: " + balaPath + "."); } - validatePackageMdAndBalToml(balaPath); + validateReadmeAndBalToml(balaPath); pushBalaToCustomRepo(balaPath, mvnClient); } @@ -243,7 +243,7 @@ public void execute() { if (!FileUtils.getExtension(balaPath).equals("bala")) { throw new ProjectException("file provided is not a bala file: " + balaPath + "."); } - validatePackageMdAndBalToml(balaPath); + validateReadmeAndBalToml(balaPath); pushBalaToRemote(balaPath, client); } } @@ -349,20 +349,29 @@ private static Path validateBalaFile(BuildProject project, Path customBalaPath) + "' in " + ProjectConstants.BALLERINA_TOML + " file. Run 'bal pack' to recompile and generate the bala."); } - validatePackageMdAndBalToml(packageBalaFile); + validateReadmeAndBalToml(packageBalaFile); // bala file path return packageBalaFile; } - private static void validatePackageMdAndBalToml(Path balaPath) { + private static void validateReadmeAndBalToml(Path balaPath) { + ProjectEnvironmentBuilder defaultBuilder = ProjectEnvironmentBuilder.getDefaultBuilder(); + defaultBuilder.addCompilationCacheFactory(TempDirCompilationCache::from); + BalaProject balaProject = BalaProject.loadProject(defaultBuilder, balaPath); + try (ZipInputStream zip = new ZipInputStream(Files.newInputStream(balaPath, StandardOpenOption.READ))) { ZipEntry entry; + String readme; while ((entry = zip.getNextEntry()) != null) { - if (entry.getName().equals( - ProjectConstants.BALA_DOCS_DIR + "/" + ProjectConstants.PACKAGE_MD_FILE_NAME)) { + if (balaProject.currentPackage().manifest().readme() == null) { + readme = ProjectConstants.BALA_DOCS_DIR + "/" + ProjectConstants.PACKAGE_MD_FILE_NAME; + } else { + readme = balaProject.currentPackage().manifest().readme(); + } + if (entry.getName().equals(readme)) { if (entry.getSize() == 0) { - throw new ProjectException(ProjectConstants.PACKAGE_MD_FILE_NAME + " cannot be empty."); + throw new ProjectException("README file cannot be empty."); } return; } @@ -370,7 +379,7 @@ private static void validatePackageMdAndBalToml(Path balaPath) { } catch (IOException e) { throw new ProjectException("error while validating the bala file: " + e.getMessage(), e); } - throw new ProjectException(ProjectConstants.PACKAGE_MD_FILE_NAME + " is missing in bala file:" + balaPath); + throw new ProjectException("README file is missing in the bala file:" + balaPath); } private void pushBalaToCustomRepo(Path balaFilePath) { @@ -485,7 +494,7 @@ private void pushBalaToRemote(Path balaPath, CentralAPIClient client) { authenticate(errStream, getBallerinaCentralCliTokenUrl(), settingsTomlFilePath, client); try { - client.pushPackage(balaPath, org, name, version, JvmTarget.JAVA_17.code(), + client.pushPackage(balaPath, org, name, version, JvmTarget.JAVA_21.code(), RepoUtils.getBallerinaVersion()); } catch (CentralClientException e) { String errorMessage = e.getMessage(); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/launcher/Main.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/launcher/Main.java index 4b0d8a039e21..29d8326b3911 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/launcher/Main.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/launcher/Main.java @@ -20,7 +20,7 @@ import io.ballerina.cli.BLauncherCmd; import io.ballerina.cli.launcher.util.BalToolsUtil; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import org.ballerinalang.compiler.BLangCompilerException; import picocli.CommandLine; diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java index 33df6f367dea..34fd14e66bbc 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CompileTask.java @@ -48,6 +48,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.Set; import static io.ballerina.cli.launcher.LauncherUtils.createLauncherException; @@ -228,16 +229,17 @@ public void execute(Project project) { start = System.currentTimeMillis(); } - String projectLoadingDiagnostic = ProjectUtils.getProjectLoadingDiagnostic(); - if (projectLoadingDiagnostic != null && !projectLoadingDiagnostic.isEmpty()) { - out.println(projectLoadingDiagnostic); - } + Optional projectLoadingDiagnostic = ProjectUtils.getProjectLoadingDiagnostic().stream().filter( + diagnostic -> diagnostic.diagnosticInfo().code().equals( + ProjectDiagnosticErrorCode.DEPRECATED_RESOURCES_STRUCTURE.diagnosticId())).findAny(); + + projectLoadingDiagnostic.ifPresent(out::println); PackageCompilation packageCompilation = project.currentPackage().getCompilation(); if (project.buildOptions().dumpBuildTime()) { BuildTime.getInstance().packageCompilationDuration = System.currentTimeMillis() - start; start = System.currentTimeMillis(); } - JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_17); + JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_21); if (project.buildOptions().dumpBuildTime()) { BuildTime.getInstance().codeGenDuration = System.currentTimeMillis() - start; } diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateBalaTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateBalaTask.java index b9fa48d15348..d2e1e0900239 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateBalaTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateBalaTask.java @@ -66,7 +66,7 @@ public void execute(Project project) { try { PackageCompilation packageCompilation = project.currentPackage().getCompilation(); - jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_17); + jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_21); long start = 0; if (project.buildOptions().dumpBuildTime()) { start = System.currentTimeMillis(); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateExecutableTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateExecutableTask.java index 36bb75e7810d..120ef82426d2 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateExecutableTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateExecutableTask.java @@ -80,7 +80,7 @@ public void execute(Project project) { Path executablePath = getExecutablePath(project, target); try { PackageCompilation pkgCompilation = project.currentPackage().getCompilation(); - JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(pkgCompilation, JvmTarget.JAVA_17); + JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(pkgCompilation, JvmTarget.JAVA_21); long start = 0; if (project.buildOptions().dumpBuildTime()) { start = System.currentTimeMillis(); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateTestExecutableTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateTestExecutableTask.java index 64ab0d001343..5f169cef2be2 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateTestExecutableTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/CreateTestExecutableTask.java @@ -98,7 +98,7 @@ public void execute(Project project) { Target target = getTarget(project); try { PackageCompilation pkgCompilation = project.currentPackage().getCompilation(); - JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(pkgCompilation, JvmTarget.JAVA_17); + JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(pkgCompilation, JvmTarget.JAVA_21); List emitDiagnostics = new ArrayList<>(); Path testCachePath = target.getTestsCachePath(); long start = 0; 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 7940325eb374..d9d9c473036a 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 @@ -161,7 +161,7 @@ public void execute(Project project) { boolean hasTests = false; PackageCompilation packageCompilation = project.currentPackage().getCompilation(); - JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_17); + JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_21); JarResolver jarResolver = jBallerinaBackend.jarResolver(); TestProcessor testProcessor = new TestProcessor(jarResolver); List updatedSingleExecTests; @@ -361,14 +361,15 @@ private int runTestSuiteWithNativeImage(Package currentPackage, Target target, // set name and path - nativeArgs.add("-H:Name=" + NativeUtils.addQuotationMarkToString(packageName)); - nativeArgs.add("-H:Path=" + NativeUtils.convertWinPathToUnixFormat(NativeUtils - .addQuotationMarkToString(nativeTargetPath.toString()))); + nativeArgs.add("-o " + NativeUtils.convertWinPathToUnixFormat(NativeUtils + .addQuotationMarkToString(nativeTargetPath.toString() + "/" + packageName))); // native-image configs + nativeArgs.add("-H:+UnlockExperimentalVMOptions"); nativeArgs.add("-H:ReflectionConfigurationFiles=" + NativeUtils .convertWinPathToUnixFormat(NativeUtils.addQuotationMarkToString( nativeConfigPath.resolve("reflect-config.json").toString()))); + nativeArgs.add("-H:-UnlockExperimentalVMOptions"); nativeArgs.add("--no-fallback"); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/RunTestsTask.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/RunTestsTask.java index 23a77a564242..802e8f7d4c11 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/RunTestsTask.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/task/RunTestsTask.java @@ -176,7 +176,7 @@ public void execute(Project project) { } PackageCompilation packageCompilation = project.currentPackage().getCompilation(); - JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_17); + JBallerinaBackend jBallerinaBackend = JBallerinaBackend.from(packageCompilation, JvmTarget.JAVA_21); JarResolver jarResolver = jBallerinaBackend.jarResolver(); // Only tests in packages are executed so default packages i.e. single bal files which has the package name diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DebugUtils.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DebugUtils.java index 66fc823ad664..34b49cf2f4dd 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DebugUtils.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/DebugUtils.java @@ -14,7 +14,7 @@ public final class DebugUtils { private static final String DEBUG_ARGS_JAVA = "-agentlib:jdwp=transport=dt_socket,server=y,suspend=y"; private static final String JAVA_VERSION_PROP = "java.version"; - private static final String COMPATIBLE_JRE_VERSION = "17"; + private static final String COMPATIBLE_JRE_VERSION = "21"; private DebugUtils() { } diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/NativeUtils.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/NativeUtils.java index c96915ff1c5b..7ed5cd20c891 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/NativeUtils.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/NativeUtils.java @@ -23,7 +23,7 @@ import com.google.gson.reflect.TypeToken; import io.ballerina.projects.Package; import io.ballerina.projects.internal.model.Target; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import org.apache.commons.compress.utils.IOUtils; import org.ballerinalang.test.runtime.entity.MockFunctionReplaceVisitor; import org.ballerinalang.test.runtime.entity.TestSuite; @@ -74,7 +74,7 @@ import static org.ballerinalang.test.runtime.util.TesterinaConstants.DOT_REPLACER; import static org.ballerinalang.test.runtime.util.TesterinaConstants.HYPHEN; import static org.ballerinalang.test.runtime.util.TesterinaConstants.JAR_EXTENSION; -import static org.ballerinalang.test.runtime.util.TesterinaConstants.JAVA_17_DIR; +import static org.ballerinalang.test.runtime.util.TesterinaConstants.JAVA_PLATFORM_DIR; import static org.ballerinalang.test.runtime.util.TesterinaConstants.MOCK_FN_DELIMITER; import static org.ballerinalang.test.runtime.util.TesterinaConstants.MOCK_FUNC_NAME_PREFIX; import static org.ballerinalang.test.runtime.util.TesterinaConstants.MOCK_LEGACY_DELIMITER; @@ -426,7 +426,7 @@ public static void modifyJarForFunctionMock(TestSuite testSuite, Target target, //Load all classes within module jar Map unmodifiedFiles = loadUnmodifiedFilesWithinJar(mainJarPath); String modifiedJarPath = (target.path().resolve(CACHE_DIR).resolve(testSuite.getOrgName()).resolve - (testSuite.getPackageName()).resolve(testSuite.getVersion()).resolve(JAVA_17_DIR)).toString() + (testSuite.getPackageName()).resolve(testSuite.getVersion()).resolve(JAVA_PLATFORM_DIR)).toString() + PATH_SEPARATOR + modifiedJarName; //Dump modified jar dumpJar(modifiedClassDef, unmodifiedFiles, modifiedJarPath); diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/ProjectWatcher.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/ProjectWatcher.java index d3cbd0edae6d..4929cfb5166a 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/ProjectWatcher.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/ProjectWatcher.java @@ -56,7 +56,7 @@ * * @since 2201.10.0 */ -public class ProjectWatcher { +public final class ProjectWatcher { private final WatchService fileWatcher; private final Map watchKeys; private final RunCommand runCommand; diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/RunCommandExecutor.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/RunCommandExecutor.java index 1b3644692ee0..bb8c1eb87520 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/RunCommandExecutor.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/RunCommandExecutor.java @@ -22,7 +22,7 @@ import io.ballerina.cli.launcher.BLauncherException; import io.ballerina.cli.launcher.LauncherUtils; import io.ballerina.cli.launcher.RuntimePanicException; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import org.ballerinalang.compiler.BLangCompilerException; import java.io.PrintStream; diff --git a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/TestUtils.java b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/TestUtils.java index 2ed11d3e6dbc..1b099b7eed8b 100644 --- a/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/TestUtils.java +++ b/cli/ballerina-cli/src/main/java/io/ballerina/cli/utils/TestUtils.java @@ -486,7 +486,7 @@ public static String getClassPath(JBallerinaBackend jBallerinaBackend, Package c List dependencies = getTestDependencyPaths(currentPackage, jarResolver).stream() .filter(Predicate.not(jars::contains)) - .filter(Predicate.not(jarResolver.optimizedJarLibraryPaths::contains)) + .filter(Predicate.not(jarResolver.getOptimizedJarLibraryPaths()::contains)) .toList(); StringJoiner classPath = joinClassPaths(dependencies); diff --git a/cli/ballerina-cli/src/main/resources/cli-help/ballerina-build.help b/cli/ballerina-cli/src/main/resources/cli-help/ballerina-build.help index 6c7accdc1a5a..58f35cba18cd 100755 --- a/cli/ballerina-cli/src/main/resources/cli-help/ballerina-build.help +++ b/cli/ballerina-cli/src/main/resources/cli-help/ballerina-build.help @@ -86,4 +86,4 @@ EXAMPLES $ bal build Build the package with additional GraalVM native image options. - $ bal build --graalvm --graalvm-build-options="--static -H:Name=hello-world" + $ bal build --graalvm --graalvm-build-options="--static --enable-monitoring" diff --git a/cli/ballerina-cli/src/main/resources/cli-help/ballerina-test.help b/cli/ballerina-cli/src/main/resources/cli-help/ballerina-test.help index 5263042e1227..e4e76699c1ca 100755 --- a/cli/ballerina-cli/src/main/resources/cli-help/ballerina-test.help +++ b/cli/ballerina-cli/src/main/resources/cli-help/ballerina-test.help @@ -187,4 +187,4 @@ EXAMPLES $ bal test -Cval1=add -Cval2=10 -Cval3=5 Test the package with additional GraalVM native image options. - $ bal test --graalvm --graalvm-build-options="--static -H:Name=hello-world" + $ bal test --graalvm --graalvm-build-options="--static --enable-monitoring" diff --git a/cli/ballerina-cli/src/main/resources/create_cmd_templates/lib/Module.md b/cli/ballerina-cli/src/main/resources/create_cmd_templates/lib/Module.md deleted file mode 100644 index 8a69f51930aa..000000000000 --- a/cli/ballerina-cli/src/main/resources/create_cmd_templates/lib/Module.md +++ /dev/null @@ -1,6 +0,0 @@ -Prints "Hello, World!" with a main function. -[//]: # (above is the module summary) - -# Module Overview -Provides an overview about the module when generating the API documentations. -For example, refer to https://lib.ballerina.io/ballerina/io/latest diff --git a/cli/ballerina-cli/src/main/resources/new_cmd_defaults/Package.md b/cli/ballerina-cli/src/main/resources/new_cmd_defaults/README.md similarity index 100% rename from cli/ballerina-cli/src/main/resources/new_cmd_defaults/Package.md rename to cli/ballerina-cli/src/main/resources/new_cmd_defaults/README.md diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/BuildCommandTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/BuildCommandTest.java index 331812a62539..65256ca36247 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/BuildCommandTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/BuildCommandTest.java @@ -20,6 +20,7 @@ import io.ballerina.cli.launcher.BLauncherException; import io.ballerina.cli.utils.BuildTime; +import io.ballerina.projects.JvmTarget; import io.ballerina.projects.ProjectEnvironmentBuilder; import io.ballerina.projects.SemanticVersion; import io.ballerina.projects.environment.Environment; @@ -277,7 +278,7 @@ public void testBuildBalProject(Boolean optimizeDependencyCompilation) throws IO Assert.assertTrue(projectPath.resolve("target").resolve("bin").resolve("winery.jar").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0.jar").toFile().exists()); } @@ -294,7 +295,7 @@ public void testCodeGeneratorForSingleFile() throws IOException { public void testCodeGeneratorForBuildProject() throws IOException { Path projectPath = this.testResources.resolve("validApplicationProject"); Path thinJarPath = projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0.jar"); Path execPath = projectPath.resolve("target").resolve("bin").resolve("winery.jar"); String generatedSource = "foo/winery/0/dummyfunc-generated_1.class"; @@ -362,7 +363,7 @@ public void testBuildBalProjectWithJarConflicts() throws IOException { Assert.assertTrue( projectPath.resolve("target").resolve("bin").resolve("conflictProject.jar").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("pramodya") - .resolve("conflictProject").resolve("0.1.7").resolve("java17") + .resolve("conflictProject").resolve("0.1.7").resolve(JvmTarget.JAVA_21.code()) .resolve("pramodya-conflictProject-0.1.7.jar").toFile().exists()); } @@ -411,7 +412,7 @@ public void testBuildJavaBalProject(Boolean optimizeDependencyCompilation) throw Assert.assertTrue(projectPath.resolve("target").resolve("bin").resolve("winery.jar").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0.jar").toFile().exists()); } @@ -427,7 +428,7 @@ public void testBuildBalProjectFromADifferentDirectory(Boolean optimizeDependenc Assert.assertTrue(projectPath.resolve("target").resolve("bin").resolve("winery.jar").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0.jar").toFile().exists()); } @@ -444,7 +445,7 @@ public void testBuildProjectWithTests(Boolean optimizeDependencyCompilation) thr Assert.assertTrue(projectPath.resolve("target").resolve("bin").resolve("winery.jar").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0.jar").toFile().exists()); } @@ -464,11 +465,11 @@ public void testBuildMultiModuleProject(Boolean optimizeDependencyCompilation) t Assert.assertTrue(projectPath.resolve("target").resolve("bin").resolve("winery.jar").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0.jar").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery.storage-0.1.0.jar").toFile().exists()); } @@ -484,10 +485,10 @@ public void testBuildProjectWithDefaultBuildOptions() throws IOException { Assert.assertTrue(projectPath.resolve("target").resolve("bin").resolve("winery.jar").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0.jar").toFile().exists()); Assert.assertFalse(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-testable-0.1.0.jar").toFile().exists()); } @@ -511,11 +512,11 @@ public void testBuildProjectOverrideBuildOptions() throws IOException { Assert.assertTrue(projectPath.resolve("target").resolve("bin").resolve("winery.jar").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0.jar").toFile().exists()); Assert.assertFalse(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0-testable.jar").toFile().exists()); Assert.assertFalse( projectPath.resolve("target").resolve("report").resolve("test_results.json").toFile().exists()); @@ -728,8 +729,9 @@ public void testBuildWithInvalidOrgName() throws IOException { Assert.assertTrue(buildLog.contains("_org/validProjectWithEmptyBallerinaToml:0.1.0")); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("_org") - .resolve("validProjectWithEmptyBallerinaToml").resolve("0.1.0").resolve("java17") - .resolve("_org-validProjectWithEmptyBallerinaToml-0.1.0.jar").toFile().exists()); + .resolve("validProjectWithEmptyBallerinaToml").resolve("0.1.0") + .resolve(JvmTarget.JAVA_21.code()) + .resolve("_org-validProjectWithEmptyBallerinaToml-0.1.0.jar").toFile().exists()); } @Test(description = "tests consistent conflicted jars reporting") @@ -873,7 +875,7 @@ public void testBuildBalProjectWithDumpGraphFlag(Boolean optimizeDependencyCompi Assert.assertEquals(buildLog, getOutput("build-project-with-dump-graph.txt")); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("package_a").resolve("0.1.0").resolve("java17") + .resolve("package_a").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-package_a-0.1.0.jar").toFile().exists()); ProjectUtils.deleteDirectory(projectPath.resolve("target")); @@ -898,7 +900,7 @@ public void testBuildBalProjectWithDumpRawGraphsFlag(Boolean optimizeDependencyC Assert.assertEquals(buildLog, getOutput("build-project-with-dump-raw-graphs.txt")); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("package_a").resolve("0.1.0").resolve("java17") + .resolve("package_a").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-package_a-0.1.0.jar").toFile().exists()); ProjectUtils.deleteDirectory(projectPath.resolve("target")); diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/CommandUtilTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/CommandUtilTest.java index f4be8be0fa56..093e3b9cf8cc 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/CommandUtilTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/CommandUtilTest.java @@ -19,6 +19,7 @@ package io.ballerina.cli.cmd; import com.google.gson.Gson; +import io.ballerina.projects.internal.bala.BalaJson; import io.ballerina.projects.internal.bala.DependencyGraphJson; import io.ballerina.projects.internal.bala.PackageJson; import org.testng.Assert; @@ -58,12 +59,18 @@ public void testWriteBallerinaToml() throws IOException { Reader fileReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); packageJson = new Gson().fromJson(fileReader, PackageJson.class); } + BalaJson balaJson; + try (InputStream inputStream = new FileInputStream( + String.valueOf(COMMAND_UTIL_RESOURCE_DIR.resolve("sample-bala.json")))) { + Reader fileReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8); + balaJson = new Gson().fromJson(fileReader, BalaJson.class); + } // Create empty Ballerina.toml Path ballerinaTomlPath = Files.createFile(COMMAND_UTIL_RESOURCE_DIR.resolve(BALLERINA_TOML)); // Test writeBallerinaToml method - writeBallerinaToml(ballerinaTomlPath, packageJson, "gsheet_new_row_to_github_new_issue", "any"); + writeBallerinaToml(ballerinaTomlPath, packageJson, balaJson, "gsheet_new_row_to_github_new_issue", "any"); Assert.assertEquals(readFileAsString(COMMAND_UTIL_RESOURCE_DIR.resolve(BALLERINA_TOML)), readFileAsString(COMMAND_UTIL_RESOURCE_DIR.resolve("expected-ballerina.toml"))); } diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/DeprecateCommandTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/DeprecateCommandTest.java index 1e0cd82d78cd..6daedd2245eb 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/DeprecateCommandTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/DeprecateCommandTest.java @@ -65,7 +65,7 @@ public void testDeprecationWithInvalidVersion() throws IOException { String actual = buildLog.replace("\r", ""); Assert.assertTrue(actual.contains( "ballerina: error: could not connect to remote repository to find package: mynewdil/deppack:xxx. " + - "reason: package not found: mynewdil/deppack:xxx_java17"), + "reason: package not found: mynewdil/deppack:xxx_java21"), actual); } diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/NewCommandTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/NewCommandTest.java index a25725186fb5..a61c7419760d 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/NewCommandTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/NewCommandTest.java @@ -81,6 +81,7 @@ public void setup() throws IOException { Files.createDirectories(this.tmpDir.resolve("dir1")); Files.createDirectories(this.tmpDir.resolve("dir2/dir1")); + ProjectUtils.clearDiagnostics(); } @AfterClass @@ -574,7 +575,7 @@ public void testNewCommandWithLib(String packagePath) throws IOException { "distribution = \"" + RepoUtils.getBallerinaShortVersion() + "\"" + "\n"; Assert.assertTrue(tomlContent.contains(expectedTomlContent)); - Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))); + Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.README_MD_FILE_NAME))); Assert.assertTrue(Files.exists(packageDir.resolve(packageName + ".bal"))); Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.TEST_DIR_NAME))); @@ -620,7 +621,7 @@ public void testNewCommandWithTool() throws IOException { "[[dependency]]\n"; Assert.assertTrue(toolTomlContent.contains(expectedToolTomlContent)); - Assert.assertTrue(Files.notExists(packageDir.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))); + Assert.assertTrue(Files.notExists(packageDir.resolve(ProjectConstants.README_MD_FILE_NAME))); Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.TOOL_DIR))); Assert.assertTrue(readOutput().contains("Created new package")); @@ -653,7 +654,7 @@ public void testNewCommandWithTool() throws IOException { Assert.assertEquals(packBuildLog.replace("\r", ""), getOutput("pack-tool-template.txt")); Assert.assertTrue( packageDir.resolve("target").resolve("bala") - .resolve("testuserorg-tool_sample-java17-0.1.0.bala").toFile().exists()); + .resolve("testuserorg-tool_sample-java21-0.1.0.bala").toFile().exists()); } @Test(description = "Test new command with invalid project name", dataProvider = "invalidProjectNames") @@ -698,7 +699,6 @@ public void testNewCommandWithToolTemplateCentral() throws IOException { "org = \"testorg\"\n" + "name = \"" + packageName + "\"\n" + "version = \"1.0.0\"\n" + - "export = [\"sample_tool_template\"]\n" + "distribution = \"2201.6.0-SNAPSHOT\"\n\n" + "[build-options]\n" + "observabilityIncluded = true\n"; @@ -713,7 +713,7 @@ public void testNewCommandWithToolTemplateCentral() throws IOException { "path = \"tool/libs/platform-io-1.3.0-java.jar\"\n"; Assert.assertTrue(toolTomlContent.contains(expectedToolTomlContent)); - Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))); + Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.README_MD_FILE_NAME))); Path dependencyPath = packageDir.resolve(TOOL_DIR).resolve("libs") .resolve("platform-io-1.3.0-java.jar"); Assert.assertTrue(Files.exists(dependencyPath)); @@ -742,7 +742,7 @@ public void testNewCommandWithToolTemplateCentral() throws IOException { Assert.assertEquals(packBuildLog.replace("\r", ""), getOutput("pack-central-tool.txt")); Assert.assertTrue( packageDir.resolve("target").resolve("bala") - .resolve("testorg-sample_tool_template-java17-1.0.0.bala").toFile().exists()); + .resolve("testorg-sample_tool_template-java21-1.0.0.bala").toFile().exists()); } @Test(description = "Test new command by pulling a central template with provided platform jars") @@ -761,7 +761,6 @@ public void testNewCommandWithProvidedTemplateCentral() throws IOException { org = "testorg" name = "sample_provided_template" version = "1.0.0" - export = ["sample_provided_template"] distribution = "2201.9.0-SNAPSHOT" [build-options] @@ -799,7 +798,6 @@ public void testNewCommandWithTemplateInLocalCache() throws IOException { org = "admin" name = "sample_pull_local" version = "0.1.5" - export = ["sample_pull_local"] distribution = "slbeta4" [build-options] @@ -808,7 +806,7 @@ public void testNewCommandWithTemplateInLocalCache() throws IOException { Assert.assertEquals( readFileAsString(packageDir.resolve(ProjectConstants.BALLERINA_TOML)), expectedTomlContent); - Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))); + Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.README_MD_FILE_NAME))); Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.GITIGNORE_FILE_NAME))); Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.DEVCONTAINER))); Assert.assertTrue(readOutput().contains("Created new package")); @@ -832,7 +830,6 @@ public void testNewCommandWithTemplateCentralPullWithoutVersion() throws IOExcep org = "parkavik" name = "sample_pull_WO_Module_Version" version = "1.0.1" - export = ["sample_pull_WO_Module_Version"] distribution = "slbeta4" [build-options] @@ -840,7 +837,7 @@ public void testNewCommandWithTemplateCentralPullWithoutVersion() throws IOExcep """; Assert.assertEquals( readFileAsString(packageDir.resolve(ProjectConstants.BALLERINA_TOML)), expectedTomlContent); - Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))); + Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.README_MD_FILE_NAME))); Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.GITIGNORE_FILE_NAME))); Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.DEVCONTAINER))); Assert.assertTrue(readOutput().contains("Created new package")); @@ -864,7 +861,6 @@ public void testNewCommandWithTemplateCentralPullWithVersion() throws IOExceptio org = "parkavik" name = "sample_pull" version = "1.0.0" - export = ["sample_pull"] distribution = "slbeta4" [build-options] @@ -872,7 +868,7 @@ public void testNewCommandWithTemplateCentralPullWithVersion() throws IOExceptio """; Assert.assertEquals( readFileAsString(packageDir.resolve(ProjectConstants.BALLERINA_TOML)), expectedTomlContent); - Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))); + Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.README_MD_FILE_NAME))); Assert.assertTrue(Files.exists(packageDir.resolve("docs").resolve("icon.png"))); Assert.assertTrue(readOutput().contains("Created new package")); } @@ -897,7 +893,6 @@ public void testNewCommandCentralTemplateReplaceImports() throws IOException { "org = \"testorg\"\n" + "name = \"" + packageName + "\"\n" + "version = \"1.0.2\"\n" + - "export = [\"central_sample\"]\n" + "distribution = \"2201.7.0-SNAPSHOT\"\n\n" + "[build-options]\n" + "observabilityIncluded = true\n"; @@ -906,7 +901,7 @@ public void testNewCommandCentralTemplateReplaceImports() throws IOException { String mainContent = readFileAsString(packageDir.resolve("main.bal")); Assert.assertTrue(mainContent.contains("import central_sample.mod1;")); - Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))); + Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.README_MD_FILE_NAME))); Assert.assertTrue(readOutput().contains("Created new package")); // System.setProperty("user.dir", packageDir.toString()); @@ -932,8 +927,7 @@ public void testMultiModuleTemplate() throws IOException { newCommand.execute(); Assert.assertTrue(Files.exists(packageDir)); - Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))); - Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.MODULE_MD_FILE_NAME))); + Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.README_MD_FILE_NAME))); Assert.assertTrue(Files.exists(packageDir.resolve("natives.bal"))); Assert.assertTrue(Files.exists(packageDir.resolve("libs/protobuf-native-1.0.1.txt"))); Assert.assertTrue(Files.exists(packageDir.resolve("modules/types.timestamp"))); @@ -942,15 +936,13 @@ public void testMultiModuleTemplate() throws IOException { Assert.assertTrue(Files.exists(packageDir.resolve("modules/types.wrappers/int.bal"))); Assert.assertTrue(Files.exists(packageDir.resolve("modules/types.wrappers/string.bal"))); Assert.assertTrue(Files.exists(packageDir.resolve("modules/types.wrappers/" + - ProjectConstants.MODULE_MD_FILE_NAME))); + ProjectConstants.README_MD_FILE_NAME))); Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.BALLERINA_TOML))); String expectedTomlContent = "[package]\n" + "org = \"ballerina\"\n" + "name = \"sample_multi_module\"\n" + "version = \"1.0.1\"\n" + - "export = [\"sample_multi_module\",\"sample_multi_module.types.timestamp\"," + - "\"sample_multi_module.types.wrappers\"]\n" + "distribution = \"slbeta4\"\n" + "license = [\"Apache-2.0\"]\n" + "authors = [\"Ballerina\"]\n" + @@ -958,6 +950,13 @@ public void testMultiModuleTemplate() throws IOException { "repository = \"https://github.com/ballerina-platform/module-ballerina-protobuf\"\n" + "\n[build-options]\n" + "observabilityIncluded = true\n" + + "\n" + + "[[package.modules]]\n" + + "name = \"sample_multi_module.types.timestamp\"\n" + + "export = true\n\n" + + "[[package.modules]]\n" + + "name = \"sample_multi_module.types.wrappers\"\n" + + "export = true\n" + "\n[[platform.java11.dependency]]\n" + "path = \"libs" + File.separator + "protobuf-native-1.0.1.jar\""; Assert.assertEquals( @@ -998,7 +997,6 @@ public void testNewCommandCentralPullWithPlatformDependencies() throws IOExcepti org = "admin" name = "sample_pull_libs" version = "0.1.0" - export = ["sample_pull_libs"] distribution = "slbeta4" """; String expectedTomlLibContent = """ @@ -1009,7 +1007,7 @@ public void testNewCommandCentralPullWithPlatformDependencies() throws IOExcepti Assert.assertTrue(tomlContent.contains(expectedTomlPkgContent)); Assert.assertTrue(tomlContent.contains(expectedTomlLibContent)); - Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))); + Assert.assertTrue(Files.exists(packageDir.resolve(ProjectConstants.README_MD_FILE_NAME))); Assert.assertTrue(readOutput().contains("Created new package")); } diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/PackCommandTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/PackCommandTest.java index f35c317e27c2..7c9253ba7651 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/PackCommandTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/PackCommandTest.java @@ -1,6 +1,9 @@ package io.ballerina.cli.cmd; +import com.google.gson.Gson; import io.ballerina.cli.launcher.BLauncherException; +import io.ballerina.projects.JvmTarget; +import io.ballerina.projects.internal.bala.PackageJson; import io.ballerina.projects.util.BuildToolUtils; import io.ballerina.projects.util.ProjectUtils; import org.ballerinalang.test.BCompileUtil; @@ -8,6 +11,7 @@ import org.mockito.Mockito; import org.testng.Assert; import org.testng.annotations.AfterClass; +import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeGroups; import org.testng.annotations.Test; @@ -19,14 +23,22 @@ import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.StandardCopyOption; import java.util.List; import java.util.Objects; import static io.ballerina.cli.cmd.CommandOutputUtils.assertTomlFilesEquals; import static io.ballerina.cli.cmd.CommandOutputUtils.getOutput; import static io.ballerina.cli.cmd.CommandOutputUtils.replaceDependenciesTomlContent; +import static io.ballerina.projects.util.ProjectConstants.BALA_DOCS_DIR; +import static io.ballerina.projects.util.ProjectConstants.BALLERINA_TOML; import static io.ballerina.projects.util.ProjectConstants.DEPENDENCIES_TOML; import static io.ballerina.projects.util.ProjectConstants.DIST_CACHE_DIRECTORY; +import static io.ballerina.projects.util.ProjectConstants.MODULES_ROOT; +import static io.ballerina.projects.util.ProjectConstants.MODULE_MD_FILE_NAME; +import static io.ballerina.projects.util.ProjectConstants.PACKAGE_JSON; +import static io.ballerina.projects.util.ProjectConstants.PACKAGE_MD_FILE_NAME; +import static io.ballerina.projects.util.ProjectConstants.README_MD_FILE_NAME; import static io.ballerina.projects.util.ProjectConstants.RESOURCE_DIR_NAME; import static io.ballerina.projects.util.ProjectConstants.USER_DIR; import static io.ballerina.projects.util.ProjectConstants.USER_DIR_PROPERTY; @@ -68,6 +80,11 @@ public void setup() throws IOException { Files.writeString(logFile, ""); } + @AfterMethod + public void afterMethod() { + ProjectUtils.clearDiagnostics(); + } + @Test(description = "Pack a library package", dataProvider = "optimizeDependencyCompilation") public void testPackProject(Boolean optimizeDependencyCompilation) throws IOException { Path projectPath = this.testResources.resolve("validLibraryProject"); @@ -84,8 +101,18 @@ public void testPackProject(Boolean optimizeDependencyCompilation) throws IOExce Assert.assertTrue( projectPath.resolve("target").resolve("bala").resolve("foo-winery-any-0.1.0.bala").toFile().exists()); Assert.assertTrue(projectPath.resolve("target").resolve("cache").resolve("foo") - .resolve("winery").resolve("0.1.0").resolve("java17") + .resolve("winery").resolve("0.1.0").resolve(JvmTarget.JAVA_21.code()) .resolve("foo-winery-0.1.0.jar").toFile().exists()); + + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + Assert.assertTrue(Files.exists(extractedPath.resolve(BALA_DOCS_DIR).resolve(README_MD_FILE_NAME))); + + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(BALA_DOCS_DIR + "/" + README_MD_FILE_NAME, packageJson.getReadme()); } @Test(description = "Pack a ballerina project with the engagement of all type of compiler plugins", @@ -169,7 +196,7 @@ public void testPackageWithPlatformLibs(Boolean optimizeDependencyCompilation) t Assert.assertEquals(buildLog.replace("\r", ""), getOutput("build-project-with-platform-libs.txt")); - Assert.assertTrue(projectPath.resolve("target").resolve("bala").resolve("sameera-myproject-java17-0.1.0.bala") + Assert.assertTrue(projectPath.resolve("target").resolve("bala").resolve("sameera-myproject-java21-0.1.0.bala") .toFile().exists()); } @@ -185,17 +212,17 @@ public void testPackageWithJava11PlatformLibs() throws IOException { Assert.assertEquals(buildLog.replace("\r", ""), getOutput("build-project-with-platform-libs.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Assert.assertTrue(balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala") + Assert.assertTrue(balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala") .toFile().exists()); Path balaDestPath = balaDirPath.resolve("extracted"); - ProjectUtils.extractBala(balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"), balaDestPath); - Assert.assertTrue(balaDestPath.resolve("platform").resolve("java17").resolve("one-1.0.0.jar") + ProjectUtils.extractBala(balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"), balaDestPath); + Assert.assertTrue(balaDestPath.resolve("platform").resolve(JvmTarget.JAVA_21.code()).resolve("one-1.0.0.jar") .toFile().exists()); } - @Test(description = "Pack a package with java11 and java17 platform libs") - public void testPackageWithJava11andJava17PlatformLibs() throws IOException { + @Test(description = "Pack a package with multiple java platform libs") + public void testPackageWithMultipleJavaPlatformLibs() throws IOException { Path projectPath = this.testResources.resolve("projectWithJava11and17PlatformLibs"); System.setProperty(USER_DIR, projectPath.toString()); PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); @@ -206,14 +233,14 @@ public void testPackageWithJava11andJava17PlatformLibs() throws IOException { Assert.assertEquals(buildLog.replace("\r", ""), getOutput("build-project-with-platform-libs.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Assert.assertTrue(balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala") + Assert.assertTrue(balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala") .toFile().exists()); Path balaDestPath = balaDirPath.resolve("extracted"); - ProjectUtils.extractBala(balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"), balaDestPath); - Assert.assertTrue(balaDestPath.resolve("platform").resolve("java17").resolve("one-1.0.0.jar") + ProjectUtils.extractBala(balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"), balaDestPath); + Assert.assertTrue(balaDestPath.resolve("platform").resolve(JvmTarget.JAVA_21.code()).resolve("one-1.0.0.jar") .toFile().exists()); - Assert.assertTrue(balaDestPath.resolve("platform").resolve("java17").resolve("two-2.0.0.jar") + Assert.assertTrue(balaDestPath.resolve("platform").resolve(JvmTarget.JAVA_21.code()).resolve("two-2.0.0.jar") .toFile().exists()); } @@ -296,7 +323,7 @@ public void testPackageWithoutRootPackageInDependenciesToml() Assert.assertEquals(buildLog.replace("\r", ""), getOutput("build-project-wo-root-pkg-in-deps-toml.txt")); - Assert.assertTrue(projectPath.resolve("target").resolve("bala").resolve("foo-winery-java17-0.1.0.bala") + Assert.assertTrue(projectPath.resolve("target").resolve("bala").resolve("foo-winery-java21-0.1.0.bala") .toFile().exists()); assertTomlFilesEquals(projectPath.resolve(DEPENDENCIES_TOML), @@ -314,7 +341,7 @@ public void testPackEmptyProjectWithCompilerPlugin() throws IOException { String buildLog = readOutput(true); Assert.assertTrue(projectPath.resolve("target").resolve("bala") - .resolve("wso2-emptyProjWithCompilerPlugin-java17-0.1.0.bala").toFile().exists()); + .resolve("wso2-emptyProjWithCompilerPlugin-java21-0.1.0.bala").toFile().exists()); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("compile-empty-project-with-compiler-plugin.txt")); } @@ -351,7 +378,7 @@ public void testPackEmptyProjectWithTool() throws IOException { String buildLog = readOutput(true); Assert.assertTrue(projectPath.resolve("target").resolve("bala") - .resolve("wso2-emptyProjWithTool-java17-0.1.0.bala").toFile().exists()); + .resolve("wso2-emptyProjWithTool-java21-0.1.0.bala").toFile().exists()); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("compile-empty-project-with-tool.txt")); } @@ -555,7 +582,7 @@ public void testPackProjectWithPlatformLibs() throws IOException { String buildLog = readOutput(true); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("pack-project-with-platform-libs.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Path balaFilePath = balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"); + Path balaFilePath = balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"); Path balaDestPath = balaDirPath.resolve("extracted"); ProjectUtils.extractBala(balaFilePath, balaDestPath); String packageJsonContent = Files.readString(balaDestPath.resolve("package.json")); @@ -573,7 +600,7 @@ public void testPackProjectWithPlatformLibsGraal1() throws IOException { String buildLog = readOutput(true); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("pack-project-with-platform-libs-graal1.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Path balaFilePath = balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"); + Path balaFilePath = balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"); Path balaDestPath = balaDirPath.resolve("extracted"); ProjectUtils.extractBala(balaFilePath, balaDestPath); String packageJsonContent = Files.readString(balaDestPath.resolve("package.json")); @@ -591,7 +618,7 @@ public void testPackProjectWithPlatformLibsGraal2() throws IOException { String buildLog = readOutput(true); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("pack-project-with-platform-libs-graal2.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Path balaFilePath = balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"); + Path balaFilePath = balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"); Path balaDestPath = balaDirPath.resolve("extracted"); ProjectUtils.extractBala(balaFilePath, balaDestPath); String packageJsonContent = Files.readString(balaDestPath.resolve("package.json")); @@ -610,7 +637,7 @@ public void testPackProjectWithPlatformLibsGraal3() throws IOException { String buildLog = readOutput(true); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("pack-project-with-platform-libs-graal3.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Path balaFilePath = balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"); + Path balaFilePath = balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"); Path balaDestPath = balaDirPath.resolve("extracted"); ProjectUtils.extractBala(balaFilePath, balaDestPath); String packageJsonContent = Files.readString(balaDestPath.resolve("package.json")); @@ -628,7 +655,7 @@ public void testPackProjectWithPlatformLibsGraal4() throws IOException { String buildLog = readOutput(true); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("pack-project-with-platform-libs-graal4.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Path balaFilePath = balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"); + Path balaFilePath = balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"); Path balaDestPath = balaDirPath.resolve("extracted"); ProjectUtils.extractBala(balaFilePath, balaDestPath); String packageJsonContent = Files.readString(balaDestPath.resolve("package.json")); @@ -647,7 +674,7 @@ public void testPackProjectWithPlatformLibsGraal5() throws IOException { String buildLog = readOutput(true); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("pack-project-with-platform-libs-graal5.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Path balaFilePath = balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"); + Path balaFilePath = balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"); Path balaDestPath = balaDirPath.resolve("extracted"); ProjectUtils.extractBala(balaFilePath, balaDestPath); String packageJsonContent = Files.readString(balaDestPath.resolve("package.json")); @@ -666,7 +693,7 @@ public void testPackProjectWithPlatformLibsGraal6() throws IOException { String buildLog = readOutput(true); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("pack-project-with-platform-libs-graal6.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Path balaFilePath = balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"); + Path balaFilePath = balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"); Path balaDestPath = balaDirPath.resolve("extracted"); ProjectUtils.extractBala(balaFilePath, balaDestPath); String packageJsonContent = Files.readString(balaDestPath.resolve("package.json")); @@ -685,13 +712,393 @@ public void testPackProjectWithPlatformLibsGraal7() throws IOException { String buildLog = readOutput(true); Assert.assertEquals(buildLog.replace("\r", ""), getOutput("pack-project-with-platform-libs-graal7.txt")); Path balaDirPath = projectPath.resolve("target").resolve("bala"); - Path balaFilePath = balaDirPath.resolve("sameera-myproject-java17-0.1.0.bala"); + Path balaFilePath = balaDirPath.resolve("sameera-myproject-java21-0.1.0.bala"); Path balaDestPath = balaDirPath.resolve("extracted"); ProjectUtils.extractBala(balaFilePath, balaDestPath); String packageJsonContent = Files.readString(balaDestPath.resolve("package.json")); Assert.assertTrue(packageJsonContent.contains("\"graalvmCompatible\": false")); } + @Test (description = "Test a package that contains Package.md and Module.md for docs") + public void testOldPackageDocStructure() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validLibraryProjectWithOldMds"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + String buildLog = readOutput(true); + String warning = """ + The default file for package documentation is changed to README.md. If you prefer to \ + use the Package.md, add the following line under the '[package]' section in your \ + Ballerina.toml file: + \treadme = "Package.md" + """; + Assert.assertTrue(buildLog.contains(warning)); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + Assert.assertTrue(Files.exists(extractedPath.resolve(BALA_DOCS_DIR).resolve(PACKAGE_MD_FILE_NAME))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve("package.json")); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(BALA_DOCS_DIR + "/" + PACKAGE_MD_FILE_NAME, packageJson.getReadme()); + } + + @Test (description = "Add the readme entry to the package with old doc structure to resolve the warning", + dependsOnMethods = "testOldPackageDocStructure") + public void testConvertOldDocStructureToNew() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validLibraryProjectWithOldMds"); + Files.move(projectPath.resolve("With-readme-Ballerina.toml"), + projectPath.resolve(BALLERINA_TOML), StandardCopyOption.REPLACE_EXISTING); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + String buildLog = readOutput(true); + String warning = """ + The default file for package documentation is changed to README.md. If you prefer to \ + use the Package.md, add the following line under the '[package]' section in your \ + Ballerina.toml file: + \treadme = "Package.md" + """; + Assert.assertFalse(buildLog.contains(warning)); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + Assert.assertTrue(Files.exists(extractedPath.resolve(BALA_DOCS_DIR).resolve(PACKAGE_MD_FILE_NAME))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve("package.json")); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(BALA_DOCS_DIR + "/" + PACKAGE_MD_FILE_NAME, packageJson.getReadme()); + } + + @Test (description = "Package root contains README.md but the Ballerina.toml has Package.md") + public void testLibPackageWithWrongMd() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("libraryProjectWithWrongMd"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + try { + packCommand.execute(); + } catch (BLauncherException e) { + String buildLog = readOutput(true); + Assert.assertTrue(buildLog.contains("could not locate the readme file")); + } + } + + @Test + public void testMultiModuleProjectWithOldDocStructure() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validMultiModuleProjectWithPackageAndModuleMds"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + String buildLog = readOutput(true); + + String warning = """ + The default file for package documentation is changed to README.md. If you prefer to \ + use the Package.md, add the following line under the '[package]' section in your \ + Ballerina.toml file: + \treadme = "Package.md" + """; + Assert.assertTrue(buildLog.contains(warning)); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + + String packageDocPath = BALA_DOCS_DIR + "/" + PACKAGE_MD_FILE_NAME; + String nonDefaultModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.storage/" + MODULE_MD_FILE_NAME; + Assert.assertTrue(Files.exists(extractedPath.resolve(packageDocPath))); + Assert.assertTrue(Files.exists(extractedPath.resolve(nonDefaultModuleDocPath))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(packageJson.getModules().size(), 1); + Assert.assertEquals(packageDocPath, packageJson.getReadme()); + Assert.assertEquals(nonDefaultModuleDocPath, packageJson.getModules().stream().filter( + module -> "winery.storage".equals(module.name())).findFirst().get().readme()); + } + + @Test (description = "Add readme entries for all places in the package with the old doc structure" + + " to resolve the warning", + dependsOnMethods = "testMultiModuleProjectWithOldDocStructure") + public void testConvertMultiModuleOldDocStructureToNew() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validMultiModuleProjectWithPackageAndModuleMds"); + System.setProperty(USER_DIR, projectPath.toString()); + Files.move(projectPath.resolve("With-readme-for-non-default-mod-Ballerina.toml"), + projectPath.resolve(BALLERINA_TOML), StandardCopyOption.REPLACE_EXISTING); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + String buildLog = readOutput(true); + String warning = """ + The default file for package documentation is changed to README.md. If you prefer to \ + use the Package.md, add the following line under the '[package]' section in your \ + Ballerina.toml file: + \treadme = "Package.md" + """; + Assert.assertFalse(buildLog.contains(warning)); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + + String packageDocPath = BALA_DOCS_DIR + "/" + PACKAGE_MD_FILE_NAME; + String nonDefaultModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.storage/" + MODULE_MD_FILE_NAME; + Assert.assertTrue(Files.exists(extractedPath.resolve(packageDocPath))); + Assert.assertTrue(Files.exists(extractedPath.resolve(nonDefaultModuleDocPath))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(packageJson.getModules().size(), 1); + Assert.assertEquals(packageDocPath, packageJson.getReadme()); + Assert.assertEquals(nonDefaultModuleDocPath, packageJson.getModules().stream().filter( + module -> "winery.storage".equals(module.name())).findFirst().get().readme()); + } + + @Test + public void testMultiModuleProjectWithNewDefaultDocStructure() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validMultiModuleProjectWithReadmeMds"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + + String packageDocPath = BALA_DOCS_DIR + "/" + README_MD_FILE_NAME; + String nonDefaultModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.storage/" + README_MD_FILE_NAME; + Assert.assertTrue(Files.exists(extractedPath.resolve(packageDocPath))); + Assert.assertTrue(Files.exists(extractedPath.resolve(nonDefaultModuleDocPath))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(packageJson.getModules().size(), 1); + Assert.assertEquals(packageDocPath, packageJson.getReadme()); + Assert.assertEquals(nonDefaultModuleDocPath, packageJson.getModules().stream().filter( + module -> "winery.storage".equals(module.name())).findFirst().get().readme()); + } + + @Test (description = "One non-default module does not contain a readme") + public void testMultiModuleProjectWithNewDefaultDocStructure2() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validMultiModuleProjectWithReadmeMds2"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + + String packageDocPath = BALA_DOCS_DIR + "/" + README_MD_FILE_NAME; + String storageModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.storage/" + README_MD_FILE_NAME; + String commonModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.common/" + README_MD_FILE_NAME; + Assert.assertTrue(Files.exists(extractedPath.resolve(packageDocPath))); + Assert.assertTrue(Files.exists(extractedPath.resolve(storageModuleDocPath))); + Assert.assertFalse(Files.exists(extractedPath.resolve(commonModuleDocPath))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(packageJson.getModules().size(), 2); + Assert.assertEquals(packageDocPath, packageJson.getReadme()); + Assert.assertEquals(storageModuleDocPath, packageJson.getModules().stream().filter( + module -> "winery.storage".equals(module.name())).findFirst().get().readme()); + } + + @Test (description = "One non-default module uses a custom MD. " + + "Other one and the package doc use the default README.md") + public void testMultiModuleProjectCustomReadmes() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validMultiModuleProjectCustomModuleReadme"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + + String packageDocPath = BALA_DOCS_DIR + "/" + README_MD_FILE_NAME; + String storageModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.storage/" + MODULE_MD_FILE_NAME; + String commonModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.common/" + README_MD_FILE_NAME; + Assert.assertTrue(Files.exists(extractedPath.resolve(packageDocPath))); + Assert.assertTrue(Files.exists(extractedPath.resolve(storageModuleDocPath))); + Assert.assertTrue(Files.exists(extractedPath.resolve(commonModuleDocPath))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(packageJson.getModules().size(), 2); + Assert.assertEquals(packageDocPath, packageJson.getReadme()); + Assert.assertEquals(storageModuleDocPath, packageJson.getModules().stream().filter( + module -> "winery.storage".equals(module.name())).findFirst().get().readme()); + Assert.assertEquals(commonModuleDocPath, packageJson.getModules().stream().filter( + module -> "winery.common".equals(module.name())).findFirst().get().readme()); + } + + @Test (description = "One non-default module does not have a doc") + public void testMultiModuleProjectReadmeOptionality() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validMultiModuleProjectOptionalModuleReadme"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + + String packageDocPath = BALA_DOCS_DIR + "/" + README_MD_FILE_NAME; + String storageModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.storage/" + MODULE_MD_FILE_NAME; + String commonModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.common/"; + Assert.assertTrue(Files.exists(extractedPath.resolve(packageDocPath))); + Assert.assertTrue(Files.exists(extractedPath.resolve(storageModuleDocPath))); + Assert.assertTrue(Files.notExists(extractedPath.resolve(commonModuleDocPath))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(packageJson.getModules().size(), 2); + Assert.assertEquals(packageDocPath, packageJson.getReadme()); + Assert.assertEquals(storageModuleDocPath, packageJson.getModules().stream().filter( + module -> "winery.storage".equals(module.name())).findFirst().get().readme()); + } + + @Test + public void testReadMeWithHierarchicalModuleName() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validHierarchicalModuleProjectWithReadmeMds"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + + String packageDocPath = BALA_DOCS_DIR + "/" + README_MD_FILE_NAME; + String storageModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.bar.storage/" + README_MD_FILE_NAME; + String commonModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/winery.bar.common/"; + Assert.assertTrue(Files.exists(extractedPath.resolve(packageDocPath))); + Assert.assertTrue(Files.exists(extractedPath.resolve(storageModuleDocPath))); + Assert.assertTrue(Files.notExists(extractedPath.resolve(commonModuleDocPath))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(packageJson.getModules().size(), 2); + Assert.assertEquals(packageDocPath, packageJson.getReadme()); + Assert.assertEquals(storageModuleDocPath, packageJson.getModules().stream().filter( + module -> "winery.bar.storage".equals(module.name())).findFirst().get().readme()); + } + + @Test + public void testReadMeWithHierarchicalPackageName() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("validHierarchicalPackageWithReadmeMds"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-bar.winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + + String packageDocPath = BALA_DOCS_DIR + "/" + README_MD_FILE_NAME; + String storageModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/bar.winery.storage/" + README_MD_FILE_NAME; + String commonModuleDocPath = BALA_DOCS_DIR + "/" + MODULES_ROOT + "/bar.winery.common/"; + Assert.assertTrue(Files.exists(extractedPath.resolve(packageDocPath))); + Assert.assertTrue(Files.exists(extractedPath.resolve(storageModuleDocPath))); + Assert.assertTrue(Files.notExists(extractedPath.resolve(commonModuleDocPath))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertEquals(packageJson.getModules().size(), 2); + Assert.assertEquals(packageDocPath, packageJson.getReadme()); + Assert.assertEquals(storageModuleDocPath, packageJson.getModules().stream().filter( + module -> "bar.winery.storage".equals(module.name())).findFirst().get().readme()); + } + + @Test + public void testLibPackageWithNoDocMds() throws IOException { + Path projectPath = this.testResources.resolve("readme-test-projects") + .resolve("libraryProjectWithNoMd"); + System.setProperty(USER_DIR, projectPath.toString()); + + PackCommand packCommand = new PackCommand(projectPath, printStream, printStream, false, true); + new CommandLine(packCommand).parseArgs(); + packCommand.execute(); + + // Verify the docs + Path balaDirPath = projectPath.resolve("target").resolve("bala"); + Path balaFilePath = balaDirPath.resolve("foo-winery-any-0.1.0.bala"); + Path extractedPath = balaDirPath.resolve("extracted"); + ProjectUtils.extractBala(balaFilePath, extractedPath); + + String packageDocPath = BALA_DOCS_DIR + "/" + README_MD_FILE_NAME; + Assert.assertTrue(Files.notExists(extractedPath.resolve(packageDocPath))); + + // Verify the docs entry in package.json + String packageJsonContent = Files.readString(extractedPath.resolve(PACKAGE_JSON)); + PackageJson packageJson = new Gson().fromJson(packageJsonContent, PackageJson.class); + Assert.assertNull(packageJson.getModules()); + } + @AfterClass public void cleanUp() throws IOException { Files.deleteIfExists(logFile); diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/PushCommandTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/PushCommandTest.java index 3c2046740d2a..4e0dc607c34c 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/PushCommandTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/PushCommandTest.java @@ -224,9 +224,8 @@ public void testPushToolToLocal() throws IOException { this.testResources.resolve("tool-gayals").toFile(), validBalProject.toFile()); FileUtils.moveDirectory( validBalProject.resolve("target-dir").toFile(), validBalProject.resolve("custom").toFile()); - Path customTargetDirBalaPath = - validBalProject.resolve("custom/bala/gayaldassanayake-tool_gayal-java17-1.1.0.bala"); + validBalProject.resolve("custom/bala/gayaldassanayake-tool_gayal-java21-1.1.0.bala"); PushCommand pushCommand = new PushCommand(validBalProject, printStream, printStream, false, customTargetDirBalaPath); String[] args = { "--repository=local" }; @@ -248,7 +247,7 @@ public void testPushToolToLocal() throws IOException { try { ProjectFiles.validateBalaProjectPath( - mockRepo.resolve("repositories/local/bala/gayaldassanayake/tool_gayal/1.1.0/java17")); + mockRepo.resolve("repositories/local/bala/gayaldassanayake/tool_gayal/1.1.0/java21")); } catch (ProjectException e) { Assert.fail(e.getMessage()); } @@ -373,7 +372,7 @@ public void testPushWithoutPackageMd() throws IOException { Assert.assertTrue(projectPath.resolve("target/bala/foo-winery-any-0.1.0.bala").toFile().exists()); // Push - String expected = "Package.md is missing in bala file"; + String expected = "README file is missing in the bala file"; PushCommand pushCommand = new PushCommand(projectPath, printStream, printStream, false); new CommandLine(pushCommand).parseArgs(); diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/RunCommandTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/RunCommandTest.java index b7b7e7ff667c..f8b5daff4463 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/RunCommandTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/RunCommandTest.java @@ -285,7 +285,7 @@ public void testRunWithCustomTarget() { Assert.assertTrue(Files.exists(customTargetDir.resolve("cache"))); Assert.assertTrue(Files.exists(customTargetDir.resolve("cache/wso2/foo/0.1.0"))); Assert.assertTrue(Files.exists(customTargetDir.resolve("cache/wso2/foo/0.1.0"))); - if (!(Files.exists(customTargetDir.resolve("cache/wso2/foo/0.1.0/java17/wso2-foo-0.1.0.jar")) || + if (!(Files.exists(customTargetDir.resolve("cache/wso2/foo/0.1.0/java21/wso2-foo-0.1.0.jar")) || Files.exists(customTargetDir.resolve("cache/wso2/foo/0.1.0/any/wso2-foo-0.1.0.jar")))) { Assert.fail("Run command with custom target dir failed"); } @@ -367,7 +367,7 @@ public void testRunBalProjectWithDumpGraphFlag() throws IOException { String buildLog = readOutput(true).replaceAll("\r", "").strip(); Assert.assertEquals(buildLog, getOutput("run-project-with-dump-graph.txt")); - Assert.assertTrue(projectPath.resolve("target/cache/foo/package_a/0.1.0/java17/foo-package_a-0.1.0.jar") + Assert.assertTrue(projectPath.resolve("target/cache/foo/package_a/0.1.0/java21/foo-package_a-0.1.0.jar") .toFile().exists()); ProjectUtils.deleteDirectory(projectPath.resolve("target")); @@ -390,9 +390,8 @@ public void testRunBalProjectWithDumpRawGraphsFlag() throws IOException { String buildLog = readOutput(true).replaceAll("\r", "").strip(); Assert.assertEquals(buildLog, getOutput("run-project-with-dump-raw-graphs.txt")); - Assert.assertTrue(projectPath.resolve("target/cache/foo/package_a/0.1.0/java17/foo-package_a-0.1.0.jar") + Assert.assertTrue(projectPath.resolve("target/cache/foo/package_a/0.1.0/java21/foo-package_a-0.1.0.jar") .toFile().exists()); - ProjectUtils.deleteDirectory(projectPath.resolve("target")); } diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/ShellCommandTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/ShellCommandTest.java index 8978967e502e..daeb8c7ce473 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/ShellCommandTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/ShellCommandTest.java @@ -91,7 +91,7 @@ public void testShellExecution() throws Exception { PipedOutputStream shellOut = new PipedOutputStream(); PipedInputStream testIn = new PipedInputStream(shellOut); - Thread testIntegratorThread = new Thread(() -> { + Thread testIntegratorThread = Thread.startVirtualThread(() -> { try { PrintStream testPrint = new PrintStream(testOut, true, Charset.defaultCharset()); InputStreamReader inStreamReader = new InputStreamReader(testIn, Charset.defaultCharset()); @@ -113,7 +113,6 @@ public void testShellExecution() throws Exception { } catch (IOException ignored) { } }); - testIntegratorThread.start(); try { BShellConfiguration configuration = new BShellConfiguration.Builder() diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/TestCommandTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/TestCommandTest.java index d8234d9fecda..fdf429d69190 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/TestCommandTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/TestCommandTest.java @@ -238,9 +238,9 @@ public void testTestCommandPreservingBinJarInTargetDir() throws IOException { Assert.assertTrue(projectPath.resolve("target/bin/winery.jar").toFile().exists()); Assert.assertEquals(md5BinJar, DigestUtils.md5Hex( Files.newInputStream(projectPath.resolve("target/bin/winery.jar")))); - Assert.assertTrue(projectPath.resolve("target/cache/foo/winery/0.1.0/java17/foo-winery-0.1.0.jar") + Assert.assertTrue(projectPath.resolve("target/cache/foo/winery/0.1.0/java21/foo-winery-0.1.0.jar") .toFile().exists()); - Assert.assertTrue(projectPath.resolve("target/cache/foo/winery/0.1.0/java17/foo-winery-0.1.0-testable.jar") + Assert.assertTrue(projectPath.resolve("target/cache/foo/winery/0.1.0/java21/foo-winery-0.1.0-testable.jar") .toFile().exists()); } @@ -366,7 +366,7 @@ public void testTestBalProjectWithDumpGraphFlag() throws IOException { String buildLog = readOutput(true).replace("\r", "").strip(); Assert.assertEquals(buildLog, getOutput("test-project-with-dump-graph.txt")); - Assert.assertTrue(projectPath.resolve("target/cache/foo/package_a/0.1.0/java17/foo-package_a-0.1.0.jar") + Assert.assertTrue(projectPath.resolve("target/cache/foo/package_a/0.1.0/java21/foo-package_a-0.1.0.jar") .toFile().exists()); ProjectUtils.deleteDirectory(projectPath.resolve("target")); @@ -392,9 +392,8 @@ public void testTestBalProjectWithDumpRawGraphsFlag() throws IOException { String buildLog = readOutput(true).replace("\r", "").replace("\\", "/").strip(); Assert.assertEquals(buildLog, getOutput("test-project-with-dump-raw-graphs.txt")); - Assert.assertTrue(projectPath.resolve("target/cache/foo/package_a/0.1.0/java17/foo-package_a-0.1.0.jar") + Assert.assertTrue(projectPath.resolve("target/cache/foo/package_a/0.1.0/java21/foo-package_a-0.1.0.jar") .toFile().exists()); - ProjectUtils.deleteDirectory(projectPath.resolve("target")); } diff --git a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/TestNativeImageCommandTest.java b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/TestNativeImageCommandTest.java index af8bb297e067..45cfa3a7ed33 100644 --- a/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/TestNativeImageCommandTest.java +++ b/cli/ballerina-cli/src/test/java/io/ballerina/cli/cmd/TestNativeImageCommandTest.java @@ -69,7 +69,8 @@ public void testNativeImageTests() throws IOException { public void testNativeImageTestsWithAdditionalArgs() throws IOException { Path projectPath = this.testResources.resolve("validProjectWithTests"); System.setProperty(ProjectConstants.USER_DIR, projectPath.toString()); - TestCommand testCommand = new TestCommand(projectPath, printStream, printStream, false, true, "-H:Name=foo"); + TestCommand testCommand = new TestCommand(projectPath, printStream, printStream, + false, true, "-o " + projectPath + "/foo"); new CommandLine(testCommand).parseArgs(); try { testCommand.execute(); @@ -126,7 +127,7 @@ public void testTestBalFileWithAdditionalArgs() { Path validBalFilePath = this.testResources.resolve("valid-test-bal-file/sample_tests.bal"); System.setProperty(ProjectConstants.USER_DIR, this.testResources.resolve("valid-test-bal-file").toString()); TestCommand testCommand = new TestCommand(validBalFilePath, printStream, printStream, - false, true, "-H:Name=foo"); + false, true, "-o " + this.testResources.resolve("valid-test-bal-file") + "/foo"); new CommandLine(testCommand).parseArgs(validBalFilePath.toString()); try { testCommand.execute(); diff --git a/cli/ballerina-cli/src/test/resources/test-resources/balacache-dependencies/foo/winery/0.1.0/any/package.json b/cli/ballerina-cli/src/test/resources/test-resources/balacache-dependencies/foo/winery/0.1.0/any/package.json index 11c7b55f78a3..b348f3270dcc 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/balacache-dependencies/foo/winery/0.1.0/any/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/balacache-dependencies/foo/winery/0.1.0/any/package.json @@ -30,10 +30,10 @@ "ballerina_version": "2201.2.0-SNAPSHOT", "implementation_vendor": "WSO2", "language_spec_version": "2022R2", - "platform": "java17", + "platform": "java21", "platformDependencies": [ { - "path": "platform/java17/ballerina-io-1.0.0-java.txt", + "path": "platform/java21/ballerina-io-1.0.0-java.txt", "artifactId": "ldap", "groupId": "ballerina", "version": "1.0.0" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/admin/lib_project/0.1.0/java11/package.json b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/admin/lib_project/0.1.0/java11/package.json index 7e593c981689..1466d2c10da2 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/admin/lib_project/0.1.0/java11/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/admin/lib_project/0.1.0/java11/package.json @@ -8,10 +8,10 @@ "ballerina_version": "slbeta4", "implementation_vendor": "WSO2", "language_spec_version": "2021R1", - "platform": "java17", + "platform": "java21", "platformDependencies": [ { - "path": "platform/java17/snakeyaml-2.0.jar", + "path": "platform/java21/snakeyaml-2.0.jar", "artifactId": "snakeyaml", "groupId": "org.yaml", "version": "2.0" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/ballerina/protobuf/1.0.1/java11/bala.json b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/ballerina/protobuf/1.0.1/java11/bala.json new file mode 100644 index 000000000000..fd0a01921270 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/ballerina/protobuf/1.0.1/java11/bala.json @@ -0,0 +1,4 @@ +{ + "bala_version": "2.0.0", + "built_by": "WSO2" +} \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/ballerina/protobuf/1.0.1/java11/package.json b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/ballerina/protobuf/1.0.1/java11/package.json index 4b88374a8fbd..c2c6edb6c3fd 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/ballerina/protobuf/1.0.1/java11/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/ballerina/protobuf/1.0.1/java11/package.json @@ -20,10 +20,10 @@ "ballerina_version": "slbeta4", "implementation_vendor": "WSO2", "language_spec_version": "2021R1", - "platform": "java17", + "platform": "java21", "platformDependencies": [ { - "path": "platform/java17/protobuf-native-1.0.1.jar" + "path": "platform/java21/protobuf-native-1.0.1.jar" } ], "template": true diff --git a/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/testorg/projectProvidedScope/1.0.0/java17/package.json b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/testorg/projectProvidedScope/1.0.0/java17/package.json index ea3724572b67..8487597c10e9 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/testorg/projectProvidedScope/1.0.0/java17/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/testorg/projectProvidedScope/1.0.0/java17/package.json @@ -8,7 +8,7 @@ "ballerina_version": "2201.9.0-SNAPSHOT", "implementation_vendor": "WSO2", "language_spec_version": "2023R1", - "platform": "java17", + "platform": "java21", "platformDependencies": [ { "artifactId": "project1", diff --git a/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/testorg/toolProject/1.0.0/java17/package.json b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/testorg/toolProject/1.0.0/java17/package.json index a09123619211..5e4fd3c3214a 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/testorg/toolProject/1.0.0/java17/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/balacache-template/testorg/toolProject/1.0.0/java17/package.json @@ -8,6 +8,6 @@ "ballerina_version": "2201.6.0-SNAPSHOT", "implementation_vendor": "WSO2", "language_spec_version": "2022R4", - "platform": "java17", + "platform": "java21", "template": true } diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-with-platform-libs.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-with-platform-libs.txt index 2d63faf99605..dff79785a135 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-with-platform-libs.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-with-platform-libs.txt @@ -2,4 +2,4 @@ Compiling source sameera/myproject:0.1.0 Creating bala - target/bala/sameera-myproject-java17-0.1.0.bala + target/bala/sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-wo-root-pkg-in-deps-toml.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-wo-root-pkg-in-deps-toml.txt index 5901a45f225a..0793205f82d3 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-wo-root-pkg-in-deps-toml.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/build-project-wo-root-pkg-in-deps-toml.txt @@ -4,4 +4,4 @@ WARNING [Dependencies.toml:(6:1,15:2)] Detected corrupted Dependencies.toml file WARNING [main.bal:(6:4,6:58)] unused variable 'isSuccess' Creating bala - target/bala/foo-winery-java17-0.1.0.bala + target/bala/foo-winery-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/compile-empty-project-with-compiler-plugin.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/compile-empty-project-with-compiler-plugin.txt index dafe43ecb682..7b4cec80fe5b 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/compile-empty-project-with-compiler-plugin.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/compile-empty-project-with-compiler-plugin.txt @@ -2,4 +2,4 @@ Compiling source wso2/emptyProjWithCompilerPlugin:0.1.0 Creating bala - target/bala/wso2-emptyProjWithCompilerPlugin-java17-0.1.0.bala + target/bala/wso2-emptyProjWithCompilerPlugin-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/compile-empty-project-with-tool.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/compile-empty-project-with-tool.txt index d31166101173..cc9506e6aaa9 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/compile-empty-project-with-tool.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/compile-empty-project-with-tool.txt @@ -2,4 +2,4 @@ Compiling source wso2/emptyProjWithTool:0.1.0 Creating bala - target/bala/wso2-emptyProjWithTool-java17-0.1.0.bala + target/bala/wso2-emptyProjWithTool-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-central-tool.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-central-tool.txt index c52dd2cde0ca..14d7a786fa81 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-central-tool.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-central-tool.txt @@ -2,4 +2,4 @@ Compiling source testorg/sample_tool_template:1.0.0 Creating bala - target/bala/testorg-sample_tool_template-java17-1.0.0.bala + target/bala/testorg-sample_tool_template-java21-1.0.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-empty-package-with-compiler-plugin.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-empty-package-with-compiler-plugin.txt index 13b4898adedf..53661e6f171b 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-empty-package-with-compiler-plugin.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-empty-package-with-compiler-plugin.txt @@ -2,4 +2,4 @@ Compiling source user/LibraryProject:0.1.0 Creating bala - target/bala/user-LibraryProject-java17-0.1.0.bala + target/bala/user-LibraryProject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal1.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal1.txt index 2d63faf99605..dff79785a135 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal1.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal1.txt @@ -2,4 +2,4 @@ Compiling source sameera/myproject:0.1.0 Creating bala - target/bala/sameera-myproject-java17-0.1.0.bala + target/bala/sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal2.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal2.txt index 095212c4bf36..959832cfb661 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal2.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal2.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target/bala/sameera-myproject-java17-0.1.0.bala + target/bala/sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal3.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal3.txt index 095212c4bf36..959832cfb661 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal3.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal3.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target/bala/sameera-myproject-java17-0.1.0.bala + target/bala/sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal4.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal4.txt index f0062bbdaa94..93c59cf71f61 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal4.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal4.txt @@ -9,8 +9,8 @@ Creating bala The GraalVM compatibility property has not been defined for the package 'myproject'. This could potentially lead to compatibility issues with GraalVM. -To resolve this warning, please ensure that all Java dependencies of this package are compatible with GraalVM. Subsequently, update the Ballerina.toml file under the section '[platform.java17]' with the attribute 'graalvmCompatible = true'.Or, add 'graalvmCompatible = true' attribute to each Java dependency entry in Ballerina.toml. +To resolve this warning, please ensure that all Java dependencies of this package are compatible with GraalVM. Subsequently, update the Ballerina.toml file under the section '[platform.java21]' with the attribute 'graalvmCompatible = true'.Or, add 'graalvmCompatible = true' attribute to each Java dependency entry in Ballerina.toml. ************************************************************ - target/bala/sameera-myproject-java17-0.1.0.bala + target/bala/sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal5.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal5.txt index 095212c4bf36..959832cfb661 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal5.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal5.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target/bala/sameera-myproject-java17-0.1.0.bala + target/bala/sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal6.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal6.txt index 095212c4bf36..959832cfb661 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal6.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal6.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target/bala/sameera-myproject-java17-0.1.0.bala + target/bala/sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal7.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal7.txt index 095212c4bf36..959832cfb661 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal7.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs-graal7.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target/bala/sameera-myproject-java17-0.1.0.bala + target/bala/sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs.txt index f0062bbdaa94..93c59cf71f61 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-project-with-platform-libs.txt @@ -9,8 +9,8 @@ Creating bala The GraalVM compatibility property has not been defined for the package 'myproject'. This could potentially lead to compatibility issues with GraalVM. -To resolve this warning, please ensure that all Java dependencies of this package are compatible with GraalVM. Subsequently, update the Ballerina.toml file under the section '[platform.java17]' with the attribute 'graalvmCompatible = true'.Or, add 'graalvmCompatible = true' attribute to each Java dependency entry in Ballerina.toml. +To resolve this warning, please ensure that all Java dependencies of this package are compatible with GraalVM. Subsequently, update the Ballerina.toml file under the section '[platform.java21]' with the attribute 'graalvmCompatible = true'.Or, add 'graalvmCompatible = true' attribute to each Java dependency entry in Ballerina.toml. ************************************************************ - target/bala/sameera-myproject-java17-0.1.0.bala + target/bala/sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-tool-template.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-tool-template.txt index 3ce6ea5fb697..ce08d93f3f18 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-tool-template.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/unix/pack-tool-template.txt @@ -2,4 +2,4 @@ Compiling source testuserorg/tool_sample:0.1.0 Creating bala - target/bala/testuserorg-tool_sample-java17-0.1.0.bala + target/bala/testuserorg-tool_sample-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-with-platform-libs.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-with-platform-libs.txt index d8a99d53141a..b2320f75d0aa 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-with-platform-libs.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-with-platform-libs.txt @@ -2,4 +2,4 @@ Compiling source sameera/myproject:0.1.0 Creating bala - target\bala\sameera-myproject-java17-0.1.0.bala + target\bala\sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-wo-root-pkg-in-deps-toml.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-wo-root-pkg-in-deps-toml.txt index fa4f3ffa61a8..5aceca7ef098 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-wo-root-pkg-in-deps-toml.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/build-project-wo-root-pkg-in-deps-toml.txt @@ -4,4 +4,4 @@ WARNING [Dependencies.toml:(6:1,15:2)] Detected corrupted Dependencies.toml file WARNING [main.bal:(6:4,6:58)] unused variable 'isSuccess' Creating bala - target\bala\foo-winery-java17-0.1.0.bala + target\bala\foo-winery-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/compile-empty-project-with-compiler-plugin.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/compile-empty-project-with-compiler-plugin.txt index 8df7751db497..7777e6aaba14 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/compile-empty-project-with-compiler-plugin.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/compile-empty-project-with-compiler-plugin.txt @@ -2,4 +2,4 @@ Compiling source wso2/emptyProjWithCompilerPlugin:0.1.0 Creating bala - target\bala\wso2-emptyProjWithCompilerPlugin-java17-0.1.0.bala + target\bala\wso2-emptyProjWithCompilerPlugin-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/compile-empty-project-with-tool.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/compile-empty-project-with-tool.txt index 7d6cd6058b04..0be7355e9d74 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/compile-empty-project-with-tool.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/compile-empty-project-with-tool.txt @@ -2,4 +2,4 @@ Compiling source wso2/emptyProjWithTool:0.1.0 Creating bala - target\bala\wso2-emptyProjWithTool-java17-0.1.0.bala + target\bala\wso2-emptyProjWithTool-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-central-tool.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-central-tool.txt index 9bd1ea7d6277..4f75f339e2fe 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-central-tool.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-central-tool.txt @@ -2,4 +2,4 @@ Compiling source testorg/sample_tool_template:1.0.0 Creating bala - target\bala\testorg-sample_tool_template-java17-1.0.0.bala + target\bala\testorg-sample_tool_template-java21-1.0.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-empty-package-with-compiler-plugin.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-empty-package-with-compiler-plugin.txt index 63f2c61d599d..5f495f94a7b5 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-empty-package-with-compiler-plugin.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-empty-package-with-compiler-plugin.txt @@ -2,4 +2,4 @@ Compiling source user/LibraryProject:0.1.0 Creating bala - target\bala\user-LibraryProject-java17-0.1.0.bala + target\bala\user-LibraryProject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal1.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal1.txt index d8a99d53141a..b2320f75d0aa 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal1.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal1.txt @@ -2,4 +2,4 @@ Compiling source sameera/myproject:0.1.0 Creating bala - target\bala\sameera-myproject-java17-0.1.0.bala + target\bala\sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal2.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal2.txt index f7e7455fb5f7..248d41ba9e50 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal2.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal2.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target\bala\sameera-myproject-java17-0.1.0.bala + target\bala\sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal3.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal3.txt index f7e7455fb5f7..248d41ba9e50 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal3.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal3.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target\bala\sameera-myproject-java17-0.1.0.bala + target\bala\sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal4.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal4.txt index 879a7e42630b..9a3d8891174f 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal4.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal4.txt @@ -9,8 +9,8 @@ Creating bala The GraalVM compatibility property has not been defined for the package 'myproject'. This could potentially lead to compatibility issues with GraalVM. -To resolve this warning, please ensure that all Java dependencies of this package are compatible with GraalVM. Subsequently, update the Ballerina.toml file under the section '[platform.java17]' with the attribute 'graalvmCompatible = true'.Or, add 'graalvmCompatible = true' attribute to each Java dependency entry in Ballerina.toml. +To resolve this warning, please ensure that all Java dependencies of this package are compatible with GraalVM. Subsequently, update the Ballerina.toml file under the section '[platform.java21]' with the attribute 'graalvmCompatible = true'.Or, add 'graalvmCompatible = true' attribute to each Java dependency entry in Ballerina.toml. ************************************************************ - target\bala\sameera-myproject-java17-0.1.0.bala + target\bala\sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal5.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal5.txt index f7e7455fb5f7..248d41ba9e50 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal5.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal5.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target\bala\sameera-myproject-java17-0.1.0.bala + target\bala\sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal6.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal6.txt index f7e7455fb5f7..248d41ba9e50 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal6.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal6.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target\bala\sameera-myproject-java17-0.1.0.bala + target\bala\sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal7.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal7.txt index f7e7455fb5f7..248d41ba9e50 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal7.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs-graal7.txt @@ -13,4 +13,4 @@ To ensure this package can function seamlessly with GraalVM, it's recommended to ************************************************************ - target\bala\sameera-myproject-java17-0.1.0.bala + target\bala\sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs.txt index 879a7e42630b..9a3d8891174f 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-project-with-platform-libs.txt @@ -9,8 +9,8 @@ Creating bala The GraalVM compatibility property has not been defined for the package 'myproject'. This could potentially lead to compatibility issues with GraalVM. -To resolve this warning, please ensure that all Java dependencies of this package are compatible with GraalVM. Subsequently, update the Ballerina.toml file under the section '[platform.java17]' with the attribute 'graalvmCompatible = true'.Or, add 'graalvmCompatible = true' attribute to each Java dependency entry in Ballerina.toml. +To resolve this warning, please ensure that all Java dependencies of this package are compatible with GraalVM. Subsequently, update the Ballerina.toml file under the section '[platform.java21]' with the attribute 'graalvmCompatible = true'.Or, add 'graalvmCompatible = true' attribute to each Java dependency entry in Ballerina.toml. ************************************************************ - target\bala\sameera-myproject-java17-0.1.0.bala + target\bala\sameera-myproject-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-tool-template.txt b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-tool-template.txt index 396cac3db719..86335b7b6c1d 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-tool-template.txt +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-outputs/windows/pack-tool-template.txt @@ -2,4 +2,4 @@ Compiling source testuserorg/tool_sample:0.1.0 Creating bala - target\bala\testuserorg-tool_sample-java17-0.1.0.bala + target\bala\testuserorg-tool_sample-java21-0.1.0.bala diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-util/expected-ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/command-util/expected-ballerina.toml index 9a4c733a687c..bcba261419b1 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/command-util/expected-ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-util/expected-ballerina.toml @@ -2,7 +2,6 @@ org = "choreo" name = "gsheet_new_row_to_github_new_issue" version = "1.0.1" -export = ["gsheet_new_row_to_github_new_issue"] distribution = "slbeta6" keywords = ["Type/Webhook","Category/Integration","Internal/http"] icon = "docs/icon.png" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/command-util/sample-bala.json b/cli/ballerina-cli/src/test/resources/test-resources/command-util/sample-bala.json new file mode 100644 index 000000000000..fd0a01921270 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/command-util/sample-bala.json @@ -0,0 +1,4 @@ +{ + "bala_version": "2.0.0", + "built_by": "WSO2" +} \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/custom-repo/luheerathan-pact1-any-0.1.0.bala b/cli/ballerina-cli/src/test/resources/test-resources/custom-repo/luheerathan-pact1-any-0.1.0.bala index 95b924e2d5f1..034d49b4c6b1 100644 Binary files a/cli/ballerina-cli/src/test/resources/test-resources/custom-repo/luheerathan-pact1-any-0.1.0.bala and b/cli/ballerina-cli/src/test/resources/test-resources/custom-repo/luheerathan-pact1-any-0.1.0.bala differ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/inconsistentConflictedJars/correctJarPackage/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/inconsistentConflictedJars/correctJarPackage/Ballerina.toml index b9a31a88d363..1099dd7d71a3 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/inconsistentConflictedJars/correctJarPackage/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/inconsistentConflictedJars/correctJarPackage/Ballerina.toml @@ -4,29 +4,29 @@ name = "correctJarPackage" version = "0.1.0" distribution = "2201.0.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-handler-4.1.71.Final.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-handler-proxy-4.1.71.Final.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-codec-http-4.1.71.Final.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-codec-4.1.71.Final.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-codec-http2-4.1.71.Final.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-transport-4.1.71.Final.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-common-4.1.71.Final.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-resolver-4.1.71.Final.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./lib/netty-buffer-4.1.71.Final.jar" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/inconsistentConflictedJars/uberJarPackage/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/inconsistentConflictedJars/uberJarPackage/Ballerina.toml index 3323655e7b65..aafadc180dfd 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/inconsistentConflictedJars/uberJarPackage/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/inconsistentConflictedJars/uberJarPackage/Ballerina.toml @@ -4,7 +4,7 @@ name = "uberJarPackage" version = "0.1.0" distribution = "2201.0.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/redis-2.2.0.jar" groupId = "org.ballerinalang" artifactId = "redis-utils" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.1.0/java17/package.json b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.1.0/java17/package.json index 25e7a82eb4cf..6c5a1b55a9b2 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.1.0/java17/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.1.0/java17/package.json @@ -8,7 +8,7 @@ "ballerina_version": "2201.9.0-SNAPSHOT", "implementation_vendor": "WSO2", "language_spec_version": "2023R1", - "platform": "java17", + "platform": "java21", "graalvmCompatible": true, "template": false } \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.2.0/java17/package.json b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.2.0/java17/package.json index 03ed7d045493..7bd5cc76fd0d 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.2.0/java17/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.2.0/java17/package.json @@ -8,7 +8,7 @@ "ballerina_version": "2201.9.0-SNAPSHOT", "implementation_vendor": "WSO2", "language_spec_version": "2023R1", - "platform": "java17", + "platform": "java21", "graalvmCompatible": true, "template": false } \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.3.0/java17/package.json b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.3.0/java17/package.json index 3854d0043286..35fe68754ff4 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.3.0/java17/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/1.3.0/java17/package.json @@ -8,7 +8,7 @@ "ballerina_version": "2201.9.0-SNAPSHOT", "implementation_vendor": "WSO2", "language_spec_version": "2023R1", - "platform": "java17", + "platform": "java21", "graalvmCompatible": true, "template": false } \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/2.2.4/java17/package.json b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/2.2.4/java17/package.json index 32939af72c39..76307a75fec5 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/2.2.4/java17/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/2.2.4/java17/package.json @@ -8,7 +8,7 @@ "ballerina_version": "2201.9.0-SNAPSHOT", "implementation_vendor": "WSO2", "language_spec_version": "2023R1", - "platform": "java17", + "platform": "java21", "graalvmCompatible": true, "template": false } \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/2.2.5/java17/package.json b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/2.2.5/java17/package.json index 959fd9a8722b..faaa0b0dfe55 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/2.2.5/java17/package.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/local-tool-test/ballerina-cache/repositories/local/bala/gayaldassanayake/tool_gayal/2.2.5/java17/package.json @@ -8,7 +8,7 @@ "ballerina_version": "2201.9.0-SNAPSHOT", "implementation_vendor": "WSO2", "language_spec_version": "2023R1", - "platform": "java17", + "platform": "java21", "graalvmCompatible": true, "template": false } \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/print-utils-output/search-results.json b/cli/ballerina-cli/src/test/resources/test-resources/print-utils-output/search-results.json index 5f3b33b12890..cc36fb849969 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/print-utils-output/search-results.json +++ b/cli/ballerina-cli/src/test/resources/test-resources/print-utils-output/search-results.json @@ -41,7 +41,7 @@ "balaVersion": "1.0.0", "balaURL": "https://fileserver.central.ballerina.io/wso2/salesforce_to_mysql/1.1.2/any/salesforce_to_mysql-2020r1-any-1.1.2.bala", "summary": "Template for Salesforce to MySQL using Ballerina", - "readme": "Template for Salesforce to MySQL using Ballerina\n\n# Salesforce to MySQL using Ballerina \n\nThis is a template for [Salesforce to MySQL Database tutorial](https:\/\/ei.docs.wso2.com\/en\/latest\/ballerina-integrator\/learn\/tutorials\/saas-integrations\/sfdc46\/salesforce-to-mysql-db\/1\/). Please refer to it for more details on what you are going to build here. This template provides a starting point for your scenario. \n\n## Using the Template\n\nRun the following command to pull the `salesforce_to_mysql` template from Ballerina Central.\n\n```\n$ bal pull wso2\/salesforce_to_mysql\n```\n\nCreate a new project.\n\n```bash\n$ bal new salesforce-to-mysql-db\n```\n\nNow navigate into the above project directory you created and run the following command to apply the predefined template \nyou pulled earlier.\n\n```bash\n$ bal add salesforce_to_mysql -t wso2\/salesforce_to_mysql\n```\n\nThis automatically creates salesforce_to_mysql service for you inside the `src` directory of your project. \n\n## Testing\n\n### 1. Set up credentials for accessing Salesforce.\n\n- Visit [Salesforce](https:\/\/www.salesforce.com) and create a Salesforce account.\n\n- Create a connected app and obtain the following credentials:\n - Base URL (Endpoint)\n - Access Token\n - Client ID\n - Client Secret\n - Refresh Token\n - Refresh Token URL\n \n#### 2. Create a database and set up credentials\n\n- If you have not installed MySQL in your computer, Please install MySql on your local computer.\nVisit [here](https:\/\/dev.mysql.com\/downloads\/) to download and install MySQL. After installing configure configure\na MySQL user and obtain username and password.\n\n- Create a new database and create a new `contacts` table. You can use following SQL script to create the table\nand insert a data row in to the table.\n```SQL\nUSE sf_company;\nCREATE TABLE IF NOT EXISTS contacts (\n email varchar(255) NOT NULL,\n first_name varchar(255) NOT NULL,\n last_name varchar(255) NOT NULL,\n last_modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n PRIMARY KEY (email)\n);\nINSERT INTO contacts VALUES (\"johndoe@wso2.com\", \"John\", \"Doe\", CURRENT_TIMESTAMP);\n```\n\n#### 3. Add JDBC client connector\n\nSince we are using JDBC client for Database operations we need to create new directory called `lib` in the project\nroot directory and add `mysql-connector-java.jar` to the newly created `lib` directory. You can install\n`mysql-connector-java.jar` from [here](https:\/\/dev.mysql.com\/downloads\/connector\/j\/). After that you should edit\nyour `Ballerina.toml` file and mentioned the path to `mysql-connector-java.jar` as follows.\n\n```toml\n[project]\norg-name= \"wso2\"\nversion= \"0.1.0\"\n\n[dependencies]\n\n[platform]\ntarget = \"java17\"\n\n [[platform.libraries]]\n module = \"salesforce_to_mysql\"\n path = \".\/lib\/mysql-connector-java.jar\"\n```\n\n#### 4. Add project configurations file\n\nAdd the project configuration file by creating a `ballerina.conf` file under the root path of the project structure.\nThis file should have following configurations. Add the obtained Salesforce configurations and Database\nconfigurations to the file.\n\n```\nSF_BASE_URL=\"\"\nSF_ACCESS_TOKEN=\"\"\nSF_CLIENT_ID=\"\"\nSF_CLIENT_SECRET=\"\"\nSF_REFRESH_URL=\"\"\nSF_REFRESH_TOKEN=\"\"\nJDBC_URL=\"\"\nDB_USERNAME=\"\"\nDB_PASSWORD=\"\"\nSCHEDULER_INTERVAL_IN_MILLIS=\n```\n\nLet’s build the module. Navigate to the project root directory and execute the following command.\n\n```bash\n$ bal build salesforce_to_mysql\n```\n\nThis creates the executables. Now run the `salesforce_to_mysql.jar` file created in the above step.\n\n```bash\n$ java -jar target\/bin\/salesforce_to_mysql.jar\n```\n\nYou will see the following log after successfully updating the database.\n\n```\n2019-09-26 17:41:27,708 INFO [wso2\/sfdc_to_mysql_db] - service started...\n2019-09-26 17:41:32,094 INFO [wso2\/sfdc_to_mysql_db] - Batch job SFDC -> MySQL has been completed.\n```", + "readme": "Template for Salesforce to MySQL using Ballerina\n\n# Salesforce to MySQL using Ballerina \n\nThis is a template for [Salesforce to MySQL Database tutorial](https:\/\/ei.docs.wso2.com\/en\/latest\/ballerina-integrator\/learn\/tutorials\/saas-integrations\/sfdc46\/salesforce-to-mysql-db\/1\/). Please refer to it for more details on what you are going to build here. This template provides a starting point for your scenario. \n\n## Using the Template\n\nRun the following command to pull the `salesforce_to_mysql` template from Ballerina Central.\n\n```\n$ bal pull wso2\/salesforce_to_mysql\n```\n\nCreate a new project.\n\n```bash\n$ bal new salesforce-to-mysql-db\n```\n\nNow navigate into the above project directory you created and run the following command to apply the predefined template \nyou pulled earlier.\n\n```bash\n$ bal add salesforce_to_mysql -t wso2\/salesforce_to_mysql\n```\n\nThis automatically creates salesforce_to_mysql service for you inside the `src` directory of your project. \n\n## Testing\n\n### 1. Set up credentials for accessing Salesforce.\n\n- Visit [Salesforce](https:\/\/www.salesforce.com) and create a Salesforce account.\n\n- Create a connected app and obtain the following credentials:\n - Base URL (Endpoint)\n - Access Token\n - Client ID\n - Client Secret\n - Refresh Token\n - Refresh Token URL\n \n#### 2. Create a database and set up credentials\n\n- If you have not installed MySQL in your computer, Please install MySql on your local computer.\nVisit [here](https:\/\/dev.mysql.com\/downloads\/) to download and install MySQL. After installing configure configure\na MySQL user and obtain username and password.\n\n- Create a new database and create a new `contacts` table. You can use following SQL script to create the table\nand insert a data row in to the table.\n```SQL\nUSE sf_company;\nCREATE TABLE IF NOT EXISTS contacts (\n email varchar(255) NOT NULL,\n first_name varchar(255) NOT NULL,\n last_name varchar(255) NOT NULL,\n last_modified timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,\n PRIMARY KEY (email)\n);\nINSERT INTO contacts VALUES (\"johndoe@wso2.com\", \"John\", \"Doe\", CURRENT_TIMESTAMP);\n```\n\n#### 3. Add JDBC client connector\n\nSince we are using JDBC client for Database operations we need to create new directory called `lib` in the project\nroot directory and add `mysql-connector-java.jar` to the newly created `lib` directory. You can install\n`mysql-connector-java.jar` from [here](https:\/\/dev.mysql.com\/downloads\/connector\/j\/). After that you should edit\nyour `Ballerina.toml` file and mentioned the path to `mysql-connector-java.jar` as follows.\n\n```toml\n[project]\norg-name= \"wso2\"\nversion= \"0.1.0\"\n\n[dependencies]\n\n[platform]\ntarget = \"java21\"\n\n [[platform.libraries]]\n module = \"salesforce_to_mysql\"\n path = \".\/lib\/mysql-connector-java.jar\"\n```\n\n#### 4. Add project configurations file\n\nAdd the project configuration file by creating a `ballerina.conf` file under the root path of the project structure.\nThis file should have following configurations. Add the obtained Salesforce configurations and Database\nconfigurations to the file.\n\n```\nSF_BASE_URL=\"\"\nSF_ACCESS_TOKEN=\"\"\nSF_CLIENT_ID=\"\"\nSF_CLIENT_SECRET=\"\"\nSF_REFRESH_URL=\"\"\nSF_REFRESH_TOKEN=\"\"\nJDBC_URL=\"\"\nDB_USERNAME=\"\"\nDB_PASSWORD=\"\"\nSCHEDULER_INTERVAL_IN_MILLIS=\n```\n\nLet’s build the module. Navigate to the project root directory and execute the following command.\n\n```bash\n$ bal build salesforce_to_mysql\n```\n\nThis creates the executables. Now run the `salesforce_to_mysql.jar` file created in the above step.\n\n```bash\n$ java -jar target\/bin\/salesforce_to_mysql.jar\n```\n\nYou will see the following log after successfully updating the database.\n\n```\n2019-09-26 17:41:27,708 INFO [wso2\/sfdc_to_mysql_db] - service started...\n2019-09-26 17:41:32,094 INFO [wso2\/sfdc_to_mysql_db] - Batch job SFDC -> MySQL has been completed.\n```", "pullCount": 9, "template": false, "licenses": [ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/projectWithConflictedJars/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/projectWithConflictedJars/Ballerina.toml index 01fe3c76df95..f101d6b02c37 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/projectWithConflictedJars/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/projectWithConflictedJars/Ballerina.toml @@ -6,12 +6,12 @@ version= "0.1.7" [build-options] listConflictedClasses=true -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" groupId = "test-sample" artifactId = "one" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/two-1.0.0.jar" groupId = "test-sample" artifactId = "two" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/projectWithJava11and17PlatformLibs/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/projectWithJava11and17PlatformLibs/Ballerina.toml index 5cf8ae2461f3..49424154ef10 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/projectWithJava11and17PlatformLibs/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/projectWithJava11and17PlatformLibs/Ballerina.toml @@ -3,7 +3,7 @@ org = "sameera" name = "myproject" version = "0.1.0" -[platform.java17] +[platform.java21] graalvmCompatible = true [[platform.java11.dependency]] diff --git a/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedDependency/pkg_a/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedDependency/pkg_a/Ballerina.toml index 358610fa8828..3aa1d2064d6a 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedDependency/pkg_a/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedDependency/pkg_a/Ballerina.toml @@ -3,7 +3,7 @@ org = "foo" name = "pkg_a" version = "1.0.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "com.example" artifactId = "project1" version = "1.0" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedDependency/pkg_b/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedDependency/pkg_b/Ballerina.toml index fb03ae62db59..76c1e8de7290 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedDependency/pkg_b/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedDependency/pkg_b/Ballerina.toml @@ -3,13 +3,13 @@ org = "foo" name = "pkg_b" version = "1.0.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "com.example.greeting" artifactId = "testProject2" version = "1.0.0" path = "libs/testProject2-1.0.0.jar" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "com.example" artifactId = "project1" version = "1.0" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedScope/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedScope/Ballerina.toml index 358610fa8828..3aa1d2064d6a 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedScope/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/projectWithProvidedScope/Ballerina.toml @@ -3,7 +3,7 @@ org = "foo" name = "pkg_a" version = "1.0.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId = "com.example" artifactId = "project1" version = "1.0" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithNoMd/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithNoMd/Ballerina.toml new file mode 100644 index 000000000000..b19e4dff52d8 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithNoMd/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" diff --git a/tests/jballerina-integration-test/src/test/resources/packaging/distinct/test_project_distinct_foo_patch/Dependencies.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithNoMd/Dependencies.toml similarity index 56% rename from tests/jballerina-integration-test/src/test/resources/packaging/distinct/test_project_distinct_foo_patch/Dependencies.toml rename to cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithNoMd/Dependencies.toml index ffffcc1753a6..283398e54bee 100644 --- a/tests/jballerina-integration-test/src/test/resources/packaging/distinct/test_project_distinct_foo_patch/Dependencies.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithNoMd/Dependencies.toml @@ -5,13 +5,13 @@ [ballerina] dependencies-toml-version = "2" -distribution-version = "2201.6.0-SNAPSHOT" +distribution-version = "2201.10.0-SNAPSHOT" [[package]] -org = "testorg" -name = "distinct_foo" -version = "1.0.1" +org = "foo" +name = "winery" +version = "0.1.0" modules = [ - {org = "testorg", packageName = "distinct_foo", moduleName = "distinct_foo"} + {org = "foo", packageName = "winery", moduleName = "winery"} ] diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithNoMd/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithNoMd/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithNoMd/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithWrongMd/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithWrongMd/Ballerina.toml new file mode 100644 index 000000000000..7a7770ab598d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithWrongMd/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" +readme = "Package.md" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithWrongMd/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithWrongMd/README.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithWrongMd/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithWrongMd/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithWrongMd/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/libraryProjectWithWrongMd/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/Ballerina.toml new file mode 100644 index 000000000000..762a45a1e819 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/Ballerina.toml @@ -0,0 +1,9 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" +readme = "Package.md" + +[[package.modules]] +name = "winery.bar.storage" +readme = "modules/bar.storage/Module.md" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/Package.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/Package.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/Package.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/modules/bar.common/common.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/modules/bar.common/common.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/modules/bar.common/common.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/modules/bar.storage/Module.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/modules/bar.storage/Module.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/modules/bar.storage/Module.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/modules/bar.storage/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/modules/bar.storage/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithCustomReadmes/modules/bar.storage/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/Ballerina.toml new file mode 100644 index 000000000000..b19e4dff52d8 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/README.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/modules/bar.common/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/modules/bar.common/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/modules/bar.common/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/modules/bar.storage/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/modules/bar.storage/README.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/modules/bar.storage/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/modules/bar.storage/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/modules/bar.storage/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalModuleProjectWithReadmeMds/modules/bar.storage/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/Ballerina.toml new file mode 100644 index 000000000000..faf881d91722 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/Ballerina.toml @@ -0,0 +1,9 @@ +[package] +org = "foo" +name = "bar.winery" +version = "0.1.0" +readme = "Package.md" + +[[package.modules]] +name = "bar.winery.storage" +readme = "modules/storage/Module.md" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/Package.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/Package.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/Package.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/modules/common/common.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/modules/common/common.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/modules/common/common.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/modules/storage/Module.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/modules/storage/Module.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/modules/storage/Module.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/modules/storage/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/modules/storage/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithCustomReadmes/modules/storage/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/Ballerina.toml new file mode 100644 index 000000000000..8302a9eabeb1 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "foo" +name = "bar.winery" +version = "0.1.0" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/README.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/modules/common/common.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/modules/common/common.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/modules/common/common.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/modules/storage/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/modules/storage/README.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/modules/storage/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/modules/storage/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/modules/storage/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validHierarchicalPackageWithReadmeMds/modules/storage/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/Ballerina.toml new file mode 100644 index 000000000000..b19e4dff52d8 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/Ballerina.toml @@ -0,0 +1,4 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/Package.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/Package.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/Package.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/With-readme-Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/With-readme-Ballerina.toml new file mode 100644 index 000000000000..7a7770ab598d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/With-readme-Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" +readme = "Package.md" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validLibraryProjectWithOldMds/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/Ballerina.toml new file mode 100644 index 000000000000..ed8c03abd2a3 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/Ballerina.toml @@ -0,0 +1,9 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" +description = "Add the sample package description here" + +[[package.modules]] +name = "winery.storage" +readme = "modules/storage/Module.md" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/README.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/common/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/common/README.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/common/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/common/common.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/common/common.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/common/common.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/storage/Module.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/storage/Module.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/storage/Module.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/storage/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/storage/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectCustomModuleReadme/modules/storage/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/Ballerina.toml new file mode 100644 index 000000000000..ed8c03abd2a3 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/Ballerina.toml @@ -0,0 +1,9 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" +description = "Add the sample package description here" + +[[package.modules]] +name = "winery.storage" +readme = "modules/storage/Module.md" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/README.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/With-readme-for-non-default-mod-Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/With-readme-for-non-default-mod-Ballerina.toml new file mode 100644 index 000000000000..e8116dc88b2d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/With-readme-for-non-default-mod-Ballerina.toml @@ -0,0 +1,10 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" +readme = "Package.md" +description = "Add the sample package description here" + +[[package.modules]] +name = "winery.storage" +readme = "modules/storage/Module.md" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/modules/common/common.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/modules/common/common.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/modules/common/common.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/modules/storage/Module.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/modules/storage/Module.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/modules/storage/Module.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/modules/storage/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/modules/storage/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectOptionalModuleReadme/modules/storage/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/Ballerina.toml new file mode 100644 index 000000000000..f64d17110b87 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/Module.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/Module.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/Module.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/Package.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/Package.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/Package.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/With-readme-for-non-default-mod-Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/With-readme-for-non-default-mod-Ballerina.toml new file mode 100644 index 000000000000..e8116dc88b2d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/With-readme-for-non-default-mod-Ballerina.toml @@ -0,0 +1,10 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" +readme = "Package.md" +description = "Add the sample package description here" + +[[package.modules]] +name = "winery.storage" +readme = "modules/storage/Module.md" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/modules/storage/Module.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/modules/storage/Module.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/modules/storage/Module.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/modules/storage/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/modules/storage/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithPackageAndModuleMds/modules/storage/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/Ballerina.toml new file mode 100644 index 000000000000..f64d17110b87 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/README.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/modules/storage/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/modules/storage/README.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/modules/storage/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/modules/storage/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/modules/storage/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds/modules/storage/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/Ballerina.toml new file mode 100644 index 000000000000..f64d17110b87 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "foo" +name = "winery" +version = "0.1.0" + diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/README.md new file mode 100644 index 000000000000..95aff3ff853d --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Package Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/main.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/main.bal new file mode 100644 index 000000000000..6b71ef415c69 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/main.bal @@ -0,0 +1,2 @@ +public function main() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/modules/common/common.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/modules/common/common.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/modules/common/common.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/modules/storage/README.md b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/modules/storage/README.md new file mode 100644 index 000000000000..a74d612315bd --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/modules/storage/README.md @@ -0,0 +1,5 @@ +Prints "Hello World!" with a hello function. +[//]: # (above is the package summary) + +# Module Overview +Prints "Hello World!" as the output to the command line using a hello function. \ No newline at end of file diff --git a/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/modules/storage/storage.bal b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/modules/storage/storage.bal new file mode 100644 index 000000000000..31b97419c1a4 --- /dev/null +++ b/cli/ballerina-cli/src/test/resources/test-resources/readme-test-projects/validMultiModuleProjectWithReadmeMds2/modules/storage/storage.bal @@ -0,0 +1,2 @@ +public function func1() { +} diff --git a/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/.DS_Store b/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/.DS_Store deleted file mode 100644 index 1ecf824cf4e0..000000000000 Binary files a/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/.DS_Store and /dev/null differ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/Package.md b/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/Package.md deleted file mode 100644 index 43fd57fbd954..000000000000 --- a/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/Package.md +++ /dev/null @@ -1,4 +0,0 @@ -# Gayals Tool - -1. Run `bal pack` with the provided ballerina distribution pack -2. Extract the .bala file to `~.ballerina/repositories/central.ballerina.io/bala/ballerina/gayalstool/0.1.0/any/` diff --git a/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/target-dir/.DS_Store b/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/target-dir/.DS_Store deleted file mode 100644 index 9dae4ac68983..000000000000 Binary files a/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/target-dir/.DS_Store and /dev/null differ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/target-dir/bala/gayaldassanayake-tool_gayal-java17-1.1.0.bala b/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/target-dir/bala/gayaldassanayake-tool_gayal-java21-1.1.0.bala similarity index 71% rename from cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/target-dir/bala/gayaldassanayake-tool_gayal-java17-1.1.0.bala rename to cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/target-dir/bala/gayaldassanayake-tool_gayal-java21-1.1.0.bala index a16fe484cdc8..e184cf8b73de 100644 Binary files a/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/target-dir/bala/gayaldassanayake-tool_gayal-java17-1.1.0.bala and b/cli/ballerina-cli/src/test/resources/test-resources/tool-gayals/target-dir/bala/gayaldassanayake-tool_gayal-java21-1.1.0.bala differ diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validGraalvmCompatibleProject/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validGraalvmCompatibleProject/Ballerina.toml index 71f72951d827..eacf2a044129 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validGraalvmCompatibleProject/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validGraalvmCompatibleProject/Ballerina.toml @@ -3,8 +3,8 @@ org = "dilhashanazeer" name = "validGraalvmCompatibleProject" version = "0.1.0" -[platform.java17] +[platform.java21] graalvmCompatible = false -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithCustomMavenRepo/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithCustomMavenRepo/Ballerina.toml index 890ae3b2a4d5..1cc803ad4b3f 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithCustomMavenRepo/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithCustomMavenRepo/Ballerina.toml @@ -3,12 +3,12 @@ org = "foo" name = "winery" version = "0.1.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] groupId="org.ballerinalang" artifactId="ballerina-command-distribution" version="0.8.14" -[[platform.java17.repository]] +[[platform.java21.repository]] id="github-update-tool" url = "https://maven.pkg.github.com/ballerina-platform/ballerina-update-tool" username = "{{username}}" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibs1/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibs1/Ballerina.toml index 41c31351d3e8..41cb5d7c29fb 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibs1/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibs1/Ballerina.toml @@ -3,5 +3,5 @@ org = "sameera" name = "myproject" version = "0.1.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibs2/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibs2/Ballerina.toml index 70dde64969ce..70d10dbfb1a5 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibs2/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibs2/Ballerina.toml @@ -3,8 +3,8 @@ org = "sameera" name = "myproject" version = "0.1.0" -[platform.java17] +[platform.java21] graalvmCompatible = false -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal1/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal1/Ballerina.toml index ba86cda3eb2f..f26d0c6c0e83 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal1/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal1/Ballerina.toml @@ -3,6 +3,6 @@ org = "sameera" name = "myproject" version = "0.1.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" graalvmCompatible = true diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal2/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal2/Ballerina.toml index ec63fad03044..82659c3005bf 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal2/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal2/Ballerina.toml @@ -3,6 +3,6 @@ org = "sameera" name = "myproject" version = "0.1.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" graalvmCompatible = false diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal3/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal3/Ballerina.toml index d41c2c3982f0..646e1b09da5b 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal3/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal3/Ballerina.toml @@ -3,13 +3,13 @@ org = "sameera" name = "myproject" version = "0.1.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" graalvmCompatible = false -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.1.jar" graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.2.jar" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal4/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal4/Ballerina.toml index 2ae222682c36..028ff2c15d6e 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal4/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal4/Ballerina.toml @@ -3,9 +3,9 @@ org = "sameera" name = "myproject" version = "0.1.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.1.jar" graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.2.jar" diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal5/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal5/Ballerina.toml index bd7f83079d43..8b0c08cc77c6 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal5/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal5/Ballerina.toml @@ -6,6 +6,6 @@ version = "0.1.0" [platform.java17] graalvmCompatible = true -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" graalvmCompatible = false diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal6/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal6/Ballerina.toml index ff692c6b4ffe..f1e0c5c658d7 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal6/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal6/Ballerina.toml @@ -6,6 +6,6 @@ version = "0.1.0" [platform.java17] graalvmCompatible = false -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" graalvmCompatible = true diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal7/Ballerina.toml b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal7/Ballerina.toml index cecc9d12115d..fa8dab31145a 100644 --- a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal7/Ballerina.toml +++ b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithPlatformLibsGraal7/Ballerina.toml @@ -3,7 +3,7 @@ org = "sameera" name = "myproject" version = "0.1.0" -[[platform.java17.dependency]] +[[platform.java21.dependency]] path = "./libs/one-1.0.0.jar" graalvmCompatible = true diff --git a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithTarget/target-dir/bala/foo-winery-any-0.1.0.bala b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithTarget/target-dir/bala/foo-winery-any-0.1.0.bala index aeb16e70abaa..20eb1a2f5229 100644 Binary files a/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithTarget/target-dir/bala/foo-winery-any-0.1.0.bala and b/cli/ballerina-cli/src/test/resources/test-resources/validProjectWithTarget/target-dir/bala/foo-winery-any-0.1.0.bala differ diff --git a/cli/central-client/src/main/java/org/ballerinalang/central/client/CentralAPIClient.java b/cli/central-client/src/main/java/org/ballerinalang/central/client/CentralAPIClient.java index 0e4b688ec97c..f791bd71cee0 100644 --- a/cli/central-client/src/main/java/org/ballerinalang/central/client/CentralAPIClient.java +++ b/cli/central-client/src/main/java/org/ballerinalang/central/client/CentralAPIClient.java @@ -54,6 +54,7 @@ import java.io.IOException; import java.io.PrintStream; import java.net.Proxy; +import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -140,6 +141,8 @@ public class CentralAPIClient { private static final String ERR_PACKAGE_UN_DEPRECATE = "error: failed to undo deprecation of the package: "; private static final String ERR_PACKAGE_RESOLUTION = "error: while connecting to central: "; private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + private static final MediaType JSON_CONTENT_TYPE = MediaType.parse("application/json"); + // System property name for enabling central verbose public static final String SYS_PROP_CENTRAL_VERBOSE_ENABLED = "CENTRAL_VERBOSE_ENABLED"; private static final int DEFAULT_CONNECT_TIMEOUT = 60; @@ -1346,20 +1349,19 @@ public void deprecatePackage(String packageInfo, String deprecationMsg, String s } /** - * Get packages from central. + * Get packages information using graphql API. * - * @param params Search query param map. - * @param supportedPlatform The supported platform. - * @param ballerinaVersion The ballerina version. - * @return Package list - * @throws CentralClientException Central client exception. + * @param query payload query + * @param supportedPlatform supported platform + * @param ballerinaVersion ballerina version + * @return {@link JsonElement} Json Response */ - public JsonElement getPackages(Map params, String supportedPlatform, String ballerinaVersion) + public JsonElement getCentralPackagesUsingGraphQL(String query, String supportedPlatform, String ballerinaVersion) throws CentralClientException { Optional body = Optional.empty(); OkHttpClient client = new OkHttpClient.Builder() .followRedirects(false) - .connectTimeout(connectTimeout, TimeUnit.SECONDS) + .connectTimeout(callTimeout, TimeUnit.SECONDS) .readTimeout(readTimeout, TimeUnit.SECONDS) .writeTimeout(writeTimeout, TimeUnit.SECONDS) .callTimeout(callTimeout, TimeUnit.SECONDS) @@ -1367,31 +1369,25 @@ public JsonElement getPackages(Map params, String supportedPlatf .build(); try { - HttpUrl.Builder httpBuilder = Objects.requireNonNull(HttpUrl.parse(this.baseUrl)) - .newBuilder().addPathSegment(PACKAGES); - for (Map.Entry param : params.entrySet()) { - httpBuilder.addQueryParameter(param.getKey(), param.getValue()); - } - - Request searchReq = getNewRequest(supportedPlatform, ballerinaVersion) - .get() - .url(httpBuilder.build()) + HttpUrl.Builder httpUrl = Objects.requireNonNull(HttpUrl.parse(this.baseUrl)).newBuilder(); + Request request = getNewRequest(supportedPlatform, ballerinaVersion) + .url(httpUrl.build()) + .post(RequestBody.create(JSON_CONTENT_TYPE, query.getBytes(StandardCharsets.UTF_8))) .build(); - Call httpRequestCall = client.newCall(searchReq); - Response searchResponse = httpRequestCall.execute(); - - ResponseBody responseBody = searchResponse.body(); + Call httpRequest = client.newCall(request); + Response response = httpRequest.execute(); + ResponseBody responseBody = response.body(); body = responseBody != null ? Optional.of(responseBody) : Optional.empty(); if (body.isPresent()) { MediaType contentType = body.get().contentType(); if (contentType != null && isApplicationJsonContentType(contentType.toString()) && - searchResponse.code() == HttpsURLConnection.HTTP_OK) { + response.code() == HttpsURLConnection.HTTP_OK) { return new Gson().toJsonTree(body.get().string()); } } - handleResponseErrors(searchResponse, ERR_CANNOT_SEARCH); - return new JsonArray(); + handleResponseErrors(response, ERR_CANNOT_SEARCH); + return new JsonObject(); } catch (IOException e) { throw new CentralClientException(ERR_CANNOT_SEARCH + "'. Reason: " + e.getMessage()); } finally { diff --git a/cli/central-client/src/test/java/org/ballerinalang/central/client/TestCentralApiClient.java b/cli/central-client/src/test/java/org/ballerinalang/central/client/TestCentralApiClient.java index 3450d1f985f4..03f3ba0b8ba0 100644 --- a/cli/central-client/src/test/java/org/ballerinalang/central/client/TestCentralApiClient.java +++ b/cli/central-client/src/test/java/org/ballerinalang/central/client/TestCentralApiClient.java @@ -90,7 +90,7 @@ public class TestCentralApiClient extends CentralAPIClient { private static final String TEST_BAL_VERSION = "slp5"; private static final String ANY_PLATFORM = "any"; private static final String TEST_BALA_NAME = "sf-any.bala"; - private static final String TEST_TOOL_BALA_NAME = "baz-toolbox-java17-0.1.0.bala"; + private static final String TEST_TOOL_BALA_NAME = "baz-toolbox-java21-0.1.0.bala"; private static final String OUTPUT_BALA = "output.bala"; private static final String WINERY = "winery"; private static final String ACCESS_TOKEN = "273cc9f6-c333-36ab-aa2q-f08e9513ff5y"; @@ -859,7 +859,7 @@ public void testSearchTool() throws IOException, CentralClientException { public void testPullTool() throws IOException, CentralClientException { Path balaPath = UTILS_TEST_RESOURCES.resolve(TEST_TOOL_BALA_NAME); File balaFile = new File(String.valueOf(balaPath)); - String balaFileName = "attachment; filename=baz-toolbox-java17-0.1.0.bala"; + String balaFileName = "attachment; filename=baz-toolbox-java21-0.1.0.bala"; try (InputStream ignored = new FileInputStream(balaFile)) { Request mockRequest = new Request.Builder() @@ -869,13 +869,13 @@ public void testPullTool() throws IOException, CentralClientException { .addHeader(ACCEPT, APPLICATION_OCTET_STREAM) .build(); String toolBalaUrl = "https://fileserver.dev-central.ballerina.io/2.0/wso2/toolbox/0.1.0/" + - "baz-toolbox-java17-0.1.0.bala"; + "baz-toolbox-java21-0.1.0.bala"; ResponseBody mockResponseBody = ResponseBody.create(MediaType.parse("application/json"), "{\n" + " \"organization\": \"baz\",\n" + " \"name\": \"toolbox\",\n" + " \"version\": \"0.1.0\",\n" + " \"balaURL\": \"" + toolBalaUrl + "\",\n" + - " \"platform\": \"java17\",\n" + + " \"platform\": \"java21\",\n" + " \"digest\": \"sha-256=623bae28884bbc9cd61eb684acf7921cf43cb1d19ed0e36766bf6a75b0cdb15b\"\n}"); Response mockResponse = new Response.Builder() .request(mockRequest) @@ -909,7 +909,7 @@ public void testPullTool() throws IOException, CentralClientException { System.setProperty(CentralClientConstants.ENABLE_OUTPUT_STREAM, "true"); this.pullTool("sample_tool", "0.1.0", TMP_DIR, ANY_PLATFORM, TEST_BAL_VERSION, false); - Path balaDir = TMP_DIR.resolve("baz").resolve("toolbox").resolve("0.1.0").resolve("java17"); + Path balaDir = TMP_DIR.resolve("baz").resolve("toolbox").resolve("0.1.0").resolve("java21"); Assert.assertTrue(balaDir.toFile().exists()); Assert.assertTrue(balaDir.resolve("bala.json").toFile().exists()); Assert.assertTrue(balaDir.resolve("modules").toFile().exists()); @@ -1059,7 +1059,7 @@ public void testPullToolConnectionReset1() throws CentralClientException, IOExce String retryOutput = "* Retrying to pull the tool: foosf:1.3.5 due to: error" + ": Connection reset. Retry attempt: "; String responseBody = "{\"id\":14069, \"organization\":\"foo\", \"name\":\"sf\", \"version\":\"1.3.5\", " + - "\"platform\":\"java17\", \"balaURL\":\"" + this.balaUrl + "\", " + + "\"platform\":\"java21\", \"balaURL\":\"" + this.balaUrl + "\", " + "\"digest\":\"sha-256=47e043c80d516234b1e6bd93140f126c9d9e79b5c7c0600cc6316d12504c2cf4\"}"; Path balaPath = UTILS_TEST_RESOURCES.resolve(TEST_BALA_NAME); File balaFile = new File(String.valueOf(balaPath)); @@ -1126,7 +1126,7 @@ public void testPullToolConnectionReset2() throws IOException { String retryOutput = "* Retrying to pull the tool: foosf:1.3.5 due to: error" + ": Connection reset. Retry attempt: "; String responseBody = "{\"id\":14069, \"organization\":\"foo\", \"name\":\"sf\", \"version\":\"1.3.5\", " + - "\"platform\":\"java17\", \"balaURL\":\"" + this.balaUrl + "\", " + + "\"platform\":\"java21\", \"balaURL\":\"" + this.balaUrl + "\", " + "\"digest\":\"sha-256=47e043c80d516234b1e6bd93140f126c9d9e79b5c7c0600cc6316d12504c2cf4\"}"; Path balaPath = UTILS_TEST_RESOURCES.resolve(TEST_BALA_NAME); File balaFile = new File(String.valueOf(balaPath)); diff --git a/cli/central-client/src/test/resources/test-resources/utils/baz-toolbox-java17-0.1.0.bala b/cli/central-client/src/test/resources/test-resources/utils/baz-toolbox-java17-0.1.0.bala deleted file mode 100644 index f9385d5b74c2..000000000000 Binary files a/cli/central-client/src/test/resources/test-resources/utils/baz-toolbox-java17-0.1.0.bala and /dev/null differ diff --git a/cli/central-client/src/test/resources/test-resources/utils/baz-toolbox-java21-0.1.0.bala b/cli/central-client/src/test/resources/test-resources/utils/baz-toolbox-java21-0.1.0.bala new file mode 100644 index 000000000000..786fbdf90775 Binary files /dev/null and b/cli/central-client/src/test/resources/test-resources/utils/baz-toolbox-java21-0.1.0.bala differ diff --git a/cli/central-client/src/test/resources/test-resources/utils/toolSearch.json b/cli/central-client/src/test/resources/test-resources/utils/toolSearch.json index 8b106dbfe7bb..f889e283f3a3 100644 --- a/cli/central-client/src/test/resources/test-resources/utils/toolSearch.json +++ b/cli/central-client/src/test/resources/test-resources/utils/toolSearch.json @@ -5,13 +5,13 @@ "organization": "ballerinax", "name": "health", "version": "2.1.1", - "platform": "java17", + "platform": "java21", "languageSpecificationVersion": "2023R1", "isDeprecated": false, "deprecateMessage": "", "URL": "/ballerinax/health/2.1.1", "balaVersion": "2.0.0", - "balaURL": "https://fileserver.dev-central.ballerina.io/2.0/ballerinax/health/2.1.1/ballerinax-health-java17-2.1.1.bala?Expires=1711434534&Signature=KDIhOMa3atru1UcXlF0ZGoGolYESt83vipe5guAA9ZXoTqTUnD10daOUcJhG-zyW9VaYVQHWh-XZ8QOJqKmCIrQ30JN8D7M2NFk-0DWN7H173UoVVs0IVmEjAfYrOWRmowoOCUMDOs7y6AOLo57W~oapeNrvGpAb~EQUiuIepK5PdF9JzO6gDXPWpyfSHUEhRENqcRdUv-DBSsYo~aWjG8E-DBxsKwa68SRznO~ebUhSaGZPS8wAfuXspsaps7nh0XyM22EAqEpxaE302L5FM7ufmnh3norDDw5Xqi8b3COHk4X64SWmYyHDuRAAcc39Y4bZ0d0nzVxn6P2hba3hyQ__&Key-Pair-Id=K1LACXT8B3Y0DU", + "balaURL": "https://fileserver.dev-central.ballerina.io/2.0/ballerinax/health/2.1.1/ballerinax-health-java21-2.1.1.bala?Expires=1711434534&Signature=KDIhOMa3atru1UcXlF0ZGoGolYESt83vipe5guAA9ZXoTqTUnD10daOUcJhG-zyW9VaYVQHWh-XZ8QOJqKmCIrQ30JN8D7M2NFk-0DWN7H173UoVVs0IVmEjAfYrOWRmowoOCUMDOs7y6AOLo57W~oapeNrvGpAb~EQUiuIepK5PdF9JzO6gDXPWpyfSHUEhRENqcRdUv-DBSsYo~aWjG8E-DBxsKwa68SRznO~ebUhSaGZPS8wAfuXspsaps7nh0XyM22EAqEpxaE302L5FM7ufmnh3norDDw5Xqi8b3COHk4X64SWmYyHDuRAAcc39Y4bZ0d0nzVxn6P2hba3hyQ__&Key-Pair-Id=K1LACXT8B3Y0DU", "digest": "sha-256=39f2ca85b12f291044301ac3cc7b9b3f73bbf4dff1b1b4172e9c340233bd3aca", "summary": "This project contains an extension implementation for Ballerina CLI that generates", "readme": "", diff --git a/compiler/ballerina-lang/spotbugs-exclude.xml b/compiler/ballerina-lang/spotbugs-exclude.xml index 601166b8aaff..01f5d928a3e3 100644 --- a/compiler/ballerina-lang/spotbugs-exclude.xml +++ b/compiler/ballerina-lang/spotbugs-exclude.xml @@ -271,6 +271,10 @@ + + + + @@ -425,7 +429,7 @@ - + @@ -483,11 +487,17 @@ - + + + + + + diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BalaWriter.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BalaWriter.java index 0d5e8ca23d67..55759f02f5b3 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BalaWriter.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BalaWriter.java @@ -49,6 +49,7 @@ import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -105,7 +106,7 @@ public Path write(Path balaPath) { this.packageContext.packageName().value(), this.packageContext.packageVersion().value().toString(), this.target); - // Create the archive over write if exists + // Create the archive overwrite if exists try (ZipOutputStream balaOutputStream = new ZipOutputStream( new FileOutputStream(String.valueOf(balaPath.resolve(balaName))))) { // Now lets put stuff in @@ -129,8 +130,7 @@ private void populateBalaArchive(ZipOutputStream balaOutputStream) addBalaJson(balaOutputStream); addPackageDoc(balaOutputStream, - this.packageContext.project().sourceRoot(), - this.packageContext.packageName().toString()); + this.packageContext.packageManifest()); addPackageSource(balaOutputStream); addResources(balaOutputStream); addIncludes(balaOutputStream); @@ -167,6 +167,7 @@ private void addPackageJson(ZipOutputStream balaOutputStream, Optional modules = new ArrayList<>(); + String packageDocPathPrefix = BALA_DOCS_DIR + UNIX_FILE_SEPARATOR; + + List moduleList = packageManifest.modules(); + for (PackageManifest.Module module : moduleList) { + String moduleDoc = null; + if (module.readme() != null && !module.readme().isEmpty()) { + moduleDoc = packageDocPathPrefix + MODULES_ROOT + UNIX_FILE_SEPARATOR + module.name() + + UNIX_FILE_SEPARATOR + Paths.get(module.readme()).getFileName(); + } + modules.add(new PackageManifest.Module( + module.name(), + module.export(), + module.description(), + moduleDoc)); + } + packageJson.setModules(modules); + } + private void setGraalVMCompatibilityProperty(PackageJson packageJson, PackageManifest packageManifest) { Map platforms = packageManifest.platforms(); Boolean allPlatformDepsGraalvmCompatible = isAllPlatformDepsGraalvmCompatible(packageManifest.platforms()); @@ -253,20 +284,19 @@ private String otherPlatformGraalvmCompatibleVerified(String target, // TODO when iterating and adding source files should create source files from Package sources - private void addPackageDoc(ZipOutputStream balaOutputStream, Path packageSourceDir, String pkgName) + private void addPackageDoc(ZipOutputStream balaOutputStream, PackageManifest packageManifest) throws IOException { - final String packageMdFileName = "Package.md"; - final String moduleMdFileName = "Module.md"; - Path packageMd = packageSourceDir.resolve(packageMdFileName); + if (packageManifest.readme() == null) { + return; + } + Path sourceRoot = this.packageContext.project().sourceRoot; + Path pkgReadme = Paths.get(packageManifest.readme()); Path docsDirInBala = Path.of(BALA_DOCS_DIR); - // If `Package.md` exists, create the docs directory & add `Package.md` - if (packageMd.toFile().exists()) { - Path packageMdInBala = docsDirInBala.resolve(packageMdFileName); - putZipEntry(balaOutputStream, packageMdInBala, - new FileInputStream(String.valueOf(packageMd))); - } + Path packageMdInBala = docsDirInBala.resolve(pkgReadme.getFileName()); + putZipEntry(balaOutputStream, packageMdInBala, + new FileInputStream(pkgReadme.toString())); // If `icon` mentioned in the Ballerina.toml, add it to docs directory String icon = this.packageContext.packageManifest().icon(); @@ -276,35 +306,16 @@ private void addPackageDoc(ZipOutputStream balaOutputStream, Path packageSourceD putZipEntry(balaOutputStream, iconInBala, new FileInputStream(String.valueOf(iconPath))); } - // If `Module.md` of default module exists, create `docs/modules` directory & add `Module.md` - Path defaultModuleMd = packageSourceDir.resolve(moduleMdFileName); Path modulesDirInBalaDocs = docsDirInBala.resolve(MODULES_ROOT); - if (defaultModuleMd.toFile().exists()) { - Path defaultModuleMdInBalaDocs = modulesDirInBalaDocs.resolve(pkgName).resolve(moduleMdFileName); - putZipEntry(balaOutputStream, defaultModuleMdInBalaDocs, - new FileInputStream(String.valueOf(defaultModuleMd))); - } - - // Add other module docs - File modulesSourceDir = new File(String.valueOf(packageSourceDir.resolve(MODULES_ROOT))); - File[] directoryListing = modulesSourceDir.listFiles(); - - if (directoryListing != null) { - for (File moduleDir : directoryListing) { - if (moduleDir.isDirectory()) { - // Get `Module.md` path - Path otherModuleMd = packageSourceDir.resolve(MODULES_ROOT).resolve(moduleDir.getName()) - .resolve(moduleMdFileName); - // Create `package.module` folder, if `Module.md` path exists - if (otherModuleMd.toFile().exists()) { - Path otherModuleMdInBalaDocs = modulesDirInBalaDocs.resolve(pkgName + "." + moduleDir.getName()) - .resolve(moduleMdFileName); - putZipEntry(balaOutputStream, otherModuleMdInBalaDocs, - new FileInputStream(String.valueOf(otherModuleMd))); - } - } + for (PackageManifest.Module module : packageManifest.modules()) { + if (module.readme() == null || module.readme().isEmpty()) { + continue; } + Path otherReadmeMdInBalaDocs = modulesDirInBalaDocs.resolve(module.name()) + .resolve(Paths.get(module.readme()).getFileName()); + putZipEntry(balaOutputStream, otherReadmeMdInBalaDocs, + new FileInputStream(sourceRoot.resolve(module.readme()).toString())); } } 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 474da65ac555..c73a5f91c9f5 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 @@ -606,9 +606,6 @@ private void performOptimizedCodeGen(ModuleContext moduleContext) { CompiledJarFile compiledJarFile = jvmCodeGenerator.generate(bLangPackage, bLangPackage.symbol.shouldGenerateDuplicateBIR, isRemoteMgtEnabled); - if (compiledJarFile == null) { - throw new IllegalStateException("Missing generated jar, module: " + moduleContext.moduleName()); - } String jarFileName = getJarFileName(moduleContext) + JAR_FILE_NAME_SUFFIX; if (bLangPackage.symbol.shouldGenerateDuplicateBIR) { jarFileName = getJarFileName(moduleContext) + "_OPTIMIZED" + JAR_FILE_NAME_SUFFIX; @@ -650,10 +647,6 @@ private void duplicateCodegen(ModuleContext moduleContext, boolean isRemoteMgtEn return; } CompiledJarFile originalJarFile = jvmCodeGenerator.generate(bLangPackage, false, isRemoteMgtEnabled); - if (originalJarFile == null) { - throw new IllegalStateException("Missing generated jar, module: " + moduleContext.moduleName()); - } - bLangPackage.symbol.bir = optimizableBirPkg; String jarFileName = getJarFileName(moduleContext) + JAR_FILE_NAME_SUFFIX; try { @@ -1109,14 +1102,13 @@ private Path emitGraalExecutable(Path executableFilePath, List emitR nativeImageName = fileName.substring(0, fileName.lastIndexOf(DOT)); nativeArgs.addAll(Arrays.asList(graalVMBuildOptions, "-jar", executableFilePath.toString(), - "-H:Name=" + nativeImageName, + "-o " + executableFilePath.getParent() + "/" + nativeImageName, "--no-fallback")); } else { nativeImageName = project.currentPackage().packageName().toString(); nativeArgs.addAll(Arrays.asList(graalVMBuildOptions, "-jar", executableFilePath.toString(), - "-H:Name=" + nativeImageName, - "-H:Path=" + executableFilePath.getParent(), + "-o " + executableFilePath.getParent() + "/" + nativeImageName, "--no-fallback")); } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBalaWriter.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBalaWriter.java index fac6f51d05c2..2d4a7051f462 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBalaWriter.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JBallerinaBalaWriter.java @@ -85,7 +85,7 @@ protected Optional addPlatformLibs(ZipOutputStream balaOutputStream) // -- Bala Root // - libs // - platform - // - java17 + // - java21 // - java-library1.jar // - java-library2.jar JsonArray newPlatformLibs = new JsonArray(); @@ -227,7 +227,7 @@ protected void addBalTool(ZipOutputStream balaOutputStream) throws IOException { } /** - * Mark target platform as `java17` if one of the following condition fulfils. + * Mark target platform as `java21` if one of the following condition fulfils. * 1) Direct dependencies of imports in the package have any `ballerina/java` dependency. * 2) Package has defined any platform dependency. * diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JarResolver.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JarResolver.java index 6d792c4b61fe..56ef0ebedc45 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JarResolver.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JarResolver.java @@ -70,7 +70,7 @@ public class JarResolver { private final List providedPlatformLibs; private ClassLoader classLoaderWithAllJars; - public Set optimizedJarLibraryPaths = new HashSet<>(); + private Set optimizedJarLibraryPaths = new HashSet<>(); JarResolver(JBallerinaBackend jBalBackend, PackageResolution pkgResolution) { this.jBalBackend = jBalBackend; @@ -406,4 +406,8 @@ public static String getQualifiedClassName(String orgName, String packageName, S } return className; } + + public Set getOptimizedJarLibraryPaths() { + return optimizedJarLibraryPaths; + } } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JvmTarget.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JvmTarget.java index f252659873fe..c249850d1aa7 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JvmTarget.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/JvmTarget.java @@ -24,6 +24,7 @@ */ // TODO move this class to a separate Java package. e.g. io.ballerina.projects.platform.jballerina public enum JvmTarget implements CompilerBackend.TargetPlatform { + JAVA_21("java21"), JAVA_17("java17"), JAVA_11("java11"); diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/Module.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/Module.java index f686084bef85..495974b09f38 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/Module.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/Module.java @@ -43,7 +43,8 @@ public class Module { private final Map testSrcDocs; private final Function populateDocumentFunc; - private Optional moduleMd = null; + private Optional moduleMd = Optional.empty(); + private ModuleReadmeMd readmeMd = null; Module(ModuleContext moduleContext, Package packageInstance) { this.moduleContext = moduleContext; @@ -133,10 +134,18 @@ public Modifier modify() { return new Modifier(this); } + @Deprecated (forRemoval = true) ModuleContext moduleContext() { return moduleContext; } + /** + * Returns the ModuleMd document. + * + * @return ModuleMd + * @deprecated use {@link #readmeMd()} instead. + */ + @Deprecated (forRemoval = true, since = "2.11.0") public Optional moduleMd() { if (null == this.moduleMd) { this.moduleMd = this.moduleContext.moduleMdContext().map(c -> @@ -146,6 +155,15 @@ public Optional moduleMd() { return this.moduleMd; } + public Optional readmeMd() { + if (null == this.readmeMd) { + this.readmeMd = this.moduleContext.readmeMdContext().map(c -> + ModuleReadmeMd.from(c, this)).orElse(null); + + } + return Optional.ofNullable(this.readmeMd); + } + private static class DocumentIterable implements Iterable { private final Collection documentList; @@ -187,7 +205,7 @@ private Modifier(Module oldModule) { dependencies = oldModule.moduleContext().moduleDescDependencies(); packageInstance = oldModule.packageInstance; project = oldModule.project(); - moduleMdContext = oldModule.moduleContext.moduleMdContext().orElse(null); + moduleMdContext = oldModule.moduleContext.readmeMdContext().orElse(null); } Modifier updateDocument(DocumentContext newDocContext) { diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleConfig.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleConfig.java index 2898d66560f2..1ccb6b608850 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleConfig.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleConfig.java @@ -32,20 +32,20 @@ public class ModuleConfig { private final List srcDocs; private final List testSrcDocs; private final List dependencies; - private final DocumentConfig moduleMd; + private final DocumentConfig readmeMd; private ModuleConfig(ModuleId moduleId, ModuleDescriptor moduleDescriptor, List srcDocs, List testSrcDocs, - DocumentConfig moduleMd, + DocumentConfig readmeMd, List dependencies) { this.moduleId = moduleId; this.moduleDescriptor = moduleDescriptor; this.srcDocs = srcDocs; this.testSrcDocs = testSrcDocs; this.dependencies = dependencies; - this.moduleMd = moduleMd; + this.readmeMd = readmeMd; } public static ModuleConfig from(ModuleId moduleId, @@ -93,8 +93,13 @@ public List dependencies() { return dependencies; } + @Deprecated (forRemoval = true, since = "2.11.0") public Optional moduleMd() { - return Optional.ofNullable(this.moduleMd); + return Optional.ofNullable(this.readmeMd); + } + + public Optional readmeMd() { + return Optional.ofNullable(this.readmeMd); } @Deprecated(since = "2201.10.0", forRemoval = true) 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 df579c0aa17b..1975f7cc582e 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 @@ -76,7 +76,7 @@ class ModuleContext { private final boolean isDefaultModule; private final Map srcDocContextMap; private final Collection testSrcDocIds; - private final MdDocumentContext moduleMdContext; + private final MdDocumentContext readmeMdContext; private final Map testDocContextMap; private final Project project; private final CompilationCache compilationCache; @@ -97,7 +97,7 @@ class ModuleContext { boolean isDefaultModule, Map srcDocContextMap, Map testDocContextMap, - MdDocumentContext moduleMd, + MdDocumentContext readmeMd, List moduleDescDependencies) { this.project = project; this.moduleId = moduleId; @@ -107,7 +107,7 @@ class ModuleContext { this.srcDocIds = Collections.unmodifiableCollection(srcDocContextMap.keySet()); this.testDocContextMap = testDocContextMap; this.testSrcDocIds = Collections.unmodifiableCollection(testDocContextMap.keySet()); - this.moduleMdContext = moduleMd; + this.readmeMdContext = readmeMd; this.moduleDescDependencies = Collections.unmodifiableList(moduleDescDependencies); @@ -131,7 +131,7 @@ static ModuleContext from(Project project, ModuleConfig moduleConfig, boolean di return new ModuleContext(project, moduleConfig.moduleId(), moduleConfig.moduleDescriptor(), moduleConfig.isDefaultModule(), srcDocContextMap, testDocContextMap, - moduleConfig.moduleMd().map(c ->MdDocumentContext.from(c)).orElse(null), + moduleConfig.readmeMd().map(c ->MdDocumentContext.from(c)).orElse(null), moduleConfig.dependencies()); } @@ -561,8 +561,13 @@ static void shrinkDocuments(ModuleContext moduleContext) { moduleContext.srcDocContextMap.values().forEach(DocumentContext::shrink); } + @Deprecated (forRemoval = true) Optional moduleMdContext() { - return Optional.ofNullable(this.moduleMdContext); + return Optional.ofNullable(this.readmeMdContext); + } + + public Optional readmeMdContext() { + return Optional.ofNullable(readmeMdContext); } ModuleContext duplicate(Project project) { @@ -578,7 +583,7 @@ ModuleContext duplicate(Project project) { testDocContextMap.put(documentId, documentContext.duplicate()); } return new ModuleContext(project, this.moduleId, this.moduleDescriptor, this.isDefaultModule, - srcDocContextMap, testDocContextMap, this.moduleMdContext().orElse(null), + srcDocContextMap, testDocContextMap, this.readmeMdContext().orElse(null), this.moduleDescDependencies); } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleMd.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleMd.java index 43da5eac1d9b..4f025c108aaf 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleMd.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleMd.java @@ -22,7 +22,9 @@ * Represents the 'Module.md' file of a module. * * @since 2.0.0 + * @deprecated use {@link ModuleReadmeMd} instead */ +@Deprecated (forRemoval = true, since = "2.11.0") public class ModuleMd { private final MdDocumentContext mdDocumentContext; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleReadmeMd.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleReadmeMd.java new file mode 100644 index 000000000000..36a1516df343 --- /dev/null +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/ModuleReadmeMd.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 io.ballerina.projects; + +/** + * Represents the README file of a module. + * + * @since 2.11.0 + */ +public class ModuleReadmeMd { + + private final MdDocumentContext mdDocumentContext; + private final Module module; + + ModuleReadmeMd(MdDocumentContext documentContext, Module module) { + this.mdDocumentContext = documentContext; + this.module = module; + } + + static ModuleReadmeMd from(MdDocumentContext documentContext, Module module) { + return new ModuleReadmeMd(documentContext, module); + } + + public Module module() { + return module; + } + + public String content() { + return mdDocumentContext.content(); + } + + + /** + * Returns an instance of the Document.Modifier. + * + * @return module modifier + */ + public Modifier modify() { + return new Modifier(this); + } + + /** + * Inner class that handles Document modifications. + */ + public static class Modifier { + private String content; + private final String name; + private final DocumentId documentId; + private final Module oldModule; + + private Modifier(ModuleReadmeMd oldDocument) { + this.content = oldDocument.mdDocumentContext.content(); + this.oldModule = oldDocument.module(); + this.name = oldDocument.mdDocumentContext.name(); + this.documentId = oldDocument.mdDocumentContext.documentId(); + } + + /** + * Sets the content to be changed. + * + * @param content content to change with + * @return Document.Modifier that holds the content to be changed + */ + public Modifier withContent(String content) { + this.content = content; + return this; + } + + /** + * Returns a new document with updated content. + * + * @return document with updated content + */ + public ModuleReadmeMd apply() { + MdDocumentContext moduleMd = MdDocumentContext.from(DocumentConfig.from(this.documentId, + this.content, this.name)); + Module newModule = oldModule.modify().updateModuleMd(moduleMd).apply(); + return newModule.readmeMd().get(); + } + } +} diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/Package.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/Package.java index d6f6b9d6d46b..6b9c329744be 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/Package.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/Package.java @@ -38,6 +38,7 @@ public class Package { private final Function populateModuleFunc; // Following are not final since they will be lazy loaded private Optional packageMd = Optional.empty(); + private Optional readmeMd = Optional.empty(); private Optional ballerinaToml = Optional.empty(); private Optional dependenciesToml = Optional.empty(); private Optional cloudToml = Optional.empty(); @@ -226,6 +227,13 @@ public Optional balToolToml() { return this.balToolToml; } + /** + * Returns the PackageMd document. + * + * @return PackageMd + * @deprecated use {@link #readmeMd()} instead. + */ + @Deprecated (forRemoval = true, since = "2.11.0") public Optional packageMd() { if (this.packageMd.isEmpty()) { this.packageMd = this.packageContext.packageMdContext().map(c -> @@ -235,6 +243,15 @@ public Optional packageMd() { return this.packageMd; } + public Optional readmeMd() { + if (this.readmeMd.isEmpty()) { + this.readmeMd = this.packageContext.readmeMdContext().map(c -> + PackageReadmeMd.from(c, this) + ); + } + return this.readmeMd; + } + public Collection resourceIds() { return this.packageContext.resourceIds(); } @@ -449,7 +466,7 @@ public static class Modifier { private TomlDocumentContext cloudTomlContext; private TomlDocumentContext compilerPluginTomlContext; private TomlDocumentContext balToolTomlContext; - private MdDocumentContext packageMdContext; + private MdDocumentContext readmeMdContext; private final Map resourceContextMap; private final Map testResourceContextMap; @@ -466,7 +483,7 @@ public Modifier(Package oldPackage) { this.cloudTomlContext = oldPackage.packageContext.cloudTomlContext().orElse(null); this.compilerPluginTomlContext = oldPackage.packageContext.compilerPluginTomlContext().orElse(null); this.balToolTomlContext = oldPackage.packageContext.balToolTomlContext().orElse(null); - this.packageMdContext = oldPackage.packageContext.packageMdContext().orElse(null); + this.readmeMdContext = oldPackage.packageContext.readmeMdContext().orElse(null); resourceContextMap = copyResources(oldPackage, oldPackage.packageContext.resourceIds()); testResourceContextMap = copyResources(oldPackage, oldPackage.packageContext.testResourceIds()); } @@ -586,7 +603,7 @@ public Modifier removeBalToolToml() { * @return Package.Modifier which contains the updated package */ public Modifier addPackageMd(DocumentConfig documentConfig) { - this.packageMdContext = MdDocumentContext.from(documentConfig); + this.readmeMdContext = MdDocumentContext.from(documentConfig); return this; } @@ -596,7 +613,7 @@ public Modifier addPackageMd(DocumentConfig documentConfig) { * @return Package.Modifier which contains the updated package */ public Modifier removePackageMd() { - this.packageMdContext = null; + this.readmeMdContext = null; return this; } @@ -631,7 +648,7 @@ Modifier updateBalToolToml(BalToolToml balToolToml) { } Modifier updatePackageMd(MdDocumentContext packageMd) { - this.packageMdContext = packageMd; + this.readmeMdContext = packageMd; return this; } @@ -658,7 +675,7 @@ private Package createNewPackage() { PackageContext newPackageContext = new PackageContext(this.project, this.packageId, this.packageManifest, this.dependencyManifest, this.ballerinaTomlContext, this.dependenciesTomlContext, this.cloudTomlContext, this.compilerPluginTomlContext, this.balToolTomlContext, - this.packageMdContext, this.compilationOptions, this.moduleContextMap, + this.readmeMdContext, this.compilationOptions, this.moduleContextMap, DependencyGraph.emptyGraph(), this.resourceContextMap, this.testResourceContextMap); this.project.setCurrentPackage(new Package(newPackageContext, this.project)); @@ -792,7 +809,7 @@ private void updateModules() { moduleContextSet.add(new ModuleContext(this.project, moduleId, moduleDescriptor, oldModuleContext.isDefaultModule(), srcDocContextMap, testDocContextMap, - oldModuleContext.moduleMdContext().orElse(null), + oldModuleContext.readmeMdContext().orElse(null), oldModuleContext.moduleDescDependencies())); // Remove the module with old PackageID from the compilation cache PackageCache.getInstance(project.projectEnvironmentContext().getService(CompilerContext.class)). diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageConfig.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageConfig.java index 9ea7569e8574..33abb5072d4d 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageConfig.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageConfig.java @@ -43,7 +43,7 @@ public class PackageConfig { private final Path packagePath; private final DependencyGraph packageDescDependencyGraph; private final Collection otherModules; - private final DocumentConfig packageMd; + private final DocumentConfig readmeMd; private final boolean disableSyntaxTree; private final List resources; private final List testResources; @@ -59,7 +59,7 @@ private PackageConfig(PackageId packageId, DocumentConfig balToolToml, Collection moduleConfigs, DependencyGraph packageDescDependencyGraph, - DocumentConfig packageMd, + DocumentConfig readmeMd, boolean disableSyntaxTree, List resources, List testResources) { @@ -74,7 +74,7 @@ private PackageConfig(PackageId packageId, this.balToolToml = balToolToml; this.otherModules = moduleConfigs; this.packageDescDependencyGraph = packageDescDependencyGraph; - this.packageMd = packageMd; + this.readmeMd = readmeMd; this.disableSyntaxTree = disableSyntaxTree; this.resources = resources; this.testResources = testResources; @@ -123,13 +123,13 @@ public static PackageConfig from(PackageId packageId, Path path, PackageManifest DependencyManifest dependencyManifest, DocumentConfig ballerinaToml, DocumentConfig dependenciesToml, DocumentConfig cloudToml, DocumentConfig compilerPluginToml, DocumentConfig balToolToml, - DocumentConfig packageMd, List moduleConfigs, + DocumentConfig readmeMd, List moduleConfigs, DependencyGraph packageDependencyGraph, boolean disableSyntaxTree, List resources, List testResources) { return new PackageConfig(packageId, path, packageManifest, dependencyManifest, ballerinaToml, dependenciesToml, cloudToml, compilerPluginToml, balToolToml, moduleConfigs, - packageDependencyGraph, packageMd, disableSyntaxTree, resources, + packageDependencyGraph, readmeMd, disableSyntaxTree, resources, testResources); } @@ -195,8 +195,19 @@ public Collection otherModules() { return otherModules; } + /** + * Returns the PackageMd document config. + * + * @return DocumentConfig optionally. + * @deprecated use {@link #readmeMd()} instead. + */ + @Deprecated (forRemoval = true) public Optional packageMd() { - return Optional.ofNullable(packageMd); + return Optional.ofNullable(readmeMd); + } + + public Optional readmeMd() { + return Optional.ofNullable(readmeMd); } public Optional dependenciesToml() { diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageContext.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageContext.java index a646004e8ffd..a753d07ed899 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageContext.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageContext.java @@ -48,7 +48,7 @@ class PackageContext { private final TomlDocumentContext cloudTomlContext; private final TomlDocumentContext compilerPluginTomlContext; private final TomlDocumentContext balToolTomlContext; - private final MdDocumentContext packageMdContext; + private final MdDocumentContext readmeMdContext; private final CompilationOptions compilationOptions; private ModuleContext defaultModuleContext; @@ -81,7 +81,7 @@ class PackageContext { TomlDocumentContext cloudTomlContext, TomlDocumentContext compilerPluginTomlContext, TomlDocumentContext balToolTomlContext, - MdDocumentContext packageMdContext, + MdDocumentContext readmeMdContext, CompilationOptions compilationOptions, Map moduleContextMap, DependencyGraph pkgDescDependencyGraph, @@ -96,7 +96,7 @@ class PackageContext { this.cloudTomlContext = cloudTomlContext; this.compilerPluginTomlContext = compilerPluginTomlContext; this.balToolTomlContext = balToolTomlContext; - this.packageMdContext = packageMdContext; + this.readmeMdContext = readmeMdContext; this.compilationOptions = compilationOptions; this.moduleIds = Collections.unmodifiableCollection(moduleContextMap.keySet()); this.moduleContextMap = moduleContextMap; @@ -132,7 +132,7 @@ static PackageContext from(Project project, PackageConfig packageConfig, Compila packageConfig.cloudToml().map(TomlDocumentContext::from).orElse(null), packageConfig.compilerPluginToml().map(TomlDocumentContext::from).orElse(null), packageConfig.balToolToml().map(TomlDocumentContext::from).orElse(null), - packageConfig.packageMd().map(MdDocumentContext::from).orElse(null), + packageConfig.readmeMd().map(MdDocumentContext::from).orElse(null), compilationOptions, moduleContextMap, packageConfig.packageDescDependencyGraph(), resourceContextMap, testResourceContextMap); } @@ -189,8 +189,14 @@ Optional balToolTomlContext() { return Optional.ofNullable(balToolTomlContext); } + + @Deprecated (forRemoval = true) Optional packageMdContext() { - return Optional.ofNullable(packageMdContext); + return Optional.ofNullable(readmeMdContext); + } + + public Optional readmeMdContext() { + return Optional.ofNullable(readmeMdContext); } CompilationOptions compilationOptions() { @@ -371,7 +377,7 @@ PackageContext duplicate(Project project) { return new PackageContext(project, this.packageId, this.packageManifest, this.dependencyManifest, this.ballerinaTomlContext, this.dependenciesTomlContext, - this.cloudTomlContext, this.compilerPluginTomlContext, this.balToolTomlContext, this.packageMdContext, + this.cloudTomlContext, this.compilerPluginTomlContext, this.balToolTomlContext, this.readmeMdContext, this.compilationOptions, duplicatedModuleContextMap, this.pkgDescDependencyGraph, this.resourceContextMap, this.testResourceContextMap); } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageManifest.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageManifest.java index 9c31d3f47e7d..69edac267bd7 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageManifest.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageManifest.java @@ -53,37 +53,14 @@ public class PackageManifest { private final String visibility; private boolean template; private final String icon; + private final String readme; + private final String description; + private final List moduleList; // Other entries hold other key/value pairs available in the Ballerina.toml file. // These keys are not part of the Ballerina package specification. private final Map otherEntries; - private PackageManifest(PackageDescriptor packageDesc, - CompilerPluginDescriptor compilerPluginDesc, - BalToolDescriptor balToolDesc, - Map platforms, - List dependencies, - Map otherEntries, - DiagnosticResult diagnostics) { - this.packageDesc = packageDesc; - this.compilerPluginDesc = compilerPluginDesc; - this.balToolDesc = balToolDesc; - this.platforms = Collections.unmodifiableMap(platforms); - this.dependencies = Collections.unmodifiableList(dependencies); - this.otherEntries = Collections.unmodifiableMap(otherEntries); - this.diagnostics = diagnostics; - this.license = Collections.emptyList(); - this.authors = Collections.emptyList(); - this.keywords = Collections.emptyList(); - this.exportedModules = Collections.emptyList(); - this.includes = Collections.emptyList(); - this.repository = ""; - this.ballerinaVersion = ""; - this.visibility = ""; - this.icon = ""; - this.tools = Collections.emptyList(); - } - private PackageManifest(PackageDescriptor packageDesc, CompilerPluginDescriptor compilerPluginDesc, BalToolDescriptor balToolDesc, @@ -109,6 +86,9 @@ private PackageManifest(PackageDescriptor packageDesc, this.visibility = ""; this.icon = ""; this.tools = Collections.unmodifiableList(tools); + this.readme = ""; + this.description = ""; + this.moduleList = Collections.emptyList(); } private PackageManifest(PackageDescriptor packageDesc, @@ -127,7 +107,10 @@ private PackageManifest(PackageDescriptor packageDesc, String ballerinaVersion, String visibility, boolean template, - String icon) { + String icon, + String readme, + String description, + List moduleList) { this.packageDesc = packageDesc; this.compilerPluginDesc = compilerPluginDesc; this.balToolDesc = balToolDesc; @@ -146,6 +129,9 @@ private PackageManifest(PackageDescriptor packageDesc, this.template = template; this.icon = icon; this.tools = Collections.emptyList(); + this.readme = readme; + this.description = description; + this.moduleList = moduleList; } private PackageManifest(PackageDescriptor packageDesc, @@ -165,7 +151,10 @@ private PackageManifest(PackageDescriptor packageDesc, String visibility, boolean template, String icon, - List tools) { + List tools, + String readme, + String description, + List moduleList) { this.packageDesc = packageDesc; this.compilerPluginDesc = compilerPluginDesc; this.balToolDesc = balToolDesc; @@ -184,6 +173,9 @@ private PackageManifest(PackageDescriptor packageDesc, this.template = template; this.icon = icon; this.tools = tools; + this.readme = readme; + this.description = description; + this.moduleList = moduleList; } public static PackageManifest from(PackageDescriptor packageDesc) { return new PackageManifest(packageDesc, null, null, Collections.emptyMap(), Collections.emptyList(), @@ -217,10 +209,13 @@ public static PackageManifest from(PackageDescriptor packageDesc, String visibility, boolean template, String icon, - List tools) { + List tools, + String readme, + String description, + List moduleList) { return new PackageManifest(packageDesc, compilerPluginDesc, balToolDesc, platforms, dependencies, otherEntries, diagnostics, license, authors, keywords, export, include, repository, ballerinaVersion, visibility, - template, icon, tools); + template, icon, tools, readme, description, moduleList); } public static PackageManifest from(PackageDescriptor packageDesc, @@ -236,10 +231,14 @@ public static PackageManifest from(PackageDescriptor packageDesc, String repository, String ballerinaVersion, String visibility, - boolean template) { + boolean template, + String readme, + String description, + List moduleList) { return new PackageManifest(packageDesc, compilerPluginDesc, balToolDescriptor, platforms, dependencies, Collections.emptyMap(), new DefaultDiagnosticResult(Collections.emptyList()), license, authors, - keywords, export, include, repository, ballerinaVersion, visibility, template, ""); + keywords, export, include, repository, ballerinaVersion, visibility, template, "", + readme, description, moduleList); } public PackageName name() { @@ -331,6 +330,18 @@ public boolean template() { return template; } + public String readme() { + return readme; + } + + public List modules() { + return moduleList; + } + + public String description() { + return description; + } + /** * Represents the platform section in Ballerina.toml file. * @@ -539,6 +550,15 @@ public record Field(String value, TomlNodeLocation location) { } } + public record Module(String name, boolean export, String description, String readme) { + public Module(String name, boolean export, String description, String readme) { + this.name = name; + this.export = export; + this.description = description; + this.readme = readme != null ? readme : ""; + } + } + private List getExport(PackageDescriptor packageDesc, List export) { if (export == null || export.isEmpty()) { return Collections.singletonList(packageDesc.name().value()); diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageMd.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageMd.java index 7743cbc537d7..de833494448e 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageMd.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageMd.java @@ -23,7 +23,9 @@ * Represents the 'Package.md' file in a package. * * @since 2.0.0 + * @deprecated use {@link PackageReadmeMd} instead */ +@Deprecated (forRemoval = true, since = "2.11.0") public class PackageMd { private final MdDocumentContext mdDocumentContext; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageReadmeMd.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageReadmeMd.java new file mode 100644 index 000000000000..a7e4f08df3d8 --- /dev/null +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/PackageReadmeMd.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024, WSO2 LLC. (https://www.wso2.com). + * + * 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 io.ballerina.projects; + +/** + * Represents the README file in a package. + * + * @since 2.11.0 + */ +public class PackageReadmeMd { + + private final MdDocumentContext mdDocumentContext; + private final Package packageInstance; + + PackageReadmeMd(MdDocumentContext documentContext, Package packageInstance) { + this.mdDocumentContext = documentContext; + this.packageInstance = packageInstance; + } + + public static PackageReadmeMd from(DocumentConfig documentConfig, Package aPackage) { + MdDocumentContext documentContext = MdDocumentContext.from(documentConfig); + return new PackageReadmeMd(documentContext, aPackage); + } + + public static PackageReadmeMd from(MdDocumentContext documentContext, Package aPackage) { + return new PackageReadmeMd(documentContext, aPackage); + } + + public Package packageInstance() { + return packageInstance; + } + + public String content() { + return mdDocumentContext.content(); + } + + /** + * Returns an instance of the Document.Modifier. + * + * @return module modifier + */ + public Modifier modify() { + return new PackageReadmeMd.Modifier(this); + } + + /** + * Inner class that handles Document modifications. + */ + public static class Modifier { + private String content; + private final String name; + private final DocumentId documentId; + private final Package oldPackage; + + private Modifier(PackageReadmeMd oldDocument) { + this.content = oldDocument.mdDocumentContext.content(); + this.oldPackage = oldDocument.packageInstance(); + this.name = oldDocument.mdDocumentContext.name(); + this.documentId = oldDocument.mdDocumentContext.documentId(); + } + + /** + * Sets the content to be changed. + * + * @param content content to change with + * @return Document.Modifier that holds the content to be changed + */ + public Modifier withContent(String content) { + this.content = content; + return this; + } + + /** + * Returns a new document with updated content. + * + * @return document with updated content + */ + public PackageReadmeMd apply() { + MdDocumentContext readmeMd = MdDocumentContext.from(DocumentConfig.from(this.documentId, + this.content, this.name)); + Package newPackage = oldPackage.modify().updatePackageMd(readmeMd).apply(); + return newPackage.readmeMd().get(); + } + } +} diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/BalaFiles.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/BalaFiles.java index 466ba29d1736..0d1253c81b14 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/BalaFiles.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/BalaFiles.java @@ -89,49 +89,60 @@ public final class BalaFiles { private BalaFiles() { } - static PackageData loadPackageData(Path balaPath, PackageManifest packageManifest) { + static PackageData loadPackageData(Path balaPath, PackageJson packageJson) { if (balaPath.toFile().isDirectory()) { - return loadPackageDataFromBalaDir(balaPath, packageManifest); + return loadPackageDataFromBalaDir(balaPath, packageJson); } else { - return loadPackageDataFromBalaFile(balaPath, packageManifest); + return loadPackageDataFromBalaFile(balaPath, packageJson); } } - private static PackageData loadPackageDataFromBalaDir(Path balaPath, PackageManifest packageManifest) { + private static PackageData loadPackageDataFromBalaDir(Path balaPath, PackageJson packageJson) { // Load default module - String pkgName = packageManifest.name().toString(); - ModuleData defaultModule = loadModule(pkgName, pkgName, balaPath); - DocumentData packageMd = loadDocument(balaPath.resolve(BALA_DOCS_DIR) - .resolve(ProjectConstants.PACKAGE_MD_FILE_NAME)); + String pkgName = packageJson.getName(); + ModuleData defaultModule = loadModule(pkgName, pkgName, balaPath, packageJson); // load other modules - List otherModules = loadOtherModules(pkgName, balaPath); + List otherModules = loadOtherModules(pkgName, balaPath, packageJson); List resources = loadResources(balaPath); if (resources.isEmpty()) { // get resources from default module path - to support balas before 2201.10.0 resources = loadResources(balaPath.resolve(MODULES_ROOT).resolve(pkgName)); } + DocumentData readmeMd; + if (packageJson.getReadme() == null) { + readmeMd = loadDocument(balaPath.resolve(BALA_DOCS_DIR).resolve(ProjectConstants.PACKAGE_MD_FILE_NAME)); + } else { + readmeMd = loadDocument(balaPath.resolve(packageJson.getReadme())); + } + return PackageData.from(balaPath, defaultModule, otherModules, null, null, - null, null, null, packageMd, resources, Collections.emptyList()); + null, null, null, readmeMd, resources, Collections.emptyList()); } - private static PackageData loadPackageDataFromBalaFile(Path balaPath, PackageManifest packageManifest) { + private static PackageData loadPackageDataFromBalaFile(Path balaPath, PackageJson packageJson) { URI zipURI = getZipURI(balaPath); try (FileSystem zipFileSystem = FileSystems.newFileSystem(zipURI, new HashMap<>())) { // Load default module - String pkgName = packageManifest.name().toString(); + String pkgName = packageJson.getName(); Path packageRoot = zipFileSystem.getPath("/"); - ModuleData defaultModule = loadModule(pkgName, pkgName, packageRoot); - DocumentData packageMd = loadDocument(zipFileSystem.getPath(BALA_DOCS_DIR) - .resolve(ProjectConstants.PACKAGE_MD_FILE_NAME)); + ModuleData defaultModule = loadModule(pkgName, pkgName, packageRoot, packageJson); // load other modules - List otherModules = loadOtherModules(pkgName, packageRoot); + List otherModules = loadOtherModules(pkgName, packageRoot, packageJson); List resources = loadResources(packageRoot); if (resources.isEmpty()) { // get resources from default module path - to support bala files before 2201.10.0 resources = loadResources(packageRoot.resolve(MODULES_ROOT).resolve(pkgName)); } + + DocumentData readmeMd; + if (packageJson.getReadme() == null) { + readmeMd = loadDocument(packageRoot.resolve(BALA_DOCS_DIR) + .resolve(ProjectConstants.PACKAGE_MD_FILE_NAME)); + } else { + readmeMd = loadDocument(packageRoot.resolve(packageJson.getReadme())); + } return PackageData.from(balaPath, defaultModule, otherModules, null, null, - null, null, null, packageMd, resources, Collections.emptyList()); + null, null, null, readmeMd, resources, Collections.emptyList()); } catch (IOException e) { throw new ProjectException("Failed to read bala file:" + balaPath); } @@ -163,7 +174,8 @@ public static DocumentData loadDocument(Path documentFilePath) { } } - private static ModuleData loadModule(String pkgName, String fullModuleName, Path packagePath) { + private static ModuleData loadModule(String pkgName, String fullModuleName, Path packagePath, + PackageJson packageJson) { Path modulePath = packagePath.resolve(MODULES_ROOT).resolve(fullModuleName); Path moduleDocPath = packagePath.resolve(BALA_DOCS_DIR).resolve(MODULES_ROOT).resolve(fullModuleName); // check module path exists @@ -189,12 +201,22 @@ private static ModuleData loadModule(String pkgName, String fullModuleName, Path List srcDocs = loadDocuments(modulePath); List testSrcDocs = Collections.emptyList(); - DocumentData moduleMd = loadDocument(moduleDocPath.resolve(ProjectConstants.MODULE_MD_FILE_NAME)); + DocumentData readmeMd = null; + if (packageJson.getReadme() == null) { + // v2 bala structure + readmeMd = loadDocument(moduleDocPath.resolve(ProjectConstants.MODULE_MD_FILE_NAME)); + } else if (packageJson.getModules() != null) { + Optional module = packageJson.getModules().stream().filter(mod -> + fullModuleName.equals(mod.name())).findAny(); + if (module.isPresent() && module.get().readme() != null && !module.get().readme().isEmpty()) { + readmeMd = loadDocument(packagePath.resolve(module.get().readme())); + } + } - return ModuleData.from(modulePath, moduleName, srcDocs, testSrcDocs, moduleMd); + return ModuleData.from(modulePath, moduleName, srcDocs, testSrcDocs, readmeMd); } - private static List loadOtherModules(String pkgName, Path packagePath) { + private static List loadOtherModules(String pkgName, Path packagePath, PackageJson packageJson) { Path modulesDirPath = packagePath.resolve(MODULES_ROOT); try (Stream pathStream = Files.walk(modulesDirPath, 1)) { return pathStream @@ -203,7 +225,7 @@ private static List loadOtherModules(String pkgName, Path packagePat && !path.getFileName().toString().equals(pkgName)) .filter(Files::isDirectory) .map(modulePath -> modulePath.getFileName().toString()) - .map(fullModuleName -> loadModule(pkgName, fullModuleName, packagePath)) + .map(fullModuleName -> loadModule(pkgName, fullModuleName, packagePath, packageJson)) .toList(); } catch (IOException e) { throw new ProjectException("Failed to read modules from directory: " + modulesDirPath, e); @@ -487,12 +509,24 @@ private static PackageManifest getPackageManifest(PackageJson packageJson, CompilerPluginDescriptor compilerPluginDescriptor = compilerPluginJson .map(CompilerPluginDescriptor::from).orElse(null); BalToolDescriptor balToolDescriptor = balToolJson.map(BalToolDescriptor::from).orElse(null); + List exports = new ArrayList<>(); + if (packageJson.getExport() == null) { + // new bala structure + exports.add(packageJson.getName()); // default module is always exported + if (packageJson.getModules() != null) { + exports.addAll(packageJson.getModules().stream().filter( + PackageManifest.Module::export).map(PackageManifest.Module::name).toList()); + } + } else { + exports = packageJson.getExport(); + } return PackageManifest .from(pkgDesc, compilerPluginDescriptor, balToolDescriptor, platforms, dependencies, packageJson.getLicenses(), packageJson.getAuthors(), packageJson.getKeywords(), - packageJson.getExport(), packageJson.getInclude(), packageJson.getSourceRepository(), + exports, packageJson.getInclude(), packageJson.getSourceRepository(), packageJson.getBallerinaVersion(), packageJson.getVisibility(), - packageJson.getTemplate()); + packageJson.getTemplate(), packageJson.getReadme(), packageJson.getDescription(), + packageJson.getModules()); } private static Map getPlatforms(PackageJson packageJson) { diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/CompilerPhaseRunner.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/CompilerPhaseRunner.java index 2992e0769836..6cd4b7d25c21 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/CompilerPhaseRunner.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/CompilerPhaseRunner.java @@ -17,7 +17,7 @@ */ package io.ballerina.projects.internal; -import io.ballerina.runtime.internal.util.RuntimeUtils; +import io.ballerina.runtime.internal.utils.RuntimeUtils; import org.ballerinalang.compiler.CompilerPhase; import org.wso2.ballerinalang.compiler.bir.BIRGen; import org.wso2.ballerinalang.compiler.bir.emit.BIREmitter; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ManifestBuilder.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ManifestBuilder.java index 85366a7de7b9..7ac2b75b4ff5 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ManifestBuilder.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ManifestBuilder.java @@ -33,6 +33,7 @@ import io.ballerina.projects.internal.model.BalToolDescriptor; import io.ballerina.projects.internal.model.CompilerPluginDescriptor; import io.ballerina.projects.util.FileUtils; +import io.ballerina.projects.util.ProjectConstants; import io.ballerina.projects.util.ProjectUtils; import io.ballerina.toml.api.Toml; import io.ballerina.toml.semantic.TomlType; @@ -51,26 +52,32 @@ import io.ballerina.tools.diagnostics.Diagnostic; import io.ballerina.tools.diagnostics.DiagnosticInfo; import io.ballerina.tools.diagnostics.DiagnosticSeverity; +import org.apache.commons.io.FilenameUtils; import org.ballerinalang.compiler.CompilerOptionName; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; import static io.ballerina.projects.internal.ManifestUtils.ToolNodeValueType; import static io.ballerina.projects.internal.ManifestUtils.convertDiagnosticToString; import static io.ballerina.projects.internal.ManifestUtils.getBooleanFromTomlTableNode; import static io.ballerina.projects.internal.ManifestUtils.getBuildToolTomlValueType; import static io.ballerina.projects.internal.ManifestUtils.getStringFromTomlTableNode; +import static io.ballerina.projects.util.ProjectConstants.DOT; import static io.ballerina.projects.util.ProjectUtils.defaultName; import static io.ballerina.projects.util.ProjectUtils.defaultOrg; import static io.ballerina.projects.util.ProjectUtils.defaultVersion; @@ -121,6 +128,10 @@ public class ManifestBuilder { private static final String TARGETMODULE = "targetModule"; private static final String OPTIONS = "options"; private static final String TOOL = "tool"; + private static final String DESCRIPTION = "description"; + private static final String README = "readme"; + + private boolean isOldStructure; private ManifestBuilder(TomlDocument ballerinaToml, TomlDocument compilerPluginToml, @@ -196,6 +207,9 @@ private PackageManifest parseAsPackageManifest() { String visibility = ""; boolean template = false; String icon = ""; + String readme = null; + String description = ""; + List moduleEntries = new ArrayList<>(); if (!tomlAstNode.entries().isEmpty()) { TopLevelNode topLevelPkgNode = tomlAstNode.entries().get(PACKAGE); @@ -210,10 +224,36 @@ private PackageManifest parseAsPackageManifest() { ballerinaVersion = getStringValueFromTomlTableNode(pkgNode, DISTRIBUTION, ""); visibility = getStringValueFromTomlTableNode(pkgNode, VISIBILITY, ""); template = getBooleanFromTemplateNode(pkgNode, TEMPLATE); - icon = getStringValueFromTomlTableNode(pkgNode, ICON, ""); + icon = getStringValueFromTomlTableNode(pkgNode, ICON, ""); // we ignore file types except png here, since file type error will be shown validateIconPathForPng(icon, pkgNode); + + String customReadmeVal = getStringValueFromTomlTableNode(pkgNode, README, null); + readme = validateAndGetReadmePath(pkgNode, customReadmeVal, packageDescriptor.name()); + description = getStringValueFromTomlTableNode(pkgNode, DESCRIPTION, ""); + moduleEntries = getModuleEntries(pkgNode, customReadmeVal, packageDescriptor.name()); + + if (!exported.isEmpty()) { + reportDiagnostic(pkgNode.entries().get(EXPORT), + "'export' under [package] is deprecated. " + + "Add the exports using the 'export' field under '[[package.modules]]'", + ProjectDiagnosticErrorCode.DEPRECATED_BALLERINA_TOML_ENTRY, DiagnosticSeverity.WARNING); + } + if (!isOldStructure) { + if (!exported.contains(packageDescriptor.name().toString())) { + exported.add(packageDescriptor.name().toString()); // default module is always exported + } + for (PackageManifest.Module moduleEntry : moduleEntries) { + if (!moduleEntry.export()) { + continue; + } + String name = moduleEntry.name(); + if (!exported.contains(name)) { + exported.add(name); + } + } + } } } @@ -252,7 +292,184 @@ private PackageManifest parseAsPackageManifest() { } return PackageManifest.from(packageDescriptor, pluginDescriptor, balToolDescriptor, platforms, localRepoDependencies, otherEntries, diagnostics(), license, authors, keywords, exported, includes, - repository, ballerinaVersion, visibility, template, icon, tools); + repository, ballerinaVersion, visibility, template, icon, tools, readme, description, moduleEntries); + } + + private List getModuleEntries( + TomlTableNode pkgNode, String customReadmeVal, PackageName packageName) { + + TopLevelNode dependencyEntries = validateAndGetModuleNodes(pkgNode, packageName); + + List moduleList = new ArrayList<>(); + Path modulesRoot = this.projectPath.resolve(ProjectConstants.MODULES_ROOT); + if (!Files.exists(modulesRoot)) { + return moduleList; + } + Map moduleDirs; + try (Stream stream = Files.walk(modulesRoot, 1)) { + moduleDirs = stream + .filter(Files::isDirectory) + .filter(path -> !path.equals(modulesRoot)) + .collect(Collectors.toMap(path -> Optional.of(path.getFileName()).get().toString(), path -> path)); + } catch (IOException e) { + throw new ProjectException("Failed to read the module README:", e); + } + + if (customReadmeVal == null) { + if (Files.exists(this.projectPath.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME))) { + // old structure. Module READMEs are captured by /Module.md file. + for (Map.Entry pathEntry : moduleDirs.entrySet()) { + Path modReadmePath = pathEntry.getValue().resolve(ProjectConstants.MODULE_MD_FILE_NAME); + String modReadme = null; + if (Files.exists(modReadmePath)) { + modReadme = Paths.get(ProjectConstants.MODULES_ROOT).resolve(pathEntry.getKey()) + .resolve(ProjectConstants.MODULE_MD_FILE_NAME).toString(); + } + PackageManifest.Module module = new PackageManifest.Module( + packageName + DOT + Optional.of(pathEntry.getValue().getFileName()).get(), false, + "", modReadme); + moduleList.add(module); + } + return moduleList; + } + } + + // new structure + if (dependencyEntries == null || dependencyEntries.kind() == TomlType.NONE) { + for (Map.Entry pathEntry : moduleDirs.entrySet()) { + Path modReadmePath = pathEntry.getValue().resolve(ProjectConstants.README_MD_FILE_NAME); + String modReadme = ""; + if (Files.exists(modReadmePath)) { + modReadme = Paths.get(ProjectConstants.MODULES_ROOT).resolve(pathEntry.getKey()) + .resolve(ProjectConstants.README_MD_FILE_NAME).toString();; + } + PackageManifest.Module module = new PackageManifest.Module( + packageName + DOT + Optional.of(pathEntry.getValue().getFileName()).get(), false, + "", modReadme); + moduleList.add(module); + } + return moduleList; + } + if (dependencyEntries.kind() == TomlType.TABLE_ARRAY) { + TomlTableArrayNode dependencyTableArray = (TomlTableArrayNode) dependencyEntries; + for (TomlTableNode modulesNode : dependencyTableArray.children()) { + String moduleName = getStringValueFromTomlTableNode(modulesNode, NAME, null); + if (moduleName == null + || !moduleName.contains(DOT)) { // The invalid module name is already handled + continue; + } + + boolean export = Boolean.TRUE.equals(getBooleanValueFromTomlTableNode(modulesNode, EXPORT)); + String description = getStringValueFromTomlTableNode(modulesNode, DESCRIPTION, null); + String modReadme = getStringValueFromTomlTableNode(modulesNode, README, null); + if (modReadme == null) { + Path defaultReadme = modulesRoot.resolve(moduleName).resolve(ProjectConstants.README_MD_FILE_NAME); + if (Files.exists(defaultReadme)) { + modReadme = defaultReadme.toString(); + } + } else { + if (!Paths.get(modReadme).isAbsolute()) { + modReadme = this.projectPath.resolve(modReadme).toString(); + } + } + PackageManifest.Module module = new PackageManifest.Module(moduleName, export, + description, modReadme); + moduleList.add(module); + moduleDirs.remove(moduleName.split("[.]")[1]); + } + // If there are README.mds in other modules, add them + for (Map.Entry pathEntry : moduleDirs.entrySet()) { + Path modReadmePath = pathEntry.getValue().resolve(ProjectConstants.README_MD_FILE_NAME); + String modReadme = ""; + if (Files.exists(modReadmePath)) { + modReadme = modReadmePath.toString(); + } + PackageManifest.Module module = new PackageManifest.Module( + packageName + DOT + Optional.of(pathEntry.getValue().getFileName()).get(), false, + "", modReadme); + moduleList.add(module); + } + } + return moduleList; + } + + private TopLevelNode validateAndGetModuleNodes(TomlTableNode pkgNode, PackageName packageName) { + TopLevelNode dependencyEntries = pkgNode.entries().get("modules"); + if (dependencyEntries != null && dependencyEntries.kind() == TomlType.TABLE_ARRAY) { + TomlTableArrayNode dependencyTableArray = (TomlTableArrayNode) dependencyEntries; + for (TomlTableNode modulesNode : dependencyTableArray.children()) { + String moduleName = getStringValueFromTomlTableNode(modulesNode, NAME, null); + if (moduleName == null) { + continue; + } + if (moduleName.equals(packageName.toString())) { + String warning = "module '" + moduleName + "' is not allowed\n"; + reportDiagnostic(modulesNode.entries().get(NAME), warning, + ProjectDiagnosticErrorCode.INVALID_MODULE, DiagnosticSeverity.ERROR); + continue; + } + + try { + if (Files.notExists(this.projectPath.resolve(ProjectConstants.MODULES_ROOT) + .resolve(moduleName.split(packageName + DOT)[1]))) { + String warning = "module '" + moduleName + "' not found"; + reportDiagnostic(modulesNode.entries().get(NAME), warning, + ProjectDiagnosticErrorCode.INVALID_MODULE, DiagnosticSeverity.ERROR); + } + } catch (ArrayIndexOutOfBoundsException e) { + String warning = "module '" + moduleName + "' not found"; + reportDiagnostic(modulesNode.entries().get(NAME), warning, + ProjectDiagnosticErrorCode.INVALID_MODULE, DiagnosticSeverity.ERROR); + } + } + } + return dependencyEntries; + } + + private String validateAndGetReadmePath(TomlTableNode pkgNode, String readme, PackageName name) { + Path readmeMdPath; + if (readme == null) { + readmeMdPath = this.projectPath.resolve(ProjectConstants.PACKAGE_MD_FILE_NAME); + if (Files.exists(readmeMdPath)) { + String warning = """ + The default file for package documentation is changed to README.md. If you prefer to \ + use the Package.md, add the following line under the '[package]' section in your \ + Ballerina.toml file: + \treadme = "Package.md" + """; + DiagnosticInfo diagnosticInfo = new DiagnosticInfo(ProjectDiagnosticErrorCode. + DEPRECATED_DOC_FILE.diagnosticId(), warning, DiagnosticSeverity.WARNING); + PackageDiagnostic packageDiagnostic = new PackageDiagnostic(diagnosticInfo, + name.toString()); + ProjectUtils.addMiscellaneousProjectDiagnostics(packageDiagnostic); + isOldStructure = true; + return readmeMdPath.toString(); + } else { + readmeMdPath = this.projectPath.resolve(ProjectConstants.README_MD_FILE_NAME); + if (Files.exists(readmeMdPath)) { + return readmeMdPath.toString(); + } else { + return null; + } + } + } + + readmeMdPath = Paths.get(readme); + if (!readmeMdPath.isAbsolute()) { + readmeMdPath = this.projectPath.resolve(readmeMdPath); + } + if (Files.notExists(readmeMdPath)) { + reportDiagnostic(pkgNode.entries().get(README), + "could not locate the readme file '" + readmeMdPath + "'", + ProjectDiagnosticErrorCode.INVALID_PATH, DiagnosticSeverity.ERROR); + } + + if (!FilenameUtils.getExtension(readme).equals(ProjectConstants.README_EXTENSION)) { + reportDiagnostic(pkgNode.entries().get(README), + "invalid 'readme' under [package]: 'readme' can only have '.md' files", + ProjectDiagnosticErrorCode.INVALID_FILE_FORMAT, DiagnosticSeverity.ERROR); + } + return readmeMdPath.toString(); } private List getTools() { @@ -438,7 +655,7 @@ private void validateIconPathForPng(String icon, TomlTableNode pkgNode) { if (!FileUtils.isValidPng(iconPath)) { reportDiagnostic(pkgNode.entries().get("icon"), "invalid 'icon' under [package]: 'icon' can only have 'png' images", - ProjectDiagnosticErrorCode.INVALID_ICON, DiagnosticSeverity.ERROR); + ProjectDiagnosticErrorCode.INVALID_FILE_FORMAT, DiagnosticSeverity.ERROR); } } catch (IOException e) { // should not reach to this line @@ -566,7 +783,7 @@ private PackageManifest.Platform getDependencyPlatform(TopLevelNode dependencyNo String artifactId = getStringValueFromPlatformEntry(platformEntryTable, ARTIFACT_ID); String version = getStringValueFromPlatformEntry(platformEntryTable, VERSION); String scope = getStringValueFromPlatformEntry(platformEntryTable, SCOPE); - Boolean graalvmCompatibility = getBooleanValueFromPlatformEntry(platformEntryTable, + Boolean graalvmCompatibility = getBooleanValueFromTomlTableNode(platformEntryTable, GRAALVM_COMPATIBLE); if (PlatformLibraryScope.PROVIDED.getStringValue().equals(scope) && !providedPlatformDependencyIsValid(artifactId, groupId, version)) { @@ -849,7 +1066,7 @@ private String getStringValueFromPlatformEntry(TomlTableNode pkgNode, String key return getStringFromTomlTableNode(topLevelNode); } - private Boolean getBooleanValueFromPlatformEntry(TomlTableNode pkgNode, String key) { + private Boolean getBooleanValueFromTomlTableNode(TomlTableNode pkgNode, String key) { TopLevelNode topLevelNode = pkgNode.entries().get(key); if (topLevelNode == null || topLevelNode.kind() == TomlType.NONE) { return null; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ModuleData.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ModuleData.java index 4829807c6ffd..033e661374e5 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ModuleData.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ModuleData.java @@ -32,7 +32,7 @@ public class ModuleData { private final String moduleName; private final List srcDocs; private final List testSrcDocs; - private final DocumentData moduleMd; + private final DocumentData readmeMd; // TODO do we need to maintain resources and test resources @@ -40,20 +40,20 @@ private ModuleData(Path moduleDirPath, String moduleName, List srcDocs, List testSrcDocs, - DocumentData moduleMd) { + DocumentData readmeMd) { this.moduleDirPath = moduleDirPath; this.moduleName = moduleName; this.srcDocs = srcDocs; this.testSrcDocs = testSrcDocs; - this.moduleMd = moduleMd; + this.readmeMd = readmeMd; } public static ModuleData from(Path path, String moduleName, List srcDocuments, List testSrcDocuments, - DocumentData moduleMd) { - return new ModuleData(path, moduleName, srcDocuments, testSrcDocuments, moduleMd); + DocumentData readmeMd) { + return new ModuleData(path, moduleName, srcDocuments, testSrcDocuments, readmeMd); } public Path moduleDirectoryPath() { @@ -80,8 +80,19 @@ public void addTestSourceDocs(List docs) { testSrcDocs.addAll(docs); } + /** + * Returns the ModuleMd document data. + * + * @return DocumentData optionally. + * @deprecated use {@link #readmeMd()} instead. + */ + @Deprecated (forRemoval = true) public Optional moduleMd() { - return Optional.ofNullable(this.moduleMd); + return Optional.ofNullable(this.readmeMd); + } + + public Optional readmeMd() { + return Optional.ofNullable(this.readmeMd); } } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageConfigCreator.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageConfigCreator.java index b9b527f00681..70dcc074fc39 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageConfigCreator.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageConfigCreator.java @@ -35,6 +35,7 @@ import io.ballerina.projects.ProjectException; import io.ballerina.projects.ResourceConfig; import io.ballerina.projects.TomlDocument; +import io.ballerina.projects.internal.model.PackageJson; import io.ballerina.projects.util.ProjectConstants; import java.nio.file.Path; @@ -116,7 +117,8 @@ public static PackageConfig createBalaProjectConfig(Path balaPath) { ProjectFiles.validateBalaProjectPath(balaPath); PackageManifest packageManifest = BalaFiles.createPackageManifest(balaPath); DependencyManifest dependencyManifest = BalaFiles.createDependencyManifest(balaPath); - PackageData packageData = BalaFiles.loadPackageData(balaPath, packageManifest); + PackageJson packageJson = BalaFiles.readPackageJson(balaPath); + PackageData packageData = BalaFiles.loadPackageData(balaPath, packageJson); BalaFiles.DependencyGraphResult packageDependencyGraph = BalaFiles .createPackageDependencyGraph(balaPath); @@ -163,8 +165,7 @@ private static PackageConfig createPackageConfig(PackageData packageData, .map(data -> createDocumentConfig(data, null)).orElse(null); DocumentConfig balToolToml = packageData.balToolToml() .map(data -> createDocumentConfig(data, null)).orElse(null); - DocumentConfig packageMd = packageData.packageMd() - .map(data -> createDocumentConfig(data, null)).orElse(null); + List resources = new ArrayList<>(); List testResources = new ArrayList<>(); if (!packageData.resources().isEmpty()) { @@ -173,9 +174,12 @@ private static PackageConfig createPackageConfig(PackageData packageData, if (!packageData.testResources().isEmpty()) { testResources = getResourceConfigs(packageData.testResources(), packageData.packagePath()); } + DocumentConfig readmeMd = packageData.readmeMd() + .map(data -> createDocumentConfig(data, null)).orElse(null); + return PackageConfig .from(packageId, packageData.packagePath(), packageManifest, dependencyManifest, ballerinaToml, - dependenciesToml, cloudToml, compilerPluginToml, balToolToml, packageMd, moduleConfigs, + dependenciesToml, cloudToml, compilerPluginToml, balToolToml, readmeMd, moduleConfigs, packageDependencyGraph, disableSyntaxTree, resources, testResources); } public static PackageConfig createPackageConfig(PackageData packageData, @@ -228,10 +232,10 @@ private static ModuleConfig createModuleConfig(ModuleDescriptor moduleDescriptor List srcDocs = getDocumentConfigs(moduleId, moduleData.sourceDocs()); List testSrcDocs = getDocumentConfigs(moduleId, moduleData.testSourceDocs()); - DocumentConfig moduleMd = moduleData.moduleMd() + DocumentConfig readmeMd = moduleData.readmeMd() .map(data -> createDocumentConfig(data, null)).orElse(null); - return ModuleConfig.from(moduleId, moduleDescriptor, srcDocs, testSrcDocs, moduleMd, dependencies); + return ModuleConfig.from(moduleId, moduleDescriptor, srcDocs, testSrcDocs, readmeMd, dependencies); } private static List getResourceConfigs(List resources, Path packagePath) { diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageData.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageData.java index fd8be26e51de..f05917665d7e 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageData.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/PackageData.java @@ -42,7 +42,7 @@ public class PackageData { private final DocumentData cloudToml; private final DocumentData compilerPluginToml; private final DocumentData balToolToml; - private final DocumentData packageMd; + private final DocumentData readmeMd; private final List resources; private final List testResources; @@ -56,7 +56,7 @@ private PackageData(Path packagePath, DocumentData cloudToml, DocumentData compilerPluginToml, DocumentData balToolToml, - DocumentData packageMd, + DocumentData readmeMd, List resources, List testResources) { this.packagePath = packagePath; @@ -64,7 +64,7 @@ private PackageData(Path packagePath, this.otherModules = otherModules; this.packageDesDependencyGraph = packageDesDependencyGraph; this.moduleDependencyGraph = moduleDependencyGraph; - this.packageMd = packageMd; + this.readmeMd = readmeMd; this.ballerinaToml = ballerinaToml; this.dependenciesToml = dependenciesToml; this.cloudToml = cloudToml; @@ -82,12 +82,12 @@ public static PackageData from(Path packagePath, DocumentData cloudToml, DocumentData compilerPluginToml, DocumentData balToolToml, - DocumentData packageMd, + DocumentData readmeMd, List resources, List testResources) { return new PackageData(packagePath, defaultModule, otherModules, DependencyGraph.emptyGraph(), DependencyGraph.emptyGraph(), ballerinaToml, dependenciesToml, cloudToml, - compilerPluginToml, balToolToml, packageMd, resources, testResources); + compilerPluginToml, balToolToml, readmeMd, resources, testResources); } public static PackageData from(Path packagePath, @@ -148,8 +148,19 @@ public Optional balToolToml() { return Optional.ofNullable(balToolToml); } + /** + * Returns the PackageMd document data. + * + * @return DocumentData optionally. + * @deprecated use {@link #readmeMd()} instead. + */ + @Deprecated (forRemoval = true) public Optional packageMd() { - return Optional.ofNullable(packageMd); + return Optional.ofNullable(readmeMd); + } + + public Optional readmeMd() { + return Optional.ofNullable(readmeMd); } public List resources () { diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectDiagnosticErrorCode.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectDiagnosticErrorCode.java index 9e325ffeae7d..353815f1055a 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectDiagnosticErrorCode.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectDiagnosticErrorCode.java @@ -30,7 +30,7 @@ public enum ProjectDiagnosticErrorCode implements DiagnosticCode { // Error codes used in the ManifestBuilder MISSING_PKG_INFO_IN_BALLERINA_TOML("BCE5001", "missing.package.info"), INVALID_PATH("BCE5002", "error.invalid.path"), - INVALID_ICON("BCE5003", "error.invalid.icon"), + INVALID_FILE_FORMAT("BCE5003", "error.invalid.file.format"), INVALID_PROVIDED_DEPENDENCY("BCE5004", "invalid.provided.dependency"), INVALID_PROVIDED_SCOPE_IN_BUILD("BCE5005", "invalid.provided.scope"), @@ -38,6 +38,9 @@ public enum ProjectDiagnosticErrorCode implements DiagnosticCode { OLD_DEPENDENCIES_TOML("BCE5101", "old.dependencies.toml"), LOCAL_PACKAGES_IN_DEPENDENCIES_TOML("BCE5102", "local.packages.in.dependencies.toml"), CORRUPTED_DEPENDENCIES_TOML("BCE5103", "corrupted.dependencies.toml"), + DEPRECATED_BALLERINA_TOML_ENTRY("BCE5104", "deprecated.ballerina.toml.entry"), + INVALID_MODULE("BCE5105", "invalid.module"), + DEPRECATED_DOC_FILE("BCE5106", "deprecated.doc.file"), // Error codes used during dependency resolution. INCOMPATIBLE_DEPENDENCY_VERSIONS("BCE5201", "incompatible.dependency.versions"), @@ -64,9 +67,10 @@ public enum ProjectDiagnosticErrorCode implements DiagnosticCode { // Error codes used in resources resolution CONFLICTING_RESOURCE_FILE("BCE5601", "conflicting.resources.type"), + DEPRECATED_RESOURCES_STRUCTURE("BCE5602", "deprecated.resources.structure"), // Error codes for invalid flag combinations. - INVALID_VERBOSE_FLAG_USAGE("BCE5701", "invalid.verbose.flag.usage"), + INVALID_VERBOSE_FLAG_USAGE("BCE5701", "invalid.verbose.flag.usage") ; private final String diagnosticId; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectFiles.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectFiles.java index 088ea516029d..3a68298fab75 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectFiles.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ProjectFiles.java @@ -25,6 +25,8 @@ import io.ballerina.projects.exceptions.InvalidBalaException; import io.ballerina.projects.util.ProjectConstants; import io.ballerina.projects.util.ProjectUtils; +import io.ballerina.tools.diagnostics.DiagnosticInfo; +import io.ballerina.tools.diagnostics.DiagnosticSeverity; import java.io.File; import java.io.IOException; @@ -201,13 +203,17 @@ private static ModuleData loadModule(Path moduleDirPath) { parentPath.toFile().getName())) { List moduleResources = loadResources(moduleDirPath); if (!moduleResources.isEmpty()) { - String diagnosticMsg = "WARNING: module-level resources are not supported. Relocate the module-level " + + String warning = "WARNING: module-level resources are not supported. Relocate the module-level " + "resources detected in '" + moduleDirPath.toFile().getName() + "' to the package " + "resources path. Resource files:\n" + moduleResources.stream() .map(Path::toString) .collect(Collectors.joining("\n")) + "\n"; - ProjectUtils.addProjectLoadingDiagnostic(diagnosticMsg); + DiagnosticInfo diagnosticInfo = new DiagnosticInfo(ProjectDiagnosticErrorCode. + DEPRECATED_RESOURCES_STRUCTURE.diagnosticId(), warning, DiagnosticSeverity.WARNING); + PackageDiagnostic packageDiagnostic = new PackageDiagnostic(diagnosticInfo, ""); + + ProjectUtils.addMiscellaneousProjectDiagnostics(packageDiagnostic); } } // TODO Read Module.md file. Do we need to? Bala creator may need to package Module.md diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/bala/BalaJson.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/bala/BalaJson.java index 53081cf60644..73547e8bd939 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/bala/BalaJson.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/bala/BalaJson.java @@ -24,7 +24,7 @@ * @since 2.0.0 */ public class BalaJson { - private String bala_version = "2.0.0"; + private String bala_version = "3.0.0"; private String built_by = "WSO2"; public String getBala_version() { diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/bala/PackageJson.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/bala/PackageJson.java index 2cd780f68e82..3d4aa44618e0 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/bala/PackageJson.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/bala/PackageJson.java @@ -19,6 +19,7 @@ package io.ballerina.projects.internal.bala; import com.google.gson.JsonArray; +import io.ballerina.projects.PackageManifest; import java.util.List; @@ -36,6 +37,7 @@ public class PackageJson { private List authors; //? private String source_repository; //? private List keywords; //? + @Deprecated private List export; //? private List include; private String visibility; @@ -48,7 +50,7 @@ public class PackageJson { // Dependencies private List dependencies; //? - private String platform; // target of the bala ie. java17, any etc. + private String platform; // target of the bala ie. java21, any etc. private JsonArray platformDependencies; // platform dependencies private Boolean graalvmCompatible; // GraalVM compatibility property for package @@ -57,6 +59,11 @@ public class PackageJson { private boolean template; //? private String template_version; //? + // Docs + private String readme; + private String description; + private List modules; + public PackageJson(String organization, String name, String version) { this.organization = organization; this.name = name; @@ -119,6 +126,7 @@ public void setKeywords(List keywords) { this.keywords = keywords; } + @Deprecated (forRemoval = true, since = "2.11.0") public List getExport() { return export; } @@ -221,4 +229,28 @@ public String getTemplateVersion() { public void setTemplateVersion(String template_version) { this.template_version = template_version; } + + public List getModules() { + return modules; + } + + public void setModules(List modules) { + this.modules = modules; + } + + public String getReadme() { + return readme; + } + + public void setReadme(String readme) { + this.readme = readme; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/model/PackageJson.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/model/PackageJson.java index d44ac8019b3f..2369310761de 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/model/PackageJson.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/model/PackageJson.java @@ -18,6 +18,8 @@ package io.ballerina.projects.internal.model; +import io.ballerina.projects.PackageManifest; + import java.util.List; /** @@ -57,6 +59,11 @@ public class PackageJson { // GraalVM compatibility property for package private Boolean graalvmCompatible; + // Docs + private String readme; + private String description; + private List modules; + public PackageJson(String organization, String name, String version) { this.organization = organization; this.name = name; @@ -214,4 +221,28 @@ public Boolean getGraalvmCompatible() { public void setGraalvmCompatible(Boolean graalvmCompatible) { this.graalvmCompatible = graalvmCompatible; } + + public String getReadme() { + return readme; + } + + public void setReadme(String readme) { + this.readme = readme; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getModules() { + return modules; + } + + public void setModules(List modules) { + this.modules = modules; + } } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/ProjectConstants.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/ProjectConstants.java index 2ca9fc4ba5c0..84900fcc1aa2 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/ProjectConstants.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/ProjectConstants.java @@ -16,6 +16,7 @@ * under the License. */ package io.ballerina.projects.util; + /** * Defines constants related to the project directory. * @@ -23,6 +24,9 @@ */ public final class ProjectConstants { + public static final String README_MD_FILE_NAME = "README.md"; + public static final String README_EXTENSION = "md"; + private ProjectConstants() {} public static final String BLANG_SOURCE_EXT = ".bal"; diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/ProjectUtils.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/ProjectUtils.java index da43638ffb7d..760313d232fb 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/ProjectUtils.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/util/ProjectUtils.java @@ -134,7 +134,7 @@ public final class ProjectUtils { private static final Pattern onlyNonAlphanumericPattern = Pattern.compile("^[^a-zA-Z0-9]+$"); private static final Pattern orgNamePattern = Pattern.compile("^[a-zA-Z0-9_]*$"); private static final Pattern separatedIdentifierWithHyphenPattern = Pattern.compile("^[a-zA-Z0-9_.-]*$"); - private static String projectLoadingDiagnostic; + private static final List projectLoadingDiagnostic = new ArrayList<>(); private ProjectUtils() { } @@ -1274,7 +1274,7 @@ private static String removeTrailingSlashes(String pattern) { } /** - * Return the path of a bala with the available platform directory (java17 or any). + * Return the path of a bala with the available platform directory (java21 or any). * * @param balaDirPath path to the bala directory * @param org org name of the bala @@ -1441,14 +1441,19 @@ public enum CompatibleRange { // TODO: Remove this with https://github.com/ballerina-platform/ballerina-lang/issues/43212 // once diagnostic support for project loading stage is added. - public static void addProjectLoadingDiagnostic(String diagnosticMessage) { - projectLoadingDiagnostic = diagnosticMessage; + public static void addMiscellaneousProjectDiagnostics(Diagnostic diagnosticMessage) { + projectLoadingDiagnostic.add(diagnosticMessage); } - public static String getProjectLoadingDiagnostic() { + public static List getProjectLoadingDiagnostic() { return projectLoadingDiagnostic; } + // This is needed to clear the diagnostics when unit testing + public static void clearDiagnostics() { + projectLoadingDiagnostic.clear(); + } + /** * Checks if there are any services in the default module of the project. * diff --git a/compiler/ballerina-lang/src/main/java/org/ballerinalang/codegen/BallerinaAnnotationProcessor.java b/compiler/ballerina-lang/src/main/java/org/ballerinalang/codegen/BallerinaAnnotationProcessor.java index dd0805b8ddcb..2e3288916017 100644 --- a/compiler/ballerina-lang/src/main/java/org/ballerinalang/codegen/BallerinaAnnotationProcessor.java +++ b/compiler/ballerina-lang/src/main/java/org/ballerinalang/codegen/BallerinaAnnotationProcessor.java @@ -53,7 +53,7 @@ */ @SupportedAnnotationTypes({ "org.ballerinalang.annotation.JavaSPIService", "org.ballerinalang.natives.annotations.BallerinaFunction" }) -@SupportedSourceVersion(SourceVersion.RELEASE_17) +@SupportedSourceVersion(SourceVersion.RELEASE_21) @SupportedOptions({ "nativeEntityProviderPackage", "nativeEntityProviderClass" }) public class BallerinaAnnotationProcessor extends AbstractProcessor { diff --git a/compiler/ballerina-lang/src/main/java/org/ballerinalang/spi/EmbeddedExecutor.java b/compiler/ballerina-lang/src/main/java/org/ballerinalang/spi/EmbeddedExecutor.java index 1020d420a9b4..df30a3d014dc 100644 --- a/compiler/ballerina-lang/src/main/java/org/ballerinalang/spi/EmbeddedExecutor.java +++ b/compiler/ballerina-lang/src/main/java/org/ballerinalang/spi/EmbeddedExecutor.java @@ -17,7 +17,7 @@ */ package org.ballerinalang.spi; -import io.ballerina.runtime.api.async.StrandMetadata; +import io.ballerina.runtime.api.concurrent.StrandMetadata; import java.util.Optional; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java index 9845ca03efc4..e4ab5f08164d 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/BIRGen.java @@ -863,13 +863,10 @@ public void visit(BLangLambdaFunction lambdaExpr) { PackageID pkgID = lambdaExpr.function.symbol.pkgID; PackageID boundMethodPkgId = getPackageIdForBoundMethod(lambdaExpr, funcName.value); - boolean isWorker = lambdaExpr.function.flagSet.contains(Flag.WORKER); - List closureMapOperands = getClosureMapOperands(lambdaExpr); - BIRNonTerminator.FPLoad fpLoad = new BIRNonTerminator.FPLoad(lambdaExpr.pos, pkgID, - boundMethodPkgId != null ? boundMethodPkgId : pkgID, funcName, lhsOp, params, closureMapOperands, - lambdaExpr.getBType(), lambdaExpr.function.symbol.strandName, - lambdaExpr.function.symbol.schedulerPolicy, isWorker); + BIRNonTerminator.FPLoad fpLoad = new BIRNonTerminator.FPLoad(lambdaExpr.pos, pkgID, funcName, lhsOp, params, + closureMapOperands, lambdaExpr.getBType(), lambdaExpr.function.symbol.strandName, + lambdaExpr.function.symbol.schedulerPolicy, boundMethodPkgId); setScopeAndEmit(fpLoad); BType targetType = getRecordTargetType(funcName.value); if (lambdaExpr.function.flagSet.contains(Flag.RECORD) && targetType != null && @@ -1430,10 +1427,17 @@ private void createCall(BLangInvocation invocationExpr, boolean isVirtual) { invocationExpr.expr.accept(this); fp = this.env.targetOperand; } - // Create a temporary variable to store the return operation result. - BIRVariableDcl tempVarDcl = new BIRVariableDcl(invocationExpr.getBType(), this.env.nextLocalVarId(names), - VarScope.FUNCTION, VarKind.TEMP); + BIRVariableDcl tempVarDcl; + if (invocationExpr.async && invocationExpr.parent instanceof BLangSimpleVariable simpleVar) { + tempVarDcl = new BIRVariableDcl(invocationExpr.pos, invocationExpr.getBType(), + this.env.nextLocalVarId(names), VarScope.FUNCTION, VarKind.TEMP, simpleVar.name.value); + } else { + tempVarDcl = new BIRVariableDcl(invocationExpr.getBType(), this.env.nextLocalVarId(names), + VarScope.FUNCTION, VarKind.TEMP); + } + + this.env.enclFunc.localVars.add(tempVarDcl); BIROperand lhsOp = new BIROperand(tempVarDcl); this.env.targetOperand = lhsOp; @@ -1447,8 +1451,13 @@ private void createCall(BLangInvocation invocationExpr, boolean isVirtual) { // TODO: make vCall a new instruction to avoid package id in vCall if (invocationExpr.functionPointerInvocation) { boolean workerDerivative = Symbols.isFlagOn(invocationExpr.symbol.flags, Flags.WORKER); + List annots = + getBIRAnnotAttachmentsForASTAnnotAttachments(invocationExpr.annAttachments); this.env.enclBB.terminator = new BIRTerminator.FPCall(invocationExpr.pos, InstructionKind.FP_CALL, - fp, args, lhsOp, invocationExpr.async, thenBB, this.currentScope, workerDerivative); + fp, args, lhsOp, invocationExpr.async, thenBB, this.currentScope, annots); + if (workerDerivative) { + this.env.enclFunc.hasWorkers = true; + } } else if (invocationExpr.async) { BInvokableSymbol bInvokableSymbol = (BInvokableSymbol) invocationExpr.symbol; List calleeAnnots = getBIRAnnotAttachments(bInvokableSymbol.getAnnotations()); @@ -2038,8 +2047,8 @@ public void visit(BLangTrapExpr trapExpr) { this.env.enclBB.terminator = new BIRTerminator.GOTO(trapExpr.pos, nextBB, this.currentScope); } - env.enclFunc.errorTable.add(new BIRNode.BIRErrorEntry(trappedBlocks.get(0), - trappedBlocks.get(trappedBlocks.size() - 1), env.targetOperand, nextBB)); + env.enclFunc.errorTable.add(new BIRNode.BIRErrorEntry(trappedBlocks.getFirst(), trappedBlocks.getLast(), + env.targetOperand, nextBB)); this.env.enclBB = nextBB; } @@ -3037,10 +3046,9 @@ private void generateFPVarRef(BLangExpression fpVarRef, BInvokableSymbol funcSym VarScope.FUNCTION, VarKind.ARG, null); params.add(birVarDcl); } - - setScopeAndEmit( - new BIRNonTerminator.FPLoad(fpVarRef.pos, funcSymbol.pkgID, funcName, lhsOp, params, new ArrayList<>(), - funcSymbol.type, funcSymbol.strandName, funcSymbol.schedulerPolicy)); + setScopeAndEmit(new BIRNonTerminator.FPLoad(fpVarRef.pos, funcSymbol.pkgID, funcName, lhsOp, params, + new ArrayList<>(), funcSymbol.type, funcSymbol.strandName, funcSymbol.schedulerPolicy, + funcSymbol.pkgID)); this.env.targetOperand = lhsOp; } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/BallerinaClassWriter.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/BallerinaClassWriter.java index 0caa2101a4f4..11c5eefa993e 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/BallerinaClassWriter.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/BallerinaClassWriter.java @@ -65,10 +65,9 @@ protected String getCommonSuperClass(String type1, String type2) { return OBJECT_CLASS; } - class1 = class1.getSuperclass(); - while (!class1.isAssignableFrom(class2)) { + do { class1 = class1.getSuperclass(); - } + } while (!class1.isAssignableFrom(class2)); return class1.getName().replace('.', '/'); } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmCodeGenUtil.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmCodeGenUtil.java index c29c33712cda..bd2c90751dd4 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmCodeGenUtil.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmCodeGenUtil.java @@ -30,16 +30,15 @@ import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; -import org.wso2.ballerinalang.compiler.bir.codegen.internal.AsyncDataCollector; import org.wso2.ballerinalang.compiler.bir.codegen.internal.LabelGenerator; import org.wso2.ballerinalang.compiler.bir.codegen.internal.NameHashComparator; -import org.wso2.ballerinalang.compiler.bir.codegen.internal.ScheduleFunctionInfo; import org.wso2.ballerinalang.compiler.bir.codegen.interop.InteropMethodGen; import org.wso2.ballerinalang.compiler.bir.codegen.model.JType; import org.wso2.ballerinalang.compiler.bir.codegen.model.JTypeTags; import org.wso2.ballerinalang.compiler.bir.codegen.split.JvmConstantsGen; import org.wso2.ballerinalang.compiler.bir.model.BIRAbstractInstruction; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; +import org.wso2.ballerinalang.compiler.bir.model.BIRTerminator; import org.wso2.ballerinalang.compiler.bir.model.BirScope; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BStructureTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeSymbol; @@ -59,33 +58,27 @@ import java.util.regex.Pattern; import static io.ballerina.runtime.api.constants.RuntimeConstants.UNDERSCORE; -import static org.objectweb.asm.Opcodes.AASTORE; import static org.objectweb.asm.Opcodes.ACONST_NULL; import static org.objectweb.asm.Opcodes.ALOAD; -import static org.objectweb.asm.Opcodes.ANEWARRAY; import static org.objectweb.asm.Opcodes.ASTORE; import static org.objectweb.asm.Opcodes.ATHROW; -import static org.objectweb.asm.Opcodes.BIPUSH; import static org.objectweb.asm.Opcodes.CHECKCAST; import static org.objectweb.asm.Opcodes.DUP; +import static org.objectweb.asm.Opcodes.GETFIELD; import static org.objectweb.asm.Opcodes.GETSTATIC; import static org.objectweb.asm.Opcodes.GOTO; -import static org.objectweb.asm.Opcodes.H_INVOKESTATIC; import static org.objectweb.asm.Opcodes.ICONST_0; -import static org.objectweb.asm.Opcodes.ICONST_1; -import static org.objectweb.asm.Opcodes.IFEQ; -import static org.objectweb.asm.Opcodes.ILOAD; import static org.objectweb.asm.Opcodes.INVOKEINTERFACE; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.INVOKESTATIC; import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; import static org.objectweb.asm.Opcodes.NEW; +import static org.objectweb.asm.Opcodes.RETURN; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BALLERINA; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BAL_EXTENSION; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BUILT_IN_PACKAGE_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_STRING_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_STRING_VAR_PREFIX; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CHANNEL_DETAILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.DECIMAL_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ENCODED_DOT_CHARACTER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ERROR_VALUE; @@ -96,16 +89,13 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JAVA_RUNTIME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_TO_STRING_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAKE_CONCAT_WITH_CONSTANTS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAX_STRINGS_PER_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_START_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OVERFLOW_LINE_NUMBER; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.START_OF_HEADING_WITH_SEMICOLON; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_CLASS; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_METADATA_VAR_PREFIX; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_WORKER_CHANNEL_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRING_BUILDER; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRING_CONCAT_FACTORY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRING_UTILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WINDOWS_PATH_SEPERATOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.FP_INIT; @@ -126,13 +116,12 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_STREAM_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TABLE_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TYPEDESC; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_WORKER_CHANNEL_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_XML; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_DESCRIPTOR_FOR_STRING_CONCAT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INITIAL_METHOD_DESC; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_CHANNEL_DETAILS; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_CLASS_CONSTRUCTOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_ERROR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_WITH_STRING; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INT_TO_STRING; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RETURN_ARRAY_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RETURN_B_OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RETURN_B_STRING_VALUE; @@ -195,7 +184,7 @@ public static void createFunctionPointer(MethodVisitor mv, String className, Str // load null here for type, since these are fps created for internal usage. mv.visitInsn(Opcodes.ACONST_NULL); - mv.visitInsn(Opcodes.ACONST_NULL); + mv.visitLdcInsn(lambdaName); mv.visitInsn(Opcodes.ICONST_0); // mark as not-concurrent ie: 'parent' mv.visitMethodInsn(Opcodes.INVOKESPECIAL, FUNCTION_POINTER, JVM_INIT_METHOD, FP_INIT, false); } @@ -269,18 +258,22 @@ public static String getFieldTypeSignature(BType bType) { public static void generateDefaultConstructor(ClassWriter cw, String ownerClass) { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, JVM_INIT_METHOD, VOID_METHOD_DESC, null, null); mv.visitCode(); - mv.visitVarInsn(Opcodes.ALOAD, 0); - mv.visitMethodInsn(Opcodes.INVOKESPECIAL, ownerClass, JVM_INIT_METHOD, VOID_METHOD_DESC, false); - mv.visitInsn(Opcodes.RETURN); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, ownerClass, JVM_INIT_METHOD, VOID_METHOD_DESC, false); + mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); } - public static String setAndGetStrandMetadataVarName(String parentFunction, AsyncDataCollector asyncDataCollector) { - String metaDataVarName = STRAND_METADATA_VAR_PREFIX + parentFunction + "$"; - asyncDataCollector.getStrandMetadata().putIfAbsent(metaDataVarName, - new ScheduleFunctionInfo(parentFunction)); - return metaDataVarName; + public static void generateInitClassConstructor(ClassWriter cw, String ownerClass) { + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, JVM_INIT_METHOD, INIT_CLASS_CONSTRUCTOR, null, null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESPECIAL, ownerClass, JVM_INIT_METHOD, INIT_CLASS_CONSTRUCTOR, false); + mv.visitInsn(Opcodes.RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); } public static boolean isExternFunc(BIRNode.BIRFunction func) { @@ -457,42 +450,6 @@ public static String generateReturnType(BType bType) { }; } - public static void loadChannelDetails(MethodVisitor mv, List channels, - int invocationVarIndex) { - mv.visitIntInsn(BIPUSH, channels.size()); - mv.visitTypeInsn(ANEWARRAY, CHANNEL_DETAILS); - int index = 0; - for (BIRNode.ChannelDetails ch : channels) { - mv.visitInsn(DUP); - mv.visitIntInsn(BIPUSH, index); - index += 1; - - mv.visitTypeInsn(NEW, CHANNEL_DETAILS); - mv.visitInsn(DUP); - mv.visitVarInsn(ILOAD, invocationVarIndex); - mv.visitInvokeDynamicInsn(MAKE_CONCAT_WITH_CONSTANTS, INT_TO_STRING, - new Handle(H_INVOKESTATIC, STRING_CONCAT_FACTORY, MAKE_CONCAT_WITH_CONSTANTS, - HANDLE_DESCRIPTOR_FOR_STRING_CONCAT, false), - ch.name + START_OF_HEADING_WITH_SEMICOLON); - - if (ch.channelInSameStrand) { - mv.visitInsn(ICONST_1); - } else { - mv.visitInsn(ICONST_0); - } - - if (ch.send) { - mv.visitInsn(ICONST_1); - } else { - mv.visitInsn(ICONST_0); - } - - mv.visitMethodInsn(INVOKESPECIAL, CHANNEL_DETAILS, JVM_INIT_METHOD, - INIT_CHANNEL_DETAILS, false); - mv.visitInsn(AASTORE); - } - } - public static String toNameString(BType t) { BTypeSymbol typeSymbol = t.tsymbol; if ((typeSymbol.kind == SymbolKind.RECORD || typeSymbol.kind == SymbolKind.OBJECT) && @@ -575,38 +532,12 @@ public static BirScope getLastScopeFromTerminator(MethodVisitor mv, BIRNode.BIRB return lastScope; } - public static void genYieldCheck(MethodVisitor mv, LabelGenerator labelGen, BIRNode.BIRBasicBlock thenBB, - String funcName, int localVarOffset, int yieldLocationVarIndex, - Location terminatorPos, String fullyQualifiedFuncName, String yieldStatus, - int yieldStatusVarIndex) { - mv.visitVarInsn(ALOAD, localVarOffset); - mv.visitMethodInsn(INVOKEVIRTUAL, STRAND_CLASS, "isYielded", "()Z", false); - generateSetYieldedStatus(mv, labelGen, funcName, yieldLocationVarIndex, terminatorPos, - fullyQualifiedFuncName, yieldStatus, yieldStatusVarIndex); - Label gotoLabel = labelGen.getLabel(funcName + thenBB.id.value); - mv.visitJumpInsn(GOTO, gotoLabel); - } - - static void generateSetYieldedStatus(MethodVisitor mv, LabelGenerator labelGen, String funcName, - int yieldLocationVarIndex, Location terminatorPos, - String fullyQualifiedFuncName, String yieldStatus, - int yieldStatusVarIndex) { - Label yieldLocationLabel = new Label(); - mv.visitJumpInsn(IFEQ, yieldLocationLabel); - - StringBuilder yieldLocationData = new StringBuilder(fullyQualifiedFuncName); - if (terminatorPos != null) { - yieldLocationData.append("(").append(terminatorPos.lineRange().fileName()).append(":") - .append(terminatorPos.lineRange().startLine().line() + 1).append(")"); + public static void genGotoThenBB(MethodVisitor mv, BIRNode.BIRBasicBlock thenBB, LabelGenerator labelGen, + BIRTerminator terminator, String funcName) { + if (thenBB != null) { + Label gotoLabel = labelGen.getLabel(funcName + terminator.thenBB.id.value); + mv.visitJumpInsn(GOTO, gotoLabel); } - mv.visitLdcInsn(yieldLocationData.toString()); - mv.visitVarInsn(ASTORE, yieldLocationVarIndex); - mv.visitLdcInsn(yieldStatus); - mv.visitVarInsn(ASTORE, yieldStatusVarIndex); - - Label yieldLabel = labelGen.getLabel(funcName + "yield"); - mv.visitJumpInsn(GOTO, yieldLabel); - mv.visitLabel(yieldLocationLabel); } public static PackageID cleanupPackageID(PackageID pkgID) { @@ -738,7 +669,6 @@ private static String removeDecimalDiscriminator(String value) { public static void createDefaultCase(MethodVisitor mv, Label defaultCaseLabel, int nameRegIndex, String errorMessage) { - mv.visitLabel(defaultCaseLabel); mv.visitTypeInsn(NEW, ERROR_VALUE); mv.visitInsn(DUP); @@ -747,24 +677,19 @@ public static void createDefaultCase(MethodVisitor mv, Label defaultCaseLabel, i mv.visitTypeInsn(NEW, STRING_BUILDER); mv.visitInsn(DUP); mv.visitLdcInsn(errorMessage); - mv.visitMethodInsn(INVOKESPECIAL, STRING_BUILDER, JVM_INIT_METHOD, INIT_WITH_STRING, - false); + mv.visitMethodInsn(INVOKESPECIAL, STRING_BUILDER, JVM_INIT_METHOD, INIT_WITH_STRING, false); mv.visitVarInsn(ALOAD, nameRegIndex); - mv.visitMethodInsn(INVOKEVIRTUAL, STRING_BUILDER, "append", - STRING_BUILDER_APPEND, false); - mv.visitMethodInsn(INVOKEVIRTUAL, STRING_BUILDER, JVM_TO_STRING_METHOD, GET_JSTRING - , false); + mv.visitMethodInsn(INVOKEVIRTUAL, STRING_BUILDER, "append", STRING_BUILDER_APPEND, false); + mv.visitMethodInsn(INVOKEVIRTUAL, STRING_BUILDER, JVM_TO_STRING_METHOD, GET_JSTRING, false); mv.visitMethodInsn(INVOKESTATIC, STRING_UTILS, "fromString", FROM_STRING, false); - mv.visitMethodInsn(INVOKESPECIAL, ERROR_VALUE, JVM_INIT_METHOD, INIT_ERROR, - false); + mv.visitMethodInsn(INVOKESPECIAL, ERROR_VALUE, JVM_INIT_METHOD, INIT_ERROR, false); mv.visitInsn(ATHROW); } public static void castToJavaString(MethodVisitor mv, int fieldNameRegIndex, int strKeyVarIndex) { mv.visitVarInsn(ALOAD, fieldNameRegIndex); mv.visitTypeInsn(CHECKCAST, B_STRING_VALUE); - mv.visitMethodInsn(INVOKEINTERFACE, B_STRING_VALUE, GET_VALUE_METHOD, - GET_JSTRING, true); + mv.visitMethodInsn(INVOKEINTERFACE, B_STRING_VALUE, GET_VALUE_METHOD, GET_JSTRING, true); mv.visitVarInsn(ASTORE, strKeyVarIndex); } @@ -779,9 +704,8 @@ public static void visitMaxStackForMethod(MethodVisitor mv, String funcName, Str try { mv.visitMaxs(0, 0); } catch (Throwable e) { - throw new BLangCompilerException( - "error while generating method '" + Utils.decodeIdentifier(funcName) + "' in class '" + - Utils.decodeIdentifier(className) + "'", e); + throw new BLangCompilerException("error while generating method '" + Utils.decodeIdentifier(funcName) + + "' in class '" + Utils.decodeIdentifier(className) + "'", e); } } @@ -831,6 +755,16 @@ public static String getSig(Class c) { } } + public static void loadWorkerChannelMap(MethodVisitor mv, BIRNode.BIRFunction func, int channelMapVarIndex, + int localVarOffset) { + if (func.hasWorkers) { + mv.visitVarInsn(ALOAD, channelMapVarIndex); + } else { + mv.visitVarInsn(ALOAD, localVarOffset); + mv.visitFieldInsn(GETFIELD, STRAND_CLASS, STRAND_WORKER_CHANNEL_MAP, GET_WORKER_CHANNEL_MAP); + } + } + public static void markAsRootPackage() { isRootPkgCodeGen = true; } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmConstants.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmConstants.java index f510a244f281..8b36b3d02c79 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmConstants.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmConstants.java @@ -46,7 +46,6 @@ public final class JvmConstants { public static final String ARRAY_VALUE = "io/ballerina/runtime/internal/values/ArrayValue"; public static final String ABSTRACT_OBJECT_VALUE = "io/ballerina/runtime/internal/values/AbstractObjectValue"; public static final String BREF_VALUE = "io/ballerina/runtime/api/values/BRefValue"; - public static final String REF_VALUE = "io/ballerina/runtime/internal/values/RefValue"; public static final String ERROR_VALUE = "io/ballerina/runtime/internal/values/ErrorValue"; public static final String BERROR = "io/ballerina/runtime/api/values/BError"; public static final String STRING_VALUE = "java/lang/String"; @@ -68,8 +67,7 @@ public final class JvmConstants { public static final String TYPEDESC_VALUE_IMPL_CLOSURES = "closures"; public static final String TYPEDESC_VALUE = "io/ballerina/runtime/internal/values/TypedescValue"; public static final String HANDLE_VALUE = "io/ballerina/runtime/internal/values/HandleValue"; - public static final String LOCK_VALUE = "io/ballerina/runtime/internal/BLock"; - public static final String LOCK_STORE = "io/ballerina/runtime/internal/BLockStore"; + public static final String LOCK_STORE = "io/ballerina/runtime/internal/lock/BLockStore"; public static final String FUNCTION_POINTER = "io/ballerina/runtime/internal/values/FPValue"; public static final String ARRAY_VALUE_IMPL = "io/ballerina/runtime/internal/values/ArrayValueImpl"; public static final String TABLE_VALUE_IMPL = "io/ballerina/runtime/internal/values/TableValueImpl"; @@ -105,7 +103,7 @@ public final class JvmConstants { // types related classes public static final String TYPE = "io/ballerina/runtime/api/types/Type"; - public static final String PREDEFINED_TYPES = "io/ballerina/runtime/api/PredefinedTypes"; + public static final String PREDEFINED_TYPES = "io/ballerina/runtime/api/types/PredefinedTypes"; public static final String ARRAY_TYPE = "io/ballerina/runtime/api/types/ArrayType"; public static final String XML_TYPE = "io/ballerina/runtime/api/types/XmlType"; @@ -164,7 +162,7 @@ public final class JvmConstants { public static final String TYPE_REF_TYPE_IMPL = "io/ballerina/runtime/internal/types/BTypeReferenceType"; public static final String TYPE_IMPL = "io/ballerina/runtime/internal/types/BType"; public static final String MODULE = "io/ballerina/runtime/api/Module"; - public static final String CURRENT_MODULE_VAR_NAME = "$moduleName"; + public static final String CURRENT_MODULE_VAR_NAME = "$currentModule"; public static final String B_STRING_VAR_PREFIX = "$bString"; public static final String LARGE_STRING_VAR_PREFIX = "$stringChunk"; public static final String GET_SURROGATE_ARRAY_METHOD_PREFIX = "getSurrogateArray"; @@ -173,6 +171,7 @@ public final class JvmConstants { public static final String TYPEREF_TYPE_VAR_PREFIX = "$typeRefType$"; public static final String TUPLE_TYPE_VAR_PREFIX = "$tupleType"; public static final String ARRAY_TYPE_VAR_PREFIX = "$arrayType"; + public static final String FUNCTION_TYPE_VAR_PREFIX = "$functionType"; public static final String MODULE_VAR_PREFIX = "$module"; public static final String VARIABLE_KEY = "io/ballerina/runtime/internal/configurable/VariableKey"; @@ -182,41 +181,40 @@ public final class JvmConstants { public static final String TYPE_ID_SET = "io/ballerina/runtime/internal/types/BTypeIdSet"; // other jvm-specific classes + public static final String BAL_RUNTIME = "io/ballerina/runtime/internal/BalRuntime"; public static final String TYPE_CHECKER = "io/ballerina/runtime/internal/TypeChecker"; public static final String SCHEDULER = "io/ballerina/runtime/internal/scheduling/Scheduler"; - public static final String JSON_UTILS = "io/ballerina/runtime/internal/JsonInternalUtils"; + public static final String JSON_UTILS = "io/ballerina/runtime/internal/json/JsonInternalUtils"; public static final String STRAND_CLASS = "io/ballerina/runtime/internal/scheduling/Strand"; - public static final String STRAND_METADATA = "io/ballerina/runtime/api/async/StrandMetadata"; + public static final String STRAND_METADATA = "io/ballerina/runtime/api/concurrent/StrandMetadata"; public static final String BAL_ENV_CLASS = "io/ballerina/runtime/internal/BalEnvironment"; public static final String BAL_ENV = "io/ballerina/runtime/api/Environment"; public static final String TYPE_CONVERTER = "io/ballerina/runtime/internal/TypeConverter"; - public static final String FUNCTION_FRAME = "io/ballerina/runtime/internal/scheduling/FunctionFrame"; public static final String VALUE_CREATOR = "io/ballerina/runtime/internal/values/ValueCreator"; - public static final String XML_FACTORY = "io/ballerina/runtime/internal/XmlFactory"; + public static final String XML_FACTORY = "io/ballerina/runtime/internal/xml/XmlFactory"; public static final String XML_SEQUENCE = "io/ballerina/runtime/internal/values/XmlSequence"; - public static final String WD_CHANNELS = "io/ballerina/runtime/internal/scheduling/WDChannels"; - public static final String WORKER_DATA_CHANNEL = "io/ballerina/runtime/internal/scheduling/WorkerDataChannel"; - public static final String CHANNEL_DETAILS = "io/ballerina/runtime/internal/values/ChannelDetails"; + public static final String ASYNC_UTILS = "io/ballerina/runtime/internal/scheduling/AsyncUtils"; public static final String WORKER_UTILS = "io/ballerina/runtime/internal/scheduling/WorkerUtils"; - public static final String MAP_UTILS = "io/ballerina/runtime/internal/MapUtils"; - public static final String TABLE_UTILS = "io/ballerina/runtime/internal/TableUtils"; + public static final String WORKER_CHANNEL_MAP = "io/ballerina/runtime/internal/scheduling/WorkerChannelMap"; + public static final String MAP_UTILS = "io/ballerina/runtime/internal/utils/MapUtils"; + public static final String TABLE_UTILS = "io/ballerina/runtime/internal/utils/TableUtils"; public static final String STRING_UTILS = "io/ballerina/runtime/api/utils/StringUtils"; - public static final String ERROR_UTILS = "io/ballerina/runtime/internal/ErrorUtils"; - public static final String RUNTIME_UTILS = "io/ballerina/runtime/internal/util/RuntimeUtils"; - public static final String LARGE_STRUCTURE_UTILS = "io/ballerina/runtime/internal/util/LargeStructureUtils"; + public static final String ERROR_UTILS = "io/ballerina/runtime/internal/utils/ErrorUtils"; + public static final String RUNTIME_UTILS = "io/ballerina/runtime/internal/utils/RuntimeUtils"; + public static final String LARGE_STRUCTURE_UTILS = "io/ballerina/runtime/internal/utils/LargeStructureUtils"; public static final String OPTION = "io/ballerina/runtime/internal/cli/Option"; public static final String OPERAND = "io/ballerina/runtime/internal/cli/Operand"; public static final String CLI_SPEC = "io/ballerina/runtime/internal/cli/CliSpec"; public static final String LAUNCH_UTILS = "io/ballerina/runtime/internal/launch/LaunchUtils"; - public static final String MATH_UTILS = "io/ballerina/runtime/internal/MathUtils"; + public static final String MATH_UTILS = "io/ballerina/runtime/internal/utils/MathUtils"; public static final String ERROR_REASONS = "io/ballerina/runtime/internal/errors/ErrorReasons"; public static final String ERROR_CODES = "io/ballerina/runtime/internal/errors/ErrorCodes"; public static final String ERROR_HELPER = "io/ballerina/runtime/internal/errors/ErrorHelper"; - public static final String COMPATIBILITY_CHECKER = "io/ballerina/runtime/internal/util/CompatibilityChecker"; + public static final String COMPATIBILITY_CHECKER = "io/ballerina/runtime/internal/utils/CompatibilityChecker"; public static final String RUNTIME_REGISTRY_CLASS = "io/ballerina/runtime/internal/scheduling/RuntimeRegistry"; - public static final String VALUE_COMPARISON_UTILS = "io/ballerina/runtime/internal/ValueComparisonUtils"; + public static final String VALUE_COMPARISON_UTILS = "io/ballerina/runtime/internal/utils/ValueComparisonUtils"; public static final String REG_EXP_FACTORY = "io/ballerina/runtime/internal/regexp/RegExpFactory"; - public static final String REPOSITORY_IMPL = "io/ballerina/runtime/internal/RepositoryImpl"; + public static final String REPOSITORY_IMPL = "io/ballerina/runtime/internal/repository/RepositoryImpl"; // other java classes public static final String OBJECT = "java/lang/Object"; @@ -224,7 +222,6 @@ public final class JvmConstants { public static final String LINKED_HASH_MAP = "java/util/LinkedHashMap"; public static final String ARRAY_LIST = "java/util/ArrayList"; public static final String LIST = "java/util/List"; - public static final String STACK = "java/util/Stack"; public static final String SET = "java/util/Set"; public static final String LINKED_HASH_SET = "java/util/LinkedHashSet"; public static final String STRING_BUILDER = "java/lang/StringBuilder"; @@ -239,11 +236,9 @@ public final class JvmConstants { public static final String HASH_MAP = "java/util/HashMap"; public static final String PATH = "java/nio/file/Path"; public static final String SYSTEM = "java/lang/System"; - public static final String STRING_CONCAT_FACTORY = "java/lang/invoke/StringConcatFactory"; - public static final String RECEIVE_FIELD = "io/ballerina/runtime/internal/scheduling/WDChannels$ReceiveField"; // service objects, annotation processing related classes - public static final String ANNOTATION_UTILS = "io/ballerina/runtime/internal/AnnotationUtils"; + public static final String ANNOTATION_UTILS = "io/ballerina/runtime/internal/utils/AnnotationUtils"; public static final String ANNOTATION_MAP_NAME = "$annotation_data"; public static final String ANNOTATIONS_FIELD = "$annotations"; public static final String DEFAULTABLE_ARGS_ANOT_NAME = "DefaultableArgs"; @@ -255,12 +250,12 @@ public final class JvmConstants { public static final String TYPE_ANY_ARRAY = "TYPE_ANY_ARRAY"; // error related constants - public static final String PANIC_FIELD = "panic"; public static final String SET_DETAIL_TYPE_METHOD = "setDetailType"; public static final String SET_TYPEID_SET_METHOD = "setTypeIdSet"; public static final String TRAP_ERROR_METHOD = "trapError"; - public static final String BLOCKED_ON_EXTERN_FIELD = "blockedOnExtern"; - public static final String IS_BLOCKED_ON_EXTERN_FIELD = "isBlockedOnExtern"; + + // future related constants + public static final String GET = "get"; // union and tuple related constants public static final String SET_MEMBERS_METHOD = "setMemberTypes"; @@ -273,12 +268,11 @@ public final class JvmConstants { // exception classes public static final String THROWABLE = "java/lang/Throwable"; public static final String STACK_OVERFLOW_ERROR = "java/lang/StackOverflowError"; - public static final String HANDLE_THROWABLE_METHOD = "handleBErrorAndExit"; - public static final String HANDLE_ALL_THROWABLE_METHOD = "handleAllRuntimeErrorsAndExit"; - public static final String HANDLE_RETURNED_ERROR_METHOD = "handleRuntimeReturnValues"; public static final String UNSUPPORTED_OPERATION_EXCEPTION = "java/lang/UnsupportedOperationException"; - public static final String HANDLE_STOP_PANIC_METHOD = "handleAllRuntimeErrors"; - public static final String HANDLE_RETURNED_ERROR_METHOD_WITHOUT_EXIT = "handleRuntimeErrorReturns"; + public static final String HANDLE_FUTURE_METHOD = "handleFuture"; + public static final String HANDLE_FUTURE_AND_RETURN_IS_PANIC_METHOD = "handleFutureAndReturnIsPanic"; + public static final String HANDLE_FUTURE_AND_EXIT_METHOD = "handleFutureAndExit"; + public static final String HANDLE_THROWABLE_METHOD = "handleThrowable"; // code generation related constants. public static final String MODULE_INIT_CLASS_NAME = "$_init"; @@ -288,10 +282,10 @@ public final class JvmConstants { public static final String TUPLE_TYPE_CONSTANT_CLASS_NAME = "constants/$_tuple_type_constants"; public static final String ARRAY_TYPE_CONSTANT_CLASS_NAME = "constants/$_array_type_constants"; public static final String TYPEREF_TYPE_CONSTANT_CLASS_NAME = "constants/$_typeref_type_constants"; + public static final String FUNCTION_TYPE_CONSTANT_CLASS_NAME = "constants/$_function_type_constants"; public static final String MODULE_STRING_CONSTANT_CLASS_NAME = "constants/$_string_constants"; public static final String MODULE_SURROGATES_CLASS_NAME = "constants/$_surrogate_methods"; public static final String MODULE_CONSTANT_CLASS_NAME = "constants/$_module_constants"; - public static final String MODULE_STRAND_METADATA_CLASS_NAME = "constants/$_strand_metadata"; public static final String CONSTANTS_CLASS_NAME = "constants/$_constants"; public static final String MODULE_TYPES_CLASS_NAME = "types/$_types"; public static final String MODULE_RECORD_TYPES_CLASS_NAME = "types/$_record_types"; @@ -300,6 +294,8 @@ public final class JvmConstants { public static final String MODULE_UNION_TYPES_CLASS_NAME = "types/$_union_types"; public static final String MODULE_TUPLE_TYPES_CLASS_NAME = "types/$_tuple_types"; public static final String MODULE_ANON_TYPES_CLASS_NAME = "types/$_anon_types"; + public static final String MODULE_FUNCTION_TYPES_CLASS_NAME = "types/$_function_types"; + public static final String B_FUNCTION_TYPE_INIT_METHOD_PREFIX = "$function_type_init"; public static final String MODULE_RECORDS_CREATOR_CLASS_NAME = "creators/$_records"; public static final String MODULE_OBJECTS_CREATOR_CLASS_NAME = "creators/$_objects"; public static final String MODULE_FUNCTION_CALLS_CLASS_NAME = "creators/$_function_calls"; @@ -321,8 +317,8 @@ public final class JvmConstants { public static final String MODULE_INIT_METHOD_PREFIX = "$module_init"; public static final String CONSTANT_INIT_METHOD_PREFIX = "$constant_init"; public static final String ANNOTATIONS_METHOD_PREFIX = "$process_annotations"; - public static final String CURRENT_MODULE_INIT = "$currentModuleInit"; - public static final String CURRENT_MODULE_STOP = "$currentModuleStop"; + public static final String CURRENT_MODULE_INIT_METHOD = "$currentModuleInit"; + public static final String CURRENT_MODULE_STOP_METHOD = "$currentModuleStop"; public static final String MODULE_INIT_METHOD = "$moduleInit"; public static final String MODULE_START_METHOD = "$moduleStart"; public static final String MODULE_STOP_METHOD = "$moduleStop"; @@ -335,12 +331,11 @@ public final class JvmConstants { public static final String FILE_NAME_PERIOD_SEPERATOR = "$$$"; public static final String VALUE_CLASS_PREFIX = "$value$"; public static final String TYPEDESC_CLASS_PREFIX = "$typedesc$"; - public static final String FRAME_CLASS_PREFIX = "frames/$frame$"; public static final String BALLERINA = "ballerina"; public static final String ENCODED_DOT_CHARACTER = "&0046"; public static final String ENCODED_JAVA_MODULE = "jballerina&0046java"; public static final PackageID DEFAULT = new PackageID(Names.ANON_ORG, new Name(ENCODED_DOT_CHARACTER), - DEFAULT_VERSION); + DEFAULT_VERSION); public static final String BUILT_IN_PACKAGE_NAME = "lang" + ENCODED_DOT_CHARACTER + "annotations"; public static final String MODULE_START_ATTEMPTED = "$moduleStartAttempted"; public static final String PARENT_MODULE_START_ATTEMPTED = "$parentModuleStartAttempted"; @@ -366,16 +361,23 @@ public final class JvmConstants { public static final String CREATE_TYPE_INSTANCES_METHOD = "$createTypeInstances"; public static final String GLOBAL_LOCK_NAME = "lock"; public static final String SERVICE_EP_AVAILABLE = "$serviceEPAvailable"; - public static final String LOCK_STORE_VAR_NAME = "$LOCK_STORE"; + public static final String BAL_RUNTIME_VAR_NAME = "$balRuntime"; + public static final String LOCK_STORE_VAR_NAME = "$lockStore"; + public static final String WORKER_CHANNEL_MAP_VAR_NAME = "$channelMap"; + public static final String SEND_WORKER_CHANNEL_NAMES_VAR_NAME = "$sendWorkerChannelNames"; + public static final String RECEIVE_WORKER_CHANNEL_NAMES_VAR_NAME = "$receiveWorkerChannelNames"; + public static final String WORKER_CHANNEL_NAMES_MAP = "$channelNamesMap"; + public static final String WORKER_CHANNELS_ADD_METHOD = "addWorkerChannels"; + public static final String WORKER_CHANNELS_COMPLETE_METHOD = "completedWorkerChannels"; + public static final String WORKER_CHANNELS_COMPLETE_WITH_PANIC_METHOD = "completeWorkerChannelsWithPanic"; public static final String RECORD_INIT_WRAPPER_NAME = "$init"; - public static final String RUNTIME_REGISTRY_VARIABLE = "$runtimeRegistry"; + public static final String RUNTIME_REGISTRY_VARIABLE = "runtimeRegistry"; + public static final String SCHEDULER_VARIABLE = "scheduler"; public static final String CONFIGURE_INIT = "$configureInit"; public static final String CONFIGURATION_CLASS_NAME = "$configurationMapper"; public static final String POPULATE_CONFIG_DATA_METHOD = "$initAndPopulateConfigData"; public static final String CONFIGURE_INIT_ATTEMPTED = "$configureInitAttempted"; public static final String HANDLE_ANYDATA_VALUES = "handleAnydataValues"; - public static final String MAKE_CONCAT_WITH_CONSTANTS = "makeConcatWithConstants"; - public static final String START_OF_HEADING_WITH_SEMICOLON = ":\u0001"; public static final String CREATE_INTEROP_ERROR_METHOD = "createInteropError"; public static final String LAMBDA_PREFIX = "$lambda$"; public static final String SPLIT_CLASS_SUFFIX = "$split$"; @@ -387,9 +389,8 @@ public final class JvmConstants { public static final String CLASS_FILE_SUFFIX = ".class"; // scheduler related constants - public static final String SCHEDULE_FUNCTION_METHOD = "scheduleFunction"; - public static final String SCHEDULE_LOCAL_METHOD = "scheduleLocal"; - public static final String SCHEDULER_START_METHOD = "start"; + public static final String START_ISOLATED_WORKER = "startIsolatedWorker"; + public static final String START_NON_ISOLATED_WORKER = "startNonIsolatedWorker"; public static final String CREATE_RECORD_VALUE = "createRecordValue"; public static final String CREATE_OBJECT_VALUE = "createObjectValue"; public static final String CREATE_ERROR_VALUE = "createErrorValue"; @@ -397,20 +398,20 @@ public final class JvmConstants { public static final String INSTANTIATE_FUNCTION = "instantiate"; public static final String GET_ANON_TYPE_METHOD = "getAnonType"; + public static final String GET_FUNCTION_TYPE_METHOD = "getFunctionType"; // strand data related constants public static final String STRAND = "strand"; public static final String STRAND_THREAD = "thread"; public static final String STRAND_NAME = "name"; public static final String STRAND_POLICY_NAME = "policy"; + public static final String STRAND_WORKER_CHANNEL_MAP = "workerChannelMap"; public static final String STRAND_VALUE_ANY = "any"; public static final String STRAND_METADATA_VAR_PREFIX = "$strand_metadata$"; public static final String MAIN_ARG_VAR_PREFIX = "%param"; - public static final String GRACEFUL_EXIT_METHOD_NAME = "gracefulExit"; - public static final String SET_LISTENER_FOUND_METHOD_NAME = "setListenerDeclarationFound"; + public static final String WAIT_ON_LISTENERS_METHOD_NAME = "waitOnListeners"; public static final String DEFAULT_STRAND_DISPATCHER = "DEFAULT"; - public static final String YIELD_LOCATION = "yieldLocation"; - public static final String YIELD_STATUS = "yieldStatus"; + public static final String DEFAULT_STRAND_NAME = "anon"; // transaction related constants public static final String TRANSACTION_CONTEXT_CLASS = "io/ballerina/runtime/transactions/TransactionLocalContext"; @@ -443,6 +444,7 @@ public final class JvmConstants { public static final int MAX_MEMBERS_PER_METHOD = 100; public static final int MAX_TYPES_PER_METHOD = 100; public static final int MAX_FIELDS_PER_SPLIT_METHOD = 500; + public static final int MAX_FUNCTION_TYPE_FIELDS_PER_SPLIT_METHOD = 140; public static final int MAX_MODULES_PER_METHOD = 100; public static final int MAX_CALLS_PER_CLIENT_METHOD = 100; public static final int MAX_CONSTANTS_PER_METHOD = 100; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmDesugarPhase.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmDesugarPhase.java index 7d00e3cf63ae..8f5a0f31cbc3 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmDesugarPhase.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmDesugarPhase.java @@ -133,7 +133,7 @@ private static void rewriteRecordInitFunction(BIRFunction func, BRecordType reco List localVars = func.localVars; List updatedLocalVars = new ArrayList<>(); - updatedLocalVars.add(localVars.get(0)); + updatedLocalVars.add(localVars.getFirst()); updatedLocalVars.add(selfParam); int index = 1; while (index < localVars.size()) { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmErrorGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmErrorGen.java index c77ba0bd9e8f..7353e8c2096f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmErrorGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmErrorGen.java @@ -80,8 +80,8 @@ void genPanic(BIRTerminator.Panic panicTerm) { } public void generateTryCatch(BIRNode.BIRFunction func, String funcName, BIRNode.BIRBasicBlock currentBB, - JvmTerminatorGen termGen, LabelGenerator labelGen, int invocationVarIndex, - int localVarOffset) { + JvmTerminatorGen termGen, LabelGenerator labelGen, int channelMapVarIndex, + int sendWorkerChannelNamesVar, int receiveWorkerChannelNamesVar, int localVarOffset) { BIRNode.BIRErrorEntry currentEE = findErrorEntry(func.errorTable, currentBB); if (currentEE == null) { @@ -108,7 +108,8 @@ public void generateTryCatch(BIRNode.BIRFunction func, String funcName, BIRNode. this.mv.visitMethodInsn(INVOKESTATIC, ERROR_UTILS, CREATE_INTEROP_ERROR_METHOD, CREATE_ERROR_FROM_THROWABLE, false); jvmInstructionGen.generateVarStore(this.mv, retVarDcl, retIndex); - termGen.genReturnTerm(retIndex, func, invocationVarIndex, localVarOffset); + termGen.genReturnTerm(retIndex, func, channelMapVarIndex, sendWorkerChannelNamesVar, + receiveWorkerChannelNamesVar, localVarOffset); this.mv.visitJumpInsn(GOTO, jumpLabel); } if (!exeptionExist) { @@ -120,13 +121,18 @@ public void generateTryCatch(BIRNode.BIRFunction func, String funcName, BIRNode. this.mv.visitJumpInsn(GOTO, jumpLabel); } Label otherErrorLabel = new Label(); + Label sOErrorlabel = new Label(); + this.mv.visitTryCatchBlock(startLabel, endLabel, sOErrorlabel, STACK_OVERFLOW_ERROR); this.mv.visitTryCatchBlock(startLabel, endLabel, otherErrorLabel, THROWABLE); - + this.mv.visitLabel(sOErrorlabel); + this.mv.visitMethodInsn(INVOKESTATIC, ERROR_UTILS, TRAP_ERROR_METHOD, CREATE_ERROR_FROM_THROWABLE, + false); + this.mv.visitInsn(ATHROW); + this.mv.visitJumpInsn(GOTO, jumpLabel); this.mv.visitLabel(otherErrorLabel); this.mv.visitMethodInsn(INVOKESTATIC, ERROR_UTILS, CREATE_INTEROP_ERROR_METHOD, CREATE_ERROR_FROM_THROWABLE, false); this.mv.visitInsn(ATHROW); - this.mv.visitJumpInsn(GOTO, jumpLabel); this.mv.visitLabel(jumpLabel); return; } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java index 1f18e04c03ae..7ba8024a01db 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmInstructionGen.java @@ -187,14 +187,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.XML_FACTORY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.XML_QNAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.XML_VALUE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_BYTE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_JBOOLEAN; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_JBYTE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_JCHAR; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_JDOUBLE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_JFLOAT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_JLONG; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_JSTRING; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ARRAY_ADD_BSTRING; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ARRAY_ADD_OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.BAL_ENV_PARAM; @@ -316,29 +309,6 @@ public JvmInstructionGen(MethodVisitor mv, BIRVarToJVMIndexMap indexMap, Package this.moduleInitClass = JvmCodeGenUtil.getModuleLevelClassName(currentPackage, MODULE_INIT_CLASS_NAME); } - static void addJUnboxInsn(MethodVisitor mv, JType jType) { - - if (jType == null) { - return; - } - - switch (jType.jTag) { - case JTypeTags.JBYTE -> mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToJByte", ANY_TO_JBYTE, false); - case JTypeTags.JCHAR -> mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToJChar", ANY_TO_JCHAR, false); - case JTypeTags.JSHORT -> - mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToJShort", ANY_TO_JSTRING, false); - case JTypeTags.JINT -> mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToJInt", ANY_TO_BYTE, false); - case JTypeTags.JLONG -> mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToJLong", ANY_TO_JLONG, false); - case JTypeTags.JFLOAT -> - mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToJFloat", ANY_TO_JFLOAT, false); - case JTypeTags.JDOUBLE -> - mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToJDouble", ANY_TO_JDOUBLE, false); - case JTypeTags.JBOOLEAN -> mv.visitMethodInsn(INVOKESTATIC, TYPE_CHECKER, "anyToJBoolean", ANY_TO_JBOOLEAN, - false); - case JTypeTags.JREF -> mv.visitTypeInsn(CHECKCAST, ((JType.JRefType) jType).typeValue); - } - } - private void generateJVarLoad(MethodVisitor mv, JType jType, int valueIndex) { switch (jType.jTag) { @@ -562,8 +532,9 @@ private void generateJMethodCallIns(int localVarOffset, JMethodCallInstruction c this.mv.visitVarInsn(ALOAD, localVarOffset); // load the current Module mv.visitFieldInsn(GETSTATIC, this.moduleInitClass, CURRENT_MODULE_VAR_NAME, GET_MODULE); - mv.visitMethodInsn(INVOKESPECIAL, BAL_ENV_CLASS, JVM_INIT_METHOD, - INIT_BAL_ENV, false); + mv.visitInsn(ACONST_NULL); + mv.visitInsn(ACONST_NULL); + mv.visitMethodInsn(INVOKESPECIAL, BAL_ENV_CLASS, JVM_INIT_METHOD, INIT_BAL_ENV, false); } while (argIndex < callIns.args.size()) { BIROperand arg = callIns.args.get(argIndex); @@ -1671,8 +1642,6 @@ void generateFPLoadIns(BIRNonTerminator.FPLoad inst) { String name = inst.funcName.value; String funcKey = inst.pkgId.toString() + ":" + name; - - BType type = JvmCodeGenUtil.getImpliedType(inst.type); if (type.tag != TypeTags.INVOKABLE) { throw new BLangCompilerException("Expected BInvokableType, found " + type); @@ -1704,8 +1673,7 @@ void generateFPLoadIns(BIRNonTerminator.FPLoad inst) { } else { mv.visitInsn(ICONST_0); } - this.mv.visitMethodInsn(INVOKESPECIAL, FUNCTION_POINTER, JVM_INIT_METHOD, - FP_INIT, false); + this.mv.visitMethodInsn(INVOKESPECIAL, FUNCTION_POINTER, JVM_INIT_METHOD, FP_INIT, false); PackageID boundMethodPkgId = inst.boundMethodPkgId; String funcPkgName = JvmCodeGenUtil.getPackageName(boundMethodPkgId == null ? inst.pkgId : boundMethodPkgId); @@ -1716,11 +1684,10 @@ void generateFPLoadIns(BIRNonTerminator.FPLoad inst) { this.mv.visitFieldInsn(GETSTATIC, pkgClassName, ANNOTATION_MAP_NAME, GET_MAP_VALUE); // Format of name `$anon$method$delegate$Foo.func$0`. this.mv.visitLdcInsn(name.startsWith(ANON_METHOD_DELEGATE) ? - name.subSequence(ANON_METHOD_DELEGATE.length(), name.lastIndexOf("$")) : - name); + name.subSequence(ANON_METHOD_DELEGATE.length(), name.lastIndexOf("$")) : + name); this.mv.visitMethodInsn(INVOKESTATIC, ANNOTATION_UTILS, "processFPValueAnnotations", PROCESS_FP_ANNOTATIONS, false); - this.storeToVar(inst.lhsOp.variableDcl); } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmObservabilityGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmObservabilityGen.java index 8802fa06e368..11231092bd9e 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmObservabilityGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmObservabilityGen.java @@ -222,8 +222,8 @@ public void instrumentPackage(BIRPackage pkg) { } } // Adding initializing instructions for all compile time known constants - BIRFunction initFunc = pkg.functions.get(0); - BIRBasicBlock constInitBB = initFunc.basicBlocks.get(0); + BIRFunction initFunc = pkg.functions.getFirst(); + BIRBasicBlock constInitBB = initFunc.basicBlocks.getFirst(); for (Map.Entry entry : compileTimeConstants.entrySet()) { BIROperand operand = entry.getValue(); ConstantLoad constLoadIns = new ConstantLoad(COMPILE_TIME_CONST_POS, entry.getKey(), @@ -427,7 +427,7 @@ private void rewriteAsyncInvocations(BIRFunction func, BIRTypeDefinition attache asyncCallIns.calleePkg = currentPkgId; asyncCallIns.isVirtual = attachedTypeDef != null; if (attachedTypeDef != null) { - asyncCallIns.args.add(0, new BIROperand(new BIRVariableDcl(attachedTypeDef.type, selfArgName, + asyncCallIns.args.addFirst(new BIROperand(new BIRVariableDcl(attachedTypeDef.type, selfArgName, VarScope.FUNCTION, VarKind.SELF))); } } @@ -456,7 +456,8 @@ private void rewriteObservableFunctionBody(BIRFunction func, BIRPackage pkg, BIR boolean isRemote, boolean isMainEntryPoint, boolean isWorker) { // Injecting observe start call at the start of the function body { - BIRBasicBlock startBB = func.basicBlocks.get(0); // Every non-abstract function should have function body + BIRBasicBlock startBB = func.basicBlocks.getFirst(); // Every non-abstract function should have function + // body BIRBasicBlock newStartBB = insertBasicBlock(func, 1); swapBasicBlockContent(func, startBB, newStartBB); @@ -539,7 +540,7 @@ private void rewriteObservableFunctionBody(BIRFunction func, BIRPackage pkg, BIR // Add error entry for the entire function { int initialBBCount = func.basicBlocks.size(); - BIRBasicBlock startBB = func.basicBlocks.get(0); + BIRBasicBlock startBB = func.basicBlocks.getFirst(); BIRBasicBlock endBB = func.basicBlocks.get(initialBBCount - 1); BIRBasicBlock observeEndBB = insertBasicBlock(func, initialBBCount); BIRBasicBlock rePanicBB = insertBasicBlock(func, initialBBCount + 1); @@ -581,7 +582,7 @@ private void rewriteObservableFunctionInvocations(BIRFunction func, BIRPackage p String action; if (callIns.isVirtual) { // Every virtual call instruction has self as the first argument - objectTypeOperand = callIns.args.get(0); + objectTypeOperand = callIns.args.getFirst(); if (callIns.name.getValue().contains(".")) { String[] split = callIns.name.getValue().split("\\."); action = split[1]; diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmPackageGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmPackageGen.java index 596f13071919..65643e45ef72 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmPackageGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmPackageGen.java @@ -33,7 +33,6 @@ import org.wso2.ballerinalang.compiler.bir.codegen.internal.AsyncDataCollector; import org.wso2.ballerinalang.compiler.bir.codegen.internal.JavaClass; import org.wso2.ballerinalang.compiler.bir.codegen.methodgen.ConfigMethodGen; -import org.wso2.ballerinalang.compiler.bir.codegen.methodgen.FrameClassGen; import org.wso2.ballerinalang.compiler.bir.codegen.methodgen.InitMethodGen; import org.wso2.ballerinalang.compiler.bir.codegen.methodgen.LambdaGen; import org.wso2.ballerinalang.compiler.bir.codegen.methodgen.MainMethodGen; @@ -93,7 +92,7 @@ import static org.objectweb.asm.Opcodes.NEW; import static org.objectweb.asm.Opcodes.PUTSTATIC; import static org.objectweb.asm.Opcodes.RETURN; -import static org.objectweb.asm.Opcodes.V17; +import static org.objectweb.asm.Opcodes.V21; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.NAME_HASH_COMPARATOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.getModuleLevelClassName; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.isExternFunc; @@ -125,6 +124,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.VALUE_CREATOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmDesugarPhase.addDefaultableBooleanVarsToSignature; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmDesugarPhase.rewriteRecordInits; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_LOCK_STORE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MODULE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VOID_METHOD_DESC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmValueGen.injectDefaultParamInitsToAttachedFuncs; @@ -139,11 +139,9 @@ public class JvmPackageGen { private static final Unifier unifier = new Unifier(); - public final SymbolTable symbolTable; public final PackageCache packageCache; private final MethodGen methodGen; - private final FrameClassGen frameClassGen; private final InitMethodGen initMethodGen; private final ConfigMethodGen configMethodGen; private final Map birFunctionMap; @@ -164,7 +162,6 @@ public class JvmPackageGen { methodGen = new MethodGen(this, types); initMethodGen = new InitMethodGen(symbolTable); configMethodGen = new ConfigMethodGen(); - frameClassGen = new FrameClassGen(); JvmInstructionGen.anyType = symbolTable.anyType; } @@ -234,10 +231,9 @@ private static void generatePackageVariable(BIRGlobalVariableDcl globalVar, Clas fv.visitEnd(); } - private static void generateLockForVariable(ClassWriter cw) { - String lockStoreClass = "L" + LOCK_STORE + ";"; + private static void generateLockStoreVariable(ClassWriter cw) { FieldVisitor fv; - fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, LOCK_STORE_VAR_NAME, lockStoreClass, null, null); + fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, LOCK_STORE_VAR_NAME, GET_LOCK_STORE, null, null); fv.visitEnd(); } @@ -268,11 +264,10 @@ private static void setConstantFields(MethodVisitor mv, BIRPackage birPackage, } private static void setLockStoreField(MethodVisitor mv, String className) { - String lockStoreClass = "L" + LOCK_STORE + ";"; mv.visitTypeInsn(NEW, LOCK_STORE); mv.visitInsn(DUP); mv.visitMethodInsn(INVOKESPECIAL, LOCK_STORE, JVM_INIT_METHOD, VOID_METHOD_DESC, false); - mv.visitFieldInsn(PUTSTATIC, className, LOCK_STORE_VAR_NAME, lockStoreClass); + mv.visitFieldInsn(PUTSTATIC, className, LOCK_STORE_VAR_NAME, GET_LOCK_STORE); } private static void setServiceEPAvailableField(ClassWriter cw, MethodVisitor mv, boolean serviceEPAvailable, @@ -313,19 +308,13 @@ private static void setModuleStatusField(ClassWriter cw, MethodVisitor mv, Strin private static void setCurrentModuleField(ClassWriter cw, MethodVisitor mv, JvmConstantsGen jvmConstantsGen, PackageID packageID, String moduleInitClass) { - FieldVisitor fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, CURRENT_MODULE_VAR_NAME, - GET_MODULE, null, null); + FieldVisitor fv = cw.visitField(ACC_PUBLIC + ACC_STATIC, CURRENT_MODULE_VAR_NAME, GET_MODULE, null, null); fv.visitEnd(); String varName = jvmConstantsGen.getModuleConstantVar(packageID); - mv.visitFieldInsn(GETSTATIC, jvmConstantsGen.getModuleConstantClass(), varName, - GET_MODULE); + mv.visitFieldInsn(GETSTATIC, jvmConstantsGen.getModuleConstantClass(), varName, GET_MODULE); mv.visitFieldInsn(PUTSTATIC, moduleInitClass, CURRENT_MODULE_VAR_NAME, GET_MODULE); } - static String computeLockNameFromString(String varName) { - return "$lock" + varName; - } - public static BIRFunctionWrapper getFunctionWrapper(BIRFunction currentFunc, PackageID packageID, String moduleClass) { BInvokableType functionTypeDesc = currentFunc.type; @@ -335,14 +324,12 @@ public static BIRFunctionWrapper getFunctionWrapper(BIRFunction currentFunc, Pac if (isExternFunc(currentFunc) && Symbols.isFlagOn(retType.flags, Flags.PARAMETERIZED)) { retType = unifier.build(retType); } - String jvmMethodDescription; if (receiver == null) { jvmMethodDescription = JvmCodeGenUtil.getMethodDesc(functionTypeDesc.paramTypes, retType); } else { jvmMethodDescription = JvmCodeGenUtil.getMethodDesc(functionTypeDesc.paramTypes, retType, receiver.type); } - return new BIRFunctionWrapper(packageID, currentFunc, moduleClass, jvmMethodDescription); } @@ -356,12 +343,10 @@ private static BIRFunction findFunction(BIRNode parentNode, String funcName) { // some generated functions will not have bir function return null; } - return func; } private static BIRFunction findFunction(List functions, String funcName) { - for (BIRFunction func : functions) { if (func.name.value.equals(funcName)) { return func; @@ -382,49 +367,46 @@ private void generateModuleClasses(BIRPackage module, JarEntries jarEntries, Str boolean isInitClass = Objects.equals(moduleClass, moduleInitClass); boolean isTestable = testExecuteFunc != null; if (isInitClass) { - cw.visit(V17, ACC_PUBLIC + ACC_SUPER, moduleClass, null, VALUE_CREATOR, null); - JvmCodeGenUtil.generateDefaultConstructor(cw, VALUE_CREATOR); + cw.visit(V21, ACC_PUBLIC + ACC_SUPER, moduleClass, null, VALUE_CREATOR, null); + JvmCodeGenUtil.generateInitClassConstructor(cw, VALUE_CREATOR); jvmTypeGen.generateUserDefinedTypeFields(cw, module.typeDefs); - jvmTypeGen.generateGetAnonTypeMethod(cw, moduleClass); + jvmTypeGen.generateGetTypeMethod(cw, moduleClass); jvmTypeGen.generateValueCreatorMethods(cw, moduleClass); + // populate global variable to class name mapping and generate them for (BIRGlobalVariableDcl globalVar : module.globalVars) { if (globalVar != null) { generatePackageVariable(globalVar, cw); } } - - MainMethodGen mainMethodGen = new MainMethodGen(symbolTable, jvmTypeGen, jvmConstantsGen, - asyncDataCollector, isRemoteMgtEnabled); + MainMethodGen mainMethodGen = new MainMethodGen(symbolTable, jvmTypeGen, + isRemoteMgtEnabled); mainMethodGen.generateMainMethod(mainFunc, cw, module, moduleClass, serviceEPAvailable, isTestable); initMethodGen.generateLambdaForModuleExecuteFunction(cw, moduleClass, jvmCastGen, mainFunc, testExecuteFunc); initMethodGen.generateLambdaForPackageInit(cw, module, moduleClass); - initMethodGen.generateGracefulExitMethod(cw); if (isTestable) { initMethodGen.generateGetTestExecutionState(cw, moduleClass); } - - generateLockForVariable(cw); + generateLockStoreVariable(cw); initMethodGen.generateModuleInitializer(cw, module, moduleInitClass, typesClass); initMethodGen.generateModuleStop(cw, moduleInitClass, asyncDataCollector, jvmConstantsGen); ModuleStopMethodGen stopMethodGen = new ModuleStopMethodGen(jvmTypeGen, jvmConstantsGen); stopMethodGen.generateExecutionStopMethod(cw, moduleInitClass, module, asyncDataCollector, immediateImports); } else { - cw.visit(V17, ACC_PUBLIC + ACC_SUPER, moduleClass, null, OBJECT, null); + cw.visit(V21, ACC_PUBLIC + ACC_SUPER, moduleClass, null, OBJECT, null); JvmCodeGenUtil.generateDefaultConstructor(cw, OBJECT); } cw.visitSource(javaClass.sourceFileName, null); // generate methods for (BIRFunction func : javaClass.functions) { - methodGen.generateMethod(func, cw, module, null, moduleClass, jvmTypeGen, jvmCastGen, - jvmConstantsGen, asyncDataCollector); + methodGen.generateMethod(func, cw, module, null, moduleClass, jvmTypeGen, jvmCastGen, jvmConstantsGen + , asyncDataCollector); } generateStaticInitializer(cw, moduleClass, module, isInitClass, serviceEPAvailable, jvmConstantsGen); cw.visitEnd(); - byte[] bytes = getBytes(cw, module); jarEntries.put(moduleClass + CLASS_FILE_SUFFIX, bytes); }); @@ -458,12 +440,10 @@ private Map generateClassNameLinking(BIRPackage module, Strin // link typedef - object attached native functions linkTypeDefinitions(module, isEntry); - return jvmClassMap; } private void linkGlobalVars(BIRPackage module, String initClass, boolean isEntry) { - if (isEntry) { for (BIRNode.BIRConstant constant : module.constants) { module.globalVars.add(new BIRGlobalVariableDcl(constant.pos, constant.flags, constant.constValue.type, @@ -477,25 +457,19 @@ private void linkGlobalVars(BIRPackage module, String initClass, boolean isEntry globalVarClassMap.put(pkgName + globalVar.name.value, initClass); } } - globalVarClassMap.put(pkgName + LOCK_STORE_VAR_NAME, initClass); } - private void linkTypeDefinitions(BIRPackage module, boolean isEntry) { List typeDefs = module.typeDefs; - for (BIRTypeDefinition optionalTypeDef : typeDefs) { BType bType = JvmCodeGenUtil.getImpliedType(optionalTypeDef.type); - if ((bType.tag != TypeTags.OBJECT || !Symbols.isFlagOn(bType.tsymbol.flags, Flags.CLASS))) { continue; } - List attachedFuncs = optionalTypeDef.attachedFuncs; String typeName = toNameString(bType); for (BIRFunction func : attachedFuncs) { - // link the bir function for lookup String functionName = func.name.value; String lookupKey = typeName + "." + functionName; @@ -527,16 +501,15 @@ private void linkModuleFunctions(BIRPackage birPackage, String initClass, boolea if (functions.isEmpty()) { return; } - int funcSize = functions.size(); int count = 0; // Generate init class. Init function should be the first function of the package, hence check first // function. - BIRFunction initFunc = functions.get(0); + BIRFunction initFunc = functions.getFirst(); String functionName = Utils.encodeFunctionIdentifier(initFunc.name.value); String fileName = initFunc.pos.lineRange().fileName(); JavaClass klass = new JavaClass(fileName, fileName); - klass.functions.add(0, initFunc); + klass.functions.addFirst(initFunc); PackageID packageID = birPackage.packageID; jvmClassMap.put(initClass, klass); String pkgName = JvmCodeGenUtil.getPackageName(packageID); @@ -594,7 +567,7 @@ private void linkModuleFunctions(BIRPackage birPackage, String initClass, boolea javaClass.functions.add(birFunc); } else { klass = new JavaClass(balFileName, cleanedBalFileName); - klass.functions.add(0, birFunc); + klass.functions.addFirst(birFunc); jvmClassMap.put(birModuleClassName, klass); } } @@ -623,7 +596,6 @@ private BIRFunctionWrapper getBirFunctionWrapper(boolean isEntry, PackageID pack } public byte[] getBytes(ClassWriter cw, BIRNode node) { - byte[] result; try { return cw.toByteArray(); @@ -645,7 +617,6 @@ public byte[] getBytes(ClassWriter cw, BIRNode node) { } catch (Throwable e) { throw new BLangCompilerException(e.getMessage(), e); } - return result; } @@ -659,7 +630,6 @@ public BIRFunctionWrapper lookupBIRFunctionWrapper(String lookupKey) { } BType lookupTypeDef(NewInstance objectNewIns) { - if (!objectNewIns.isExternalDef) { return objectNewIns.def.type; } else { @@ -680,7 +650,6 @@ BType lookupTypeDef(NewInstance objectNewIns) { return objectTypeSymbol.type; } } - throw new BLangCompilerException("Reference to unknown type " + objectNewIns.externalPackageId + "/" + objectNewIns.objectName); } @@ -711,8 +680,8 @@ CompiledJarFile generate(BIRPackage module) { String typesClass = getModuleLevelClassName(module.packageID, MODULE_TYPES_CLASS_NAME); Map jvmClassMapping = generateClassNameLinking(module, moduleInitClass, true); - CompiledJarFile compiledJarFile = new CompiledJarFile( - getModuleLevelClassName(module.packageID, MODULE_INIT_CLASS_NAME, ".")); + CompiledJarFile compiledJarFile = new CompiledJarFile(getModuleLevelClassName(module.packageID, + MODULE_INIT_CLASS_NAME, ".")); // use a ByteArrayOutputStream to store class byte values final JarEntries jarEntries = compiledJarFile.jarEntries; // desugar parameter initialization @@ -733,7 +702,7 @@ CompiledJarFile generate(BIRPackage module) { // enrich current package with package initializers initMethodGen.enrichPkgWithInitializers(birFunctionMap, jvmClassMapping, moduleInitClass, module, - immediateImports, serviceEPAvailable, mainFunc, testExecuteFunc); + immediateImports, mainFunc, testExecuteFunc); TypeHashVisitor typeHashVisitor = new TypeHashVisitor(); AsyncDataCollector asyncDataCollector = new AsyncDataCollector(module); JvmConstantsGen jvmConstantsGen = new JvmConstantsGen(module, moduleInitClass, types, typeHashVisitor); @@ -744,8 +713,7 @@ CompiledJarFile generate(BIRPackage module) { typeHashVisitor, jarEntries, symbolTable); // generate the shutdown listener class. - new ShutDownListenerGen().generateShutdownSignalListener(moduleInitClass, jarEntries - ); + new ShutDownListenerGen().generateShutdownSignalListener(moduleInitClass, jarEntries); removeSourceAnnotationTypeDefs(module.typeDefs); // desugar the record init function @@ -757,22 +725,18 @@ CompiledJarFile generate(BIRPackage module) { LambdaGen lambdaGen = new LambdaGen(this, jvmCastGen, module); valueGen.generateValueClasses(jarEntries, jvmConstantsGen, jvmTypeGen, asyncDataCollector); - // generate frame classes - frameClassGen.generateFrameClasses(module, jarEntries); - // generate module classes generateModuleClasses(module, jarEntries, moduleInitClass, typesClass, jvmTypeGen, jvmCastGen, jvmConstantsGen, jvmClassMapping, serviceEPAvailable, mainFunc, testExecuteFunc, asyncDataCollector, immediateImports); List sortedFunctions = new ArrayList<>(module.functions); sortedFunctions.sort(NAME_HASH_COMPARATOR); - jvmMethodsSplitter.generateMethods(jarEntries, jvmCastGen, sortedFunctions, asyncDataCollector); - jvmConstantsGen.generateConstants(jarEntries, asyncDataCollector.getStrandMetadata()); + jvmMethodsSplitter.generateMethods(jarEntries, jvmCastGen, sortedFunctions); + jvmConstantsGen.generateConstants(jarEntries); lambdaGen.generateLambdaClasses(asyncDataCollector, jarEntries); // clear class name mappings clearPackageGenInfo(); - return compiledJarFile; } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmSignatures.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmSignatures.java index 69ece2dae70f..98b674a2367a 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmSignatures.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmSignatures.java @@ -24,6 +24,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ARRAY_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ARRAY_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BAL_ENV; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BAL_RUNTIME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BERROR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BOOLEAN_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BOOLEAN_VALUE; @@ -37,8 +38,8 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_STRING_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_XML_QNAME; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CHANNEL_DETAILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.COLLECTION; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CONFIG_DETAILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.DECIMAL_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.DECIMAL_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.DOUBLE_VALUE; @@ -50,6 +51,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUNCTION; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUNCTION_PARAMETER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUNCTION_POINTER; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUNCTION_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUNCTION_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUTURE_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_TYPE; @@ -63,7 +65,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LINKED_HASH_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LINKED_HASH_SET; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LIST; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LOCK_VALUE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LOCK_STORE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LONG_STREAM; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LONG_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAP; @@ -82,8 +84,6 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OPTION; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.PATH; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.READONLY_TYPE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RECEIVE_FIELD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.REF_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.REG_EXP_ASSERTION; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.REG_EXP_ATOM_QUANTIFIER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.REG_EXP_CAPTURING_GROUP; @@ -102,7 +102,6 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SERVICE_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SET; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STACK; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_CLASS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_METADATA; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STREAM_VALUE; @@ -111,7 +110,6 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRING_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TABLE_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.THROWABLE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CONFIG_DETAILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TRANSACTION_CONTEXT_CLASS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TUPLE_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TYPE; @@ -122,8 +120,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.UNION_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.VALUE_CREATOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.VARIABLE_KEY; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WD_CHANNELS; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_DATA_CHANNEL; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_CHANNEL_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.XML_SEQUENCE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.XML_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.XML_VALUE; @@ -135,33 +132,26 @@ */ public final class JvmSignatures { - public static final String INIT_ERROR_WITH_TYPE = - "(L" + TYPE + ";L" + B_STRING_VALUE + ";L" + BERROR + ";L" + OBJECT + ";)V"; - public static final String INIT_XML_QNAME = - "(L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";)V"; + public static final String ADD_BALLERINA_INFO = "(L" + STRING_VALUE + ";L" + STRING_VALUE + ";Z)V"; public static final String ADD_COLLECTION = "(L" + COLLECTION + ";)Z"; public static final String ADD_MODULE_CONFIG_DATA = "(L" + MAP + ";L" + MODULE + ";[L" + VARIABLE_KEY + ";)V"; + public static final String ADD_SERVICE_LISTENER = "(L" + B_OBJECT + ";L" + B_OBJECT + ";L" + OBJECT + ";)V"; public static final String ADD_SHUTDOWN_HOOK = "(L" + JAVA_THREAD + ";)V"; public static final String ADD_TYPE_ID = "(L" + MODULE + ";L" + STRING_VALUE + ";Z)V"; public static final String ADD_VALUE_CREATOR = "(L" + STRING_VALUE + ";L" + STRING_VALUE + ";L" + STRING_VALUE + ";ZL" + VALUE_CREATOR + ";)V"; - public static final String ANNOTATION_GET_STRAND = - "(L" + FUNCTION_POINTER + ";L" + STRING_VALUE + ";)L" + STRING_VALUE + ";"; - public static final String MAIN_METHOD_SIGNATURE = "([L" + STRING_VALUE + ";)V"; + public static final String ALT_RECEIVE_CALL = "(L" + STRAND_CLASS + ";L" + WORKER_CHANNEL_MAP + ";[L" + + STRING_VALUE + ";)L" + OBJECT + ";"; public static final String ANY_TO_BYTE = "(L" + OBJECT + ";)I"; public static final String ANY_TO_DECIMAL = "(L" + OBJECT + ";)L" + DECIMAL_VALUE + ";"; public static final String ANY_TO_JBOOLEAN = "(L" + OBJECT + ";)Z"; - public static final String ANY_TO_JBYTE = "(L" + OBJECT + ";)B"; - public static final String ANY_TO_JCHAR = "(L" + OBJECT + ";)C"; public static final String ANY_TO_JDOUBLE = "(L" + OBJECT + ";)D"; - public static final String ANY_TO_JFLOAT = "(L" + OBJECT + ";)F"; public static final String ANY_TO_JLONG = "(L" + OBJECT + ";)J"; - public static final String ANY_TO_JSTRING = "(L" + OBJECT + ";)S"; public static final String ARRAY_ADD_BSTRING = "(JL" + JvmConstants.B_STRING_VALUE + ";)V"; public static final String ARRAY_ADD_OBJECT = "(JL" + OBJECT + ";)V"; public static final String BAL_ENV_PARAM = "(L" + BAL_ENV + ";"; - public static final String BOBJECT_CALL = - "(L" + STRAND_CLASS + ";L" + STRING_VALUE + ";[L" + OBJECT + ";)L" + OBJECT + ";"; + public static final String BOBJECT_CALL = "(L" + STRAND_CLASS + ";L" + STRING_VALUE + ";[L" + OBJECT + ";)L" + + OBJECT + ";"; public static final String BOBJECT_GET = "(L" + B_STRING_VALUE + ";)L" + OBJECT + ";"; public static final String BOOLEAN_TO_STRING = "(Z)L" + STRING_VALUE + ";"; public static final String BOOLEAN_VALUE_OF_METHOD = "(Z)L" + BOOLEAN_VALUE + ";"; @@ -176,23 +166,42 @@ public final class JvmSignatures { public static final String COMPARE_DECIMALS = "(L" + DECIMAL_VALUE + ";L" + DECIMAL_VALUE + ";)Z"; public static final String COMPARE_OBJECTS = "(L" + OBJECT + ";L" + OBJECT + ";)Z"; public static final String CONTAINS_KEY = "(L" + STRING_VALUE + ";L" + OBJECT + ";)Z"; - public static final String CREATE_CANCELLED_FUTURE_ERROR = "()L" + ERROR_VALUE + ";"; - public static final String CREATE_ERROR = - "(L" + STRING_VALUE + ";L" + B_STRING_VALUE + ";L" + BERROR + ";L" + OBJECT + ";)L" + BERROR + ";"; + public static final String CREATE_ERROR = "(L" + STRING_VALUE + ";L" + B_STRING_VALUE + ";L" + BERROR + ";L" + + OBJECT + ";)L" + BERROR + ";"; public static final String CREATE_ERROR_FROM_THROWABLE = "(L" + THROWABLE + ";)L" + ERROR_VALUE + ";"; - public static final String CREATE_OBJECT = - "(L" + STRING_VALUE + ";L" + SCHEDULER + ";L" + STRAND_CLASS + ";L" + MAP + ";[L" + OBJECT + ";)L" + - B_OBJECT + ";"; + public static final String CREATE_OBJECT = "(L" + STRING_VALUE + ";L" + STRAND_CLASS + ";[L" + OBJECT + ";)L" + + B_OBJECT + ";"; + public static final String CREATE_RE_ASSERTION = "(L" + B_STRING_VALUE + ";)L" + REG_EXP_ASSERTION + ";"; + public static final String CREATE_RE_ATOM_QUANTIFIER = "(L" + OBJECT + ";L" + REG_EXP_QUANTIFIER + ";)L" + + REG_EXP_ATOM_QUANTIFIER + ";"; + public static final String CREATE_RE_CAPTURING_GROUP = "(L" + B_STRING_VALUE + ";L" + OBJECT + ";L" + + REG_EXP_DISJUNCTION + ";L" + B_STRING_VALUE + ";)L" + REG_EXP_CAPTURING_GROUP + ";"; + public static final String CREATE_RE_CHAR_CLASS = "(L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";L" + + REG_EXP_CHAR_SET + ";L" + B_STRING_VALUE + ";)L" + REG_EXP_CHAR_CLASS + ";"; + public static final String CREATE_RE_CHAR_SET = "(L" + ARRAY_VALUE + ";)L" + REG_EXP_CHAR_SET + ";"; + public static final String CREATE_RE_CHAR_SET_RANGE = "(L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";L" + + B_STRING_VALUE + ";)L" + REG_EXP_CHAR_SET_RANGE + ";"; + public static final String CREATE_RE_DISJUNCTION = "(L" + ARRAY_VALUE + ";)L" + REG_EXP_DISJUNCTION + ";"; + public static final String CREATE_RE_FLAG_EXPR = + "(L" + B_STRING_VALUE + ";L" + REG_EXP_FLAG_ON_OFF + ";L" + B_STRING_VALUE + ";)L" + + REG_EXP_FLAG_EXPR + ";"; + public static final String CREATE_RE_FLAG_ON_OFF = "(L" + B_STRING_VALUE + ";)L" + REG_EXP_FLAG_ON_OFF + ";"; + public static final String CREATE_RE_LITERAL_CHAR = "(L" + B_STRING_VALUE + ";)L" + REG_EXP_CHAR_ESCAPE + ";"; + public static final String CREATE_RE_QUANTIFIER = "(L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";)L" + + REG_EXP_QUANTIFIER + ";"; + public static final String CREATE_RE_SEQUENCE = "(L" + ARRAY_VALUE + ";)L" + REG_EXP_SEQUENCE + ";"; public static final String CREATE_RECORD = "(L" + STRING_VALUE + ";)L" + MAP_VALUE + ";"; - public static final String CREATE_RECORD_WITH_MAP = - "(L" + STRING_VALUE + ";)L" + MAP_VALUE + ";"; + public static final String CREATE_RECORD_WITH_MAP = "(L" + STRING_VALUE + ";)L" + MAP_VALUE + ";"; + public static final String CREATE_REGEXP = "(L" + REG_EXP_DISJUNCTION + ";)L" + REG_EXP_VALUE + ";"; public static final String CREATE_XML_COMMENT = "(L" + B_STRING_VALUE + ";Z)L" + XML_VALUE + ";"; - public static final String CREATE_XML_ELEMENT = - "(L" + B_XML_QNAME + ";L" + B_STRING_VALUE + ";Z)L" + XML_VALUE + ";"; + public static final String CREATE_XML_ELEMENT = "(L" + B_XML_QNAME + ";L" + B_STRING_VALUE + ";Z)L" + XML_VALUE + + ";"; public static final String CREATE_XML_PI = "(L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";Z)L" + XML_VALUE + ";"; public static final String CREATE_XML_TEXT = "(L" + B_STRING_VALUE + ";)L" + XML_VALUE + ";"; public static final String CRETAE_XML_SEQUENCE = "()L" + XML_SEQUENCE + ";"; - public static final String CURRENT_MODULE_STOP = "(L" + RUNTIME_REGISTRY_CLASS + ";)V"; + public static final String CURRENT_MODULE_INIT = "(L" + BAL_RUNTIME + ";)L" + OBJECT + ";"; + public static final String CURRENT_MODULE_STOP = "(L" + BAL_RUNTIME + ";)V"; public static final String DECIMAL_NEGATE = "()L" + DECIMAL_VALUE + ";"; public static final String DECIMAL_TO_HANDLE = "(L" + OBJECT + ";)L" + HANDLE_VALUE + ";"; public static final String DECIMAL_VALUE_OF_BOOLEAN = "(B)L" + DECIMAL_VALUE + ";"; @@ -202,115 +211,110 @@ public final class JvmSignatures { public static final String DECIMAL_VALUE_OF_INT = "(I)L" + DECIMAL_VALUE + ";"; public static final String DECIMAL_VALUE_OF_LONG = "(J)L" + DECIMAL_VALUE + ";"; public static final String DECIMAL_VALUE_OF_SHORT = "(S)L" + DECIMAL_VALUE + ";"; - public static final String INT_TO_STRING = "(I)L" + STRING_VALUE + ";"; public static final String DOUBLE_TO_STRING = "(D)L" + STRING_VALUE + ";"; public static final String DOUBLE_VALUE_OF_METHOD = "(D)L" + DOUBLE_VALUE + ";"; public static final String ERROR_CALL = "(L" + BAL_ENV + ";L" + ERROR_VALUE + ";)V"; - public static final String ERROR_INIT = "(L" + TYPE + ";L" + B_STRING_VALUE + ";L" + BERROR + ";L" + OBJECT + ";)V"; + public static final String ERROR_INIT = "(L" + TYPE + ";L" + B_STRING_VALUE + ";L" + BERROR + ";L" + B_MAP + ";)V"; public static final String FP_INIT = "(L" + FUNCTION + ";L" + TYPE + ";L" + STRING_VALUE + ";Z)V"; - public static final String FUNCTION_CALL = - "(L" + STRAND_CLASS + ";L" + STRING_VALUE + ";[L" + OBJECT + ";)L" + OBJECT + ";"; public static final String FROM_STRING = "(L" + STRING_VALUE + ";)L" + B_STRING_VALUE + ";"; - public static final String GET_ANNOTATION_VALUE = - "(L" + TYPEDESC_VALUE + ";L" + B_STRING_VALUE + ";)L" + OBJECT + ";"; + public static final String FUNCTION_CALL = "(L" + STRAND_CLASS + ";L" + STRING_VALUE + ";[L" + OBJECT + ";)L" + + OBJECT + ";"; + public static final String GET_ANNOTATION_VALUE = "(L" + TYPEDESC_VALUE + ";L" + B_STRING_VALUE + ";)L" + OBJECT + + ";"; public static final String GET_ANON_TYPE = "(IL" + STRING_VALUE + ";)L" + TYPE + ";"; public static final String GET_ARRAY_TYPE_IMPL = "L" + ARRAY_TYPE_IMPL + ";"; public static final String GET_ARRAY_VALUE = "L" + ARRAY_VALUE + ";"; public static final String GET_ATTRAIBUTE_MAP = "()L" + MAP_VALUE + ";"; + public static final String GET_BAL_RUNTIME = "L" + BAL_RUNTIME + ";"; public static final String GET_BDECIMAL = "L" + DECIMAL_VALUE + ";"; - public static final String GET_BERROR = "L" + BERROR + ";"; public static final String GET_BOBJECT = "L" + B_OBJECT + ";"; public static final String GET_BSTRING = "L" + B_STRING_VALUE + ";"; - public static final String GET_REGEXP = "L" + REG_EXP_VALUE + ";"; public static final String GET_BSTRING_FOR_ARRAY_INDEX = "(J)L" + JvmConstants.B_STRING_VALUE + ";"; + public static final String GET_CONFIG_DETAILS = "()L" + CONFIG_DETAILS + ";"; public static final String GET_ERROR_TYPE = "L" + ERROR_TYPE + ";"; + public static final String GET_ERROR_TYPE_IMPL = "L" + ERROR_TYPE_IMPL + ";"; public static final String GET_ERROR_VALUE = "L" + ERROR_VALUE + ";"; - public static final String GET_FUNCTION = "()L" + FUNCTION + ";"; + public static final String GET_FUNCTION = "L" + FUNCTION + ";"; public static final String GET_FUNCTION_POINTER = "L" + FUNCTION_POINTER + ";"; + public static final String GET_FUNCTION_TYPE = "L" + FUNCTION_TYPE + ";"; + public static final String GET_FUNCTION_TYPE_FOR_STRING = "(L" + STRING_VALUE + ";)" + GET_FUNCTION_TYPE; public static final String GET_FUTURE_VALUE = "L" + FUTURE_VALUE + ";"; public static final String GET_HANDLE_VALUE = "L" + HANDLE_VALUE + ";"; + public static final String GET_JBOOLEAN_TYPE = "Z"; public static final String GET_JSTRING = "()L" + STRING_VALUE + ";"; - public static final String GET_STRING_ARRAY = "()[L" + STRING_VALUE + ";"; - public static final String GET_RUNTIME_REGISTRY = "L" + RUNTIME_REGISTRY_CLASS + ";"; - public static final String GET_RUNTIME_REGISTRY_CLASS = "()L" + RUNTIME_REGISTRY_CLASS + ";"; - public static final String GET_LOCK_FROM_MAP = "(L" + STRING_VALUE + ";)L" + LOCK_VALUE + ";"; - public static final String GET_LOCK_MAP = "(L" + STRING_VALUE + ";)L" + LOCK_VALUE + ";"; + public static final String GET_LOCK_STORE = "L" + LOCK_STORE + ";"; public static final String GET_MAIN_ARGS = "()[L" + OBJECT + ";"; public static final String GET_MAP_ARRAY = "[L" + MAP_VALUE + ";"; public static final String GET_MAP_VALUE = "L" + MAP_VALUE + ";"; public static final String GET_MODULE = "L" + MODULE + ";"; public static final String GET_OBJECT = "L" + OBJECT + ";"; public static final String GET_OBJECT_FOR_STRING = "(L" + STRING_VALUE + ";)L" + OBJECT + ";"; + public static final String GET_PATH = "[L" + PATH + ";"; + public static final String GET_REGEXP = "L" + REG_EXP_VALUE + ";"; public static final String GET_RUNTIME = "()L" + JvmConstants.JAVA_RUNTIME + ";"; public static final String GET_RUNTIME_ERROR = "L" + ERROR_CODES + ";"; - public static final String GET_RUNTIME_EXCEPTION = - "(L" + STRING_VALUE + ";L" + ERROR_CODES + ";[L" + OBJECT + ";)L" + ERROR_VALUE + ";"; + public static final String GET_RUNTIME_EXCEPTION = "(L" + STRING_VALUE + ";L" + ERROR_CODES + ";[L" + OBJECT + + ";)L" + ERROR_VALUE + ";"; + public static final String GET_RUNTIME_REGISTRY = "L" + RUNTIME_REGISTRY_CLASS + ";"; public static final String GET_SCHEDULER = "L" + SCHEDULER + ";"; public static final String GET_STRAND = "L" + STRAND_CLASS + ";"; public static final String GET_STRAND_METADATA = "L" + STRAND_METADATA + ";"; public static final String GET_STREAM_VALUE = "L" + STREAM_VALUE + ";"; public static final String GET_STRING = "L" + STRING_VALUE + ";"; + public static final String GET_STRING_ARRAY = "()[L" + STRING_VALUE + ";"; public static final String GET_STRING_AT = "(L" + B_STRING_VALUE + ";J)L" + B_STRING_VALUE + ";"; public static final String GET_STRING_FROM_ARRAY = "(J)L" + OBJECT + ";"; - public static final String GET_PATH = "[L" + PATH + ";"; public static final String GET_TABLE_VALUE = "L" + TABLE_VALUE + ";"; - public static final String GET_JBOOLEAN_TYPE = "Z"; - public static final String GET_THROWABLE = "L" + THROWABLE + ";"; + public static final String GET_TEST_CONFIG_PATH = "(L" + MODULE + ";L" + STRING_VALUE + ";L" + STRING_VALUE + + ";)L" + CONFIG_DETAILS + ";"; public static final String GET_TUPLE_TYPE_IMPL = "L" + TUPLE_TYPE_IMPL + ";"; public static final String GET_TYPE = "L" + TYPE + ";"; + public static final String GET_TYPE_REF_TYPE_IMPL = "L" + TYPE_REF_TYPE_IMPL + ";"; public static final String GET_TYPEDESC = "L" + TYPEDESC_VALUE + ";"; public static final String GET_TYPEDESC_OF_OBJECT = "(L" + OBJECT + ";)L" + TYPEDESC_VALUE + ";"; public static final String GET_UNION_TYPE_IMPL = "L" + UNION_TYPE_IMPL + ";"; - public static final String GET_ERROR_TYPE_IMPL = "L" + ERROR_TYPE_IMPL + ";"; - public static final String GET_TYPE_REF_TYPE_IMPL = "L" + TYPE_REF_TYPE_IMPL + ";"; - public static final String GET_WD_CHANNELS = "L" + WD_CHANNELS + ";"; - public static final String GET_WORKER_DATA_CHANNEL = "(L" + STRING_VALUE + ";)L" + WORKER_DATA_CHANNEL + ";"; - public static final String REMOVE_WORKER_DATA_CHANNEL = "(L" + STRAND_CLASS + ";L" + STRING_VALUE + ";)V"; + public static final String GET_WORKER_CHANNEL_MAP = "L" + WORKER_CHANNEL_MAP + ";"; public static final String GET_XML = "L" + XML_VALUE + ";"; - public static final String HANDLE_CHANNEL_ERROR = "([L" + CHANNEL_DETAILS + ";L" + ERROR_VALUE + ";)V"; - public static final String HANDLE_ERROR_RETURN = "(L" + OBJECT + ";)V"; - public static final String HANDLE_FLUSH = "([L" + CHANNEL_DETAILS + ";)L" + ERROR_VALUE + ";"; + public static final String HANDLE_FLUSH = "(L" + STRAND_CLASS + ";L" + WORKER_CHANNEL_MAP + ";[L" + + STRING_VALUE + ";)" + "L" + OBJECT + ";"; + public static final String HANDLE_FUTURE = "(L" + FUTURE_VALUE + ";)V"; + public static final String HANDLE_FUTURE_AND_RETURN_IS_PANIC = "(L" + FUTURE_VALUE + ";)Z"; public static final String HANDLE_MAP_STORE = "(L" + MAP_VALUE + ";L" + B_STRING_VALUE + ";L" + OBJECT + ";)V"; - public static final String HANDLE_STOP_PANIC = "(L" + THROWABLE + ";)V"; + public static final String HANDLE_OBJECT_LONG_ARGS = "(" + GET_HANDLE_VALUE + GET_OBJECT + "J)V"; public static final String HANDLE_TABLE_STORE = "(L" + TABLE_VALUE + ";L" + OBJECT + ";L" + OBJECT + ";)V"; public static final String HANDLE_THROWABLE = "(L" + JvmConstants.THROWABLE + ";)V"; - public static final String HANDLE_WAIT_ANY = "(L" + LIST + ";)L" + STRAND_CLASS + "$WaitResult;"; - public static final String HANDLE_WAIT_MULTIPLE = "(L" + MAP + ";L" + MAP_VALUE + ";)V"; - public static final String HANDLE_WORKER_ERROR = - "(L" + REF_VALUE + ";L" + STRAND_CLASS + ";[L" + CHANNEL_DETAILS + ";)V"; - public static final String HANDLE_OBJECT_LONG_ARGS = "(" + GET_HANDLE_VALUE + GET_OBJECT + "J)V"; + public static final String HANDLE_WAIT = "(L" + STRAND_CLASS + ";L" + FUTURE_VALUE + ";)L" + OBJECT + ";"; + public static final String HANDLE_WAIT_ANY = "(L" + STRAND_CLASS + ";L" + LIST + ";)L" + OBJECT + ";"; + public static final String HANDLE_WAIT_MULTIPLE = "(L" + STRAND_CLASS + ";L" + MAP + ";L" + MAP_VALUE + ";)V"; + public static final String INIT_ANYDATA_ARRAY = "([L" + OBJECT + ";L" + ARRAY_TYPE + ";)V"; public static final String INIT_ARRAY = "(L" + TYPE + ";[L" + B_LIST_INITIAL_VALUE_ENTRY + ";)V"; public static final String INIT_ARRAY_TYPE_IMPL = "(L" + TYPE + ";IZI)V"; - public static final String INIT_ARRAY_WITH_INITIAL_VALUES = - "(L" + TYPE + ";[L" + B_LIST_INITIAL_VALUE_ENTRY + ";L" + TYPEDESC_VALUE + ";)V"; - public static final String INIT_BAL_ENV = "(L" + STRAND_CLASS + ";L" + MODULE + ";)V"; - public static final String INIT_BAL_ENV_WITH_FUNC_NAME = "(L" + STRAND_CLASS + ";L" + MODULE + ";L" + STRING_VALUE - + ";[L" + FUNCTION_PARAMETER + ";)V"; - public static final String INIT_CHANNEL_DETAILS = "(L" + STRING_VALUE + ";ZZ)V"; - public static final String INIT_RECEIVE_FIELD = "(L" + STRING_VALUE + ";L" + STRING_VALUE + ";)V"; + public static final String INIT_ARRAY_WITH_INITIAL_VALUES = "(L" + TYPE + ";[L" + B_LIST_INITIAL_VALUE_ENTRY + + ";L" + TYPEDESC_VALUE + ";)V"; + public static final String INIT_BAL_ENV = + "(L" + STRAND_CLASS + ";L" + MODULE + ";L" + STRING_VALUE + ";[L" + FUNCTION_PARAMETER + ";)V"; public static final String INIT_CLI_SPEC = "(L" + OPTION + ";[L" + OPERAND + ";[L" + STRING_VALUE + ";)V"; - public static final String INIT_CONFIG = - "(L" + MAP + ";" + "[L" + STRING_VALUE + ";[L" + PATH + ";L" + STRING_VALUE + ";)V"; - public static final String INIT_CONFIGURABLES = - "(L" + MODULE + ";L" + MAP + ";[L" + STRING_VALUE + ";[L" + PATH + ";L" + STRING_VALUE + ";)V"; - public static final String INIT_TEST_ARGS = "([L" + STRING_VALUE + ";)V"; + public static final String INIT_CLASS_CONSTRUCTOR = "(L" + BAL_RUNTIME + ";)V"; + public static final String INIT_CONFIG = "(L" + MAP + ";" + "[L" + STRING_VALUE + ";[L" + PATH + ";L" + + STRING_VALUE + ";L" + BAL_RUNTIME + ";)V"; + public static final String INIT_CONFIGURABLE = "(L" + MODULE + ";L" + MAP + ";[L" + STRING_VALUE + ";[L" + PATH + + ";L" + STRING_VALUE + ";)V"; public static final String INIT_ERROR = "(L" + B_STRING_VALUE + ";)V"; public static final String INIT_ERROR_TYPE_IMPL = "(L" + STRING_VALUE + ";L" + MODULE + ";)V"; + public static final String INIT_ERROR_WITH_TYPE = "(L" + TYPE + ";L" + B_STRING_VALUE + ";L" + BERROR + ";L" + + B_MAP + ";)V"; public static final String INIT_FIELD_IMPL = "(L" + TYPE + ";L" + STRING_VALUE + ";J)V"; public static final String INIT_FINITE_TYPE_IMPL = "(L" + STRING_VALUE + ";L" + STRING_VALUE + ";L" + SET + ";I)V"; public static final String INIT_FUNCTION_PARAM = "(L" + STRING_VALUE + ";ZL" + STRING_VALUE + ";L" + TYPE + ";)V"; public static final String INIT_FUNCTION_TYPE_IMPL = "(L" + MODULE + ";J)V"; - public static final String INIT_FUNCTION_TYPE_IMPL_WITH_PARAMS = "(L" + MODULE + ";[L" + FUNCTION_PARAMETER + ";" + - "L" + TYPE + ";L" + TYPE + ";" + "JL" + STRING_VALUE + ";)V"; - public static final String INIT_INTERSECTION_TYPE_WITH_REFERENCE_TYPE = - "(L" + STRING_VALUE + ";L" + MODULE + ";[L" + TYPE + ";L" + INTERSECTABLE_REFERENCE_TYPE + ";IZ)V"; - public static final String INIT_INTERSECTION_TYPE_WITH_TYPE = - "(L" + STRING_VALUE + ";L" + MODULE + ";[L" + TYPE + ";L" + TYPE + ";IZ)V"; + public static final String INIT_FUNCTION_TYPE_IMPL_WITH_PARAMS = "(L" + MODULE + ";[L" + FUNCTION_PARAMETER + + ";" + "L" + TYPE + ";L" + TYPE + ";" + "JL" + STRING_VALUE + ";)V"; + public static final String INIT_INTERSECTION_TYPE_WITH_REFERENCE_TYPE = "(L" + STRING_VALUE + ";L" + MODULE + + ";[L" + TYPE + ";L" + INTERSECTABLE_REFERENCE_TYPE + ";IZ)V"; + public static final String INIT_INTERSECTION_TYPE_WITH_TYPE = "(L" + STRING_VALUE + ";L" + MODULE + ";[L" + TYPE + + ";L" + TYPE + ";IZ)V"; public static final String INIT_LIST_INITIAL_EXPRESSION_ENTRY = "(L" + OBJECT + ";)V"; public static final String INIT_LIST_INITIAL_SPREAD_ENTRY = "(L" + B_ARRAY + ";)V"; - public static final String INIT_RUNTIME_REGISTRY = "(L" + RUNTIME_REGISTRY_CLASS + ";)V"; - public static final String MODULE_INITIALIZER = "(L" + STRAND_CLASS + ";)L" + OBJECT + ";"; - public static final String MODULE_STOP = "(L" + SCHEDULER + ";L" + FUTURE_VALUE + ";)V"; public static final String INIT_MAPPING_INITIAL_SPREAD_FIELD_ENTRY = "(L" + B_MAP + ";)V"; public static final String INIT_MODULE = "(L" + STRING_VALUE + ";L" + STRING_VALUE + ";L" + STRING_VALUE + ";Z)V"; public static final String INIT_NON_BMP_STRING_VALUE = "(L" + STRING_VALUE + ";[I)V"; @@ -318,40 +322,37 @@ public final class JvmSignatures { public static final String INIT_OPERAND = "(ZL" + STRING_VALUE + ";L" + TYPE + ";)V"; public static final String INIT_OPTION = "(L" + TYPE + ";I)V"; public static final String INIT_PARAMETERIZED_TYPE_IMPL = "(L" + TYPE + ";I)V"; + public static final String INIT_RUNTIME = "(L" + MODULE + ";)V"; + public static final String INIT_SIGNAL_LISTENER = "(L" + BAL_RUNTIME + ";)V"; public static final String INIT_STRAND = - "(L" + STRING_VALUE + ";L" + STRAND_METADATA + ";L" + SCHEDULER + ";L" + STRAND_CLASS + ";L" + MAP + ";L" + "(L" + SCHEDULER + ";L" + STRAND_CLASS + ";ZL" + STRING_VALUE + ";L" + STRING_VALUE + ";L" + MAP + ";L" + TRANSACTION_CONTEXT_CLASS + ";)V"; - public static final String INIT_STRAND_METADATA = - "(L" + STRING_VALUE + ";L" + STRING_VALUE + ";L" + STRING_VALUE + ";L" + STRING_VALUE + ";L" + - STRING_VALUE + ";)V"; public static final String INIT_STREAM_TYPE_IMPL = "(L" + TYPE + ";L" + TYPE + ";)V"; public static final String INIT_TABLE_TYPE_IMPL = "(L" + TYPE + ";L" + TYPE + ";Z)V"; public static final String INIT_TABLE_TYPE_WITH_FIELD_NAME_LIST = "(L" + TYPE + ";[L" + STRING_VALUE + ";Z)V"; - public static final String INIT_TABLE_VALUE_IMPL = "(L" + TYPE + ";L" + ARRAY_VALUE + ";L" + ARRAY_VALUE + - ";)V"; + public static final String INIT_TABLE_VALUE_IMPL = "(L" + TYPE + ";L" + ARRAY_VALUE + ";L" + ARRAY_VALUE + ";)V"; + public static final String INIT_TEST_ARGS = "([L" + STRING_VALUE + ";)V"; public static final String INIT_TUPLE_TYPE_IMPL = "(L" + STRING_VALUE + ";L" + MODULE + ";IZZ)V"; + public static final String INIT_TYPE_REF = "(L" + STRING_VALUE + ";L" + MODULE + ";IZ)V"; public static final String INIT_TYPEDESC = "(L" + TYPEDESC_VALUE + ";)V"; public static final String INIT_UNION_TYPE_IMPL = "(L" + STRING_VALUE + ";L" + MODULE + ";IZJ)V"; public static final String INIT_WITH_BOOLEAN = "(L" + TYPE + ";Z)V"; public static final String INIT_WITH_STRING = "(L" + STRING_VALUE + ";)V"; + public static final String INIT_XML_QNAME = "(L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + + ";)V"; public static final String INITIAL_METHOD_DESC = "(L" + STRAND_CLASS + ";"; - public static final String INIT_TYPE_REF = "(L" + STRING_VALUE + ";L" + MODULE + ";IZ)V"; - public static final String INSTANTIATE_WITH_INITIAL_VALUES = "(L" + STRAND_CLASS + ";[L" + - B_INITIAL_VALUE_ENTRY + ";)L" + OBJECT + ";"; public static final String INSTANTIATE = "(L" + STRAND_CLASS + ";)L" + OBJECT + ";"; + public static final String INSTANTIATE_WITH_INITIAL_VALUES = "(L" + STRAND_CLASS + ";[L" + B_INITIAL_VALUE_ENTRY + + ";)L" + OBJECT + ";"; public static final String INT_VALUE_OF_METHOD = "(I)L" + INT_VALUE + ";"; - public static final String INTI_VARIABLE_KEY = - "(L" + MODULE + ";L" + STRING_VALUE + ";L" + TYPE + ";L" + STRING_VALUE + ";Z)V"; - public static final String IS_CONCURRENT = "(L" + FUNCTION_POINTER + ";)Z"; + public static final String INTI_VARIABLE_KEY = "(L" + MODULE + ";L" + STRING_VALUE + ";L" + TYPE + ";L" + + STRING_VALUE + ";Z)V"; public static final String JSON_GET_ELEMENT = "(L" + OBJECT + ";L" + B_STRING_VALUE + ";)L" + OBJECT + ";"; public static final String JSON_SET_ELEMENT = "(L" + OBJECT + ";L" + STRING_VALUE + ";L" + OBJECT + ";)V"; - public static final String LAMBDA_STOP_DYNAMIC = "([L" + OBJECT + ";)L" + OBJECT + ";"; public static final String LINKED_HASH_SET_OP = "(L" + LINKED_HASH_SET + ";)V"; - public static final String LOAD_JOBJECT_TYPE = "L" + OBJECT + ";"; public static final String LOAD_ANY_TYPE = "L" + ANY_TYPE + ";"; public static final String LOAD_ANYDATA_TYPE = "L" + ANYDATA_TYPE + ";"; public static final String LOAD_ARRAY_TYPE = "L" + ARRAY_TYPE + ";"; - public static final String INIT_ANYDATA_ARRAY = "([L" + OBJECT + ";L" + ARRAY_TYPE + ";)V"; public static final String LOAD_BOOLEAN_TYPE = "L" + BOOLEAN_TYPE + ";"; public static final String LOAD_BYTE_TYPE = "L" + BYTE_TYPE + ";"; public static final String LOAD_DECIMAL_TYPE = "L" + DECIMAL_TYPE + ";"; @@ -368,60 +369,66 @@ public final class JvmSignatures { public static final String LOAD_TYPE = "L" + TYPE + ";"; public static final String LOAD_UNION_TYPE = "L" + UNION_TYPE + ";"; public static final String LOAD_XML_TYPE = "L" + XML_TYPE + ";"; - public static final String LOCK = "(L" + STRAND_CLASS + ";)Z"; public static final String LONG_STREAM_RANGE_CLOSED = "(JJ)L" + LONG_STREAM + ";"; public static final String LONG_TO_STRING = "(J)L" + STRING_VALUE + ";"; public static final String LONG_VALUE_OF = "(J)L" + LONG_VALUE + ";"; + public static final String MAIN_METHOD_SIGNATURE = "([L" + STRING_VALUE + ";)V"; public static final String MAP_PUT = "(L" + OBJECT + ";L" + OBJECT + ";)L" + OBJECT + ";"; public static final String MAP_VALUES = "()L" + COLLECTION + ";"; public static final String MAP_VALUES_WITH_COLLECTION = "()L" + COLLECTION + ";"; public static final String METHOD_STRING_PARAM = "(L" + JvmConstants.STRING_VALUE + ";)V"; public static final String METHOD_TYPE_IMPL_ARRAY_PARAM = "([L" + METHOD_TYPE_IMPL + ";)V"; - public static final String METHOD_TYPE_IMPL_INIT = - "(L" + STRING_VALUE + ";L" + MODULE + ";L" + OBJECT_TYPE_IMPL + ";L" + FUNCTION_TYPE_IMPL + ";J)V"; + public static final String METHOD_TYPE_IMPL_INIT = "(L" + STRING_VALUE + ";L" + MODULE + ";L" + OBJECT_TYPE_IMPL + + ";L" + FUNCTION_TYPE_IMPL + ";J)V"; public static final String METHOD_TYPE_IMPL_PARAM = "(L" + METHOD_TYPE_IMPL + ";)V"; + public static final String MODULE_INITIALIZER = "(L" + STRAND_CLASS + ";)L" + OBJECT + ";"; public static final String MODULE_START = "(L" + STRAND_CLASS + ";)L" + OBJECT + ";"; + public static final String MODULE_STOP = "(L" + SCHEDULER + ";L" + FUTURE_VALUE + ";)V"; + public static final String MULTIPLE_RECEIVE_CALL = "(L" + STRAND_CLASS + ";L" + WORKER_CHANNEL_MAP + ";L" + MAP + + ";L" + TYPE + ";)L" + B_MAP + ";"; public static final String OBJECT_SET = "(L" + STRING_VALUE + ";L" + B_STRING_VALUE + ";L" + OBJECT + ";)V"; public static final String OBJECT_TYPE_DUPLICATE = "()L" + OBJECT_TYPE_IMPL + ";"; public static final String OBJECT_TYPE_IMPL_INIT = "(L" + TYPE + ";)V"; - public static final String PANIC_IF_IN_LOCK = "(L" + STRAND_CLASS + ";)V"; - public static final String PASS_B_STRING_RETURN_OBJECT = "(L" + B_STRING_VALUE + ";)L" + OBJECT + ";"; - public static final String PASS_B_STRING_RETURN_LONG = "(L" + B_STRING_VALUE + ";)L" + LONG_VALUE + ";"; - public static final String PASS_B_STRING_RETURN_UNBOXED_LONG = "(L" + B_STRING_VALUE + ";)J"; - public static final String PASS_B_STRING_RETURN_DOUBLE = "(L" + B_STRING_VALUE + ";)L" + DOUBLE_VALUE + ";"; - public static final String PASS_B_STRING_RETURN_UNBOXED_DOUBLE = "(L" + B_STRING_VALUE + ";)D"; public static final String PASS_B_STRING_RETURN_B_STRING = "(L" + B_STRING_VALUE + ";)L" + B_STRING_VALUE + ";"; public static final String PASS_B_STRING_RETURN_BOOLEAN = "(L" + B_STRING_VALUE + ";)L" + BOOLEAN_VALUE + ";"; + public static final String PASS_B_STRING_RETURN_DOUBLE = "(L" + B_STRING_VALUE + ";)L" + DOUBLE_VALUE + ";"; + public static final String PASS_B_STRING_RETURN_LONG = "(L" + B_STRING_VALUE + ";)L" + LONG_VALUE + ";"; + public static final String PASS_B_STRING_RETURN_OBJECT = "(L" + B_STRING_VALUE + ";)L" + OBJECT + ";"; public static final String PASS_B_STRING_RETURN_UNBOXED_BOOLEAN = "(L" + B_STRING_VALUE + ";)Z"; + public static final String PASS_B_STRING_RETURN_UNBOXED_DOUBLE = "(L" + B_STRING_VALUE + ";)D"; + public static final String PASS_B_STRING_RETURN_UNBOXED_LONG = "(L" + B_STRING_VALUE + ";)J"; + public static final String PASS_OBJECT_ARRAY_RETURN_OBJECT = "([L" + OBJECT + ";)L" + OBJECT + ";"; public static final String PASS_OBJECT_RETURN_OBJECT = "(L" + OBJECT + ";)L" + OBJECT + ";"; public static final String PASS_OBJECT_RETURN_SAME_TYPE = "(L" + OBJECT + ";)TV;"; + public static final String PASS_STRAND = "(L" + STRAND_CLASS + ";)V"; + public static final String PASS_STRAND_AND_LOCK_NAME = "(L" + STRAND_CLASS + ";L" + STRING_VALUE + ";)V"; public static final String POPULATE_ATTACHED_FUNCTION = "([L" + METHOD_TYPE_IMPL + ";)V"; - public static final String POPULATE_CONFIG_DATA = "()[L" + VARIABLE_KEY + ";"; + public static final String POPULATE_CONFIG_DATA = "(L" + BAL_RUNTIME + ";)[L" + VARIABLE_KEY + ";"; public static final String POPULATE_INITIAL_VALUES = "([L" + B_MAPPING_INITIAL_VALUE_ENTRY + ";)V"; public static final String PROCESS_ANNOTATIONS = "(L" + MAP_VALUE + ";L" + TYPE + ";)V"; public static final String PROCESS_FP_ANNOTATIONS = "(L" + FUNCTION_POINTER + ";L" + MAP_VALUE + ";L" + STRING_VALUE + ";)V"; public static final String PROCESS_OBJ_CTR_ANNOTATIONS = "(L" + OBJECT_TYPE_IMPL + ";L" + MAP_VALUE + ";L" + STRAND_CLASS + ";)V"; - public static final String STACK_FRAMES = "L" + STACK + ";"; + public static final String RECEIVE_DATA = + "(L" + STRAND_CLASS + ";L" + WORKER_CHANNEL_MAP + ";L" + STRING_VALUE + ";" + ")L" + OBJECT + ";"; public static final String RECORD_GET = "(L" + STRING_VALUE + ";L" + OBJECT + ";)L" + OBJECT + ";"; public static final String RECORD_GET_KEYS = "()[L" + OBJECT + ";"; public static final String RECORD_PUT = "(L" + STRING_VALUE + ";L" + OBJECT + ";L" + OBJECT + ";)L" + OBJECT + ";"; public static final String RECORD_REMOVE = "(L" + STRING_VALUE + ";L" + OBJECT + ";)L" + OBJECT + ";"; public static final String RECORD_SET = "()L" + SET + ";"; public static final String RECORD_SET_MAP_ENTRY = "()L" + SET + ";>;"; - public static final String RECORD_TYPE_IMPL_INIT = - "(L" + STRING_VALUE + ";L" + STRING_VALUE + ";L" + MODULE + ";JZI)V"; + public static final String RECORD_TYPE_IMPL_INIT = "(L" + STRING_VALUE + ";L" + STRING_VALUE + ";L" + MODULE + + ";JZI)V"; public static final String RECORD_VALUE_CLASS = "L" + MAP_VALUE_IMPL + ";L" + MAP_VALUE + ";"; public static final String RESOURCE_METHOD_TYPE_ARRAY_PARAM = "([L" + RESOURCE_METHOD_TYPE + ";)V"; public static final String RESOURCE_METHOD_TYPE_IMPL_INIT = - "(L" + STRING_VALUE + ";L" + MODULE + ";L" + OBJECT_TYPE_IMPL + ";L" + FUNCTION_TYPE_IMPL + ";[L" + - TYPE + ";JL" + STRING_VALUE + ";[L" + STRING_VALUE + ";)V"; + "(L" + STRING_VALUE + ";L" + MODULE + ";L" + OBJECT_TYPE_IMPL + ";L" + FUNCTION_TYPE_IMPL + ";[L" + TYPE + + ";JL" + STRING_VALUE + ";[L" + STRING_VALUE + ";)V"; public static final String RETURN_ARRAY_VALUE = ")L" + ARRAY_VALUE + ";"; public static final String RETURN_B_OBJECT = ")L" + B_OBJECT + ";"; public static final String RETURN_B_STRING_VALUE = ")L" + B_STRING_VALUE + ";"; - public static final String RETURN_REGEX_VALUE = ")L" + REG_EXP_VALUE + ";"; public static final String RETURN_DECIMAL_VALUE = ")L" + DECIMAL_VALUE + ";"; public static final String RETURN_ERROR_VALUE = ")L" + ERROR_VALUE + ";"; public static final String RETURN_FUNCTION_POINTER = ")L" + FUNCTION_POINTER + ";"; @@ -430,51 +437,51 @@ public final class JvmSignatures { public static final String RETURN_JOBJECT = ")L" + OBJECT + ";"; public static final String RETURN_MAP_VALUE = ")L" + MAP_VALUE + ";"; public static final String RETURN_OBJECT = "()L" + OBJECT + ";"; + public static final String RETURN_REGEX_VALUE = ")L" + REG_EXP_VALUE + ";"; public static final String RETURN_STREAM_VALUE = ")L" + STREAM_VALUE + ";"; public static final String RETURN_TABLE_VALUE = ")L" + TABLE_VALUE + ";"; public static final String RETURN_TYPEDESC_VALUE = ")L" + TYPEDESC_VALUE + ";"; public static final String RETURN_XML_VALUE = ")L" + XML_VALUE + ";"; - public static final String SCHEDULE_LOCAL = "([L" + OBJECT + ";L" + B_FUNCTION_POINTER + ";L" + - STRAND_CLASS + ";" + "L" + TYPE + ";L" + STRING_VALUE + ";L" + STRAND_METADATA + ";)L" + FUTURE_VALUE + ";"; - public static final String SCHEDULE_FUNCTION = - "([L" + OBJECT + ";L" + B_FUNCTION_POINTER + ";L" + STRAND_CLASS + ";L" + TYPE + ";L" + - STRING_VALUE + ";" + "L" + STRAND_METADATA + ";)L" + FUTURE_VALUE + ";"; - public static final String SEND_DATA = "(L" + OBJECT + ";L" + STRAND_CLASS + ";)V"; + public static final String SCHEDULE_CALL = "(L" + FUNCTION_POINTER + ";L" + STRAND_CLASS + ";" + "L" + TYPE + + ";L" + STRING_VALUE + ";L" + WORKER_CHANNEL_MAP + ";" + "[L" + OBJECT + ";)L" + FUTURE_VALUE + ";"; + public static final String SYNC_SEND = "(L" + STRAND_CLASS + ";L" + WORKER_CHANNEL_MAP + ";L" + STRING_VALUE + + ";L" + OBJECT + ";)L" + OBJECT + ";"; + public static final String ASYNC_SEND = "(L" + WORKER_CHANNEL_MAP + ";L" + STRING_VALUE + ";L" + OBJECT + ";)V"; public static final String SET_ARRAY_ELEMENT = "(L" + TYPE + ";IZ)V"; public static final String SET_DECIMAL_RETURN_DECIMAL = "(L" + DECIMAL_VALUE + ";)L" + DECIMAL_VALUE + ";"; + public static final String SET_DEFAULT_VALUE_METHOD = "(L" + STRING_VALUE + ";L" + B_FUNCTION_POINTER + ";)V"; public static final String SET_IMMUTABLE_TYPE = "(L" + INTERSECTION_TYPE + ";)V"; + public static final String SET_INIT_METHOD = "(L" + METHOD_TYPE + ";)V"; public static final String SET_LINKED_HASH_MAP = "(L" + LINKED_HASH_MAP + ";)V"; public static final String SET_MAP = "(L" + MAP + ";)V"; public static final String SET_METHODS = "([L" + METHOD_TYPE + ";)V"; - public static final String SET_INIT_METHOD = "(L" + METHOD_TYPE + ";)V"; public static final String SET_ON_INIT = "(L" + B_STRING_VALUE + ";L" + OBJECT + ";)V"; public static final String SET_RESOURCE_METHOD_TYPE_ARRAY = "([L" + RESOURCE_METHOD_TYPE + ";)V"; - public static final String SET_STRAND = "(L" + STRAND_CLASS + ";)V"; public static final String SET_TYPE_ARRAY = "([L" + TYPE + ";)V"; public static final String SET_TYPE_ID_SET = "(L" + TYPE_ID_SET + ";)V"; public static final String SET_VALUE = "(L" + B_STRING_VALUE + ";L" + OBJECT + ";)V"; - public static final String START_CALLABLE_OBSERVATION = - "(L" + BAL_ENV + ";L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";JJL" + B_OBJECT + ";L" + - B_STRING_VALUE + ";ZZZ)V"; - public static final String START_RESOURCE_OBSERVATION = - "(L" + BAL_ENV + ";L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";JJL" + B_STRING_VALUE + ";L" + - B_STRING_VALUE + ";L" + B_STRING_VALUE + ";ZZ)V"; + public static final String START_CALLABLE_OBSERVATION = "(L" + BAL_ENV + ";L" + B_STRING_VALUE + ";L" + + B_STRING_VALUE + ";JJL" + B_OBJECT + ";L" + B_STRING_VALUE + ";ZZZ)V"; + public static final String START_RESOURCE_OBSERVATION = "(L" + BAL_ENV + ";L" + B_STRING_VALUE + ";L" + + B_STRING_VALUE + ";JJL" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";ZZ)V"; public static final String STOP_OBSERVATION = "(L" + BAL_ENV + ";)V"; public static final String STRING_BUILDER_APPEND = "(L" + STRING_VALUE + ";)L" + STRING_BUILDER + ";"; - public static final String SYNC_SEND_DATA = "(L" + OBJECT + ";L" + STRAND_CLASS + ";)L" + OBJECT + ";"; public static final String TO_ARRAY = "([L" + OBJECT + ";)[L" + OBJECT + ";"; public static final String TO_CHAR = "(L" + OBJECT + ";)L" + B_STRING_VALUE + ";"; public static final String TO_STRING_RETURN = "()L" + STRING_VALUE + ";"; - public static final String TRY_TAKE_DATA = "(L" + STRAND_CLASS + ";)L" + OBJECT + ";"; public static final String TUPLE_SET_MEMBERS_METHOD = "(L" + LIST + ";L" + TYPE + ";)V"; public static final String TWO_OBJECTS_ARGS = "(L" + OBJECT + ";L" + OBJECT + ";)V"; public static final String TYPE_DESC_CONSTRUCTOR = "(L" + TYPE + ";[L" + MAP_VALUE + ";)V"; - public static final String TYPE_DESC_CONSTRUCTOR_WITH_ANNOTATIONS = - "(L" + TYPE + ";[L" + MAP_VALUE + ";L" + MAP_VALUE + ";)V"; + public static final String TYPE_DESC_CONSTRUCTOR_WITH_ANNOTATIONS = "(L" + TYPE + ";[L" + MAP_VALUE + ";L" + + MAP_VALUE + ";)V"; public static final String TYPE_PARAMETER = "(L" + TYPE + ";)V"; - public static final String UPDATE_CHANNEL_DETAILS = "([L" + CHANNEL_DETAILS + ";)V"; public static final String VALUE_OF_JSTRING = "(L" + OBJECT + ";)L" + STRING_VALUE + ";"; - public static final String WAIT_RESULT = STRAND_CLASS + "$WaitResult"; + public static final String VOID_METHOD_DESC = "()V"; + public static final String WORKER_CHANNELS_ADD = "(L" + WORKER_CHANNEL_MAP + ";[L" + STRING_VALUE + ";)V"; + public static final String WORKER_CHANNELS_COMPLETE = "(L" + WORKER_CHANNEL_MAP + ";L" + OBJECT + ";[L" + + STRING_VALUE + ";[L" + STRING_VALUE + ";)V"; + public static final String WORKER_CHANNELS_COMPLETE_WITH_PANIC = "(L" + WORKER_CHANNEL_MAP + ";L" + THROWABLE + + ";[L" + STRING_VALUE + ";[L" + STRING_VALUE + ";)V"; public static final String XML_ADD_CHILDREN = "(L" + XML_VALUE + ";)V"; public static final String XML_CHILDREN = "()L" + XML_VALUE + ";"; public static final String XML_CHILDREN_FROM_STRING = "(L" + STRING_VALUE + ";)L" + XML_VALUE + ";"; @@ -482,40 +489,8 @@ public final class JvmSignatures { public static final String XML_GET_ATTRIBUTE = "(L" + B_XML_QNAME + ";)L" + STRING_VALUE + ";"; public static final String XML_GET_ITEM = "(I)L" + XML_VALUE + ";"; public static final String XML_SET_ATTRIBUTE = "(L" + B_XML_QNAME + ";L" + B_STRING_VALUE + ";)V"; - public static final String VOID_METHOD_DESC = "()V"; - public static final String HANDLE_DESCRIPTOR_FOR_STRING_CONCAT = "(Ljava/lang/invoke/MethodHandles$Lookup;" + - GET_STRING + "Ljava/lang/invoke/MethodType;" + GET_STRING + "[" + GET_OBJECT + ")" + - "Ljava/lang/invoke/CallSite;"; - public static final String CREATE_REGEXP = "(L" + REG_EXP_DISJUNCTION + ";)L" + REG_EXP_VALUE + ";"; - public static final String CREATE_RE_DISJUNCTION = "(L" + ARRAY_VALUE + ";)L" + REG_EXP_DISJUNCTION + ";"; - public static final String CREATE_RE_SEQUENCE = "(L" + ARRAY_VALUE + ";)L" + REG_EXP_SEQUENCE + ";"; - public static final String CREATE_RE_ASSERTION = "(L" + B_STRING_VALUE + ";)L" + REG_EXP_ASSERTION + ";"; - public static final String CREATE_RE_ATOM_QUANTIFIER = "(L" + OBJECT + ";L" + REG_EXP_QUANTIFIER + ";)L" - + REG_EXP_ATOM_QUANTIFIER + ";"; - public static final String CREATE_RE_LITERAL_CHAR = "(L" + B_STRING_VALUE + ";)L" + REG_EXP_CHAR_ESCAPE + ";"; - public static final String CREATE_RE_CHAR_CLASS = "(L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";L" - + REG_EXP_CHAR_SET + ";L" + B_STRING_VALUE + ";)L" + REG_EXP_CHAR_CLASS + ";"; - public static final String CREATE_RE_CHAR_SET = "(L" + ARRAY_VALUE + ";)L" + REG_EXP_CHAR_SET + ";"; - public static final String CREATE_RE_CHAR_SET_RANGE = "(L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";L" + - B_STRING_VALUE + ";)L" + REG_EXP_CHAR_SET_RANGE + ";"; - public static final String CREATE_RE_CAPTURING_GROUP = "(L" + B_STRING_VALUE + ";L" + OBJECT + - ";L" + REG_EXP_DISJUNCTION + ";L" + B_STRING_VALUE + ";)L" + REG_EXP_CAPTURING_GROUP + ";"; - public static final String CREATE_RE_FLAG_EXPR = "(L" + B_STRING_VALUE + ";L" + REG_EXP_FLAG_ON_OFF + - ";L" + B_STRING_VALUE + ";)L" + REG_EXP_FLAG_EXPR + ";"; - public static final String CREATE_RE_FLAG_ON_OFF = "(L" + B_STRING_VALUE + ";)L" + REG_EXP_FLAG_ON_OFF + ";"; - public static final String CREATE_RE_QUANTIFIER = "(L" + B_STRING_VALUE + ";L" + B_STRING_VALUE + ";)L" - + REG_EXP_QUANTIFIER + ";"; - public static final String GRACEFUL_EXIT_METHOD = "(L" + STRAND_CLASS + ";)V"; - public static final String GET_CONFIG_DETAILS = "()L" + CONFIG_DETAILS + ";"; - public static final String GET_TEST_CONFIG_PATH = "(L" + MODULE + ";L" + STRING_VALUE + ";L" + STRING_VALUE + - ";)L" + CONFIG_DETAILS + ";"; - public static final String SET_DEFAULT_VALUE_METHOD = "(L" + STRING_VALUE + ";L" + B_FUNCTION_POINTER + ";)V"; - public static final String ADD_SERVICE_LISTENER = "(L" + B_OBJECT + ";L" + B_OBJECT + ";L" + OBJECT + ";)V"; - public static final String ALT_RECEIVE_CALL = "(L" + STRAND_CLASS + ";[L" + STRING_VALUE + ";)L" + OBJECT + ";"; - public static final String MULTIPLE_RECEIVE_CALL = "(L" + STRAND_CLASS + ";[L" + RECEIVE_FIELD + ";L" + TYPE + - ";)L" + OBJECT + ";"; - public static final String ADD_BALLERINA_INFO = "(L" + STRING_VALUE + ";L" + STRING_VALUE + ";Z)V"; private JvmSignatures() { + } } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTerminatorGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTerminatorGen.java index 27938d6c9f82..088e937ba560 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTerminatorGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTerminatorGen.java @@ -18,24 +18,21 @@ package org.wso2.ballerinalang.compiler.bir.codegen; import io.ballerina.identifier.Utils; -import io.ballerina.tools.diagnostics.Location; import org.ballerinalang.compiler.BLangCompilerException; import org.ballerinalang.model.elements.PackageID; -import org.objectweb.asm.Handle; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; +import org.objectweb.asm.Opcodes; import org.wso2.ballerinalang.compiler.PackageCache; import org.wso2.ballerinalang.compiler.bir.codegen.internal.AsyncDataCollector; import org.wso2.ballerinalang.compiler.bir.codegen.internal.BIRVarToJVMIndexMap; import org.wso2.ballerinalang.compiler.bir.codegen.internal.LabelGenerator; import org.wso2.ballerinalang.compiler.bir.codegen.internal.LambdaFunction; -import org.wso2.ballerinalang.compiler.bir.codegen.internal.ScheduleFunctionInfo; import org.wso2.ballerinalang.compiler.bir.codegen.model.BIRFunctionWrapper; import org.wso2.ballerinalang.compiler.bir.codegen.model.JIConstructorCall; import org.wso2.ballerinalang.compiler.bir.codegen.model.JIMethodCLICall; import org.wso2.ballerinalang.compiler.bir.codegen.model.JIMethodCall; import org.wso2.ballerinalang.compiler.bir.codegen.model.JTerminator; -import org.wso2.ballerinalang.compiler.bir.codegen.model.JType; import org.wso2.ballerinalang.compiler.bir.codegen.model.JavaMethodCall; import org.wso2.ballerinalang.compiler.bir.codegen.split.JvmConstantsGen; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; @@ -47,22 +44,17 @@ import org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BPackageSymbol; -import org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols; import org.wso2.ballerinalang.compiler.semantics.model.types.BFutureType; import org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType; import org.wso2.ballerinalang.compiler.semantics.model.types.BType; -import org.wso2.ballerinalang.compiler.semantics.model.types.BUnionType; import org.wso2.ballerinalang.compiler.util.Name; import org.wso2.ballerinalang.compiler.util.TypeTags; import org.wso2.ballerinalang.compiler.util.Unifier; -import org.wso2.ballerinalang.util.Flags; import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; +import java.util.Objects; import static org.objectweb.asm.Opcodes.AALOAD; import static org.objectweb.asm.Opcodes.AASTORE; @@ -80,37 +72,30 @@ import static org.objectweb.asm.Opcodes.GETFIELD; import static org.objectweb.asm.Opcodes.GETSTATIC; import static org.objectweb.asm.Opcodes.GOTO; -import static org.objectweb.asm.Opcodes.H_INVOKESTATIC; import static org.objectweb.asm.Opcodes.ICONST_0; -import static org.objectweb.asm.Opcodes.ICONST_1; -import static org.objectweb.asm.Opcodes.IFEQ; import static org.objectweb.asm.Opcodes.IFGT; import static org.objectweb.asm.Opcodes.IFNONNULL; -import static org.objectweb.asm.Opcodes.IFNULL; import static org.objectweb.asm.Opcodes.ILOAD; import static org.objectweb.asm.Opcodes.INVOKEINTERFACE; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.INVOKESTATIC; import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; import static org.objectweb.asm.Opcodes.IRETURN; -import static org.objectweb.asm.Opcodes.ISTORE; import static org.objectweb.asm.Opcodes.L2I; import static org.objectweb.asm.Opcodes.LLOAD; import static org.objectweb.asm.Opcodes.LRETURN; import static org.objectweb.asm.Opcodes.NEW; import static org.objectweb.asm.Opcodes.POP; -import static org.objectweb.asm.Opcodes.PUTFIELD; -import static org.objectweb.asm.Opcodes.SIPUSH; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ADD_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ANNOTATION_UTILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ARRAY_LIST; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ARRAY_VALUE_IMPL; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ASYNC_UTILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BAL_ENV_CLASS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BAL_EXTENSION; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BLOCKED_ON_EXTERN_FIELD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_VAR_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.DEFAULT_STRAND_DISPATCHER; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.DEFAULT_STRAND_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ERROR_CODES; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ERROR_HELPER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ERROR_REASONS; @@ -120,88 +105,60 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.GLOBAL_LOCK_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HASH_MAP; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.INT_VALUE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.IS_BLOCKED_ON_EXTERN_FIELD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LIST; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LOCK_STORE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LOCK_STORE_VAR_NAME; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LOCK_VALUE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAKE_CONCAT_WITH_CONSTANTS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAP; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.MODULE_INITIALIZER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_INIT_CLASS_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OBJECT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.PANIC_FIELD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.PREDEFINED_TYPES; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RECEIVE_FIELD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULER; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULE_FUNCTION_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULE_LOCAL_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.START_OF_HEADING_WITH_SEMICOLON; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.START_ISOLATED_WORKER; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.START_NON_ISOLATED_WORKER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_CLASS; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_METADATA_VAR_PREFIX; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_POLICY_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_THREAD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_VALUE_ANY; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRING_CONCAT_FACTORY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRING_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TYPE_ANYDATA_ARRAY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TYPE_ANY_ARRAY; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.VALUE_OF_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WD_CHANNELS; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_DATA_CHANNEL; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_CHANNELS_COMPLETE_METHOD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_CHANNEL_NAMES_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_UTILS; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmInstructionGen.addJUnboxInsn; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ALT_RECEIVE_CALL; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANNOTATION_GET_STRAND; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ANY_TO_JBOOLEAN; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ASYNC_SEND; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.BAL_ENV_PARAM; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.BOBJECT_CALL; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_BERROR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_FUNCTION; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_LOCK_FROM_MAP; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_LOCK_MAP; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_LOCK_STORE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MODULE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_RUNTIME_ERROR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_RUNTIME_EXCEPTION; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_SCHEDULER; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_STRAND; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_STRAND_METADATA; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_STRING; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_WD_CHANNELS; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_WORKER_DATA_CHANNEL; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_CHANNEL_ERROR; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_DESCRIPTOR_FOR_STRING_CONCAT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_FLUSH; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_WAIT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_WAIT_ANY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_WAIT_MULTIPLE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_WORKER_ERROR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_ANYDATA_ARRAY; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_BAL_ENV_WITH_FUNC_NAME; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_RECEIVE_FIELD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INT_TO_STRING; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INT_VALUE_OF_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.IS_CONCURRENT; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_BAL_ENV; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.LOAD_ARRAY_TYPE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.LOAD_JOBJECT_TYPE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.LOCK; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.MAP_PUT; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.MODULE_INITIALIZER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.MULTIPLE_RECEIVE_CALL; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.PANIC_IF_IN_LOCK; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.PASS_OBJECT_RETURN_OBJECT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.REMOVE_WORKER_DATA_CHANNEL; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.PASS_STRAND; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.PASS_STRAND_AND_LOCK_NAME; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RECEIVE_DATA; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RETURN_OBJECT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SCHEDULE_FUNCTION; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SCHEDULE_LOCAL; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SEND_DATA; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SYNC_SEND_DATA; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.TRY_TAKE_DATA; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SCHEDULE_CALL; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SYNC_SEND; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VOID_METHOD_DESC; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.WAIT_RESULT; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.WORKER_CHANNELS_COMPLETE; import static org.wso2.ballerinalang.compiler.bir.codegen.interop.InteropMethodGen.genVarArg; /** @@ -225,7 +182,6 @@ public class JvmTerminatorGen { private final JvmTypeGen jvmTypeGen; private final JvmCastGen jvmCastGen; private final AsyncDataCollector asyncDataCollector; - private final String strandMetadataClass; public JvmTerminatorGen(MethodVisitor mv, BIRVarToJVMIndexMap indexMap, LabelGenerator labelGen, JvmErrorGen errorGen, PackageID packageID, JvmInstructionGen jvmInstructionGen, @@ -247,55 +203,42 @@ public JvmTerminatorGen(MethodVisitor mv, BIRVarToJVMIndexMap indexMap, LabelGen this.moduleInitClass = JvmCodeGenUtil.getModuleLevelClassName(packageID, MODULE_INIT_CLASS_NAME); this.unifier = new Unifier(); this.asyncDataCollector = asyncDataCollector; - this.strandMetadataClass = jvmConstantsGen.getStrandMetadataConstantsClass(); - } - - private static void genYieldCheckForLock(MethodVisitor mv, LabelGenerator labelGen, String funcName, - int localVarOffset, int yieldLocationVarIndex, int yieldStatusVarIndex, - String fullyQualifiedFuncName, Location terminatorPos) { - - mv.visitVarInsn(ALOAD, localVarOffset); - mv.visitMethodInsn(INVOKEVIRTUAL, STRAND_CLASS, "isYielded", "()Z", false); - JvmCodeGenUtil.generateSetYieldedStatus(mv, labelGen, funcName, yieldLocationVarIndex, - terminatorPos, fullyQualifiedFuncName, "WAITING FOR LOCK", yieldStatusVarIndex); } - public void genTerminator(BIRTerminator terminator, String moduleClassName, BIRNode.BIRFunction func, - String funcName, int localVarOffset, int stateVarIndex, int returnVarRefIndex, - BType attachedType, int yieldLocationVarIndex, int yieldStatusVarIndex, - int invocationVarIndex, int loopVarIndex, String fullyQualifiedFuncName, - BIRNode.BIRBasicBlock currentBB, Label loopLabel) { - + public void genTerminator(BIRTerminator terminator, BIRNode.BIRFunction func, + String funcName, int localVarOffset, int returnVarRefIndex, + BType attachedType, int channelMapVarIndex, int sendWorkerChannelNamesVar, + int receiveWorkerChannelNamesVar) { switch (terminator.kind) { - case LOCK -> { - this.genLockTerm((BIRTerminator.Lock) terminator, funcName, localVarOffset, yieldLocationVarIndex, - terminator.pos, fullyQualifiedFuncName, yieldStatusVarIndex); + case GOTO -> { + this.genGoToTerm((BIRTerminator.GOTO) terminator, funcName); return; } - case UNLOCK -> { - this.genUnlockTerm((BIRTerminator.Unlock) terminator, funcName); + case RETURN -> { + this.genReturnTerm(returnVarRefIndex, func, channelMapVarIndex, sendWorkerChannelNamesVar, + receiveWorkerChannelNamesVar, localVarOffset); return; } - case GOTO -> { - this.genGoToTerm((BIRTerminator.GOTO) terminator, funcName, currentBB, stateVarIndex, loopVarIndex, - loopLabel); + case BRANCH -> { + this.genBranchTerm((BIRTerminator.Branch) terminator, funcName); return; } case CALL -> { - this.genCallTerm((BIRTerminator.Call) terminator, localVarOffset); + this.genCallTerm((BIRTerminator.Call) terminator, localVarOffset, funcName); return; } - case ASYNC_CALL -> { - this.genAsyncCallTerm((BIRTerminator.AsyncCall) terminator, localVarOffset, - moduleClassName, attachedType, funcName); + case FP_CALL -> { + this.genFPCallIns((BIRTerminator.FPCall) terminator, localVarOffset, + func.hasWorkers, channelMapVarIndex); return; } - case BRANCH -> { - this.genBranchTerm((BIRTerminator.Branch) terminator, funcName); + case ASYNC_CALL -> { + this.genAsyncCallTerm((BIRTerminator.AsyncCall) terminator, localVarOffset, + func.hasWorkers, channelMapVarIndex); return; } - case RETURN -> { - this.genReturnTerm(returnVarRefIndex, func, invocationVarIndex, localVarOffset); + case PLATFORM -> { + this.genPlatformIns((JTerminator) terminator, attachedType, localVarOffset, func); return; } case PANIC -> { @@ -310,35 +253,35 @@ public void genTerminator(BIRTerminator terminator, String moduleClassName, BIRN this.genWaitAllIns((BIRTerminator.WaitAll) terminator, localVarOffset); return; } - case FP_CALL -> { - this.genFPCallIns((BIRTerminator.FPCall) terminator, moduleClassName, attachedType, - funcName, localVarOffset, invocationVarIndex); + case LOCK -> { + this.genLockTerm((BIRTerminator.Lock) terminator, funcName, localVarOffset); + return; + } + case UNLOCK -> { + this.genUnlockTerm((BIRTerminator.Unlock) terminator, funcName, localVarOffset); return; } case WK_SEND -> { - this.genWorkerSendIns((BIRTerminator.WorkerSend) terminator, localVarOffset, invocationVarIndex); + this.genWorkerSendIns((BIRTerminator.WorkerSend) terminator, func, channelMapVarIndex, localVarOffset); return; } case WK_RECEIVE -> { - this.genWorkerReceiveIns((BIRTerminator.WorkerReceive) terminator, localVarOffset, invocationVarIndex); + this.genWorkerReceiveIns((BIRTerminator.WorkerReceive) terminator, func, channelMapVarIndex, + localVarOffset); return; } case WK_ALT_RECEIVE -> { - this.genWorkerAlternateReceiveIns((BIRTerminator.WorkerAlternateReceive) terminator, localVarOffset, - invocationVarIndex); + this.genWorkerAlternateReceiveIns((BIRTerminator.WorkerAlternateReceive) terminator, + func, channelMapVarIndex, localVarOffset); return; } case WK_MULTIPLE_RECEIVE -> { - this.genWorkerMultipleReceiveIns((BIRTerminator.WorkerMultipleReceive) terminator, localVarOffset, - invocationVarIndex); + this.genWorkerMultipleReceiveIns((BIRTerminator.WorkerMultipleReceive) terminator, func, + channelMapVarIndex, localVarOffset); return; } case FLUSH -> { - this.genFlushIns((BIRTerminator.Flush) terminator, localVarOffset, invocationVarIndex); - return; - } - case PLATFORM -> { - this.genPlatformIns((JTerminator) terminator, attachedType, localVarOffset, func); + this.genFlushIns((BIRTerminator.Flush) terminator, func, channelMapVarIndex, localVarOffset); return; } } @@ -347,115 +290,81 @@ public void genTerminator(BIRTerminator terminator, String moduleClassName, BIRN } - private void genGoToTerm(BIRTerminator.GOTO gotoIns, String funcName, BIRNode.BIRBasicBlock currentBB, - int stateVarIndex, int loopVarIndex, Label loopLabel) { - int currentBBNumber = currentBB.number; - int gotoBBNumber = gotoIns.targetBB.number; - if (currentBBNumber <= gotoBBNumber) { - Label gotoLabel = this.labelGen.getLabel(funcName + gotoIns.targetBB.id.value); - this.mv.visitJumpInsn(GOTO, gotoLabel); + private void genGoToTerm(BIRTerminator.GOTO gotoIns, String funcName) { + Label gotoLabel = this.labelGen.getLabel(funcName + gotoIns.targetBB.id.value); + this.mv.visitJumpInsn(GOTO, gotoLabel); + } + + public void genReturnTerm(int returnVarRefIndex, BIRNode.BIRFunction func, int channelMapVarIndex, + int sendWorkerChannelNamesVar, int receiveWorkerChannelNamesVar, int localVarOffset) { + BType bType = unifier.build(func.type.retType); + generateReturnTermFromType(bType, func, returnVarRefIndex, channelMapVarIndex, sendWorkerChannelNamesVar, + receiveWorkerChannelNamesVar, localVarOffset); + } + + private void genBranchTerm(BIRTerminator.Branch branchIns, String funcName) { + this.loadVar(branchIns.op.variableDcl); + Label trueBBLabel = this.labelGen.getLabel(funcName + branchIns.trueBB.id.value); + this.mv.visitJumpInsn(IFGT, trueBBLabel); + Label falseBBLabel = this.labelGen.getLabel(funcName + branchIns.falseBB.id.value); + this.mv.visitJumpInsn(GOTO, falseBBLabel); + } + + private void genCall(BIRTerminator.Call callIns, PackageID packageID, int localVarOffset) { + + if (!callIns.isVirtual) { + this.genFuncCall(callIns, packageID, localVarOffset); return; } - this.mv.visitInsn(ICONST_1); - this.mv.visitVarInsn(ISTORE, loopVarIndex); - this.mv.visitIntInsn(SIPUSH, gotoBBNumber); - this.mv.visitVarInsn(ISTORE, stateVarIndex); - this.mv.visitJumpInsn(GOTO, loopLabel); - } - private void genLockTerm(BIRTerminator.Lock lockIns, String funcName, int localVarOffset, int yieldLocationVarIndex, - Location terminatorPos, String fullyQualifiedFuncName, int yieldStatusVarIndex) { + BIRNode.BIRVariableDcl selfArg = callIns.args.getFirst().variableDcl; + BType selfArgRefType = JvmCodeGenUtil.getImpliedType(selfArg.type); + if (selfArgRefType.tag == TypeTags.OBJECT || selfArgRefType.tag == TypeTags.UNION) { + this.genVirtualCall(callIns, localVarOffset); + } else { + // then this is a function attached to a built-in type + this.genBuiltinTypeAttachedFuncCall(callIns, packageID, localVarOffset); + } + } + private void genLockTerm(BIRTerminator.Lock lockIns, String funcName, int localVarOffset) { Label gotoLabel = this.labelGen.getLabel(funcName + lockIns.lockedBB.id.value); - String lockStore = "L" + LOCK_STORE + ";"; String initClassName = jvmPackageGen.lookupGlobalVarClassName(this.currentPackageName, LOCK_STORE_VAR_NAME); String lockName = GLOBAL_LOCK_NAME + lockIns.lockId; - this.mv.visitFieldInsn(GETSTATIC, initClassName, LOCK_STORE_VAR_NAME, lockStore); - this.mv.visitLdcInsn(lockName); - this.mv.visitMethodInsn(INVOKEVIRTUAL, LOCK_STORE, "getLockFromMap", GET_LOCK_FROM_MAP, false); + this.mv.visitFieldInsn(GETSTATIC, initClassName, LOCK_STORE_VAR_NAME, GET_LOCK_STORE); this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitMethodInsn(INVOKEVIRTUAL, LOCK_VALUE, "lock", LOCK, false); - this.mv.visitInsn(POP); - genYieldCheckForLock(this.mv, this.labelGen, funcName, localVarOffset, yieldLocationVarIndex, - yieldStatusVarIndex, fullyQualifiedFuncName, terminatorPos); + this.mv.visitLdcInsn(lockName); + this.mv.visitMethodInsn(INVOKEVIRTUAL, LOCK_STORE, "lock", PASS_STRAND_AND_LOCK_NAME, false); this.mv.visitJumpInsn(GOTO, gotoLabel); } - private void genUnlockTerm(BIRTerminator.Unlock unlockIns, String funcName) { - + private void genUnlockTerm(BIRTerminator.Unlock unlockIns, String funcName, int localVarOffset) { Label gotoLabel = this.labelGen.getLabel(funcName + unlockIns.unlockBB.id.value); - - // unlocked in the same order https://yarchive.net/comp/linux/lock_ordering.html - String lockStore = "L" + LOCK_STORE + ";"; String lockName = GLOBAL_LOCK_NAME + unlockIns.relatedLock.lockId; String initClassName = jvmPackageGen.lookupGlobalVarClassName(this.currentPackageName, LOCK_STORE_VAR_NAME); - this.mv.visitFieldInsn(GETSTATIC, initClassName, LOCK_STORE_VAR_NAME, lockStore); + this.mv.visitFieldInsn(GETSTATIC, initClassName, LOCK_STORE_VAR_NAME, GET_LOCK_STORE); + this.mv.visitVarInsn(ALOAD, localVarOffset); this.mv.visitLdcInsn(lockName); - this.mv.visitMethodInsn(INVOKEVIRTUAL, LOCK_STORE, "getLockFromMap", GET_LOCK_MAP, false); - this.mv.visitMethodInsn(INVOKEVIRTUAL, LOCK_VALUE, "unlock", VOID_METHOD_DESC, false); - + this.mv.visitMethodInsn(INVOKEVIRTUAL, LOCK_STORE, "unlock", PASS_STRAND_AND_LOCK_NAME, false); this.mv.visitJumpInsn(GOTO, gotoLabel); } - private void handleErrorRetInUnion(int returnVarRefIndex, List channels, BUnionType bType, - int invocationVarIndex, int localVarOffset) { - - if (channels.isEmpty()) { - return; - } - - boolean errorIncluded = false; - for (BType member : bType.getMemberTypes()) { - member = JvmCodeGenUtil.getImpliedType(member); - if (member.tag == TypeTags.ERROR) { - errorIncluded = true; - break; - } - } - - if (errorIncluded) { - this.mv.visitVarInsn(ALOAD, returnVarRefIndex); - this.mv.visitVarInsn(ALOAD, localVarOffset); - JvmCodeGenUtil.loadChannelDetails(this.mv, channels, invocationVarIndex); - this.mv.visitMethodInsn(INVOKESTATIC, WORKER_UTILS, "handleWorkerError", - HANDLE_WORKER_ERROR, false); - } - } - - private void notifyChannels(List channels, int retIndex, int invocationVarIndex) { - - if (channels.isEmpty()) { - return; - } - - this.mv.visitVarInsn(ALOAD, 0); - JvmCodeGenUtil.loadChannelDetails(this.mv, channels, invocationVarIndex); - this.mv.visitVarInsn(ALOAD, retIndex); - this.mv.visitMethodInsn(INVOKEVIRTUAL, STRAND_CLASS, "handleChannelError", HANDLE_CHANNEL_ERROR, false); - } - - private void genBranchTerm(BIRTerminator.Branch branchIns, String funcName) { - this.loadVar(branchIns.op.variableDcl); - Label trueBBLabel = this.labelGen.getLabel(funcName + branchIns.trueBB.id.value); - this.mv.visitJumpInsn(IFGT, trueBBLabel); - Label falseBBLabel = this.labelGen.getLabel(funcName + branchIns.falseBB.id.value); - this.mv.visitJumpInsn(GOTO, falseBBLabel); - } - - private void genCallTerm(BIRTerminator.Call callIns, int localVarOffset) { + private void genCallTerm(BIRTerminator.Call callIns, int localVarOffset, String funcName) { // invoke the function this.genCall(callIns, callIns.calleePkg, localVarOffset); // store return this.storeReturnFromCallIns(callIns.lhsOp != null ? callIns.lhsOp.variableDcl : null); + Label thenBBLabel = this.labelGen.getLabel(funcName + callIns.thenBB.id.value); + this.mv.visitJumpInsn(GOTO, thenBBLabel); } private void genPlatformIns(JTerminator terminator, BType attachedType, int localVarOffset, BIRNode.BIRFunction func) { switch (terminator.jTermKind) { case J_METHOD_CALL -> this.genJCallTerm((JavaMethodCall) terminator, attachedType, localVarOffset); - case JI_METHOD_CALL -> this.genJICallTerm((JIMethodCall) terminator, localVarOffset, func); - case JI_CONSTRUCTOR_CALL -> this.genJIConstructorTerm((JIConstructorCall) terminator, localVarOffset); + case JI_METHOD_CALL -> this.genJICallTerm((JIMethodCall) terminator, localVarOffset, func, attachedType); + case JI_CONSTRUCTOR_CALL -> this.genJIConstructorTerm((JIConstructorCall) terminator); case JI_METHOD_CLI_CALL -> this.genJICLICallTerm((JIMethodCLICall) terminator, localVarOffset); default -> throw new BLangCompilerException("JVM generation is not supported for terminator instruction " + terminator); @@ -463,12 +372,6 @@ private void genPlatformIns(JTerminator terminator, BType attachedType, int loca } private void genJICLICallTerm(JIMethodCLICall terminator, int localVarOffset) { - Label blockedOnExternLabel = new Label(); - Label notBlockedOnExternLabel = new Label(); - genHandlingBlockedOnExternal(localVarOffset, blockedOnExternLabel); - this.mv.visitJumpInsn(GOTO, notBlockedOnExternLabel); - - this.mv.visitLabel(blockedOnExternLabel); this.mv.visitVarInsn(ALOAD, localVarOffset + 1); this.mv.visitTypeInsn(CHECKCAST, terminator.jClassName); this.mv.visitMethodInsn(INVOKEVIRTUAL, terminator.jClassName, terminator.name, terminator.jMethodVMSig, false); @@ -490,26 +393,9 @@ private void genJICLICallTerm(JIMethodCLICall terminator, int localVarOffset) { index++; this.storeToVar(lhsArg.variableDcl); } - this.mv.visitLabel(notBlockedOnExternLabel); } private void genJCallTerm(JavaMethodCall callIns, BType attachedType, int localVarOffset) { - // Load function parameters of the target Java method to the stack. - Label blockedOnExternLabel = new Label(); - Label notBlockedOnExternLabel = new Label(); - - genHandlingBlockedOnExternal(localVarOffset, blockedOnExternLabel); - - if (callIns.lhsOp != null && callIns.lhsOp.variableDcl != null) { - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "returnValue", LOAD_JOBJECT_TYPE); - jvmCastGen.addUnboxInsn(this.mv, callIns.lhsOp.variableDcl.type); // store return - this.storeToVar(callIns.lhsOp.variableDcl); - } - - this.mv.visitJumpInsn(GOTO, notBlockedOnExternLabel); - - this.mv.visitLabel(blockedOnExternLabel); int argIndex = 0; if (attachedType == null) { @@ -518,7 +404,7 @@ private void genJCallTerm(JavaMethodCall callIns, BType attachedType, int localV // Below codes are not needed (as normal external functions doesn't support attached invocations) // check whether function params already include the self this.mv.visitVarInsn(ALOAD, localVarOffset); - BIRNode.BIRVariableDcl selfArg = callIns.args.get(0).variableDcl; + BIRNode.BIRVariableDcl selfArg = callIns.args.getFirst().variableDcl; this.loadVar(selfArg); this.mv.visitTypeInsn(CHECKCAST, B_OBJECT); argIndex += 1; @@ -537,34 +423,14 @@ private void genJCallTerm(JavaMethodCall callIns, BType attachedType, int localV if (callIns.lhsOp != null && callIns.lhsOp.variableDcl != null) { this.storeToVar(callIns.lhsOp.variableDcl); } - - this.mv.visitLabel(notBlockedOnExternLabel); } - private void genJICallTerm(JIMethodCall callIns, int localVarOffset, BIRNode.BIRFunction func) { - // Load function parameters of the target Java method to the stack. - Label blockedOnExternLabel = new Label(); - Label notBlockedOnExternLabel = new Label(); - - genHandlingBlockedOnExternal(localVarOffset, blockedOnExternLabel); - if (callIns.lhsOp != null) { - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "returnValue", LOAD_JOBJECT_TYPE); - // store return - BIROperand lhsOpVarDcl = callIns.lhsOp; - addJUnboxInsn(this.mv, ((JType) lhsOpVarDcl.variableDcl.type)); - this.storeToVar(lhsOpVarDcl.variableDcl); - } - - this.mv.visitJumpInsn(GOTO, notBlockedOnExternLabel); - - this.mv.visitLabel(blockedOnExternLabel); + private void genJICallTerm(JIMethodCall callIns, int localVarOffset, BIRNode.BIRFunction func, BType attachedType) { boolean isInterface = callIns.invocationType == INVOKEINTERFACE; - int argIndex = 0; if (callIns.invocationType == INVOKEVIRTUAL || isInterface) { // check whether function params already include the self - BIRNode.BIRVariableDcl selfArg = callIns.args.get(0).variableDcl; + BIRNode.BIRVariableDcl selfArg = callIns.args.getFirst().variableDcl; this.loadVar(selfArg); this.mv.visitMethodInsn(INVOKEVIRTUAL, HANDLE_VALUE, GET_VALUE_METHOD, RETURN_OBJECT, false); this.mv.visitTypeInsn(CHECKCAST, callIns.jClassName); @@ -594,15 +460,15 @@ private void genJICallTerm(JIMethodCall callIns, int localVarOffset, BIRNode.BIR boolean hasBalEnvParam = jMethodVMSig.startsWith(BAL_ENV_PARAM); if (hasBalEnvParam) { - mv.visitTypeInsn(NEW, BAL_ENV_CLASS); - mv.visitInsn(DUP); + this.mv.visitTypeInsn(NEW, BAL_ENV_CLASS); + this.mv.visitInsn(DUP); this.mv.visitVarInsn(ALOAD, localVarOffset); // load the strand // load the current Module - mv.visitFieldInsn(GETSTATIC, this.moduleInitClass, CURRENT_MODULE_VAR_NAME, GET_MODULE); + this.mv.visitFieldInsn(GETSTATIC, this.moduleInitClass, CURRENT_MODULE_VAR_NAME, GET_MODULE); // load function name - mv.visitLdcInsn(func.name.getValue()); + this.mv.visitLdcInsn(func.name.getValue()); this.jvmTypeGen.loadFunctionPathParameters(mv, (BInvokableTypeSymbol) func.type.tsymbol); - mv.visitMethodInsn(INVOKESPECIAL, BAL_ENV_CLASS, JVM_INIT_METHOD, INIT_BAL_ENV_WITH_FUNC_NAME, false); + this.mv.visitMethodInsn(INVOKESPECIAL, BAL_ENV_CLASS, JVM_INIT_METHOD, INIT_BAL_ENV, false); } if (callIns.receiver != null) { @@ -630,62 +496,22 @@ private void genJICallTerm(JIMethodCall callIns, int localVarOffset, BIRNode.BIR if (callIns.varArgExist) { BIROperand arg = callIns.args.get(argIndex); int localVarIndex = this.indexMap.addIfNotExists(arg.variableDcl.name.value, arg.variableDcl.type); - genVarArg(this.mv, this.indexMap, arg.variableDcl.type, callIns.varArgType, localVarIndex, - symbolTable, jvmCastGen); + genVarArg(this.mv, this.indexMap, arg.variableDcl.type, callIns.varArgType, localVarIndex, + symbolTable, jvmCastGen); } String jClassName = callIns.jClassName; String jMethodName = callIns.name; this.mv.visitMethodInsn(callIns.invocationType, jClassName, jMethodName, jMethodVMSig, isInterface); - - boolean isVoidMethod = jMethodVMSig.endsWith(")V"); if (callIns.lhsOp != null && callIns.lhsOp.variableDcl != null) { - if (hasBalEnvParam && isVoidMethod) { - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "returnValue", "Ljava/lang/Object;"); - - Label doNotStoreReturn = new Label(); - mv.visitJumpInsn(IFNULL, doNotStoreReturn); - - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "returnValue", "Ljava/lang/Object;"); - BIROperand lhsOpVarDcl = callIns.lhsOp; - addJUnboxInsn(this.mv, ((JType) lhsOpVarDcl.variableDcl.type)); - this.storeToVar(lhsOpVarDcl.variableDcl); - - mv.visitLabel(doNotStoreReturn); - } else { - this.storeToVar(callIns.lhsOp.variableDcl); - } + this.storeToVar(callIns.lhsOp.variableDcl); } - - this.mv.visitLabel(notBlockedOnExternLabel); } - private void genJIConstructorTerm(JIConstructorCall callIns, int localVarOffset) { - // Load function parameters of the target Java method to the stack. - Label blockedOnExternLabel = new Label(); - Label notBlockedOnExternLabel = new Label(); - - genHandlingBlockedOnExternal(localVarOffset, blockedOnExternLabel); - if (callIns.lhsOp.variableDcl != null) { - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "returnValue", GET_OBJECT); - jvmCastGen.addUnboxInsn(this.mv, callIns.lhsOp.variableDcl.type); - // store return - BIRNode.BIRVariableDcl lhsOpVarDcl = callIns.lhsOp.variableDcl; - this.storeToVar(lhsOpVarDcl); - } - - this.mv.visitJumpInsn(GOTO, notBlockedOnExternLabel); - - this.mv.visitLabel(blockedOnExternLabel); - + private void genJIConstructorTerm(JIConstructorCall callIns) { this.mv.visitTypeInsn(NEW, callIns.jClassName); this.mv.visitInsn(DUP); - int argIndex = 0; - int argsCount = callIns.args.size(); while (argIndex < argsCount) { BIROperand arg = callIns.args.get(argIndex); @@ -697,42 +523,13 @@ private void genJIConstructorTerm(JIConstructorCall callIns, int localVarOffset) String jMethodName = callIns.name; String jMethodVMSig = callIns.jMethodVMSig; this.mv.visitMethodInsn(INVOKESPECIAL, jClassName, jMethodName, jMethodVMSig, false); - BIRNode.BIRVariableDcl lhsOpVarDcl = callIns.lhsOp.variableDcl; - if (lhsOpVarDcl != null) { this.storeToVar(lhsOpVarDcl); } - - this.mv.visitLabel(notBlockedOnExternLabel); - } - - private void genHandlingBlockedOnExternal(int localVarOffset, Label blockedOnExternLabel) { - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitMethodInsn(INVOKEVIRTUAL, STRAND_CLASS, IS_BLOCKED_ON_EXTERN_FIELD, "()Z", false); - this.mv.visitJumpInsn(IFEQ, blockedOnExternLabel); - - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitInsn(ICONST_0); - this.mv.visitFieldInsn(PUTFIELD, STRAND_CLASS, BLOCKED_ON_EXTERN_FIELD, "Z"); - - // Throw error if strand has panic - this.mv.visitVarInsn(ALOAD, localVarOffset); - mv.visitFieldInsn(GETFIELD, STRAND_CLASS, PANIC_FIELD, GET_BERROR); - Label panicLabel = new Label(); - mv.visitJumpInsn(IFNULL, panicLabel); - this.mv.visitVarInsn(ALOAD, localVarOffset); - mv.visitFieldInsn(GETFIELD, STRAND_CLASS, PANIC_FIELD, GET_BERROR); - mv.visitInsn(DUP); - this.mv.visitVarInsn(ALOAD, localVarOffset); - mv.visitInsn(ACONST_NULL); - mv.visitFieldInsn(PUTFIELD, STRAND_CLASS, PANIC_FIELD, GET_BERROR); - mv.visitInsn(ATHROW); - mv.visitLabel(panicLabel); } private void storeReturnFromCallIns(BIRNode.BIRVariableDcl lhsOpVarDcl) { - if (lhsOpVarDcl != null) { this.storeToVar(lhsOpVarDcl); } else { @@ -741,23 +538,6 @@ private void storeReturnFromCallIns(BIRNode.BIRVariableDcl lhsOpVarDcl) { } - private void genCall(BIRTerminator.Call callIns, PackageID packageID, int localVarOffset) { - - if (!callIns.isVirtual) { - this.genFuncCall(callIns, packageID, localVarOffset); - return; - } - - BIRNode.BIRVariableDcl selfArg = callIns.args.get(0).variableDcl; - BType selfArgRefType = JvmCodeGenUtil.getImpliedType(selfArg.type); - if (selfArgRefType.tag == TypeTags.OBJECT || selfArgRefType.tag == TypeTags.UNION) { - this.genVirtualCall(callIns, localVarOffset); - } else { - // then this is a function attached to a built-in type - this.genBuiltinTypeAttachedFuncCall(callIns, packageID, localVarOffset); - } - } - private void genFuncCall(BIRTerminator.Call callIns, PackageID packageID, int localVarOffset) { String methodName = callIns.name.value; this.genStaticCall(callIns, packageID, localVarOffset, methodName, methodName); @@ -811,6 +591,7 @@ private void genStaticCall(BIRTerminator.Call callIns, PackageID packageID, int this.mv.visitMethodInsn(INVOKESTATIC, jvmClass, encodedMethodName, MODULE_INITIALIZER, false); return; } + assert funcSymbol != null; BInvokableType type = (BInvokableType) funcSymbol.type; ArrayList params = new ArrayList<>(type.paramTypes); if (type.restType != null) { @@ -823,7 +604,7 @@ private void genStaticCall(BIRTerminator.Call callIns, PackageID packageID, int } jvmClass = JvmCodeGenUtil.getModuleLevelClassName(packageID, - JvmCodeGenUtil.cleanupPathSeparators(balFileName)); + JvmCodeGenUtil.cleanupPathSeparators(balFileName)); //TODO: add receiver: BType attachedType = type.r != null ? receiver.type : null; BType retType = unifier.build(type.retType); methodDesc = JvmCodeGenUtil.getMethodDesc(params, retType); @@ -833,7 +614,7 @@ private void genStaticCall(BIRTerminator.Call callIns, PackageID packageID, int private void genVirtualCall(BIRTerminator.Call callIns, int localVarOffset) { // load self - BIRNode.BIRVariableDcl selfArg = callIns.args.get(0).variableDcl; + BIRNode.BIRVariableDcl selfArg = callIns.args.getFirst().variableDcl; this.loadVar(selfArg); this.mv.visitTypeInsn(CHECKCAST, B_OBJECT); @@ -867,50 +648,25 @@ private void genVirtualCall(BIRTerminator.Call callIns, int localVarOffset) { // call method this.mv.visitMethodInsn(INVOKEINTERFACE, B_OBJECT, "call", BOBJECT_CALL, true); - BType returnType = callIns.lhsOp.variableDcl.type; jvmCastGen.addUnboxInsn(this.mv, returnType); } - private void genAsyncCallTerm(BIRTerminator.AsyncCall callIns, int localVarOffset, String moduleClassName, - BType attachedType, String parentFunction) { + private void genAsyncCallTerm(BIRTerminator.AsyncCall callIns, int localVarOffset, + boolean hasWorkers, int channelMapVarIndex) { // Check if already locked before submitting to scheduler. - String lockStore = "L" + LOCK_STORE + ";"; - String initClassName = jvmPackageGen.lookupGlobalVarClassName(this.currentPackageName, LOCK_STORE_VAR_NAME); - this.mv.visitFieldInsn(GETSTATIC, initClassName, LOCK_STORE_VAR_NAME, lockStore); - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitMethodInsn(INVOKEVIRTUAL, LOCK_STORE, "panicIfInLock", PANIC_IF_IN_LOCK, false); + genPanicIfInLock(localVarOffset); // Load the scheduler from strand this.mv.visitVarInsn(ALOAD, localVarOffset); this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "scheduler", GET_SCHEDULER); - // create an Object[] for the rest params - int argsCount = callIns.args.size(); - //create an object array of args - this.mv.visitLdcInsn((long) (argsCount + 1)); - this.mv.visitInsn(L2I); - this.mv.visitTypeInsn(ANEWARRAY, OBJECT); - - int paramIndex = 1; - for (BIROperand arg : callIns.args) { - this.mv.visitInsn(DUP); - this.mv.visitLdcInsn((long) paramIndex); - this.mv.visitInsn(L2I); - - this.loadVar(arg.variableDcl); - // Add to the rest params array - jvmCastGen.addBoxInsn(this.mv, arg.variableDcl.type); - this.mv.visitInsn(AASTORE); - paramIndex += 1; - } - LambdaFunction lambdaFunction = asyncDataCollector.addAndGetLambda(callIns.name.value, callIns, true); JvmCodeGenUtil.createFunctionPointer(this.mv, lambdaFunction.enclosingClass, lambdaFunction.lambdaName); - boolean concurrent = false; + boolean isIsolated = false; String strandName = null; - // check for concurrent annotation + // check for isIsolated annotation if (!callIns.annotAttachments.isEmpty()) { for (BIRNode.BIRAnnotationAttachment annotationAttachment : callIns.annotAttachments) { if (annotationAttachment == null || @@ -922,19 +678,20 @@ private void genAsyncCallTerm(BIRTerminator.AsyncCall callIns, int localVarOffse Object strandAnnot = ((BIRNode.BIRConstAnnotationAttachment) annotationAttachment).annotValue.value; if (strandAnnot instanceof Map recordValue) { if (recordValue.containsKey(STRAND_THREAD)) { - if (STRAND_VALUE_ANY.equals(((BIRNode.ConstValue) recordValue.get(STRAND_THREAD)).value)) { - concurrent = true; + BIRNode.ConstValue constValue = (BIRNode.ConstValue) recordValue.get(STRAND_THREAD); + if (STRAND_VALUE_ANY.equals(constValue.value)) { + isIsolated = true; } } if (recordValue.containsKey(STRAND_NAME)) { - strandName = ((BIRNode.ConstValue) recordValue.get(STRAND_NAME)).value.toString(); - + BIRNode.ConstValue constValue = (BIRNode.ConstValue) recordValue.get(STRAND_NAME); + strandName = (String) constValue.value; } if (recordValue.containsKey(STRAND_POLICY_NAME)) { - if (!DEFAULT_STRAND_DISPATCHER.equals( - ((BIRNode.ConstValue) recordValue.get(STRAND_POLICY_NAME)).value)) { + BIRNode.ConstValue constValue = (BIRNode.ConstValue) recordValue.get(STRAND_POLICY_NAME); + if (!DEFAULT_STRAND_DISPATCHER.equals(constValue.value)) { throw new BLangCompilerException("Unsupported policy. Only 'DEFAULT' policy is " + "supported by jBallerina runtime."); } @@ -945,62 +702,71 @@ private void genAsyncCallTerm(BIRTerminator.AsyncCall callIns, int localVarOffse } this.mv.visitVarInsn(ALOAD, localVarOffset); loadFpReturnType(callIns.lhsOp); - String workerName = strandName; - if (workerName == null) { - if (callIns.lhsOp.variableDcl.metaVarName != null) { - this.mv.visitLdcInsn(callIns.lhsOp.variableDcl.metaVarName); - } else { - mv.visitInsn(ACONST_NULL); - } - } else { - this.mv.visitLdcInsn(workerName); - } + String workerName = strandName; + this.mv.visitLdcInsn(Objects.requireNonNullElseGet(workerName, + () -> Objects.requireNonNullElse(callIns.lhsOp.variableDcl.metaVarName, DEFAULT_STRAND_NAME))); + this.submitToScheduler(callIns.lhsOp, isIsolated, callIns, hasWorkers, + channelMapVarIndex); + } + + private void genPanicIfInLock(int localVarOffset) { + String lockStore = "L" + LOCK_STORE + ";"; + String initClassName = jvmPackageGen.lookupGlobalVarClassName(this.currentPackageName, LOCK_STORE_VAR_NAME); + this.mv.visitFieldInsn(GETSTATIC, initClassName, LOCK_STORE_VAR_NAME, lockStore); + this.mv.visitVarInsn(ALOAD, localVarOffset); + this.mv.visitMethodInsn(INVOKEVIRTUAL, LOCK_STORE, "panicIfInLock", PASS_STRAND, false); + } + + private void genAsyncCallArgs(BIRTerminator.AsyncCall callIns) { + // create an Object[] for the rest params + int argsCount = callIns.args.size(); + //create an object array of args + this.mv.visitLdcInsn((long) (argsCount + 1)); + this.mv.visitInsn(L2I); + this.mv.visitTypeInsn(ANEWARRAY, OBJECT); - this.submitToScheduler(callIns.lhsOp, attachedType, parentFunction, concurrent); + int paramIndex = 1; + for (BIROperand arg : callIns.args) { + this.mv.visitInsn(DUP); + this.mv.visitLdcInsn((long) paramIndex); + this.mv.visitInsn(L2I); + + this.loadVar(arg.variableDcl); + // Add to the rest params array + jvmCastGen.addBoxInsn(this.mv, arg.variableDcl.type); + this.mv.visitInsn(AASTORE); + paramIndex += 1; + } } private void generateWaitIns(BIRTerminator.Wait waitInst, int localVarOffset) { - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitTypeInsn(NEW, ARRAY_LIST); - this.mv.visitInsn(DUP); - this.mv.visitMethodInsn(INVOKESPECIAL, ARRAY_LIST, JVM_INIT_METHOD, VOID_METHOD_DESC, false); - - int i = 0; - while (i < waitInst.exprList.size()) { + if (waitInst.exprList.size() == 1) { + BIROperand futureVal = waitInst.exprList.getFirst(); + this.loadVar(futureVal.variableDcl); + this.mv.visitMethodInsn(INVOKESTATIC, ASYNC_UTILS, "handleWait", HANDLE_WAIT, false); + } else { + this.mv.visitTypeInsn(NEW, ARRAY_LIST); this.mv.visitInsn(DUP); - BIROperand futureVal = waitInst.exprList.get(i); - if (futureVal != null) { + this.mv.visitMethodInsn(INVOKESPECIAL, ARRAY_LIST, JVM_INIT_METHOD, VOID_METHOD_DESC, false); + + int i = 0; + while (i < waitInst.exprList.size()) { + this.mv.visitInsn(DUP); + BIROperand futureVal = waitInst.exprList.get(i); this.loadVar(futureVal.variableDcl); + this.mv.visitMethodInsn(INVOKEINTERFACE, LIST, ADD_METHOD, ANY_TO_JBOOLEAN, true); + this.mv.visitInsn(POP); + i += 1; } - this.mv.visitMethodInsn(INVOKEINTERFACE, LIST, ADD_METHOD, ANY_TO_JBOOLEAN, true); - this.mv.visitInsn(POP); - i += 1; + this.mv.visitMethodInsn(INVOKESTATIC, ASYNC_UTILS, "handleWaitAny", HANDLE_WAIT_ANY, false); } - - this.mv.visitMethodInsn(INVOKEVIRTUAL, STRAND_CLASS, "handleWaitAny", HANDLE_WAIT_ANY, false); - BIRNode.BIRVariableDcl tempVar = new BIRNode.BIRVariableDcl(symbolTable.anyType, new Name("waitResult"), - VarScope.FUNCTION, VarKind.ARG); - int resultIndex = this.getJVMIndexOfVarRef(tempVar); - this.mv.visitVarInsn(ASTORE, resultIndex); - - // assign result if result available - Label afterIf = new Label(); - this.mv.visitVarInsn(ALOAD, resultIndex); - this.mv.visitFieldInsn(GETFIELD, WAIT_RESULT, "done", "Z"); - this.mv.visitJumpInsn(IFEQ, afterIf); - Label withinIf = new Label(); - this.mv.visitLabel(withinIf); - this.mv.visitVarInsn(ALOAD, resultIndex); - this.mv.visitFieldInsn(GETFIELD, WAIT_RESULT, "result", - GET_OBJECT); + // assign result jvmCastGen.addUnboxInsn(this.mv, waitInst.lhsOp.variableDcl.type); this.storeToVar(waitInst.lhsOp.variableDcl); - this.mv.visitLabel(afterIf); } private void genWaitAllIns(BIRTerminator.WaitAll waitAll, int localVarOffset) { - this.mv.visitVarInsn(ALOAD, localVarOffset); this.mv.visitTypeInsn(NEW, HASH_MAP); this.mv.visitInsn(DUP); @@ -1017,37 +783,79 @@ private void genWaitAllIns(BIRTerminator.WaitAll waitAll, int localVarOffset) { this.mv.visitInsn(POP); i += 1; } - this.loadVar(waitAll.lhsOp.variableDcl); - this.mv.visitMethodInsn(INVOKEVIRTUAL, STRAND_CLASS, "handleWaitMultiple", HANDLE_WAIT_MULTIPLE, - false); + this.mv.visitMethodInsn(INVOKESTATIC, ASYNC_UTILS, "handleWaitMultiple", HANDLE_WAIT_MULTIPLE, false); } - private void genFPCallIns(BIRTerminator.FPCall fpCall, String moduleClassName, BType attachedType, - String funcName, int localVarOffset, int invocationVarIndex) { + private void genFPCallIns(BIRTerminator.FPCall fpCall, int localVarOffset, + boolean hasWorkers, int channelMapVarIndex) { if (fpCall.isAsync) { // Check if already locked before submitting to scheduler. - String lockStore = "L" + LOCK_STORE + ";"; - String initClassName = jvmPackageGen.lookupGlobalVarClassName(this.currentPackageName, LOCK_STORE_VAR_NAME); - this.mv.visitFieldInsn(GETSTATIC, initClassName, LOCK_STORE_VAR_NAME, lockStore); - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitMethodInsn(INVOKEVIRTUAL, LOCK_STORE, "panicIfInLock", PANIC_IF_IN_LOCK, false); - + genPanicIfInLock(localVarOffset); // Load the scheduler from strand this.mv.visitVarInsn(ALOAD, localVarOffset); this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "scheduler", GET_SCHEDULER); } else { // load function ref, going to directly call the fp this.loadVar(fpCall.fp.variableDcl); - this.mv.visitMethodInsn(INVOKEVIRTUAL, FUNCTION_POINTER, "getFunction", GET_FUNCTION, false); + this.mv.visitFieldInsn(GETFIELD, FUNCTION_POINTER, "function", GET_FUNCTION); } - boolean workerDerivative = fpCall.workerDerivative; - int argCount = fpCall.args.size() + 1; - if (workerDerivative) { - argCount++; + // if async, we submit this to scheduler (worker scenario) + if (fpCall.isAsync) { + String workerName = fpCall.lhsOp.variableDcl.metaVarName; + boolean isIsolated = false; + // check for isIsolated annotation + for (BIRNode.BIRAnnotationAttachment annotationAttachment : fpCall.annotAttachments) { + Object strandAnnot = ((BIRNode.BIRConstAnnotationAttachment) annotationAttachment).annotValue.value; + if (strandAnnot instanceof Map recordValue) { + if (recordValue.containsKey(STRAND_THREAD)) { + BIRNode.ConstValue constValue = (BIRNode.ConstValue) recordValue.get(STRAND_THREAD); + if (STRAND_VALUE_ANY.equals(constValue.value)) { + isIsolated = true; + } + } + if (recordValue.containsKey(STRAND_NAME)) { + BIRNode.ConstValue constValue = (BIRNode.ConstValue) recordValue.get(STRAND_NAME); + workerName = (String) constValue.value; + } + if (recordValue.containsKey(STRAND_POLICY_NAME)) { + BIRNode.ConstValue constValue = (BIRNode.ConstValue) recordValue.get(STRAND_POLICY_NAME); + if (!DEFAULT_STRAND_DISPATCHER.equals(constValue.value)) { + throw new BLangCompilerException("Unsupported policy. Only 'DEFAULT' policy is " + + "supported by jBallerina runtime."); + } + } + break; + } + } + // load function ref now + this.loadVar(fpCall.fp.variableDcl); + this.mv.visitVarInsn(ALOAD, localVarOffset); + loadFpReturnType(fpCall.lhsOp); + this.mv.visitLdcInsn(Objects.requireNonNullElse(workerName, DEFAULT_STRAND_NAME)); + this.submitToScheduler(fpCall.lhsOp, isIsolated, fpCall, localVarOffset, hasWorkers, channelMapVarIndex); + } else { + this.genFpCallArgs(fpCall, localVarOffset); + this.mv.visitMethodInsn(INVOKEINTERFACE, FUNCTION, "apply", PASS_OBJECT_RETURN_OBJECT, true); + // store result + BType lhsType = fpCall.lhsOp.variableDcl.type; + if (lhsType != null) { + jvmCastGen.addUnboxInsn(this.mv, lhsType); + } + + BIRNode.BIRVariableDcl lhsVar = fpCall.lhsOp.variableDcl; + if (lhsVar != null) { + this.storeToVar(lhsVar); + } else { + this.mv.visitInsn(POP); + } } + } + + private void genFpCallArgs(BIRTerminator.FPCall fpCall, int localVarOffset) { + int argCount = fpCall.args.size() + 1; // create an object array of args this.mv.visitIntInsn(BIPUSH, argCount); @@ -1061,13 +869,6 @@ private void genFPCallIns(BIRTerminator.FPCall fpCall, String moduleClassName, B this.mv.visitInsn(AASTORE); int paramIndex = 1; - if (workerDerivative) { - this.mv.visitInsn(DUP); - this.mv.visitIntInsn(BIPUSH, paramIndex++); - this.mv.visitVarInsn(ILOAD, invocationVarIndex); - this.mv.visitMethodInsn(INVOKESTATIC, INT_VALUE, VALUE_OF_METHOD, INT_VALUE_OF_METHOD, false); - this.mv.visitInsn(AASTORE); - } // load args for (BIROperand arg : fpCall.args) { @@ -1079,229 +880,125 @@ private void genFPCallIns(BIRTerminator.FPCall fpCall, String moduleClassName, B this.mv.visitInsn(AASTORE); paramIndex += 1; } - - // if async, we submit this to scheduler (worker scenario) - - if (fpCall.isAsync) { - String workerName = fpCall.lhsOp.variableDcl.metaVarName; - - // load function ref now - this.loadVar(fpCall.fp.variableDcl); - this.mv.visitMethodInsn(INVOKESTATIC, ANNOTATION_UTILS, "isConcurrent", IS_CONCURRENT, false); - Label notConcurrent = new Label(); - this.mv.visitJumpInsn(IFEQ, notConcurrent); - Label concurrent = new Label(); - this.mv.visitLabel(concurrent); - this.loadVar(fpCall.fp.variableDcl); - this.mv.visitVarInsn(ALOAD, localVarOffset); - loadFpReturnType(fpCall.lhsOp); - this.loadVar(fpCall.fp.variableDcl); - if (workerName == null) { - this.mv.visitInsn(ACONST_NULL); - } else { - this.mv.visitLdcInsn(workerName); - } - this.mv.visitMethodInsn(INVOKESTATIC, ANNOTATION_UTILS, "getStrandName", ANNOTATION_GET_STRAND, - false); - this.submitToScheduler(fpCall.lhsOp, attachedType, funcName, true); - Label afterSubmit = new Label(); - this.mv.visitJumpInsn(GOTO, afterSubmit); - this.mv.visitLabel(notConcurrent); - this.loadVar(fpCall.fp.variableDcl); - this.mv.visitVarInsn(ALOAD, localVarOffset); - loadFpReturnType(fpCall.lhsOp); - this.loadVar(fpCall.fp.variableDcl); - if (workerName == null) { - this.mv.visitInsn(ACONST_NULL); - } else { - this.mv.visitLdcInsn(workerName); - } - this.mv.visitMethodInsn(INVOKESTATIC, ANNOTATION_UTILS, "getStrandName", ANNOTATION_GET_STRAND, - false); - this.submitToScheduler(fpCall.lhsOp, attachedType, funcName, false); - this.mv.visitLabel(afterSubmit); - } else { - this.mv.visitMethodInsn(INVOKEINTERFACE, FUNCTION, "apply", - PASS_OBJECT_RETURN_OBJECT, true); - // store result - BType lhsType = fpCall.lhsOp.variableDcl.type; - if (lhsType != null) { - jvmCastGen.addUnboxInsn(this.mv, lhsType); - } - - BIRNode.BIRVariableDcl lhsVar = fpCall.lhsOp.variableDcl; - if (lhsVar != null) { - this.storeToVar(lhsVar); - } else { - this.mv.visitInsn(POP); - } - } } - private void genWorkerSendIns(BIRTerminator.WorkerSend ins, int localVarOffset, int invocationVarIndex) { - - this.mv.visitVarInsn(ALOAD, localVarOffset); - if (!ins.isSameStrand) { - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "parent", GET_STRAND); + private void genWorkerSendIns(BIRTerminator.WorkerSend ins, BIRNode.BIRFunction func, int channelMapVarIndex, + int localVarOffset) { + if (ins.isSync) { + mv.visitVarInsn(ALOAD, localVarOffset); } - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "wdChannels", GET_WD_CHANNELS); - this.mv.visitVarInsn(ILOAD, invocationVarIndex); - this.mv.visitInvokeDynamicInsn(MAKE_CONCAT_WITH_CONSTANTS, INT_TO_STRING, - new Handle(H_INVOKESTATIC, STRING_CONCAT_FACTORY, MAKE_CONCAT_WITH_CONSTANTS, - HANDLE_DESCRIPTOR_FOR_STRING_CONCAT, false), - ins.channel.value + START_OF_HEADING_WITH_SEMICOLON); - this.mv.visitMethodInsn(INVOKEVIRTUAL, WD_CHANNELS, "getWorkerDataChannel", GET_WORKER_DATA_CHANNEL, false); + JvmCodeGenUtil.loadWorkerChannelMap(this.mv, func, channelMapVarIndex, localVarOffset); + this.mv.visitLdcInsn(ins.channel.value); this.loadVar(ins.data.variableDcl); - jvmCastGen.addBoxInsn(this.mv, ins.data.variableDcl.type); - this.mv.visitVarInsn(ALOAD, localVarOffset); - - if (!ins.isSync) { - this.mv.visitMethodInsn(INVOKEVIRTUAL, WORKER_DATA_CHANNEL, "sendData", SEND_DATA, false); - } else { - this.mv.visitMethodInsn(INVOKEVIRTUAL, WORKER_DATA_CHANNEL, "syncSendData", - SYNC_SEND_DATA, false); + this.jvmCastGen.addBoxInsn(this.mv, ins.data.variableDcl.type); + if (ins.isSync) { + this.mv.visitMethodInsn(INVOKESTATIC, WORKER_UTILS, "syncSend", SYNC_SEND, false); BIROperand lhsOp = ins.lhsOp; if (lhsOp != null) { this.storeToVar(lhsOp.variableDcl); + } else { + this.mv.visitInsn(POP); } + } else { + this.mv.visitMethodInsn(INVOKESTATIC, WORKER_UTILS, "asyncSend", ASYNC_SEND, false); } } - private void genWorkerAlternateReceiveIns(BIRTerminator.WorkerAlternateReceive ins, int localVarOffset, - int invocationVarIndex) { - BIRNode.BIRVariableDcl listVar = new BIRNode.BIRVariableDcl(symbolTable.anyType, new Name("channels"), - VarScope.FUNCTION, VarKind.LOCAL); - int channelIndex = this.getJVMIndexOfVarRef(listVar); + private void genWorkerAlternateReceiveIns(BIRTerminator.WorkerAlternateReceive ins, BIRNode.BIRFunction func, + int channelMapVarIndex, int localVarOffset) { + this.mv.visitVarInsn(ALOAD, localVarOffset); + JvmCodeGenUtil.loadWorkerChannelMap(this.mv, func, channelMapVarIndex, localVarOffset); int channelSize = ins.channels.size(); this.mv.visitIntInsn(BIPUSH, channelSize); this.mv.visitTypeInsn(ANEWARRAY, STRING_VALUE); - int i = 0; - while (i < channelSize) { + int count = 0; + for (String channel : ins.channels) { this.mv.visitInsn(DUP); - this.mv.visitIntInsn(BIPUSH, i); - this.mv.visitVarInsn(ILOAD, invocationVarIndex); - this.mv.visitInvokeDynamicInsn(MAKE_CONCAT_WITH_CONSTANTS, INT_TO_STRING, - new Handle(H_INVOKESTATIC, STRING_CONCAT_FACTORY, MAKE_CONCAT_WITH_CONSTANTS, - HANDLE_DESCRIPTOR_FOR_STRING_CONCAT, false), - ins.channels.get(i) + START_OF_HEADING_WITH_SEMICOLON); + this.mv.visitIntInsn(BIPUSH, count++); + this.mv.visitLdcInsn(channel); this.mv.visitInsn(AASTORE); - i += 1; } - this.mv.visitVarInsn(ASTORE, channelIndex); - this.mv.visitVarInsn(ALOAD, localVarOffset); - if (!ins.isSameStrand) { - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "parent", GET_STRAND); - } - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "wdChannels", GET_WD_CHANNELS); - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitVarInsn(ALOAD, channelIndex); - this.mv.visitMethodInsn(INVOKEVIRTUAL, WD_CHANNELS, "receiveDataAlternateChannels", ALT_RECEIVE_CALL, false); - - generateReceiveResultStore(ins.lhsOp); + this.mv.visitMethodInsn(INVOKESTATIC, WORKER_UTILS, "alternateReceive", ALT_RECEIVE_CALL, false); + jvmCastGen.addUnboxInsn(this.mv, ins.lhsOp.variableDcl.type); + this.storeToVar(ins.lhsOp.variableDcl); } - private void genWorkerMultipleReceiveIns(BIRTerminator.WorkerMultipleReceive ins, int localVarOffset, - int invocationVarIndex) { - BIRNode.BIRVariableDcl listVar = new BIRNode.BIRVariableDcl(symbolTable.anyType, new Name("channels"), - VarScope.FUNCTION, VarKind.LOCAL); - int channelIndex = this.getJVMIndexOfVarRef(listVar); - int channelSize = ins.receiveFields.size(); - this.mv.visitIntInsn(BIPUSH, channelSize); - this.mv.visitTypeInsn(ANEWARRAY, RECEIVE_FIELD); - int i = 0; - while (i < channelSize) { - BIRTerminator.WorkerMultipleReceive.ReceiveField receiveField = ins.receiveFields.get(i); - this.mv.visitInsn(DUP); - this.mv.visitIntInsn(BIPUSH, i); - this.mv.visitTypeInsn(NEW, RECEIVE_FIELD); - this.mv.visitInsn(DUP); + private void genWorkerMultipleReceiveIns(BIRTerminator.WorkerMultipleReceive ins, BIRNode.BIRFunction func, + int channelMapVarIndex, int localVarOffset) { + + BIRNode.BIRVariableDcl mapVar = new BIRNode.BIRVariableDcl(symbolTable.anyType, + new Name(WORKER_CHANNEL_NAMES_MAP), VarScope.FUNCTION, VarKind.LOCAL); + int mapVarIndex = this.getJVMIndexOfVarRef(mapVar); + this.mv.visitTypeInsn(NEW, HASH_MAP); + this.mv.visitInsn(DUP); + this.mv.visitMethodInsn(INVOKESPECIAL, HASH_MAP, JVM_INIT_METHOD, VOID_METHOD_DESC, false); + this.mv.visitVarInsn(ASTORE, mapVarIndex); + + for (BIRTerminator.WorkerMultipleReceive.ReceiveField receiveField : ins.receiveFields) { + this.mv.visitVarInsn(ALOAD, mapVarIndex); this.mv.visitLdcInsn(receiveField.key()); - this.mv.visitVarInsn(ILOAD, invocationVarIndex); - this.mv.visitInvokeDynamicInsn(MAKE_CONCAT_WITH_CONSTANTS, INT_TO_STRING, - new Handle(H_INVOKESTATIC, STRING_CONCAT_FACTORY, MAKE_CONCAT_WITH_CONSTANTS, - HANDLE_DESCRIPTOR_FOR_STRING_CONCAT, false), - receiveField.workerReceive() + START_OF_HEADING_WITH_SEMICOLON); - this.mv.visitMethodInsn(INVOKESPECIAL, RECEIVE_FIELD, JVM_INIT_METHOD, INIT_RECEIVE_FIELD, false); - this.mv.visitInsn(AASTORE); - i += 1; - } - this.mv.visitVarInsn(ASTORE, channelIndex); - this.mv.visitVarInsn(ALOAD, localVarOffset); - if (!ins.isSameStrand) { - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "parent", GET_STRAND); + this.mv.visitLdcInsn(receiveField.workerReceive()); + this.mv.visitMethodInsn(INVOKEINTERFACE, MAP, "put", MAP_PUT, true); + this.mv.visitInsn(POP); } - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "wdChannels", GET_WD_CHANNELS); + this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitVarInsn(ALOAD, channelIndex); + JvmCodeGenUtil.loadWorkerChannelMap(this.mv, func, channelMapVarIndex, localVarOffset); + this.mv.visitVarInsn(ALOAD, mapVarIndex); jvmTypeGen.loadType(this.mv, ins.targetType); - this.mv.visitMethodInsn(INVOKEVIRTUAL, WD_CHANNELS, "receiveDataMultipleChannels", - MULTIPLE_RECEIVE_CALL, false); - generateReceiveResultStore(ins.lhsOp); + this.mv.visitMethodInsn(INVOKESTATIC, WORKER_UTILS, "multipleReceive", MULTIPLE_RECEIVE_CALL, false); + jvmCastGen.addUnboxInsn(this.mv, ins.lhsOp.variableDcl.type); + this.storeToVar(ins.lhsOp.variableDcl); } - private void genWorkerReceiveIns(BIRTerminator.WorkerReceive ins, int localVarOffset, int invocationVarIndex) { - + private void genWorkerReceiveIns(BIRTerminator.WorkerReceive ins, BIRNode.BIRFunction func, + int channelMapVarIndex, int localVarOffset) { this.mv.visitVarInsn(ALOAD, localVarOffset); - if (!ins.isSameStrand) { - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "parent", GET_STRAND); - } - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "wdChannels", GET_WD_CHANNELS); - this.mv.visitVarInsn(ILOAD, invocationVarIndex); - this.mv.visitInvokeDynamicInsn(MAKE_CONCAT_WITH_CONSTANTS, INT_TO_STRING, - new Handle(H_INVOKESTATIC, STRING_CONCAT_FACTORY, MAKE_CONCAT_WITH_CONSTANTS, - HANDLE_DESCRIPTOR_FOR_STRING_CONCAT, false), - ins.workerName.value + START_OF_HEADING_WITH_SEMICOLON); - this.mv.visitMethodInsn(INVOKEVIRTUAL, WD_CHANNELS, "getWorkerDataChannel", GET_WORKER_DATA_CHANNEL, false); + JvmCodeGenUtil.loadWorkerChannelMap(this.mv, func, channelMapVarIndex, localVarOffset); + this.mv.visitLdcInsn(ins.workerName.value); + this.mv.visitMethodInsn(INVOKESTATIC, WORKER_UTILS, "receive", RECEIVE_DATA, false); + jvmCastGen.addUnboxInsn(this.mv, ins.lhsOp.variableDcl.type); + this.storeToVar(ins.lhsOp.variableDcl); + } + private void genFlushIns(BIRTerminator.Flush ins, BIRNode.BIRFunction func, int channelMapVarIndex, + int localVarOffset) { this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitMethodInsn(INVOKEVIRTUAL, WORKER_DATA_CHANNEL, "tryTakeData", TRY_TAKE_DATA, false); - generateReceiveResultStore(ins.lhsOp); + JvmCodeGenUtil.loadWorkerChannelMap(this.mv, func, channelMapVarIndex, localVarOffset); + int channelSize = ins.channels.length; + this.mv.visitIntInsn(BIPUSH, channelSize); + this.mv.visitTypeInsn(ANEWARRAY, STRING_VALUE); + int count = 0; + for (BIRNode.ChannelDetails channelDetails : ins.channels) { + this.mv.visitInsn(DUP); + this.mv.visitIntInsn(BIPUSH, count++); + this.mv.visitLdcInsn(channelDetails.name); + this.mv.visitInsn(AASTORE); + } + this.mv.visitMethodInsn(INVOKESTATIC, WORKER_UTILS, "flush", HANDLE_FLUSH, false); + this.storeToVar(ins.lhsOp.variableDcl); } - private void generateReceiveResultStore(BIROperand ins) { - BIRNode.BIRVariableDcl tempVar = new BIRNode.BIRVariableDcl(symbolTable.anyType, new Name("wrkMsg"), - VarScope.FUNCTION, VarKind.ARG); - int wrkResultIndex = this.getJVMIndexOfVarRef(tempVar); - this.mv.visitVarInsn(ASTORE, wrkResultIndex); - - Label jumpAfterReceive = new Label(); - this.mv.visitVarInsn(ALOAD, wrkResultIndex); - this.mv.visitJumpInsn(IFNULL, jumpAfterReceive); - - Label withinReceiveSuccess = new Label(); - this.mv.visitLabel(withinReceiveSuccess); - this.mv.visitVarInsn(ALOAD, wrkResultIndex); - jvmCastGen.addUnboxInsn(this.mv, ins.variableDcl.type); - this.storeToVar(ins.variableDcl); - this.mv.visitLabel(jumpAfterReceive); + private void submitToScheduler(BIROperand lhsOp, boolean isIsolated, BIRTerminator.AsyncCall callIns, + boolean hasWorkers, int channelMapVarIndex) { + this.genWorkerChannelMapForCall(hasWorkers, channelMapVarIndex); + this.genAsyncCallArgs(callIns); + this.genStartFunctionCall(lhsOp, isIsolated); } - private void genFlushIns(BIRTerminator.Flush ins, int localVarOffset, int invocationVarIndex) { - - this.mv.visitVarInsn(ALOAD, localVarOffset); - JvmCodeGenUtil.loadChannelDetails(this.mv, Arrays.asList(ins.channels), invocationVarIndex); - this.mv.visitMethodInsn(INVOKEVIRTUAL, STRAND_CLASS, "handleFlush", - HANDLE_FLUSH, false); - this.storeToVar(ins.lhsOp.variableDcl); + private void submitToScheduler(BIROperand lhsOp, boolean isIsolated, BIRTerminator.FPCall fpCall, + int localVarOffset, boolean hasWorkers, int channelMapVarIndex) { + this.genWorkerChannelMapForCall(hasWorkers, channelMapVarIndex); + this.genFpCallArgs(fpCall, localVarOffset); + this.genStartFunctionCall(lhsOp, isIsolated); } - private void submitToScheduler(BIROperand lhsOp, BType attachedType, String parentFunction, boolean concurrent) { - - String metaDataVarName; - if (attachedType != null) { - metaDataVarName = setAndGetStrandMetadataVarName(attachedType.tsymbol.name.value, parentFunction, - asyncDataCollector); - } else { - metaDataVarName = JvmCodeGenUtil.setAndGetStrandMetadataVarName(parentFunction, asyncDataCollector); - } - this.mv.visitFieldInsn(GETSTATIC, this.strandMetadataClass, metaDataVarName, GET_STRAND_METADATA); - if (concurrent) { - mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, SCHEDULE_FUNCTION_METHOD, - SCHEDULE_FUNCTION, false); + private void genStartFunctionCall(BIROperand lhsOp, boolean isIsolated) { + if (isIsolated) { + this.mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, START_ISOLATED_WORKER, SCHEDULE_CALL, false); } else { - mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, SCHEDULE_LOCAL_METHOD, - SCHEDULE_LOCAL, false); + this.mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, START_NON_ISOLATED_WORKER, SCHEDULE_CALL, false); } // store return if (lhsOp.variableDcl != null) { @@ -1311,12 +1008,12 @@ private void submitToScheduler(BIROperand lhsOp, BType attachedType, String pare } } - private String setAndGetStrandMetadataVarName(String typeName, String parentFunction, - AsyncDataCollector asyncDataCollector) { - String metaDataVarName = STRAND_METADATA_VAR_PREFIX + typeName + "$" + parentFunction + "$"; - asyncDataCollector.getStrandMetadata().putIfAbsent(metaDataVarName, - new ScheduleFunctionInfo(typeName, parentFunction)); - return metaDataVarName; + private void genWorkerChannelMapForCall(boolean hasWorkers, int channelMapVarIndex) { + if (hasWorkers) { + this.mv.visitVarInsn(ALOAD, channelMapVarIndex); + } else { + this.mv.visitInsn(ACONST_NULL); + } } private void loadFpReturnType(BIROperand lhsOp) { @@ -1355,16 +1052,16 @@ private void genBundledFunctionArgs(List args) { private void genBundledArgs(List args, int argsArrayIndex, int bundledArrayIndex, String fieldName, boolean isFromPathArgs) { - mv.visitLdcInsn((long) args.size()); - mv.visitInsn(L2I); - mv.visitTypeInsn(ANEWARRAY, OBJECT); - mv.visitVarInsn(ASTORE, argsArrayIndex); + this.mv.visitLdcInsn((long) args.size()); + this.mv.visitInsn(L2I); + this.mv.visitTypeInsn(ANEWARRAY, OBJECT); + this.mv.visitVarInsn(ASTORE, argsArrayIndex); int i = 0; for (BIROperand arg : args) { - mv.visitVarInsn(ALOAD, argsArrayIndex); - mv.visitLdcInsn((long) i); - mv.visitInsn(L2I); + this.mv.visitVarInsn(ALOAD, argsArrayIndex); + this.mv.visitLdcInsn((long) i); + this.mv.visitInsn(L2I); this.loadVar(arg.variableDcl); if (isFromPathArgs) { // Add CheckCast instruction for path args. @@ -1373,53 +1070,32 @@ private void genBundledArgs(List args, int argsArrayIndex, int bundl // Add Box instruction if the type is a value type. jvmCastGen.addBoxInsn(mv, arg.variableDcl.type); } - mv.visitInsn(AASTORE); + this.mv.visitInsn(AASTORE); i++; } - mv.visitTypeInsn(NEW, ARRAY_VALUE_IMPL); - mv.visitInsn(DUP); - mv.visitVarInsn(ALOAD, argsArrayIndex); - mv.visitFieldInsn(GETSTATIC, PREDEFINED_TYPES, fieldName, LOAD_ARRAY_TYPE); - mv.visitMethodInsn(INVOKESPECIAL, ARRAY_VALUE_IMPL, JVM_INIT_METHOD, INIT_ANYDATA_ARRAY, false); - mv.visitVarInsn(ASTORE, bundledArrayIndex); - mv.visitVarInsn(ALOAD, bundledArrayIndex); - } - - public void genReturnTerm(int returnVarRefIndex, BIRNode.BIRFunction func, int invocationVarIndex, - int localVarOffset) { - if (func.workerChannels != null) { - Set uniqueValues = new HashSet<>(); - for (BIRNode.ChannelDetails channel : func.workerChannels) { - if (uniqueValues.add(channel)) { - this.mv.visitVarInsn(ALOAD, localVarOffset); - if (Symbols.isFlagOn(func.flags, Flags.WORKER)) { - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "parent", GET_STRAND); - } - this.mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "wdChannels", GET_WD_CHANNELS); - this.mv.visitVarInsn(ALOAD, localVarOffset); - this.mv.visitVarInsn(ILOAD, invocationVarIndex); - this.mv.visitInvokeDynamicInsn(MAKE_CONCAT_WITH_CONSTANTS, INT_TO_STRING, - new Handle(H_INVOKESTATIC, STRING_CONCAT_FACTORY, MAKE_CONCAT_WITH_CONSTANTS, - HANDLE_DESCRIPTOR_FOR_STRING_CONCAT, false), channel.name - + START_OF_HEADING_WITH_SEMICOLON); - this.mv.visitMethodInsn(INVOKEVIRTUAL, WD_CHANNELS, "removeCompletedChannels", - REMOVE_WORKER_DATA_CHANNEL, false); - } - } - } - BType bType = unifier.build(func.type.retType); - generateReturnTermFromType(returnVarRefIndex, bType, func, invocationVarIndex, localVarOffset); + this.mv.visitTypeInsn(NEW, ARRAY_VALUE_IMPL); + this.mv.visitInsn(DUP); + this.mv.visitVarInsn(ALOAD, argsArrayIndex); + this.mv.visitFieldInsn(GETSTATIC, PREDEFINED_TYPES, fieldName, LOAD_ARRAY_TYPE); + this.mv.visitMethodInsn(INVOKESPECIAL, ARRAY_VALUE_IMPL, JVM_INIT_METHOD, INIT_ANYDATA_ARRAY, false); + this.mv.visitVarInsn(ASTORE, bundledArrayIndex); + this.mv.visitVarInsn(ALOAD, bundledArrayIndex); } - private void generateReturnTermFromType(int returnVarRefIndex, BType bType, BIRNode.BIRFunction func, - int invocationVarIndex, int localVarOffset) { + private void generateReturnTermFromType(BType bType, BIRNode.BIRFunction func, int returnVarRefIndex, + int channelMapVarIndex, int sendWorkerChannelNamesVar, + int receiveWorkerChannelNamesVar, int localVarOffset) { bType = JvmCodeGenUtil.getImpliedType(bType); if (TypeTags.isIntegerTypeTag(bType.tag)) { + handleWorkerReturn(func, channelMapVarIndex, sendWorkerChannelNamesVar, receiveWorkerChannelNamesVar, + localVarOffset); this.mv.visitVarInsn(LLOAD, returnVarRefIndex); this.mv.visitInsn(LRETURN); return; } else if (TypeTags.isStringTypeTag(bType.tag) || TypeTags.isXMLTypeTag(bType.tag) || TypeTags.REGEXP == bType.tag) { + handleWorkerReturn(func, channelMapVarIndex, sendWorkerChannelNamesVar, receiveWorkerChannelNamesVar, + localVarOffset); this.mv.visitVarInsn(ALOAD, returnVarRefIndex); this.mv.visitInsn(ARETURN); return; @@ -1427,28 +1103,29 @@ private void generateReturnTermFromType(int returnVarRefIndex, BType bType, BIRN switch (bType.tag) { case TypeTags.NIL, TypeTags.NEVER, TypeTags.MAP, TypeTags.ARRAY, TypeTags.ANY, TypeTags.STREAM, - TypeTags.TABLE, TypeTags.ANYDATA, TypeTags.OBJECT, TypeTags.DECIMAL, TypeTags.RECORD, - TypeTags.TUPLE, TypeTags.JSON, TypeTags.FUTURE, TypeTags.INVOKABLE, TypeTags.HANDLE, - TypeTags.FINITE, TypeTags.TYPEDESC, TypeTags.READONLY -> { + TypeTags.TABLE, TypeTags.ANYDATA, TypeTags.OBJECT, TypeTags.DECIMAL, TypeTags.RECORD, + TypeTags.TUPLE, TypeTags.JSON, TypeTags.FUTURE, TypeTags.INVOKABLE, TypeTags.HANDLE, + TypeTags.FINITE, TypeTags.TYPEDESC, TypeTags.READONLY -> { + handleWorkerReturn(func, channelMapVarIndex, sendWorkerChannelNamesVar, receiveWorkerChannelNamesVar, + localVarOffset); this.mv.visitVarInsn(ALOAD, returnVarRefIndex); this.mv.visitInsn(ARETURN); } case TypeTags.BYTE, TypeTags.BOOLEAN -> { + handleWorkerReturn(func, channelMapVarIndex, sendWorkerChannelNamesVar, receiveWorkerChannelNamesVar, + localVarOffset); this.mv.visitVarInsn(ILOAD, returnVarRefIndex); this.mv.visitInsn(IRETURN); } case TypeTags.FLOAT -> { + handleWorkerReturn(func, channelMapVarIndex, sendWorkerChannelNamesVar, receiveWorkerChannelNamesVar, + localVarOffset); this.mv.visitVarInsn(DLOAD, returnVarRefIndex); this.mv.visitInsn(DRETURN); } - case TypeTags.UNION -> { - this.handleErrorRetInUnion(returnVarRefIndex, Arrays.asList(func.workerChannels), - (BUnionType) bType, invocationVarIndex, localVarOffset); - this.mv.visitVarInsn(ALOAD, returnVarRefIndex); - this.mv.visitInsn(ARETURN); - } - case TypeTags.ERROR -> { - this.notifyChannels(Arrays.asList(func.workerChannels), returnVarRefIndex, invocationVarIndex); + case TypeTags.UNION, TypeTags.ERROR -> { + handleWorkerReturnWithError(func, returnVarRefIndex, channelMapVarIndex, sendWorkerChannelNamesVar, + receiveWorkerChannelNamesVar, localVarOffset); this.mv.visitVarInsn(ALOAD, returnVarRefIndex); this.mv.visitInsn(ARETURN); } @@ -1457,7 +1134,32 @@ private void generateReturnTermFromType(int returnVarRefIndex, BType bType, BIRN } } - public LabelGenerator getLabelGenerator() { - return this.labelGen; + private void handleWorkerReturn(BIRNode.BIRFunction func, int channelMapVarIndex, int sendWorkerChannelNamesVar, + int receiveWorkerChannelNamesVar, int localVarOffset) { + if (func.workerChannels.length == 0) { + return; + } + JvmCodeGenUtil.loadWorkerChannelMap(this.mv, func, channelMapVarIndex, localVarOffset); + mv.visitInsn(Opcodes.ACONST_NULL); + handleWorkerReturn(sendWorkerChannelNamesVar, receiveWorkerChannelNamesVar); + } + + private void handleWorkerReturnWithError(BIRNode.BIRFunction func, int returnVarRefIndex, int channelMapVarIndex, + int sendWorkerChannelNamesVar, int receiveWorkerChannelNamesVar, + int localVarOffset) { + if (func.workerChannels.length == 0) { + return; + } + JvmCodeGenUtil.loadWorkerChannelMap(this.mv, func, channelMapVarIndex, localVarOffset); + this.mv.visitVarInsn(ALOAD, returnVarRefIndex); + handleWorkerReturn(sendWorkerChannelNamesVar, receiveWorkerChannelNamesVar); + + } + + private void handleWorkerReturn(int sendWorkerChannelNamesVar, int receiveWorkerChannelNamesVar) { + this.mv.visitVarInsn(ALOAD, sendWorkerChannelNamesVar); + this.mv.visitVarInsn(ALOAD, receiveWorkerChannelNamesVar); + this.mv.visitMethodInsn(INVOKESTATIC, WORKER_UTILS, WORKER_CHANNELS_COMPLETE_METHOD, + WORKER_CHANNELS_COMPLETE, false); } } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java index e6d31db01347..491a1fa6b564 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmTypeGen.java @@ -97,6 +97,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUNCTION_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUTURE_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.GET_ANON_TYPE_METHOD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.GET_FUNCTION_TYPE_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.INTERSECTION_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.INT_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; @@ -106,6 +107,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_ANON_TYPES_CLASS_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_ERRORS_CREATOR_CLASS_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_FUNCTION_CALLS_CLASS_NAME; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_FUNCTION_TYPES_CLASS_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_INIT_CLASS_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_OBJECTS_CREATOR_CLASS_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_RECORDS_CREATOR_CLASS_NAME; @@ -135,6 +137,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_ERROR_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_ERROR_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_FUNCTION_POINTER; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_FUNCTION_TYPE_FOR_STRING; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_FUTURE_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_HANDLE_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MAP_VALUE; @@ -147,6 +150,7 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TYPEDESC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TYPE_REF_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_XML; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_CLASS_CONSTRUCTOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_FINITE_TYPE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_FUNCTION_PARAM; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_FUNCTION_TYPE_IMPL; @@ -196,6 +200,7 @@ public class JvmTypeGen { private final SymbolTable symbolTable; private final PackageID packageID; private final String anonTypesClass; + private final String functionTypesClass; private final String recordsClass; private final String objectsClass; private final String errorsClass; @@ -210,6 +215,7 @@ public JvmTypeGen(JvmConstantsGen jvmConstantsGen, PackageID packageID, TypeHash this.typeHashVisitor = typeHashVisitor; this.symbolTable = symbolTable; this.anonTypesClass = getModuleLevelClassName(packageID, MODULE_ANON_TYPES_CLASS_NAME); + this.functionTypesClass = getModuleLevelClassName(packageID, MODULE_FUNCTION_TYPES_CLASS_NAME); this.recordsClass = getModuleLevelClassName(packageID, MODULE_RECORDS_CREATOR_CLASS_NAME); this.objectsClass = getModuleLevelClassName(packageID, MODULE_OBJECTS_CREATOR_CLASS_NAME); this.errorsClass = getModuleLevelClassName(packageID, MODULE_ERRORS_CREATOR_CLASS_NAME); @@ -250,10 +256,14 @@ private void generateTypedescField(ClassWriter cw, String name) { } // ------------------------------------------------------- - // getAnonType() generation methods + // getType() generation methods // ------------------------------------------------------- - void generateGetAnonTypeMethod(ClassWriter cw, String moduleClass) { + void generateGetTypeMethod(ClassWriter cw, String moduleClass) { + generateGetAnonTypeMethod(cw, moduleClass); + generateGetFunctionTypeMethod(cw); + } + void generateGetAnonTypeMethod(ClassWriter cw, String moduleClass) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, GET_ANON_TYPE_METHOD, JvmSignatures.GET_ANON_TYPE, null, null); mv.visitCode(); @@ -265,6 +275,18 @@ void generateGetAnonTypeMethod(ClassWriter cw, String moduleClass) { mv.visitEnd(); } + void generateGetFunctionTypeMethod(ClassWriter cw) { + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, GET_FUNCTION_TYPE_METHOD, GET_FUNCTION_TYPE_FOR_STRING, null, + null); + mv.visitCode(); + mv.visitVarInsn(ALOAD, 1); + mv.visitMethodInsn(INVOKESTATIC, functionTypesClass, GET_FUNCTION_TYPE_METHOD, GET_FUNCTION_TYPE_FOR_STRING, + false); + mv.visitInsn(ARETURN); + mv.visitMaxs(0, 0); + mv.visitEnd(); + } + // ------------------------------------------------------- // Runtime value creation methods // ------------------------------------------------------- @@ -294,8 +316,6 @@ private void generateObjectValueCreateMethod(ClassWriter cw, String moduleClass) mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 3); - mv.visitVarInsn(ALOAD, 4); - mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn(INVOKESTATIC, objectsClass, CREATE_OBJECT_VALUE, CREATE_OBJECT, false); mv.visitInsn(ARETURN); JvmCodeGenUtil.visitMaxStackForMethod(mv, CREATE_OBJECT_VALUE, moduleClass); @@ -802,7 +822,8 @@ private void loadUserDefinedType(MethodVisitor mv, BType bType) { mv.visitTypeInsn(NEW, typeOwner); mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, typeOwner, JVM_INIT_METHOD, VOID_METHOD_DESC, false); + mv.visitInsn(ACONST_NULL); + mv.visitMethodInsn(INVOKESPECIAL, typeOwner, JVM_INIT_METHOD, INIT_CLASS_CONSTRUCTOR, false); mv.visitLdcInsn(hash); mv.visitLdcInsn("Package: " + typeOwner + ", TypeName: " + fieldName + ", Shape: " + shape); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmValueGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmValueGen.java index f0802f68060d..7d97b9ab36c9 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmValueGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/JvmValueGen.java @@ -68,7 +68,7 @@ import static org.objectweb.asm.Opcodes.PUTFIELD; import static org.objectweb.asm.Opcodes.RETURN; import static org.objectweb.asm.Opcodes.SWAP; -import static org.objectweb.asm.Opcodes.V17; +import static org.objectweb.asm.Opcodes.V21; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.toNameString; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ABSTRACT_OBJECT_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ANNOTATIONS_FIELD; @@ -77,7 +77,6 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CLASS_FILE_SUFFIX; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.INSTANTIATE_FUNCTION; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LOCK_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAP_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAP_VALUE_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAX_METHOD_COUNT_PER_BALLERINA_OBJECT; @@ -93,7 +92,6 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.UNSUPPORTED_OPERATION_EXCEPTION; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.VALUE_CLASS_PREFIX; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmDesugarPhase.addDefaultableBooleanVarsToSignature; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmPackageGen.computeLockNameFromString; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.CAST_B_MAPPING_INITIAL_VALUE_ENTRY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MAP_ARRAY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MAP_VALUE; @@ -201,8 +199,7 @@ void generateValueClasses(JarEntries jarEntries, JvmConstantsGen jvmConstantsGen asyncDataCollector, jarEntries); } else if (bType.tag == TypeTags.RECORD) { BRecordType recordType = (BRecordType) bType; - byte[] bytes = this.createRecordValueClass(recordType, className, optionalTypeDef, - asyncDataCollector, jvmTypeGen); + byte[] bytes = this.createRecordValueClass(recordType, className, optionalTypeDef, jvmTypeGen); jarEntries.put(className + CLASS_FILE_SUFFIX, bytes); String typedescClass = getTypeDescClassName(packageName, optionalTypeDef.internalName.value); bytes = this.createRecordTypeDescClass(recordType, typedescClass, optionalTypeDef, jvmTypeGen); @@ -221,7 +218,7 @@ private byte[] createRecordTypeDescClass(BRecordType recordType, String classNam } else { cw.visitSource(className, null); } - cw.visit(V17, ACC_PUBLIC + ACC_SUPER, className, null, TYPEDESC_VALUE_IMPL, new String[]{TYPEDESC_VALUE}); + cw.visit(V21, ACC_PUBLIC + ACC_SUPER, className, null, TYPEDESC_VALUE_IMPL, new String[]{TYPEDESC_VALUE}); FieldVisitor fv = cw.visitField(0, ANNOTATIONS_FIELD, GET_MAP_VALUE, null, null); fv.visitEnd(); @@ -297,7 +294,7 @@ public static String getTypeValueClassName(PackageID packageID, String typeName) } private byte[] createRecordValueClass(BRecordType recordType, String className, BIRNode.BIRTypeDefinition typeDef, - AsyncDataCollector asyncDataCollector, JvmTypeGen jvmTypeGen) { + JvmTypeGen jvmTypeGen) { ClassWriter cw = new BallerinaClassWriter(COMPUTE_FRAMES); if (typeDef.pos != null) { cw.visitSource(typeDef.pos.lineRange().fileName(), null); @@ -305,7 +302,7 @@ private byte[] createRecordValueClass(BRecordType recordType, String className, cw.visitSource(className, null); } JvmCastGen jvmCastGen = new JvmCastGen(jvmPackageGen.symbolTable, jvmTypeGen, types); - cw.visit(V17, ACC_PUBLIC + ACC_SUPER + ACC_FINAL, className, RECORD_VALUE_CLASS, MAP_VALUE_IMPL, + cw.visit(V21, ACC_PUBLIC + ACC_SUPER + ACC_FINAL, className, RECORD_VALUE_CLASS, MAP_VALUE_IMPL, new String[]{MAP_VALUE}); Map fields = recordType.fields; @@ -462,7 +459,7 @@ private void createObjectValueClasses(BObjectType objectType, String className, SymbolTable symbolTable = jvmPackageGen.symbolTable; JvmTypeGen jvmTypeGen = new JvmTypeGen(jvmConstantsGen, module.packageID, typeHashVisitor, symbolTable); JvmCastGen jvmCastGen = new JvmCastGen(symbolTable, jvmTypeGen, types); - cw.visit(V17, ACC_PUBLIC + ACC_SUPER, className, null, ABSTRACT_OBJECT_VALUE, new String[]{B_OBJECT}); + cw.visit(V21, ACC_PUBLIC + ACC_SUPER, className, null, ABSTRACT_OBJECT_VALUE, new String[]{B_OBJECT}); Map fields = objectType.fields; this.createObjectFields(cw, fields); @@ -476,7 +473,7 @@ private void createObjectValueClasses(BObjectType objectType, String className, jvmConstantsGen, asyncDataCollector); } - this.createObjectInit(cw, fields, className); + this.createObjectInit(cw); jvmObjectGen.createAndSplitCallMethod(cw, attachedFuncs, className, jvmCastGen); jvmObjectGen.createAndSplitGetMethod(cw, fields, className, jvmCastGen); jvmObjectGen.createAndSplitSetMethod(cw, fields, className, jvmCastGen); @@ -492,10 +489,6 @@ private void createObjectFields(ClassWriter cw, Map fields) { } FieldVisitor fvb = cw.visitField(0, field.name.value, getTypeDesc(field.type), null, null); fvb.visitEnd(); - String lockClass = "L" + LOCK_VALUE + ";"; - FieldVisitor fv = cw.visitField(ACC_PUBLIC, computeLockNameFromString(field.name.value), - lockClass, null, null); - fv.visitEnd(); } } @@ -519,7 +512,7 @@ private void createObjectMethodsWithSplitClasses(ClassWriter cw, List fields, String className) { + private void createObjectInit(ClassWriter cw) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, JVM_INIT_METHOD, OBJECT_TYPE_IMPL_INIT, null, null); @@ -566,22 +559,6 @@ private void createObjectInit(ClassWriter cw, Map fields, String mv.visitVarInsn(ALOAD, 1); // invoke super(type); mv.visitMethodInsn(INVOKESPECIAL, ABSTRACT_OBJECT_VALUE, JVM_INIT_METHOD, OBJECT_TYPE_IMPL_INIT, false); - - String lockClass = "L" + LOCK_VALUE + ";"; - for (BField field : fields.values()) { - if (field == null) { - continue; - } - - Label fLabel = new Label(); - mv.visitLabel(fLabel); - mv.visitVarInsn(ALOAD, 0); - mv.visitTypeInsn(NEW, LOCK_VALUE); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, LOCK_VALUE, JVM_INIT_METHOD, VOID_METHOD_DESC, false); - mv.visitFieldInsn(PUTFIELD, className, computeLockNameFromString(field.name.value), lockClass); - } - mv.visitInsn(RETURN); mv.visitMaxs(5, 5); mv.visitEnd(); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/ShutDownListenerGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/ShutDownListenerGen.java index 440ca2ee2b2c..aa2aed5f28ee 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/ShutDownListenerGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/ShutDownListenerGen.java @@ -32,14 +32,15 @@ import static org.objectweb.asm.Opcodes.INVOKESTATIC; import static org.objectweb.asm.Opcodes.PUTFIELD; import static org.objectweb.asm.Opcodes.RETURN; -import static org.objectweb.asm.Opcodes.V17; +import static org.objectweb.asm.Opcodes.V21; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BAL_RUNTIME_VAR_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CLASS_FILE_SUFFIX; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_STOP; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_STOP_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JAVA_THREAD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RUNTIME_REGISTRY_VARIABLE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_RUNTIME_REGISTRY; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_RUNTIME_REGISTRY; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.CURRENT_MODULE_STOP; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_BAL_RUNTIME; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_SIGNAL_LISTENER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VOID_METHOD_DESC; /** @@ -52,9 +53,8 @@ public class ShutDownListenerGen { void generateShutdownSignalListener(String initClass, JarEntries jarEntries) { String innerClassName = initClass + "$SignalListener"; ClassWriter cw = new BallerinaClassWriter(COMPUTE_FRAMES); - cw.visit(V17, ACC_SUPER, innerClassName, null, JAVA_THREAD, null); - FieldVisitor fv = cw.visitField(ACC_PRIVATE, RUNTIME_REGISTRY_VARIABLE, - GET_RUNTIME_REGISTRY, null, null); + cw.visit(V21, ACC_SUPER, innerClassName, null, JAVA_THREAD, null); + FieldVisitor fv = cw.visitField(ACC_PRIVATE, BAL_RUNTIME_VAR_NAME, GET_BAL_RUNTIME, null, null); fv.visitEnd(); // create constructor @@ -68,13 +68,13 @@ void generateShutdownSignalListener(String initClass, JarEntries jarEntries) { } private void genConstructor(String innerClassName, ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, JVM_INIT_METHOD, INIT_RUNTIME_REGISTRY, null, null); + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, JVM_INIT_METHOD, INIT_SIGNAL_LISTENER, null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); mv.visitMethodInsn(INVOKESPECIAL, JAVA_THREAD, JVM_INIT_METHOD, VOID_METHOD_DESC, false); mv.visitVarInsn(ALOAD, 0); mv.visitVarInsn(ALOAD, 1); - mv.visitFieldInsn(PUTFIELD, innerClassName, RUNTIME_REGISTRY_VARIABLE, GET_RUNTIME_REGISTRY); + mv.visitFieldInsn(PUTFIELD, innerClassName, BAL_RUNTIME_VAR_NAME, GET_BAL_RUNTIME); mv.visitInsn(RETURN); JvmCodeGenUtil.visitMaxStackForMethod(mv, JVM_INIT_METHOD, innerClassName); mv.visitEnd(); @@ -83,11 +83,9 @@ private void genConstructor(String innerClassName, ClassWriter cw) { private void genRunMethod(String initClass, String innerClassName, ClassWriter cw) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "run", VOID_METHOD_DESC, null, null); mv.visitCode(); - // Create a scheduler. A new scheduler is used here, to make the stop function to not - // depend/wait on whatever is being running on the background. eg: a busy loop in the main. mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, innerClassName, RUNTIME_REGISTRY_VARIABLE, GET_RUNTIME_REGISTRY); - mv.visitMethodInsn(INVOKESTATIC, initClass, CURRENT_MODULE_STOP, JvmSignatures.CURRENT_MODULE_STOP, false); + mv.visitFieldInsn(GETFIELD, innerClassName, BAL_RUNTIME_VAR_NAME, GET_BAL_RUNTIME); + mv.visitMethodInsn(INVOKESTATIC, initClass, CURRENT_MODULE_STOP_METHOD, CURRENT_MODULE_STOP, false); mv.visitInsn(RETURN); JvmCodeGenUtil.visitMaxStackForMethod(mv, "run", innerClassName); mv.visitEnd(); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/internal/AsyncDataCollector.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/internal/AsyncDataCollector.java index 75fd86acb445..f69ec5a07e53 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/internal/AsyncDataCollector.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/internal/AsyncDataCollector.java @@ -38,7 +38,6 @@ public class AsyncDataCollector { private final Map lambdas; - private final Map strandMetaDataMap; private final PackageID packageID; private String currentSourceFileWithoutExt = null; private String currentSourceFileName = null; @@ -47,7 +46,6 @@ public class AsyncDataCollector { public AsyncDataCollector(BIRNode.BIRPackage module) { this.lambdas = new HashMap<>(); - this.strandMetaDataMap = new HashMap<>(); this.packageID = module.packageID; } @@ -87,8 +85,4 @@ public void setCurrentSourceFileName(String currentSourceFileName) { public void setCurrentSourceFileWithoutExt(String currentSourceFileWithoutExt) { this.currentSourceFileWithoutExt = currentSourceFileWithoutExt; } - - public Map getStrandMetadata() { - return strandMetaDataMap; - } } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/InteropMethodGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/InteropMethodGen.java index 4d30424e3221..0b2d373cf1e9 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/InteropMethodGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/InteropMethodGen.java @@ -175,7 +175,7 @@ static void genJFieldForInteropField(JFieldBIRFunction birFunc, ClassWriter clas // Load receiver which is the 0th parameter in the birFunc if (!jField.isStatic()) { - BIRNode.BIRVariableDcl var = birFuncParams.get(0); + BIRNode.BIRVariableDcl var = birFuncParams.getFirst(); int receiverLocalVarIndex = indexMap.addIfNotExists(var.name.value, var.type); mv.visitVarInsn(ALOAD, receiverLocalVarIndex); mv.visitMethodInsn(INVOKEVIRTUAL, HANDLE_VALUE, GET_VALUE_METHOD, "()Ljava/lang/Object;", false); @@ -252,7 +252,7 @@ static void genJFieldForInteropField(JFieldBIRFunction birFunc, ClassWriter clas Label retLabel = labelGen.getLabel("return_lable"); mv.visitLabel(retLabel); mv.visitLineNumber(birFunc.pos.lineRange().endLine().line() + 1, retLabel); - termGen.genReturnTerm(returnVarRefIndex, birFunc, -1, 0); + termGen.genReturnTerm(returnVarRefIndex, birFunc, -1, -1, -1, -1); JvmCodeGenUtil.visitMaxStackForMethod(mv, birFunc.name.value, birFunc.javaField.getDeclaringClassName()); mv.visitEnd(); } @@ -377,9 +377,9 @@ public static void desugarInteropFuncs(JMethodBIRFunction birFunc, InitMethodGen BIRBasicBlock thenBB = insertAndGetNextBasicBlock(birFunc.basicBlocks, initMethodGen); BIRBasicBlock retBB = new BIRBasicBlock(getNextDesugarBBId(initMethodGen)); thenBB.terminator = new BIRTerminator.GOTO(birFunc.pos, retBB); + BIROperand retRef = new BIROperand(birFunc.localVars.getFirst()); if (JvmCodeGenUtil.getImpliedType(retType).tag != TypeTags.NIL) { - BIROperand retRef = new BIROperand(birFunc.localVars.get(0)); if (JType.J_VOID != jMethodRetType) { BIRVariableDcl retJObjectVarDcl = new BIRVariableDcl(jMethodRetType, new Name("$_ret_jobject_var_$"), null, VarKind.LOCAL); @@ -392,19 +392,17 @@ public static void desugarInteropFuncs(JMethodBIRFunction birFunc, InitMethodGen jToBCast.targetType = retType; thenBB.instructions.add(jToBCast); } - - BIRBasicBlock catchBB = new BIRBasicBlock(getNextDesugarBBId(initMethodGen)); - JErrorEntry ee = new JErrorEntry(beginBB, thenBB, retRef, catchBB); - for (Class exception : birFunc.jMethod.getExceptionTypes()) { - BIRTerminator.Return exceptionRet = new BIRTerminator.Return(birFunc.pos); - CatchIns catchIns = new CatchIns(); - catchIns.errorClass = exception.getName().replace(".", "/"); - catchIns.term = exceptionRet; - ee.catchIns.add(catchIns); - } - - birFunc.errorTable.add(ee); } + BIRBasicBlock catchBB = new BIRBasicBlock(getNextDesugarBBId(initMethodGen)); + JErrorEntry ee = new JErrorEntry(beginBB, thenBB, retRef, catchBB); + for (Class exception : birFunc.jMethod.getExceptionTypes()) { + BIRTerminator.Return exceptionRet = new BIRTerminator.Return(birFunc.pos); + CatchIns catchIns = new CatchIns(); + catchIns.errorClass = exception.getName().replace(".", "/"); + catchIns.term = exceptionRet; + ee.catchIns.add(catchIns); + } + birFunc.errorTable.add(ee); // We may be able to use the same instruction rather than two, check later if (jMethod.kind == JMethodKind.CONSTRUCTOR) { diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/InteropValidator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/InteropValidator.java index ccee37a09242..59be56de92d3 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/InteropValidator.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/InteropValidator.java @@ -292,7 +292,7 @@ void validateJInstanceField(JFieldMethod method, List bFuncParamTypes, St throw new JInteropException(DiagnosticErrorCode.INVALID_NUMBER_OF_PARAMETERS, "Two parameters are required to set the value to the instance field '" + fieldName + "' in class '" + className + "'"); - } else if (bFuncParamTypes.get(0).tag != TypeTags.HANDLE) { + } else if (bFuncParamTypes.getFirst().tag != TypeTags.HANDLE) { throw new JInteropException(DiagnosticErrorCode.INVALID_PARAMETER_TYPE, "First parameter needs " + "to be of the handle type to set the value to the instance field '" + fieldName + "' in class '" + className + "'"); @@ -302,7 +302,7 @@ void validateJInstanceField(JFieldMethod method, List bFuncParamTypes, St throw new JInteropException(DiagnosticErrorCode.INVALID_NUMBER_OF_PARAMETERS, "One parameter is required to get the value of the instance field '" + fieldName + "' in class '" + className + "'"); - } else if (bFuncParamTypes.get(0).tag != TypeTags.HANDLE) { + } else if (bFuncParamTypes.getFirst().tag != TypeTags.HANDLE) { throw new JInteropException(DiagnosticErrorCode.INVALID_PARAMETER_TYPE, "The parameter needs " + "to be of the handle type to get the value of the instance field '" + fieldName + "' in class '" + className + "'"); 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 29c69a942619..3289cfa31446 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 @@ -285,12 +285,12 @@ private boolean isParamAssignableToBArray(Class paramType) { private JMethod resolve(JMethodRequest jMethodRequest, List jMethods) { boolean noConstraints = noConstraintsSpecified(jMethodRequest.paramTypeConstraints); if (jMethods.size() == 1 && noConstraints) { - return jMethods.get(0); + return jMethods.getFirst(); } else if (noConstraints) { if (areAllMethodsOverridden(jMethods, jMethodRequest.declaringClass)) { - return jMethods.get(0); + return jMethods.getFirst(); } - throwOverloadedMethodError(jMethodRequest, jMethods.get(0).getParamTypes().length); + throwOverloadedMethodError(jMethodRequest, jMethods.getFirst().getParamTypes().length); } JMethod jMethod = resolveExactMethod(jMethodRequest.declaringClass, jMethodRequest.methodName, @@ -302,7 +302,7 @@ private JMethod resolve(JMethodRequest jMethodRequest, List jMethods) { } private boolean areAllMethodsOverridden(List jMethods, Class clazz) { - if (jMethods.get(0).getKind() == JMethodKind.CONSTRUCTOR) { + if (jMethods.getFirst().getKind() == JMethodKind.CONSTRUCTOR) { return false; } for (int i = 0; i < jMethods.size(); i++) { @@ -506,7 +506,7 @@ private void bundlePathParams(JMethodRequest jMethodRequest, JMethod jMethod) { return; } List paramTypes = new ArrayList<>(Arrays.asList(jMethodRequest.bParamTypes)); - int initialPathParamIndex = paramTypes.indexOf(pathParamSymbols.get(0).type); + int initialPathParamIndex = paramTypes.indexOf(pathParamSymbols.getFirst().type); for (BVarSymbol param : pathParamSymbols) { paramTypes.remove(param.type); } @@ -956,7 +956,7 @@ private JMethod resolveMatchingMethod(JMethodRequest jMethodRequest, List imprtMods, BIRNode.BIRPackage pk JarEntries jarEntries, SymbolTable symbolTable) { innerClassName = JvmCodeGenUtil.getModuleLevelClassName(pkg.packageID, CONFIGURATION_CLASS_NAME); ClassWriter cw = new BallerinaClassWriter(COMPUTE_FRAMES); - cw.visit(V17, ACC_PUBLIC | ACC_SUPER, innerClassName, null, OBJECT, null); + cw.visit(V21, ACC_PUBLIC | ACC_SUPER, innerClassName, null, OBJECT, null); generateStaticFields(cw, innerClassName); MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, JVM_INIT_METHOD, VOID_METHOD_DESC, null, null); mv.visitCode(); @@ -152,17 +152,16 @@ private void generateConfigInit(ClassWriter cw, Set imprtMods, Packag private void generateInvokeConfiguration(MethodVisitor mv, PackageID id) { String moduleClass = JvmCodeGenUtil.getModuleLevelClassName(id, CONFIGURATION_CLASS_NAME); String initClass = JvmCodeGenUtil.getModuleLevelClassName(id, MODULE_INIT_CLASS_NAME); - - mv.visitMethodInsn(INVOKESTATIC, moduleClass, POPULATE_CONFIG_DATA_METHOD, - POPULATE_CONFIG_DATA, false); - mv.visitVarInsn(ASTORE, 4); mv.visitVarInsn(ALOAD, 4); + mv.visitMethodInsn(INVOKESTATIC, moduleClass, POPULATE_CONFIG_DATA_METHOD, POPULATE_CONFIG_DATA, false); + mv.visitVarInsn(ASTORE, 5); + mv.visitVarInsn(ALOAD, 5); mv.visitInsn(ARRAYLENGTH); Label elseLabel = new Label(); mv.visitJumpInsn(IFEQ, elseLabel); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETSTATIC, initClass, CURRENT_MODULE_VAR_NAME, GET_MODULE); - mv.visitVarInsn(ALOAD, 4); + mv.visitVarInsn(ALOAD, 5); mv.visitMethodInsn(INVOKESTATIC, LAUNCH_UTILS, "addModuleConfigData", ADD_MODULE_CONFIG_DATA, false); mv.visitLabel(elseLabel); } @@ -173,6 +172,7 @@ private void generateInvokeConfigureInit(MethodVisitor mv, PackageID id) { mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 2); mv.visitVarInsn(ALOAD, 3); + mv.visitVarInsn(ALOAD, 4); mv.visitMethodInsn(INVOKESTATIC, configClass, CONFIGURE_INIT, INIT_CONFIG, false); } @@ -181,12 +181,13 @@ private void populateConfigDataMethod(ClassWriter cw, String moduleClass, MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, POPULATE_CONFIG_DATA_METHOD, POPULATE_CONFIG_DATA, null, null); mv.visitCode(); - mv.visitMethodInsn(INVOKESTATIC, moduleClass, CURRENT_MODULE_INIT, RETURN_OBJECT, false); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESTATIC, moduleClass, CURRENT_MODULE_INIT_METHOD, CURRENT_MODULE_INIT, false); //create configuration data array mv.visitLdcInsn(calculateConfigArraySize(module.globalVars)); mv.visitTypeInsn(ANEWARRAY, VARIABLE_KEY); - mv.visitVarInsn(ASTORE, 0); + mv.visitVarInsn(ASTORE, 1); int varCount = 0; for (BIRNode.BIRGlobalVariableDcl globalVar : module.globalVars) { @@ -205,16 +206,16 @@ private void populateConfigDataMethod(ClassWriter cw, String moduleClass, mv.visitInsn(ICONST_0); } mv.visitMethodInsn(INVOKESPECIAL, VARIABLE_KEY, JVM_INIT_METHOD, INTI_VARIABLE_KEY, false); - mv.visitVarInsn(ASTORE, varCount + 1); + mv.visitVarInsn(ASTORE, varCount + 2); - mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); mv.visitLdcInsn(varCount); - mv.visitVarInsn(ALOAD, varCount + 1); + mv.visitVarInsn(ALOAD, varCount + 2); mv.visitInsn(AASTORE); varCount++; } } - mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ALOAD, 1); mv.visitInsn(ARETURN); JvmCodeGenUtil.visitMaxStackForMethod(mv, POPULATE_CONFIG_DATA_METHOD, innerClassName); mv.visitEnd(); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/FrameClassGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/FrameClassGen.java deleted file mode 100644 index 3a116ac0efba..000000000000 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/FrameClassGen.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2020, 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. - */ - -package org.wso2.ballerinalang.compiler.bir.codegen.methodgen; - -import org.ballerinalang.model.elements.PackageID; -import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.FieldVisitor; -import org.objectweb.asm.Opcodes; -import org.wso2.ballerinalang.compiler.bir.codegen.BallerinaClassWriter; -import org.wso2.ballerinalang.compiler.bir.codegen.JarEntries; -import org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil; -import org.wso2.ballerinalang.compiler.bir.model.BIRNode; -import org.wso2.ballerinalang.compiler.semantics.model.types.BType; -import org.wso2.ballerinalang.compiler.util.TypeTags; - -import java.util.List; - -import static org.objectweb.asm.ClassWriter.COMPUTE_FRAMES; -import static org.objectweb.asm.Opcodes.ACC_SUPER; -import static org.objectweb.asm.Opcodes.V17; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CLASS_FILE_SUFFIX; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUNCTION_FRAME; -import static org.wso2.ballerinalang.compiler.bir.codegen.methodgen.MethodGen.FUNCTION_INVOCATION; -import static org.wso2.ballerinalang.compiler.bir.codegen.methodgen.MethodGen.STATE; - -/** - * Generates Jvm byte code for the generateFrame classes. - * - * @since 2.0.0 - */ -public class FrameClassGen { - - public void generateFrameClasses(BIRNode.BIRPackage pkg, JarEntries pkgEntries) { - pkg.functions.forEach( - func -> generateFrameClassForFunction(pkg.packageID, func, pkgEntries, null)); - - for (BIRNode.BIRTypeDefinition typeDef : pkg.typeDefs) { - List attachedFuncs = typeDef.attachedFuncs; - if (attachedFuncs == null || attachedFuncs.isEmpty()) { - continue; - } - - BType attachedType; - if (JvmCodeGenUtil.getImpliedType(typeDef.type).tag == TypeTags.RECORD) { - // Only attach function of records is the record init. That should be - // generated as a static function. - attachedType = null; - } else { - attachedType = typeDef.type; - } - attachedFuncs.forEach(func -> generateFrameClassForFunction( - pkg.packageID, func, pkgEntries, attachedType)); - } - } - - private void generateFrameClassForFunction(PackageID packageID, BIRNode.BIRFunction func, - JarEntries pkgEntries, - BType attachedType) { - String frameClassName = MethodGenUtils.getFrameClassName(JvmCodeGenUtil.getPackageName(packageID), - func.name.value, attachedType); - ClassWriter cw = new BallerinaClassWriter(COMPUTE_FRAMES); - if (func.pos != null && func.pos.lineRange().fileName() != null) { - cw.visitSource(func.pos.lineRange().fileName(), null); - } - cw.visit(V17, Opcodes.ACC_PUBLIC + ACC_SUPER, frameClassName, null, FUNCTION_FRAME, null); - JvmCodeGenUtil.generateDefaultConstructor(cw, FUNCTION_FRAME); - - int k = 0; - List localVars = func.localVars; - while (k < localVars.size()) { - BIRNode.BIRVariableDcl localVar = localVars.get(k); - if (localVar.onlyUsedInSingleBB) { - k = k + 1; - continue; - } - BType bType = localVar.type; - String fieldName = localVar.jvmVarName; - String typeSig = JvmCodeGenUtil.getFieldTypeSignature(bType); - cw.visitField(Opcodes.ACC_PUBLIC, fieldName, typeSig, null, null).visitEnd(); - k = k + 1; - } - - FieldVisitor fv = cw.visitField(Opcodes.ACC_PUBLIC, STATE, "I", null, null); - fv.visitEnd(); - fv = cw.visitField(Opcodes.ACC_PUBLIC, FUNCTION_INVOCATION, "I", null, null); - fv.visitEnd(); - - cw.visitEnd(); - - // panic if there are errors in the frame class. These cannot be logged, since - // frame classes are internal implementation details. - pkgEntries.put(frameClassName + CLASS_FILE_SUFFIX, cw.toByteArray()); - } - -} diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/InitMethodGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/InitMethodGen.java index 4393d2ae2c46..95692b46bd37 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/InitMethodGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/InitMethodGen.java @@ -21,7 +21,6 @@ import io.ballerina.identifier.Utils; import org.ballerinalang.model.elements.PackageID; import org.objectweb.asm.ClassWriter; -import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.wso2.ballerinalang.compiler.bir.codegen.JvmCastGen; @@ -32,7 +31,6 @@ import org.wso2.ballerinalang.compiler.bir.codegen.internal.JavaClass; import org.wso2.ballerinalang.compiler.bir.codegen.model.BIRFunctionWrapper; import org.wso2.ballerinalang.compiler.bir.codegen.model.JIMethodCLICall; -import org.wso2.ballerinalang.compiler.bir.codegen.model.JIMethodCall; import org.wso2.ballerinalang.compiler.bir.codegen.split.JvmConstantsGen; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; import org.wso2.ballerinalang.compiler.bir.model.BIRNonTerminator; @@ -44,12 +42,10 @@ import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.BInvokableTypeSymbol; -import org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols; import org.wso2.ballerinalang.compiler.semantics.model.types.BInvokableType; import org.wso2.ballerinalang.compiler.semantics.model.types.BType; import org.wso2.ballerinalang.compiler.semantics.model.types.BUnionType; import org.wso2.ballerinalang.compiler.util.Name; -import org.wso2.ballerinalang.util.Flags; import java.util.ArrayList; import java.util.Collections; @@ -73,22 +69,19 @@ import static org.objectweb.asm.Opcodes.GETSTATIC; import static org.objectweb.asm.Opcodes.ICONST_0; import static org.objectweb.asm.Opcodes.ICONST_1; -import static org.objectweb.asm.Opcodes.IFNULL; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.INVOKESTATIC; import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; import static org.objectweb.asm.Opcodes.LRETURN; import static org.objectweb.asm.Opcodes.NEW; -import static org.objectweb.asm.Opcodes.PUTFIELD; import static org.objectweb.asm.Opcodes.RETURN; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BAL_RUNTIME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CLI_SPEC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CREATE_TYPES_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_INIT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_STOP; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUTURE_VALUE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_INIT_METHOD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_STOP_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.GET_TEST_EXECUTION_STATE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.GRACEFUL_EXIT_METHOD_NAME; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_STOP_PANIC_METHOD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_FUTURE_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.LAMBDA_PREFIX; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MAIN_METHOD; @@ -97,31 +90,30 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_START_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_STOP_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OBJECT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.PANIC_FIELD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.PREDEFINED_TYPES; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RUNTIME_REGISTRY_CLASS; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RUNTIME_REGISTRY_VARIABLE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RUNTIME_UTILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULER; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULER_START_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STACK; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULER_VARIABLE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.START_ISOLATED_WORKER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_CLASS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TEST_EXECUTE_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TEST_EXECUTION_STATE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.VALUE_CREATOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ADD_VALUE_CREATOR; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.CURRENT_MODULE_INIT; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.CURRENT_MODULE_STOP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MAIN_ARGS; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_RUNTIME_REGISTRY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_SCHEDULER; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_STRAND; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_THROWABLE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GRACEFUL_EXIT_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_STOP_PANIC; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.LAMBDA_STOP_DYNAMIC; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_FUTURE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_CLASS_CONSTRUCTOR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.LOAD_NULL_TYPE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.MODULE_STOP; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RETURN_OBJECT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SET_STRAND; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.STACK_FRAMES; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.PASS_OBJECT_ARRAY_RETURN_OBJECT; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.PASS_STRAND; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SCHEDULE_CALL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VOID_METHOD_DESC; import static org.wso2.ballerinalang.compiler.util.CompilerUtils.getMajorVersion; @@ -166,7 +158,6 @@ public void generateLambdaForModuleExecuteFunction(ClassWriter cw, String initCl MethodVisitor mv = visitFunction(cw, lambdaFuncName); mv.visitCode(); String methodDesc; - MethodGenUtils.callSetDaemonStrand(mv); //load strand as first arg mv.visitVarInsn(ALOAD, 0); mv.visitInsn(ICONST_0); @@ -203,7 +194,8 @@ public void generateLambdaForModuleExecuteFunction(ClassWriter cw, String initCl } private MethodVisitor visitFunction(ClassWriter cw, String funcName) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, funcName, LAMBDA_STOP_DYNAMIC, null, null); + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, funcName, PASS_OBJECT_ARRAY_RETURN_OBJECT, + null, null); mv.visitCode(); return mv; } @@ -224,13 +216,14 @@ public void generateModuleInitializer(ClassWriter cw, BIRNode.BIRPackage module, String moduleInitClass) { // Using object return type since this is similar to a ballerina function without a return. // A ballerina function with no returns is equivalent to a function with nil-return. - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CURRENT_MODULE_INIT, - RETURN_OBJECT, null, null); + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CURRENT_MODULE_INIT_METHOD, + CURRENT_MODULE_INIT, null, null); mv.visitCode(); mv.visitMethodInsn(INVOKESTATIC, moduleInitClass, CREATE_TYPES_METHOD, VOID_METHOD_DESC, false); mv.visitTypeInsn(NEW, typeOwnerClass); mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, typeOwnerClass, JVM_INIT_METHOD, VOID_METHOD_DESC, false); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, typeOwnerClass, JVM_INIT_METHOD, INIT_CLASS_CONSTRUCTOR, false); mv.visitVarInsn(ASTORE, 1); mv.visitLdcInsn(Utils.decodeIdentifier(module.packageID.orgName.getValue())); mv.visitLdcInsn(Utils.decodeIdentifier(module.packageID.name.getValue())); @@ -245,41 +238,39 @@ public void generateModuleInitializer(ClassWriter cw, BIRNode.BIRPackage module, // Add a nil-return mv.visitInsn(ACONST_NULL); - MethodGenUtils.visitReturn(mv, CURRENT_MODULE_INIT, typeOwnerClass); + MethodGenUtils.visitReturn(mv, CURRENT_MODULE_INIT_METHOD, typeOwnerClass); } public void generateModuleStop(ClassWriter cw, String moduleInitClass, AsyncDataCollector asyncDataCollector, JvmConstantsGen jvmConstantsGen) { // Using object return type since this is similar to a ballerina function without a return. // A ballerina function with no returns is equivalent to a function with nil-return. - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CURRENT_MODULE_STOP, - JvmSignatures.CURRENT_MODULE_STOP, null, null); + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, CURRENT_MODULE_STOP_METHOD, CURRENT_MODULE_STOP, + null, null); mv.visitCode(); - - // Create a scheduler. A new scheduler is used here, to make the stop function to not - // depend/wait on whatever is being running on the background. eg: a busy loop in the main. - mv.visitTypeInsn(NEW, SCHEDULER); - mv.visitInsn(DUP); - mv.visitInsn(ICONST_1); - mv.visitInsn(ICONST_0); - mv.visitMethodInsn(INVOKESPECIAL, SCHEDULER, JVM_INIT_METHOD, "(IZ)V", false); - mv.visitVarInsn(ASTORE, 1); // Scheduler var1 + generateGetSchedulerVar(mv); String lambdaName = generateStopDynamicLambdaBody(cw, moduleInitClass); - generateCallStopDynamicLambda(mv, lambdaName, moduleInitClass, asyncDataCollector, jvmConstantsGen); - mv.visitVarInsn(ALOAD, 0); + generateCallStopDynamicLambda(mv, lambdaName, moduleInitClass); + mv.visitVarInsn(ALOAD, 1); mv.visitVarInsn(ALOAD, 3); mv.visitMethodInsn(INVOKESTATIC, moduleInitClass, MODULE_STOP_METHOD, MODULE_STOP, false); mv.visitInsn(RETURN); - JvmCodeGenUtil.visitMaxStackForMethod(mv, CURRENT_MODULE_STOP, moduleInitClass); + JvmCodeGenUtil.visitMaxStackForMethod(mv, CURRENT_MODULE_STOP_METHOD, moduleInitClass); mv.visitEnd(); } + private static void generateGetSchedulerVar(MethodVisitor mv) { + mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, BAL_RUNTIME, SCHEDULER_VARIABLE, GET_SCHEDULER); + mv.visitVarInsn(ASTORE, 1); + } + private String generateStopDynamicLambdaBody(ClassWriter cw, String initClass) { String lambdaName = LAMBDA_PREFIX + "stopdynamic"; - MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + ACC_STATIC, lambdaName, LAMBDA_STOP_DYNAMIC, null, null); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + ACC_STATIC, lambdaName, PASS_OBJECT_ARRAY_RETURN_OBJECT, + null, null); mv.visitCode(); - MethodGenUtils.callSetDaemonStrand(mv); generateCallSchedulerStopDynamicListeners(mv, lambdaName, initClass); return lambdaName; } @@ -293,24 +284,17 @@ private void generateCallSchedulerStopDynamicListeners(MethodVisitor mv, String mv.visitInsn(ICONST_0); mv.visitInsn(AALOAD); mv.visitTypeInsn(CHECKCAST, STRAND_CLASS); - mv.visitMethodInsn(INVOKEVIRTUAL, RUNTIME_REGISTRY_CLASS, "gracefulStop", SET_STRAND, false); + mv.visitMethodInsn(INVOKEVIRTUAL, RUNTIME_REGISTRY_CLASS, "gracefulStop", PASS_STRAND, false); mv.visitInsn(ACONST_NULL); MethodGenUtils.visitReturn(mv, lambdaName, initClass); } - private void generateCallStopDynamicLambda(MethodVisitor mv, String lambdaName, String moduleInitClass, - AsyncDataCollector asyncDataCollector, JvmConstantsGen jvmConstantsGen) { + private void generateCallStopDynamicLambda(MethodVisitor mv, String lambdaName, String moduleInitClass) { addRuntimeRegistryAsParameter(mv); - generateMethodBody(mv, moduleInitClass, lambdaName, asyncDataCollector, jvmConstantsGen); - // handle any runtime errors - Label labelIf = new Label(); + generateMethodBody(mv, moduleInitClass, lambdaName); + // handle future result mv.visitVarInsn(ALOAD, 3); - mv.visitFieldInsn(GETFIELD, FUTURE_VALUE, PANIC_FIELD, GET_THROWABLE); - mv.visitJumpInsn(IFNULL, labelIf); - mv.visitVarInsn(ALOAD, 3); - mv.visitFieldInsn(GETFIELD, FUTURE_VALUE, PANIC_FIELD, GET_THROWABLE); - mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_STOP_PANIC_METHOD, HANDLE_STOP_PANIC, false); - mv.visitLabel(labelIf); + mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_FUTURE_METHOD, HANDLE_FUTURE, false); } private void addRuntimeRegistryAsParameter(MethodVisitor mv) { @@ -320,33 +304,26 @@ private void addRuntimeRegistryAsParameter(MethodVisitor mv) { mv.visitVarInsn(ALOAD, 2); mv.visitInsn(ICONST_1); mv.visitVarInsn(ALOAD, 0); + mv.visitFieldInsn(GETFIELD, BAL_RUNTIME, RUNTIME_REGISTRY_VARIABLE, GET_RUNTIME_REGISTRY); mv.visitInsn(AASTORE); - mv.visitVarInsn(ALOAD, 1); - mv.visitVarInsn(ALOAD, 2); } - private void generateMethodBody(MethodVisitor mv, String initClass, String stopFuncName, - AsyncDataCollector asyncDataCollector, JvmConstantsGen jvmConstantsGen) { + private void generateMethodBody(MethodVisitor mv, String initClass, String stopFuncName) { + mv.visitVarInsn(ALOAD, 1); JvmCodeGenUtil.createFunctionPointer(mv, initClass, stopFuncName); mv.visitInsn(ACONST_NULL); mv.visitFieldInsn(GETSTATIC, PREDEFINED_TYPES, "TYPE_NULL", LOAD_NULL_TYPE); - MethodGenUtils.submitToScheduler(mv, jvmConstantsGen.getStrandMetadataConstantsClass(), "stop", - asyncDataCollector); + mv.visitLdcInsn("stop"); + mv.visitInsn(ACONST_NULL); + mv.visitVarInsn(ALOAD, 2); + mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, START_ISOLATED_WORKER, SCHEDULE_CALL, false); mv.visitVarInsn(ASTORE, 3); - mv.visitVarInsn(ALOAD, 3); - mv.visitFieldInsn(GETFIELD, FUTURE_VALUE, STRAND, GET_STRAND); - mv.visitTypeInsn(NEW, STACK); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, STACK, JVM_INIT_METHOD, VOID_METHOD_DESC, false); - mv.visitFieldInsn(PUTFIELD, STRAND_CLASS, MethodGenUtils.FRAMES, STACK_FRAMES); - mv.visitVarInsn(ALOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, SCHEDULER_START_METHOD, VOID_METHOD_DESC, false); } public void enrichPkgWithInitializers(Map birFunctionMap, Map jvmClassMap, String typeOwnerClass, BIRNode.BIRPackage pkg, Set moduleImports, - boolean serviceEPAvailable, BIRNode.BIRFunction mainFunc, + BIRNode.BIRFunction mainFunc, BIRNode.BIRFunction testExecuteFunc) { JavaClass javaClass = jvmClassMap.get(typeOwnerClass); BIRNode.BIRFunction initFunc = generateDefaultFunction(moduleImports, pkg, MODULE_INIT_METHOD, @@ -363,17 +340,17 @@ public void enrichPkgWithInitializers(Map birFunctio birFunctionMap.put(JvmCodeGenUtil.getPackageName(pkg.packageID) + MODULE_START_METHOD, JvmPackageGen.getFunctionWrapper(startFunc, pkg.packageID, typeOwnerClass)); - BIRNode.BIRFunction execFunc = generateExecuteFunction(pkg, serviceEPAvailable, mainFunc, testExecuteFunc, - typeOwnerClass); + BIRNode.BIRFunction execFunc = generateExecuteFunction(pkg, mainFunc, testExecuteFunc + ); javaClass.functions.add(execFunc); pkg.functions.add(execFunc); birFunctionMap.put(JvmCodeGenUtil.getPackageName(pkg.packageID) + MODULE_EXECUTE_METHOD, JvmPackageGen.getFunctionWrapper(execFunc, pkg.packageID, typeOwnerClass)); } - private BIRNode.BIRFunction generateExecuteFunction(BIRNode.BIRPackage pkg, boolean serviceEPAvailable, + private BIRNode.BIRFunction generateExecuteFunction(BIRNode.BIRPackage pkg, BIRNode.BIRFunction mainFunc, - BIRNode.BIRFunction testExecuteFunc, String typeOwnerClass) { + BIRNode.BIRFunction testExecuteFunc) { BIRNode.BIRVariableDcl retVar = new BIRNode.BIRVariableDcl(null, errorOrNilType, new Name("%ret"), VarScope.FUNCTION, VarKind.RETURN, null); BIROperand retVarRef = new BIROperand(retVar); @@ -457,9 +434,7 @@ private BIRNode.BIRFunction generateExecuteFunction(BIRNode.BIRPackage pkg, bool if (testExecuteFunc != null) { lastBB = addTestExecuteInvocationWithGracefulExitCall(modExecFunc, pkg.packageID, retVarRef, functionArgs, - Collections.emptyList(), typeOwnerClass); - } else if (!serviceEPAvailable && !JvmPackageGen.isLangModule(pkg.packageID)) { - lastBB = addInvocationForGracefulExitCall(modExecFunc, typeOwnerClass); + Collections.emptyList()); } lastBB.terminator = new BIRTerminator.Return(null); return modExecFunc; @@ -467,7 +442,7 @@ private BIRNode.BIRFunction generateExecuteFunction(BIRNode.BIRPackage pkg, bool private void injectCLIArgInvocation(BIRNode.BIRFunction modExecFunc, List functionArgs, List tempFuncArgs) { - BIRNode.BIRBasicBlock lastBB = modExecFunc.basicBlocks.get(modExecFunc.basicBlocks.size() - 1); + BIRNode.BIRBasicBlock lastBB = modExecFunc.basicBlocks.getLast(); JIMethodCLICall jiMethodCall = new JIMethodCLICall(null); jiMethodCall.lhsArgs = functionArgs; jiMethodCall.jClassName = CLI_SPEC; @@ -485,7 +460,7 @@ private void injectDefaultArgs(List mainArgs, BIRNode.BIRFunction ma for (int i = 0; i < tempFuncArgs.size(); i++) { int mainFuncParamIndex = mainFunc.parameters.size() - defaultParamCount + i; BIRNode.BIRFunctionParameter parameter = mainFunc.parameters.get(mainFuncParamIndex); - BIRNode.BIRBasicBlock lastBB = modExecFunc.basicBlocks.get(modExecFunc.basicBlocks.size() - 1); + BIRNode.BIRBasicBlock lastBB = modExecFunc.basicBlocks.getLast(); BIROperand argOperand = mainArgs.get(mainFuncParamIndex); BIROperand tempArgOperand = tempFuncArgs.get(i); BIRNonTerminator.TypeTest typeTest = @@ -512,9 +487,8 @@ private BIRTerminator.FPCall getFPCallForDefaultParameter(BInvokableSymbol defau List args) { BIRNode.BIRGlobalVariableDcl defaultFuncVar = getDefaultFuncFPGlobalVar(defaultFunc.name, globalVars); BIROperand defaultFP = new BIROperand(defaultFuncVar); - boolean workerDerivative = Symbols.isFlagOn(defaultFunc.flags, Flags.WORKER); - return new BIRTerminator.FPCall(null, InstructionKind.FP_CALL, defaultFP, args, argOperand, false, - thenBB, null, workerDerivative); + return new BIRTerminator.FPCall(null, InstructionKind.FP_CALL, defaultFP, args, argOperand, false, thenBB, + null, new ArrayList<>()); } private BIRNode.BIRGlobalVariableDcl getDefaultFuncFPGlobalVar(Name name, @@ -572,34 +546,12 @@ private Name getNextVarId() { return new Name(varIdPrefix + nextVarId); } - private BIRNode.BIRBasicBlock addInvocationForGracefulExitCall(BIRNode.BIRFunction func, - String typeOwnerClass) { - BIRNode.BIRBasicBlock lastBB = func.basicBlocks.get(func.basicBlocks.size() - 1); - BIRNode.BIRBasicBlock nextBB = addAndGetNextBasicBlock(func); - lastBB.terminator = getExitMethodCall(nextBB, typeOwnerClass); - return nextBB; - } - - private static JIMethodCall getExitMethodCall(BIRNode.BIRBasicBlock nextBB, String typeOwnerClass) { - JIMethodCall jiMethodCall = new JIMethodCall(null); - jiMethodCall.args = new ArrayList<>(); - jiMethodCall.varArgExist = false; - jiMethodCall.jClassName = typeOwnerClass; - jiMethodCall.jMethodVMSig = GRACEFUL_EXIT_METHOD; - jiMethodCall.name = GRACEFUL_EXIT_METHOD_NAME; - jiMethodCall.invocationType = INVOKESTATIC; - jiMethodCall.thenBB = nextBB; - jiMethodCall.isInternal = true; - return jiMethodCall; - } - private BIRNode.BIRBasicBlock addTestExecuteInvocationWithGracefulExitCall(BIRNode.BIRFunction func, PackageID modId, BIROperand retVar, List args, List - calleeAnnotAttachments, - String typeOwnerClass) { - BIRNode.BIRBasicBlock lastBB = func.basicBlocks.get(func.basicBlocks.size() - 1); + calleeAnnotAttachments) { + BIRNode.BIRBasicBlock lastBB = func.basicBlocks.getLast(); BIRNode.BIRBasicBlock nextBB = addAndGetNextBasicBlock(func); if (JvmCodeGenUtil.isBuiltInPackage(modId)) { lastBB.terminator = new BIRTerminator.Call(null, InstructionKind.CALL, false, modId, @@ -608,18 +560,16 @@ private BIRNode.BIRBasicBlock addTestExecuteInvocationWithGracefulExitCall(BIRNo } lastBB.terminator = new BIRTerminator.Call(null, InstructionKind.CALL, false, modId, new Name(TEST_EXECUTE_METHOD), args, retVar, nextBB, calleeAnnotAttachments, Collections.emptySet()); - BIRNode.BIRBasicBlock finalBB = addAndGetNextBasicBlock(func); - nextBB.terminator = getExitMethodCall(finalBB, typeOwnerClass); - return finalBB; + return nextBB; } private BIRNode.BIRBasicBlock addCheckedInvocationWithArgs(BIRNode.BIRFunction func, PackageID modId, - String initFuncName, - BIROperand retVar, BIROperand boolRef, + String initFuncName, BIROperand retVar, + BIROperand boolRef, List args, List calleeAnnotAttachments) { - BIRNode.BIRBasicBlock lastBB = func.basicBlocks.get(func.basicBlocks.size() - 1); + BIRNode.BIRBasicBlock lastBB = func.basicBlocks.getLast(); BIRNode.BIRBasicBlock nextBB = addAndGetNextBasicBlock(func); // TODO remove once lang.annotation is fixed if (JvmCodeGenUtil.isBuiltInPackage(modId)) { @@ -665,17 +615,6 @@ public int incrementAndGetNextId() { return nextId++; } - public void generateGracefulExitMethod(ClassWriter cw) { - MethodVisitor mv = cw.visitMethod(ACC_STATIC, GRACEFUL_EXIT_METHOD_NAME, SET_STRAND, null, null); - mv.visitCode(); - mv.visitVarInsn(ALOAD, 0); - mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "scheduler", GET_SCHEDULER); - mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, GRACEFUL_EXIT_METHOD_NAME, "()V", false); - mv.visitInsn(RETURN); - JvmCodeGenUtil.visitMaxStackForMethod(mv, GRACEFUL_EXIT_METHOD_NAME, SCHEDULER); - mv.visitEnd(); - } - public void generateGetTestExecutionState(ClassWriter cw, String className) { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, GET_TEST_EXECUTION_STATE, "()J", null, null); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/LambdaGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/LambdaGen.java index db6a0d634707..d013ccdf566f 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/LambdaGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/LambdaGen.java @@ -61,41 +61,27 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import static org.objectweb.asm.Opcodes.ACC_STATIC; import static org.objectweb.asm.Opcodes.ACC_SUPER; -import static org.objectweb.asm.Opcodes.ACONST_NULL; import static org.objectweb.asm.Opcodes.ALOAD; import static org.objectweb.asm.Opcodes.ANEWARRAY; -import static org.objectweb.asm.Opcodes.ARETURN; -import static org.objectweb.asm.Opcodes.ASTORE; -import static org.objectweb.asm.Opcodes.ATHROW; import static org.objectweb.asm.Opcodes.BIPUSH; import static org.objectweb.asm.Opcodes.CHECKCAST; import static org.objectweb.asm.Opcodes.DUP; -import static org.objectweb.asm.Opcodes.GETFIELD; import static org.objectweb.asm.Opcodes.ICONST_0; import static org.objectweb.asm.Opcodes.ICONST_1; -import static org.objectweb.asm.Opcodes.IFEQ; -import static org.objectweb.asm.Opcodes.IFNULL; import static org.objectweb.asm.Opcodes.INVOKEINTERFACE; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.INVOKESTATIC; -import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; import static org.objectweb.asm.Opcodes.POP; -import static org.objectweb.asm.Opcodes.PUTFIELD; -import static org.objectweb.asm.Opcodes.V17; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BLOCKED_ON_EXTERN_FIELD; +import static org.objectweb.asm.Opcodes.V21; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.B_OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CALL_FUNCTION; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CLASS_FILE_SUFFIX; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.INT_VALUE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.IS_BLOCKED_ON_EXTERN_FIELD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_FUNCTION_CALLS_CLASS_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OBJECT_SELF_INSTANCE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.PANIC_FIELD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_CLASS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.BOBJECT_CALL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.FUNCTION_CALL; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_BERROR; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INITIAL_METHOD_DESC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VOID_METHOD_DESC; @@ -141,7 +127,7 @@ public void generateLambdaClasses(AsyncDataCollector asyncDataCollector, } private void generateConstantsClassInit(ClassWriter cw, String lambdaClassName) { - cw.visit(V17, ACC_PUBLIC | ACC_SUPER, lambdaClassName, null, JvmConstants.OBJECT, null); + cw.visit(V21, ACC_PUBLIC | ACC_SUPER, lambdaClassName, null, JvmConstants.OBJECT, null); MethodVisitor methodVisitor = cw.visitMethod(ACC_PRIVATE, JvmConstants.JVM_INIT_METHOD, VOID_METHOD_DESC, null, null); methodVisitor.visitCode(); @@ -171,7 +157,7 @@ private void generateLambdaMethod(BIRInstruction ins, ClassWriter cw, String lam } private void genNonVirtual(LambdaDetails lambdaDetails, MethodVisitor mv, List paramBTypes, - boolean isWorker, boolean isSamePkg) { + boolean isSamePkg) { String jvmClass, funcName, methodDesc; if (!isSamePkg) { // Use call method of function calls class to execute functions from imported modules @@ -188,8 +174,7 @@ private void genNonVirtual(LambdaDetails lambdaDetails, MethodVisitor mv, List getFpParamTypes(LambdaDetails lambdaDetails) { @@ -297,7 +282,7 @@ private void handleFpLambda(BIRNonTerminator.FPLoad ins, LambdaDetails lambdaDet loadClosureMaps(lambdaDetails, mv); // load and cast param values loadAndCastParamValues(ins, lambdaDetails, mv, paramBTypes, isSamePkg); - genNonVirtual(lambdaDetails, mv, paramBTypes, ins.isWorker, isSamePkg); + genNonVirtual(lambdaDetails, mv, paramBTypes, isSamePkg); } private void loadAndCastParamValues(BIRNonTerminator.FPLoad ins, LambdaDetails lambdaDetails, MethodVisitor mv, @@ -346,16 +331,6 @@ private MethodVisitor getMethodVisitorAndLoadFirst(ClassWriter cw, String lambda if (!isSamePkg) { mv.visitLdcInsn(lambdaDetails.encodedFuncName); } - if ((ins.getKind() == InstructionKind.FP_LOAD) && ((BIRNonTerminator.FPLoad) ins).isWorker) { - mv.visitVarInsn(ALOAD, lambdaDetails.closureMapsCount); - mv.visitInsn(ICONST_1); - mv.visitInsn(AALOAD); - mv.visitTypeInsn(CHECKCAST, INT_VALUE); - mv.visitMethodInsn(INVOKEVIRTUAL, INT_VALUE, "intValue", "()I", false); - } - if (lambdaDetails.isExternFunction) { - generateBlockedOnExtern(lambdaDetails.closureMapsCount, mv); - } return mv; } @@ -367,38 +342,6 @@ private String getMapValueDesc(int count) { return desc.toString(); } - private void generateBlockedOnExtern(int closureMapsCount, MethodVisitor mv) { - Label blockedOnExternLabel = new Label(); - - mv.visitInsn(DUP); - - mv.visitMethodInsn(INVOKEVIRTUAL, STRAND_CLASS , IS_BLOCKED_ON_EXTERN_FIELD, "()Z", false); - mv.visitJumpInsn(IFEQ, blockedOnExternLabel); - - mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitFieldInsn(PUTFIELD, STRAND_CLASS , BLOCKED_ON_EXTERN_FIELD, "Z"); - - mv.visitInsn(DUP); - mv.visitFieldInsn(GETFIELD, STRAND_CLASS , PANIC_FIELD, GET_BERROR); - Label panicLabel = new Label(); - mv.visitJumpInsn(IFNULL, panicLabel); - mv.visitInsn(DUP); - mv.visitFieldInsn(GETFIELD, STRAND_CLASS , PANIC_FIELD, GET_BERROR); - mv.visitVarInsn(ASTORE, closureMapsCount + 1); - mv.visitInsn(ACONST_NULL); - mv.visitFieldInsn(PUTFIELD, STRAND_CLASS , PANIC_FIELD, GET_BERROR); - mv.visitVarInsn(ALOAD, closureMapsCount + 1); - mv.visitInsn(ATHROW); - mv.visitLabel(panicLabel); - - mv.visitInsn(DUP); - mv.visitFieldInsn(GETFIELD, STRAND_CLASS, "returnValue", "Ljava/lang/Object;"); - mv.visitInsn(ARETURN); - - mv.visitLabel(blockedOnExternLabel); - } - private LambdaDetails getLambdaDetails(BIRInstruction ins) { InstructionKind kind = ins.getKind(); LambdaDetails lambdaDetails; @@ -509,11 +452,8 @@ private static class LambdaDetails { int closureMapsCount = 0; } - private String getLambdaMethodDesc(List paramTypes, BType retType, int closureMapsCount, boolean isWorker) { + private String getLambdaMethodDesc(List paramTypes, BType retType, int closureMapsCount) { StringBuilder desc = new StringBuilder(INITIAL_METHOD_DESC); - if (isWorker) { - desc.append("I"); - } appendClosureMaps(closureMapsCount, desc); appendParamTypes(paramTypes, desc); desc.append(JvmCodeGenUtil.generateReturnType(retType)); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MainMethodGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MainMethodGen.java index e4bd8a182f6c..a9a6a1fe457e 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MainMethodGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MainMethodGen.java @@ -26,14 +26,12 @@ import org.objectweb.asm.Opcodes; import org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil; import org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants; -import org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures; import org.wso2.ballerinalang.compiler.bir.codegen.JvmTypeGen; -import org.wso2.ballerinalang.compiler.bir.codegen.internal.AsyncDataCollector; import org.wso2.ballerinalang.compiler.bir.codegen.internal.BIRVarToJVMIndexMap; -import org.wso2.ballerinalang.compiler.bir.codegen.split.JvmConstantsGen; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable; import org.wso2.ballerinalang.compiler.semantics.model.types.BType; +import org.wso2.ballerinalang.util.Flags; import java.util.ArrayList; import java.util.List; @@ -53,7 +51,7 @@ import static org.objectweb.asm.Opcodes.ICONST_0; import static org.objectweb.asm.Opcodes.ICONST_1; import static org.objectweb.asm.Opcodes.ICONST_2; -import static org.objectweb.asm.Opcodes.IFNULL; +import static org.objectweb.asm.Opcodes.IFEQ; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.INVOKESTATIC; import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; @@ -64,17 +62,16 @@ import static org.objectweb.asm.Opcodes.RETURN; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BALLERINA_HOME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BALLERINA_VERSION; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.BAL_RUNTIME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CLI_SPEC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.COMPATIBILITY_CHECKER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CONFIGURATION_CLASS_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CONFIGURE_INIT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CONFIG_DETAILS; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_STOP; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_STOP_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.CURRENT_MODULE_VAR_NAME; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.FUTURE_VALUE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_ALL_THROWABLE_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_RETURNED_ERROR_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_STOP_PANIC_METHOD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_FUTURE_AND_EXIT_METHOD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_FUTURE_AND_RETURN_IS_PANIC_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HANDLE_THROWABLE_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.HASH_MAP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JAVA_RUNTIME; @@ -87,45 +84,43 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OPERAND; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OPTION; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.PANIC_FIELD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.REPOSITORY_IMPL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RUNTIME_UTILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULER; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULER_START_METHOD; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SET_LISTENER_FOUND_METHOD_NAME; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STACK; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_CLASS; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SCHEDULER_VARIABLE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.START_ISOLATED_WORKER; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.START_NON_ISOLATED_WORKER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TEST_ARGUMENTS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TEST_CONFIG_ARGS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TEST_EXECUTION_STATE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.THROWABLE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WAIT_ON_LISTENERS_METHOD_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ADD_BALLERINA_INFO; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.ADD_SHUTDOWN_HOOK; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.CURRENT_MODULE_STOP; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_CONFIG_DETAILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MAIN_ARGS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_MODULE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_OBJECT; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_PATH; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_RUNTIME; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_RUNTIME_REGISTRY_CLASS; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_STRAND; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_SCHEDULER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_STRING; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_STRING_ARRAY; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TEST_CONFIG_PATH; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_THROWABLE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_ERROR_RETURN; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_FUTURE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_FUTURE_AND_RETURN_IS_PANIC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.HANDLE_THROWABLE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_CLI_SPEC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_CONFIG; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_CONFIGURABLES; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_CONFIGURABLE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_OPERAND; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_OPTION; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_RUNTIME_REGISTRY; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_RUNTIME; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_SIGNAL_LISTENER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INIT_TEST_ARGS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.MAIN_METHOD_SIGNATURE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.METHOD_STRING_PARAM; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.STACK_FRAMES; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.SCHEDULE_CALL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VOID_METHOD_DESC; /** @@ -135,30 +130,30 @@ */ public class MainMethodGen { - public static final String INIT_FUTURE_VAR = "initFutureVar"; - public static final String SCHEDULER_VAR = "schedulerVar"; - public static final String CONFIG_VAR = "configVar"; + public static final String RUNTIME_VAR = "$runtime"; + public static final String FUTURE_VAR = "$future"; + public static final String SCHEDULER_VAR = "$schedulerVar"; + public static final String CONFIG_VAR = "$configVar"; private final SymbolTable symbolTable; private final BIRVarToJVMIndexMap indexMap; private final JvmTypeGen jvmTypeGen; - private final AsyncDataCollector asyncDataCollector; - private final String strandMetadataClass; private final boolean isRemoteMgtEnabled; - public MainMethodGen(SymbolTable symbolTable, JvmTypeGen jvmTypeGen, JvmConstantsGen jvmConstantsGen, - AsyncDataCollector asyncDataCollector, boolean isRemoteMgtEnabled) { + public MainMethodGen(SymbolTable symbolTable, JvmTypeGen jvmTypeGen, boolean isRemoteMgtEnabled) { this.symbolTable = symbolTable; // add main string[] args param first indexMap = new BIRVarToJVMIndexMap(1); this.jvmTypeGen = jvmTypeGen; - this.asyncDataCollector = asyncDataCollector; - this.strandMetadataClass = jvmConstantsGen.getStrandMetadataConstantsClass(); this.isRemoteMgtEnabled = isRemoteMgtEnabled; } public void generateMainMethod(BIRNode.BIRFunction userMainFunc, ClassWriter cw, BIRNode.BIRPackage pkg, String initClass, boolean serviceEPAvailable, boolean isTestable) { + int runtimeVarIndex = indexMap.addIfNotExists(RUNTIME_VAR, symbolTable.anyType); + int schedulerVarIndex = indexMap.addIfNotExists(SCHEDULER_VAR, symbolTable.anyType); + int futureVarIndex = indexMap.addIfNotExists(FUTURE_VAR, symbolTable.anyType); + MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + ACC_STATIC, MAIN_METHOD, MAIN_METHOD_SIGNATURE, null, null); mv.visitCode(); @@ -171,34 +166,34 @@ public void generateMainMethod(BIRNode.BIRFunction userMainFunc, ClassWriter cw, // check for java compatibility generateJavaCompatibilityCheck(mv); generateBallerinaRuntimeInformation(mv); - invokeConfigInit(mv, pkg.packageID); - // start all listeners and TRAP signal handler - startListenersAndSignalHandler(mv, serviceEPAvailable); - - genInitScheduler(mv); + genRuntimeAndGetScheduler(mv, initClass, runtimeVarIndex, schedulerVarIndex); + invokeConfigInit(mv, pkg.packageID, runtimeVarIndex); + // TRAP signal handler + genStartTrapSignalHandler(mv); // register a shutdown hook to call package stop() method. if (!isTestable) { - genShutdownHook(mv, initClass); + genShutdownHook(mv, initClass, runtimeVarIndex); } boolean hasInitFunction = MethodGenUtils.hasInitFunction(pkg); - generateExecuteFunctionCall(initClass, mv, userMainFunc, isTestable); - - if (hasInitFunction && !isTestable) { - setListenerFound(mv, serviceEPAvailable); - } - stopListeners(mv, serviceEPAvailable); - if (!serviceEPAvailable && !isTestable) { - JvmCodeGenUtil.generateExitRuntime(mv); - } - + // handle calling init and start during module initialization. + generateSetModuleInitialedAndStarted(mv, runtimeVarIndex); + generateExecuteFunctionCall(initClass, mv, userMainFunc, isTestable, schedulerVarIndex, futureVarIndex); + handleFutureValue(mv, initClass, isTestable, futureVarIndex); if (isTestable) { - generateModuleStopCall(initClass, mv); + generateModuleStopCall(initClass, mv, runtimeVarIndex); + } else { + if (hasInitFunction) { + setListenerFound(mv, serviceEPAvailable, runtimeVarIndex); + } + if (!serviceEPAvailable) { + JvmCodeGenUtil.generateExitRuntime(mv); + } } mv.visitLabel(tryCatchEnd); mv.visitInsn(RETURN); mv.visitLabel(tryCatchHandle); - mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_ALL_THROWABLE_METHOD, HANDLE_THROWABLE, false); + mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_THROWABLE_METHOD, HANDLE_THROWABLE, false); mv.visitInsn(RETURN); JvmCodeGenUtil.visitMaxStackForMethod(mv, "main", initClass); mv.visitEnd(); @@ -218,34 +213,28 @@ private void generateBallerinaRuntimeInformation(MethodVisitor mv) { false); } - private void generateExecuteFunctionCall(String initClass, MethodVisitor mv, BIRNode.BIRFunction userMainFunc, - boolean isTestable) { - mv.visitVarInsn(ALOAD, indexMap.get(SCHEDULER_VAR)); - if (userMainFunc != null) { - loadCLIArgsForMain(mv, userMainFunc.parameters, userMainFunc.annotAttachments); - } else if (isTestable) { - loadCLIArgsForTestExecute(mv); - } else { - mv.visitIntInsn(BIPUSH, 1); - mv.visitTypeInsn(ANEWARRAY, OBJECT); - } - // invoke the module execute method - genSubmitToScheduler(initClass, mv, isTestable); - genReturn(mv, indexMap); + private void generateSetModuleInitialedAndStarted(MethodVisitor mv, int runtimeVarIndex) { + mv.visitVarInsn(ALOAD, runtimeVarIndex); + mv.visitInsn(ICONST_1); + mv.visitFieldInsn(PUTFIELD, BAL_RUNTIME, "moduleInitialized", "Z"); + mv.visitVarInsn(ALOAD, runtimeVarIndex); + mv.visitInsn(ICONST_1); + mv.visitFieldInsn(PUTFIELD, BAL_RUNTIME, "moduleStarted", "Z"); } - private void generateModuleStopCall(String initClass, MethodVisitor mv) { - mv.visitVarInsn(ALOAD, indexMap.get(SCHEDULER_VAR)); - mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, "getRuntimeRegistry", GET_RUNTIME_REGISTRY_CLASS, false); - mv.visitMethodInsn(INVOKESTATIC, initClass, CURRENT_MODULE_STOP, JvmSignatures.CURRENT_MODULE_STOP, false); + private void generateExecuteFunctionCall(String initClass, MethodVisitor mv, BIRNode.BIRFunction userMainFunc, + boolean isTestable, int schedulerVarIndex, int futureVarIndex) { + mv.visitVarInsn(ALOAD, schedulerVarIndex); + // invoke the module execute method + genSubmitToScheduler(initClass, mv, userMainFunc, isTestable, futureVarIndex); } - private void startScheduler(int schedulerVarIndex, MethodVisitor mv) { - mv.visitVarInsn(ALOAD, schedulerVarIndex); - mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, SCHEDULER_START_METHOD, VOID_METHOD_DESC, false); + private void generateModuleStopCall(String initClass, MethodVisitor mv, int runtimeVarIndex) { + mv.visitVarInsn(ALOAD, runtimeVarIndex); + mv.visitMethodInsn(INVOKESTATIC, initClass, CURRENT_MODULE_STOP_METHOD, CURRENT_MODULE_STOP, false); } - private void invokeConfigInit(MethodVisitor mv, PackageID packageID) { + private void invokeConfigInit(MethodVisitor mv, PackageID packageID, int runtimeVarIndex) { String configClass = JvmCodeGenUtil.getModuleLevelClassName(packageID, CONFIGURATION_CLASS_NAME); mv.visitTypeInsn(NEW, HASH_MAP); mv.visitInsn(DUP); @@ -273,6 +262,7 @@ private void invokeConfigInit(MethodVisitor mv, PackageID packageID) { mv.visitFieldInsn(GETFIELD, CONFIG_DETAILS, "paths", GET_PATH); mv.visitVarInsn(ALOAD, configDetailsIndex); mv.visitFieldInsn(GETFIELD, CONFIG_DETAILS, "configContent", GET_STRING); + mv.visitVarInsn(ALOAD, runtimeVarIndex); mv.visitMethodInsn(INVOKESTATIC, configClass, CONFIGURE_INIT, INIT_CONFIG, false); String moduleInitClass = JvmCodeGenUtil.getModuleLevelClassName(packageID, MODULE_INIT_CLASS_NAME); mv.visitFieldInsn(GETSTATIC, moduleInitClass, CURRENT_MODULE_VAR_NAME, GET_MODULE); @@ -282,7 +272,7 @@ private void invokeConfigInit(MethodVisitor mv, PackageID packageID) { mv.visitFieldInsn(GETFIELD, CONFIG_DETAILS, "paths", GET_PATH); mv.visitVarInsn(ALOAD, configDetailsIndex); mv.visitFieldInsn(GETFIELD, CONFIG_DETAILS, "configContent", GET_STRING); - mv.visitMethodInsn(INVOKESTATIC, LAUNCH_UTILS, "initConfigurableVariables", INIT_CONFIGURABLES, false); + mv.visitMethodInsn(INVOKESTATIC, LAUNCH_UTILS, "initConfigurableVariables", INIT_CONFIGURABLE, false); } private void generateJavaCompatibilityCheck(MethodVisitor mv) { @@ -297,49 +287,40 @@ private String getJavaVersion() { return Objects.requireNonNullElse(javaVersion, ""); } - private void startListenersAndSignalHandler(MethodVisitor mv, boolean isServiceEPAvailable) { - mv.visitLdcInsn(isServiceEPAvailable); - mv.visitMethodInsn(INVOKESTATIC, LAUNCH_UTILS, "startListenersAndSignalHandler", "(Z)V", false); + private void genStartTrapSignalHandler(MethodVisitor mv) { + mv.visitMethodInsn(INVOKESTATIC, LAUNCH_UTILS, "startTrapSignalHandler", VOID_METHOD_DESC, false); } - private void genShutdownHook(MethodVisitor mv, String initClass) { + private void genShutdownHook(MethodVisitor mv, String initClass, int runtimeVarIndex) { String shutdownClassName = initClass + "$SignalListener"; - mv.visitMethodInsn(INVOKESTATIC, JAVA_RUNTIME, "getRuntime", - GET_RUNTIME, false); + mv.visitMethodInsn(INVOKESTATIC, JAVA_RUNTIME, "getRuntime", GET_RUNTIME, false); mv.visitTypeInsn(NEW, shutdownClassName); mv.visitInsn(DUP); - mv.visitVarInsn(ALOAD, indexMap.get(SCHEDULER_VAR)); - mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, "getRuntimeRegistry", - GET_RUNTIME_REGISTRY_CLASS, false); - mv.visitMethodInsn(INVOKESPECIAL, shutdownClassName, JVM_INIT_METHOD, - INIT_RUNTIME_REGISTRY, false); + mv.visitVarInsn(ALOAD, runtimeVarIndex); + mv.visitMethodInsn(INVOKESPECIAL, shutdownClassName, JVM_INIT_METHOD, INIT_SIGNAL_LISTENER, false); mv.visitMethodInsn(INVOKEVIRTUAL, JAVA_RUNTIME, "addShutdownHook", ADD_SHUTDOWN_HOOK, false); } - private void genInitScheduler(MethodVisitor mv) { - mv.visitTypeInsn(NEW , SCHEDULER); + private void genRuntimeAndGetScheduler(MethodVisitor mv, String initClass, int runtimeVarIndex, + int schedulerVarIndex) { + mv.visitTypeInsn(NEW, BAL_RUNTIME); mv.visitInsn(DUP); - mv.visitInsn(ICONST_0); - mv.visitMethodInsn(INVOKESPECIAL , SCHEDULER , JVM_INIT_METHOD, "(Z)V", false); - int schedulerVarIndex = indexMap.addIfNotExists(SCHEDULER_VAR, symbolTable.anyType); + mv.visitFieldInsn(GETSTATIC, initClass, CURRENT_MODULE_VAR_NAME, GET_MODULE); + mv.visitMethodInsn(INVOKESPECIAL, BAL_RUNTIME, JVM_INIT_METHOD, INIT_RUNTIME, false); + mv.visitInsn(DUP); + mv.visitVarInsn(ASTORE, runtimeVarIndex); + mv.visitFieldInsn(GETFIELD, BAL_RUNTIME, SCHEDULER_VARIABLE, GET_SCHEDULER); mv.visitVarInsn(ASTORE, schedulerVarIndex); } - private void setListenerFound(MethodVisitor mv, boolean serviceEPAvailable) { - // need to set immortal=true and start the scheduler again + private void setListenerFound(MethodVisitor mv, boolean serviceEPAvailable, int runtimeVarIndex) { + mv.visitVarInsn(ALOAD, runtimeVarIndex); if (serviceEPAvailable) { - int schedulerVarIndex = indexMap.get(SCHEDULER_VAR); - mv.visitVarInsn(ALOAD, schedulerVarIndex); mv.visitInsn(ICONST_1); - mv.visitMethodInsn(INVOKEVIRTUAL , SCHEDULER, SET_LISTENER_FOUND_METHOD_NAME, "(Z)V", false); - startScheduler(schedulerVarIndex, mv); + } else { + mv.visitInsn(ICONST_0); } - } - - private void storeFuture(BIRVarToJVMIndexMap indexMap, MethodVisitor mv) { - int mainFutureVarIndex = indexMap.addIfNotExists(INIT_FUTURE_VAR, symbolTable.anyType); - mv.visitVarInsn(ASTORE, mainFutureVarIndex); - mv.visitVarInsn(ALOAD, mainFutureVarIndex); + mv.visitMethodInsn(INVOKEVIRTUAL , BAL_RUNTIME, WAIT_ON_LISTENERS_METHOD_NAME, "(Z)V", false); } private void loadCLIArgsForMain(MethodVisitor mv, List params, @@ -439,12 +420,11 @@ private List getDefaultableNames(List a int defaultableIndex = 0; for (BIRNode.BIRAnnotationAttachment attachment : annotAttachments) { if (attachment != null && attachment.annotTagRef.value.equals(JvmConstants.DEFAULTABLE_ARGS_ANOT_NAME)) { - Map annotFieldMap = - (Map) - ((BIRNode.BIRConstAnnotationAttachment) attachment).annotValue.value; - - BIRNode.ConstValue[] annotArrayValue = - (BIRNode.ConstValue[]) annotFieldMap.get(JvmConstants.DEFAULTABLE_ARGS_ANOT_FIELD).value; + Map annotFieldMap = (Map) ((BIRNode.BIRConstAnnotationAttachment) attachment) + .annotValue.value; + BIRNode.ConstValue annConstValue = + (BIRNode.ConstValue) annotFieldMap.get(JvmConstants.DEFAULTABLE_ARGS_ANOT_FIELD); + BIRNode.ConstValue[] annotArrayValue = (BIRNode.ConstValue[]) annConstValue.value; for (BIRNode.ConstValue entryOptional : annotArrayValue) { defaultableNames.add(defaultableIndex, (String) entryOptional.value); defaultableIndex += 1; @@ -455,57 +435,44 @@ private List getDefaultableNames(List a return defaultableNames; } - private void genReturn(MethodVisitor mv, BIRVarToJVMIndexMap indexMap) { - // store future value - mv.visitVarInsn(ALOAD, indexMap.get(INIT_FUTURE_VAR)); - mv.visitFieldInsn(GETFIELD , FUTURE_VALUE, "result", GET_OBJECT); - - mv.visitMethodInsn(INVOKESTATIC , RUNTIME_UTILS , HANDLE_RETURNED_ERROR_METHOD, - HANDLE_ERROR_RETURN, false); - } - - private void genSubmitToScheduler(String initClass, MethodVisitor mv, boolean isTestFunction) { + private void genSubmitToScheduler(String initClass, MethodVisitor mv, BIRNode.BIRFunction userMainFunc, + boolean isTestable, int futureVarIndex) { JvmCodeGenUtil.createFunctionPointer(mv, initClass, LAMBDA_PREFIX + MODULE_EXECUTE_METHOD + "$"); - // no parent strand mv.visitInsn(ACONST_NULL); - BType anyType = symbolTable.anyType; jvmTypeGen.loadType(mv, anyType); - MethodGenUtils.submitToScheduler(mv, this.strandMetadataClass, MAIN_METHOD, asyncDataCollector); - storeFuture(indexMap, mv); - mv.visitFieldInsn(GETFIELD , FUTURE_VALUE , STRAND, GET_STRAND); - mv.visitTypeInsn(NEW, STACK); - mv.visitInsn(DUP); - mv.visitMethodInsn(INVOKESPECIAL, STACK, JVM_INIT_METHOD, VOID_METHOD_DESC, false); - mv.visitFieldInsn(PUTFIELD, STRAND_CLASS, MethodGenUtils.FRAMES, STACK_FRAMES); - - startScheduler(indexMap.get(SCHEDULER_VAR), mv); - handleErrorFromFutureValue(mv, initClass, isTestFunction); - } - - private void stopListeners(MethodVisitor mv, boolean isServiceEPAvailable) { - mv.visitLdcInsn(isServiceEPAvailable); - mv.visitMethodInsn(INVOKESTATIC , LAUNCH_UTILS, "stopListeners", "(Z)V", false); + mv.visitLdcInsn(MAIN_METHOD); + mv.visitInsn(ACONST_NULL); + if (userMainFunc != null) { + loadCLIArgsForMain(mv, userMainFunc.parameters, userMainFunc.annotAttachments); + } else if (isTestable) { + loadCLIArgsForTestExecute(mv); + } else { + mv.visitIntInsn(BIPUSH, 1); + mv.visitTypeInsn(ANEWARRAY, OBJECT); + } + if (userMainFunc != null && (userMainFunc.flags & Flags.ISOLATED) == Flags.ISOLATED) { + mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, START_ISOLATED_WORKER, SCHEDULE_CALL, false); + } else { + mv.visitMethodInsn(INVOKEVIRTUAL, SCHEDULER, START_NON_ISOLATED_WORKER, SCHEDULE_CALL, false); + } + mv.visitVarInsn(ASTORE, futureVarIndex); } - private void handleErrorFromFutureValue(MethodVisitor mv, String initClass, boolean isTestFunction) { - mv.visitVarInsn(ALOAD, indexMap.get(INIT_FUTURE_VAR)); - mv.visitInsn(DUP); - mv.visitFieldInsn(GETFIELD, FUTURE_VALUE, PANIC_FIELD, GET_THROWABLE); - - // handle any runtime errors - Label labelIf = new Label(); - mv.visitJumpInsn(IFNULL, labelIf); - mv.visitFieldInsn(GETFIELD, FUTURE_VALUE, PANIC_FIELD, GET_THROWABLE); - if (isTestFunction) { - mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_STOP_PANIC_METHOD, HANDLE_THROWABLE, false); + private void handleFutureValue(MethodVisitor mv, String initClass, boolean isTestable, int futureVarIndex) { + mv.visitVarInsn(ALOAD, futureVarIndex); + if (isTestable) { + mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_FUTURE_AND_RETURN_IS_PANIC_METHOD, + HANDLE_FUTURE_AND_RETURN_IS_PANIC, false); + Label ifLabel = new Label(); + mv.visitJumpInsn(IFEQ, ifLabel); mv.visitInsn(LCONST_1); mv.visitFieldInsn(PUTSTATIC, initClass, TEST_EXECUTION_STATE, "J"); + mv.visitLabel(ifLabel); + } else { - mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_THROWABLE_METHOD, HANDLE_THROWABLE, false); + mv.visitMethodInsn(INVOKESTATIC, RUNTIME_UTILS, HANDLE_FUTURE_AND_EXIT_METHOD, HANDLE_FUTURE, false); } - mv.visitInsn(RETURN); - mv.visitLabel(labelIf); } } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MethodGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MethodGen.java index f6966b814703..fd6d717c40fc 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MethodGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/methodgen/MethodGen.java @@ -54,65 +54,50 @@ import org.wso2.ballerinalang.compiler.bir.model.VarKind; import org.wso2.ballerinalang.compiler.semantics.analyzer.Types; import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable; -import org.wso2.ballerinalang.compiler.semantics.model.symbols.BTypeSymbol; import org.wso2.ballerinalang.compiler.semantics.model.symbols.Symbols; import org.wso2.ballerinalang.compiler.semantics.model.types.BType; import org.wso2.ballerinalang.compiler.util.TypeTags; import org.wso2.ballerinalang.util.Flags; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; +import static org.objectweb.asm.Opcodes.AASTORE; import static org.objectweb.asm.Opcodes.ACC_STATIC; import static org.objectweb.asm.Opcodes.ACONST_NULL; import static org.objectweb.asm.Opcodes.ALOAD; +import static org.objectweb.asm.Opcodes.ANEWARRAY; import static org.objectweb.asm.Opcodes.ARETURN; import static org.objectweb.asm.Opcodes.ASTORE; import static org.objectweb.asm.Opcodes.ATHROW; -import static org.objectweb.asm.Opcodes.CHECKCAST; +import static org.objectweb.asm.Opcodes.BIPUSH; import static org.objectweb.asm.Opcodes.DCONST_0; -import static org.objectweb.asm.Opcodes.DLOAD; import static org.objectweb.asm.Opcodes.DRETURN; import static org.objectweb.asm.Opcodes.DSTORE; import static org.objectweb.asm.Opcodes.DUP; -import static org.objectweb.asm.Opcodes.DUP_X1; import static org.objectweb.asm.Opcodes.FCONST_0; -import static org.objectweb.asm.Opcodes.FLOAD; import static org.objectweb.asm.Opcodes.FSTORE; -import static org.objectweb.asm.Opcodes.GETFIELD; import static org.objectweb.asm.Opcodes.GETSTATIC; import static org.objectweb.asm.Opcodes.GOTO; import static org.objectweb.asm.Opcodes.IADD; import static org.objectweb.asm.Opcodes.ICONST_0; import static org.objectweb.asm.Opcodes.ICONST_1; import static org.objectweb.asm.Opcodes.IFEQ; -import static org.objectweb.asm.Opcodes.IFGT; import static org.objectweb.asm.Opcodes.IF_ICMPEQ; -import static org.objectweb.asm.Opcodes.ILOAD; import static org.objectweb.asm.Opcodes.INVOKESPECIAL; import static org.objectweb.asm.Opcodes.INVOKESTATIC; -import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL; import static org.objectweb.asm.Opcodes.IRETURN; import static org.objectweb.asm.Opcodes.ISTORE; -import static org.objectweb.asm.Opcodes.ISUB; import static org.objectweb.asm.Opcodes.LCONST_0; -import static org.objectweb.asm.Opcodes.LLOAD; import static org.objectweb.asm.Opcodes.LRETURN; import static org.objectweb.asm.Opcodes.LSTORE; import static org.objectweb.asm.Opcodes.NEW; -import static org.objectweb.asm.Opcodes.POP; -import static org.objectweb.asm.Opcodes.PUTFIELD; import static org.objectweb.asm.Opcodes.PUTSTATIC; -import static org.objectweb.asm.Opcodes.SIPUSH; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.SCOPE_PREFIX; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.generateReturnType; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.getMethodDescParams; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmCodeGenUtil.getModuleLevelClassName; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ANNOTATIONS_METHOD_PREFIX; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.ERROR_UTILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.JVM_INIT_METHOD; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_ANNOTATIONS_CLASS_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.MODULE_INIT_CLASS_NAME; @@ -121,18 +106,20 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.NO_OF_DEPENDANT_MODULES; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.OBJECT_SELF_INSTANCE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.PARENT_MODULE_START_ATTEMPTED; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STACK; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.RECEIVE_WORKER_CHANNEL_NAMES_VAR_NAME; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.SEND_WORKER_CHANNEL_NAMES_VAR_NAME; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_CLASS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRAND_LOCAL_VARIABLE_NAME; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.TYPEDESC_VALUE; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.YIELD_LOCATION; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.YIELD_STATUS; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.CREATE_CANCELLED_FUTURE_ERROR; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.STRING_VALUE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.THROWABLE; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_CHANNELS_ADD_METHOD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_CHANNELS_COMPLETE_WITH_PANIC_METHOD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_CHANNEL_MAP; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_CHANNEL_MAP_VAR_NAME; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmConstants.WORKER_UTILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_ARRAY_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_BDECIMAL; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_BOBJECT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_BSTRING; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_ERROR_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_FUNCTION_POINTER; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_FUTURE_VALUE; @@ -146,12 +133,9 @@ import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TABLE_VALUE; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_TYPEDESC; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.GET_XML; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.INITIAL_METHOD_DESC; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.PASS_OBJECT_RETURN_OBJECT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.RETURN_OBJECT; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.STACK_FRAMES; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.UPDATE_CHANNEL_DETAILS; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.VOID_METHOD_DESC; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.WORKER_CHANNELS_ADD; +import static org.wso2.ballerinalang.compiler.bir.codegen.JvmSignatures.WORKER_CHANNELS_COMPLETE_WITH_PANIC; /** * BIR function to JVM byte code generation class. @@ -160,11 +144,6 @@ */ public class MethodGen { - protected static final String STATE = "state"; - protected static final String LOOP_VAR = "loopVar"; - protected static final String FUNCTION_INVOCATION = "functionInvocation"; - private static final String INVOCATION_COUNT = "%invocationCount"; - private static final String RESUME_INDEX = "resumeIndex"; private final JvmPackageGen jvmPackageGen; private final SymbolTable symbolTable; private final Types types; @@ -249,8 +228,6 @@ public void genJMethodForBFunc(BIRFunction func, ClassWriter cw, BIRPackage modu boolean isObjectMethodSplit) { BIRVarToJVMIndexMap indexMap = new BIRVarToJVMIndexMap(); - boolean isWorker = Symbols.isFlagOn(func.flags, Flags.WORKER); - // generate method desc int access = Opcodes.ACC_PUBLIC; // localVarOffset is actually the local var index of the strand which is passed as an argument to the function @@ -263,137 +240,69 @@ public void genJMethodForBFunc(BIRFunction func, ClassWriter cw, BIRPackage modu localVarOffset = 0; access += ACC_STATIC; } - indexMap.addIfNotExists(STRAND, symbolTable.stringType); if (isObjectMethodSplit) { indexMap.addIfNotExists(OBJECT_SELF_INSTANCE, symbolTable.anyType); } - String funcName = func.name.value; BType retType = getReturnType(func); String desc; - int invocationCountArgVarIndex = -1; - if (isWorker) { - invocationCountArgVarIndex = indexMap.addIfNotExists(INVOCATION_COUNT, symbolTable.stringType); - desc = INITIAL_METHOD_DESC + "I" + getMethodDescParams(func.type.paramTypes) + generateReturnType(retType); - } else if (isObjectMethodSplit) { + if (isObjectMethodSplit) { desc = JvmCodeGenUtil.getMethodDesc(func.type.paramTypes, retType, moduleClassName); } else { desc = JvmCodeGenUtil.getMethodDesc(func.type.paramTypes, retType); } MethodVisitor mv = cw.visitMethod(access, funcName, desc, null, null); mv.visitCode(); - visitStartFunction(module.packageID, funcName, mv); Label methodStartLabel = new Label(); mv.visitLabel(methodStartLabel); genLocalVars(indexMap, mv, func.localVars); - int returnVarRefIndex = getReturnVarRefIndex(func, indexMap, retType, mv); - int stateVarIndex = getIntVarIndex(STATE, indexMap, mv, ICONST_0); - int loopVarIndex = getIntVarIndex(LOOP_VAR, indexMap, mv, ICONST_1); - int yieldLocationVarIndex = getFrameStringVarIndex(indexMap, mv, YIELD_LOCATION); - int yieldStatusVarIndex = getFrameStringVarIndex(indexMap, mv, YIELD_STATUS); - int invocationVarIndex = getIntVarIndex(FUNCTION_INVOCATION, indexMap, mv, ICONST_0); - - mv.visitVarInsn(ALOAD, localVarOffset); - mv.visitFieldInsn(GETFIELD, STRAND_CLASS, RESUME_INDEX, "I"); - + int channelMapVarIndex = getWorkerChannelMapVarIndex(func, indexMap, mv); + List sendWorkerChannels = new ArrayList<>(); + List receiveWorkerChannels = new ArrayList<>(); + filterWorkerChannels(func, sendWorkerChannels, receiveWorkerChannels); + int sendWorkerChannelNamesVar = getSendWorkerChannelNamesVarIndex(func, indexMap, mv, sendWorkerChannels, + channelMapVarIndex, localVarOffset); + int receiveWorkerChannelNamesVar = getReceiveWorkerChannelNamesVarIndex(func, indexMap, mv, + receiveWorkerChannels, channelMapVarIndex, localVarOffset); LabelGenerator labelGen = new LabelGenerator(); - Label resumeLabel = labelGen.getLabel(funcName + "resume"); - mv.visitJumpInsn(IFGT, resumeLabel); - - // set function invocation variable - setFunctionInvocationVar(localVarOffset, mv, invocationVarIndex, invocationCountArgVarIndex, module.packageID, - funcName); - // set channel details to strand. - setChannelDetailsToStrand(func, localVarOffset, mv, invocationVarIndex); - - Label varInitLabel = labelGen.getLabel(funcName + "varinit"); - mv.visitLabel(varInitLabel); - - // panic if this strand is cancelled - checkStrandCancelled(mv, localVarOffset); - - // handle loops reducible way - Label loopLabel = new Label(); - mv.visitLabel(loopLabel); - mv.visitVarInsn(ILOAD, loopVarIndex); - Label loopConditionLabel = new Label(); - mv.visitJumpInsn(IFEQ, loopConditionLabel); - mv.visitInsn(ICONST_0); - mv.visitVarInsn(ISTORE, loopVarIndex); - - // process basic blocks - List