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);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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);
        }
Beispiel #10
0
        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);
        }