Browse Source

added abstract support to documentation generation

Nicolas Cannasse 13 years ago
parent
commit
e43bef02ad

+ 3 - 1
genxml.ml

@@ -194,7 +194,9 @@ let gen_type_decl com pos t =
 	| TAbstractDecl a ->
 	| TAbstractDecl a ->
 		let doc = gen_doc_opt a.a_doc in
 		let doc = gen_doc_opt a.a_doc in
 		let meta = gen_meta a.a_meta in
 		let meta = gen_meta a.a_meta in
-		node "abstract" (gen_type_params pos a.a_private (tpath t) a.a_types a.a_pos m) ([] @ doc @ meta)
+		let sub = (match a.a_sub with [] -> [] | l -> node "sub" [] [List.map gen_type l]) in
+		let super = (match a.a_super with [] -> [] | l -> node "super" [] [List.map gen_type l]) in		
+		node "abstract" (gen_type_params pos a.a_private (tpath t) a.a_types a.a_pos m) (sub @ super @ doc @ meta)
 
 
 let att_str att =
 let att_str att =
 	String.concat "" (List.map (fun (a,v) -> Printf.sprintf " %s=\"%s\"" a v) att)
 	String.concat "" (List.map (fun (a,v) -> Printf.sprintf " %s=\"%s\"" a v) att)

+ 14 - 0
std/haxe/rtti/CType.hx

@@ -36,6 +36,7 @@ enum CType {
 	CFunction( args : List<{ name : String, opt : Bool, t : CType }>, ret : CType );
 	CFunction( args : List<{ name : String, opt : Bool, t : CType }>, ret : CType );
 	CAnonymous( fields : List<ClassField> );
 	CAnonymous( fields : List<ClassField> );
 	CDynamic( ?t : CType );
 	CDynamic( ?t : CType );
+	CAbstract( name : Path, params : List<CType> );
 }
 }
 
 
 typedef PathParams = {
 typedef PathParams = {
@@ -109,11 +110,17 @@ typedef Typedef = {> TypeInfos,
 	var types : Hash<CType>; // by platform
 	var types : Hash<CType>; // by platform
 }
 }
 
 
+typedef Abstractdef = {> TypeInfos,
+	var subs : Array<CType>;
+	var supers : Array<CType>;
+}
+
 enum TypeTree {
 enum TypeTree {
 	TPackage( name : String, full : String, subs : Array<TypeTree> );
 	TPackage( name : String, full : String, subs : Array<TypeTree> );
 	TClassdecl( c : Classdef );
 	TClassdecl( c : Classdef );
 	TEnumdecl( e : Enumdef );
 	TEnumdecl( e : Enumdef );
 	TTypedecl( t : Typedef );
 	TTypedecl( t : Typedef );
+	TAbstractdecl( a : Abstractdef );
 }
 }
 
 
 typedef TypeRoot = Array<TypeTree>
 typedef TypeRoot = Array<TypeTree>
@@ -126,6 +133,7 @@ class TypeApi {
 		case TClassdecl(c): inf = c;
 		case TClassdecl(c): inf = c;
 		case TEnumdecl(e): inf = e;
 		case TEnumdecl(e): inf = e;
 		case TTypedecl(t): inf = t;
 		case TTypedecl(t): inf = t;
+		case TAbstractdecl(a): inf = a;
 		case TPackage(_,_,_): throw "Unexpected Package";
 		case TPackage(_,_,_): throw "Unexpected Package";
 		}
 		}
 		return inf;
 		return inf;
@@ -182,6 +190,12 @@ class TypeApi {
 				return name == name2 && leq(typeEq,params,params2);
 				return name == name2 && leq(typeEq,params,params2);
 			default:
 			default:
 			}
 			}
+		case CAbstract(name,params):
+			switch( t2 ) {
+			case CAbstract(name2,params2):
+				return name == name2 && leq(typeEq,params,params2);
+			default:
+			}
 		case CTypedef(name,params):
 		case CTypedef(name,params):
 			switch( t2 ) {
 			switch( t2 ) {
 			case CTypedef(name2,params2):
 			case CTypedef(name2,params2):

+ 0 - 339
std/haxe/rtti/HtmlEditor.hx

@@ -1,339 +0,0 @@
-/*
- * Copyright (c) 2006-2009, The haXe Project Contributors
- * All rights reserved.
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- *   - Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   - Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE HAXE PROJECT CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE HAXE PROJECT CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- */
-package haxe.rtti;
-import haxe.rtti.CType;
-
-class HtmlEditor {
-
-	static var UID = 0;
-
-	var id : String;
-	var types : Hash<TypeTree>;
-	var buf : StringBuf;
-	var nfields : Int;
-
-	public function new() {
-		types = new Hash();
-	}
-
-	public function add( tl : TypeRoot ) {
-		for( t in tl )
-			switch(t) {
-			case TPackage(_,_,subs):
-				add(subs);
-			case TClassdecl(c):
-				types.set(c.path,t);
-			case TEnumdecl(e):
-				types.set(e.path,t);
-			case TTypedecl(td):
-				types.set(td.path,t);
-			}
-	}
-
-	public function buildHTML( id : String, v : Dynamic, t : CType ) {
-		this.id = id;
-		nfields = 0;
-		buf = new StringBuf();
-		buildHTMLRec(v,t,false);
-		var str = buf.toString();
-		buf = null;
-		return str;
-	}
-
-	function open(t) {
-		buf.add("<"+t);
-	}
-
-	function close(?t) {
-		buf.add(( t == null ) ? "/>" : "</"+t+">");
-	}
-
-	function genUID() {
-		return "__u"+id+"_"+(UID++);
-	}
-
-	function genFieldName() {
-		return "__f"+id+"_"+(nfields++);
-	}
-
-	function skipField() {
-		nfields++;
-	}
-
-	function attrib(name,value) {
-		buf.add(" "+name+'="'+value+'"');
-	}
-
-	function followTypeDef( name, params : List<CType> ) {
-		var td = types.get(name);
-		if( td == null ) throw "Missing type "+name;
-		if( !params.isEmpty() ) throw "Can't apply parameters";
-		return switch( td ) {
-			case TTypedecl(t): t.type;
-			default: throw "assert";
-		};
-	}
-
-	function getEnum( name ) {
-		var td = types.get(name);
-		if( td == null ) throw "Missing type "+name;
-		return switch( td ) { case TEnumdecl(e): e; default: throw "assert"; };
-	}
-
-	function buildNullField( checked ) {
-		open("input");
-		attrib("name",genFieldName());
-		attrib("class","null");
-		attrib("type","checkbox");
-		if( checked )
-			attrib("checked","checked");
-		close();
-	}
-
-	function buildHTMLRec( v : Dynamic, t : CType, nullable ) {
-		switch( t ) {
-		case CUnknown,CDynamic(_),CFunction(_,_):
-			buf.add("???");
-		case CTypedef(name,params):
-			var t = followTypeDef(name,params);
-			buildHTMLRec(v,t,nullable || name == "Null");
-		case CAnonymous(fl):
-			open("table");
-			attrib("class","anon");
-			buf.add(">");
-			for( f in fl ) {
-				buf.add("<tr><th>");
-				buf.add(f.name);
-				buf.add("</th><td>");
-				buildHTMLRec(Reflect.field(v,f.name),f.type,false);
-				buf.add("</td></tr>");
-			}
-			close("table");
-		case CClass(name,params):
-			if( !params.isEmpty() ) throw "Can't use type parameters";
-			switch( name ) {
-			case "Int":
-				open("input");
-				attrib("name",genFieldName());
-				attrib("class","int");
-				if( v != null )
-					attrib("value",v);
-				close();
-			case "String":
-				if( nullable )
-					buildNullField(v != null);
-				open("input");
-				attrib("name",genFieldName());
-				attrib("class","string");
-				if( v != null )
-					attrib("value",v);
-				close();
-			case "Bool":
-				if( nullable )
-					buildNullField(v != null);
-				open("input");
-				attrib("name",genFieldName());
-				attrib("type","checkbox");
-				if( v )
-					attrib("checked","checked");
-				close();
-			default:
-				throw "Can't edit instances of "+name;
-			}
-		case CEnum(name,params):
-			if( name == "Bool" ) {
-				buildHTMLRec(v,CClass("Bool",params),nullable);
-				return;
-			}
-			if( !params.isEmpty() ) throw "Can't use type parameters";
-			var e = getEnum(name);
-			var js = genUID();
-			open("select");
-			attrib("name",genFieldName());
-			attrib("class","enum");
-			attrib("onchange",js+"(this)");
-			buf.add(">");
-			var current = if( v == null ) null else Type.enumConstructor(v);
-			if( nullable )
-				buf.add("<option value=''>---- NULL ----</option>");
-			var prefix = if( e.constructors.length <= 1 ) "" else e.constructors.first().name;
-			for( c in e.constructors )
-				while( prefix.length > 0 )
-					if( c.name.substr(0,prefix.length) == prefix )
-						break;
-					else
-						prefix = prefix.substr(0,prefix.length-1);
-			for( c in e.constructors ) {
-				open("option");
-				attrib("value",c.name);
-				if( current == c.name )
-					attrib("selected","selected");
-				buf.add(">");
-				buf.add(c.name.substr(prefix.length));
-				close("option");
-			}
-			close("select");
-			var ids = new Array();
-			for( c in e.constructors ) {
-				var id = genUID();
-				ids.push({ id : id, c : c });
-				open("table");
-				attrib("id",id);
-				attrib("class","construct");
-				if( current != c.name )
-					attrib("style","display : none");
-				buf.add(">");
-				if( c.args != null ) {
-					var args = if( current == c.name ) Type.enumParameters(v) else new Array();
-					var i = 0;
-					for( p in c.args ) {
-						buf.add("<tr><th>");
-						buf.add(p.name);
-						buf.add("</th><td>");
-						buildHTMLRec(args[i++],p.t,p.opt);
-						buf.add("</td></tr>");
-					}
-				}
-				close("table");
-			}
-			open("script");
-			attrib("type","text/javascript");
-			buf.add(">");
-			buf.add("function "+js+"(s) {");
-			for( c in ids )
-				buf.add("document.getElementById('"+c.id+"').style.display = (s.value == '"+c.c.name+"')?'':'none';");
-			buf.add("}");
-			close("script");
-		}
-	}
-
-	public function buildObject( id : String, params : Hash<String>, t : CType ) : Dynamic {
-		this.id = id;
-		nfields = 0;
-		return buildObjectRec(params,t,false);
-	}
-
-	function buildObjectRec( params : Hash<String>, t : CType, nullable : Bool ) : Dynamic {
-		return switch( t ) {
-		case CUnknown,CDynamic(_),CFunction(_,_):
-			throw Type.enumConstructor(t)+" can't be built";
-		case CTypedef(name,pl):
-			buildObjectRec(params,followTypeDef(name,pl),nullable || name == "Null");
-		case CAnonymous(fl):
-			var o = {};
-			for( f in fl )
-				Reflect.setField(o,f.name,buildObjectRec(params,f.type,false));
-			o;
-		case CClass(name,_):
-			var v = params.get(genFieldName());
-			var ret : Dynamic;
-			switch( name ) {
-			case "Int":
-				if( v == null || (v == "" && !nullable) )
-					throw "Missing required value";
-				if( !~/^[0-9]+$/.match(v) )
-					throw "Invalid int format '"+v+"'";
-				ret = ( v == "" ) ? null : Std.parseInt(v);
-			case "String":
-				if( nullable ) {
-					var str = params.get(genFieldName());
-					ret = if( v == null && str == "" ) null else str;
-				} else {
-					if( v == null )
-						throw "Missing required value";
-					ret = v;
-				}
-			case "Bool":
-				if( nullable ) {
-					var b = params.exists(genFieldName());
-					ret = if( v == null && !b ) null else b;
-				} else
-					ret = (v != null);
-			default:
-				throw name+" can't be built";
-			}
-			ret;
-		case CEnum(name,_):
-			if( name == "Bool" )
-				buildObjectRec(params,CClass("Bool",new List()),nullable);
-			else {
-				var e = getEnum(name);
-				var v = genFieldName();
-				var current = params.get(v);
-				var value = null;
-				for( c in e.constructors ) {
-					if( c.name == current ) {
-						var args = null;
-						if( c.args != null ) {
-							args = new Array();
-							for( a in c.args )
-								args.push(buildObjectRec(params,a.t,a.opt));
-						}
-						value = Type.createEnum(Type.resolveEnum(name),current,args);
-					} else if( c.args != null ) {
-						for( a in c.args )
-							skipObjectRec(a.t,a.opt);
-					}
-				}
-				if( value == null && !nullable )
-					throw name+" can't be null";
-				value;
-			}
-		};
-	}
-
-	function skipObjectRec( t : CType, nullable ) {
-		switch( t ) {
-		case CUnknown,CDynamic(_),CFunction(_,_):
-			// nothing
-		case CTypedef(name,pl):
-			skipObjectRec(followTypeDef(name,pl),nullable || name == "Null");
-		case CAnonymous(fl):
-			for( f in fl )
-				skipObjectRec(f.type,false);
-		case CEnum(name,_):
-			if( name == "Bool" ) {
-				skipObjectRec(CClass("Bool",new List()),nullable);
-				return;
-			}
-			var e = getEnum(name);
-			skipField();
-			for( c in e.constructors ) {
-				if( c.args == null ) continue;
-				for( a in c.args )
-					skipObjectRec(a.t,a.opt);
-			}
-		case CClass(name,_):
-			switch( name ) {
-			case "Int": skipField();
-			case "String", "Bool":
-				if( nullable ) skipField();
-				skipField();
-			default:
-			}
-		}
-	}
-
-}

+ 61 - 1
std/haxe/rtti/XmlParser.hx

@@ -56,7 +56,8 @@ class XmlParser {
 			case TClassdecl(c):
 			case TClassdecl(c):
 				c.fields = sortFields(c.fields);
 				c.fields = sortFields(c.fields);
 				c.statics = sortFields(c.statics);
 				c.statics = sortFields(c.statics);
-			case TEnumdecl(e):
+			case TEnumdecl(_):
+			case TAbstractdecl(_):
 			case TTypedecl(_):
 			case TTypedecl(_):
 			}
 			}
 	}
 	}
@@ -177,6 +178,21 @@ class XmlParser {
 		return true;
 		return true;
 	}
 	}
 
 
+	function mergeAbstracts( a : Abstractdef, a2 : Abstractdef ) {
+		if( curplatform == null )
+			return false;
+		if( a.subs.length != a2.subs.length || a.supers.length != a2.supers.length )
+			return false;
+		for( i in 0...a.subs.length )
+			if( !TypeApi.typeEq(a.subs[i],a2.subs[i]) )
+				return false;
+		for( i in 0...a.supers.length )
+			if( !TypeApi.typeEq(a.supers[i],a2.supers[i]) )
+				return false;
+		a.platforms.add(curplatform);
+		return true;
+	}
+
 	function merge( t : TypeTree ) {
 	function merge( t : TypeTree ) {
 		var inf = TypeApi.typeInfos(t);
 		var inf = TypeApi.typeInfos(t);
 		var pack = inf.path.split(".");
 		var pack = inf.path.split(".");
@@ -243,6 +259,14 @@ class XmlParser {
 								return;
 								return;
 						default:
 						default:
 						}
 						}
+					case TAbstractdecl(a):
+						switch( t ) {
+						case TAbstractdecl(a2):
+							if( mergeAbstracts(a,a2) )
+								return;
+						default:
+							sameType = false;
+						}
 					case TPackage(_,_,_):
 					case TPackage(_,_,_):
 						sameType = false;
 						sameType = false;
 					}
 					}
@@ -295,6 +319,7 @@ class XmlParser {
 		case "class": TClassdecl(xclass(c));
 		case "class": TClassdecl(xclass(c));
 		case "enum": TEnumdecl(xenum(c));
 		case "enum": TEnumdecl(xenum(c));
 		case "typedef": TTypedecl(xtypedef(c));
 		case "typedef": TTypedecl(xtypedef(c));
+		case "abstract": TAbstractdecl(xabstract(c));
 		default: xerror(c);
 		default: xerror(c);
 		}
 		}
 	}
 	}
@@ -442,6 +467,39 @@ class XmlParser {
 		};
 		};
 	}
 	}
 
 
+	function xabstract( x : Fast ) : Abstractdef {
+		var doc = null;
+		var meta = [], subs = [], supers = [];
+		for( c in x.elements )
+			switch( c.name ) {
+			case "haxe_doc":
+				doc = c.innerData;
+			case "meta":
+				meta = xmeta(c);
+			case "sub":
+				for( t in c.elements )
+					subs.push(xtype(t));
+			case "super":
+				for( t in c.elements )
+					supers.push(xtype(t));
+			default:
+				xerror(c);
+			}
+		return {
+			file : if(x.has.file) x.att.file else null,
+			path : mkPath(x.att.path),
+			module : if( x.has.module ) mkPath(x.att.module) else null,
+			doc : doc,
+			isPrivate : x.x.exists("private"),
+			params : mkTypeParams(x.att.params),
+			platforms : defplat(),
+			meta : meta,
+			subs : subs,
+			supers : supers,
+		};
+	}
+
+
 	function xtypedef( x : Fast ) : Typedef {
 	function xtypedef( x : Fast ) : Typedef {
 		var doc = null;
 		var doc = null;
 		var t = null;
 		var t = null;
@@ -480,6 +538,8 @@ class XmlParser {
 			CClass(mkPath(x.att.path),xtypeparams(x));
 			CClass(mkPath(x.att.path),xtypeparams(x));
 		case "t":
 		case "t":
 			CTypedef(mkPath(x.att.path),xtypeparams(x));
 			CTypedef(mkPath(x.att.path),xtypeparams(x));
+		case "x":
+			CAbstract(mkPath(x.att.path),xtypeparams(x));
 		case "f":
 		case "f":
 			var args = new List();
 			var args = new List();
 			var aname = x.att.a.split(":");
 			var aname = x.att.a.split(":");

+ 18 - 0
std/tools/haxedoc/HtmlPrinter.hx

@@ -166,6 +166,7 @@ class HtmlPrinter {
 			case TClassdecl(c): processClass(c);
 			case TClassdecl(c): processClass(c);
 			case TEnumdecl(e): processEnum(e);
 			case TEnumdecl(e): processEnum(e);
 			case TTypedecl(t): processTypedef(t);
 			case TTypedecl(t): processTypedef(t);
+			case TAbstractdecl(a): processAbstract(a);
 			case TPackage(_,_,_): throw "ASSERT";
 			case TPackage(_,_,_): throw "ASSERT";
 			}
 			}
 			print(head);
 			print(head);
@@ -354,6 +355,21 @@ class HtmlPrinter {
 		print('</dl>');
 		print('</dl>');
 	}
 	}
 
 
+	function processAbstract( a : Abstractdef ) {
+		print('<div class="classname">');
+		if( a.isPrivate )
+			keyword("private");
+		keyword("abstract");
+		print(fmtpath(a.path));
+		if( a.params.length != 0 ) {
+			print("&lt;");
+			print(a.params.join(", "));
+			print("&gt;");
+		}
+		print('</div>');
+		processInfos(a);
+	}
+	
 	function processTypedef(t : Typedef) {
 	function processTypedef(t : Typedef) {
 		print('<div class="classname">');
 		print('<div class="classname">');
 		if( t.isPrivate )
 		if( t.isPrivate )
@@ -430,6 +446,8 @@ class HtmlPrinter {
 			processPath(path,params);
 			processPath(path,params);
 		case CTypedef(path,params):
 		case CTypedef(path,params):
 			processPath(path,params);
 			processPath(path,params);
+		case CAbstract(path,params):
+			processPath(path,params);
 		case CFunction(args,ret):
 		case CFunction(args,ret):
 			if( args.isEmpty() ) {
 			if( args.isEmpty() ) {
 				processPath("Void");
 				processPath("Void");

+ 4 - 5
std/tools/haxedoc/haxedoc.hxml

@@ -1,5 +1,4 @@
-# haxedoc
--neko haxedoc.n
--main tools.haxedoc.Main
--cmd nekotools boot haxedoc.n
--D haxe3
+-neko haxedoc.n
+-main tools.haxedoc.Main
+-D haxe3
+-cmd "nekotools boot haxedoc.n"

+ 0 - 9
std/tools/haxedoc/haxedoc.hxp

@@ -1,9 +0,0 @@
-<haxe selected="0">
-  <output name="haxedoc" mode="neko" out="haxedoc.n" class="tools.haxedoc.Main" lib="" cmd="" main="True" debug="False">-cmd nekotools boot haxedoc.n</output>
-  <files path="/">
-    <file path="HtmlPrinter.hx" />
-    <file path="Main.hx" />
-    <file path="..\..\haxe\rtti\Type.hx" />
-    <file path="..\..\haxe\rtti\XmlParser.hx" />
-  </files>
-</haxe>

+ 2 - 2
std/tools/haxelib/Main.hx

@@ -298,7 +298,7 @@ class Main {
 		var pass2 = param("Confirm",true);
 		var pass2 = param("Confirm",true);
 		if( pass != pass2 )
 		if( pass != pass2 )
 			throw "Password does not match";
 			throw "Password does not match";
-		pass = haxe.Md5.encode(pass);
+		pass = haxe.crypto.Md5.encode(pass);
 		site.register(name,pass,email,fullname);
 		site.register(name,pass,email,fullname);
 		return pass;
 		return pass;
 	}
 	}
@@ -317,7 +317,7 @@ class Main {
 		} else {
 		} else {
 			if( infos.developers.length > 1 )
 			if( infos.developers.length > 1 )
 				user = param("User");
 				user = param("User");
-			password = haxe.Md5.encode(param("Password",true));
+			password = haxe.crypto.Md5.encode(param("Password",true));
 			if( !site.checkPassword(user,password) )
 			if( !site.checkPassword(user,password) )
 				throw "Invalid password for "+user;
 				throw "Invalid password for "+user;
 		}
 		}