private void HandleDecimal(ResolveResult resolveOperator, bool isLong = false) { var orr = resolveOperator as OperatorResolveResult; var op = UnaryOperatorExpression.Operator; var oldType = Emitter.UnaryOperatorType; var oldAccessor = Emitter.IsUnaryAccessor; var typeCode = isLong ? KnownTypeCode.Int64 : KnownTypeCode.Decimal; Emitter.UnaryOperatorType = op; var argResolverResult = Emitter.Resolver.ResolveNode(UnaryOperatorExpression.Expression); bool nullable = NullableType.IsNullable(argResolverResult.Type); bool isAccessor = false; if (argResolverResult is MemberResolveResult memberArgResolverResult && memberArgResolverResult.Member is IProperty) { var isIgnore = Emitter.Validator.IsExternalType(memberArgResolverResult.Member.DeclaringTypeDefinition); var inlineAttr = Emitter.GetAttribute(memberArgResolverResult.Member.Attributes, Translator.H5_ASSEMBLY + ".TemplateAttribute"); var ignoreAccessor = Emitter.Validator.IsExternalType(((IProperty)memberArgResolverResult.Member).Getter); var isAccessorsIndexer = Emitter.Validator.IsAccessorsIndexer(memberArgResolverResult.Member); isAccessor = ((IProperty)memberArgResolverResult.Member).IsIndexer; if (inlineAttr == null && (isIgnore || ignoreAccessor) && !isAccessorsIndexer) { isAccessor = false; } }
protected virtual string GetCastCode(Expression expression, AstType astType, string op, out bool isCastAttr) { isCastAttr = false; if (!(Emitter.Resolver.ResolveNode(astType) is TypeResolveResult resolveResult)) { return(null); } var exprResolveResult = Emitter.Resolver.ResolveNode(expression); string inline = null; bool isOp = op == CS.Ops.IS; var method = isOp ? null : GetCastMethod(exprResolveResult.Type, resolveResult.Type, out inline); if (method == null && !isOp && (NullableType.IsNullable(exprResolveResult.Type) || NullableType.IsNullable(resolveResult.Type))) { method = GetCastMethod(NullableType.IsNullable(exprResolveResult.Type) ? NullableType.GetUnderlyingType(exprResolveResult.Type) : exprResolveResult.Type, NullableType.IsNullable(resolveResult.Type) ? NullableType.GetUnderlyingType(resolveResult.Type) : resolveResult.Type, out inline); } if (inline != null) { InlineMethod = method; return(inline); } IEnumerable <IAttribute> attributes = null; var type = resolveResult.Type.GetDefinition(); if (type != null) { attributes = type.Attributes; } else { if (resolveResult.Type is ParameterizedType paramType) { attributes = paramType.GetDefinition().Attributes; } } if (attributes != null) { var attribute = Emitter.GetAttribute(attributes, Translator.H5_ASSEMBLY + ".CastAttribute"); if (attribute != null) { isCastAttr = true; return(attribute.PositionalArguments[0].ConstantValue.ToString()); } } return(null); }
protected void VisitIdentifierExpression() { IdentifierExpression identifierExpression = IdentifierExpression; int pos = Emitter.Output.Length; ResolveResult resolveResult = null; isRefArg = Emitter.IsRefArg; Emitter.IsRefArg = false; resolveResult = Emitter.Resolver.ResolveNode(identifierExpression); var id = identifierExpression.Identifier; var isResolved = resolveResult != null && !(resolveResult is ErrorResolveResult); var memberResult = resolveResult as MemberResolveResult; if (Emitter.Locals != null && Emitter.Locals.ContainsKey(id) && resolveResult is LocalResolveResult) { var lrr = (LocalResolveResult)resolveResult; if (Emitter.LocalsMap != null && Emitter.LocalsMap.ContainsKey(lrr.Variable) && !(identifierExpression.Parent is DirectionExpression)) { Write(Emitter.LocalsMap[lrr.Variable]); } else if (Emitter.LocalsNamesMap != null && Emitter.LocalsNamesMap.ContainsKey(id)) { Write(Emitter.LocalsNamesMap[id]); } else { Write(id); } Helpers.CheckValueTypeClone(resolveResult, identifierExpression, this, pos); return; } if (resolveResult is TypeResolveResult) { Write(H5Types.ToJsName(resolveResult.Type, Emitter)); /*if (this.Emitter.Validator.IsExternalType(resolveResult.Type.GetDefinition()) || resolveResult.Type.Kind == TypeKind.Enum) * { * this.Write(H5Types.ToJsName(resolveResult.Type, this.Emitter)); * } * else * { * this.Write("H5.get(" + H5Types.ToJsName(resolveResult.Type, this.Emitter) + ")"); * }*/ return; } string inlineCode = memberResult != null?Emitter.GetInline(memberResult.Member) : null; var isInvoke = identifierExpression.Parent is InvocationExpression && (((InvocationExpression)(identifierExpression.Parent)).Target == identifierExpression); if (memberResult != null && memberResult.Member is IMethod && isInvoke) { if (Emitter.Resolver.ResolveNode(identifierExpression.Parent) is CSharpInvocationResolveResult i_rr && !i_rr.IsExpandedForm) { var tpl = Emitter.GetAttribute(memberResult.Member.Attributes, JS.NS.H5 + ".TemplateAttribute"); if (tpl != null && tpl.PositionalArguments.Count == 2) { inlineCode = tpl.PositionalArguments[1].ConstantValue.ToString(); } } } if (string.IsNullOrEmpty(inlineCode) && memberResult != null && memberResult.Member is IMethod && !(memberResult is InvocationResolveResult) && !( identifierExpression.Parent is InvocationExpression && identifierExpression.NextSibling != null && identifierExpression.NextSibling.Role is TokenRole && ((TokenRole)identifierExpression.NextSibling.Role).Token == "(" ) ) { if (!(identifierExpression.Parent is InvocationExpression parentInvocation) || parentInvocation.Target != identifierExpression) { var method = (IMethod)memberResult.Member; if (method.TypeArguments.Count > 0) { inlineCode = MemberReferenceBlock.GenerateInlineForMethodReference(method, Emitter); } } } bool hasInline = !string.IsNullOrEmpty(inlineCode); inlineCode = hasInline ? Helpers.ConvertTokens(Emitter, inlineCode, memberResult.Member) : inlineCode; bool hasThis = hasInline && Helpers.HasThis(inlineCode); if (hasInline && inlineCode.StartsWith("<self>")) { hasThis = true; inlineCode = inlineCode.Substring(6); } if (hasThis) { Emitter.ThisRefCounter++; Write(""); var oldBuilder = Emitter.Output; Emitter.Output = new StringBuilder(); if (memberResult.Member.IsStatic) { Write(H5Types.ToJsName(memberResult.Member.DeclaringType, Emitter, ignoreLiteralName: false)); /*if (!this.Emitter.Validator.IsExternalType(memberResult.Member.DeclaringTypeDefinition) && memberResult.Member.DeclaringTypeDefinition.Kind != TypeKind.Enum) * { * this.Write("(H5.get(" + H5Types.ToJsName(memberResult.Member.DeclaringType, this.Emitter) + "))"); * } * else * { * this.Write(H5Types.ToJsName(memberResult.Member.DeclaringType, this.Emitter)); * }*/ } else { WriteThis(); } var oldInline = inlineCode; var thisArg = Emitter.Output.ToString(); int thisIndex = inlineCode.IndexOf("{this}"); inlineCode = inlineCode.Replace("{this}", thisArg); Emitter.Output = oldBuilder; int[] range = null; if (thisIndex > -1) { range = new[] { thisIndex, thisIndex + thisArg.Length }; } if (resolveResult is InvocationResolveResult) { PushWriter(inlineCode, null, thisArg, range); } else { if (memberResult.Member is IMethod) { ResolveResult targetrr = null; if (memberResult.Member.IsStatic) { targetrr = new TypeResolveResult(memberResult.Member.DeclaringType); } new InlineArgumentsBlock(Emitter, new ArgumentsInfo(Emitter, IdentifierExpression, resolveResult), oldInline, (IMethod)memberResult.Member, targetrr).EmitFunctionReference(); } else if (memberResult != null && memberResult.Member is IField && inlineCode.Contains("{0}")) { PushWriter(inlineCode, null, thisArg, range); } else if (InlineArgumentsBlock.FormatArgRegex.IsMatch(inlineCode)) { PushWriter(inlineCode, null, thisArg, range); } else { Write(inlineCode); } } return; } if (hasInline) { if (!memberResult.Member.IsStatic) { inlineCode = "this." + inlineCode; } if (resolveResult is InvocationResolveResult) { PushWriter(inlineCode); } else { if (memberResult.Member is IMethod) { ResolveResult targetrr = null; if (memberResult.Member.IsStatic) { targetrr = new TypeResolveResult(memberResult.Member.DeclaringType); } new InlineArgumentsBlock(Emitter, new ArgumentsInfo(Emitter, IdentifierExpression, resolveResult), inlineCode, (IMethod)memberResult.Member, targetrr).EmitFunctionReference(); } else if (InlineArgumentsBlock.FormatArgRegex.IsMatch(inlineCode)) { PushWriter(inlineCode); } else { Write(inlineCode); } } return; } string appendAdditionalCode = null; if (memberResult != null && memberResult.Member is IMethod && !(memberResult is InvocationResolveResult) && !( identifierExpression.Parent is InvocationExpression && identifierExpression.NextSibling != null && identifierExpression.NextSibling.Role is TokenRole && ((TokenRole)identifierExpression.NextSibling.Role).Token == "(" ) ) { if (!(identifierExpression.Parent is InvocationExpression parentInvocation) || parentInvocation.Target != identifierExpression) { if (!string.IsNullOrEmpty(inlineCode)) { ResolveResult targetrr = null; if (memberResult.Member.IsStatic) { targetrr = new TypeResolveResult(memberResult.Member.DeclaringType); } new InlineArgumentsBlock(Emitter, new ArgumentsInfo(Emitter, identifierExpression, resolveResult), inlineCode, (IMethod)memberResult.Member, targetrr).EmitFunctionReference(); } else { var resolvedMethod = (IMethod)memberResult.Member; bool isStatic = resolvedMethod != null && resolvedMethod.IsStatic; if (!isStatic) { var isExtensionMethod = resolvedMethod.IsExtensionMethod; Write(isExtensionMethod ? JS.Funcs.H5_BIND_SCOPE : JS.Funcs.H5_CACHE_BIND); WriteOpenParentheses(); WriteThis(); Write(", "); appendAdditionalCode = ")"; } } } } if (memberResult != null && memberResult.Member.SymbolKind == SymbolKind.Field && Emitter.IsMemberConst(memberResult.Member) && Emitter.IsInlineConst(memberResult.Member)) { WriteScript(memberResult.ConstantValue); return; } if (memberResult != null && memberResult.Member.SymbolKind == SymbolKind.Property && memberResult.TargetResult.Type.Kind != TypeKind.Anonymous) { bool isStatement = false; string valueVar = null; if (Emitter.IsUnaryAccessor) { isStatement = identifierExpression.Parent is UnaryOperatorExpression && identifierExpression.Parent.Parent is ExpressionStatement; if (NullableType.IsNullable(memberResult.Type)) { isStatement = false; } if (!isStatement) { WriteOpenParentheses(); valueVar = GetTempVarName(); Write(valueVar); Write(" = "); } } WriteTarget(memberResult); if (!string.IsNullOrWhiteSpace(inlineCode)) { //this.Write(inlineCode); if (resolveResult is InvocationResolveResult || (memberResult.Member.SymbolKind == SymbolKind.Property && Emitter.IsAssignment)) { PushWriter(inlineCode); } else { Write(inlineCode); } } else if (memberResult.Member is IProperty) { var name = Helpers.GetPropertyRef(memberResult.Member, Emitter); WriteIdentifier(name); } else if (!Emitter.IsAssignment) { if (Emitter.IsUnaryAccessor) { bool isDecimal = Helpers.IsDecimalType(memberResult.Member.ReturnType, Emitter.Resolver); bool isLong = Helpers.Is64Type(memberResult.Member.ReturnType, Emitter.Resolver); bool isNullable = NullableType.IsNullable(memberResult.Member.ReturnType); if (isStatement) { Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, true)); WriteOpenParentheses(); if (isDecimal || isLong) { if (isNullable) { Write(JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1); WriteOpenParentheses(); if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment || Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { WriteScript(JS.Funcs.Math.INC); } else { WriteScript(JS.Funcs.Math.DEC); } WriteComma(); WriteTarget(memberResult); Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false)); WriteOpenParentheses(); WriteCloseParentheses(); WriteCloseParentheses(); } else { WriteTarget(memberResult); Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false)); WriteOpenParentheses(); WriteCloseParentheses(); WriteDot(); if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment || Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { Write(JS.Funcs.Math.INC); } else { Write(JS.Funcs.Math.DEC); } WriteOpenParentheses(); WriteCloseParentheses(); } } else { WriteTarget(memberResult); Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false)); WriteOpenParentheses(); WriteCloseParentheses(); if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment || Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { Write("+"); } else { Write("-"); } Write("1"); } WriteCloseParentheses(); } else { Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false)); WriteOpenParentheses(); WriteCloseParentheses(); WriteComma(); WriteTarget(memberResult); Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, true)); WriteOpenParentheses(); if (isDecimal || isLong) { if (isNullable) { Write(JS.Types.SYSTEM_NULLABLE + "." + JS.Funcs.Math.LIFT1); WriteOpenParentheses(); if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment || Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { WriteScript(JS.Funcs.Math.INC); } else { WriteScript(JS.Funcs.Math.DEC); } WriteComma(); Write(valueVar); WriteCloseParentheses(); } else { Write(valueVar); WriteDot(); if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment || Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { Write(JS.Funcs.Math.INC); } else { Write(JS.Funcs.Math.DEC); } WriteOpenParentheses(); WriteCloseParentheses(); } } else { Write(valueVar); if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment || Emitter.UnaryOperatorType == UnaryOperatorType.PostIncrement) { Write("+"); } else { Write("-"); } Write("1"); } WriteCloseParentheses(); WriteComma(); if (Emitter.UnaryOperatorType == UnaryOperatorType.Increment || Emitter.UnaryOperatorType == UnaryOperatorType.Decrement) { WriteTarget(memberResult); Write(Helpers.GetPropertyRef(memberResult.Member, Emitter, false)); WriteOpenParentheses(); WriteCloseParentheses(); } else { Write(valueVar); } WriteCloseParentheses(); if (valueVar != null) { RemoveTempVar(valueVar); } } } else { Write(Helpers.GetPropertyRef(memberResult.Member, Emitter)); WriteOpenParentheses(); WriteCloseParentheses(); } } else if (Emitter.AssignmentType != AssignmentOperatorType.Assign) { string trg; if (memberResult.Member.IsStatic) { trg = H5Types.ToJsName(memberResult.Member.DeclaringType, Emitter, ignoreLiteralName: false); } else { trg = "this"; } bool isBool = memberResult != null && NullableType.IsNullable(memberResult.Member.ReturnType) ? NullableType.GetUnderlyingType(memberResult.Member.ReturnType).IsKnownType(KnownTypeCode.Boolean) : memberResult.Member.ReturnType.IsKnownType(KnownTypeCode.Boolean); bool skipGet = false; bool special = Emitter.Resolver.ResolveNode(identifierExpression.Parent) is OperatorResolveResult orr && orr.IsLiftedOperator; if (!special && isBool && (Emitter.AssignmentType == AssignmentOperatorType.BitwiseAnd || Emitter.AssignmentType == AssignmentOperatorType.BitwiseOr)) { skipGet = true; } if (skipGet) { PushWriter(string.Concat(Helpers.GetPropertyRef(memberResult.Member, Emitter, true), "({0})")); } else { PushWriter(string.Concat(Helpers.GetPropertyRef(memberResult.Member, Emitter, true), "(", trg, ".", Helpers.GetPropertyRef(memberResult.Member, Emitter, false), "()", "{0})")); } } else { PushWriter(Helpers.GetPropertyRef(memberResult.Member, Emitter, true) + "({0})"); } } else if (memberResult != null && memberResult.Member is IEvent) { if (Emitter.IsAssignment && (Emitter.AssignmentType == AssignmentOperatorType.Add || Emitter.AssignmentType == AssignmentOperatorType.Subtract)) { WriteTarget(memberResult); if (!string.IsNullOrWhiteSpace(inlineCode)) { Write(inlineCode); } else { Write(Helpers.GetAddOrRemove(Emitter.AssignmentType == AssignmentOperatorType.Add)); Write( OverloadsCollection.Create(Emitter, memberResult.Member, Emitter.AssignmentType == AssignmentOperatorType.Subtract).GetOverloadName()); } WriteOpenParentheses(); } else { WriteTarget(memberResult); Write(Emitter.GetEntityName(memberResult.Member)); } } else { if (!string.IsNullOrWhiteSpace(inlineCode)) { Write(inlineCode); } else if (isResolved) { if (resolveResult is LocalResolveResult localResolveResult) { Write(localResolveResult.Variable.Name); } else if (memberResult != null) { WriteTarget(memberResult); string name = OverloadsCollection.Create(Emitter, memberResult.Member).GetOverloadName(); if (isRefArg) { WriteScript(name); } else if (memberResult.Member is IField) { WriteIdentifier(name); } else { Write(name); } } else { Write(resolveResult.ToString()); } } else { throw new EmitterException(identifierExpression, "Cannot resolve identifier: " + id); } } if (appendAdditionalCode != null) { Write(appendAdditionalCode); } Helpers.CheckValueTypeClone(resolveResult, identifierExpression, this, pos); }
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; }