diff --git a/CHANGELOG.md b/CHANGELOG.md index 05ed3faa7e3b..e4b1fb43a194 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file. When sendin ### Language -- +- [Add getAllDependents and getAllDependencies method to the DependencyGraph class](https://github.com/ballerina-platform/ballerina-lang/pull/41561) - - - diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BirWriter.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BirWriter.java deleted file mode 100644 index 18b04cfa311a..000000000000 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/BirWriter.java +++ /dev/null @@ -1,69 +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.projects; - -import org.wso2.ballerinalang.compiler.tree.BLangPackage; -import org.wso2.ballerinalang.programfile.PackageFileWriter; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.StandardOpenOption; - -/** - * Write a bir to a provided path. - */ -class BirWriter { - - private BirWriter() { - - } - - /** - * Write the compiled module to a bir file. - * - * @param bLangPackage module to create the BIR for - * @param birFilePath The path to the bir file. - */ - public static void write(BLangPackage bLangPackage, Path birFilePath) { - write(bLangPackage, birFilePath, true); - } - - /** - * Write the compiled module to a bir file. - * - * @param bLangPackage compiled module - * @param birFilePath The path to the bir file. - * @param forceOverwrite whether the file should be overwritten - */ - static void write(BLangPackage bLangPackage, Path birFilePath, boolean forceOverwrite) { - try { - //TODO: write our own utility for writePackage - byte[] pkgBirBinaryContent = PackageFileWriter.writePackage(bLangPackage.symbol.birPackageFile); - if (forceOverwrite) { - Files.write(birFilePath, pkgBirBinaryContent); - } else { - Files.write(birFilePath, pkgBirBinaryContent, StandardOpenOption.CREATE_NEW); - } - } catch (IOException e) { - String msg = "error writing the compiled module(BIR) of '" + - bLangPackage.packageID + "' to '" + birFilePath + "': " + e.getMessage(); - throw new ProjectException(msg, e); - } - } -} diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DependencyGraph.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DependencyGraph.java index 784ec17c2697..9bfe85bf9466 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DependencyGraph.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DependencyGraph.java @@ -129,6 +129,22 @@ public T getRoot() { return rootNode; } + // Returns all direct and indirect dependents of the node T + public Collection getAllDependents(T node) { + Set allDependents = new HashSet<>(); + Set visited = new HashSet<>(); + getAllDependentsRecursive(node, allDependents, visited); + return allDependents; + } + + // Returns all direct and indirect dependencies of node T + public Collection getAllDependencies(T node) { + Set allDependencies = new HashSet<>(); + Set visited = new HashSet<>(); + getAllDependenciesRecursive(node, allDependencies, visited); + return allDependencies; + } + public boolean contains(T node) { return dependencies.containsKey(node); } @@ -192,6 +208,30 @@ private void sortTopologically(T vertex, List visited, List ancestors, Lis ancestors.remove(vertex); } + private void getAllDependentsRecursive(T node, Set allDependents, Set visited) { + visited.add(node); + Collection directDependents = getDirectDependents(node); + allDependents.addAll(directDependents); + + for (T dependent : directDependents) { + if (!visited.contains(dependent)) { + getAllDependentsRecursive(dependent, allDependents, visited); + } + } + } + + private void getAllDependenciesRecursive(T node, Set allDependencies, Set visited) { + visited.add(node); + Collection directDependencies = getDirectDependencies(node); + allDependencies.addAll(directDependencies); + + for (T dependency : directDependencies) { + if (!visited.contains(dependency)) { + getAllDependenciesRecursive(dependency, allDependencies, visited); + } + } + } + /** * Builds a {@code DependencyGraph}. * diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DocumentContext.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DocumentContext.java index c4a7ef1b98f5..b91b222fe5a5 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DocumentContext.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/DocumentContext.java @@ -59,7 +59,7 @@ class DocumentContext { private final DocumentId documentId; private final String name; private String content; - private boolean disableSyntaxTree = false; + private final boolean disableSyntaxTree; private DocumentContext(DocumentId documentId, String name, String content, boolean disableSyntaxTree) { this.documentId = documentId; @@ -82,14 +82,14 @@ String name() { } SyntaxTree parse() { - if (syntaxTree != null) { - return syntaxTree; + if (this.syntaxTree != null) { + return this.syntaxTree; } - if (!disableSyntaxTree) { - syntaxTree = SyntaxTree.from(this.textDocument(), name); - return syntaxTree; + if (!this.disableSyntaxTree) { + this.syntaxTree = SyntaxTree.from(this.textDocument(), this.name); + return this.syntaxTree; } - return SyntaxTree.from(this.textDocument(), name); + return SyntaxTree.from(this.textDocument(), this.name); } SyntaxTree syntaxTree() { @@ -97,25 +97,29 @@ SyntaxTree syntaxTree() { } TextDocument textDocument() { - if (this.textDocument == null) { + if (this.textDocument != null) { + return this.textDocument; + } + if (!this.disableSyntaxTree) { this.textDocument = TextDocuments.from(this.content); + return this.textDocument; } - return this.textDocument; + return TextDocuments.from(this.content); } BLangCompilationUnit compilationUnit(CompilerContext compilerContext, PackageID pkgID, SourceKind sourceKind) { BLangDiagnosticLog dlog = BLangDiagnosticLog.getInstance(compilerContext); - SyntaxTree syntaxTree = syntaxTree(); - reportSyntaxDiagnostics(pkgID, syntaxTree, dlog); + SyntaxTree synTree = syntaxTree(); + reportSyntaxDiagnostics(pkgID, synTree, dlog); - nodeCloner = NodeCloner.getInstance(compilerContext); - if (compilationUnit != null) { - return nodeCloner.cloneCUnit(compilationUnit); + this.nodeCloner = NodeCloner.getInstance(compilerContext); + if (this.compilationUnit != null) { + return this.nodeCloner.cloneCUnit(this.compilationUnit); } BLangNodeBuilder bLangNodeBuilder = new BLangNodeBuilder(compilerContext, pkgID, this.name); - compilationUnit = (BLangCompilationUnit) bLangNodeBuilder.accept(syntaxTree.rootNode()).get(0); - compilationUnit.setSourceKind(sourceKind); - return nodeCloner.cloneCUnit(compilationUnit); + this.compilationUnit = (BLangCompilationUnit) bLangNodeBuilder.accept(synTree.rootNode()).get(0); + this.compilationUnit.setSourceKind(sourceKind); + return this.nodeCloner.cloneCUnit(this.compilationUnit); } Set moduleLoadRequests(ModuleDescriptor currentModuleDesc, PackageDependencyScope scope) { @@ -129,10 +133,10 @@ Set moduleLoadRequests(ModuleDescriptor currentModuleDesc, Pa private Set getModuleLoadRequests(ModuleDescriptor currentModuleDesc, PackageDependencyScope scope) { - Set moduleLoadRequests = new LinkedHashSet<>(); + Set moduleLoadRequestSet = new LinkedHashSet<>(); ModulePartNode modulePartNode = syntaxTree().rootNode(); for (ImportDeclarationNode importDcl : modulePartNode.imports()) { - moduleLoadRequests.add(getModuleLoadRequest(importDcl, scope)); + moduleLoadRequestSet.add(getModuleLoadRequest(importDcl, scope)); } // TODO This is a temporary solution for SLP6 release @@ -145,9 +149,9 @@ private Set getModuleLoadRequests(ModuleDescriptor currentMod ModuleLoadRequest ballerinaiLoadReq = new ModuleLoadRequest( PackageOrg.from(Names.BALLERINA_INTERNAL_ORG.value), moduleName, scope, DependencyResolutionType.PLATFORM_PROVIDED); - moduleLoadRequests.add(ballerinaiLoadReq); + moduleLoadRequestSet.add(ballerinaiLoadReq); } - return moduleLoadRequests; + return moduleLoadRequestSet; } private ModuleLoadRequest getModuleLoadRequest(ImportDeclarationNode importDcl, PackageDependencyScope scope) { 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 a1063da8ed9f..2bba26323976 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 @@ -178,8 +178,10 @@ private void performCodeGen() { new PackageDiagnostic(diagnostic, moduleContext.descriptor(), moduleContext.project())); } - //TODO: remove this once ballerina-lang#41407 is fixed ModuleContext.shrinkDocuments(moduleContext); + if (moduleContext.project().kind() == ProjectKind.BALA_PROJECT) { + moduleContext.cleanBLangPackage(); + } } // add compilation diagnostics diagnostics.addAll(moduleDiagnostics); 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 6578b424fdc8..4c5f3159c77f 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 @@ -245,6 +245,10 @@ BLangPackage bLangPackage() { return getBLangPackageOrThrow(); } + protected void cleanBLangPackage() { + this.bLangPackage = null; + } + ModuleCompilationState compilationState() { return moduleCompState; } @@ -308,10 +312,6 @@ void setCompilationState(ModuleCompilationState moduleCompState) { this.moduleCompState = moduleCompState; } - void parse() { - currentCompilationState().parse(this); - } - void resolveDependencies(DependencyResolution dependencyResolution) { Set moduleDependencies = new HashSet<>(); if (this.project.kind() == ProjectKind.BALA_PROJECT) { @@ -506,12 +506,8 @@ private static boolean shouldGenerateBir(ModuleContext moduleContext, CompilerCo if (Boolean.parseBoolean(compilerOptions.get(CompilerOptionName.DUMP_BIR_FILE))) { return true; } - if (moduleContext.project.kind().equals(ProjectKind.BUILD_PROJECT) - && moduleContext.project().buildOptions().enableCache()) { - return true; - } - - return false; + return moduleContext.project.kind().equals(ProjectKind.BUILD_PROJECT) + && moduleContext.project().buildOptions().enableCache(); } private static ByteArrayOutputStream generateBIR(ModuleContext moduleContext, CompilerContext compilerContext) { @@ -560,7 +556,6 @@ static void loadPlatformSpecificCodeInternal(ModuleContext moduleContext, Compil // TODO implement } - //TODO: should be removed once we properly fix ballerina-lang#41407 static void shrinkDocuments(ModuleContext moduleContext) { moduleContext.srcDocContextMap.values().forEach(DocumentContext::shrink); } diff --git a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ModuleResolver.java b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ModuleResolver.java index acebe2f5b63d..4c0d610cfd9e 100644 --- a/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ModuleResolver.java +++ b/compiler/ballerina-lang/src/main/java/io/ballerina/projects/internal/ModuleResolver.java @@ -78,6 +78,9 @@ public PackageContainer resolveModuleLoadRequests( for (ModuleLoadRequest moduleLoadRequest : moduleLoadRequests) { resolveModuleLoadRequest(moduleLoadRequest, pkgContainer, unresolvedModuleRequests); } + if (unresolvedModuleRequests.isEmpty()) { + return pkgContainer; + } // Resolve unresolved import module declarations Collection importModResponses = diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/CodeGenerator.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/CodeGenerator.java index 4dcce2d1775d..caa42a629497 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/CodeGenerator.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/CodeGenerator.java @@ -21,6 +21,7 @@ import org.wso2.ballerinalang.compiler.PackageCache; import org.wso2.ballerinalang.compiler.bir.BIRGenUtils; import org.wso2.ballerinalang.compiler.bir.codegen.optimizer.LargeMethodOptimizer; +import org.wso2.ballerinalang.compiler.bir.model.BIRNode; import org.wso2.ballerinalang.compiler.diagnostic.BLangDiagnosticLog; import org.wso2.ballerinalang.compiler.semantics.analyzer.Types; import org.wso2.ballerinalang.compiler.semantics.model.SymbolTable; @@ -38,14 +39,12 @@ public class CodeGenerator { private static final CompilerContext.Key CODE_GEN = new CompilerContext.Key<>(); - private SymbolTable symbolTable; - private PackageCache packageCache; - private BLangDiagnosticLog dlog; - private Types types; - private LargeMethodOptimizer largeMethodOptimizer; + private final SymbolTable symbolTable; + private final PackageCache packageCache; + private final BLangDiagnosticLog dlog; + private final Types types; private CodeGenerator(CompilerContext compilerContext) { - compilerContext.put(CODE_GEN, this); this.symbolTable = SymbolTable.getInstance(compilerContext); this.packageCache = PackageCache.getInstance(compilerContext); @@ -54,12 +53,10 @@ private CodeGenerator(CompilerContext compilerContext) { } public static CodeGenerator getInstance(CompilerContext context) { - CodeGenerator codeGenerator = context.get(CODE_GEN); if (codeGenerator == null) { codeGenerator = new CodeGenerator(context); } - return codeGenerator; } @@ -75,7 +72,7 @@ public CompiledJarFile generateTestModule(BLangPackage bLangTestablePackage) { private CompiledJarFile generate(BPackageSymbol packageSymbol) { // Split large BIR functions into smaller methods - largeMethodOptimizer = new LargeMethodOptimizer(symbolTable); + LargeMethodOptimizer largeMethodOptimizer = new LargeMethodOptimizer(symbolTable); largeMethodOptimizer.splitLargeBIRFunctions(packageSymbol.bir); // Desugar BIR to include the observations @@ -93,9 +90,42 @@ private CompiledJarFile generate(BPackageSymbol packageSymbol) { // TODO Get-rid of the following assignment CompiledJarFile compiledJarFile = jvmPackageGen.generate(packageSymbol.bir, true); - + cleanUpBirPackage(packageSymbol); //Revert encoding identifier names JvmDesugarPhase.replaceEncodedModuleIdentifiers(packageSymbol.bir, originalIdentifierMap); return compiledJarFile; } + + private static void cleanUpBirPackage(BPackageSymbol packageSymbol) { + packageSymbol.birPackageFile = null; + BIRNode.BIRPackage bir = packageSymbol.bir; + for (BIRNode.BIRTypeDefinition typeDef : bir.typeDefs) { + for (BIRNode.BIRFunction attachedFunc : typeDef.attachedFuncs) { + cleanUpBirFunction(attachedFunc); + } + typeDef.annotAttachments = null; + } + bir.importedGlobalVarsDummyVarDcls.clear(); + for (BIRNode.BIRFunction function : bir.functions) { + cleanUpBirFunction(function); + } + bir.annotations.clear(); + bir.constants.clear(); + bir.serviceDecls.clear(); + } + + private static void cleanUpBirFunction(BIRNode.BIRFunction function) { + function.receiver = null; + function.localVars = null; + function.returnVariable = null; + function.parameters = null; + function.basicBlocks = null; + function.errorTable = null; + function.workerChannels = null; + function.annotAttachments = null; + function.returnTypeAnnots = null; + function.dependentGlobalVars = null; + function.pathParams = null; + function.restPathParam = null; + } } 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 58de262b3ae5..b406cce3835e 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 @@ -19,7 +19,6 @@ package org.wso2.ballerinalang.compiler.bir.codegen; import io.ballerina.identifier.Utils; -import org.ballerinalang.compiler.BLangCompilerException; import org.ballerinalang.model.elements.PackageID; import org.wso2.ballerinalang.compiler.bir.codegen.methodgen.InitMethodGen; import org.wso2.ballerinalang.compiler.bir.model.BIRNode; @@ -59,28 +58,15 @@ */ public class JvmDesugarPhase { - public static void addDefaultableBooleanVarsToSignature(BIRFunction func, BType booleanType) { + private JvmDesugarPhase() { + } + public static void addDefaultableBooleanVarsToSignature(BIRFunction func) { func.type = new BInvokableType(func.type.paramTypes, func.type.restType, func.type.retType, func.type.tsymbol); BInvokableType type = func.type; func.type.paramTypes = updateParamTypesWithDefaultableBooleanVar(func.type.paramTypes, - type.restType, booleanType); - } - - public static void enrichWithDefaultableParamInits(BIRFunction currentFunc, InitMethodGen initMethodGen) { - int k = 1; - List functionParams = new ArrayList<>(); - List localVars = currentFunc.localVars; - while (k < localVars.size()) { - BIRVariableDcl localVar = localVars.get(k); - if (localVar instanceof BIRFunctionParameter) { - functionParams.add((BIRFunctionParameter) localVar); - } - k += 1; - } - - initMethodGen.resetIds(); + type.restType); } public static BIRBasicBlock insertAndGetNextBasicBlock(List basicBlocks, @@ -94,11 +80,8 @@ public static int getNextDesugarBBId(InitMethodGen initMethodGen) { return initMethodGen.incrementAndGetNextId(); } - private static List updateParamTypesWithDefaultableBooleanVar(List funcParams, BType restType, - BType booleanType) { - + private static List updateParamTypesWithDefaultableBooleanVar(List funcParams, BType restType) { List paramTypes = new ArrayList<>(); - int counter = 0; int size = funcParams == null ? 0 : funcParams.size(); while (counter < size) { @@ -160,17 +143,6 @@ private static void rewriteRecordInitFunction(BIRFunction func, BRecordType reco func.localVars = updatedLocalVars; } - private static BIRFunctionParameter getFunctionParam(BIRFunctionParameter localVar) { - if (localVar == null) { - throw new BLangCompilerException("Invalid function parameter"); - } - - return localVar; - } - - private JvmDesugarPhase() { - } - static HashMap encodeModuleIdentifiers(BIRNode.BIRPackage module) { HashMap encodedVsInitialIds = new HashMap<>(); encodePackageIdentifiers(module.packageID, encodedVsInitialIds); @@ -276,9 +248,6 @@ private static void encodeAttachedFunctionIdentifiers(List fu private static void encodeGlobalVariableIdentifiers(List globalVars, HashMap encodedVsInitialIds) { for (BIRNode.BIRGlobalVariableDcl globalVar : globalVars) { - if (globalVar == null) { - continue; - } globalVar.name = Names.fromString(encodeNonFunctionIdentifier(globalVar.name.value, encodedVsInitialIds)); } } @@ -295,7 +264,6 @@ static void replaceEncodedModuleIdentifiers(BIRNode.BIRPackage module, HashMap encodedVsInitialIds) { replaceEncodedPackageIdentifiers(module.packageID, encodedVsInitialIds); replaceEncodedGlobalVariableIdentifiers(module.globalVars, encodedVsInitialIds); - replaceEncodedImportedGlobalVariableIdentifiers(module.importedGlobalVarsDummyVarDcls, encodedVsInitialIds); replaceEncodedFunctionIdentifiers(module.functions, encodedVsInitialIds); replaceEncodedTypeDefIdentifiers(module.typeDefs, encodedVsInitialIds); } @@ -337,12 +305,6 @@ private static void replaceEncodedFunctionIdentifiers(List function HashMap encodedVsInitialIds) { for (BIRFunction function : functions) { function.name = getInitialIdString(function.name, encodedVsInitialIds); - for (BIRNode.BIRVariableDcl localVar : function.localVars) { - if (localVar.metaVarName == null) { - continue; - } - localVar.metaVarName = getInitialIdString(localVar.metaVarName, encodedVsInitialIds); - } for (BIRNode.BIRParameter parameter : function.requiredParams) { parameter.name = getInitialIdString(parameter.name, encodedVsInitialIds); } @@ -383,16 +345,6 @@ private static void replaceEncodedAttachedFunctionIdentifiers(List globalVars, HashMap encodedVsInitialIds) { - for (BIRNode.BIRGlobalVariableDcl globalVar : globalVars) { - if (globalVar == null) { - continue; - } - globalVar.name = getInitialIdString(globalVar.name, encodedVsInitialIds); - } - } - - private static void replaceEncodedImportedGlobalVariableIdentifiers(Set globalVars, - HashMap encodedVsInitialIds) { for (BIRNode.BIRGlobalVariableDcl globalVar : globalVars) { globalVar.name = getInitialIdString(globalVar.name, encodedVsInitialIds); } @@ -416,14 +368,6 @@ private static String encodeNonFunctionIdentifier(String identifier, HashMap encodedVsInitialIds) { - String initialString = encodedVsInitialIds.get(encodedIdString); - if (initialString != null) { - return initialString; - } - return encodedIdString; - } - private static Name getInitialIdString(Name encodedIdString, HashMap encodedVsInitialIds) { String initialString = encodedVsInitialIds.get(encodedIdString.value); if (initialString != null) { 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 5d0cbc0a2304..c0fb9d134a49 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,7 +80,8 @@ void genPanic(BIRTerminator.Panic panicTerm) { } public void generateTryCatch(BIRNode.BIRFunction func, String funcName, BIRNode.BIRBasicBlock currentBB, - JvmTerminatorGen termGen, LabelGenerator labelGen, int invocationVarIndex) { + JvmTerminatorGen termGen, LabelGenerator labelGen, int invocationVarIndex, + int localVarOffset) { BIRNode.BIRErrorEntry currentEE = findErrorEntry(func.errorTable, currentBB); if (currentEE == null) { @@ -108,7 +109,7 @@ 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); + termGen.genReturnTerm(retIndex, func, invocationVarIndex, localVarOffset); this.mv.visitJumpInsn(GOTO, jumpLabel); } if (!exeptionExist) { 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 fb6454ffdea8..9e62e0c54be4 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 @@ -606,11 +606,10 @@ private BIRFunctionWrapper getBirFunctionWrapper(boolean isEntry, PackageID pack BIRFunction birFunc, String birModuleClassName) { BIRFunctionWrapper birFuncWrapperOrError; if (isExternFunc(birFunc) && isEntry) { - birFuncWrapperOrError = createExternalFunctionWrapper(isEntry, birFunc, packageID, - birModuleClassName, this); + birFuncWrapperOrError = createExternalFunctionWrapper(isEntry, birFunc, packageID, birModuleClassName); } else { if (isEntry && birFunc.receiver == null) { - addDefaultableBooleanVarsToSignature(birFunc, symbolTable.booleanType); + addDefaultableBooleanVarsToSignature(birFunc); } birFuncWrapperOrError = getFunctionWrapper(birFunc, packageID, birModuleClassName); } @@ -815,12 +814,10 @@ private BIRFunction getFunction(BIRPackage module, String funcName) { private boolean listenerDeclarationFound(BPackageSymbol packageSymbol) { if (packageSymbol.bir != null && packageSymbol.bir.isListenerAvailable) { return true; - } else { - for (BPackageSymbol importPkgSymbol : packageSymbol.imports) { - if (importPkgSymbol == null) { - continue; - } - return listenerDeclarationFound(importPkgSymbol); + } + for (BPackageSymbol importPkgSymbol : packageSymbol.imports) { + if (importPkgSymbol != null && listenerDeclarationFound(importPkgSymbol)) { + return true; } } return false; 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 5560c9c5066d..a5beae88253e 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 @@ -364,7 +364,7 @@ public void genTerminator(BIRTerminator terminator, String moduleClassName, BIRN this.genBranchTerm((BIRTerminator.Branch) terminator, funcName); return; case RETURN: - this.genReturnTerm(returnVarRefIndex, func, invocationVarIndex); + this.genReturnTerm(returnVarRefIndex, func, invocationVarIndex, localVarOffset); return; case PANIC: this.errorGen.genPanic((BIRTerminator.Panic) terminator); @@ -448,9 +448,9 @@ private void genUnlockTerm(BIRTerminator.Unlock unlockIns, String funcName) { } private void handleErrorRetInUnion(int returnVarRefIndex, List channels, BUnionType bType, - int invocationVarIndex) { + int invocationVarIndex, int localVarOffset) { - if (channels.size() == 0) { + if (channels.isEmpty()) { return; } @@ -465,7 +465,7 @@ private void handleErrorRetInUnion(int returnVarRefIndex, List channels, int retIndex, int invocationVarIndex) { - if (channels.size() == 0) { + if (channels.isEmpty()) { return; } @@ -1324,13 +1324,14 @@ private void genResourcePathArgs(List pathArgs) { mv.visitVarInsn(ALOAD, bundledArrayIndex); } - public void genReturnTerm(int returnVarRefIndex, BIRNode.BIRFunction func, int invocationVarIndex) { + public void genReturnTerm(int returnVarRefIndex, BIRNode.BIRFunction func, int invocationVarIndex, + int localVarOffset) { BType bType = unifier.build(func.type.retType); - generateReturnTermFromType(returnVarRefIndex, bType, func, invocationVarIndex); + generateReturnTermFromType(returnVarRefIndex, bType, func, invocationVarIndex, localVarOffset); } private void generateReturnTermFromType(int returnVarRefIndex, BType bType, BIRNode.BIRFunction func, - int invocationVarIndex) { + int invocationVarIndex, int localVarOffset) { bType = JvmCodeGenUtil.getImpliedType(bType); if (TypeTags.isIntegerTypeTag(bType.tag)) { this.mv.visitVarInsn(LLOAD, returnVarRefIndex); @@ -1377,7 +1378,7 @@ private void generateReturnTermFromType(int returnVarRefIndex, BType bType, BIRN break; case TypeTags.UNION: this.handleErrorRetInUnion(returnVarRefIndex, Arrays.asList(func.workerChannels), - (BUnionType) bType, invocationVarIndex); + (BUnionType) bType, invocationVarIndex, localVarOffset); this.mv.visitVarInsn(ALOAD, returnVarRefIndex); this.mv.visitInsn(ARETURN); break; 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 6fda06146a15..7c01b0918acc 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 @@ -104,7 +104,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.JvmDesugarPhase.enrichWithDefaultableParamInits; 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; @@ -172,13 +171,13 @@ private static void desugarObjectMethods(List attachedFuncs, InitMe if (JvmCodeGenUtil.isExternFunc(birFunc)) { if (birFunc instanceof JMethodBIRFunction) { desugarInteropFuncs((JMethodBIRFunction) birFunc, initMethodGen); - enrichWithDefaultableParamInits(birFunc, initMethodGen); + initMethodGen.resetIds(); } else if (!(birFunc instanceof JFieldBIRFunction)) { - enrichWithDefaultableParamInits(birFunc, initMethodGen); + initMethodGen.resetIds(); } } else { - addDefaultableBooleanVarsToSignature(birFunc, jvmPackageGen.symbolTable.booleanType); - enrichWithDefaultableParamInits(birFunc, initMethodGen); + addDefaultableBooleanVarsToSignature(birFunc); + initMethodGen.resetIds(); } } } diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/ExternalMethodGen.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/ExternalMethodGen.java index 0a5c63acbad1..821a0b48e45c 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/ExternalMethodGen.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/bir/codegen/interop/ExternalMethodGen.java @@ -35,7 +35,6 @@ import java.util.List; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmDesugarPhase.addDefaultableBooleanVarsToSignature; -import static org.wso2.ballerinalang.compiler.bir.codegen.JvmDesugarPhase.enrichWithDefaultableParamInits; import static org.wso2.ballerinalang.compiler.bir.codegen.JvmPackageGen.getFunctionWrapper; import static org.wso2.ballerinalang.compiler.bir.codegen.interop.InteropMethodGen.desugarInteropFuncs; import static org.wso2.ballerinalang.compiler.bir.codegen.interop.InteropMethodGen.genJFieldForInteropField; @@ -73,19 +72,18 @@ public static void injectDefaultParamInits(BIRPackage module, InitMethodGen init count = count + 1; if (birFunc instanceof JMethodBIRFunction) { desugarInteropFuncs((JMethodBIRFunction) birFunc, initMethodGen); - enrichWithDefaultableParamInits(birFunc, initMethodGen); + initMethodGen.resetIds(); } else if (!(birFunc instanceof JFieldBIRFunction)) { - enrichWithDefaultableParamInits(birFunc, initMethodGen); + initMethodGen.resetIds(); } } } } public static BIRFunctionWrapper createExternalFunctionWrapper(boolean isEntry, BIRFunction birFunc, - PackageID packageID, String birModuleClassName, - JvmPackageGen jvmPackageGen) { + PackageID packageID, String birModuleClassName) { if (isEntry) { - addDefaultableBooleanVarsToSignature(birFunc, jvmPackageGen.symbolTable.booleanType); + addDefaultableBooleanVarsToSignature(birFunc); } return getFunctionWrapper(birFunc, packageID, birModuleClassName); } 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 35108c9113ab..6d92a296b5a6 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 @@ -241,7 +241,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); + termGen.genReturnTerm(returnVarRefIndex, birFunc, -1, 0); JvmCodeGenUtil.visitMaxStackForMethod(mv, birFunc.name.value, birFunc.javaField.getDeclaringClassName()); mv.visitEnd(); } 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 914adac9463c..36c007ea7e8e 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 @@ -376,7 +376,7 @@ public void genJMethodForBFunc(BIRFunction func, ClassWriter cw, BIRPackage modu Label methodEndLabel = new Label(); mv.visitLabel(methodEndLabel); - termGen.genReturnTerm(returnVarRefIndex, func, invocationVarIndex); + termGen.genReturnTerm(returnVarRefIndex, func, invocationVarIndex, localVarOffset); // Create Local Variable Table createLocalVariableTable(func, indexMap, localVarOffset, mv, methodStartLabel, labelGen, methodEndLabel, @@ -639,7 +639,7 @@ void generateBasicBlocks(MethodVisitor mv, LabelGenerator labelGen, JvmErrorGen lastScope = JvmCodeGenUtil .getLastScopeFromTerminator(mv, bb, funcName, labelGen, lastScope, visitedScopesSet); - errorGen.generateTryCatch(func, funcName, bb, termGen, labelGen, invocationVarIndex); + errorGen.generateTryCatch(func, funcName, bb, termGen, labelGen, invocationVarIndex, localVarOffset); String yieldStatus = getYieldStatusByTerminator(terminator); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java index a64cc3158e1f..6717ab79d19c 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/analyzer/SymbolEnter.java @@ -1116,10 +1116,8 @@ public void visit(BLangImportPackage importPkgNode) { return; } - List imports = ((BPackageSymbol) this.env.scope.owner).imports; - if (!imports.contains(pkgSymbol)) { - imports.add(pkgSymbol); - } + Set imports = ((BPackageSymbol) this.env.scope.owner).imports; + imports.add(pkgSymbol); // get a copy of the package symbol, add compilation unit info to it, // and define it in the current package scope @@ -1134,7 +1132,6 @@ public void visit(BLangImportPackage importPkgNode) { public void initPredeclaredModules(Map predeclaredModules, List compUnits, SymbolEnv env) { - SymbolEnv prevEnv = this.env; this.env = env; for (Map.Entry predeclaredModuleEntry : predeclaredModules.entrySet()) { Name alias = predeclaredModuleEntry.getKey(); diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/symbols/BPackageSymbol.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/symbols/BPackageSymbol.java index 19ac138d2fb4..aecf695a9253 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/symbols/BPackageSymbol.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/semantics/model/symbols/BPackageSymbol.java @@ -29,9 +29,9 @@ import org.wso2.ballerinalang.programfile.CompiledBinaryFile.BIRPackageFile; import org.wso2.ballerinalang.programfile.CompiledBinaryFile.PackageFile; -import java.util.ArrayList; -import java.util.List; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; import static org.wso2.ballerinalang.compiler.semantics.model.symbols.SymTag.PACKAGE; @@ -42,7 +42,7 @@ public class BPackageSymbol extends BTypeSymbol { public BInvokableSymbol initFunctionSymbol, startFunctionSymbol, stopFunctionSymbol, testInitFunctionSymbol, testStartFunctionSymbol, testStopFunctionSymbol; - public List imports = new ArrayList<>(); + public Set imports = new HashSet<>(); public PackageFile packageFile; public CompiledPackage compiledPackage; public Name compUnit; diff --git a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/createvar/CreateVariableWithTypeCodeAction.java b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/createvar/CreateVariableWithTypeCodeAction.java index 56652d78ad7c..983975973206 100644 --- a/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/createvar/CreateVariableWithTypeCodeAction.java +++ b/language-server/modules/langserver-core/src/main/java/org/ballerinalang/langserver/codeaction/providers/createvar/CreateVariableWithTypeCodeAction.java @@ -261,7 +261,7 @@ private String getTypeName(TypeSymbol symbol, CodeActionContext context) { : getRawType(symbol, context).signature()); return FunctionGenerator.processModuleIDsInText(new ImportsAcceptor(context), moduleQualifiedName, context); } - return symbol.signature(); + return FunctionGenerator.processModuleIDsInText(new ImportsAcceptor(context), symbol.signature(), context); } private boolean isLangAnnotationModule(ModuleID moduleID) { diff --git a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/CreateVariableWithTypeTest.java b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/CreateVariableWithTypeTest.java index 68a08a1a9f92..c4f21743ff11 100644 --- a/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/CreateVariableWithTypeTest.java +++ b/language-server/modules/langserver-core/src/test/java/org/ballerinalang/langserver/codeaction/CreateVariableWithTypeTest.java @@ -52,6 +52,7 @@ public Object[][] dataProvider() { {"type_infer_for_remote_method_call_config1.json"}, {"type_infer_for_remote_method_call_config2.json"}, {"type_infer_for_resource_action_config.json"}, + {"type_infer_for_resource_action_config2.json"}, {"type_infer_for_resource_action_with_check1.json"}, {"type_infer_for_resource_action_with_check2.json"} }; diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-var-with-type/config/type_infer_for_resource_action_config2.json b/language-server/modules/langserver-core/src/test/resources/codeaction/create-var-with-type/config/type_infer_for_resource_action_config2.json new file mode 100644 index 000000000000..08c983678a70 --- /dev/null +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-var-with-type/config/type_infer_for_resource_action_config2.json @@ -0,0 +1,29 @@ +{ + "position": { + "line": 27, + "character": 23 + }, + "source": "source1.bal", + "expected": [ + { + "title": "Create variable", + "kind": "quickfix", + "edits": [ + { + "range": { + "start": { + "line": 27, + "character": 4 + }, + "end": { + "line": 27, + "character": 4 + } + }, + "newText": "stream streamResult = " + } + ], + "resolvable": false + } + ] +} diff --git a/language-server/modules/langserver-core/src/test/resources/codeaction/create-var-with-type/source/source1.bal b/language-server/modules/langserver-core/src/test/resources/codeaction/create-var-with-type/source/source1.bal index 089970262b8e..eb66ff0be1ba 100644 --- a/language-server/modules/langserver-core/src/test/resources/codeaction/create-var-with-type/source/source1.bal +++ b/language-server/modules/langserver-core/src/test/resources/codeaction/create-var-with-type/source/source1.bal @@ -23,3 +23,7 @@ function testRemoteMethodCallWithCheck() returns error? { function testRemoteMethodCallWithCheck2() returns error? { check 'client->/path4/["pathParam"]; } + +function testResourceAccessOfStreamReturnType() returns error? { + 'client->/responses +} diff --git a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/client_resource_access_action_config21.json b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/client_resource_access_action_config21.json index dc6db1d61e51..0926b8d372f0 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/client_resource_access_action_config21.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/client_resource_access_action_config21.json @@ -243,6 +243,40 @@ "title": "editor.action.triggerParameterHints", "command": "editor.action.triggerParameterHints" } + }, + { + "label": "/responses(module1:TargetType2 targetType)", + "kind": "Function", + "detail": "stream", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/module1:0.1.0_ \n \nSample resource function to return a stream of objects\n \n**Params** \n- `module1:TargetType2` targetType: Response or `anydata`, which is expected to be returned after data binding(Defaultable) \n \n**Return** `stream` \n- A stream of targetType and/or ClientError \n \n" + } + }, + "sortText": "C", + "filterText": "responses|get", + "insertText": "/responses(${1});", + "insertTextFormat": "Snippet", + "additionalTextEdits": [ + { + "range": { + "start": { + "line": 5, + "character": 22 + }, + "end": { + "line": 5, + "character": 23 + } + }, + "newText": "" + } + ], + "command": { + "title": "editor.action.triggerParameterHints", + "command": "editor.action.triggerParameterHints" + } } ] } diff --git a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/client_resource_access_action_config8.json b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/client_resource_access_action_config8.json index 4c5ef064d217..91e45276bc73 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/client_resource_access_action_config8.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/client_resource_access_action_config8.json @@ -214,6 +214,25 @@ "title": "editor.action.triggerParameterHints", "command": "editor.action.triggerParameterHints" } + }, + { + "label": "/responses(module1:TargetType2 targetType)", + "kind": "Function", + "detail": "stream", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/module1:0.1.0_ \n \nSample resource function to return a stream of objects\n \n**Params** \n- `module1:TargetType2` targetType: Response or `anydata`, which is expected to be returned after data binding(Defaultable) \n \n**Return** `stream` \n- A stream of targetType and/or ClientError \n \n" + } + }, + "sortText": "CC", + "filterText": "responses|get", + "insertText": "/responses(${1});", + "insertTextFormat": "Snippet", + "command": { + "title": "editor.action.triggerParameterHints", + "command": "editor.action.triggerParameterHints" + } } ] } diff --git a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config1.json b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config1.json index 3b332de160c9..3aac992a0ee8 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config1.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config1.json @@ -214,6 +214,25 @@ "title": "editor.action.triggerParameterHints", "command": "editor.action.triggerParameterHints" } + }, + { + "label": "/responses(module1:TargetType2 targetType)", + "kind": "Function", + "detail": "stream", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/module1:0.1.0_ \n \nSample resource function to return a stream of objects\n \n**Params** \n- `module1:TargetType2` targetType: Response or `anydata`, which is expected to be returned after data binding(Defaultable) \n \n**Return** `stream` \n- A stream of targetType and/or ClientError \n \n" + } + }, + "sortText": "CC", + "filterText": "responses|get", + "insertText": "/responses(${1});", + "insertTextFormat": "Snippet", + "command": { + "title": "editor.action.triggerParameterHints", + "command": "editor.action.triggerParameterHints" + } } ] } diff --git a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config2.json b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config2.json index c0a587a73e29..0deebde40c30 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config2.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config2.json @@ -214,6 +214,25 @@ "title": "editor.action.triggerParameterHints", "command": "editor.action.triggerParameterHints" } + }, + { + "label": "/responses(module1:TargetType2 targetType)", + "kind": "Function", + "detail": "stream", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/module1:0.1.0_ \n \nSample resource function to return a stream of objects\n \n**Params** \n- `module1:TargetType2` targetType: Response or `anydata`, which is expected to be returned after data binding(Defaultable) \n \n**Return** `stream` \n- A stream of targetType and/or ClientError \n \n" + } + }, + "sortText": "CC", + "filterText": "responses|get", + "insertText": "/responses(${1});", + "insertTextFormat": "Snippet", + "command": { + "title": "editor.action.triggerParameterHints", + "command": "editor.action.triggerParameterHints" + } } ] } diff --git a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config4.json b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config4.json index 83cc41d3921e..e56c92acc586 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config4.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config4.json @@ -214,6 +214,25 @@ "title": "editor.action.triggerParameterHints", "command": "editor.action.triggerParameterHints" } + }, + { + "label": "/responses(mod:TargetType2 targetType)", + "kind": "Function", + "detail": "stream", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/module1:0.1.0_ \n \nSample resource function to return a stream of objects\n \n**Params** \n- `mod:TargetType2` targetType: Response or `anydata`, which is expected to be returned after data binding(Defaultable) \n \n**Return** `stream` \n- A stream of targetType and/or ClientError \n \n" + } + }, + "sortText": "CC", + "filterText": "responses|get", + "insertText": "/responses(${1});", + "insertTextFormat": "Snippet", + "command": { + "title": "editor.action.triggerParameterHints", + "command": "editor.action.triggerParameterHints" + } } ] } diff --git a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config5.json b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config5.json index 9951cbdc988f..9e861cc4ed87 100644 --- a/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config5.json +++ b/language-server/modules/langserver-core/src/test/resources/completion/action_node_context/config/remote_action_config5.json @@ -214,6 +214,25 @@ "title": "editor.action.triggerParameterHints", "command": "editor.action.triggerParameterHints" } + }, + { + "label": "/responses(module1:TargetType2 targetType)", + "kind": "Function", + "detail": "stream", + "documentation": { + "right": { + "kind": "markdown", + "value": "**Package:** _ballerina/module1:0.1.0_ \n \nSample resource function to return a stream of objects\n \n**Params** \n- `module1:TargetType2` targetType: Response or `anydata`, which is expected to be returned after data binding(Defaultable) \n \n**Return** `stream` \n- A stream of targetType and/or ClientError \n \n" + } + }, + "sortText": "CC", + "filterText": "responses|get", + "insertText": "/responses(${1});", + "insertTextFormat": "Snippet", + "command": { + "title": "editor.action.triggerParameterHints", + "command": "editor.action.triggerParameterHints" + } } ] } diff --git a/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_for_api_docs_client.json b/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_for_api_docs_client.json index 7eb4f891af0e..648683a43532 100644 --- a/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_for_api_docs_client.json +++ b/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_for_api_docs_client.json @@ -10,7 +10,7 @@ "result": { "contents": { "kind": "markdown", - "value": "The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs. \n \n--- \n \n### Fields \n \n`string` ***url*** : Target service url \n \n--- \n \n### Methods \n \n+ `remote function post(string path, module1:RequestMessage message, string targetType) returns module1:Response` \nThe `Client.post()` function can be used to send HTTP POST requests to HTTP endpoints. \n \n+ `resource function post path1/[string id1]/path2/[string... ids] (string str, string... ids2) returns module1:Response` \nSample resource method. \n \n+ `remote function get(string path, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample remote method with java interoperability \n \n+ `remote function forward(string path, handle request, module1:TargetType targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `remote function delete(module1:TargetType2 targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `resource function get path3 (module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with java interoperability \n \n+ `resource function get path4/[string pathParam] (module1:TargetType targetType) returns targetType|module1:ClientError|error` \nSample resource function with multiple target types with java interoperability \n \n+ `isolated resource function post [string... path] (module1:RequestMessage message, map? headers, string? mediaType, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with rest path praram with multiple target types with java interoperability \n \n \n--- \n \n[View API Docs](https://lib.ballerina.io/ballerina/module1/0.1.0#Client)" + "value": "The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs. \n \n--- \n \n### Fields \n \n`string` ***url*** : Target service url \n \n--- \n \n### Methods \n \n+ `remote function post(string path, module1:RequestMessage message, string targetType) returns module1:Response` \nThe `Client.post()` function can be used to send HTTP POST requests to HTTP endpoints. \n \n+ `resource function post path1/[string id1]/path2/[string... ids] (string str, string... ids2) returns module1:Response` \nSample resource method. \n \n+ `remote function get(string path, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample remote method with java interoperability \n \n+ `remote function forward(string path, handle request, module1:TargetType targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `remote function delete(module1:TargetType2 targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `resource function get path3 (module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with java interoperability \n \n+ `resource function get path4/[string pathParam] (module1:TargetType targetType) returns targetType|module1:ClientError|error` \nSample resource function with multiple target types with java interoperability \n \n+ `isolated resource function post [string... path] (module1:RequestMessage message, map? headers, string? mediaType, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with rest path praram with multiple target types with java interoperability \n \n+ `isolated resource function get responses (module1:TargetType2 targetType) returns stream` \nSample resource function to return a stream of objects \n \n \n--- \n \n[View API Docs](https://lib.ballerina.io/ballerina/module1/0.1.0#Client)" } }, "id": { diff --git a/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_performance.json b/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_performance.json index 83cee93ac2e2..41a7543de1a0 100644 --- a/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_performance.json +++ b/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_performance.json @@ -10,7 +10,7 @@ "result": { "contents": { "kind": "markdown", - "value": "The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs. \n \n--- \n \n### Fields \n \n`string` ***url*** : Target service url \n \n--- \n \n### Methods \n \n+ `remote function post(string path, module1:RequestMessage message, string targetType) returns module1:Response` \nThe `Client.post()` function can be used to send HTTP POST requests to HTTP endpoints. \n \n+ `resource function post path1/[string id1]/path2/[string... ids] (string str, string... ids2) returns module1:Response` \nSample resource method. \n \n+ `remote function get(string path, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample remote method with java interoperability \n \n+ `remote function forward(string path, handle request, module1:TargetType targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `remote function delete(module1:TargetType2 targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `resource function get path3 (module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with java interoperability \n \n+ `resource function get path4/[string pathParam] (module1:TargetType targetType) returns targetType|module1:ClientError|error` \nSample resource function with multiple target types with java interoperability \n \n+ `isolated resource function post [string... path] (module1:RequestMessage message, map? headers, string? mediaType, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with rest path praram with multiple target types with java interoperability \n \n \n--- \n \n[View API Docs](https://lib.ballerina.io/ballerina/module1/0.1.0#Client)" + "value": "The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs. \n \n--- \n \n### Fields \n \n`string` ***url*** : Target service url \n \n--- \n \n### Methods \n \n+ `remote function post(string path, module1:RequestMessage message, string targetType) returns module1:Response` \nThe `Client.post()` function can be used to send HTTP POST requests to HTTP endpoints. \n \n+ `resource function post path1/[string id1]/path2/[string... ids] (string str, string... ids2) returns module1:Response` \nSample resource method. \n \n+ `remote function get(string path, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample remote method with java interoperability \n \n+ `remote function forward(string path, handle request, module1:TargetType targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `remote function delete(module1:TargetType2 targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `resource function get path3 (module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with java interoperability \n \n+ `resource function get path4/[string pathParam] (module1:TargetType targetType) returns targetType|module1:ClientError|error` \nSample resource function with multiple target types with java interoperability \n \n+ `isolated resource function post [string... path] (module1:RequestMessage message, map? headers, string? mediaType, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with rest path praram with multiple target types with java interoperability \n \n+ `isolated resource function get responses (module1:TargetType2 targetType) returns stream` \nSample resource function to return a stream of objects \n \n \n--- \n \n[View API Docs](https://lib.ballerina.io/ballerina/module1/0.1.0#Client)" } }, "id": { diff --git a/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_typeref1.json b/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_typeref1.json index 83cee93ac2e2..41a7543de1a0 100644 --- a/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_typeref1.json +++ b/language-server/modules/langserver-core/src/test/resources/hover/configs/hover_typeref1.json @@ -10,7 +10,7 @@ "result": { "contents": { "kind": "markdown", - "value": "The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs. \n \n--- \n \n### Fields \n \n`string` ***url*** : Target service url \n \n--- \n \n### Methods \n \n+ `remote function post(string path, module1:RequestMessage message, string targetType) returns module1:Response` \nThe `Client.post()` function can be used to send HTTP POST requests to HTTP endpoints. \n \n+ `resource function post path1/[string id1]/path2/[string... ids] (string str, string... ids2) returns module1:Response` \nSample resource method. \n \n+ `remote function get(string path, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample remote method with java interoperability \n \n+ `remote function forward(string path, handle request, module1:TargetType targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `remote function delete(module1:TargetType2 targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `resource function get path3 (module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with java interoperability \n \n+ `resource function get path4/[string pathParam] (module1:TargetType targetType) returns targetType|module1:ClientError|error` \nSample resource function with multiple target types with java interoperability \n \n+ `isolated resource function post [string... path] (module1:RequestMessage message, map? headers, string? mediaType, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with rest path praram with multiple target types with java interoperability \n \n \n--- \n \n[View API Docs](https://lib.ballerina.io/ballerina/module1/0.1.0#Client)" + "value": "The HTTP client provides the capability for initiating contact with a remote HTTP service. The API it\nprovides includes functions for the standard HTTP methods, forwarding a received request and sending requests\nusing custom HTTP verbs. \n \n--- \n \n### Fields \n \n`string` ***url*** : Target service url \n \n--- \n \n### Methods \n \n+ `remote function post(string path, module1:RequestMessage message, string targetType) returns module1:Response` \nThe `Client.post()` function can be used to send HTTP POST requests to HTTP endpoints. \n \n+ `resource function post path1/[string id1]/path2/[string... ids] (string str, string... ids2) returns module1:Response` \nSample resource method. \n \n+ `remote function get(string path, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample remote method with java interoperability \n \n+ `remote function forward(string path, handle request, module1:TargetType targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `remote function delete(module1:TargetType2 targetType) returns targetType` \nSample remote method with java interoperability \n \n+ `resource function get path3 (module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with java interoperability \n \n+ `resource function get path4/[string pathParam] (module1:TargetType targetType) returns targetType|module1:ClientError|error` \nSample resource function with multiple target types with java interoperability \n \n+ `isolated resource function post [string... path] (module1:RequestMessage message, map? headers, string? mediaType, module1:TargetType targetType) returns targetType|module1:ClientError` \nSample resource function with rest path praram with multiple target types with java interoperability \n \n+ `isolated resource function get responses (module1:TargetType2 targetType) returns stream` \nSample resource function to return a stream of objects \n \n \n--- \n \n[View API Docs](https://lib.ballerina.io/ballerina/module1/0.1.0#Client)" } }, "id": { diff --git a/language-server/modules/langserver-stdlib/src/main/ballerina/clients_source1.bal b/language-server/modules/langserver-stdlib/src/main/ballerina/clients_source1.bal index 4ac0d14425fd..2b6db9930653 100644 --- a/language-server/modules/langserver-stdlib/src/main/ballerina/clients_source1.bal +++ b/language-server/modules/langserver-stdlib/src/main/ballerina/clients_source1.bal @@ -93,6 +93,16 @@ public client class Client { 'class: "org.ballerinalang.langserver.stdlib.ClientAction", name: "postResource" } external; + + + # Sample resource function to return a stream of objects + # + # + targetType - Response or `anydata`, which is expected to be returned after data binding + # + return - A stream of targetType and/or ClientError + isolated resource function get responses(TargetType2 targetType = <>) returns stream = @java:Method { + 'class: "org.ballerinalang.langserver.stdlib.ClientAction", + name: "responses" + } external; } # Represents a response. diff --git a/language-server/modules/langserver-stdlib/src/main/java/org/ballerinalang/langserver/stdlib/ClientAction.java b/language-server/modules/langserver-stdlib/src/main/java/org/ballerinalang/langserver/stdlib/ClientAction.java index 7c6aa52dc890..92494df24e38 100644 --- a/language-server/modules/langserver-stdlib/src/main/java/org/ballerinalang/langserver/stdlib/ClientAction.java +++ b/language-server/modules/langserver-stdlib/src/main/java/org/ballerinalang/langserver/stdlib/ClientAction.java @@ -15,8 +15,11 @@ */ package org.ballerinalang.langserver.stdlib; +import io.ballerina.runtime.api.creators.TypeCreator; +import io.ballerina.runtime.api.creators.ValueCreator; import io.ballerina.runtime.api.values.BArray; import io.ballerina.runtime.api.values.BObject; +import io.ballerina.runtime.api.values.BStream; import io.ballerina.runtime.api.values.BString; import io.ballerina.runtime.api.values.BTypedesc; @@ -42,6 +45,10 @@ public static Object delete(BTypedesc targetType) { return new Object(); } + public static BStream responses(BTypedesc targetType) { + return ValueCreator.createStreamValue(TypeCreator.createStreamType(targetType.getDescribingType())); + } + public static Object postResource(BArray path, Object message, Object headers, Object mediaType, BTypedesc targetType) { return new Object(); diff --git a/project-api/project-api-test/src/test/java/io/ballerina/projects/test/DependencyGraphTests.java b/project-api/project-api-test/src/test/java/io/ballerina/projects/test/DependencyGraphTests.java index f6ccbb0f2795..3d1696388f01 100644 --- a/project-api/project-api-test/src/test/java/io/ballerina/projects/test/DependencyGraphTests.java +++ b/project-api/project-api-test/src/test/java/io/ballerina/projects/test/DependencyGraphTests.java @@ -58,8 +58,10 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; @@ -628,6 +630,56 @@ public void testVersionResolutionHARD() { ResolutionResponse.ResolutionStatus.RESOLVED); } + @Test + public void testGetAllDependents() { + // Create a sample DependencyGraph with String nodes + DependencyGraph dependencyGraph = DependencyGraph.from(new LinkedHashMap<>() {{ + put("A", new LinkedHashSet<>() {{ + add("B"); + add("C"); + }}); + put("B", new LinkedHashSet<>() {{ + add("D"); + }}); + put("C", new LinkedHashSet<>()); + put("D", new LinkedHashSet<>()); + put("E", new LinkedHashSet<>() {{ + add("F"); + }}); + put("F", new LinkedHashSet<>()); + }}); + + Collection allDependents = dependencyGraph.getAllDependents("D"); + Set expectedDependents = new HashSet<>(Arrays.asList("A", "B")); + + Assert.assertEquals(expectedDependents, allDependents); + } + + @Test + public void testGetAllDependencies() { + // Create a sample DependencyGraph with String nodes + DependencyGraph dependencyGraph = DependencyGraph.from(new LinkedHashMap<>() {{ + put("A", new LinkedHashSet<>() {{ + add("B"); + add("C"); + }}); + put("B", new LinkedHashSet<>() {{ + add("D"); + }}); + put("C", new LinkedHashSet<>()); + put("D", new LinkedHashSet<>()); + put("E", new LinkedHashSet<>() {{ + add("F"); + }}); + put("F", new LinkedHashSet<>()); + }}); + + Collection allDependencies = dependencyGraph.getAllDependencies("A"); + Set expectedDependencies = new HashSet<>(Arrays.asList("B", "C", "D")); + + Assert.assertEquals(expectedDependencies, allDependencies); + } + @Test public void testTopologicalSortOfModuleDescriptor() { PackageName packageName = PackageName.from("package"); diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/bala/listener/ListenerBalaTestExtPackage.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/bala/listener/ListenerBalaTestExtPackage.java index 21db7794d06f..3d6c978b3035 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/bala/listener/ListenerBalaTestExtPackage.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/bala/listener/ListenerBalaTestExtPackage.java @@ -20,8 +20,6 @@ import org.ballerinalang.test.BCompileUtil; import org.ballerinalang.test.BRunUtil; import org.ballerinalang.test.CompileResult; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** @@ -29,22 +27,21 @@ */ public class ListenerBalaTestExtPackage { - private CompileResult compileResult; - - @BeforeClass - public void setup() { - BCompileUtil.compileAndCacheBala("test-src/bala/test_projects/test_listener"); - compileResult = BCompileUtil.compile("test-src/bala/test_bala/listener/external_packaged_listener_access.bal"); - } - @Test(description = "Test access listener in different package") - public void testListenerObjectDefinedInDifferentPackage() { + public void testListenerObjectDefinedInDifferentPackages() { + BCompileUtil.compileAndCacheBala("test-src/bala/test_projects/test_listener"); + CompileResult compileResult = BCompileUtil.compile( + "test-src/bala/test_bala/listener/external_packaged_listener_access.bal"); BRunUtil.invoke(compileResult, "getStartAndAttachCount"); } - @AfterClass - public void tearDown() { - compileResult = null; + @Test(description = "Test listeners defined only in a different package") + public void testListenerObjectDefinedOnlyInADifferentPackage() { + BCompileUtil.compileAndCacheBala("test-src/bala/test_projects/test_listener_non_default"); + CompileResult compileResult = BCompileUtil.compile( + "test-src/bala/test_bala/listener/external_packaged_listener_access_non_default_module.bal"); + BRunUtil.invoke(compileResult, "main"); } + } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/bir/BIRModelTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/bir/BIRModelTest.java index cf851886076f..165cb3988864 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/bir/BIRModelTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/bir/BIRModelTest.java @@ -22,8 +22,6 @@ import org.ballerinalang.test.CompileResult; import org.testng.Assert; import org.testng.annotations.Test; -import org.wso2.ballerinalang.compiler.bir.model.BIRNode; -import org.wso2.ballerinalang.compiler.tree.BLangPackage; /** * This class contains unit tests to cover AST to BIR lowering. @@ -36,7 +34,5 @@ public class BIRModelTest { public void testBIRGen() { CompileResult result = BCompileUtil.compile("test-src/bir/bir_model.bal"); Assert.assertEquals(result.getErrorCount(), 0); - - BIRNode.BIRPackage birPackage = ((BLangPackage) result.getAST()).symbol.bir; } } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/services/ErrorReturnTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/services/ErrorReturnTest.java index d54e976131e2..e2dd52999198 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/services/ErrorReturnTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/services/ErrorReturnTest.java @@ -33,4 +33,11 @@ public void testErrorReturnFunction() { CompileResult compileResult = BCompileUtil.compile("test-src/services/error_return_function.bal"); BRunUtil.invoke(compileResult, "testErrorFunction"); } + + @Test(description = "Tests invoking a function with default worker returning an error union value in a service") + public void testErrorReturnFunctionWithDistinctListenerArg() { + CompileResult compileResult = BCompileUtil.compile( + "test-src/services/error_union_return_with_default_worker.bal"); + BRunUtil.invoke(compileResult, "testErrorUnionWithDefaultWorkerFunction"); + } } diff --git a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/statements/vardeclr/ModuleListenerDeclTest.java b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/statements/vardeclr/ModuleListenerDeclTest.java index 2acfdc68cd18..9d5234bd0e34 100644 --- a/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/statements/vardeclr/ModuleListenerDeclTest.java +++ b/tests/jballerina-unit-test/src/test/java/org/ballerinalang/test/statements/vardeclr/ModuleListenerDeclTest.java @@ -18,6 +18,7 @@ import org.ballerinalang.test.BAssertUtil; import org.ballerinalang.test.BCompileUtil; +import org.ballerinalang.test.BRunUtil; import org.ballerinalang.test.CompileResult; import org.testng.Assert; import org.testng.annotations.Test; @@ -35,6 +36,12 @@ public void testModuleListenerDeclaration() { Assert.assertEquals(result.getErrorCount(), 0); } + @Test + public void testImportedModuleListenersDeclarations() { + CompileResult result = BCompileUtil.compile("test-src/statements/vardeclr/listener-project"); + BRunUtil.invoke(result, "main"); + } + @Test public void testModuleLevelErrorVarDeclNegative() { CompileResult result = BCompileUtil.compile("test-src/statements/vardeclr/module_listener_decl_negative.bal"); diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_bala/listener/external_packaged_listener_access_non_default_module.bal b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_bala/listener/external_packaged_listener_access_non_default_module.bal new file mode 100644 index 000000000000..722efe510bf4 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_bala/listener/external_packaged_listener_access_non_default_module.bal @@ -0,0 +1,28 @@ +// Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/test; +import listenerproject/test_listener_external as _; + +int count = 0; + +function init() returns error? { + count += 1; +} + +public function main() { + test:assertEquals(count, 1); +} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener/listener.bal b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener/listener.bal index a51507729485..ddc6faee5080 100644 --- a/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener/listener.bal +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener/listener.bal @@ -1,9 +1,25 @@ +// Copyright (c) 2019, 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. + int startCount = 0; int attachCount = 0; -public function getStartAndAttachCount() returns string { - return attachCount.toString() + "_" + startCount.toString(); -} +public listener ABC ep = new ABC(); +public listener ep1 = new ABC(); +listener ep3 = new ABC(); public class ABC { @@ -30,6 +46,6 @@ public class ABC { } } -public listener ABC ep = new ABC(); -public listener ep1 = new ABC(); -listener ep3 = new ABC(); +public function getStartAndAttachCount() returns string { + return attachCount.toString() + "_" + startCount.toString(); +} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener_non_default/Ballerina.toml b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener_non_default/Ballerina.toml new file mode 100644 index 000000000000..dcb16803828a --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener_non_default/Ballerina.toml @@ -0,0 +1,5 @@ +[package] +org = "listenerproject" +name = "test_listener_external" +version = "0.0.0" +export = ["test_listener_external", "test_listener_external.ext"] diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener_non_default/listener.bal b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener_non_default/listener.bal new file mode 100644 index 000000000000..33da00de0324 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener_non_default/listener.bal @@ -0,0 +1,27 @@ +// Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ballerina/test; +import test_listener_external.ext; + +function init() returns error? { + check ext:ep.start(); + test:assertEquals(ext:getStartAndAttachCount(), "0_1"); + check ext:ep1.start(); + test:assertEquals(ext:getStartAndAttachCount(), "0_2"); + check ext:startNonPublicListener(); + test:assertEquals(ext:getStartAndAttachCount(), "0_3"); +} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener_non_default/modules/ext/listener.bal b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener_non_default/modules/ext/listener.bal new file mode 100644 index 000000000000..0fb99d862364 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/bala/test_projects/test_listener_non_default/modules/ext/listener.bal @@ -0,0 +1,55 @@ +// 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. + +int startCount = 0; +int attachCount = 0; + +public listener ABC ep = new ABC(); +public listener ep1 = new ABC(); +listener ep3 = new ABC(); + +public class ABC { + + public function init() { + } + + public function 'start() returns error? { + startCount += 1; + } + + public function gracefulStop() returns error? { + return (); + } + + public function immediateStop() returns error? { + return (); + } + + public function attach(service object {} s, string[]|string? name = ()) returns error? { + attachCount += 1; + } + + public function detach(service object {} s) returns error? { + } +} + +public function getStartAndAttachCount() returns string { + return attachCount.toString() + "_" + startCount.toString(); +} + +public function startNonPublicListener() returns error? { + check ep3.start(); +} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/services/error_union_return_with_default_worker.bal b/tests/jballerina-unit-test/src/test/resources/test-src/services/error_union_return_with_default_worker.bal new file mode 100644 index 000000000000..f6e4d94179f6 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/services/error_union_return_with_default_worker.bal @@ -0,0 +1,37 @@ +// Copyright (c) 2023, 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. + +import ballerina/test; + +public function testErrorUnionWithDefaultWorkerFunction() { + Class c = new(10); + test:assertEquals(10, checkpanic c.getId()); +} + +public class Class { + private int id; + + public function init(int id) { + self.id = id; + } + + public function getId() returns int|error { + worker w1 returns error? { + self.id -> function; + } + return <- w1; + } +} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/Ballerina.toml b/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/Ballerina.toml new file mode 100644 index 000000000000..05e17ab78072 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/Ballerina.toml @@ -0,0 +1,7 @@ +[package] +org = "test_org" +name = "ListenerProject" +version = "0.1.0" + +[build-options] +observabilityIncluded = false diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/main.bal b/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/main.bal new file mode 100644 index 000000000000..1b1139c48c68 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/main.bal @@ -0,0 +1,21 @@ +// Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ListenerProject.module1 as _; + +public function main() { + +} diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/modules/module1/module1.bal b/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/modules/module1/module1.bal new file mode 100644 index 000000000000..29ab9d2cf817 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/modules/module1/module1.bal @@ -0,0 +1,17 @@ +// Copyright (c) 2023, WSO2 LLC. (https://www.wso2.com) All Rights Reserved. +// +// WSO2 LLC. licenses this file to you under the Apache License, +// Version 2.0 (the "License"); you may not use this file except +// in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +import ListenerProject.module2 as _; diff --git a/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/modules/module2/module2.bal b/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/modules/module2/module2.bal new file mode 100644 index 000000000000..0cdd42c94138 --- /dev/null +++ b/tests/jballerina-unit-test/src/test/resources/test-src/statements/vardeclr/listener-project/modules/module2/module2.bal @@ -0,0 +1,62 @@ +// 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. + +public listener ABCD ep = new ABCD(); +public listener ep1 = new ABCD(); +listener ep2 = new ABCD(); + +int startCount = 0; + +public class ABCD { + + public function 'start() returns error? { + startCount += 1; + } + + public function gracefulStop() returns error? {} + + public function immediateStop() returns error? {} + + public function attach(service object {} s, string[]|string? name = ()) returns error? {} + + public function detach(service object {} s) returns error? {} +} + +service /sampleService1 on ep { + + resource function get foo(string b) { + } + + resource function get bar(string b) { + } +} + +service /sampleService2 on ep1 { + resource function get foo(string b) {} +} + +service /sampleService3 on ep2 { + resource function get foo(string b) {} +} + +function init() returns error? { + check ep.start(); + check ep1.start(); + check ep2.start(); + if (startCount != 3) { + panic error("Started listener count differ"); + } +}