diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowExpressionAnalyzer.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowExpressionAnalyzer.java index 2d1d4c0f..7b08e5e5 100644 --- a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowExpressionAnalyzer.java +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowExpressionAnalyzer.java @@ -32,7 +32,6 @@ final class PbsFlowExpressionAnalyzer { } private final PbsFlowTypeOps typeOps; - private BlockAnalyzer blockAnalyzer; PbsFlowExpressionAnalyzer(final PbsFlowTypeOps typeOps) { this.typeOps = typeOps; @@ -50,35 +49,33 @@ final class PbsFlowExpressionAnalyzer { final ExprUse use, final boolean valueContext, final BlockAnalyzer blockAnalyzer) { - final var previousBlockAnalyzer = this.blockAnalyzer; - this.blockAnalyzer = blockAnalyzer; - try { - return analyzeExpressionInternal( - expression, - scope, - expectedType, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - use, - valueContext); - } finally { - this.blockAnalyzer = previousBlockAnalyzer; - } + return analyzeExpressionInternal( + expression, + new PbsFlowExpressionContext( + scope, + expectedType, + returnType, + resultErrorName, + receiverType, + model, + diagnostics, + use, + valueContext, + blockAnalyzer)); } + private ExprResult analyzeExpressionInternal( final PbsAst.Expression expression, - final Scope scope, - final TypeView expectedType, - final TypeView returnType, - final String resultErrorName, - final TypeView receiverType, - final Model model, - final DiagnosticSink diagnostics, - final ExprUse use, - final boolean valueContext) { + final PbsFlowExpressionContext context) { + final var scope = context.scope(); + final var expectedType = context.expectedType(); + final var returnType = context.returnType(); + final var resultErrorName = context.resultErrorName(); + final var receiverType = context.receiverType(); + final var model = context.model(); + final var diagnostics = context.diagnostics(); + final var use = context.use(); + final var valueContext = context.valueContext(); if (expression instanceof PbsAst.IntLiteralExpr) { return ExprResult.type(TypeView.intType()); } @@ -140,59 +137,21 @@ final class PbsFlowExpressionAnalyzer { return ExprResult.type(TypeView.unknown()); } if (expression instanceof PbsAst.GroupExpr groupExpr) { - return analyzeExpressionInternal( - groupExpr.expression(), - scope, - expectedType, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - use, - valueContext); + return analyzeExpressionInternal(groupExpr.expression(), context); } if (expression instanceof PbsAst.TupleExpr tupleExpr) { final var fields = new ArrayList(tupleExpr.items().size()); for (final var item : tupleExpr.items()) { - final var value = analyzeExpressionInternal( - item.expression(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var value = analyzeValueExpression(item.expression(), context, null).type(); fields.add(new TupleField(item.label(), value)); } return ExprResult.type(TypeView.tuple(fields)); } if (expression instanceof PbsAst.BlockExpr blockExpr) { - return ExprResult.type(blockAnalyzer.analyze( - blockExpr.block(), - scope, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - valueContext)); + return ExprResult.type(analyzeBlock(blockExpr.block(), context, valueContext)); } if (expression instanceof PbsAst.UnaryExpr unaryExpr) { - final var operand = analyzeExpressionInternal( - unaryExpr.expression(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var operand = analyzeValueExpression(unaryExpr.expression(), context, null).type(); if ("!".equals(unaryExpr.operator()) || "not".equals(unaryExpr.operator())) { return ExprResult.type(TypeView.bool()); } @@ -202,75 +161,23 @@ final class PbsFlowExpressionAnalyzer { return ExprResult.type(TypeView.unknown()); } if (expression instanceof PbsAst.BinaryExpr binaryExpr) { - final var left = analyzeExpressionInternal( - binaryExpr.left(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); - final var right = analyzeExpressionInternal( - binaryExpr.right(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var left = analyzeValueExpression(binaryExpr.left(), context, null).type(); + final var right = analyzeValueExpression(binaryExpr.right(), context, null).type(); return ExprResult.type(typeOps.inferBinaryResult(binaryExpr.operator(), left, right)); } if (expression instanceof PbsAst.MemberExpr memberExpr) { return analyzeMemberExpression( memberExpr, - scope, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - use); + context); } if (expression instanceof PbsAst.CallExpr callExpr) { - return analyzeCallExpression( - callExpr, - scope, - expectedType, - returnType, - resultErrorName, - receiverType, - model, - diagnostics); + return analyzeCallExpression(callExpr, context); } if (expression instanceof PbsAst.ApplyExpr applyExpr) { - return analyzeApplyExpression( - applyExpr, - scope, - expectedType, - returnType, - resultErrorName, - receiverType, - model, - diagnostics); + return analyzeApplyExpression(applyExpr, context); } if (expression instanceof PbsAst.IfExpr ifExpr) { - final var condition = analyzeExpressionInternal( - ifExpr.condition(), - scope, - TypeView.bool(), - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var condition = analyzeValueExpression(ifExpr.condition(), context, TypeView.bool()).type(); if (!typeOps.isBool(condition)) { p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_IF_NON_BOOL_CONDITION.name(), @@ -278,18 +185,8 @@ final class PbsFlowExpressionAnalyzer { ifExpr.condition().span()); } - final var thenType = blockAnalyzer.analyze(ifExpr.thenBlock(), scope, returnType, resultErrorName, receiverType, model, diagnostics, true); - final var elseType = analyzeExpressionInternal( - ifExpr.elseExpression(), - scope, - expectedType, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var thenType = analyzeBlock(ifExpr.thenBlock(), context, true); + final var elseType = analyzeValueExpression(ifExpr.elseExpression(), context, expectedType).type(); if (!typeOps.compatible(thenType, elseType)) { p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, @@ -301,60 +198,21 @@ final class PbsFlowExpressionAnalyzer { return ExprResult.type(thenType); } if (expression instanceof PbsAst.SwitchExpr switchExpr) { - return ExprResult.type(analyzeSwitchExpression( - switchExpr, - scope, - expectedType, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - valueContext)); + return ExprResult.type(analyzeSwitchExpression(switchExpr, context)); } if (expression instanceof PbsAst.ElseExpr elseExpr) { - final var optional = analyzeExpressionInternal( - elseExpr.optionalExpression(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var optional = analyzeValueExpression(elseExpr.optionalExpression(), context, null).type(); if (optional.kind() != Kind.OPTIONAL) { p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_ELSE_NON_OPTIONAL_LEFT.name(), "Left operand of 'else' must have optional type", elseExpr.optionalExpression().span()); - analyzeExpressionInternal( - elseExpr.fallbackExpression(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true); + analyzeValueExpression(elseExpr.fallbackExpression(), context, null); return ExprResult.type(TypeView.unknown()); } final var payload = optional.inner(); - final var fallback = analyzeExpressionInternal( - elseExpr.fallbackExpression(), - scope, - payload, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var fallback = analyzeValueExpression(elseExpr.fallbackExpression(), context, payload).type(); if (!typeOps.compatible(fallback, payload)) { p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_ELSE_FALLBACK_TYPE_MISMATCH.name(), @@ -364,17 +222,7 @@ final class PbsFlowExpressionAnalyzer { return ExprResult.type(payload); } if (expression instanceof PbsAst.PropagateExpr propagateExpr) { - final var source = analyzeExpressionInternal( - propagateExpr.expression(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var source = analyzeValueExpression(propagateExpr.expression(), context, null).type(); if (source.kind() != Kind.RESULT) { p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_RESULT_PROPAGATE_NON_RESULT.name(), @@ -392,14 +240,7 @@ final class PbsFlowExpressionAnalyzer { return ExprResult.type(source.inner()); } if (expression instanceof PbsAst.HandleExpr handleExpr) { - return ExprResult.type(analyzeHandleExpression( - handleExpr, - scope, - returnType, - resultErrorName, - receiverType, - model, - diagnostics)); + return ExprResult.type(analyzeHandleExpression(handleExpr, context)); } if (expression instanceof PbsAst.NoneExpr noneExpr) { if (expectedType == null || expectedType.kind() != Kind.OPTIONAL) { @@ -415,31 +256,11 @@ final class PbsFlowExpressionAnalyzer { final var payloadExpected = expectedType != null && expectedType.kind() == Kind.OPTIONAL ? expectedType.inner() : null; - final var payload = analyzeExpressionInternal( - someExpr.value(), - scope, - payloadExpected, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var payload = analyzeValueExpression(someExpr.value(), context, payloadExpected).type(); return ExprResult.type(TypeView.optional(payloadExpected == null ? payload : payloadExpected)); } if (expression instanceof PbsAst.BindExpr bindExpr) { - final var contextType = analyzeExpressionInternal( - bindExpr.contextExpression(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var contextType = analyzeValueExpression(bindExpr.contextExpression(), context, null).type(); if (expectedType == null || expectedType.kind() != Kind.CALLBACK) { return ExprResult.type(TypeView.unknown()); } @@ -491,17 +312,7 @@ final class PbsFlowExpressionAnalyzer { return ExprResult.type(TypeView.unknown()); } if (expression instanceof PbsAst.AsExpr asExpr) { - analyzeExpressionInternal( - asExpr.expression(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true); + analyzeValueExpression(asExpr.expression(), context, null); if (model.contracts.containsKey(asExpr.contractName())) { return ExprResult.type(TypeView.contract(asExpr.contractName())); } @@ -513,17 +324,7 @@ final class PbsFlowExpressionAnalyzer { PbsSemanticsErrors.E_SEM_RESULT_FLOW_INVALID_POSITION.name(), "'ok(...)' is only allowed in result return flow and handle arm terminals", okExpr.span()); - analyzeExpressionInternal( - okExpr.value(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true); + analyzeValueExpression(okExpr.value(), context, null); return ExprResult.type(TypeView.unknown()); } if (expression instanceof PbsAst.ErrExpr errExpr) { @@ -539,54 +340,18 @@ final class PbsFlowExpressionAnalyzer { private ExprResult analyzeCallExpression( final PbsAst.CallExpr callExpr, - final Scope scope, - final TypeView expectedType, - final TypeView returnType, - final String resultErrorName, - final TypeView receiverType, - final Model model, - final DiagnosticSink diagnostics) { - final var callee = analyzeExpressionInternal( - callExpr.callee(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.CALL_TARGET, - true); + final PbsFlowExpressionContext context) { + final var callee = analyzeTargetExpression(callExpr.callee(), context, ExprUse.CALL_TARGET); final TypeView argumentType; if (callExpr.arguments().isEmpty()) { argumentType = TypeView.unit(); } else if (callExpr.arguments().size() == 1) { - argumentType = analyzeExpressionInternal( - callExpr.arguments().getFirst(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + argumentType = analyzeValueExpression(callExpr.arguments().getFirst(), context, null).type(); } else { final var fields = new ArrayList(callExpr.arguments().size()); for (final var argument : callExpr.arguments()) { - final var itemType = analyzeExpressionInternal( - argument, - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final var itemType = analyzeValueExpression(argument, context, null).type(); fields.add(new TupleField(null, itemType)); } argumentType = TypeView.tuple(fields); @@ -597,49 +362,23 @@ final class PbsFlowExpressionAnalyzer { callExpr.callee().span(), callee, argumentType, - expectedType, - diagnostics); + context.expectedType(), + context.diagnostics()); } private ExprResult analyzeApplyExpression( final PbsAst.ApplyExpr applyExpr, - final Scope scope, - final TypeView expectedType, - final TypeView returnType, - final String resultErrorName, - final TypeView receiverType, - final Model model, - final DiagnosticSink diagnostics) { - final var callee = analyzeExpressionInternal( - applyExpr.callee(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.APPLY_TARGET, - true); - final var argument = analyzeExpressionInternal( - applyExpr.argument(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final PbsFlowExpressionContext context) { + final var callee = analyzeTargetExpression(applyExpr.callee(), context, ExprUse.APPLY_TARGET); + final var argument = analyzeValueExpression(applyExpr.argument(), context, null).type(); return resolveCallableApplication( applyExpr.span(), applyExpr.callee().span(), callee, argument, - expectedType, - diagnostics); + context.expectedType(), + context.diagnostics()); } private ExprResult resolveCallableApplication( @@ -702,24 +441,12 @@ final class PbsFlowExpressionAnalyzer { private ExprResult analyzeMemberExpression( final PbsAst.MemberExpr memberExpr, - final Scope scope, - final TypeView returnType, - final String resultErrorName, - final TypeView receiverType, - final Model model, - final DiagnosticSink diagnostics, - final ExprUse use) { - final var receiver = analyzeExpressionInternal( - memberExpr.receiver(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final PbsFlowExpressionContext context) { + final var receiver = analyzeValueExpression(memberExpr.receiver(), context, null).type(); + final var model = context.model(); + final var diagnostics = context.diagnostics(); + final var receiverType = context.receiverType(); + final var use = context.use(); if (receiver.kind() == Kind.TYPE_REF) { final var enumCases = model.enums.get(receiver.name()); @@ -857,25 +584,10 @@ final class PbsFlowExpressionAnalyzer { private TypeView analyzeSwitchExpression( final PbsAst.SwitchExpr switchExpr, - final Scope scope, - final TypeView expectedType, - final TypeView returnType, - final String resultErrorName, - final TypeView receiverType, - final Model model, - final DiagnosticSink diagnostics, - final boolean valueContext) { - final var selector = analyzeExpressionInternal( - switchExpr.selector(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final PbsFlowExpressionContext context) { + final var model = context.model(); + final var diagnostics = context.diagnostics(); + final var selector = analyzeValueExpression(switchExpr.selector(), context, null).type(); final var selectorComparable = typeOps.isScalarComparable(selector) || selector.kind() == Kind.ENUM; if (!selectorComparable) { @@ -928,15 +640,7 @@ final class PbsFlowExpressionAnalyzer { arm.pattern().span()); } - final var currentArmType = blockAnalyzer.analyze( - arm.block(), - scope, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - true); + final var currentArmType = analyzeBlock(arm.block(), context, true); if (armType == null) { armType = currentArmType; } else if (!typeOps.compatible(currentArmType, armType)) { @@ -947,7 +651,7 @@ final class PbsFlowExpressionAnalyzer { } } - if (valueContext && !hasWildcard) { + if (context.valueContext() && !hasWildcard) { var exhaustive = false; if (selector.kind() == Kind.ENUM) { final var allCases = model.enums.get(selector.name()); @@ -974,8 +678,8 @@ final class PbsFlowExpressionAnalyzer { if (armType == null) { return TypeView.unit(); } - if (expectedType != null && typeOps.compatible(armType, expectedType)) { - return expectedType; + if (context.expectedType() != null && typeOps.compatible(armType, context.expectedType())) { + return context.expectedType(); } return armType; } @@ -1037,23 +741,11 @@ final class PbsFlowExpressionAnalyzer { private TypeView analyzeHandleExpression( final PbsAst.HandleExpr handleExpr, - final Scope scope, - final TypeView returnType, - final String resultErrorName, - final TypeView receiverType, - final Model model, - final DiagnosticSink diagnostics) { - final var sourceType = analyzeExpressionInternal( - handleExpr.value(), - scope, - null, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - ExprUse.VALUE, - true).type(); + final PbsFlowExpressionContext context) { + final var model = context.model(); + final var diagnostics = context.diagnostics(); + final var resultErrorName = context.resultErrorName(); + final var sourceType = analyzeValueExpression(handleExpr.value(), context, null).type(); if (sourceType.kind() != Kind.RESULT) { p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_HANDLE_NON_RESULT.name(), @@ -1107,11 +799,8 @@ final class PbsFlowExpressionAnalyzer { } analyzeHandleBlockArm( arm, - scope, + context, sourcePayloadType, - returnType, - resultErrorName, - receiverType, model, diagnostics); } @@ -1128,13 +817,14 @@ final class PbsFlowExpressionAnalyzer { private void analyzeHandleBlockArm( final PbsAst.HandleArm arm, - final Scope scope, + final PbsFlowExpressionContext context, final TypeView sourcePayloadType, - final TypeView returnType, - final String resultErrorName, - final TypeView receiverType, final Model model, final DiagnosticSink diagnostics) { + final var returnType = context.returnType(); + final var resultErrorName = context.resultErrorName(); + final var receiverType = context.receiverType(); + final var scope = context.scope(); if (arm.block() == null) { p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_HANDLE_ARM_TERMINAL_INVALID.name(), @@ -1147,15 +837,7 @@ final class PbsFlowExpressionAnalyzer { final var terminal = unwrapGroup(block.tailExpression()); if (terminal instanceof PbsAst.OkExpr okExpr) { final var payloadBlock = new PbsAst.Block(block.statements(), okExpr.value(), block.span()); - final var actualPayloadType = blockAnalyzer.analyze( - payloadBlock, - scope, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - true); + final var actualPayloadType = analyzeBlock(payloadBlock, context, true); if (!typeOps.compatible(actualPayloadType, sourcePayloadType)) { p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_RESULT_OK_PAYLOAD_MISMATCH.name(), @@ -1167,15 +849,7 @@ final class PbsFlowExpressionAnalyzer { if (terminal instanceof PbsAst.ErrExpr errExpr) { final var statementsOnly = new PbsAst.Block(block.statements(), null, block.span()); - blockAnalyzer.analyze( - statementsOnly, - scope, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - false); + analyzeBlock(statementsOnly, context, false); if (resultErrorName != null && !matchesTargetError(errExpr.errorPath(), resultErrorName, model)) { p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_RESULT_ERROR_LABEL_INVALID.name(), @@ -1187,25 +861,9 @@ final class PbsFlowExpressionAnalyzer { if (block.tailExpression() == null) { final var statementsOnly = new PbsAst.Block(block.statements(), null, block.span()); - blockAnalyzer.analyze( - statementsOnly, - scope, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - false); + analyzeBlock(statementsOnly, context, false); } else { - blockAnalyzer.analyze( - block, - scope, - returnType, - resultErrorName, - receiverType, - model, - diagnostics, - true); + analyzeBlock(block, context, true); } p.studio.compiler.source.diagnostics.Diagnostics.error(diagnostics, PbsSemanticsErrors.E_SEM_HANDLE_ARM_TERMINAL_INVALID.name(), @@ -1236,4 +894,41 @@ final class PbsFlowExpressionAnalyzer { return expression; } + private ExprResult analyzeValueExpression( + final PbsAst.Expression expression, + final PbsFlowExpressionContext context, + final TypeView expectedType) { + return analyzeExpressionInternal( + expression, + context.withExpectedType(expectedType) + .withUse(ExprUse.VALUE) + .withValueContext(true)); + } + + private ExprResult analyzeTargetExpression( + final PbsAst.Expression expression, + final PbsFlowExpressionContext context, + final ExprUse use) { + return analyzeExpressionInternal( + expression, + context.withExpectedType(null) + .withUse(use) + .withValueContext(true)); + } + + private TypeView analyzeBlock( + final PbsAst.Block block, + final PbsFlowExpressionContext context, + final boolean valueContext) { + return context.blockAnalyzer().analyze( + block, + context.scope(), + context.returnType(), + context.resultErrorName(), + context.receiverType(), + context.model(), + context.diagnostics(), + valueContext); + } + } diff --git a/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowExpressionContext.java b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowExpressionContext.java new file mode 100644 index 00000000..76963710 --- /dev/null +++ b/prometeu-compiler/frontends/prometeu-frontend-pbs/src/main/java/p/studio/compiler/pbs/semantics/PbsFlowExpressionContext.java @@ -0,0 +1,125 @@ +package p.studio.compiler.pbs.semantics; + +import p.studio.compiler.source.diagnostics.DiagnosticSink; +import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.ExprUse; +import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.Model; +import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.Scope; +import p.studio.compiler.pbs.semantics.PbsFlowSemanticSupport.TypeView; + +final class PbsFlowExpressionContext { + private final Scope scope; + private final TypeView expectedType; + private final TypeView returnType; + private final String resultErrorName; + private final TypeView receiverType; + private final Model model; + private final DiagnosticSink diagnostics; + private final ExprUse use; + private final boolean valueContext; + private final PbsFlowExpressionAnalyzer.BlockAnalyzer blockAnalyzer; + + PbsFlowExpressionContext( + final Scope scope, + final TypeView expectedType, + final TypeView returnType, + final String resultErrorName, + final TypeView receiverType, + final Model model, + final DiagnosticSink diagnostics, + final ExprUse use, + final boolean valueContext, + final PbsFlowExpressionAnalyzer.BlockAnalyzer blockAnalyzer) { + this.scope = scope; + this.expectedType = expectedType; + this.returnType = returnType; + this.resultErrorName = resultErrorName; + this.receiverType = receiverType; + this.model = model; + this.diagnostics = diagnostics; + this.use = use; + this.valueContext = valueContext; + this.blockAnalyzer = blockAnalyzer; + } + + Scope scope() { + return scope; + } + + TypeView expectedType() { + return expectedType; + } + + TypeView returnType() { + return returnType; + } + + String resultErrorName() { + return resultErrorName; + } + + TypeView receiverType() { + return receiverType; + } + + Model model() { + return model; + } + + DiagnosticSink diagnostics() { + return diagnostics; + } + + ExprUse use() { + return use; + } + + boolean valueContext() { + return valueContext; + } + + PbsFlowExpressionAnalyzer.BlockAnalyzer blockAnalyzer() { + return blockAnalyzer; + } + + PbsFlowExpressionContext withExpectedType(final TypeView nextExpectedType) { + return new PbsFlowExpressionContext( + scope, + nextExpectedType, + returnType, + resultErrorName, + receiverType, + model, + diagnostics, + use, + valueContext, + blockAnalyzer); + } + + PbsFlowExpressionContext withUse(final ExprUse nextUse) { + return new PbsFlowExpressionContext( + scope, + expectedType, + returnType, + resultErrorName, + receiverType, + model, + diagnostics, + nextUse, + valueContext, + blockAnalyzer); + } + + PbsFlowExpressionContext withValueContext(final boolean nextValueContext) { + return new PbsFlowExpressionContext( + scope, + expectedType, + returnType, + resultErrorName, + receiverType, + model, + diagnostics, + use, + nextValueContext, + blockAnalyzer); + } +}