protected override void DoEmit() { XmlToJsDoc.EmitComment(this, Emitter.Translator.EmitNode); string globalTarget = H5Types.GetGlobalTarget(TypeInfo.Type.GetDefinition(), TypeInfo.TypeDeclaration); if (globalTarget != null) { CheckGlobalClass(); Emitter.NamedFunctions = new Dictionary <string, string>(); WriteTopInitMethods(); Write(JS.Types.H5.APPLY); WriteOpenParentheses(); Write(globalTarget); Write(", "); BeginBlock(); new MethodBlock(Emitter, TypeInfo, true).Emit(); EmitMetadata(); WriteNewLine(); EndBlock(); WriteCloseParentheses(); WriteSemiColon(); EmitAnonymousTypes(); EmitNamedFunctions(); WriteAfterInitMethods(); WriteNewLine(); } else { EmitClassHeader(); Emitter.NamedFunctions = new Dictionary <string, string>(); if (TypeInfo.TypeDeclaration.ClassType != ClassType.Interface) { MethodDeclaration entryPoint = null; if (TypeInfo.StaticMethods.Any(group => { return(group.Value.Any(method => { var result = Helpers.IsEntryPointMethod(Emitter, method); if (result) { entryPoint = method; } return result; })); })) { if (!entryPoint.Body.IsNull) { Emitter.VisitMethodDeclaration(entryPoint); } } EmitStaticBlock(); EmitInstantiableBlock(); } EmitClassEnd(); } }
public IMethod GetCastMethod(IType fromType, IType toType, out string template) { string inline = null; var method = fromType.GetMethods().FirstOrDefault(m => { if (m.IsOperator && (m.Name == "op_Explicit" || m.Name == "op_Implicit") && m.Parameters.Count == 1 && m.ReturnType.ReflectionName == toType.ReflectionName && m.Parameters[0].Type.ReflectionName == fromType.ReflectionName ) { string tmpInline = Emitter.GetInline(m); if (!string.IsNullOrWhiteSpace(tmpInline)) { inline = tmpInline; return(true); } } return(false); }); if (method == null) { method = toType.GetMethods().FirstOrDefault(m => { if (m.IsOperator && (m.Name == "op_Explicit" || m.Name == "op_Implicit") && m.Parameters.Count == 1 && m.ReturnType.ReflectionName == toType.ReflectionName && (m.Parameters[0].Type.ReflectionName == fromType.ReflectionName) ) { string tmpInline = Emitter.GetInline(m); if (!string.IsNullOrWhiteSpace(tmpInline)) { inline = tmpInline; return(true); } } return(false); }); } if (method == null && CastExpression != null) { var conversion = Emitter.Resolver.Resolver.GetConversion(CastExpression); if (conversion.IsUserDefined) { method = conversion.Method; string tmpInline = Emitter.GetInline(method); if (!string.IsNullOrWhiteSpace(tmpInline)) { inline = tmpInline; } } } template = inline; return(method); }
protected virtual void EmitClassHeader() { WriteTopInitMethods(); var typeDef = Emitter.GetTypeDefinition(); string name = Emitter.Validator.GetCustomTypeName(typeDef, Emitter, false); IsGeneric = typeDef.GenericParameters.Count > 0 && !Helpers.IsIgnoreGeneric(TypeInfo.Type, Emitter); if (name.IsEmpty()) { name = H5Types.ToJsName(TypeInfo.Type, Emitter, asDefinition: true, nomodule: true, ignoreLiteralName: false); } if (typeDef.IsInterface && typeDef.HasGenericParameters) { Write(JS.Types.H5.DEFINE_I); } else { Write(JS.Types.H5.DEFINE); } WriteOpenParentheses(); WriteScript(name); StartPosition = Emitter.Output.Length; Write(", "); if (IsGeneric) { if (TypeInfo.Module != null) { Write(TypeInfo.Module.Name); Write(", "); } WriteFunction(); WriteOpenParentheses(); foreach (var p in typeDef.GenericParameters) { if (typeDef.GenericParameters.Count(gp => gp.FullName == p.FullName) > 1) { throw new EmitterException(TypeInfo.TypeDeclaration, $"Type parameter '{p.FullName}' has the same name as the type parameter from outer type."); } EnsureComma(false); Write(p.Name); Emitter.Comma = true; } Emitter.Comma = false; WriteCloseParentheses(); Write(" { return "); } BeginBlock(); string extend = Emitter.GetTypeHierarchy(); if (extend.IsNotEmpty() && !TypeInfo.IsEnum) { var h5Type = Emitter.H5Types.Get(Emitter.TypeInfo); if (TypeInfo.InstanceMethods.Any(m => m.Value.Any(subm => Emitter.GetEntityName(subm) == JS.Fields.INHERITS)) || TypeInfo.InstanceConfig.Fields.Any(m => m.GetName(Emitter) == JS.Fields.INHERITS)) { Write(JS.Vars.D); } Write(JS.Fields.INHERITS); WriteColon(); if (Helpers.IsTypeArgInSubclass(h5Type.TypeDefinition, h5Type.TypeDefinition, Emitter, false)) { WriteFunction(); WriteOpenCloseParentheses(true); WriteOpenBrace(true); WriteReturn(true); Write(extend); WriteSemiColon(); WriteCloseBrace(true); } else { Write(extend); } Emitter.Comma = true; } WriteKind(); EmitMetadata(); WriteObjectLiteral(); if (TypeInfo.Module != null) { WriteScope(); WriteModule(); } WriteVariance(); }
protected virtual void EmitMethods(Dictionary <string, List <MethodDeclaration> > methods, Dictionary <string, List <EntityDeclaration> > properties, Dictionary <OperatorType, List <OperatorDeclaration> > operators) { int pos = Emitter.Output.Length; var writerInfo = SaveWriter(); string globalTarget = H5Types.GetGlobalTarget(TypeInfo.Type.GetDefinition(), TypeInfo.TypeDeclaration); if (globalTarget == null) { EnsureComma(); Write(JS.Fields.METHODS); WriteColon(); BeginBlock(); } int checkPos = Emitter.Output.Length; var names = new List <string>(properties.Keys); foreach (var name in names) { var props = properties[name]; foreach (var prop in props) { if (prop is PropertyDeclaration) { Emitter.VisitPropertyDeclaration((PropertyDeclaration)prop); } else if (prop is CustomEventDeclaration) { Emitter.VisitCustomEventDeclaration((CustomEventDeclaration)prop); } else if (prop is IndexerDeclaration) { Emitter.VisitIndexerDeclaration((IndexerDeclaration)prop); } } } names = new List <string>(methods.Keys); foreach (var name in names) { EmitMethodsGroup(methods[name]); } if (operators != null) { var ops = new List <OperatorType>(operators.Keys); foreach (var op in ops) { EmitOperatorGroup(operators[op]); } } if (TypeInfo.ClassType == ClassType.Struct) { if (!StaticBlock) { EmitStructMethods(); } else { string structName = H5Types.ToJsName(TypeInfo.Type, Emitter); if (TypeInfo.Type.TypeArguments.Count > 0 && !Helpers.IsIgnoreGeneric(TypeInfo.Type, Emitter)) { structName = "(" + structName + ")"; } EnsureComma(); Write(JS.Funcs.GETDEFAULTVALUE + ": function () { return new " + structName + "(); }"); Emitter.Comma = true; } } else if (StaticBlock) { var ctor = TypeInfo.Type.GetConstructors().FirstOrDefault(c => c.Parameters.Count == 0 && Emitter.GetInline(c) != null); if (ctor != null) { var code = Emitter.GetInline(ctor); EnsureComma(); Write(JS.Funcs.GETDEFAULTVALUE + ": function () "); BeginBlock(); Write("return "); var argsInfo = new ArgumentsInfo(Emitter, ctor); new InlineArgumentsBlock(Emitter, argsInfo, code).Emit(); Write(";"); WriteNewLine(); EndBlock(); Emitter.Comma = true; } } if (globalTarget == null) { if (checkPos == Emitter.Output.Length) { Emitter.IsNewLine = writerInfo.IsNewLine; Emitter.ResetLevel(writerInfo.Level); Emitter.Comma = writerInfo.Comma; Emitter.Output.Length = pos; } else { WriteNewLine(); EndBlock(); } } }
protected virtual void EmitCastExpression(Expression expression, AstType type, string method) { var itype = Emitter.H5Types.ToType(type); bool isCastAttr; string castCode = GetCastCode(expression, type, method, out isCastAttr); var enumType = itype; if (NullableType.IsNullable(enumType)) { enumType = NullableType.GetUnderlyingType(enumType); } var castToEnum = enumType.Kind == TypeKind.Enum; if (castToEnum) { itype = enumType.GetDefinition().EnumUnderlyingType; var enumMode = Helpers.EnumEmitMode(enumType); if (enumMode >= 3 && enumMode < 7) { itype = Emitter.Resolver.Compilation.FindType(KnownTypeCode.String); } } if (expression is NullReferenceExpression || (method != CS.Ops.IS && Helpers.IsIgnoreCast(type, Emitter)) || IsExternalCast(itype)) { if (expression is ParenthesizedExpression) { expression = ((ParenthesizedExpression)expression).Expression; } expression.AcceptVisitor(Emitter); return; } var expressionrr = Emitter.Resolver.ResolveNode(expression); var typerr = Emitter.Resolver.ResolveNode(type); if (expressionrr.Type.Kind == TypeKind.Enum) { var enumMode = Helpers.EnumEmitMode(expressionrr.Type); if (enumMode >= 3 && enumMode < 7 && Helpers.IsIntegerType(itype, Emitter.Resolver)) { throw new EmitterException(CastExpression, "Enum underlying type is string and cannot be casted to number"); } } if (method == CS.Ops.CAST && expressionrr.Type.Kind != TypeKind.Enum) { var cast_rr = Emitter.Resolver.ResolveNode(CastExpression); if (cast_rr is ConstantResolveResult) { var expectedType = Emitter.Resolver.Resolver.GetExpectedType(CastExpression); var value = ((ConstantResolveResult)cast_rr).ConstantValue; WriteCastValue(value, expectedType); return; } else { if (cast_rr is ConversionResolveResult conv_rr && conv_rr.Input is ConstantResolveResult && !conv_rr.Conversion.IsUserDefined) { var expectedType = Emitter.Resolver.Resolver.GetExpectedType(CastExpression); var value = ((ConstantResolveResult)conv_rr.Input).ConstantValue; WriteCastValue(value, expectedType); return; } } } if (method == CS.Ops.IS && castToEnum) { Write(JS.Types.H5.IS); WriteOpenParentheses(); expression.AcceptVisitor(Emitter); Write(", "); Write(H5Types.ToJsName(itype, Emitter)); Write(")"); return; } if (expressionrr.Type.Equals(itype)) { if (method == CS.Ops.IS) { Write(JS.Funcs.H5_HASVALUE); WriteOpenParentheses(); } expression.AcceptVisitor(Emitter); if (method == CS.Ops.IS) { Write(")"); } return; } bool isResultNullable = NullableType.IsNullable(typerr.Type); if (castCode != null) { EmitInlineCast(expressionrr, expression, type, castCode, isCastAttr, method); return; } bool isCast = method == CS.Ops.CAST; if (isCast) { if (IsUserDefinedConversion(this, CastExpression.Expression) || IsUserDefinedConversion(this, CastExpression)) { expression.AcceptVisitor(Emitter); return; } } var conversion = Emitter.Resolver.Resolver.GetConversion(expression); if (conversion.IsNumericConversion || conversion.IsEnumerationConversion || (isCast && conversion.IsIdentityConversion)) { expression.AcceptVisitor(Emitter); return; } bool hasValue = false; if (type is SimpleType simpleType && simpleType.Identifier == "dynamic") { if (method == CS.Ops.CAST || method == CS.Ops.AS) { expression.AcceptVisitor(Emitter); return; } else if (method == CS.Ops.IS) { hasValue = true; method = "hasValue"; } } bool unbox = Emitter.Rules.Boxing == BoxingRule.Managed && !(itype.IsReferenceType.HasValue ? itype.IsReferenceType.Value : true) && !NullableType.IsNullable(itype) && isCast && conversion.IsUnboxingConversion; if (unbox) { Write("System.Nullable.getValue("); } var typeDef = itype.Kind == TypeKind.TypeParameter ? null : Emitter.GetTypeDefinition(type, true); if (typeDef != null && method == CS.Ops.IS && itype.Kind != TypeKind.Interface && Emitter.Validator.IsObjectLiteral(typeDef) && Emitter.Validator.GetObjectCreateMode(typeDef) == 0) { throw new EmitterException(type, $"ObjectLiteral type ({itype.FullName}) with Plain mode cannot be used in 'is' operator. Please define cast logic in Cast attribute or use Constructor mode."); } Write(JS.NS.H5); WriteDot(); Write(method); WriteOpenParentheses(); expression.AcceptVisitor(Emitter); if (!hasValue) { WriteComma(); EmitCastType(itype); } if (isResultNullable && method != CS.Ops.IS) { WriteComma(); WriteScript(true); } WriteCloseParentheses(); if (unbox) { Write(")"); } }
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(); } else { var nm = Helpers.GetFunctionName(Emitter.AssemblyInfo.NamedFunctions, member_rr.Member, Emitter); if (nm != null) { Write(nm); 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 EmitStructMethods() { var typeDef = Emitter.GetTypeDefinition(); string structName = H5Types.ToJsName(TypeInfo.Type, Emitter); bool immutable = Emitter.Validator.IsImmutableType(typeDef); if (!immutable) { var mutableFields = TypeInfo.Type.GetFields(f => !f.IsConst, GetMemberOptions.IgnoreInheritedMembers); var autoProps = typeDef.Properties.Where(Helpers.IsAutoProperty); var autoEvents = TypeInfo.Type.GetEvents(null, GetMemberOptions.IgnoreInheritedMembers); immutable = !mutableFields.Any() && !autoProps.Any() && !autoEvents.Any(); } var fields = TypeInfo.InstanceConfig.Fields; var props = TypeInfo.InstanceConfig.Properties.Where(ent => { return(ent.Entity is PropertyDeclaration p && p.Getter != null && p.Getter.Body.IsNull && p.Setter != null && p.Setter.Body.IsNull); }); var list = fields.ToList(); list.AddRange(props); if (list.Count == 0) { EnsureComma(); Write(JS.Funcs.CLONE + ": function (to) { return this; }"); Emitter.Comma = true; return; } if (!TypeInfo.InstanceMethods.ContainsKey(CS.Methods.GETHASHCODE)) { EnsureComma(); Write(JS.Funcs.GETHASHCODE + ": function () "); BeginBlock(); Write("var h = " + JS.Funcs.H5_ADDHASH + "(["); var nameHashValue = new HashHelper().GetDeterministicHash(TypeInfo.Name); Write(nameHashValue); foreach (var field in list) { string fieldName = field.GetName(Emitter); Write(", this." + fieldName); } Write("]);"); WriteNewLine(); Write("return h;"); WriteNewLine(); EndBlock(); Emitter.Comma = true; } if (!TypeInfo.InstanceMethods.ContainsKey(CS.Methods.EQUALS)) { EnsureComma(); Write(JS.Funcs.EQUALS + ": function (o) "); BeginBlock(); Write("if (!" + JS.Types.H5.IS + "(o, "); Write(structName); Write(")) "); BeginBlock(); Write("return false;"); WriteNewLine(); EndBlock(); WriteNewLine(); Write("return "); bool and = false; foreach (var field in list) { string fieldName = field.GetName(Emitter); if (and) { Write(" && "); } and = true; Write(JS.Funcs.H5_EQUALS + "(this."); Write(fieldName); Write(", o."); Write(fieldName); Write(")"); } Write(";"); WriteNewLine(); EndBlock(); Emitter.Comma = true; } EnsureComma(); if (immutable) { Write(JS.Funcs.CLONE + ": function (to) { return this; }"); } else { Write(JS.Funcs.CLONE + ": function (to) "); BeginBlock(); Write("var s = to || new "); if (TypeInfo.Type.TypeArguments.Count > 0 && !Helpers.IsIgnoreGeneric(TypeInfo.Type, Emitter)) { structName = "(" + structName + ")"; } Write(structName); Write("();"); foreach (var field in list) { WriteNewLine(); string fieldName = field.GetName(Emitter); Write("s."); Write(fieldName); Write(" = "); int insertPosition = Emitter.Output.Length; Write("this."); Write(fieldName); var rr = Emitter.Resolver.ResolveNode(field.Entity) as MemberResolveResult; if (rr == null && field.VarInitializer != null) { rr = Emitter.Resolver.ResolveNode(field.VarInitializer) as MemberResolveResult; } if (rr != null) { Helpers.CheckValueTypeClone(rr, null, this, insertPosition); } Write(";"); } WriteNewLine(); Write("return s;"); WriteNewLine(); EndBlock(); } Emitter.Comma = true; }
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; }
public virtual void EmitPropertyMethod(PropertyDeclaration propertyDeclaration, Accessor accessor, IMethod method, bool setter, bool isObjectLiteral) { if ((!accessor.IsNull || method != null && Helpers.IsScript(method)) && Emitter.GetInline(accessor) == null) { EnsureComma(); ResetLocals(); var prevMap = BuildLocalsMap(); var prevNamesMap = BuildLocalsNamesMap(); if (setter) { AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body); } else { AddLocals(new ParameterDeclaration[0], accessor.Body); } //XmlToJsDoc.EmitComment(this, this.PropertyDeclaration); Write(setter ? JS.Funcs.Property.SET : JS.Funcs.Property.GET); WriteColon(); WriteFunction(); var m_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(propertyDeclaration); WriteOpenParentheses(); Write(setter ? "value" : ""); WriteCloseParentheses(); WriteSpace(); var script = Emitter.GetScript(accessor); if (script == null) { if (YieldBlock.HasYield(accessor.Body)) { new GeneratorBlock(Emitter, accessor).Emit(); } else { accessor.Body.AcceptVisitor(Emitter); } } else { BeginBlock(); WriteLines(script); EndBlock(); } ClearLocalsMap(prevMap); ClearLocalsNamesMap(prevNamesMap); Emitter.Comma = true; } }
public void Translate(CancellationToken cancellationToken) { using (new Measure(Logger, "Translating assembly")) { var config = AssemblyInfo; Dictionary <string, string> discoveredAssemblyPaths = null; if (Rebuild) { Logger.ZLogInformation("Rebuilding assembly on path {0}", AssemblyLocation); discoveredAssemblyPaths = BuildAssembly(cancellationToken); } else if (!File.Exists(AssemblyLocation)) { Logger.ZLogInformation("Building assembly on path {0}", AssemblyLocation); discoveredAssemblyPaths = BuildAssembly(cancellationToken); } var references = InspectReferences(discoveredAssemblyPaths); References = references; LogProductInfo(); if (!string.IsNullOrWhiteSpace(config.BeforeBuild)) { try { using (new Measure(Logger, $"Running BeforeBuild event {config.BeforeBuild}")) { RunEvent(config.BeforeBuild); } } catch (Exception exc) { Logger.ZLogError(exc, "Error running BeforeBuild event {0}", config.BeforeBuild); throw new TranslatorException($"Error: Unable to run beforeBuild event command: {exc.Message}\nStack trace:\n{exc.StackTrace}"); } } BuildSyntaxTree(cancellationToken); var resolver = new MemberResolver(ParsedSourceFiles, Emitter.ToAssemblyReferences(references), AssemblyDefinition); resolver = Preconvert(resolver, config, cancellationToken); InspectTypes(resolver, config); resolver.CanFreeze = true; var emitter = CreateEmitter(resolver, cancellationToken); if (!AssemblyInfo.OverflowMode.HasValue) { AssemblyInfo.OverflowMode = OverflowMode; } emitter.Translator = this; emitter.AssemblyInfo = AssemblyInfo; emitter.References = references; emitter.SourceFiles = SourceFiles; emitter.InitialLevel = 1; if (AssemblyInfo.Module != null) { AssemblyInfo.Module.Emitter = emitter; } foreach (var td in TypeInfoDefinitions) { if (td.Value.Module != null) { td.Value.Module.Emitter = emitter; } } SortReferences(); AddMainOutputs(emitter.Emit()); EmitterOutputs = emitter.Outputs; } }
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; }
protected virtual void VisitVariableDeclarationStatement() { bool needVar = true; bool needComma = false; bool addSemicolon = !Emitter.IsAsync; var oldSemiColon = Emitter.EnableSemicolon; var asyncExpressionHandling = Emitter.AsyncExpressionHandling; foreach (var variable in VariableDeclarationStatement.Variables) { WriteSourceMapName(variable.Name); var varName = AddLocal(variable.Name, variable, VariableDeclarationStatement.Type); lastVarName = varName; if (variable.Initializer != null && !variable.Initializer.IsNull && variable.Initializer.ToString().Contains(JS.Vars.FIX_ARGUMENT_NAME)) { continue; } if (needVar) { WriteVar(); needVar = false; } bool isReferenceLocal = false; if (Emitter.LocalsMap != null && Emitter.Resolver.ResolveNode(variable) is LocalResolveResult lrr && Emitter.LocalsMap.ContainsKey(lrr.Variable)) { isReferenceLocal = Emitter.LocalsMap[lrr.Variable].EndsWith(".v"); } lastIsReferenceLocal = isReferenceLocal; var hasInitializer = !variable.Initializer.IsNull; if (variable.Initializer.IsNull && !VariableDeclarationStatement.Type.IsVar()) { var typeDef = Emitter.GetTypeDefinition(VariableDeclarationStatement.Type, true); if (typeDef != null && typeDef.IsValueType && !Emitter.Validator.IsExternalType(typeDef)) { hasInitializer = true; } } if ((!Emitter.IsAsync || hasInitializer || isReferenceLocal) && needComma) { if (Emitter.IsAsync) { WriteSemiColon(true); } else { WriteComma(); } } needComma = true; WriteAwaiters(variable.Initializer); if (!Emitter.IsAsync || hasInitializer || isReferenceLocal) { Write(varName); } if (hasInitializer) { addSemicolon = true; Write(" = "); if (isReferenceLocal) { Write("{ v : "); } var oldValue = Emitter.ReplaceAwaiterByVar; Emitter.ReplaceAwaiterByVar = true; if (!variable.Initializer.IsNull) { variable.Initializer.AcceptVisitor(Emitter); } else { var typerr = Emitter.Resolver.ResolveNode(VariableDeclarationStatement.Type).Type; var isGeneric = typerr.TypeArguments.Count > 0 && !Helpers.IsIgnoreGeneric(typerr, Emitter); Write(string.Concat("new ", isGeneric ? "(" : "", H5Types.ToJsName(VariableDeclarationStatement.Type, Emitter), isGeneric ? ")" : "", "()")); } Emitter.ReplaceAwaiterByVar = oldValue; if (isReferenceLocal) { Write(" }"); } } else if (isReferenceLocal) { addSemicolon = true; Write(" = { }"); } } Emitter.AsyncExpressionHandling = asyncExpressionHandling; if (Emitter.EnableSemicolon && !needVar && addSemicolon) { WriteSemiColon(true); } if (oldSemiColon) { Emitter.EnableSemicolon = true; } }
private void BuildDynamicArgumentsList(DynamicInvocationResolveResult drr, IList <Expression> arguments) { Expression paramsArg = null; string paramArgName = null; IMethod method = null; if (drr.Target is MethodGroupResolveResult group && group.Methods.Count() > 1) { method = group.Methods.FirstOrDefault(m => { if (drr.Arguments.Count != m.Parameters.Count) { return(false); } for (int i = 0; i < m.Parameters.Count; i++) { var argType = drr.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(Expression, Constants.Messages.Exceptions.DYNAMIC_INVOCATION_TOO_MANY_OVERLOADS); } } if (method != null) { var member = method; var parameters = method.Parameters; Expression[] result = new Expression[parameters.Count]; string[] names = new string[result.Length]; bool named = false; int i = 0; bool isInterfaceMember = false; if (member != null) { var inlineStr = Emitter.GetInline(member); named = !string.IsNullOrEmpty(inlineStr); isInterfaceMember = member.DeclaringTypeDefinition != null && member.DeclaringTypeDefinition.Kind == TypeKind.Interface; } foreach (var arg in arguments) { if (arg is NamedArgumentExpression namedArg) { var namedParam = parameters.First(p => p.Name == namedArg.Name); var index = parameters.IndexOf(namedParam); result[index] = namedArg.Expression; names[index] = namedArg.Name; named = true; if (paramsArg == null && (parameters.Count > i) && parameters[i].IsParams) { if (member.DeclaringTypeDefinition == null || !Emitter.Validator.IsExternalType(member.DeclaringTypeDefinition)) { paramsArg = namedArg.Expression; } paramArgName = namedArg.Name; } } else { if (paramsArg == null && (parameters.Count > i) && parameters[i].IsParams) { if (member.DeclaringTypeDefinition == null || !Emitter.Validator.IsExternalType(member.DeclaringTypeDefinition)) { paramsArg = arg; } paramArgName = parameters[i].Name; } if (i >= result.Length) { var list = result.ToList(); list.AddRange(new Expression[arguments.Count - i]); var strList = names.ToList(); strList.AddRange(new string[arguments.Count - i]); result = list.ToArray(); names = strList.ToArray(); } result[i] = arg; names[i] = i < parameters.Count ? parameters[i].Name : paramArgName; } i++; } for (i = 0; i < result.Length; i++) { if (result[i] == null) { var p = parameters[i]; object t = null; if (p.Type.Kind == TypeKind.Enum) { t = Helpers.GetEnumValue(Emitter, p.Type, p.ConstantValue); } else { t = p.ConstantValue; } if ((named || isInterfaceMember) && !p.IsParams) { if (t == null) { result[i] = new PrimitiveExpression(new RawValue("void 0")); } else { result[i] = new PrimitiveExpression(t); } } names[i] = parameters[i].Name; } } ArgumentsExpressions = result; ArgumentsNames = names; ParamsExpression = paramsArg; NamedExpressions = CreateNamedExpressions(names, result); } else { ArgumentsExpressions = arguments.ToArray(); } }
protected void VisitObjectCreateExpression() { ObjectCreateExpression objectCreateExpression = ObjectCreateExpression; var resolveResult = Emitter.Resolver.ResolveNode(objectCreateExpression.Type) as TypeResolveResult; if (resolveResult != null && resolveResult.Type.Kind == TypeKind.Enum) { Write("(0)"); return; } bool isTypeParam = resolveResult != null && resolveResult.Type.Kind == TypeKind.TypeParameter; var invocationResolveResult = Emitter.Resolver.ResolveNode(objectCreateExpression) as InvocationResolveResult; var hasInitializer = !objectCreateExpression.Initializer.IsNull && objectCreateExpression.Initializer.Elements.Count > 0; if (isTypeParam && invocationResolveResult != null && invocationResolveResult.Member.Parameters.Count == 0 && !hasInitializer) { Write(JS.Funcs.H5_CREATEINSTANCE); WriteOpenParentheses(); Write(resolveResult.Type.Name); WriteCloseParentheses(); return; } var type = isTypeParam ? null : Emitter.GetTypeDefinition(objectCreateExpression.Type); var isObjectLiteral = type != null && Emitter.Validator.IsObjectLiteral(type); if (type != null && type.BaseType != null && type.BaseType.FullName == "System.MulticastDelegate") { bool wrap = false; if (objectCreateExpression.Parent is InvocationExpression parent && parent.Target == objectCreateExpression) { wrap = true; } if (wrap) { WriteOpenParentheses(); } Write("H5.fn.$build(["); objectCreateExpression.Arguments.First().AcceptVisitor(Emitter); Write("])"); if (wrap) { WriteCloseParentheses(); } return; } var argsInfo = new ArgumentsInfo(Emitter, objectCreateExpression); var argsExpressions = argsInfo.ArgumentsExpressions; var paramsArg = argsInfo.ParamsExpression; string inlineCode = null; if (invocationResolveResult != null) { if (invocationResolveResult.Member.DeclaringType.Kind == TypeKind.Struct && objectCreateExpression.Arguments.Count == 0) { var ctors = invocationResolveResult.Member.DeclaringType.GetConstructors(c => c.Parameters.Count == 1); var defCtor = ctors.FirstOrDefault(c => c.Parameters.First().Type.FullName == "System.Runtime.CompilerServices.DummyTypeUsedToAddAttributeToDefaultValueTypeConstructor"); if (defCtor != null) { inlineCode = Emitter.GetInline(defCtor); } } if (inlineCode == null) { inlineCode = Emitter.GetInline(invocationResolveResult.Member); } } var customCtor = isTypeParam ? "" : (Emitter.Validator.GetCustomConstructor(type) ?? ""); AstNodeCollection <Expression> elements = null; if (hasInitializer) { elements = objectCreateExpression.Initializer.Elements; } var isPlainObjectCtor = Regex.Match(customCtor, @"\s*\{\s*\}\s*").Success; var isPlainMode = type != null && Emitter.Validator.GetObjectCreateMode(type) == 0; if (inlineCode == null && isPlainObjectCtor && isPlainMode) { WriteOpenBrace(); WriteSpace(); var pos = Emitter.Output.Length; WriteObjectInitializer(objectCreateExpression.Initializer.Elements, type, invocationResolveResult, false); if (pos < Emitter.Output.Length) { WriteSpace(); } WriteCloseBrace(); } else { string tempVar = null; if (hasInitializer) { tempVar = GetTempVarName(); WriteOpenParentheses(); Write(tempVar); Write(" = "); } if (inlineCode != null) { new InlineArgumentsBlock(Emitter, argsInfo, inlineCode).Emit(); } else { var ctorMember = ((InvocationResolveResult)Emitter.Resolver.ResolveNode(objectCreateExpression)).Member; var expandParams = ctorMember.Attributes.Any(a => a.AttributeType.FullName == "H5.ExpandParamsAttribute"); bool applyCtor = false; if (expandParams) { var ctor_rr = Emitter.Resolver.ResolveNode(paramsArg); if (ctor_rr.Type.Kind == TypeKind.Array && !(paramsArg is ArrayCreateExpression) && objectCreateExpression.Arguments.Last() == paramsArg) { Write(JS.Types.H5.Reflection.APPLYCONSTRUCTOR + "("); applyCtor = true; } } if (String.IsNullOrEmpty(customCtor) || (isObjectLiteral && isPlainObjectCtor)) { if (!applyCtor && !isObjectLiteral) { WriteNew(); } var typerr = Emitter.Resolver.ResolveNode(objectCreateExpression.Type).Type; var td = typerr.GetDefinition(); var isGeneric = typerr.TypeArguments.Count > 0 && !Helpers.IsIgnoreGeneric(typerr, Emitter) || td != null && Validator.IsVirtualTypeStatic(td); if (isGeneric && !applyCtor) { WriteOpenParentheses(); } objectCreateExpression.Type.AcceptVisitor(Emitter); if (isGeneric && !applyCtor) { WriteCloseParentheses(); } } else { Write(customCtor); } if (!isTypeParam && type.Methods.Count(m => m.IsConstructor && !m.IsStatic) > (type.IsValueType || isObjectLiteral ? 0 : 1)) { var member = ((InvocationResolveResult)Emitter.Resolver.ResolveNode(objectCreateExpression)).Member; if (!Emitter.Validator.IsExternalType(type) || member.Attributes.Any(a => a.AttributeType.FullName == "H5.NameAttribute")) { WriteDot(); var name = OverloadsCollection.Create(Emitter, member).GetOverloadName(); Write(name); } } if (applyCtor) { Write(", "); } else { WriteOpenParentheses(); } new ExpressionListBlock(Emitter, argsExpressions, paramsArg, objectCreateExpression, -1).Emit(); WriteCloseParentheses(); } if (hasInitializer) { if (isObjectLiteral && isPlainMode) { WriteObjectInitializer(objectCreateExpression.Initializer.Elements, type, invocationResolveResult, true); } else { foreach (Expression item in elements) { WriteInitializerExpression(item, tempVar); } } WriteComma(); Write(tempVar); WriteCloseParentheses(); RemoveTempVar(tempVar); } } //Helpers.CheckValueTypeClone(invocationResolveResult, this.ObjectCreateExpression, this, pos); }
private void BuildArgumentsList(IList <Expression> arguments) { Expression paramsArg = null; string paramArgName = null; var resolveResult = ResolveResult; if (resolveResult != null) { var parameters = resolveResult.Member.Parameters; var isDelegate = resolveResult.Member.DeclaringType.Kind == TypeKind.Delegate; int shift = 0; if (resolveResult.Member is IMethod resolvedMethod && resolveResult is CSharpInvocationResolveResult invocationResult && resolvedMethod.IsExtensionMethod && invocationResult.IsExtensionMethodInvocation) { shift = 1; ThisName = resolvedMethod.Parameters[0].Name; IsExtensionMethod = true; } Expression[] result = new Expression[parameters.Count - shift]; string[] names = new string[result.Length]; bool named = false; int i = 0; bool isInterfaceMember = false; if (resolveResult.Member != null) { var inlineStr = Emitter.GetInline(resolveResult.Member); named = !string.IsNullOrEmpty(inlineStr); isInterfaceMember = resolveResult.Member.DeclaringTypeDefinition != null && resolveResult.Member.DeclaringTypeDefinition.Kind == TypeKind.Interface; } var expandParams = resolveResult.Member.Attributes.Any(a => a.AttributeType.FullName == "H5.ExpandParamsAttribute"); foreach (var arg in arguments) { if (arg is NamedArgumentExpression namedArg) { var namedParam = parameters.First(p => p.Name == namedArg.Name); var index = parameters.IndexOf(namedParam) - shift; result[index] = namedArg.Expression; names[index] = namedArg.Name; named = true; if (paramsArg == null && parameters.FirstOrDefault(p => p.Name == namedArg.Name).IsParams) { if (resolveResult.Member.DeclaringTypeDefinition == null || !Emitter.Validator.IsExternalType(resolveResult.Member.DeclaringTypeDefinition)) { paramsArg = namedArg.Expression; } paramArgName = namedArg.Name; } } else { if (paramsArg == null && (parameters.Count > (i + shift)) && parameters[i + shift].IsParams) { if (resolveResult.Member.DeclaringTypeDefinition == null || !Emitter.Validator.IsExternalType(resolveResult.Member.DeclaringTypeDefinition) || expandParams) { paramsArg = arg; } paramArgName = parameters[i + shift].Name; } if (i >= result.Length) { var list = result.ToList(); list.AddRange(new Expression[arguments.Count - i]); var strList = names.ToList(); strList.AddRange(new string[arguments.Count - i]); result = list.ToArray(); names = strList.ToArray(); } result[i] = arg; names[i] = (i + shift) < parameters.Count ? parameters[i + shift].Name : paramArgName; } i++; } for (i = 0; i < result.Length; i++) { if (result[i] == null) { var p = parameters[i + shift]; object t = null; if (p.Type.Kind == TypeKind.Enum) { t = Helpers.GetEnumValue(Emitter, p.Type, p.ConstantValue); } else { t = p.ConstantValue; } if ((named || isInterfaceMember || isDelegate) && !p.IsParams) { if (t == null) { result[i] = new PrimitiveExpression(new RawValue("void 0")); } else { result[i] = new PrimitiveExpression(t); } } names[i] = parameters[i + shift].Name; } } ArgumentsExpressions = result; ArgumentsNames = names; ParamsExpression = paramsArg; NamedExpressions = CreateNamedExpressions(names, result); } else { ArgumentsExpressions = arguments.ToArray(); } }
protected virtual void EmitIndexerMethod(IndexerDeclaration indexerDeclaration, IProperty prop, Accessor accessor, IMethod propAccessor, bool setter) { var isIgnore = propAccessor != null && Emitter.Validator.IsExternalType(propAccessor); if (!accessor.IsNull && Emitter.GetInline(accessor) == null && !isIgnore) { EnsureComma(); ResetLocals(); var prevMap = BuildLocalsMap(); var prevNamesMap = BuildLocalsNamesMap(); if (setter) { AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body); } else { AddLocals(new ParameterDeclaration[0], accessor.Body); } XmlToJsDoc.EmitComment(this, IndexerDeclaration, !setter); string accName = null; if (prop != null) { accName = Emitter.GetEntityNameFromAttr(prop, setter); if (string.IsNullOrEmpty(accName)) { var member_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(indexerDeclaration); var overloads = OverloadsCollection.Create(Emitter, indexerDeclaration, setter); accName = overloads.GetOverloadName(false, Helpers.GetSetOrGet(setter), OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr)); } } Write(accName); WriteColon(); WriteFunction(); var nm = Helpers.GetFunctionName(Emitter.AssemblyInfo.NamedFunctions, prop, Emitter, setter); if (nm != null) { Write(nm); } EmitMethodParameters(indexerDeclaration.Parameters, null, indexerDeclaration, setter); if (setter) { Write(", value)"); } WriteSpace(); var script = Emitter.GetScript(accessor); if (script == null) { if (YieldBlock.HasYield(accessor.Body)) { new GeneratorBlock(Emitter, accessor).Emit(); } else { accessor.Body.AcceptVisitor(Emitter); } } else { BeginBlock(); WriteLines(script); EndBlock(); } ClearLocalsMap(prevMap); ClearLocalsNamesMap(prevNamesMap); Emitter.Comma = true; } }