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