protected void VisitForeachStatement(bool?replaceAwaiterByVar = null) { ForeachStatement foreachStatement = ForeachStatement; var jumpStatements = Emitter.JumpStatements; Emitter.JumpStatements = null; if (foreachStatement.EmbeddedStatement is EmptyStatement) { return; } WriteSourceMapName(foreachStatement.VariableName); var iteratorVar = GetTempVarName(); var iteratorName = AddLocal(iteratorVar, null, AstType.Null); var rr = (ForEachResolveResult)Emitter.Resolver.ResolveNode(foreachStatement); var get_rr = rr.GetEnumeratorCall as InvocationResolveResult; var in_rr = Emitter.Resolver.ResolveNode(foreachStatement.InExpression); var inline = get_rr != null?Emitter.GetInline(get_rr.Member) : null; var checkEnum = in_rr.Type.Kind != TypeKind.Array && !in_rr.Type.IsKnownType(KnownTypeCode.String) && !in_rr.Type.IsKnownType(KnownTypeCode.Array); var isGenericEnumerable = rr.CollectionType.IsParameterized && rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable"; var emitInline = checkEnum && !isGenericEnumerable && inline != null; Write(iteratorName, " = "); if (!emitInline) { Write(JS.Funcs.H5_GET_ENUMERATOR); WriteOpenParentheses(); foreachStatement.InExpression.AcceptVisitor(Emitter); } if (checkEnum) { if (isGenericEnumerable) { WriteComma(false); Write(H5Types.ToJsName(((ParameterizedType)rr.CollectionType).TypeArguments[0], Emitter)); } else if (get_rr != null) { if (inline != null) { var argsInfo = new ArgumentsInfo(Emitter, foreachStatement.InExpression, get_rr); new InlineArgumentsBlock(Emitter, argsInfo, inline).Emit(); } else { var name = OverloadsCollection.Create(Emitter, get_rr.Member).GetOverloadName(); if (name != "GetEnumerator" && name != "System$Collections$IEnumerable$GetEnumerator") { WriteComma(false); WriteScript(name); } } } } if (!emitInline) { WriteCloseParentheses(); } WriteSemiColon(); WriteNewLine(); WriteTry(); BeginBlock(); WriteWhile(); WriteOpenParentheses(); Write(iteratorName); WriteDot(); Write(JS.Funcs.MOVE_NEXT); WriteOpenCloseParentheses(); WriteCloseParentheses(); WriteSpace(); BeginBlock(); PushLocals(); Action ac = () => { bool isReferenceLocal = false; if (Emitter.LocalsMap != null && Emitter.LocalsMap.ContainsKey(rr.ElementVariable)) { isReferenceLocal = Emitter.LocalsMap[rr.ElementVariable].EndsWith(".v"); } var varName = AddLocal(foreachStatement.VariableName, foreachStatement.VariableNameToken, foreachStatement.VariableType); WriteVar(); Write(varName + " = "); if (isReferenceLocal) { Write("{ v : "); } string castCode = GetCastCode(rr.ElementType, rr.ElementVariable.Type); if (castCode != null) { EmitInlineCast(iteratorName + "." + JS.Funcs.GET_CURRENT, castCode); } else if (CastMethod != null) { Write(H5Types.ToJsName(CastMethod.DeclaringType, Emitter)); WriteDot(); Write(OverloadsCollection.Create(Emitter, CastMethod).GetOverloadName()); WriteOpenParentheses(); int pos = Emitter.Output.Length; Write(iteratorName + "." + JS.Funcs.GET_CURRENT); Helpers.CheckValueTypeClone(rr, ForeachStatement.InExpression, this, pos); WriteCloseParentheses(); } else { var needCast = !rr.ElementType.Equals(rr.ElementVariable.Type); if (needCast) { Write(JS.Funcs.H5_CAST); WriteOpenParentheses(); } int pos = Emitter.Output.Length; Write(iteratorName); WriteDot(); Write(JS.Funcs.GET_CURRENT); Helpers.CheckValueTypeClone(rr, ForeachStatement.InExpression, this, pos); if (needCast) { Write(", ", H5Types.ToJsName(rr.ElementVariable.Type, Emitter), ")"); } } if (isReferenceLocal) { Write(" }"); } WriteSemiColon(); WriteNewLine(); }; Emitter.BeforeBlock = ac; if (replaceAwaiterByVar.HasValue) { Emitter.ReplaceAwaiterByVar = replaceAwaiterByVar.Value; } if (foreachStatement.EmbeddedStatement is BlockStatement block) { Emitter.NoBraceBlock = block; } foreachStatement.EmbeddedStatement.AcceptVisitor(Emitter); PopLocals(); if (!Emitter.IsNewLine) { WriteNewLine(); } EndBlock(); WriteNewLine(); EndBlock(); WriteSpace(); WriteFinally(); BeginBlock(); Write($"if ({JS.Types.H5.IS}({iteratorName}, {JS.Types.System.IDisposable.NAME})) "); BeginBlock(); Write($"{iteratorName}.{JS.Types.System.IDisposable.INTERFACE_DISPOSE}();"); WriteNewLine(); EndBlock(); WriteNewLine(); EndBlock(); WriteNewLine(); Emitter.JumpStatements = jumpStatements; }
protected void VisitAsyncForeachStatement() { ForeachStatement foreachStatement = ForeachStatement; if (foreachStatement.EmbeddedStatement is EmptyStatement) { return; } var oldValue = Emitter.ReplaceAwaiterByVar; var jumpStatements = Emitter.JumpStatements; Emitter.JumpStatements = new List <IJumpInfo>(); WriteAwaiters(foreachStatement.InExpression); bool containsAwaits = false; var awaiters = GetAwaiters(foreachStatement.EmbeddedStatement); if (awaiters != null && awaiters.Length > 0) { containsAwaits = true; } Emitter.ReplaceAwaiterByVar = true; if (!containsAwaits) { VisitForeachStatement(oldValue); return; } var iteratorName = AddLocal(GetTempVarName(), null, AstType.Null); var for_rr = (ForEachResolveResult)Emitter.Resolver.ResolveNode(foreachStatement); var get_rr = for_rr.GetEnumeratorCall as InvocationResolveResult; var in_rr = Emitter.Resolver.ResolveNode(foreachStatement.InExpression); var inline = get_rr != null?Emitter.GetInline(get_rr.Member) : null; var checkEnum = in_rr.Type.Kind != TypeKind.Array && !in_rr.Type.IsKnownType(KnownTypeCode.String) && !in_rr.Type.IsKnownType(KnownTypeCode.Array); var isGenericEnumerable = for_rr.CollectionType.IsParameterized && for_rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable"; var emitInline = checkEnum && !isGenericEnumerable && inline != null; Write(iteratorName, " = "); if (!emitInline) { Write(JS.Funcs.H5_GET_ENUMERATOR); WriteOpenParentheses(); foreachStatement.InExpression.AcceptVisitor(Emitter); } if (checkEnum) { if (for_rr.CollectionType.IsParameterized && for_rr.CollectionType.FullName == "System.Collections.Generic.IEnumerable") { WriteComma(false); Write(H5Types.ToJsName(((ParameterizedType)for_rr.CollectionType).TypeArguments[0], Emitter)); } else if (get_rr != null) { if (inline != null) { var argsInfo = new ArgumentsInfo(Emitter, foreachStatement.InExpression, get_rr); new InlineArgumentsBlock(Emitter, argsInfo, inline).Emit(); } else { var name = OverloadsCollection.Create(Emitter, get_rr.Member).GetOverloadName(); if (name != "GetEnumerator" && name != "System$Collections$IEnumerable$GetEnumerator") { WriteComma(false); WriteScript(name); } } } } Emitter.ReplaceAwaiterByVar = oldValue; if (!emitInline) { WriteCloseParentheses(); } WriteSemiColon(); WriteNewLine(); Write(JS.Vars.ASYNC_STEP + " = " + Emitter.AsyncBlock.Step + ";"); WriteNewLine(); Write("continue;"); WriteNewLine(); IAsyncStep conditionStep = Emitter.AsyncBlock.AddAsyncStep(); WriteIf(); WriteOpenParentheses(); Write(iteratorName); WriteDot(); Write(JS.Funcs.MOVE_NEXT); WriteOpenCloseParentheses(); WriteCloseParentheses(); WriteSpace(); BeginBlock(); PushLocals(); var varName = AddLocal(foreachStatement.VariableName, foreachStatement.VariableNameToken, foreachStatement.VariableType); WriteVar(); Write(varName + " = "); var rr = Emitter.Resolver.ResolveNode(foreachStatement) as ForEachResolveResult; bool isReferenceLocal = false; if (Emitter.LocalsMap != null && Emitter.LocalsMap.ContainsKey(rr.ElementVariable)) { isReferenceLocal = Emitter.LocalsMap[rr.ElementVariable].EndsWith(".v"); } if (isReferenceLocal) { Write("{ v : "); } string castCode = GetCastCode(rr.ElementType, rr.ElementVariable.Type); if (castCode != null) { EmitInlineCast(iteratorName + "." + JS.Funcs.GET_CURRENT, castCode); } else if (CastMethod != null) { Write(H5Types.ToJsName(CastMethod.DeclaringType, Emitter)); WriteDot(); Write(OverloadsCollection.Create(Emitter, CastMethod).GetOverloadName()); WriteOpenParentheses(); var pos = Emitter.Output.Length; Write(iteratorName + "." + JS.Funcs.GET_CURRENT); Helpers.CheckValueTypeClone(rr, ForeachStatement.InExpression, this, pos); WriteCloseParentheses(); } else { var needCast = !rr.ElementType.Equals(rr.ElementVariable.Type); if (needCast) { Write(JS.Funcs.H5_CAST); WriteOpenParentheses(); } var pos = Emitter.Output.Length; Write(iteratorName); WriteDot(); Write(JS.Funcs.GET_CURRENT); Helpers.CheckValueTypeClone(rr, ForeachStatement.InExpression, this, pos); if (needCast) { Write(", ", H5Types.ToJsName(rr.ElementVariable.Type, Emitter), ")"); } } if (isReferenceLocal) { Write(" }"); } WriteSemiColon(); WriteNewLine(); Write(JS.Vars.ASYNC_STEP + " = " + Emitter.AsyncBlock.Step + ";"); WriteNewLine(); Write("continue;"); var writer = SaveWriter(); Emitter.AsyncBlock.AddAsyncStep(); Emitter.IgnoreBlock = foreachStatement.EmbeddedStatement; var startCount = Emitter.AsyncBlock.Steps.Count; if (foreachStatement.EmbeddedStatement is BlockStatement block) { block.AcceptChildren(Emitter); } else { foreachStatement.EmbeddedStatement.AcceptVisitor(Emitter); } IAsyncStep loopStep = null; if (Emitter.AsyncBlock.Steps.Count > startCount) { loopStep = Emitter.AsyncBlock.Steps.Last(); loopStep.JumpToStep = conditionStep.Step; } RestoreWriter(writer); if (!IsJumpStatementLast(Emitter.Output.ToString())) { Write(JS.Vars.ASYNC_STEP + " = " + conditionStep.Step + ";"); WriteNewLine(); Write("continue;"); WriteNewLine(); } PopLocals(); WriteNewLine(); EndBlock(); WriteNewLine(); var nextStep = Emitter.AsyncBlock.AddAsyncStep(); conditionStep.JumpToStep = nextStep.Step; if (Emitter.JumpStatements.Count > 0) { Emitter.JumpStatements.Sort((j1, j2) => - j1.Position.CompareTo(j2.Position)); foreach (var jump in Emitter.JumpStatements) { jump.Output.Insert(jump.Position, jump.Break ? nextStep.Step : conditionStep.Step); } } Emitter.JumpStatements = jumpStatements; }
protected void VisitInvocationExpression() { InvocationExpression invocationExpression = InvocationExpression; int pos = Emitter.Output.Length; if (Emitter.IsForbiddenInvocation(invocationExpression)) { throw new EmitterException(invocationExpression, "This method cannot be invoked directly"); } var oldValue = Emitter.ReplaceAwaiterByVar; var oldAsyncExpressionHandling = Emitter.AsyncExpressionHandling; if (Emitter.IsAsync && !Emitter.AsyncExpressionHandling) { WriteAwaiters(invocationExpression); Emitter.ReplaceAwaiterByVar = true; Emitter.AsyncExpressionHandling = true; } Tuple <bool, bool, string> inlineInfo = Emitter.GetInlineCode(invocationExpression); var argsInfo = new ArgumentsInfo(Emitter, invocationExpression); var argsExpressions = argsInfo.ArgumentsExpressions; var paramsArg = argsInfo.ParamsExpression; var targetResolve = Emitter.Resolver.ResolveNode(invocationExpression); var csharpInvocation = targetResolve as CSharpInvocationResolveResult; MemberReferenceExpression targetMember = invocationExpression.Target as MemberReferenceExpression; bool isObjectLiteral = csharpInvocation != null && csharpInvocation.Member.DeclaringTypeDefinition != null?Emitter.Validator.IsObjectLiteral(csharpInvocation.Member.DeclaringTypeDefinition) : false; if (inlineInfo != null) { bool isStaticMethod = inlineInfo.Item1; bool isInlineMethod = inlineInfo.Item2; string inlineScript = inlineInfo.Item3; if (isInlineMethod) { if (invocationExpression.Arguments.Count > 0) { var code = invocationExpression.Arguments.First(); if (!(code is PrimitiveExpression inlineExpression)) { throw new EmitterException(invocationExpression, "Only primitive expression can be inlined"); } string value = inlineExpression.Value.ToString().Trim(); if (value.Length > 0) { value = InlineArgumentsBlock.ReplaceInlineArgs(this, inlineExpression.Value.ToString(), invocationExpression.Arguments.Skip(1).ToArray()); Write(value); value = value.Trim(); if (value[value.Length - 1] == ';' || value.EndsWith("*/", StringComparison.InvariantCulture) || value.StartsWith("//")) { Emitter.SkipSemiColon = true; WriteNewLine(); } } else { // Empty string, emit nothing. Emitter.SkipSemiColon = true; } Emitter.ReplaceAwaiterByVar = oldValue; Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } else { bool isBase = invocationExpression.Target is MemberReferenceExpression targetMemberRef && targetMemberRef.Target is BaseReferenceExpression; if (!String.IsNullOrEmpty(inlineScript) && (isBase || invocationExpression.Target is IdentifierExpression)) { argsInfo.ThisArgument = "this"; bool noThis = !Helpers.HasThis(inlineScript); if (inlineScript.StartsWith("<self>")) { noThis = false; inlineScript = inlineScript.Substring(6); } if (!noThis) { Emitter.ThisRefCounter++; } if (!isStaticMethod && noThis) { WriteThis(); WriteDot(); } new InlineArgumentsBlock(Emitter, argsInfo, inlineScript).Emit(); Emitter.ReplaceAwaiterByVar = oldValue; Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } } if (targetMember != null || isObjectLiteral) { var member = targetMember != null?Emitter.Resolver.ResolveNode(targetMember.Target) : null; if (targetResolve != null) { InvocationResolveResult invocationResult; bool isExtensionMethodInvocation = false; if (csharpInvocation != null) { if (member != null && member.Type.Kind == TypeKind.Delegate && (/*csharpInvocation.Member.Name == "Invoke" || */ csharpInvocation.Member.Name == "BeginInvoke" || csharpInvocation.Member.Name == "EndInvoke") && !csharpInvocation.IsExtensionMethodInvocation) { throw new EmitterException(invocationExpression, "Delegate's 'Invoke' methods are not supported. Please use direct delegate invoke."); } if (csharpInvocation.IsExtensionMethodInvocation) { invocationResult = csharpInvocation; isExtensionMethodInvocation = true; if (invocationResult.Member is IMethod resolvedMethod && resolvedMethod.IsExtensionMethod) { string inline = Emitter.GetInline(resolvedMethod); bool isNative = IsNativeMethod(resolvedMethod); if (string.IsNullOrWhiteSpace(inline) && isNative) { invocationResult = null; } } } else { invocationResult = null; } if (IsEmptyPartialInvoking(csharpInvocation.Member as IMethod) || IsConditionallyRemoved(invocationExpression, csharpInvocation.Member)) { Emitter.SkipSemiColon = true; Emitter.ReplaceAwaiterByVar = oldValue; Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } else { invocationResult = targetResolve as InvocationResolveResult; if (invocationResult != null && (IsEmptyPartialInvoking(invocationResult.Member as IMethod) || IsConditionallyRemoved(invocationExpression, invocationResult.Member))) { Emitter.SkipSemiColon = true; Emitter.ReplaceAwaiterByVar = oldValue; Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } if (invocationResult == null) { invocationResult = Emitter.Resolver.ResolveNode(invocationExpression) as InvocationResolveResult; } if (invocationResult != null) { if (invocationResult.Member is IMethod resolvedMethod && (resolvedMethod.IsExtensionMethod || isObjectLiteral)) { string inline = Emitter.GetInline(resolvedMethod); bool isNative = IsNativeMethod(resolvedMethod); if (isExtensionMethodInvocation || isObjectLiteral) { if (!string.IsNullOrWhiteSpace(inline)) { Write(""); StringBuilder savedBuilder = Emitter.Output; Emitter.Output = new StringBuilder(); WriteThisExtension(invocationExpression.Target); argsInfo.ThisArgument = Emitter.Output.ToString(); Emitter.Output = savedBuilder; new InlineArgumentsBlock(Emitter, argsInfo, inline).Emit(); } else if (!isNative) { var overloads = OverloadsCollection.Create(Emitter, resolvedMethod); if (isObjectLiteral && !resolvedMethod.IsStatic && resolvedMethod.DeclaringType.Kind == TypeKind.Interface) { Write("H5.getType("); WriteThisExtension(invocationExpression.Target); Write(")."); } else { string name = H5Types.ToJsName(resolvedMethod.DeclaringType, Emitter, ignoreLiteralName: false) + "."; Write(name); } if (isObjectLiteral && !resolvedMethod.IsStatic) { Write(JS.Fields.PROTOTYPE + "." + overloads.GetOverloadName() + "." + JS.Funcs.CALL); } else { Write(overloads.GetOverloadName()); } var isIgnoreClass = resolvedMethod.DeclaringTypeDefinition != null && Emitter.Validator.IsExternalType(resolvedMethod.DeclaringTypeDefinition); int openPos = Emitter.Output.Length; WriteOpenParentheses(); Emitter.Comma = false; if (isObjectLiteral && !resolvedMethod.IsStatic) { WriteThisExtension(invocationExpression.Target); Emitter.Comma = true; } if (!isIgnoreClass && !Helpers.IsIgnoreGeneric(resolvedMethod, Emitter) && argsInfo.HasTypeArguments) { EnsureComma(false); new TypeExpressionListBlock(Emitter, argsInfo.TypeArguments).Emit(); Emitter.Comma = true; } if (!isObjectLiteral && resolvedMethod.IsStatic) { EnsureComma(false); WriteThisExtension(invocationExpression.Target); Emitter.Comma = true; } if (invocationExpression.Arguments.Count > 0) { EnsureComma(false); } new ExpressionListBlock(Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit(); WriteCloseParentheses(); } if (!string.IsNullOrWhiteSpace(inline) || !isNative) { Emitter.ReplaceAwaiterByVar = oldValue; Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } else if (isNative) { if (!string.IsNullOrWhiteSpace(inline)) { Write(""); StringBuilder savedBuilder = Emitter.Output; Emitter.Output = new StringBuilder(); WriteThisExtension(invocationExpression.Target); argsInfo.ThisArgument = Emitter.Output.ToString(); Emitter.Output = savedBuilder; new InlineArgumentsBlock(Emitter, argsInfo, inline).Emit(); } else { argsExpressions.First().AcceptVisitor(Emitter); WriteDot(); string name = Emitter.GetEntityName(resolvedMethod); Write(name); int openPos = Emitter.Output.Length; WriteOpenParentheses(); new ExpressionListBlock(Emitter, argsExpressions.Skip(1), paramsArg, invocationExpression, openPos).Emit(); WriteCloseParentheses(); } Emitter.ReplaceAwaiterByVar = oldValue; Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } } } } } var proto = false; if (targetMember != null && targetMember.Target is BaseReferenceExpression) { if (Emitter.Resolver.ResolveNode(targetMember) is MemberResolveResult rr) { proto = rr.IsVirtualCall; /*var method = rr.Member as IMethod; * if (method != null && method.IsVirtual) * { * proto = true; * } * else * { * var prop = rr.Member as IProperty; * * if (prop != null && prop.IsVirtual) * { * proto = true; * } * }*/ } } if (proto) { var baseType = Emitter.GetBaseMethodOwnerTypeDefinition(targetMember.MemberName, targetMember.TypeArguments.Count); bool isIgnore = Emitter.Validator.IsExternalType(baseType); bool needComma = false; var resolveResult = Emitter.Resolver.ResolveNode(targetMember); string name = null; if (Emitter.TypeInfo.GetBaseTypes(Emitter).Any()) { name = H5Types.ToJsName(Emitter.TypeInfo.GetBaseClass(Emitter), Emitter); } else { name = H5Types.ToJsName(baseType, Emitter); } string baseMethod; bool isIgnoreGeneric = false; if (resolveResult is MemberResolveResult memberResult) { baseMethod = OverloadsCollection.Create(Emitter, memberResult.Member).GetOverloadName(); isIgnoreGeneric = Helpers.IsIgnoreGeneric(memberResult.Member, Emitter); } else { baseMethod = targetMember.MemberName; baseMethod = Object.Net.Utilities.StringUtils.ToLowerCamelCase(baseMethod); } Write(name, "." + JS.Fields.PROTOTYPE + ".", baseMethod); WriteCall(); WriteOpenParentheses(); WriteThis(); Emitter.Comma = true; if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments) { new TypeExpressionListBlock(Emitter, argsInfo.TypeArguments).Emit(); } needComma = false; foreach (var arg in argsExpressions) { if (arg == null) { continue; } EnsureComma(false); if (needComma) { WriteComma(); } needComma = true; arg.AcceptVisitor(Emitter); } Emitter.Comma = false; WriteCloseParentheses(); } else { IMethod method = null; if (Emitter.Resolver.ResolveNode(invocationExpression) is DynamicInvocationResolveResult dynamicResolveResult) { if (dynamicResolveResult.Target is MethodGroupResolveResult group && group.Methods.Count() > 1) { method = group.Methods.FirstOrDefault(m => { if (dynamicResolveResult.Arguments.Count != m.Parameters.Count) { return(false); } for (int i = 0; i < m.Parameters.Count; i++) { var argType = dynamicResolveResult.Arguments[i].Type; if (argType.Kind == TypeKind.Dynamic) { argType = Emitter.Resolver.Compilation.FindType(TypeCode.Object); } if (!m.Parameters[i].Type.Equals(argType)) { return(false); } } return(true); }); if (method == null) { throw new EmitterException(invocationExpression, Constants.Messages.Exceptions.DYNAMIC_INVOCATION_TOO_MANY_OVERLOADS); } } } else { var targetResolveResult = Emitter.Resolver.ResolveNode(invocationExpression.Target); if (targetResolveResult is MemberResolveResult invocationResolveResult) { method = invocationResolveResult.Member as IMethod; } } if (IsEmptyPartialInvoking(method) || IsConditionallyRemoved(invocationExpression, method)) { Emitter.SkipSemiColon = true; Emitter.ReplaceAwaiterByVar = oldValue; Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; return; } bool isIgnore = method != null && method.DeclaringTypeDefinition != null && Emitter.Validator.IsExternalType(method.DeclaringTypeDefinition); bool needExpand = false; if (method != null) { string paramsName = null; var paramsParam = method.Parameters.FirstOrDefault(p => p.IsParams); if (paramsParam != null) { paramsName = paramsParam.Name; } if (paramsName != null) { if (csharpInvocation != null && !csharpInvocation.IsExpandedForm) { needExpand = true; } } } int count = Emitter.Writers.Count; invocationExpression.Target.AcceptVisitor(Emitter); if (Emitter.Writers.Count > count) { var writer = Emitter.Writers.Pop(); if (method != null && method.IsExtensionMethod) { StringBuilder savedBuilder = Emitter.Output; Emitter.Output = new StringBuilder(); WriteThisExtension(invocationExpression.Target); argsInfo.ThisArgument = Emitter.Output.ToString(); Emitter.Output = savedBuilder; } else if (writer.ThisArg != null) { argsInfo.ThisArgument = writer.ThisArg; } new InlineArgumentsBlock(Emitter, argsInfo, writer.InlineCode) { IgnoreRange = writer.IgnoreRange }.Emit(); var result = Emitter.Output.ToString(); Emitter.Output = writer.Output; Emitter.IsNewLine = writer.IsNewLine; Write(result); if (writer.Callback != null) { writer.Callback.Invoke(); } } else { if (needExpand && isIgnore) { Write("." + JS.Funcs.APPLY); } int openPos = Emitter.Output.Length; WriteOpenParentheses(); bool isIgnoreGeneric = false; if (targetResolve is InvocationResolveResult invocationResult) { isIgnoreGeneric = Helpers.IsIgnoreGeneric(invocationResult.Member, Emitter); } bool isWrapRest = false; if (needExpand && isIgnore) { StringBuilder savedBuilder = Emitter.Output; Emitter.Output = new StringBuilder(); WriteThisExtension(invocationExpression.Target); var thisArg = Emitter.Output.ToString(); Emitter.Output = savedBuilder; Write(thisArg); Emitter.Comma = true; if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments) { new TypeExpressionListBlock(Emitter, argsInfo.TypeArguments).Emit(); } EnsureComma(false); if (argsExpressions.Length > 1) { WriteOpenBracket(); var elb = new ExpressionListBlock(Emitter, argsExpressions.Take(argsExpressions.Length - 1).ToArray(), paramsArg, invocationExpression, openPos); elb.IgnoreExpandParams = true; elb.Emit(); WriteCloseBracket(); Write(".concat("); elb = new ExpressionListBlock(Emitter, new Expression[] { argsExpressions[argsExpressions.Length - 1] }, paramsArg, invocationExpression, openPos); elb.IgnoreExpandParams = true; elb.Emit(); Write(")"); } else { new ExpressionListBlock(Emitter, argsExpressions, paramsArg, invocationExpression, -1).Emit(); } } else { if (method != null && method.Attributes.Any(a => a.AttributeType.FullName == "H5.WrapRestAttribute")) { isWrapRest = true; } Emitter.Comma = false; if (!isIgnore && !isIgnoreGeneric && argsInfo.HasTypeArguments) { new TypeExpressionListBlock(Emitter, argsInfo.TypeArguments).Emit(); } if (invocationExpression.Arguments.Count > 0 || argsExpressions.Length > 0 && !argsExpressions.All(expr => expr == null)) { EnsureComma(false); } new ExpressionListBlock(Emitter, argsExpressions, paramsArg, invocationExpression, openPos).Emit(); } if (isWrapRest) { EnsureComma(false); Write("H5.fn.bind(this, function () "); BeginBlock(); Emitter.WrapRestCounter++; Emitter.SkipSemiColon = true; } else { Emitter.Comma = false; WriteCloseParentheses(); } } } if (targetResolve is InvocationResolveResult irr && irr.Member.MemberDefinition != null && irr.Member.MemberDefinition.ReturnType.Kind == TypeKind.TypeParameter) { Helpers.CheckValueTypeClone(Emitter.Resolver.ResolveNode(invocationExpression), invocationExpression, this, pos); } Emitter.ReplaceAwaiterByVar = oldValue; Emitter.AsyncExpressionHandling = oldAsyncExpressionHandling; }