public void checkLambdaSideEffects(LambdaAnalysis lambda) throws QueryTransformException { for (PathAnalysis path: lambda.symbolicAnalysis.paths) { if (!path.getSideEffects().isEmpty()) throw new QueryTransformException("Lambda has a side-effect that can't be emulated with a database query"); } }
private void analyzeConstructor(MethodAnalysisResults analysis) throws QueryTransformException { if (analysis == null) throw new QueryTransformException("Symbolic execution of constructor failed"); if (analysis.paths.size() != 1) throw new QueryTransformException("Symbolic execution of constructor failed"); for (MethodSideEffect effect: analysis.paths.get(0).getSideEffects()) { if (effect instanceof MethodSideEffectCall) { MethodSideEffectCall call = (MethodSideEffectCall) effect; if (call.m.equals(abstractFunction1Constructor)) continue; } else if (effect instanceof MethodSideEffectFieldAssign) { // Assigning to local fields is safe as long as the constructed object doesn't escape the lambda. continue; } else throw new QueryTransformException("Lambda calls a constructor with unknown side-effects"); } }
if (analysis == null) throw new QueryTransformException("Symbolic execution of constructor failed"); if (analysis.paths.size() != 1) throw new QueryTransformException("Symbolic execution of constructor failed"); for (MethodSideEffect effect: analysis.paths.get(0).getSideEffects())
@Override public void checkLambdaSideEffects(LambdaAnalysis lambda) throws QueryTransformException { for (PathAnalysis path: lambda.symbolicAnalysis.paths) { for (MethodSideEffect effect: path.getSideEffects()) { if (effect instanceof MethodSideEffectCall) { MethodSideEffectCall call = (MethodSideEffectCall)effect; if (!call.m.name.equals("<init>")) throw new QueryTransformException("Lambda has a side-effect that can't be emulated with a database query"); try { TransformationClassAnalyzer classAnalyzer = new TransformationClassAnalyzer(call.m.owner, alternateClassLoader); PathAnalysisFactory pathAnalysisFactory = new PathAnalysisFactory( metamodel.getMethodChecker(isObjectEqualsSafe, isAllEqualsSafe, isCollectionContainsSafe)); MethodAnalysisResults analysis = classAnalyzer.analyzeLambdaMethod(call.m.name, call.m.desc, pathAnalysisFactory); analyzeConstructor(analysis); continue; } catch (AnalyzerException | IOException e) { throw new QueryTransformException("Could not analyze the side-effects of the lambda to check for safety", e); } } throw new QueryTransformException("Lambda has a side-effect that can't be emulated with a database query"); } } } }