public override void VisitLabelStatement(LabelStatement labelStatement) { if (AsyncBlock != null) { var step = AsyncBlock.AddAsyncStep(); step.Label = labelStatement.Label; step.Node = labelStatement; } }
protected void VisitMethodDeclaration(MethodDeclaration methodDeclaration) { foreach (var attrSection in methodDeclaration.Attributes) { foreach (var attr in attrSection.Attributes) { var rr = Emitter.Resolver.ResolveNode(attr.Type); if (rr.Type.FullName == "H5.ExternalAttribute") { return; } else if (rr.Type.FullName == "H5.InitAttribute") { InitPosition initPosition = InitPosition.After; if (attr.HasArgumentList) { if (attr.Arguments.Any()) { var argExpr = attr.Arguments.First(); var argrr = Emitter.Resolver.ResolveNode(argExpr); if (argrr.ConstantValue is int) { initPosition = (InitPosition)argrr.ConstantValue; } } } if (initPosition > 0) { return; } } } } EnsureComma(); ResetLocals(); var prevMap = BuildLocalsMap(); var prevNamesMap = BuildLocalsNamesMap(); AddLocals(methodDeclaration.Parameters, methodDeclaration.Body); var overloads = OverloadsCollection.Create(Emitter, methodDeclaration); XmlToJsDoc.EmitComment(this, MethodDeclaration); var isEntryPoint = Helpers.IsEntryPointMethod(Emitter, MethodDeclaration); var member_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(MethodDeclaration); string name = overloads.GetOverloadName(false, null, excludeTypeOnly: OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr)); if (isEntryPoint) { Write(JS.Funcs.ENTRY_POINT_NAME); } else { Write(name); } WriteColon(); WriteFunction(); if (isEntryPoint) { Write(name); WriteSpace(); } EmitMethodParameters(methodDeclaration.Parameters, methodDeclaration.TypeParameters.Count > 0 && Helpers.IsIgnoreGeneric(methodDeclaration, Emitter) ? null : methodDeclaration.TypeParameters, methodDeclaration); WriteSpace(); var script = Emitter.GetScript(methodDeclaration); if (script == null) { if (YieldBlock.HasYield(methodDeclaration.Body)) { new GeneratorBlock(Emitter, methodDeclaration).Emit(); } else if (methodDeclaration.HasModifier(Modifiers.Async) || AsyncBlock.HasGoto(methodDeclaration.Body)) { new AsyncBlock(Emitter, methodDeclaration).Emit(); } else { methodDeclaration.Body.AcceptVisitor(Emitter); } } else { BeginBlock(); WriteLines(script); EndBlock(); } ClearLocalsMap(prevMap); ClearLocalsNamesMap(prevNamesMap); Emitter.Comma = true; }
protected virtual void EmitLambda(IEnumerable <ParameterDeclaration> parameters, AstNode body, AstNode context) { var rr = Emitter.Resolver.ResolveNode(context); var oldLifting = Emitter.ForbidLifting; Emitter.ForbidLifting = false; var noLiftingRule = Emitter.Rules.Lambda == LambdaRule.Plain; CaptureAnalyzer analyzer = null; if (!noLiftingRule) { analyzer = new CaptureAnalyzer(Emitter); analyzer.Analyze(Body, Parameters.Select(p => p.Name)); } var oldLevel = Emitter.Level; if (!noLiftingRule && analyzer.UsedVariables.Count == 0) { Emitter.ResetLevel(); Indent(); } IAsyncBlock asyncBlock = null; PushLocals(); if (IsAsync) { if (context is LambdaExpression) { asyncBlock = new AsyncBlock(Emitter, (LambdaExpression)context); } else { asyncBlock = new AsyncBlock(Emitter, (AnonymousMethodExpression)context); } asyncBlock.InitAsyncBlock(); } else if (YieldBlock.HasYield(body)) { IsAsync = true; if (context is LambdaExpression) { asyncBlock = new GeneratorBlock(Emitter, (LambdaExpression)context); } else { asyncBlock = new GeneratorBlock(Emitter, (AnonymousMethodExpression)context); } asyncBlock.InitAsyncBlock(); } var prevMap = BuildLocalsMap(); var prevNamesMap = BuildLocalsNamesMap(); AddLocals(parameters, body); bool block = body is BlockStatement; Write(""); var savedThisCount = Emitter.ThisRefCounter; var capturedVariables = GetCapturedLoopVariablesNames(); var hasCapturedVariables = capturedVariables != null && capturedVariables.Length > 0; if (hasCapturedVariables) { Write("(function ($me, "); Write(string.Join(", ", capturedVariables) + ") "); BeginBlock(); Write("return "); } var savedPos = Emitter.Output.Length; WriteFunction(); EmitMethodParameters(parameters, null, context); WriteSpace(); int pos = 0; if (!block && !IsAsync) { BeginBlock(); pos = Emitter.Output.Length; } bool isSimpleLambda = body.Parent is LambdaExpression && !block && !IsAsync; if (isSimpleLambda) { ConvertParamsToReferences(parameters); if (!(rr is LambdaResolveResult lrr) || lrr.ReturnType.Kind != TypeKind.Void) { WriteReturn(true); } } if (IsAsync) { asyncBlock.Emit(true); } else { body.AcceptVisitor(Emitter); } if (isSimpleLambda) { WriteSemiColon(); } if (!block && !IsAsync) { WriteNewLine(); EndBlock(); } if (!block && !IsAsync) { EmitTempVars(pos); } if (!noLiftingRule && analyzer.UsedVariables.Count == 0) { if (!Emitter.ForbidLifting) { var name = "f" + (Emitter.NamedFunctions.Count + 1); var code = Emitter.Output.ToString().Substring(savedPos); var codeForComare = RemoveTokens(code); var pair = Emitter.NamedFunctions.FirstOrDefault(p => { if (Emitter.AssemblyInfo.SourceMap.Enabled) { return(RemoveTokens(p.Value) == codeForComare); } return(p.Value == code); }); if (pair.Key != null && pair.Value != null) { name = pair.Key; } else { Emitter.NamedFunctions.Add(name, code); } Emitter.Output.Remove(savedPos, Emitter.Output.Length - savedPos); Emitter.Output.Insert(savedPos, JS.Vars.D_ + "." + H5Types.ToJsName(Emitter.TypeInfo.Type, Emitter, true) + "." + name); } Emitter.ResetLevel(oldLevel); } Emitter.ForbidLifting = oldLifting; var methodDeclaration = Body.GetParent <MethodDeclaration>(); var thisCaptured = Emitter.ThisRefCounter > savedThisCount || IsAsync && methodDeclaration != null && !methodDeclaration.HasModifier(Modifiers.Static); if (thisCaptured) { Emitter.Output.Insert(savedPos, JS.Funcs.H5_BIND + (hasCapturedVariables ? "($me, " : "(this, ")); WriteCloseParentheses(); } if (hasCapturedVariables) { WriteSemiColon(true); EndBlock(); Write(")("); Write("this, "); Write(string.Join(", ", capturedVariables)); Write(")"); } PopLocals(); ClearLocalsMap(prevMap); ClearLocalsNamesMap(prevNamesMap); }