protected bool EmitMemberAlias(IMember member, IMember interfaceMember) { bool nonEmpty = false; if (member.IsShadowing || !member.IsOverride) { var baseMember = InheritanceHelper.GetBaseMember(member); if (baseMember != null && baseMember.ImplementedInterfaceMembers.Contains(interfaceMember)) { return(false); } } var excludeTypeParam = OverloadsCollection.ExcludeTypeParameterForDefinition(member); var excludeAliasTypeParam = member.IsExplicitInterfaceImplementation && !excludeTypeParam; var pair = false; var itypeDef = interfaceMember.DeclaringTypeDefinition; if (!member.IsExplicitInterfaceImplementation && MetadataUtils.IsJsGeneric(itypeDef, this.Emitter) && itypeDef.TypeParameters != null && itypeDef.TypeParameters.Any(typeParameter => typeParameter.Variance != VarianceModifier.Invariant)) { pair = true; } if (member is IProperty && ((IProperty)member).IsIndexer) { var property = (IProperty)member; if (property.CanGet) { nonEmpty = true; this.EnsureComma(); this.WriteScript(Helpers.GetPropertyRef(member, this.Emitter, false, false, false, excludeTypeParam)); this.WriteComma(); var alias = Helpers.GetPropertyRef(interfaceMember, this.Emitter, false, false, false, withoutTypeParams: excludeAliasTypeParam); if (pair) { this.WriteOpenBracket(); } if (alias.StartsWith("\"")) { this.Write(alias); } else { this.WriteScript(alias); } if (pair) { this.WriteComma(); this.WriteScript(Helpers.GetPropertyRef(interfaceMember, this.Emitter, withoutTypeParams: true)); this.WriteCloseBracket(); } this.Emitter.Comma = true; } if (property.CanSet) { nonEmpty = true; this.EnsureComma(); this.WriteScript(Helpers.GetPropertyRef(member, this.Emitter, true, false, false, excludeTypeParam)); this.WriteComma(); var alias = Helpers.GetPropertyRef(interfaceMember, this.Emitter, true, false, false, withoutTypeParams: excludeAliasTypeParam); if (pair) { this.WriteOpenBracket(); } if (alias.StartsWith("\"")) { this.Write(alias); } else { this.WriteScript(alias); } if (pair) { this.WriteComma(); this.WriteScript(Helpers.GetPropertyRef(interfaceMember, this.Emitter, true, withoutTypeParams: true)); this.WriteCloseBracket(); } this.Emitter.Comma = true; } } else if (member is IEvent) { var ev = (IEvent)member; if (ev.CanAdd) { nonEmpty = true; this.EnsureComma(); this.WriteScript(Helpers.GetEventRef(member, this.Emitter, false, false, false, excludeTypeParam)); this.WriteComma(); var alias = Helpers.GetEventRef(interfaceMember, this.Emitter, false, false, false, excludeAliasTypeParam); if (pair) { this.WriteOpenBracket(); } if (alias.StartsWith("\"")) { this.Write(alias); } else { this.WriteScript(alias); } if (pair) { this.WriteComma(); this.WriteScript(Helpers.GetEventRef(interfaceMember, this.Emitter, withoutTypeParams: true)); this.WriteCloseBracket(); } this.Emitter.Comma = true; } if (ev.CanRemove) { nonEmpty = true; this.EnsureComma(); this.WriteScript(Helpers.GetEventRef(member, this.Emitter, true, false, false, excludeTypeParam)); this.WriteComma(); var alias = Helpers.GetEventRef(interfaceMember, this.Emitter, true, false, false, excludeAliasTypeParam); if (pair) { this.WriteOpenBracket(); } if (alias.StartsWith("\"")) { this.Write(alias); } else { this.WriteScript(alias); } if (pair) { this.WriteComma(); this.WriteScript(Helpers.GetEventRef(interfaceMember, this.Emitter, true, withoutTypeParams: true)); this.WriteCloseBracket(); } this.Emitter.Comma = true; } } else { nonEmpty = true; this.EnsureComma(); this.WriteScript(OverloadsCollection.Create(Emitter, member).GetOverloadName(false, null, excludeTypeParam)); this.WriteComma(); var alias = OverloadsCollection.Create(Emitter, interfaceMember).GetOverloadName(withoutTypeParams: excludeAliasTypeParam); if (pair) { this.WriteOpenBracket(); } if (alias.StartsWith("\"")) { this.Write(alias); } else { this.WriteScript(alias); } if (pair) { this.WriteComma(); this.WriteScript(OverloadsCollection.Create(Emitter, interfaceMember).GetOverloadName(withoutTypeParams: true)); this.WriteCloseBracket(); } } this.Emitter.Comma = true; return(nonEmpty); }
protected virtual bool WriteObject(string objectName, List <TypeConfigItem> members, string format, string interfaceFormat) { bool hasProperties = this.HasProperties(objectName, members); int pos = 0; IWriterInfo writer = null; bool beginBlock = false; if (hasProperties && objectName != null && !this.IsObjectLiteral) { beginBlock = true; pos = this.Emitter.Output.Length; writer = this.SaveWriter(); this.EnsureComma(); this.Write(objectName); this.WriteColon(); this.BeginBlock(); } bool isProperty = JS.Fields.PROPERTIES == objectName; bool isField = JS.Fields.FIELDS == objectName; int count = 0; foreach (var member in members) { object constValue = null; bool isPrimitive = false; var primitiveExpr = member.Initializer as PrimitiveExpression; bool write = false; bool writeScript = false; if (primitiveExpr != null) { //isPrimitive = true; constValue = primitiveExpr.Value; ResolveResult rr = null; if (member.VarInitializer != null) { rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter); } else { rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter); } if (rr != null && rr.Type.Kind == TypeKind.Enum) { constValue = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue); writeScript = true; } } if (constValue is RawValue) { constValue = constValue.ToString(); write = true; writeScript = false; } var isNull = member.Initializer.IsNull || member.Initializer is NullReferenceExpression || member.Initializer.Parent == null; if (!isNull && !isPrimitive) { var constrr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter); if (constrr != null && constrr.IsCompileTimeConstant) { //isPrimitive = true; constValue = constrr.ConstantValue; var expectedType = this.Emitter.Resolver.Resolver.GetExpectedType(member.Initializer); if (!expectedType.Equals(constrr.Type) && expectedType.Kind != TypeKind.Dynamic) { try { constValue = Convert.ChangeType(constValue, ReflectionHelper.GetTypeCode(expectedType)); } catch (Exception) { this.Emitter.Log.Warn($"FieldBlock: Convert.ChangeType is failed. Value type: {constrr.Type.FullName}, Target type: {expectedType.FullName}"); } } if (constrr.Type.Kind == TypeKind.Enum) { constValue = Helpers.GetEnumValue(this.Emitter, constrr.Type, constrr.ConstantValue); } writeScript = true; } } var isNullable = false; if (isPrimitive && constValue is AstType) { var itype = this.Emitter.Resolver.ResolveNode((AstType)constValue, this.Emitter); if (NullableType.IsNullable(itype.Type)) { isNullable = true; } } string tpl = null; IMember templateMember = null; MemberResolveResult init_rr = null; if (isField && member.VarInitializer != null) { init_rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter) as MemberResolveResult; tpl = init_rr != null?this.Emitter.GetInline(init_rr.Member) : null; if (tpl != null) { templateMember = init_rr.Member; } } bool isAutoProperty = false; if (isProperty) { var member_rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter) as MemberResolveResult; var property = (IProperty)member_rr.Member; isAutoProperty = Helpers.IsAutoProperty(property); } bool written = false; if (!isNull && (!isPrimitive || constValue is AstType || tpl != null) && !(isProperty && !IsObjectLiteral && !isAutoProperty)) { string value = null; bool needContinue = false; string defValue = ""; if (!isPrimitive) { var oldWriter = this.SaveWriter(); this.NewWriter(); member.Initializer.AcceptVisitor(this.Emitter); value = this.Emitter.Output.ToString(); this.RestoreWriter(oldWriter); ResolveResult rr = null; AstType astType = null; if (member.VarInitializer != null) { rr = this.Emitter.Resolver.ResolveNode(member.VarInitializer, this.Emitter); } else { astType = member.Entity.ReturnType; rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter); } constValue = Inspector.GetDefaultFieldValue(rr.Type, astType); if (rr.Type.Kind == TypeKind.Enum) { constValue = Helpers.GetEnumValue(this.Emitter, rr.Type, constValue); } isNullable = NullableType.IsNullable(rr.Type); needContinue = constValue is IType; writeScript = true; /*if (needContinue && !(member.Initializer is ObjectCreateExpression)) * { * defValue = " || " + Inspector.GetStructDefaultValue((IType)constValue, this.Emitter); * }*/ } else if (constValue is AstType) { value = isNullable ? "null" : Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter); constValue = value; write = true; needContinue = !isProperty && !isNullable; } var name = member.GetName(this.Emitter); bool isValidIdentifier = Helpers.IsValidIdentifier(name); if (isProperty && isPrimitive) { constValue = "null"; if (this.IsObjectLiteral) { written = true; if (isValidIdentifier) { this.Write(string.Format("this.{0} = {1};", name, value)); } else { this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value)); } this.WriteNewLine(); } else { this.Injectors.Add(string.Format(name.StartsWith("\"") || !isValidIdentifier ? "this[{0}] = {1};" : "this.{0} = {1};", isValidIdentifier ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value)); } } else { if (this.IsObjectLiteral) { written = true; if (isValidIdentifier) { this.Write(string.Format("this.{0} = {1};", name, value + defValue)); } else { this.Write(string.Format("this[{0}] = {1};", AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue)); } this.WriteNewLine(); } else if (tpl != null) { if (!tpl.Contains("{0}")) { tpl = tpl + " = {0};"; } string v = null; if (!isNull && (!isPrimitive || constValue is AstType)) { v = value + defValue; } else { if (write) { v = constValue != null?constValue.ToString() : ""; } else if (writeScript) { v = AbstractEmitterBlock.ToJavaScript(constValue, this.Emitter); } else { var oldWriter = this.SaveWriter(); this.NewWriter(); member.Initializer.AcceptVisitor(this.Emitter); v = this.Emitter.Output.ToString(); this.RestoreWriter(oldWriter); } } tpl = Helpers.ConvertTokens(this.Emitter, tpl, templateMember); tpl = tpl.Replace("{this}", "this").Replace("{0}", v); if (!tpl.EndsWith(";")) { tpl += ";"; } this.Injectors.Add(tpl); } else { var rr = this.Emitter.Resolver.ResolveNode(member.Initializer, this.Emitter) as CSharpInvocationResolveResult; bool isDefaultInstance = rr != null && rr.Member.SymbolKind == SymbolKind.Constructor && rr.Arguments.Count == 0 && rr.InitializerStatements.Count == 0 && rr.Type.Kind == TypeKind.Struct; if (!isDefaultInstance) { if (isField && !isValidIdentifier) { this.Injectors.Add(string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value + defValue)); } else { this.Injectors.Add(string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value + defValue)); } } } } } count++; if (written) { continue; } bool withoutTypeParams = true; MemberResolveResult m_rr = null; if (member.Entity != null) { m_rr = this.Emitter.Resolver.ResolveNode(member.Entity, this.Emitter) as MemberResolveResult; if (m_rr != null) { withoutTypeParams = OverloadsCollection.ExcludeTypeParameterForDefinition(m_rr); } } var mname = member.GetName(this.Emitter, withoutTypeParams); if (this.TypeInfo.IsEnum && m_rr != null) { mname = this.Emitter.GetEntityName(m_rr.Member); } bool isValid = Helpers.IsValidIdentifier(mname); if (!isValid) { if (this.IsObjectLiteral) { mname = "[" + AbstractEmitterBlock.ToJavaScript(mname, this.Emitter) + "]"; } else { mname = AbstractEmitterBlock.ToJavaScript(mname, this.Emitter); } } if (this.IsObjectLiteral) { this.WriteThis(); if (isValid) { this.WriteDot(); } this.Write(mname); this.Write(" = "); } else { this.EnsureComma(); XmlToJsDoc.EmitComment(this, member.Entity, null, member.Entity is FieldDeclaration ? member.VarInitializer : null); this.Write(mname); this.WriteColon(); } bool close = false; if (isProperty && !IsObjectLiteral && !isAutoProperty) { var oldTempVars = this.Emitter.TempVariables; this.BeginBlock(); new VisitorPropertyBlock(this.Emitter, (PropertyDeclaration)member.Entity).Emit(); this.WriteNewLine(); this.EndBlock(); this.Emitter.Comma = true; this.Emitter.TempVariables = oldTempVars; continue; } if (constValue is AstType || constValue is IType) { this.Write("null"); if (!isNullable) { var name = member.GetName(this.Emitter); bool isValidIdentifier = Helpers.IsValidIdentifier(name); var value = constValue is AstType?Inspector.GetStructDefaultValue((AstType)constValue, this.Emitter) : Inspector.GetStructDefaultValue((IType)constValue, this.Emitter); if (!isValidIdentifier) { this.Injectors.Insert(BeginCounter++, string.Format("this[{0}] = {1};", name.StartsWith("\"") ? name : AbstractEmitterBlock.ToJavaScript(name, this.Emitter), value)); } else { this.Injectors.Insert(BeginCounter++, string.Format(name.StartsWith("\"") ? interfaceFormat : format, name, value)); } } } else if (write) { this.Write(constValue); } else if (writeScript) { this.WriteScript(constValue); } else { member.Initializer.AcceptVisitor(this.Emitter); } if (close) { this.Write(" }"); } if (this.IsObjectLiteral) { this.WriteSemiColon(true); } this.Emitter.Comma = true; } if (count > 0 && objectName != null && !IsObjectLiteral) { this.WriteNewLine(); this.EndBlock(); } else if (beginBlock) { this.Emitter.IsNewLine = writer.IsNewLine; this.Emitter.ResetLevel(writer.Level); this.Emitter.Comma = writer.Comma; this.Emitter.Output.Length = pos; } return(count > 0); }
protected virtual void EmitPropertyMethod(CustomEventDeclaration customEventDeclaration, Accessor accessor, bool remover) { if (!accessor.IsNull && Emitter.GetInline(accessor) == null) { EnsureComma(); ResetLocals(); var prevMap = BuildLocalsMap(); var prevNamesMap = BuildLocalsNamesMap(); AddLocals(new ParameterDeclaration[] { new ParameterDeclaration { Name = "value" } }, accessor.Body); XmlToJsDoc.EmitComment(this, CustomEventDeclaration); var member_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(customEventDeclaration); Write(Helpers.GetEventRef(customEventDeclaration, Emitter, remover, false, false, OverloadsCollection.ExcludeTypeParameterForDefinition(member_rr))); WriteColon(); WriteFunction(); var m_rr = (MemberResolveResult)Emitter.Resolver.ResolveNode(customEventDeclaration); var nm = Helpers.GetFunctionName(Emitter.AssemblyInfo.NamedFunctions, m_rr.Member, Emitter, remover); if (nm != null) { Write(nm); } WriteOpenParentheses(); Write("value"); WriteCloseParentheses(); WriteSpace(); var script = Emitter.GetScript(accessor); if (script == null) { accessor.Body.AcceptVisitor(Emitter); } else { BeginBlock(); WriteLines(script); EndBlock(); } ClearLocalsMap(prevMap); ClearLocalsNamesMap(prevNamesMap); 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") { 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 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(); 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; } }