protected void VisitUnaryOperatorExpression() { var unaryOperatorExpression = UnaryOperatorExpression; var oldType = Emitter.UnaryOperatorType; var oldAccessor = Emitter.IsUnaryAccessor; var resolveOperator = Emitter.Resolver.ResolveNode(unaryOperatorExpression); var expectedType = Emitter.Resolver.Resolver.GetExpectedType(unaryOperatorExpression); bool isDecimalExpected = Helpers.IsDecimalType(expectedType, Emitter.Resolver); bool isDecimal = Helpers.IsDecimalType(resolveOperator.Type, Emitter.Resolver); bool isLongExpected = Helpers.Is64Type(expectedType, Emitter.Resolver); bool isLong = Helpers.Is64Type(resolveOperator.Type, Emitter.Resolver); OperatorResolveResult orr = resolveOperator as OperatorResolveResult; int count = Emitter.Writers.Count; if (resolveOperator is ConstantResolveResult crr) { object constantValue = crr.ConstantValue; if (unaryOperatorExpression.Operator == UnaryOperatorType.Minus && SyntaxHelper.IsNumeric(constantValue.GetType()) && Convert.ToDouble(constantValue) == 0) { Write("-"); } WriteScript(constantValue); return; } if (Helpers.IsDecimalType(resolveOperator.Type, Emitter.Resolver)) { isDecimal = true; isDecimalExpected = true; } if (isDecimal && isDecimalExpected && unaryOperatorExpression.Operator != UnaryOperatorType.Await) { HandleDecimal(resolveOperator); return; } if (ResolveOperator(unaryOperatorExpression, orr)) { return; } if (Helpers.Is64Type(resolveOperator.Type, Emitter.Resolver)) { isLong = true; isLongExpected = true; } if (isLong && isLongExpected && unaryOperatorExpression.Operator != UnaryOperatorType.Await) { HandleDecimal(resolveOperator, true); return; } if (ResolveOperator(unaryOperatorExpression, orr)) { return; } var op = unaryOperatorExpression.Operator; var argResolverResult = Emitter.Resolver.ResolveNode(unaryOperatorExpression.Expression); bool nullable = NullableType.IsNullable(argResolverResult.Type); if (nullable) { if (op != UnaryOperatorType.Increment && op != UnaryOperatorType.Decrement && op != UnaryOperatorType.PostIncrement && op != UnaryOperatorType.PostDecrement) { Write(JS.Types.SYSTEM_NULLABLE + "."); } } bool isAccessor = false; if (argResolverResult is MemberResolveResult memberArgResolverResult) { if (memberArgResolverResult.Member is IProperty prop) { var isIgnore = memberArgResolverResult.Member.DeclaringTypeDefinition != null && Emitter.Validator.IsExternalType(memberArgResolverResult.Member.DeclaringTypeDefinition); var inlineAttr = prop.Getter != null?Emitter.GetAttribute(prop.Getter.Attributes, Translator.H5_ASSEMBLY + ".TemplateAttribute") : null; var ignoreAccessor = prop.Getter != null && Emitter.Validator.IsExternalType(prop.Getter); var isAccessorsIndexer = Emitter.Validator.IsAccessorsIndexer(memberArgResolverResult.Member); isAccessor = prop.IsIndexer; if (inlineAttr == null && (isIgnore || ignoreAccessor) && !isAccessorsIndexer) { isAccessor = false; } } } else if (argResolverResult is ArrayAccessResolveResult) { isAccessor = ((ArrayAccessResolveResult)argResolverResult).Indexes.Count > 1; } Emitter.UnaryOperatorType = op; if ((isAccessor) && (op == UnaryOperatorType.Increment || op == UnaryOperatorType.Decrement || op == UnaryOperatorType.PostIncrement || op == UnaryOperatorType.PostDecrement)) { Emitter.IsUnaryAccessor = true; if (nullable) { Write(JS.Funcs.H5_HASVALUE); WriteOpenParentheses(); Emitter.IsUnaryAccessor = false; unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(") ? "); Emitter.IsUnaryAccessor = true; unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(" : null)"); } else { unaryOperatorExpression.Expression.AcceptVisitor(Emitter); } Emitter.IsUnaryAccessor = oldAccessor; if (Emitter.Writers.Count > count) { PopWriter(); } } else { switch (op) { case UnaryOperatorType.BitNot: if (nullable) { Write("bnot("); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(")"); } else { Write("~"); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); } break; case UnaryOperatorType.Decrement: if (nullable) { Write(JS.Funcs.H5_HASVALUE); WriteOpenParentheses(); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(") ? "); Write("--"); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(" : null)"); } else { Write("--"); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); } break; case UnaryOperatorType.Increment: if (nullable) { Write(JS.Funcs.H5_HASVALUE); WriteOpenParentheses(); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(") ? "); Write("++"); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(" : null)"); } else { Write("++"); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); } break; case UnaryOperatorType.Minus: if (nullable) { Write("neg("); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(")"); } else { Write("-"); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); } break; case UnaryOperatorType.Not: if (nullable) { Write("not("); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(")"); } else { Write("!"); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); } break; case UnaryOperatorType.Plus: if (nullable) { Write("pos("); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(")"); } else { unaryOperatorExpression.Expression.AcceptVisitor(Emitter); } break; case UnaryOperatorType.PostDecrement: if (nullable) { Write(JS.Funcs.H5_HASVALUE); WriteOpenParentheses(); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(") ? "); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write("--"); Write(" : null)"); } else { unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write("--"); } break; case UnaryOperatorType.PostIncrement: if (nullable) { Write(JS.Funcs.H5_HASVALUE); WriteOpenParentheses(); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write(") ? "); unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write("++"); Write(" : null)"); } else { unaryOperatorExpression.Expression.AcceptVisitor(Emitter); Write("++"); } break; case UnaryOperatorType.Await: if (Emitter.ReplaceAwaiterByVar) { var index = Array.IndexOf(Emitter.AsyncBlock.AwaitExpressions, unaryOperatorExpression.Expression) + 1; Write(JS.Vars.ASYNC_TASK_RESULT + index); } else { var oldValue = Emitter.ReplaceAwaiterByVar; var oldAsyncExpressionHandling = Emitter.AsyncExpressionHandling; if (Emitter.IsAsync && !Emitter.AsyncExpressionHandling) { WriteAwaiters(unaryOperatorExpression.Expression); Emitter.ReplaceAwaiterByVar = true; Emitter.AsyncExpressionHandling = true; } WriteAwaiter(unaryOperatorExpression.Expression); Emitter.ReplaceAwaiterByVar = oldValue; Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; } break; default: throw new EmitterException(unaryOperatorExpression, "Unsupported unary operator: " + unaryOperatorExpression.Operator.ToString()); } if (Emitter.Writers.Count > count) { PopWriter(); } } Emitter.UnaryOperatorType = oldType; }