public static JObject ConstructITypeMetadata(IType type, IEmitter emitter) { var properties = MetadataUtils.GetCommonTypeProperties(type, emitter); if (type.Kind == TypeKind.Class || type.Kind == TypeKind.Anonymous) { var members = type.GetMembers(null, GetMemberOptions.IgnoreInheritedMembers).Where(m => MetadataUtils.IsReflectable(m, emitter, false, null)) .OrderBy(m => m, MemberOrderer.Instance) .Select(m => MetadataUtils.ConstructMemberInfo(m, emitter, false, false, null)) .ToList(); if (members.Count > 0) { properties.Add("m", new JArray(members)); } } return(properties.Count > 0 ? properties : null); }
public static JObject ConstructMemberInfo(IMember m, IEmitter emitter, bool includeDeclaringType, bool isGenericSpecialization, SyntaxTree tree) { if (m is IMethod && ((IMethod)m).IsConstructor) { return(MetadataUtils.ConstructConstructorInfo((IMethod)m, emitter, includeDeclaringType, isGenericSpecialization, tree)); } var properties = MetadataUtils.GetCommonMemberInfoProperties(m, emitter, includeDeclaringType, isGenericSpecialization, tree); if (m.IsStatic) { properties.Add("is", true); } if (m is IMethod) { var method = (IMethod)m; var inline = emitter.GetInline(method); if (string.IsNullOrEmpty(inline) && method.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExpandParamsAttribute")) { properties.Add("exp", true); } properties.Add("t", (int)MemberTypes.Method); var parametersInfo = method.Parameters.Select(p => MetadataUtils.ConstructParameterInfo(p, emitter, false, false, tree)).ToList(); if (parametersInfo.Count > 0) { properties.Add("pi", new JArray(parametersInfo)); } if (!string.IsNullOrEmpty(inline)) { if (inline.StartsWith("<self>")) { inline = inline.Substring(6); } var block = new InlineArgumentsBlock(emitter, new ArgumentsInfo(emitter, method), inline, method); var oldWriter = block.SaveWriter(); block.NewWriter(); block.EmitFunctionReference(true); var str = emitter.Output.ToString(); block.RestoreWriter(oldWriter); properties.Add("tpc", method.TypeParameters.Count); properties.Add("def", new JRaw(str)); } else { if (MetadataUtils.IsJsGeneric(method, emitter)) { properties.Add("tpc", method.TypeParameters.Count); properties.Add("tprm", new JArray(method.TypeParameters.Select(tp => tp.Name).ToArray())); } string sname; if (method.IsAccessor) { if (method.AccessorOwner is IProperty) { sname = Helpers.GetPropertyRef(method.AccessorOwner, emitter, ((IProperty)method.AccessorOwner).Setter == method); } else if (method.AccessorOwner is IEvent) { sname = Helpers.GetEventRef(method.AccessorOwner, emitter, ((IEvent)method.AccessorOwner).RemoveAccessor == method); } else { sname = OverloadsCollection.Create(emitter, method).GetOverloadName(); } } else { sname = OverloadsCollection.Create(emitter, method).GetOverloadName(); } if (sname.Contains("\"")) { properties.Add("sn", new JRaw(sname)); } else { properties.Add("sn", sname); } } properties.Add("rt", new JRaw(MetadataUtils.GetTypeName(method.ReturnType, emitter, isGenericSpecialization))); var attr = MetadataUtils.GetScriptableAttributes(method.ReturnTypeAttributes, emitter, tree).ToList(); if (attr.Count > 0) { JArray attrArr = new JArray(); foreach (var a in attr) { attrArr.Add(MetadataUtils.ConstructAttribute(a, null, emitter)); } properties.Add("rta", attrArr); } if (method.Parameters.Count > 0) { properties.Add("p", new JArray(method.Parameters.Select(p => new JRaw(MetadataUtils.GetTypeName(p.Type, emitter, isGenericSpecialization))))); } } else if (m is IField) { var field = (IField)m; properties.Add("t", (int)MemberTypes.Field); properties.Add("rt", new JRaw(MetadataUtils.GetTypeName(field.ReturnType, emitter, isGenericSpecialization))); properties.Add("sn", OverloadsCollection.Create(emitter, field).GetOverloadName()); if (field.IsReadOnly) { properties.Add("ro", field.IsReadOnly); } } else if (m is IProperty) { var prop = (IProperty)m; properties.Add("t", (int)MemberTypes.Property); properties.Add("rt", new JRaw(MetadataUtils.GetTypeName(prop.ReturnType, emitter, isGenericSpecialization))); if (prop.Parameters.Count > 0) { properties.Add("p", new JArray(prop.Parameters.Select(p => new JRaw(MetadataUtils.GetTypeName(p.Type, emitter, isGenericSpecialization))))); } if (prop.IsIndexer) { properties.Add("i", true); } if (prop.IsIndexer) { if (prop.Getter != null) { var parametersInfo = prop.Getter.Parameters.Select(p => MetadataUtils.ConstructParameterInfo(p, emitter, false, false, tree)).ToList(); if (parametersInfo.Count > 0) { properties.Add("ipi", new JArray(parametersInfo)); } } else if (prop.Setter != null) { var parametersInfo = prop.Setter.Parameters.Take(prop.Setter.Parameters.Count - 1).Select(p => MetadataUtils.ConstructParameterInfo(p, emitter, false, false, tree)).ToList(); if (parametersInfo.Count > 0) { properties.Add("ipi", new JArray(parametersInfo)); } } } var inlineGetter = prop.CanGet && (emitter.GetInline(prop.Getter) != null || Helpers.IsScript(prop.Getter)); var inlineSetter = prop.CanSet && (emitter.GetInline(prop.Setter) != null || Helpers.IsScript(prop.Setter)); if (inlineGetter || inlineSetter || prop.IsIndexer) { if (prop.CanGet) { properties.Add("g", MetadataUtils.ConstructMemberInfo(prop.Getter, emitter, includeDeclaringType, isGenericSpecialization, tree)); } if (prop.CanSet) { properties.Add("s", MetadataUtils.ConstructMemberInfo(prop.Setter, emitter, includeDeclaringType, isGenericSpecialization, tree)); } } else { var fieldName = OverloadsCollection.Create(emitter, prop).GetOverloadName(); if (prop.CanGet) { properties.Add("g", MetadataUtils.ConstructFieldPropertyAccessor(prop.Getter, emitter, fieldName, true, includeDeclaringType, isGenericSpecialization, tree)); } if (prop.CanSet) { properties.Add("s", MetadataUtils.ConstructFieldPropertyAccessor(prop.Setter, emitter, fieldName, false, includeDeclaringType, isGenericSpecialization, tree)); } properties.Add("fn", fieldName); } } else if (m is IEvent) { var evt = (IEvent)m; properties.Add("t", (int)MemberTypes.Event); properties.Add("ad", MetadataUtils.ConstructMemberInfo(evt.AddAccessor, emitter, includeDeclaringType, isGenericSpecialization, tree)); properties.Add("r", MetadataUtils.ConstructMemberInfo(evt.RemoveAccessor, emitter, includeDeclaringType, isGenericSpecialization, tree)); } else { throw new ArgumentException("Invalid member " + m); } return(properties); }
private static JObject ConstructConstructorInfo(IMethod constructor, IEmitter emitter, bool includeDeclaringType, bool isGenericSpecialization, SyntaxTree tree) { var properties = MetadataUtils.GetCommonMemberInfoProperties(constructor, emitter, includeDeclaringType, isGenericSpecialization, tree); if (Helpers.IsNonScriptable(constructor)) { return(null); } properties.Add("t", (int)MemberTypes.Constructor); if (constructor.Parameters.Count > 0) { properties.Add("p", new JArray(constructor.Parameters.Select(p => new JRaw(MetadataUtils.GetTypeName(p.Type, emitter, isGenericSpecialization))))); } var parametersInfo = constructor.Parameters.Select(p => MetadataUtils.ConstructParameterInfo(p, emitter, false, false, tree)).ToList(); if (parametersInfo.Count > 0) { properties.Add("pi", new JArray(parametersInfo)); } var inline = emitter.GetInline(constructor); var typeDef = constructor.DeclaringTypeDefinition; IAttribute customCtor = null; if (typeDef != null) { customCtor = emitter.Validator.GetAttribute(typeDef.Attributes, Translator.Bridge_ASSEMBLY + ".ConstructorAttribute"); } if (string.IsNullOrEmpty(inline) && customCtor == null) { string sname; if (constructor.IsStatic || constructor.DeclaringType.Kind == TypeKind.Anonymous) { sname = JS.Funcs.CONSTRUCTOR; } else { sname = OverloadsCollection.Create(emitter, constructor).GetOverloadName(); } properties.Add("sn", sname); } if (constructor.IsStatic) { properties.Add("sm", true); } if (string.IsNullOrEmpty(inline) && constructor.Attributes.Any(a => a.AttributeType.FullName == "Bridge.ExpandParamsAttribute")) { properties.Add("exp", true); } if (!string.IsNullOrEmpty(inline)) { var block = new InlineArgumentsBlock(emitter, new ArgumentsInfo(emitter, constructor), inline, constructor); var oldWriter = block.SaveWriter(); block.NewWriter(); block.EmitFunctionReference(true); var str = emitter.Output.ToString(); block.RestoreWriter(oldWriter); properties.Add("def", new JRaw(str)); } else if (customCtor != null) { inline = customCtor.PositionalArguments[0].ConstantValue.ToString(); if (Regex.Match(inline, @"\s*\{\s*\}\s*").Success) { var names = constructor.Parameters.Select(p => p.Name); StringBuilder sb = new StringBuilder("function (" + string.Join(", ", names.ToArray()) + ") { return {"); bool needComma = false; foreach (var name in names) { if (needComma) { sb.Append(", "); } needComma = true; sb.Append(name + ": " + name); } sb.Append("};}"); properties.Add("def", new JRaw(sb.ToString())); } else { var block = new InlineArgumentsBlock(emitter, new ArgumentsInfo(emitter, constructor), inline, constructor); var oldWriter = block.SaveWriter(); block.NewWriter(); block.EmitFunctionReference(true); var str = emitter.Output.ToString(); block.RestoreWriter(oldWriter); properties.Add("def", new JRaw(str)); } } return(properties); }
private static bool?ReflectableValue(IList <IAttribute> attributes, IMember member, IEmitter emitter) { var attr = attributes.FirstOrDefault(a => a.AttributeType.FullName == "Bridge.ReflectableAttribute"); if (attr == null) { attr = Helpers.GetInheritedAttribute(member, "Bridge.ReflectableAttribute"); if (attr != null) { if (attr.NamedArguments.Count > 0 && attr.NamedArguments.Any(arg => arg.Key.Name == "Inherits")) { var inherits = attr.NamedArguments.First(arg => arg.Key.Name == "Inherits"); if (!(bool)inherits.Value.ConstantValue) { attr = null; } } else { attr = null; } } } if (attr != null) { if (attr.PositionalArguments.Count == 0) { return(true); } if (attr.PositionalArguments.Count > 1) { var list = new List <MemberAccessibility>(); for (int i = 0; i < attr.PositionalArguments.Count; i++) { object v = attr.PositionalArguments[i].ConstantValue; list.Add((MemberAccessibility)(int)v); } return(MetadataUtils.IsMemberReflectable(member, list.ToArray())); } else { var rr = attr.PositionalArguments.First(); var value = rr.ConstantValue; if (rr is ArrayCreateResolveResult) { return(MetadataUtils.IsMemberReflectable(member, ((ArrayCreateResolveResult)rr).InitializerElements.Select(ie => (int)ie.ConstantValue).Cast <MemberAccessibility>().ToArray())); } if (value is bool) { return((bool)attr.PositionalArguments.First().ConstantValue); } if (value is int) { return(MetadataUtils.IsMemberReflectable(member, new[] { (MemberAccessibility)(int)value })); } if (value is int[]) { return(MetadataUtils.IsMemberReflectable(member, ((int[])value).Cast <MemberAccessibility>().ToArray())); } } } return(null); }
private static JObject ConstructParameterInfo(IParameter p, IEmitter emitter, bool includeDeclaringType, bool isGenericSpecialization, SyntaxTree tree) { var result = new JObject(); var attr = MetadataUtils.GetScriptableAttributes(p.Attributes, emitter, tree).ToList(); if (attr.Count > 0) { JArray attrArr = new JArray(); foreach (var a in attr) { attrArr.Add(MetadataUtils.ConstructAttribute(a, null, emitter)); } result.Add("at", attrArr); } result.Add("n", p.Name); if (p.IsOptional) { var typeParam = p.Type as ITypeParameter; if (typeParam != null && p.ConstantValue == null) { result.Add("dv", typeParam.OwnerType == SymbolKind.Method ? new JRaw(emitter.ToJavaScript(p.ConstantValue)) : new JRaw(string.Format("{0}({1})", JS.Funcs.BRIDGE_GETDEFAULTVALUE, typeParam.Name))); } else { result.Add("dv", new JRaw(emitter.ToJavaScript(p.ConstantValue))); } result.Add("o", true); } if (p.IsOut) { result.Add("out", true); } if (p.IsRef) { result.Add("ref", true); } if (p.IsParams) { result.Add("ip", true); } result.Add("pt", new JRaw(MetadataUtils.GetTypeName(p.Type, emitter, isGenericSpecialization))); result.Add("ps", p.Owner.Parameters.IndexOf(p)); var nameAttr = p.Attributes.FirstOrDefault(a => a.AttributeType.FullName == "Bridge.NameAttribute"); if (nameAttr != null) { var value = nameAttr.PositionalArguments.First().ConstantValue; if (value is string) { var name = Helpers.ConvertNameTokens(value.ToString(), p.Name); if (Helpers.IsReservedWord(emitter, name)) { name = Helpers.ChangeReservedWord(name); } result.Add("sn", name); } } return(result); }
public static JObject ConstructTypeMetadata(ITypeDefinition type, IEmitter emitter, bool ifHasAttribute, SyntaxTree tree) { var properties = ifHasAttribute ? new JObject() : MetadataUtils.GetCommonTypeProperties(type, emitter); var scriptableAttributes = MetadataUtils.GetScriptableAttributes(type.Attributes, emitter, tree).ToList(); if (scriptableAttributes.Count != 0) { JArray attrArr = new JArray(); foreach (var a in scriptableAttributes) { attrArr.Add(MetadataUtils.ConstructAttribute(a, type, emitter)); } properties.Add("at", attrArr); } if (type.Kind == TypeKind.Class || type.Kind == TypeKind.Struct || type.Kind == TypeKind.Interface || type.Kind == TypeKind.Enum) { var members = type.Members.Where(m => MetadataUtils.IsReflectable(m, emitter, ifHasAttribute, tree)) .OrderBy(m => m, MemberOrderer.Instance) .Select(m => MetadataUtils.ConstructMemberInfo(m, emitter, false, false, tree)) .ToList(); if (members.Count > 0) { properties.Add("m", new JArray(members)); } var aua = type.Attributes.FirstOrDefault(a => a.AttributeType.FullName == "System.AttributeUsageAttribute"); if (aua != null) { var inherited = true; var allowMultiple = false; if (aua.PositionalArguments.Count == 3) { allowMultiple = (bool)aua.PositionalArguments[1].ConstantValue; inherited = (bool)aua.PositionalArguments[2].ConstantValue; } if (aua.NamedArguments.Count > 0) { foreach (var arg in aua.NamedArguments) { if (arg.Key.Name == "AllowMultiple") { allowMultiple = (bool)arg.Value.ConstantValue; } else if (arg.Key.Name == "Inherited") { inherited = (bool)arg.Value.ConstantValue; } } } if (!inherited) { properties.Add("ni", true); } if (allowMultiple) { properties.Add("am", true); } } } return(properties.Count > 0 ? properties : null); }
protected override void DoEmit() { this.Emitter.Tag = "JS"; this.Emitter.Writers = new Stack <IWriter>(); this.Emitter.Outputs = new EmitterOutputs(); var metas = new Dictionary <IType, JObject>(); this.Emitter.Translator.Plugins.BeforeTypesEmit(this.Emitter, this.Emitter.Types); this.Emitter.ReflectableTypes = this.GetReflectableTypes(); var reflectedTypes = this.Emitter.ReflectableTypes; var tmpBuffer = new StringBuilder(); StringBuilder currentOutput = null; this.Emitter.NamedBoxedFunctions = new Dictionary <IType, Dictionary <string, string> >(); this.Emitter.HasModules = this.Emitter.Types.Any(t => t.Module != null); foreach (var type in this.Emitter.Types) { this.Emitter.Translator.Plugins.BeforeTypeEmit(this.Emitter, type); this.Emitter.Translator.EmitNode = type.TypeDeclaration; var typeDef = type.Type.GetDefinition(); this.Emitter.Rules = Rules.Get(this.Emitter, typeDef); bool isNative; if (typeDef.Kind == TypeKind.Interface && this.Emitter.Validator.IsExternalInterface(typeDef, out isNative)) { this.Emitter.Translator.Plugins.AfterTypeEmit(this.Emitter, type); continue; } if (type.IsObjectLiteral) { var mode = this.Emitter.Validator.GetObjectCreateMode(this.Emitter.GetTypeDefinition(type.Type)); var ignore = mode == 0 && !type.Type.GetMethods(null, GetMemberOptions.IgnoreInheritedMembers).Any(m => !m.IsConstructor && !m.IsAccessor); if (this.Emitter.Validator.IsExternalType(typeDef) || ignore) { this.Emitter.Translator.Plugins.AfterTypeEmit(this.Emitter, type); continue; } } this.Emitter.InitEmitter(); ITypeInfo typeInfo; if (this.Emitter.TypeInfoDefinitions.ContainsKey(type.Key)) { typeInfo = this.Emitter.TypeInfoDefinitions[type.Key]; type.Module = typeInfo.Module; type.FileName = typeInfo.FileName; type.Dependencies = typeInfo.Dependencies; typeInfo = type; } else { typeInfo = type; } this.Emitter.SourceFileName = type.TypeDeclaration.GetParent <SyntaxTree>().FileName; this.Emitter.SourceFileNameIndex = this.Emitter.SourceFiles.IndexOf(this.Emitter.SourceFileName); this.Emitter.Output = this.GetOutputForType(typeInfo, null); this.Emitter.TypeInfo = type; type.JsName = BridgeTypes.ToJsName(type.Type, this.Emitter, true, removeScope: false); if (this.Emitter.Output.Length > 0) { this.WriteNewLine(); } tmpBuffer.Length = 0; currentOutput = this.Emitter.Output; this.Emitter.Output = tmpBuffer; if (this.Emitter.TypeInfo.Module != null) { this.Indent(); } var name = BridgeTypes.ToJsName(type.Type, this.Emitter, true, true, true); if (type.Type.DeclaringType != null && JS.Reserved.StaticNames.Any(n => String.Equals(name, n, StringComparison.InvariantCulture))) { throw new EmitterException(type.TypeDeclaration, "Nested class cannot have such name: " + name + ". Please rename it."); } new ClassBlock(this.Emitter, this.Emitter.TypeInfo).Emit(); this.Emitter.Translator.Plugins.AfterTypeEmit(this.Emitter, type); currentOutput.Append(tmpBuffer.ToString()); this.Emitter.Output = currentOutput; } this.Emitter.DisableDependencyTracking = true; this.EmitNamedBoxedFunctions(); this.Emitter.NamespacesCache = new Dictionary <string, int>(); if (!this.Emitter.HasModules && this.Emitter.AssemblyInfo.Reflection.Target != MetadataTarget.Type) { foreach (var type in this.Emitter.Types) { var typeDef = type.Type.GetDefinition(); bool isGlobal = false; if (typeDef != null) { isGlobal = typeDef.Attributes.Any(a => a.AttributeType.FullName == "Bridge.GlobalMethodsAttribute" || a.AttributeType.FullName == "Bridge.MixinAttribute"); } if (typeDef.FullName != "System.Object") { var name = BridgeTypes.ToJsName(typeDef, this.Emitter); if (name == "Object") { continue; } } var isObjectLiteral = this.Emitter.Validator.IsObjectLiteral(typeDef); var isPlainMode = isObjectLiteral && this.Emitter.Validator.GetObjectCreateMode(this.Emitter.BridgeTypes.Get(type.Key).TypeDefinition) == 0; if (isPlainMode) { continue; } if (isGlobal || this.Emitter.TypeInfo.Module != null || reflectedTypes.Any(t => t == type.Type)) { continue; } var meta = MetadataUtils.ConstructTypeMetadata(typeDef, this.Emitter, true, type.TypeDeclaration.GetParent <SyntaxTree>()); if (meta != null) { metas.Add(type.Type, meta); } } } foreach (var reflectedType in reflectedTypes) { var typeDef = reflectedType.GetDefinition(); JObject meta = null; if (typeDef != null) { var tInfo = this.Emitter.Types.FirstOrDefault(t => t.Type == reflectedType); SyntaxTree tree = null; if (tInfo != null && tInfo.TypeDeclaration != null) { tree = tInfo.TypeDeclaration.GetParent <SyntaxTree>(); } if (tInfo != null && tInfo.Module != null || this.Emitter.HasModules || this.Emitter.AssemblyInfo.Reflection.Target == MetadataTarget.Type) { continue; } meta = MetadataUtils.ConstructTypeMetadata(reflectedType.GetDefinition(), this.Emitter, false, tree); } else { meta = MetadataUtils.ConstructITypeMetadata(reflectedType, this.Emitter); } if (meta != null) { metas.Add(reflectedType, meta); } } var lastOutput = this.Emitter.Output; var output = this.Emitter.AssemblyInfo.Reflection.Output; if (this.Emitter.AssemblyInfo.Reflection.Target == MetadataTarget.File) { if (string.IsNullOrEmpty(output)) { if (!string.IsNullOrWhiteSpace(this.Emitter.AssemblyInfo.FileName) && this.Emitter.AssemblyInfo.FileName != AssemblyInfo.DEFAULT_FILENAME) { output = System.IO.Path.GetFileNameWithoutExtension(this.Emitter.AssemblyInfo.FileName) + ".meta.js"; } else { output = this.Emitter.Translator.ProjectProperties.AssemblyName + ".meta.js"; } } this.Emitter.Output = this.GetOutputForType(null, output, true); this.Emitter.MetaDataOutputName = this.Emitter.EmitterOutput.FileName; } var scriptableAttributes = MetadataUtils.GetScriptableAttributes(this.Emitter.Resolver.Compilation.MainAssembly.AssemblyAttributes, this.Emitter, null).ToList(); bool hasMeta = metas.Count > 0 || scriptableAttributes.Count > 0; if (hasMeta) { this.WriteNewLine(); int pos = 0; if (metas.Count > 0) { this.Write("var $m = " + JS.Types.Bridge.SET_METADATA + ","); this.WriteNewLine(); this.Write(Bridge.Translator.Emitter.INDENT + "$n = "); pos = this.Emitter.Output.Length; this.Write(";"); this.WriteNewLine(); } foreach (var meta in metas) { var metaData = meta.Value; string typeArgs = ""; if (meta.Key.TypeArguments.Count > 0 && !Helpers.IsIgnoreGeneric(meta.Key, this.Emitter)) { StringBuilder arr_sb = new StringBuilder(); var comma = false; foreach (var typeArgument in meta.Key.TypeArguments) { if (comma) { arr_sb.Append(", "); } arr_sb.Append(typeArgument.Name); comma = true; } typeArgs = arr_sb.ToString(); } this.Write(string.Format("$m(\"{0}\", function ({2}) {{ return {1}; }}, $n);", MetadataUtils.GetTypeName(meta.Key, this.Emitter, false, true, false), metaData.ToString(Formatting.None), typeArgs)); this.WriteNewLine(); } if (pos > 0) { this.Emitter.Output.Insert(pos, this.Emitter.ToJavaScript(this.Emitter.NamespacesCache.OrderBy(key => key.Value).Select(item => item.Key).ToArray())); this.Emitter.NamespacesCache = null; } if (scriptableAttributes.Count > 0) { JArray attrArr = new JArray(); foreach (var a in scriptableAttributes) { attrArr.Add(MetadataUtils.ConstructAttribute(a, null, this.Emitter)); } this.Write(string.Format("$asm.attr= {0};", attrArr.ToString(Formatting.None))); this.WriteNewLine(); } } this.Emitter.Output = lastOutput; //this.RemovePenultimateEmptyLines(true); this.Emitter.Translator.Plugins.AfterTypesEmit(this.Emitter, this.Emitter.Types); }
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 override void DoEmit() { this.Emitter.Writers = new Stack <IWriter>(); this.Emitter.Outputs = new EmitterOutputs(); var metas = new Dictionary <IType, JObject>(); this.Emitter.Translator.Plugins.BeforeTypesEmit(this.Emitter, this.Emitter.Types); this.Emitter.ReflectableTypes = this.GetReflectableTypes(); var reflectedTypes = this.Emitter.ReflectableTypes; var tmpBuffer = new StringBuilder(); StringBuilder currentOutput = null; foreach (var type in this.Emitter.Types) { this.Emitter.Translator.Plugins.BeforeTypeEmit(this.Emitter, type); this.Emitter.Translator.EmitNode = type.TypeDeclaration; var typeDef = type.Type.GetDefinition(); bool isNative; if (this.Emitter.Validator.IsExternalInterface(typeDef, out isNative)) { this.Emitter.Translator.Plugins.AfterTypeEmit(this.Emitter, type); continue; } if (type.IsObjectLiteral) { //var mode = this.Emitter.Validator.GetObjectCreateMode(this.Emitter.GetTypeDefinition(type.Type)); //var ignore = mode == 0 && !type.Type.GetMethods(null, GetMemberOptions.IgnoreInheritedMembers).Any(m => !m.IsConstructor && !m.IsAccessor); if (this.Emitter.Validator.IsIgnoreType(typeDef)) { this.Emitter.Translator.Plugins.AfterTypeEmit(this.Emitter, type); continue; } } this.Emitter.InitEmitter(); ITypeInfo typeInfo; if (this.Emitter.TypeInfoDefinitions.ContainsKey(type.Key)) { typeInfo = this.Emitter.TypeInfoDefinitions[type.Key]; type.Module = typeInfo.Module; type.FileName = typeInfo.FileName; type.Dependencies = typeInfo.Dependencies; typeInfo = type; } else { typeInfo = type; } this.Emitter.Output = this.GetOutputForType(typeInfo, null); this.Emitter.TypeInfo = type; type.JsName = BridgeTypes.ToJsName(type.Type, this.Emitter, true); if (this.Emitter.Output.Length > 0) { this.WriteNewLine(); } tmpBuffer.Length = 0; currentOutput = this.Emitter.Output; this.Emitter.Output = tmpBuffer; if (this.Emitter.TypeInfo.Module != null) { this.Indent(); } new ClassBlock(this.Emitter, this.Emitter.TypeInfo).Emit(); this.Emitter.Translator.Plugins.AfterTypeEmit(this.Emitter, type); currentOutput.Append(tmpBuffer.ToString()); this.Emitter.Output = currentOutput; } this.Emitter.NamespacesCache = new Dictionary <string, int>(); foreach (var type in this.Emitter.Types) { var typeDef = type.Type.GetDefinition(); bool isGlobal = false; if (typeDef != null) { isGlobal = typeDef.Attributes.Any(a => a.AttributeType.FullName == "Bridge.GlobalMethodsAttribute" || a.AttributeType.FullName == "Bridge.MixinAttribute"); } if (typeDef.FullName != "System.Object") { var name = BridgeTypes.ToJsName(typeDef, this.Emitter); if (name == "Object") { continue; } } if (reflectedTypes.Any(t => t == type.Type) || isGlobal) { continue; } var meta = MetadataUtils.ConstructTypeMetadata(typeDef, this.Emitter, true, type.TypeDeclaration.GetParent <SyntaxTree>()); if (meta != null) { metas.Add(type.Type, meta); } } foreach (var reflectedType in reflectedTypes) { var typeDef = reflectedType.GetDefinition(); JObject meta = null; if (typeDef != null) { var tInfo = this.Emitter.Types.FirstOrDefault(t => t.Type == reflectedType); SyntaxTree tree = null; if (tInfo != null && tInfo.TypeDeclaration != null) { tree = tInfo.TypeDeclaration.GetParent <SyntaxTree>(); } meta = MetadataUtils.ConstructTypeMetadata(reflectedType.GetDefinition(), this.Emitter, false, tree); } else { meta = MetadataUtils.ConstructITypeMetadata(reflectedType, this.Emitter); } if (meta != null) { metas.Add(reflectedType, meta); } } var lastOutput = this.Emitter.Output; var output = this.Emitter.AssemblyInfo.Reflection.Output; if (!string.IsNullOrEmpty(output)) { this.Emitter.Output = this.GetOutputForType(null, output); this.Emitter.MetaDataOutputName = this.Emitter.EmitterOutput.FileName; } var scriptableAttributes = MetadataUtils.GetScriptableAttributes(this.Emitter.Resolver.Compilation.MainAssembly.AssemblyAttributes, this.Emitter, null).ToList(); bool hasMeta = metas.Count > 0 || scriptableAttributes.Count > 0; if (hasMeta) { this.WriteNewLine(); int pos = 0; if (metas.Count > 0) { this.Write("var $m = " + JS.Types.Bridge.SET_METADATA + ","); this.WriteNewLine(); this.Write(Bridge.Translator.Emitter.INDENT + "$n = "); pos = this.Emitter.Output.Length; this.Write(";"); this.WriteNewLine(); } foreach (var meta in metas) { var metaData = meta.Value; string typeArgs = ""; if (meta.Key.TypeArguments.Count > 0) { StringBuilder arr_sb = new StringBuilder(); var comma = false; foreach (var typeArgument in meta.Key.TypeArguments) { if (comma) { arr_sb.Append(", "); } arr_sb.Append(typeArgument.Name); comma = true; } typeArgs = arr_sb.ToString(); } this.Write(string.Format("$m({0}, function ({2}) {{ return {1}; }});", MetadataUtils.GetTypeName(meta.Key, this.Emitter, false, true), metaData.ToString(Formatting.None), typeArgs)); this.WriteNewLine(); } if (pos > 0) { this.Emitter.Output.Insert(pos, this.Emitter.ToJavaScript(this.Emitter.NamespacesCache.OrderBy(key => key.Value).Select(item => new JRaw(item.Key)).ToArray())); this.Emitter.NamespacesCache = null; } if (scriptableAttributes.Count > 0) { JArray attrArr = new JArray(); foreach (var a in scriptableAttributes) { attrArr.Add(MetadataUtils.ConstructAttribute(a, null, this.Emitter)); } this.Write(string.Format("$asm.attr= {0};", attrArr.ToString(Formatting.None))); this.WriteNewLine(); } } this.Emitter.Output = lastOutput; //this.RemovePenultimateEmptyLines(true); this.Emitter.Translator.Plugins.AfterTypesEmit(this.Emitter, this.Emitter.Types); }
private static JObject GetCommonMemberInfoProperties(IMember m, IEmitter emitter, bool includeDeclaringType, bool isGenericSpecialization, SyntaxTree tree) { var result = new JObject(); var attr = MetadataUtils.GetScriptableAttributes(m.Attributes, emitter, tree).ToList(); if (attr.Count > 0) { JArray attrArr = new JArray(); foreach (var a in attr) { attrArr.Add(MetadataUtils.ConstructAttribute(a, m.DeclaringTypeDefinition, emitter)); } result.Add("at", attrArr); } if (includeDeclaringType) { result.Add("td", new JRaw(MetadataUtils.GetTypeName(m.DeclaringType, emitter, isGenericSpecialization))); } if (m.IsOverride) { result.Add("ov", true); } if (m.IsVirtual) { result.Add("v", true); } if (m.IsAbstract) { result.Add("ab", true); } if (m.Accessibility != Accessibility.None) { if (m.Attributes.Any(a => a.AttributeType.FullName == "Bridge.PrivateProtectedAttribute")) { result.Add("a", (int)Accessibility.ProtectedAndInternal); } else { result.Add("a", (int)m.Accessibility); } } if (m.IsSealed) { result.Add("sl", true); } if (m.IsSynthetic) { result.Add("isSynthetic", true); } result.Add("n", m.Name); return(result); }