Skip to content

Commit

Permalink
Merge pull request #42366 from LakshanWeerasinghe/fix-#41691_start_only
Browse files Browse the repository at this point in the history
Fix isolation analysis for start actions
  • Loading branch information
LakshanWeerasinghe committed Apr 4, 2024
2 parents 2ec481a + a22e04b commit 0a7e4c9
Show file tree
Hide file tree
Showing 5 changed files with 312 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ public class IsolationAnalyzer extends BLangNodeVisitor {

private boolean inferredIsolated = true;
private boolean inLockStatement = false;
private boolean inIsolatedStartAction = false;
private final Stack<LockInfo> copyInLockInfoStack = new Stack<>();
private final Stack<Set<BSymbol>> isolatedLetVarStack = new Stack<>();
private final Map<BSymbol, IsolationInferenceInfo> isolationInferenceInfoMap = new HashMap<>();
Expand Down Expand Up @@ -1288,6 +1289,12 @@ public void visit(BLangSimpleVarRef varRefExpr) {
}
}

if (this.inIsolatedStartAction
&& !isSubtypeOfReadOnlyOrIsolatedObjectOrInferableObject(symbol.owner, symbol.getType())) {
inferredIsolated = false;
return;
}

if (!recordFieldDefaultValue && !objectFieldDefaultValueRequiringIsolation && enclInvokable != null &&
isReferenceToVarDefinedInSameInvokable(symbol.owner, enclInvokable.symbol)) {
return;
Expand Down Expand Up @@ -2096,7 +2103,10 @@ private void analyzeInvocation(BLangInvocation invocationExpr) {
}

if (isolatedFunctionCall) {
boolean prevInIsolationStartAction = this.inIsolatedStartAction;
this.inIsolatedStartAction = inStartAction;
analyzeArgIsolatedness(invocationExpr, requiredArgs, restArgs, symbol, expectsIsolation);
this.inIsolatedStartAction = prevInIsolationStartAction;
return;
}

Expand Down Expand Up @@ -4142,7 +4152,8 @@ private boolean inferFunctionIsolation(BSymbol symbol, IsolationInferenceInfo fu
}

for (BLangExpression dependsOnArg : functionIsolationInferenceInfo.dependsOnFuncCallArgExprs) {
if (!isIsolatedExpression(dependsOnArg)) {
if (!isIsolatedExpression(dependsOnArg, false, false, new ArrayList<>(), true,
publiclyExposedObjectTypes, classDefinitions, moduleLevelVariables, unresolvedSymbols)) {
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,14 @@ public void testAnonIsolatedFuncAccessingImplicitlyFinalVars() {
}
}

@Test
public void testIsolationAnalysisForAsyncActions() {
CompileResult result = BCompileUtil.compile(
"test-src/isolation-analysis/isolation_analysis_for_async_actions.bal");
Assert.assertEquals(result.getErrorCount(), 0);
Assert.assertEquals(result.getWarnCount(), 0);
}

@Test
public void testIsolatedFunctionsSemanticNegative() {
CompileResult result =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,28 +46,64 @@ public void testIsolationWarnings() {
int i = 0;
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 26, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 30, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 43, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 47, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 62, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 66, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 79, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 83, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 101, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 105, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 118, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 122, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 137, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 141, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 154, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 158, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 176, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 180, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 193, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 39, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 43, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 47, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 56, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 60, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 70, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 74, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 78, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 88, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 92, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 100, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 104, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 108, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 118, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 122, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 132, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 136, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 140, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 153, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 157, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 166, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 170, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 174, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 183, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 187, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 197, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 211, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 201, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 205, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 215, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 228, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 232, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 219, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 227, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 231, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 235, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 245, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 249, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 259, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 263, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 267, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 280, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_HINT, 284, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 293, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 297, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 301, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 310, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 314, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 324, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 328, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 332, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 341, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 345, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 353, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 357, 5);
validateHint(result, i++, NON_ISOLATED_METHOD_HINT, 361, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 371, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 375, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 385, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 389, 5);
validateHint(result, i++, NON_ISOLATED_SERVICE_AND_METHOD_HINT, 393, 5);
assertEquals(result.getHintCount(), i);

LineRange lineRange = result.getDiagnostics()[0].location().lineRange();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright (c) 2024, WSO2 LLC. (http://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.
//

service / on new Listener() {

resource function post h2(string[] arr) {
_ = start callFunction(arr.clone());
}

resource function post h3(string[] arr) {
string[] newArray = [...arr];
_ = start callFunction(newArray.clone());
}

resource function get h4() {
_ = start fn();
}
}

function fn(any x = ()) returns any {
_ = start fn(fn());
}

isolated function callFunction(string[] arr) {
}

class Listener {
public function attach(service object {} s, string|string[]? name = ()) returns error? {
return;
}

public function detach(service object {} s) returns error? {
return;
}

public function 'start() returns error? {
return;
}

public function gracefulStop() returns error? {
return;
}

public function immediateStop() returns error? {
return;
}
}
Loading

0 comments on commit 0a7e4c9

Please sign in to comment.