Пример #1
0
        private void GenereateMetadata(IAnonymousTypeConfig config)
        {
            var meta = MetadataUtils.ConstructITypeMetadata(config.Type, this.Emitter);

            if (meta != null)
            {
                this.EnsureComma();
                this.Write("statics : ");
                this.BeginBlock();
                this.Write("$metadata : ");
                this.Write(meta.ToString(Formatting.None));
                this.WriteNewLine();
                this.EndBlock();
            }
        }
Пример #2
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.IsExternalType(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, 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();
                }

                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 && !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}; }});", 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);
        }
Пример #3
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 && this.Emitter.AssemblyInfo.Module == null)
            {
                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);
        }
Пример #4
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;

            foreach (var type in this.Emitter.Types)
            {
                this.Emitter.Translator.Plugins.BeforeTypeEmit(this.Emitter, type);

                this.Emitter.Translator.EmitNode = type.TypeDeclaration;
                if (type.IsObjectLiteral)
                {
                    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;

                if (this.Emitter.TypeInfo.Module != null)
                {
                    this.Indent();
                }

                new ClassBlock(this.Emitter, this.Emitter.TypeInfo).Emit();
                this.Emitter.Translator.Plugins.AfterTypeEmit(this.Emitter, 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 (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();

            if (metas.Count > 0 || scriptableAttributes.Count > 0)
            {
                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("Bridge.setMetadata({0}, function ({2}) {{ return {1}; }});", BridgeTypes.ToJsName(meta.Key, this.Emitter, true), metaData.ToString(Formatting.None), typeArgs));
                this.WriteNewLine();
            }

            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);
        }