private void Export(Method me) { ExportXmlDoc2(me); me.Attributes.ForEach(Export); if (me.IsConstructor) { Write("public {0}(", Identifier(me.DeclaringClass.Name)); me.Parameters.ForEachJoin(Export, WriteComma); Write(")"); if (me.DeclaringClass.BaseClass != null) { var baseCtors = me.DeclaringClass.BaseClass.Members.OfType<Method>().Where(t => t.IsConstructor).ToList(); if (baseCtors.Count > 0 && baseCtors.Where(t => t.Parameters.Count == 0).FirstOrDefault() == null) { Write(" : base("); baseCtors.First().Parameters.ForEachJoin(p => Write("null"), WriteComma); Write(")"); } } WriteLine("{}"); } else { ExportVisibility(me); Write("{0}{1}{2}{3}{4} {5}(", me.IsStatic.If("static "), me.IsVirtual.If("virtual "), me.IsOverride.If("override "), me.IsNew.If("new "), me.Type == null ? "void" : Class(me.Type), Identifier(me.Name)); me.Parameters.ForEachJoin(Export, WriteComma); Write(")"); if (me.DeclaringClass.IsInterface) { WriteLine(";"); } else { Write("{"); if (me.Type != null && me.Type.Name != "void") { if (me.Type.Name == "bool") Write("return false;"); else Write("return null;", Class(me.Type)); } WriteLine("}"); } } }
private void GenerateMember(object node) { var names = node.GetNames(); var itemType = node.Get<string>("itemtype"); var name = node.Get<string>("name"); var access = node.Get<string>("access"); if (name.IsNullOrEmpty()) { Console.WriteLine("Warning: empty name " + name); return; } var className = node.Get<string>("class"); if (name == "content" && className.Contains("EditorBase")) { } var type = node.Get<string>("type"); var ce = FindClass(className); if (ce == null) { Console.WriteLine("Warning: Can't find class: " + className); return; } Element me2 = null; if (itemType == "attribute" || itemType == "property") { var isReadOnly = node.Get<string>("readonly") != null; if (type.IsNullOrEmpty()) { type = "object"; Console.WriteLine("Warning: type is null: " + className + "." + name + " assuming object"); //return; } var pe = new Property { Name = name, Type = FindClass(type), }; pe.IsReadOnly = isReadOnly; if (Char.IsDigit(pe.Name[0])) { Console.WriteLine("Warning: Invalid name " + pe.Name); return; } if (pe.Type == null) { Console.WriteLine("Warning: type is null"); return; } ce.Members.Add(pe); if (itemType == "attribute") { var ctor = ce.GetEmptyConstructor(); if (ctor == null) { ctor = new Method { IsConstructor = true, Name=".ctor", }; ce.Members.Add(ctor); } var att = ctor.Attributes.Where(t => t.Name == "JsMethod").FirstOrDefault(); if (att == null) { att = new SharpKit.ExtJs4.Generator.Attribute { Name = "JsMethod", NamedParamters = new Dictionary<string, string> { { "JsonInitializers", "true" } }, }; ctor.Attributes.Add(att); } } me2 = pe; } else if (itemType == "method") { var prms = node.GetValues("params"); var returns = node.GetValues("return"); var me = new Method { Name = name, //Type = FindClass(type), }; if (prms != null) me.Parameters = prms.Select(GenerateParameter).ToList(); if (me.Parameters.Contains(null)) { Console.WriteLine("Warning: prms contains nulls:" + className + "." + name); return; } if (returns != null) { var returnType = returns.LastOrDefault() as string; returnType = returnType.Split('|').FirstOrDefault().Trim(); me.Type = FindClass(returnType); if (me.Type == null) { Console.WriteLine("Cannot resolve method return type: " + className + "." + name); me.Type = ObjectClass; } } ce.Members.Add(me); me2 = me; } if (me2 != null) { if (access.IsNullOrEmpty()) { } else if (access == "protected") me2.IsProtected = true; else if (access == "private") me2.IsPrivate = true; else if (access == "public") { } else { } ImportDocumentation(me2, node); } }
private static void AddOptionalOverloads(Class ce, Method me, List<Parameter> optionalParameters) { foreach (var prm in optionalParameters.ToArray()) { var me2 = me.Clone(); me2.Parameters.Remove(me2.Parameters.Where(t => t.Name == prm.Name).First()); ce.Members.Add(me2); var op2 = optionalParameters.ToArray().ToList(); op2.Remove(prm); AddOptionalOverloads(ce, me2, op2); } }
private static Method ProcessMethod( ExtMember me2 ) { //var owner = GetClass( me2.owner ); //ProcessMemberDocs( me2 ); var clsName = me2.name == "constructor" ? me2.owner : me2.type; //unified "type" is never null var me = new Method { Name = me2.name, Type = GetClass( clsName ), Summary = me2.shortDoc, ParametersDocs = me2.paramsDocs, ReturnsDocs = me2.returnsDocs, IsPrivate = me2.meta.@private, IsProtected = me2.meta.@protected, IsStatic = me2.meta.@static, IsVirtual = me2.shortDoc.Contains( "template method" ), IsConstructor = me2.name == "constructor", ReturnsArray = me2.ReturnsArray }; if ( me2.@params != null && [email protected] > 0 ) me.Parameters.AddRange( [email protected]( ProcessParam ) ); return me; }
private static List<Class> Fix( List<Class> list ) { list.ForEach( t => t.Members.Where( m => m.DeclaringClass == null ).ForEach( m => m.DeclaringClass = t ) ); list.ForEach( t => t.Members.OfType<Method>().Where( m => m.Name.Equals( "callParent", StringComparison.Ordinal ) && m.Parameters.Count == 1 ).ForEach( m => m.Parameters.ForEach( p => { p.IsOptional = true; p.Type = GetClass( "object" ); } ) ) ); var ceExt = GetClass( "Ext.ExtContext", false ); if ( InheritFromJsContext ) ceExt.BaseClass = GetClass( "JsContext", false ); ceExt.Attributes[ 0 ].NamedParamters.Add( "Name", "\"Ext\"" ); //Fixing Ext aliases. ceExt.Members.Where( m => m.Name.Equals( "getDoc" ) || m.Name.Equals( "getDom" ) || m.Name.Equals( "getElementById" ) || m.Name.Equals( "getBody" ) ).ForEach( m => m.Type = GetClass( "Element" ) ); ceExt.Members.OfType<Method>().Where( m => m.Name.Equals( "getClass" ) ).ForEach( m => { m.Type = GetClass( "Ext.Class" ); m.Parameters.Add( new Parameter { DeclaringClass = ceExt, Name = "cls", Type = GetClass( "object" ) } ); } ); ceExt.Members.OfType<Method>().Where( m => m.Name.Equals( "getClassName" ) ).ForEach( m => { m.Type = GetClass( "JsString" ); m.Parameters.Add( new Parameter { DeclaringClass = ceExt, Name = "cls", Type = GetClass( "object" ) } ); } ); ceExt.Members.OfType<Method>().Where( m => m.Name.Equals( "createByAlias" ) ).ForEach( m => { m.Type = GetClass( "object" ); m.Parameters.Add( new Parameter { DeclaringClass = ceExt, Name = "name", Type = GetClass( "JsString" ) } ); m.Parameters.Add( new Parameter { DeclaringClass = ceExt, Name = "args", Type = GetClass( "object" ), IsParams = true } ); } ); ceExt.Members.OfType<Method>().Where( m => m.Name.Equals( "create" ) ).ForEach( m => { m.Parameters[ 0 ].IsOptional = false; m.Parameters[ 1 ].IsOptional = false; m.Parameters[ 1 ].IsParams = true; } ); ceExt.Members.Where( m => m.Name.Equals( "getCmp" ) ).ForEach( m => m.Type = GetClass( "Ext.Component" ) ); ceExt.Members.OfType<Method>().Where( m => m.Name.Equals( "require" ) ).ForEach( m => m.Parameters.Add( new Parameter { Type = GetClass( "object" ), Name = "args", IsParams = true, DeclaringClass = ceExt } ) ); //End fixing Ext aliases //Adding Ext non existant aliases. ceExt.Members.Add( new Property { Name = "Msg", Type = GetClass( "Ext.window.MessageBox" ), DeclaringClass = ceExt, IsStatic = true } ); ceExt.Members.Add( new Property { Name = "Direct", Type = GetClass( "Ext.direct.Manager" ), DeclaringClass = ceExt, IsStatic = true } ); //END adding non existant aliases. //Add a new utility class to deal with this var cellModel = GetClass( "Ext.selection.CellModel" ); var jsonPositionClass = GetClass( "Ext.selection.CellModel.Position", true ); jsonPositionClass.Attributes.Add( CreateJsAttribute( "Json" ) ); jsonPositionClass.Members.AddRange( new Element[] { new Property { Name = "row", Type = GetClass( "int" ), DeclaringClass = jsonPositionClass }, new Property { Name = "column", Type = GetClass( "int" ), DeclaringClass = jsonPositionClass } } ); cellModel.Members.Where( m => m.Name.Equals( "getCurrentPosition", StringComparison.Ordinal ) ).ForEach( m => m.Type = jsonPositionClass ); var bExt = GetClass( "Ext.Base", false ); if ( InheritFromJsContext ) bExt.BaseClass = GetClass( "JsContext", false ); //Explicitly setting these members as public to be able to use it in anonymous objects via @this.As<XXX>().callXXX(); (and borrow should be public but docs are wrong according to Ext forum) bExt.Members.OfType<Method>().Where( m => m.Name.Equals( "create", StringComparison.Ordinal ) || m.Name.Equals( "implement", StringComparison.Ordinal ) ).ForEach( m => { m.IsStatic = false; m.Parameters.Add( new Parameter { Type = GetClass( "object" ), Name = "args", IsParams = true, DeclaringClass = bExt } ); } ); bExt.Members.Where( m => new[] { "@className", "configMap", "initConfigList", "initConfigMap", "isInstance", "self", "callParent", "callOverridden", "destroy" }.Any( s => s.Equals( m.Name, StringComparison.Ordinal ) ) ).ForEach( m => m.IsProtected = m.IsPrivate = false ); list.Where( t => t.FullName == "Ext.util.Sortable" || t.Interfaces.FirstOrDefault( i => i.FullName == "Ext.util.Sortable" ) != null ).ForEach( t => t.Members.Where( m => m.Name.IsNullOrEmpty() ).ForEach( m => m.Name = "sortRoot" ) ); list.ForEach( t => t.Members.Where( m => m.Type != null && m.Type.Name == "this" ).ForEach( m => m.Type = t ) ); list = list.Where( t => t.Name != "this" ).ToList(); list.ForEach( t => t.Members.OfType<Method>().Where( m => m.Name == "toFixed" && m.Type == VoidClass ).ForEach( m => m.Type = GetClass( "JsString" ) ) ); list.ForEach( t => t.Members.OfType<Method>().Where( m => ( m.Name == "child" || m.Name == "down" || m.Name == "up" ) && m.Type == VoidClass ).ForEach( m => m.Type = GetClass( "Ext.container.AbstractContainer" ) ) ); list.Where( t => t.FullName == "Ext.Action" ).ForEach( t => t.Members.OfType<Method>().Where( m => ( m.Name == "getText" || m.Name == "getIconCls" ) && m.Type == VoidClass ).ForEach( m => m.Type = GetClass( "JsString" ) ) ); list.Where( t => t.FullName == "Ext.AbstractComponent" ).ForEach( t => t.Members.OfType<Method>().Where( m => m.Name == "addChildEls" ).ForEach( m => m.Parameters.Add( new Parameter { Type = GetClass( "object" ), DeclaringClass = t, Name = "args", IsParams = true, Summary = "<param name=\"args\">An object or array describing the child elements of the Component. <see cref=\"Ext.AbstractComponent.childEls\" /></param>" } ) ) ); list.Where( t => t.FullName == "Ext.container.AbstractContainer" ).ForEach( t => t.Members.OfType<Method>().Where( m => m.Name.Equals( "add", StringComparison.Ordinal ) ).ForEach( m => { m.Parameters[ 0 ].IsParams = true; m.Parameters[ 0 ].IsOptional = false; } ) ); list.Where( t => t.FullName == "Ext.data.Store" ).ForEach( t => { t.Members.OfType<Method>().Where( m => m.Name.Equals( "guaranteeRange", StringComparison.Ordinal ) ).ForEach( m => { m.Parameters[ 2 ].IsOptional = true; m.Parameters[ 3 ].IsOptional = true; } ); t.Members.OfType<Method>().Where( m => m.Name.Equals( "loadPage" ) ).ForEach( m => m.Parameters[ 1 ].IsOptional = true ); } ); list.Where( t => t.FullName == "Ext.EventObject" ).ForEach( t => t.Members.OfType<Method>().ForEach( m => m.IsStatic = false ) ); list.Where( t => t.FullName == "Ext.CompositeElement" ).ForEach( t => t.Members.Where( m => m.Name.IsNullOrEmpty() ).ForEach( m => m.Name = "UNKNOWN" ) ); list.ForEach( t => t.Members.OfType<Method>().Where( m => m.Name == "getStore" ).ForEach( m => m.Type = GetClass( "Ext.data.Store" ) ) ); list.Where( t => t.FullName == "Ext.Error" ).ForEach( t => t.BaseClass = null ); list.Where( t => t.IsInterface && t.BaseClass != null ).ForEach( t => t.BaseClass = null ); list.ForEach( t => t.Members.Where( m => m.Name == "isValid" && ( m.Type == null || m.Type == VoidClass ) ).ForEach( m => m.Type = GetClass( "Boolean" ) ) ); list.ForEach( t => t.Members.Where( m => m.Name == "getState" && ( m.Type == null || m.Type == VoidClass ) ).ForEach( m => m.Type = ObjectClass ) ); list.ForEach( t => t.Members.Where( m => m.Name == "getSubTplMarkup" && m.Type == ObjectClass ).ForEach( m => m.Type = GetClass( "JsString" ) ) ); list.ForEach( t => t.Members.Where( m => m.Name == "getInputId" && m.Type == ObjectClass ).ForEach( m => m.Type = GetClass( "JsString" ) ) ); list.ForEach( t => t.Members.Where( m => m.Name == "getFieldLabel" && m.Type == ObjectClass ).ForEach( m => m.Type = GetClass( "JsString" ) ) ); list.Where( t => t.FullName.StartsWith( "Ext.selection" ) ).ForEach( t => t.Members.Where( m => m.Name == "getLastSelected" && m.Type == VoidClass ).ForEach( m => m.Type = GetClass( "Ext.data.Model" ) ) ); list.Where( t => t.Namespace.Equals( "Ext.ux.event", StringComparison.Ordinal ) ).ForEach( t => t.Namespace = "Ext.ux.@event" ); var ceField = GetClass( "Ext.form.field.Field" ); list.ForEach( t => t.Members.Where( m => m.Name == "setValue" && m.Type.Interfaces.Contains( ceField ) ).ForEach( m => m.Type = ceField ) ); list.Where( t => t.BaseClass != null && t.BaseClass.IsInterface ).ForEach( t => { t.Interfaces.Insert( 0, t.BaseClass ); t.BaseClass = null; } ); //Implement missing interface methods list.Where( t => !t.IsInterface && t.Interfaces.Count > 0 ).ForEach( t => t.Interfaces.ForEach( i => i.Members.ForEach( im => { if ( !InterfaceMemberIsImplementedBySelfOrBaseClass( im, t ) ) { var ne = new Element(); if ( im is Method ) { ne = new Method(); ( ne as Method ).Parameters = ( im as Method ).Parameters; ( ne as Method ).ReturnsArray = ( im as Method ).ReturnsArray; ( ne as Method ).IsVirtual = true;//Interface implemented methods are virtual by default. } else if ( im is Property ) { ne = new Property(); } else if ( im is Field ) { ne = new Field(); ( ne as Field ).Initializer = ( im as Field ).Initializer; } ne.Attributes = im.Attributes; ne.DeclaringClass = t; ne.IsNew = im.IsNew; ne.IsOverride = false; ne.IsPrivate = false; ne.IsProtected = false; ne.IsStatic = false; ne.IsVirtual = true; ne.Name = im.Name; ne.Remarks = im.Remarks; ne.Summary = im.Summary; ne.Type = im.Type ?? ObjectClass; t.Members.Add( ne ); } } ) ) ); //Make sure interface implemented methods are public, non static and have proper return type list.Where( t => !t.IsInterface && t.Interfaces.Count > 0 ).ForEach( t => t.Members.ForEach( m => t.Interfaces.ForEach( i => i.Members.Where( im => im.Name.Equals( m.Name, StringComparison.Ordinal ) ).ForEach( im => { var implementedInBase = AnyBaseClassImplements( m ); m.IsPrivate = m.IsProtected = m.IsStatic = false; if ( im is Method && m is Method && ( im as Method ).Parameters.Count == ( m as Method ).Parameters.Count ) { m.Type = im.Type; ( m as Method ).ReturnsArray = ( im as Method ).ReturnsArray; var index = 0; //If this is the only implementation, lets fix parameter types and make it virtual if ( !implementedInBase ) { ( m as Method ).IsVirtual = true; ( im as Method ).Parameters.ForEach( ip => { if ( ( m as Method ).Parameters[ index ].Type != ip.Type ) { ( m as Method ).Parameters[ index ].Type = ip.Type; } index++; } ); } } else if ( !( ( im is Method ) || !( m is Method ) ) ) { m.Type = im.Type; } } ) ) ) ); //list.Where( t => !t.IsInterface && t.Interfaces.Count > 0 ).ForEach( t => t.Members.ForEach( m => t.Interfaces.Where( i => i.Members.Any( im => im.Name.Equals( m.Name, StringComparison.Ordinal ) ) ).ForEach( im => //{ // m.IsPrivate = m.IsProtected = m.IsStatic = false; // m.Type = im.Type; //} ) ) ); var invalidMethods = new List<Method>(); foreach ( var ce in list ) { if ( !ce.IsInterface ) { var ce2 = ce.BaseClass; while ( ce2 != null ) { if ( !ce2.IsInterface ) { ce.Members.ForEach( pe => { var parentM = ce2.Members.FirstOrDefault( t => HasSameNameAndParameterTypes( t, pe ) ); if ( parentM != null ) { if ( parentM.IsVirtual && !pe.IsStatic ) { pe.IsPrivate = parentM.IsPrivate; pe.IsProtected = parentM.IsProtected; pe.IsOverride = true; pe.IsNew = false; } else { pe.IsNew = true; } } } ); } ce2 = ce2.BaseClass; } } foreach ( var me in ce.Members.OfType<Method>().ToList() ) { if ( ce.IsInterface ) { me.IsVirtual = false; } var i1 = me.Parameters.FindIndex( p => p.IsOptional ); var i2 = me.Parameters.FindLastIndex( p => !p.IsOptional ); if ( i2 >= 0 && i1 >= 0 && i2 > i1 ) { //This rarelly happens, so far, only one method and we can get away setting the param to optional. me.Parameters[ i2 ].IsOptional = true; } else if ( me.Parameters.FirstOrDefault( t => t.Name == "*" ) != null ) { invalidMethods.Add( me ); ce.Members.Remove( me );//invalid method prm name } } } File.WriteAllLines( Path.Combine( OutputDir, "InvalidMethods.txt" ), invalidMethods.Select( t => t.DeclaringClass.FullName + ":" + t.Name ).ToArray() ); list.RemoveAll( t => t.Name == "*" ); list.Where( ce => !ce.IsInterface ).ForEach( ce => { var ceCfg = GetClass( ce.FullName + "Config", false ); if ( ceCfg != null ) { var ctors = ce.Members.OfType<Method>().Where( t => t.IsConstructor ).ToList(); if ( ctors.FirstOrDefault( t => t.Parameters.Count == 1 && t.Parameters[ 0 ].Type == ceCfg ) == null ) { ce.Members.Add( new Method { IsConstructor = true, Parameters = new List<Parameter> { new Parameter { Name = "config", Type = ceCfg } } } ); } } if ( !HasEmptyOrDefaultConstructor( ce ) ) ce.Members.Add( new Method { IsConstructor = true } ); if ( GenerateParamsConstructor ) { ce.Members.Add( new Method { IsConstructor = true, Parameters = new List<Parameter> { new Parameter { Name = "args", IsParams = true, Type = GetClass( "object" ) } } } ); } } ); list.ForEach( t => t.Members.Where( m => m.DeclaringClass == null ).ForEach( m => m.DeclaringClass = t ) ); list.Where( t => t.IsInterface && t.Members.OfType<Method>().Any( m => m.IsConstructor ) ).ForEach( t => { var toRemove = new List<Element>(); t.Members.ForEach( toRemove.Add ); toRemove.ForEach( r => t.Members.Remove( r ) ); } ); //Remove members already implemented in any base class list.Where( t => !t.IsInterface && t.BaseClass != null ).ForEach( t => { var toRemove = new List<Element>(); t.Members.ForEach( m => { if ( AnyBaseClassImplements( m ) ) { if ( m is Method ) { var mt = m as Method; if ( !mt.IsOverride ) { toRemove.Add( m ); } else { list.ForEach( ty => { var parentM = ty.Members.OfType<Method>().FirstOrDefault( me => me.Name != null && me.Name.Equals( mt.Name ) ); if ( parentM != null && HasSameNameAndParameterTypes( mt, parentM ) ) { toRemove.Add( m ); } } ); } } else { toRemove.Add( m ); } } } ); toRemove.ForEach( m => t.Members.Remove( m ) ); } ); if ( UseProperCaseForPublicMethods ) { list.ForEach( t => t.Members.OfType<Method>().Where( m => !m.IsConstructor && ( !m.IsPrivate || t.IsInterface ) ).ForEach( m => { var needsExtraRename = false; m.Name = m.Name.Trim( '@' ); var newName = m.Name.Substring( 0, 1 ).ToUpperInvariant() + m.Name.Substring( 1 ); if ( m.DeclaringClass != null && newName.Equals( m.DeclaringClass.Name, StringComparison.Ordinal ) ) { needsExtraRename = true; } if ( !needsExtraRename && t.SubClasses.Any( s => s.Name.Equals( newName ) ) ) { needsExtraRename = true; } if ( needsExtraRename ) { newName = "Mt" + newName; m.Remarks = "This method was renamed from: " + m.Name + " to: Mt" + m.Name + ", this is only for C# code, in Javascript it will appear with the original 'Ext' name (" + m.Name + ")"; } if ( m.Attributes.Count == 0 ) { m.Attributes.Add( CreateNameAttribute( "JsMethod", m.Name ) ); } FixNewName( list, m, newName ); m.Name = newName; } ) ); } return FixSameNameAsNamespace( list ); }
private static Element Clone( Element el, object newPropertys = null ) { Element newEl = null; if ( el is Method ) { newEl = new Method(); } else if ( el is Property ) { newEl = new Property(); } else if ( el is Field ) { newEl = new Field(); } el.GetType().GetProperties().ForEach( p => { var val = p.GetValue( el, new object[] { } ); newEl.GetType().GetProperty( p.Name ).SetValue( newEl, val, new object[] { } ); } ); return newEl; }