Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

comment for Expression #980

Merged
merged 40 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from 39 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
5709e36
update
chenzhitong Mar 4, 2024
0d8976b
Update BinaryExpression.cs
chenzhitong Mar 4, 2024
2134fb1
Update AnonymousObjectCreationExpression.cs
chenzhitong Mar 4, 2024
ceb138b
Update ElementExpression.cs
chenzhitong Mar 4, 2024
7f35bfc
Update CastExpression.cs
chenzhitong Mar 4, 2024
dec24ed
Update CastExpression.cs
chenzhitong Mar 4, 2024
9249d59
Update ConditionalAccessExpression.cs
chenzhitong Mar 4, 2024
3809a63
TernaryConditional & NullConditionalAccess
chenzhitong Mar 4, 2024
6b22cfe
revert rename
chenzhitong Mar 4, 2024
566af11
update ConvertCheckedExpression.cs
chenzhitong Mar 4, 2024
48671e5
Update IdentifierNameExpression.cs
chenzhitong Mar 4, 2024
443380b
Update ImplicitArrayCreationExpression.cs
chenzhitong Mar 5, 2024
e580b19
update InterpolatedStringExpression.cs
chenzhitong Mar 5, 2024
ff9e303
update
chenzhitong Mar 5, 2024
283ee84
Update SwitchExpression.cs
chenzhitong Mar 5, 2024
139cd1a
update
chenzhitong Mar 6, 2024
6c229be
Merge branch 'master' into comment2
shargon Mar 6, 2024
bdf62ef
update
chenzhitong Mar 7, 2024
5092117
Merge branch 'comment2' of https://github.com/chenzhitong/neo-devpack…
chenzhitong Mar 7, 2024
5e9077c
update
chenzhitong Mar 7, 2024
7f3fcd4
Merge branch 'master' into comment2
Jim8y Mar 7, 2024
ea2b666
add seealso
chenzhitong Mar 7, 2024
6f8fafe
Merge branch 'comment2' of https://github.com/chenzhitong/neo-devpack…
chenzhitong Mar 7, 2024
7c9ed32
update
chenzhitong Mar 7, 2024
5831fce
update
chenzhitong Mar 7, 2024
f2c27c2
ConvertMemberBindingExpression and ConvertElementBindingExpression
chenzhitong Mar 8, 2024
637c061
ConvertInitializerExpression
chenzhitong Mar 8, 2024
3ce867a
BaseExpression and ThisExpression
chenzhitong Mar 8, 2024
fb99b89
Create Contract_Logical.cs
chenzhitong Mar 8, 2024
c4027cd
Update Contract_Logical.cs
chenzhitong Mar 8, 2024
a57885b
format
chenzhitong Mar 8, 2024
aeb9abf
add ut
chenzhitong Mar 8, 2024
d922352
Update Contract_NULL.cs
chenzhitong Mar 8, 2024
1cc369d
throw
chenzhitong Mar 8, 2024
e08b74f
Merge branch 'master' into comment2
Jim8y Mar 8, 2024
1218f3d
Merge branch 'master' into comment2
Jim8y Mar 8, 2024
c6a9ab3
fix
chenzhitong Mar 8, 2024
ad70e85
Merge branch 'comment2' of https://github.com/chenzhitong/neo-devpack…
chenzhitong Mar 8, 2024
bbcd3e0
delegate
chenzhitong Mar 8, 2024
0b8358b
Update src/Neo.Compiler.CSharp/MethodConvert/Expression/AssignmentExp…
shargon Mar 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,21 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// Methods for converting the creation of an object of an anonymous type into a series of instructions.
/// </summary>
/// <param name="model">The semantic model providing context and information about the anonymous object creation.</param>
/// <param name="expression">The syntax representation of the anonymous object creation statement being converted.</param>
/// <remarks>
/// Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first.
/// The type name is generated by the compiler and is not available at the source code level.
/// The type of each property is inferred by the compiler.
/// </remarks>
/// <example>
/// The following example shows an anonymous type that is initialized with two properties named Amount and Message.
/// <c>var v = new { Amount = 108, Message = "Hello" };</c>
/// </example>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/anonymous-types">Anonymous types</seealso>
private void ConvertAnonymousObjectCreationExpression(SemanticModel model, AnonymousObjectCreationExpressionSyntax expression)
{
AddInstruction(OpCode.NEWARRAY0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,25 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// Converts the code for constructing arrays and initializing arrays into OpCodes.
/// This method includes analyzing the array length, array type, array dimension and initial data.
/// </summary>
/// <param name="model">The semantic model providing context and information about the array creation.</param>
/// <param name="expression">The syntax representation of the array creation statement being converted.</param>
/// <exception cref="CompilationException">Only one-dimensional arrays are supported, otherwise an exception is thrown.</exception>
/// <remarks>
/// When the array is initialized to null, this code converts it to "array length" + OpCode.NEWBUFFER (only for byte[]) or OpCode.NEWARRAY_T.
/// When the array is not initialized to null, this code converts the initialized constants one by one in reverse order, then adds the "array length" and OpCode.PACK
/// </remarks>
/// <example>
/// Example of a array creation syntax:
/// <c>var array = new byte[4];</c>
/// The compilation result of the example code is: OpCode.PUSH4, OpCode.NEWBUFFER
/// <c>var array = new int[4] { 5, 6, 7, 8};</c>
/// The compilation result of the example code is: OpCode.PUSH8, OpCode.PUSH7, OpCode.PUSH6, OpCode.PUSH5, OpCode.PUSH4, OpCode.PACK
/// </example>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/arrays">Arrays</seealso>
private void ConvertArrayCreationExpression(SemanticModel model, ArrayCreationExpressionSyntax expression)
{
ArrayRankSpecifierSyntax specifier = expression.Type.RankSpecifiers[0];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,32 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// Converts the code for null-coalescing assignment expression into OpCodes.
/// The null-coalescing assignment operator ??= assigns the value of its right-hand operand to its left-hand operand only if the left-hand operand evaluates to null.
/// The ??= operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-null.
/// Null-coalescing assignment expressions are a new feature introduced in C# 8.0(Released September, 2019).
/// </summary>
/// <param name="model">The semantic model providing context and information about coalesce assignment expression.</param>
/// <param name="expression">The syntax representation of the coalesce assignment expression statement being converted.</param>
/// <exception cref="CompilationException">Thrown when the syntax is not supported.</exception>
/// <example>
/// <code>
/// public class Cat
/// {
/// public string Name { get; set; }
/// }
/// </code>
/// <code>
/// Cat nullableCat = null;
/// Cat nonNullableCat = new() { Name = "Mimi" };
/// nullableCat ??= nonNullableCat;
/// Runtime.Log("Nullable cat: " + nullableCat.Name);
/// </code>
/// <c>nullableCat ??= nonNullableCat;</c> this line is evaluated as
/// <c>nullableCat = nullableCat ?? nonNullableCat;</c> is evaluated as <c>if (nullableCat == null) nullableCat = nonNullableCat;</c>
/// </example>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator">?? and ??= operators - the null-coalescing operators</seealso>
private void ConvertCoalesceAssignmentExpression(SemanticModel model, AssignmentExpressionSyntax expression)
{
switch (expression.Left)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,34 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// Converts the code for complex assignment (or compound assignment) expression into OpCodes.
/// </summary>
/// <param name="model">The semantic model providing context and information about complex assignment expression.</param>
/// <param name="expression">The syntax representation of the complex assignment expression statement being converted.</param>
/// <exception cref="CompilationException">Thrown when the syntax is not supported.</exception>
/// <remarks>
/// For a binary operator op, a compound assignment expression of the form "x op= y" is equivalent to "x = x op y" except that x is only evaluated once.
/// </remarks>
/// <example>
/// The following example demonstrates the usage of compound assignment with arithmetic operators:
/// The corresponding code branch is "ConvertComplexAssignmentExpression"
/// <code>
/// int a = 5;
/// a += 9;
/// Runtime.Log(a.ToString());
/// a -= 4;
/// Runtime.Log(a.ToString());
/// a *= 2;
/// Runtime.Log(a.ToString());
/// a /= 4;
/// Runtime.Log(a.ToString());
/// a %= 3;
/// Runtime.Log(a.ToString());
/// </code>
/// output: 14, 10, 20, 5, 2
/// </example>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/assignment-operator#compound-assignment">Compound assignment</seealso>
private void ConvertComplexAssignmentExpression(SemanticModel model, AssignmentExpressionSyntax expression)
{
ITypeSymbol type = model.GetTypeInfo(expression).Type!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,23 @@ namespace Neo.Compiler;
partial class MethodConvert
{

/// <summary>
shargon marked this conversation as resolved.
Show resolved Hide resolved
/// Converts the code for simple assignment expression into OpCodes.
/// The assignment operator = assigns the value of its right-hand operand to a variable,
/// a property, or an indexer element given by its left-hand operand.
/// </summary>
/// <param name="model">The semantic model providing context and information about simple assignment expression.</param>
/// <param name="expression">The syntax representation of the simple assignment expression statement being converted.</param>
/// <exception cref="CompilationException">Thrown when the syntax is not supported.</exception>
/// <remarks>
/// The result of an assignment expression is the value assigned to the left-hand operand.
/// The type of the right-hand operand must be the same as the type of the left-hand operand or implicitly convertible to it.
/// </remarks>
/// <example>
/// The assignment operator = is right-associative, that is, an expression of the form
/// <c>a = b = c</c> is evaluated as <c>a = (b = c)</c>
/// </example>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/assignment-operator">Assignment operators</seealso>
private void ConvertSimpleAssignmentExpression(SemanticModel model, AssignmentExpressionSyntax expression)
{
ConvertExpression(model, expression.Right);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,31 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// Converts the code for assignment expression into OpCodes.
/// Include assignment operator (=), null-coalescing assignment operator (??=) and compound assignment(+=, -=, *=, /= ... )
/// </summary>
/// <param name="model">The semantic model providing context and information about assignment expression.</param>
/// <param name="expression">The syntax representation of the assignment expression statement being converted.</param>
/// <example>
/// The following code covers three branches. If you want to see the example code for only one of the branches,
/// you can look at the comments of the corresponding method.
/// <code>
/// public class Cat
/// {
/// public string Name { get; set; }
/// }
/// </code>
/// <code>
/// Cat nullableCat = null;
/// Cat nonNullableCat = new() { Name = "Mimi" };
/// nullableCat ??= nonNullableCat;
/// var logInfo = "Nullable cat: ";
/// logInfo += nullableCat.Name;
/// Runtime.Log(log);
/// </code>
/// </example>
/// <seealso cref="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/assignment-operator"/>
private void ConvertAssignmentExpression(SemanticModel model, AssignmentExpressionSyntax expression)
{
switch (expression.OperatorToken.ValueText)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,32 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// The conditional logical OR operator ||, also known as the "short-circuiting" logical OR operator, computes the logical OR of its operands.
/// The result of x || y is true if either x or y evaluates to true.
/// Otherwise, the result is false. If x evaluates to true, y isn't evaluated.
///
/// The conditional logical AND operator &&, also known as the "short-circuiting" logical AND operator, computes the logical AND of its operands.
/// The result of x && y is true if both x and y evaluate to true.
/// Otherwise, the result is false. If x evaluates to false, y isn't evaluated.
///
/// The is operator checks if the run-time type of an expression result is compatible with a given type. The is operator also tests an expression result against a pattern.
///
/// The as operator explicitly converts the result of an expression to a given reference or nullable value type. If the conversion isn't possible, the as operator returns null. Unlike a cast expression, the as operator never throws an exception.
///
/// The null-coalescing operator ?? returns the value of its left-hand operand if it isn't null;
/// otherwise, it evaluates the right-hand operand and returns its result.
/// The ?? operator doesn't evaluate its right-hand operand if the left-hand operand evaluates to non-null.
/// </summary>
/// <param name="model">The semantic model providing context and information about binary expression.</param>
/// <param name="expression">The syntax representation of the binary expression statement being converted.</param>
/// <exception cref="CompilationException">If an unsupported operator is encountered</exception>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators">Boolean logical operators - AND, OR</seealso>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast">Type-testing operators and cast expressions - is, as</seealso>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator">?? operators - the null-coalescing operators</seealso>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators">Bitwise and shift operators</seealso>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/arithmetic-operators">Arithmetic operators</seealso>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/boolean-logical-operators">Boolean logical operators - AND, OR, NOT, XOR</seealso>
private void ConvertBinaryExpression(SemanticModel model, BinaryExpressionSyntax expression)
{
switch (expression.OperatorToken.ValueText)
Expand Down
22 changes: 22 additions & 0 deletions src/Neo.Compiler.CSharp/MethodConvert/Expression/CastExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,28 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// This method converts a cast expression to OpCodes.
/// A cast expression of the form (T)E performs an explicit conversion of the result of expression E to type T.
/// If no explicit conversion exists from the type of E to type T, a compile-time error occurs.
/// </summary>
/// <param name="model">The semantic model providing context and information about cast expression.</param>
/// <param name="expression">The syntax representation of the cast expression statement being converted.</param>
/// <remarks>
/// This method determines the source type and the target type of the cast expression.
/// If the cast can be resolved to a method symbol, it calls the corresponding method.
/// Otherwise, it generates OpCodes based on the types involved in the cast operation.
/// </remarks>
/// <example>
/// This code is cast a ByteString type to an ECPoint type,
/// where the source type is ByteString and the target type is ECPoint.
/// <code>
/// ByteString bytes = ByteString.Empty;
/// ECPoint point = (ECPoint)bytes;
/// Runtime.Log(point.ToString());
/// </code>
/// </example>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/type-testing-and-cast#cast-expression">Cast expression</seealso>
private void ConvertCastExpression(SemanticModel model, CastExpressionSyntax expression)
{
ITypeSymbol sType = model.GetTypeInfo(expression.Expression).Type!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,39 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// The checked and unchecked statements specify the overflow-checking context for integral-type arithmetic operations and conversions.
/// When integer arithmetic overflow occurs, the overflow-checking context defines what happens.
/// In a checked context, a System.OverflowException is thrown;
/// if overflow happens in a constant expression, a compile-time error occurs.
/// </summary>
/// <param name="model">The semantic model providing context and information about checked and unchecked statement.</param>
/// <param name="expression">The syntax representation of the checked and unchecked statement being converted.</param>
/// <example>
/// Use the checked keyword to qualify the result of the temp*2 calculation and use a try catch to handle the overflow if it occurs.
/// <code>
/// try
/// {
/// int temp = int.MaxValue;
/// int a = checked(temp * 2);
/// }
/// catch (OverflowException)
/// {
/// Runtime.Log("Overflow");
/// }
/// </code>
/// </example>
/// <remarks>
/// This code is not called when the checked keyword modifies a block of statements, for example.
/// <code>
/// checked
/// {
/// int a = temp * 2;
/// }
/// </code>
/// For a checked statement, see <see cref="ConvertCheckedStatement(SemanticModel, CheckedStatementSyntax)"/>
/// </remarks>
/// <seealso href="https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/operators/arithmetic-operators#integer-arithmetic-overflow">Integer arithmetic overflow</seealso>
private void ConvertCheckedExpression(SemanticModel model, CheckedExpressionSyntax expression)
{
_checkedStack.Push(expression.Keyword.IsKind(SyntaxKind.CheckedKeyword));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,36 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// This method converts a null-conditional access expression to OpCodes.
/// </summary>
/// /// <param name="model">The semantic model providing context and information about null-conditional access expression.</param>
/// <param name="expression">The syntax representation of the null-conditional access expression statement being converted.</param>
/// <remarks>
/// The method evaluates the expression and checks if it is null.
/// If the expression is not null, it converts the 'WhenNotNull' part of the expression.
/// If the resulting type of the expression is 'System.Void', it handles the case differently by dropping the result.
/// A null-conditional operator applies a member access (?.) or element access (?[]) operation to its operand only if that operand evaluates to non-null;
/// otherwise, it returns null.
/// It will jump to <see cref="ConvertMemberBindingExpression"/> and <see cref="ConvertElementBindingExpression"/> to handle the case where the variable or array is not null.
/// </remarks>
/// <example>
/// If Block is not null, get the block's timestamp; otherwise, it returns null.
/// <code>
/// var block = Ledger.GetBlock(10000);
/// var timestamp = block?.Timestamp;
/// Runtime.Log(timestamp.ToString());
/// </code>
/// If array is not null, get the array's element; otherwise, it returns null.
/// <code>
/// var a = Ledger.GetBlock(10000);
/// var b = Ledger.GetBlock(10001);
/// var array = new[] { a, b };
/// var firstItem = array?[0];
/// Runtime.Log(firstItem?.Timestamp.ToString());
/// </code>
/// </example>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators--and-">Null-conditional operators ?. and ?[]</seealso>
private void ConvertConditionalAccessExpression(SemanticModel model, ConditionalAccessExpressionSyntax expression)
{
ITypeSymbol type = model.GetTypeInfo(expression).Type!;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,23 @@ namespace Neo.Compiler;

partial class MethodConvert
{
/// <summary>
/// This method converts a ternary conditional expression to OpCodes.
/// </summary>
/// /// <param name="model">The semantic model providing context and information about ternary conditional expression.</param>
/// <param name="expression">The syntax representation of the ternary conditional expression statement being converted.</param>
/// <example>
/// The conditional operator ?:, also known as the ternary conditional operator,
/// evaluates a Boolean expression and returns the result of one of the two expressions,
/// depending on whether the Boolean expression evaluates to true or false, as the following example shows:
/// <code>
/// var index = 10000;
/// var current = Ledger.CurrentIndex;
/// var state = current > index ? "start" : "stop";
/// Runtime.Log(state.ToString());
/// </code>
/// </example>
/// <seealso href="https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/conditional-operator">?: operator - the ternary conditional operator</seealso>
private void ConvertConditionalExpression(SemanticModel model, ConditionalExpressionSyntax expression)
{
JumpTarget falseTarget = new();
Expand Down
Loading
Loading