public virtual void EmitPropertyMethod(PropertyDeclaration propertyDeclaration, Accessor accessor, IMethod method, bool setter, bool isObjectLiteral) { if ((!accessor.IsNull || method != null && Helpers.IsScript(method)) && this.Emitter.GetInline(accessor) == null) { this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); if (setter) { this.AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body); } else { this.AddLocals(new ParameterDeclaration[0], accessor.Body); } //XmlToJsDoc.EmitComment(this, this.PropertyDeclaration); this.Write(setter ? JS.Funcs.Property.SET : JS.Funcs.Property.GET); this.WriteColon(); this.WriteFunction(); this.WriteOpenParentheses(); this.Write(setter ? "value" : ""); this.WriteCloseParentheses(); this.WriteSpace(); var script = this.Emitter.GetScript(accessor); if (script == null) { if (YieldBlock.HasYield(accessor.Body)) { new GeneratorBlock(this.Emitter, accessor).Emit(); } else { accessor.Body.AcceptVisitor(this.Emitter); } } else { this.BeginBlock(); this.WriteLines(script); this.EndBlock(); } this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); this.Emitter.Comma = true; } }
public void DoEmitBlock() { if (this.BlockStatement.Parent is MethodDeclaration) { this.IsMethodBlock = true; var methodDeclaration = (MethodDeclaration)this.BlockStatement.Parent; if (!methodDeclaration.ReturnType.IsNull) { var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration.ReturnType, this.Emitter); this.ReturnType = rr.Type; } this.ConvertParamsToReferences(methodDeclaration.Parameters); } else if (this.BlockStatement.Parent is AnonymousMethodExpression) { this.IsMethodBlock = true; var methodDeclaration = (AnonymousMethodExpression)this.BlockStatement.Parent; var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration, this.Emitter); this.ReturnType = rr.Type; this.ConvertParamsToReferences(methodDeclaration.Parameters); } else if (this.BlockStatement.Parent is LambdaExpression) { this.IsMethodBlock = true; var methodDeclaration = (LambdaExpression)this.BlockStatement.Parent; var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration, this.Emitter); this.ReturnType = rr.Type; this.ConvertParamsToReferences(methodDeclaration.Parameters); } else if (this.BlockStatement.Parent is ConstructorDeclaration) { this.IsMethodBlock = true; this.ConvertParamsToReferences(((ConstructorDeclaration)this.BlockStatement.Parent).Parameters); } else if (this.BlockStatement.Parent is OperatorDeclaration) { this.IsMethodBlock = true; this.ConvertParamsToReferences(((OperatorDeclaration)this.BlockStatement.Parent).Parameters); } else if (this.BlockStatement.Parent is Accessor) { this.IsMethodBlock = true; var role = this.BlockStatement.Parent.Role.ToString(); if (role == "Setter") { this.ConvertParamsToReferences(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }); } else if (role == "Getter") { var methodDeclaration = (Accessor)this.BlockStatement.Parent; if (!methodDeclaration.ReturnType.IsNull) { var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration.ReturnType, this.Emitter); this.ReturnType = rr.Type; } } } if (this.IsMethodBlock && YieldBlock.HasYield(this.BlockStatement)) { this.IsYield = true; } if (this.IsMethodBlock) { this.OldReturnType = this.Emitter.ReturnType; this.Emitter.ReturnType = this.ReturnType; } if (this.Emitter.BeforeBlock != null) { this.Emitter.BeforeBlock(); this.Emitter.BeforeBlock = null; } var ra = ReachabilityAnalysis.Create(this.BlockStatement, this.Emitter.Resolver.Resolver); this.BlockStatement.Children.ToList().ForEach(child => { var statement = child as Statement; if (statement != null && !ra.IsReachable(statement)) { return; } child.AcceptVisitor(this.Emitter); }); }
protected void VisitMethodDeclaration(MethodDeclaration methodDeclaration) { foreach (var attrSection in methodDeclaration.Attributes) { foreach (var attr in attrSection.Attributes) { var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter); if (rr.Type.FullName == "Bridge.ExternalAttribute") { return; } else if (rr.Type.FullName == "Bridge.InitAttribute") { InitPosition initPosition = InitPosition.After; if (attr.HasArgumentList) { if (attr.Arguments.Any()) { var argExpr = attr.Arguments.First(); var argrr = this.Emitter.Resolver.ResolveNode(argExpr, this.Emitter); if (argrr.ConstantValue is int) { initPosition = (InitPosition)argrr.ConstantValue; } } } if (initPosition > 0) { return; } } } } this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); this.AddLocals(methodDeclaration.Parameters, methodDeclaration.Body); var overloads = OverloadsCollection.Create(this.Emitter, methodDeclaration); XmlToJsDoc.EmitComment(this, this.MethodDeclaration); var isEntryPoint = Helpers.IsEntryPointMethod(this.Emitter, this.MethodDeclaration); var member_rr = (MemberResolveResult)this.Emitter.Resolver.ResolveNode(this.MethodDeclaration, this.Emitter); string name = overloads.GetOverloadName(false, null, excludeTypeOnly: OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr)); if (isEntryPoint) { this.Write(JS.Funcs.ENTRY_POINT_NAME); } else { this.Write(name); } this.WriteColon(); this.WriteFunction(); if (isEntryPoint) { this.Write(name); this.WriteSpace(); } else { var nm = Helpers.GetFunctionName(this.Emitter.AssemblyInfo.NamedFunctions, member_rr.Member, this.Emitter); if (nm != null) { this.Write(nm); this.WriteSpace(); } } this.EmitMethodParameters(methodDeclaration.Parameters, methodDeclaration.TypeParameters.Count > 0 && Helpers.IsIgnoreGeneric(methodDeclaration, this.Emitter) ? null : methodDeclaration.TypeParameters, methodDeclaration); this.WriteSpace(); var script = this.Emitter.GetScript(methodDeclaration); if (script == null) { if (YieldBlock.HasYield(methodDeclaration.Body)) { new GeneratorBlock(this.Emitter, methodDeclaration).Emit(); } else if (methodDeclaration.HasModifier(Modifiers.Async) || AsyncBlock.HasGoto(methodDeclaration.Body)) { new AsyncBlock(this.Emitter, methodDeclaration).Emit(); } else { methodDeclaration.Body.AcceptVisitor(this.Emitter); } } else { this.BeginBlock(); this.WriteLines(script); this.EndBlock(); } this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); this.Emitter.Comma = true; }
protected void VisitMethodDeclaration(MethodDeclaration methodDeclaration) { foreach (var attrSection in methodDeclaration.Attributes) { foreach (var attr in attrSection.Attributes) { var rr = this.Emitter.Resolver.ResolveNode(attr.Type, this.Emitter); if (rr.Type.FullName == "Bridge.ExternalAttribute") { return; } else if (rr.Type.FullName == "Bridge.InitAttribute") { int initPosition = 0; if (attr.HasArgumentList) { if (attr.Arguments.Any()) { var argExpr = attr.Arguments.First(); var argrr = this.Emitter.Resolver.ResolveNode(argExpr, this.Emitter); if (argrr.ConstantValue is int) { initPosition = (int)argrr.ConstantValue; } } } if (initPosition > 0) { return; } } } } this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); this.AddLocals(methodDeclaration.Parameters, methodDeclaration.Body); var overloads = OverloadsCollection.Create(this.Emitter, methodDeclaration); XmlToJsDoc.EmitComment(this, this.MethodDeclaration); string name = overloads.GetOverloadName(false, null, true); if (Helpers.IsEntryPointMethod(this.Emitter, methodDeclaration)) { name = JS.Fields.MAIN; } this.Write(name); this.WriteColon(); this.WriteFunction(); this.EmitMethodParameters(methodDeclaration.Parameters, methodDeclaration.TypeParameters.Count > 0 && Helpers.IsIgnoreGeneric(methodDeclaration, this.Emitter) ? null : methodDeclaration.TypeParameters, methodDeclaration); this.WriteSpace(); var script = this.Emitter.GetScript(methodDeclaration); if (script == null) { if (YieldBlock.HasYield(methodDeclaration.Body)) { new GeneratorBlock(this.Emitter, methodDeclaration).Emit(); } else if (methodDeclaration.HasModifier(Modifiers.Async)) { new AsyncBlock(this.Emitter, methodDeclaration).Emit(); } else { methodDeclaration.Body.AcceptVisitor(this.Emitter); } } else { this.BeginBlock(); this.WriteLines(script); this.EndBlock(); } this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); this.Emitter.Comma = true; }
public virtual void EmitPropertyMethod(PropertyDeclaration propertyDeclaration, Accessor accessor, bool setter, bool isObjectLiteral) { var memberResult = this.Emitter.Resolver.ResolveNode(propertyDeclaration, this.Emitter) as MemberResolveResult; if (memberResult != null && (AttributeHelper.HasFieldAttribute(memberResult.Member) || memberResult.Member.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExternalAttribute") || (propertyDeclaration.Getter.IsNull && propertyDeclaration.Setter.IsNull)) ) { return; } if (!accessor.IsNull && this.Emitter.GetInline(accessor) == null) { this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); if (setter) { this.AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body); } else { this.AddLocals(new ParameterDeclaration[0], accessor.Body); } XmlToJsDoc.EmitComment(this, this.PropertyDeclaration); if (isObjectLiteral) { this.Write(setter ? JS.Funcs.Property.SET : JS.Funcs.Property.GET); } else { string name = Helpers.GetPropertyRef(propertyDeclaration, this.Emitter, setter, false, false, true); this.Write(name); } this.WriteColon(); this.WriteFunction(); this.WriteOpenParentheses(); this.Write(setter ? "value" : ""); this.WriteCloseParentheses(); this.WriteSpace(); var script = this.Emitter.GetScript(accessor); if (script == null) { if (YieldBlock.HasYield(accessor.Body)) { new GeneratorBlock(this.Emitter, accessor).Emit(); } else { accessor.Body.AcceptVisitor(this.Emitter); } } else { this.BeginBlock(); this.WriteLines(script); this.EndBlock(); } this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); this.Emitter.Comma = true; } }
protected virtual void EmitLambda(IEnumerable <ParameterDeclaration> parameters, AstNode body, AstNode context) { var rr = this.Emitter.Resolver.ResolveNode(context, this.Emitter); var oldLifting = this.Emitter.ForbidLifting; this.Emitter.ForbidLifting = false; var noLiftingRule = this.Emitter.Rules.Lambda == LambdaRule.Plain; CaptureAnalyzer analyzer = null; if (!noLiftingRule) { analyzer = new CaptureAnalyzer(this.Emitter); analyzer.Analyze(this.Body, this.Parameters.Select(p => p.Name)); } var oldLevel = this.Emitter.Level; if (!noLiftingRule && analyzer.UsedVariables.Count == 0) { this.Emitter.ResetLevel(); Indent(); } IAsyncBlock asyncBlock = null; this.PushLocals(); if (this.IsAsync) { if (context is LambdaExpression) { asyncBlock = new AsyncBlock(this.Emitter, (LambdaExpression)context); } else { asyncBlock = new AsyncBlock(this.Emitter, (AnonymousMethodExpression)context); } asyncBlock.InitAsyncBlock(); } else if (YieldBlock.HasYield(body)) { this.IsAsync = true; if (context is LambdaExpression) { asyncBlock = new GeneratorBlock(this.Emitter, (LambdaExpression)context); } else { asyncBlock = new GeneratorBlock(this.Emitter, (AnonymousMethodExpression)context); } asyncBlock.InitAsyncBlock(); } var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); this.AddLocals(parameters, body); bool block = body is BlockStatement; this.Write(""); var savedThisCount = this.Emitter.ThisRefCounter; var capturedVariables = this.GetCapturedLoopVariablesNames(); var hasCapturedVariables = capturedVariables != null && capturedVariables.Length > 0; if (hasCapturedVariables) { this.Write("(function ($me, "); this.Write(string.Join(", ", capturedVariables) + ") "); this.BeginBlock(); this.Write("return "); } var savedPos = this.Emitter.Output.Length; this.WriteFunction(); this.EmitMethodParameters(parameters, null, context); this.WriteSpace(); int pos = 0; if (!block && !this.IsAsync) { this.BeginBlock(); pos = this.Emitter.Output.Length; } bool isSimpleLambda = body.Parent is LambdaExpression && !block && !this.IsAsync; if (isSimpleLambda) { this.ConvertParamsToReferences(parameters); var lrr = rr as LambdaResolveResult; if (lrr == null || lrr.ReturnType.Kind != TypeKind.Void) { this.WriteReturn(true); } } if (this.IsAsync) { asyncBlock.Emit(true); } else { body.AcceptVisitor(this.Emitter); } if (isSimpleLambda) { this.WriteSemiColon(); } if (!block && !this.IsAsync) { this.WriteNewLine(); this.EndBlock(); } if (!block && !this.IsAsync) { this.EmitTempVars(pos); } if (!noLiftingRule && analyzer.UsedVariables.Count == 0) { if (!this.Emitter.ForbidLifting) { var name = "f" + (this.Emitter.NamedFunctions.Count + 1); var code = this.Emitter.Output.ToString().Substring(savedPos); var codeForComare = this.RemoveTokens(code); var pair = this.Emitter.NamedFunctions.FirstOrDefault(p => { if (this.Emitter.AssemblyInfo.SourceMap.Enabled) { return(this.RemoveTokens(p.Value) == codeForComare); } return(p.Value == code); }); if (pair.Key != null && pair.Value != null) { name = pair.Key; } else { this.Emitter.NamedFunctions.Add(name, code); } this.Emitter.Output.Remove(savedPos, this.Emitter.Output.Length - savedPos); this.Emitter.Output.Insert(savedPos, JS.Vars.D_ + "." + BridgeTypes.ToJsName(this.Emitter.TypeInfo.Type, this.Emitter, true) + "." + name); } this.Emitter.ResetLevel(oldLevel); } this.Emitter.ForbidLifting = oldLifting; var methodDeclaration = this.Body.GetParent <MethodDeclaration>(); var thisCaptured = this.Emitter.ThisRefCounter > savedThisCount || this.IsAsync && methodDeclaration != null && !methodDeclaration.HasModifier(Modifiers.Static); if (thisCaptured) { this.Emitter.Output.Insert(savedPos, JS.Funcs.BRIDGE_BIND + (hasCapturedVariables ? "($me, " : "(this, ")); this.WriteCloseParentheses(); } if (hasCapturedVariables) { this.WriteSemiColon(true); this.EndBlock(); this.Write(")("); this.Write("this, "); this.Write(string.Join(", ", capturedVariables)); this.Write(")"); } this.PopLocals(); this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); }
protected virtual void EmitIndexerMethod(IndexerDeclaration indexerDeclaration, IProperty prop, Accessor accessor, IMethod propAccessor, bool setter) { var isIgnore = propAccessor != null && this.Emitter.Validator.IsExternalType(propAccessor); if (!accessor.IsNull && this.Emitter.GetInline(accessor) == null && !isIgnore) { this.EnsureComma(); this.ResetLocals(); var prevMap = this.BuildLocalsMap(); var prevNamesMap = this.BuildLocalsNamesMap(); if (setter) { this.AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body); } else { this.AddLocals(new ParameterDeclaration[0], accessor.Body); } XmlToJsDoc.EmitComment(this, this.IndexerDeclaration, !setter); string accName = null; if (prop != null) { accName = this.Emitter.GetEntityNameFromAttr(prop, setter); if (string.IsNullOrEmpty(accName)) { var member_rr = (MemberResolveResult)this.Emitter.Resolver.ResolveNode(indexerDeclaration, this.Emitter); var overloads = OverloadsCollection.Create(this.Emitter, indexerDeclaration, setter); accName = overloads.GetOverloadName(false, Helpers.GetSetOrGet(setter), OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr)); } } this.Write(accName); this.WriteColon(); this.WriteFunction(); var nm = Helpers.GetFunctionName(this.Emitter.AssemblyInfo.NamedFunctions, prop, this.Emitter, setter); if (nm != null) { this.Write(nm); } this.EmitMethodParameters(indexerDeclaration.Parameters, null, indexerDeclaration, setter); if (setter) { this.Write(", value)"); } this.WriteSpace(); var script = this.Emitter.GetScript(accessor); if (script == null) { if (YieldBlock.HasYield(accessor.Body)) { new GeneratorBlock(this.Emitter, accessor).Emit(); } else { accessor.Body.AcceptVisitor(this.Emitter); } } else { this.BeginBlock(); this.WriteLines(script); this.EndBlock(); } this.ClearLocalsMap(prevMap); this.ClearLocalsNamesMap(prevNamesMap); this.Emitter.Comma = true; } }
public void DoEmitBlock() { if (this.BlockStatement.Parent is MethodDeclaration) { this.IsMethodBlock = true; var methodDeclaration = (MethodDeclaration)this.BlockStatement.Parent; if (!methodDeclaration.ReturnType.IsNull) { var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration.ReturnType, this.Emitter); this.ReturnType = rr.Type; } this.ConvertParamsToReferences(methodDeclaration.Parameters); } else if (this.BlockStatement.Parent is AnonymousMethodExpression) { this.IsMethodBlock = true; var methodDeclaration = (AnonymousMethodExpression)this.BlockStatement.Parent; var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration, this.Emitter); this.ReturnType = rr.Type; this.ConvertParamsToReferences(methodDeclaration.Parameters); } else if (this.BlockStatement.Parent is LambdaExpression) { this.IsMethodBlock = true; var methodDeclaration = (LambdaExpression)this.BlockStatement.Parent; var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration, this.Emitter); this.ReturnType = rr.Type; this.ConvertParamsToReferences(methodDeclaration.Parameters); } else if (this.BlockStatement.Parent is ConstructorDeclaration) { this.IsMethodBlock = true; this.ConvertParamsToReferences(((ConstructorDeclaration)this.BlockStatement.Parent).Parameters); } else if (this.BlockStatement.Parent is OperatorDeclaration) { this.IsMethodBlock = true; this.ConvertParamsToReferences(((OperatorDeclaration)this.BlockStatement.Parent).Parameters); } else if (this.BlockStatement.Parent is Accessor) { this.IsMethodBlock = true; var role = this.BlockStatement.Parent.Role.ToString(); if (role == "Setter") { this.ConvertParamsToReferences(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }); } else if (role == "Getter") { var methodDeclaration = (Accessor)this.BlockStatement.Parent; if (!methodDeclaration.ReturnType.IsNull) { var rr = this.Emitter.Resolver.ResolveNode(methodDeclaration.ReturnType, this.Emitter); this.ReturnType = rr.Type; } } } if (this.IsMethodBlock && YieldBlock.HasYield(this.BlockStatement)) { this.IsYield = true; YieldBlock.EmitYield(this, this.ReturnType); } this.BlockStatement.Children.ToList().ForEach(child => child.AcceptVisitor(this.Emitter)); }