in src/Bicep.Core/Intermediate/ExpressionBuilder.cs [66:242]
private Expression ConvertWithoutLowering(SyntaxBase syntax)
{
switch (syntax)
{
case StringSyntax @string:
{
if (@string.TryGetLiteralValue() is { } stringValue)
{
return new StringLiteralExpression(@string, stringValue);
}
return new InterpolatedStringExpression(
@string,
@string.SegmentValues,
@string.Expressions.Select(ConvertWithoutLowering).ToImmutableArray());
}
case IntegerLiteralSyntax @int:
{
var literalValue = SafeConvertIntegerValue(@int, isNegative: false);
return new IntegerLiteralExpression(@int, literalValue);
}
case UnaryOperationSyntax { Operator: UnaryOperator.Minus } unary when unary.Expression is IntegerLiteralSyntax @int:
{
var literalValue = SafeConvertIntegerValue(@int, isNegative: true);
return new IntegerLiteralExpression(unary, literalValue);
}
case BooleanLiteralSyntax @bool:
return new BooleanLiteralExpression(@bool, @bool.Value);
case NullLiteralSyntax:
return new NullLiteralExpression(syntax);
case ParenthesizedExpressionSyntax x:
return ConvertWithoutLowering(x.Expression);
case NonNullAssertionSyntax assertion:
return ConvertWithoutLowering(assertion.BaseExpression);
case ObjectSyntax @object:
return ConvertObject(@object);
case ArraySyntax array:
return ConvertArray(array);
case TernaryOperationSyntax ternary:
return new TernaryExpression(
ternary,
ConvertWithoutLowering(ternary.ConditionExpression),
ConvertWithoutLowering(ternary.TrueExpression),
ConvertWithoutLowering(ternary.FalseExpression));
case BinaryOperationSyntax binary:
return new BinaryExpression(
binary,
binary.Operator,
ConvertWithoutLowering(binary.LeftExpression),
ConvertWithoutLowering(binary.RightExpression));
case UnaryOperationSyntax unary:
return new UnaryExpression(
unary,
unary.Operator,
ConvertWithoutLowering(unary.Expression));
case FunctionCallSyntaxBase function:
return ConvertFunction(function);
case ArrayAccessSyntax arrayAccess:
// TODO: should we lower an arrayAccess with constant property name to a propertyAccess?
return ConvertArrayAccess(arrayAccess);
case PropertyAccessSyntax propertyAccess:
return ConvertPropertyAccess(propertyAccess);
case VariableAccessSyntax variableAccess:
return ConvertVariableAccess(variableAccess);
case ResourceAccessSyntax resourceAccess:
return ConvertResourceAccess(resourceAccess);
case LambdaSyntax lambda:
var variables = lambda.GetLocalVariables();
return new LambdaExpression(
lambda,
variables.Select(x => x.Name.IdentifierName).ToImmutableArray(),
variables.Select<LocalVariableSyntax, TypeExpression?>(x => null).ToImmutableArray(),
ConvertWithoutLowering(lambda.Body),
null);
case TypedLambdaSyntax lambda:
var typedVariables = lambda.GetLocalVariables();
return new LambdaExpression(
lambda,
typedVariables.Select(x => x.Name.IdentifierName).ToImmutableArray(),
typedVariables.Select(x => ConvertTypeWithoutLowering(x.Type)).ToImmutableArray<TypeExpression?>(),
ConvertWithoutLowering(lambda.Body),
ConvertTypeWithoutLowering(lambda.ReturnType));
case ForSyntax forSyntax:
return new ForLoopExpression(
forSyntax,
ConvertWithoutLowering(forSyntax.Expression),
ConvertWithoutLowering(forSyntax.Body),
null,
null);
case IfConditionSyntax conditionSyntax:
return new ConditionExpression(
conditionSyntax,
ConvertWithoutLowering(conditionSyntax.ConditionExpression),
ConvertWithoutLowering(conditionSyntax.Body));
case MetadataDeclarationSyntax metadata:
return EvaluateDecorators(metadata, new DeclaredMetadataExpression(
metadata,
metadata.Name.IdentifierName,
ConvertWithoutLowering(metadata.Value)));
case ExtensionDeclarationSyntax extension:
var symbol = GetDeclaredSymbol<ExtensionNamespaceSymbol>(extension);
return EvaluateDecorators(extension, new ExtensionExpression(
extension,
symbol.Name,
GetTypeInfo<NamespaceType>(extension).Settings,
extension.Config is not null ? ConvertWithoutLowering(extension.Config) : null));
case ParameterDeclarationSyntax parameter:
return EvaluateDecorators(parameter, new DeclaredParameterExpression(
parameter,
parameter.Name.IdentifierName,
ConvertTypeWithoutLowering(parameter.Type),
parameter.Modifier is ParameterDefaultValueSyntax defaultValue ? ConvertWithoutLowering(defaultValue.DefaultValue) : null));
case VariableDeclarationSyntax variable:
return EvaluateDecorators(variable, new DeclaredVariableExpression(
variable,
variable.Name.IdentifierName,
variable.Type != null ? ConvertTypeWithoutLowering(variable.Type) : null,
ConvertWithoutLowering(variable.Value)));
case FunctionDeclarationSyntax function:
return EvaluateDecorators(function, new DeclaredFunctionExpression(
function,
EmitConstants.UserDefinedFunctionsNamespace,
function.Name.IdentifierName,
ConvertWithoutLowering(function.Lambda)));
case OutputDeclarationSyntax output:
return EvaluateDecorators(output, new DeclaredOutputExpression(
output,
output.Name.IdentifierName,
ConvertTypeWithoutLowering(output.Type),
ConvertWithoutLowering(output.Value)));
case AssertDeclarationSyntax assert:
return EvaluateDecorators(assert, new DeclaredAssertExpression(
assert,
assert.Name.IdentifierName,
ConvertWithoutLowering(assert.Value)));
case ResourceDeclarationSyntax resource:
return EvaluateDecorators(resource, ConvertResource(resource));
case ModuleDeclarationSyntax module:
return EvaluateDecorators(module, ConvertModule(module));
case TypeDeclarationSyntax typeDeclaration:
return EvaluateDecorators(typeDeclaration, new DeclaredTypeExpression(typeDeclaration,
typeDeclaration.Name.IdentifierName,
ConvertTypeWithoutLowering(typeDeclaration.Value)));
case ObjectTypePropertySyntax typeProperty:
return EvaluateDecorators(typeProperty, new ObjectTypePropertyExpression(typeProperty,
typeProperty.TryGetKeyText() ?? throw new ArgumentException("Unable to resolve name of object type property"),
ConvertTypeWithoutLowering(typeProperty.Value)));
case ObjectTypeAdditionalPropertiesSyntax typeAdditionalProperties:
return EvaluateDecorators(typeAdditionalProperties, new ObjectTypeAdditionalPropertiesExpression(typeAdditionalProperties,
ConvertTypeWithoutLowering(typeAdditionalProperties.Value)));
case TupleTypeItemSyntax tupleItem:
return EvaluateDecorators(tupleItem, new TupleTypeItemExpression(tupleItem, ConvertTypeWithoutLowering(tupleItem.Value)));
case ProgramSyntax program:
return ConvertProgram(program);
default:
throw new ArgumentException($"Failed to convert syntax of type {syntax.GetType()}");
}
}