Browse Source

More work on reflection.

Mark Sibly 7 years ago
parent
commit
e248dae442

+ 25 - 0
modules/monkey/native/bbdeclinfo_r.h

@@ -432,6 +432,31 @@ template<class R,class...A> bbDeclInfo *bbFunctionDecl( bbString name,R (*ptr)(A
 	return new bbFunctionDeclInfo<R,A...>( name,meta,ptr );
 }
 
+// ***** Literal *****
+//
+template<class T> struct bbLiteralDeclInfo : public bbDeclInfo{
+
+	T value;
+	
+	bbLiteralDeclInfo( bbString name,bbString meta,T value ):value( value ){
+		this->name=name;
+		this->meta=meta;
+		this->kind="Const";
+		this->type=bbGetType<T>();
+		this->flags=BB_DECL_GETTABLE;
+	}
+	
+	bbVariant get( bbVariant instance ){
+	
+		return bbVariant( value );
+	}
+};
+
+template<class T> bbDeclInfo *bbLiteralDecl( bbString name,T value,bbString meta="" ){
+
+	return new bbLiteralDeclInfo<T>( name,meta,value );
+}
+
 template<class...Ds> bbDeclInfo **bbMembers( Ds...ds ){
 
 	int n=sizeof...(Ds);

+ 1 - 1
modules/monkey/native/bbtypeinfo.cpp

@@ -1,5 +1,5 @@
 
-#include "bbtypeinfo.h"
+#include "bbtypeinfo_r.h"
 #include "bbdeclinfo.h"
 
 namespace{

+ 9 - 3
modules/monkey/native/bbtypeinfo.h

@@ -7,7 +7,7 @@
 #include "bbarray.h"
 #include "bbfunction.h"
 
-struct bbClassTypeInfo;
+//struct bbClassTypeInfo;
 
 struct bbTypeInfo{
 
@@ -147,6 +147,7 @@ template<class...A> struct bbFunctionTypeInfo<void,A...> : public bbTypeInfo{
 
 };
 
+/*
 struct bbClassDecls{
 
 	bbClassDecls *_succ;
@@ -185,6 +186,7 @@ struct bbClassTypeInfo : public bbTypeInfo{
 	
 	static bbClassTypeInfo *getNamespace( bbString name );
 };
+*/
 
 #define BB_GETTYPE_DECL( TYPE ) bbTypeInfo *bbGetType( TYPE const& );
 
@@ -207,12 +209,16 @@ inline bbTypeInfo *bbGetType( bbObject* const& ){
 	return &bbObjectTypeInfo::instance;
 }
 
-template<class T> bbTypeInfo *bbGetType( T const& ){
-	static bbUnknownTypeInfo info;
+template<class T> bbTypeInfo *bbGetUnknownType(){
+ 	static bbUnknownTypeInfo info;
 	
 	return &info;
 }
 
+template<class T> bbTypeInfo *bbGetType( T const& ){
+	return bbGetUnknownType<T>();
+}
+
 template<class T> bbTypeInfo *bbGetType( T* const& ){
 	static bbPointerTypeInfo<T> info;
 	

+ 55 - 0
modules/monkey/native/bbtypeinfo_r.h

@@ -0,0 +1,55 @@
+
+#ifndef BB_TYPEINFO_R_H
+#define BB_TYPEINFO_R_H
+
+#include "bbtypeinfo.h"
+
+struct bbClassTypeInfo;
+
+struct bbClassDecls{
+
+	bbClassDecls *_succ;
+	bbDeclInfo **_decls=0;
+	int _numDecls=0;
+
+	bbClassDecls( bbClassTypeInfo *classType );
+	
+	bbDeclInfo **decls();
+	
+	int numDecls();
+	
+	virtual bbDeclInfo **initDecls(){
+		return 0;
+	}
+};
+
+struct bbClassTypeInfo : public bbTypeInfo{
+
+	bbClassTypeInfo *_succ=0;
+	bbClassDecls *_decls=0;
+	
+	bbClassTypeInfo( bbString name,bbString kind );
+	
+	bbTypeInfo *superType();
+	
+	bbArray<bbTypeInfo*> interfaceTypes();
+	
+	bbBool extendsType( bbTypeInfo *type );
+	
+	bbArray<bbDeclInfo*> getDecls();
+	
+	bbString toString(){
+		return kind+" "+name;
+	}
+	
+	static bbClassTypeInfo *getNamespace( bbString name );
+};
+
+struct bbEnumTypeInfo : public bbClassTypeInfo{
+	
+	bbEnumTypeInfo( bbString name ):bbClassTypeInfo( name,"Enum" ){
+	}
+};
+
+#endif
+

+ 32 - 0
modules/reflection/tests/alltypes.monkey2

@@ -0,0 +1,32 @@
+
+'Ok, not quite *all* types, but getting there...
+'
+#Import "<std>"
+#Import "<mojo>"
+#Import "<mojox>"
+#Import "<mojo3d>"
+
+#Reflect std..
+#Reflect mojo..
+#Reflect mojox..
+#Reflect mojo3d..
+
+Function Main()
+	
+	'This is all reflection.DebugTypes really does-ish...
+	'
+	For Local type:=Eachin TypeInfo.GetTypes()
+		
+		Print type
+		
+		For Local decl:=Eachin type.GetDecls()
+			
+			Print " "+decl
+		Next
+		
+		Print ""
+	End
+	
+	Print "Done!"
+
+End

+ 37 - 0
modules/reflection/tests/enum.monkey2

@@ -0,0 +1,37 @@
+
+Namespace test
+
+#Reflect test
+
+Enum E
+	A,B,C
+End
+
+Function Test( e:E )
+	
+	Print "e="+Int( e )
+End
+
+Function Main()
+	
+	Print Typeof<E>
+
+	Local e:=E.A
+	
+	Print Typeof( e )
+	
+	Local type:=Typeof( e )
+	
+	For Local decl:=Eachin type.GetDecls()
+		
+		Local e:=Cast<E>( decl.Get( Null ) )
+		
+		Print decl.Name+"="+Int( e )
+	
+	Next
+	
+	Local rtest:=TypeInfo.GetType( "test" ).GetDecl( "Test" )
+	
+	rtest.Invoke( Null,New Variant[]( E.C ) )
+
+End

+ 15 - 15
modules/reflection/tests/property.monkey2

@@ -2,21 +2,13 @@
 Namespace test
 
 #Import "<reflection>"
-#Import "<std>"
-#Import "<mojo>"
-#Import "<mojox>"
-#Import "<mojo3d>"
 
 #Reflect test
-#Reflect std
-#Reflect mojo
-#Reflect mojo3d
-#Reflect mojox
 
 Using reflection..
 Using std..
 
-Class E
+Class C
 	
 	Field _name:="Brian"
 	
@@ -33,7 +25,7 @@ Class E
 	
 End
 
-Class E Extension
+Class C Extension
 	
 	Property Position:Vec3f()
 		
@@ -47,15 +39,23 @@ Class E Extension
 End
 
 Function Main()
+	
+	Local c:=New C
+	
+	Print "Name="+c.Name
 
-	Local e:=New E
+	'set name using reflection	
+	SetProperty( "Name",c,"Douglas" )
 	
-	SetProperty( "Name",e,"Douglas" )
+	'get name using reflection
+	Print "Name="+GetProperty<String>( "Name",c )
 	
-	Print GetProperty<String>( "Name",e )
+	Print "Position="+c.Position
 	
-	SetProperty( "Position",e,New Vec3f( 4,5,6 ) )
+	'set position using reflection
+	SetProperty( "Position",c,New Vec3f( 4,5,6 ) )
 	
-	Print GetProperty<Vec3f>( "Position",e )
+	'set position using reflection
+	Print "Position="+GetProperty<Vec3f>( "Position",c )
 	
 End

+ 4 - 2
modules/std/permissions/permissions.monkey2

@@ -121,6 +121,8 @@ Function CheckPermission:Int( permission:String )
 
 End
 
+Alias ResultType:uInt
+
 #rem monkeydoc Request android permissions.
 
 This function is only available on android.
@@ -134,13 +136,13 @@ The permission strings should be in android manifest form, eg: "android.permissi
 If the result is an empty array, the operation was cancelled.
 
 #end
-Function RequestPermissions( permissions:String[],finished:void( results:Int[] ) )
+Function RequestPermissions( permissions:String[],finished:Void( results:ResultType[] ) )
 
 #If __TARGET__="android"
 
 	Init()
 
-	_requests.AddLast( New Request( permissions,finished ) )
+'	_requests.AddLast( New Request( permissions,finished ) )
 	
 	StartNextRequest()
 	

+ 15 - 46
src/mx2cc/test.monkey2

@@ -3,68 +3,37 @@ Namespace test
 
 #Import "<reflection>"
 
-#Import "<mojo3d>"
-#Import "<std>"
-
-Using reflection..
-
-Using std..
-
-#Reflect mojo3d
-#Reflect std
-
 #Reflect test
 
-Class C
+Enum E
+	A,B,C
 End
 
-Class D Extends C
-	
-	Property Position:Vec3f()
+Function Test( e:E )
 	
-		Return New Vec3f(1,2,3)
-	End
+	Print "e="+Int( e )
 End
 
-Class E
-	
-	Field _c:C=New D
-	
-	Field _pos:=New Vec3f( 1,2,3 )
+Function Main()
 	
-	Method GetC:C()
-		
-		Return _c
-	End
+	Local e:=E.A
 	
-End
-
-Class E Extension
+	Print Typeof( e )
 	
-	Property D:D()
-		
-		Return Cast<D>( GetC() )
-	End
+	Local type:=Typeof( e )
 	
-	Property Position:Vec3f()
+	For Local decl:=Eachin type.GetDecls()
 		
-		Return _pos
-	
-	Setter( pos:Vec3f )
+		Local e:=Cast<E>( decl.Get( Null ) )
 		
-		_pos=pos
-	End
+		Print decl.Name+"="+Int( e )'Cast<Int>( decl.Get( Null ) )
 	
-End
-
-Function Main()
-
-	DebugTypes()
+	Next
 	
-	Local e:=New E
+	Local rtest:=TypeInfo.GetType( "test" ).GetDecl( "Test" )
 	
-	SetProperty( "Position",e,New Vec3f( 4,5,6 ) )
+	rtest.Invoke( Null,New Variant[]( E.C ) )
 	
-	Print GetProperty<Vec3f>( "Position",e )
 	
+
 End

+ 12 - 8
src/mx2cc/translator.monkey2

@@ -332,23 +332,20 @@ Class Translator
 		
 			Local ctype:=TCast<ClassType>( type )
 			If ctype
-		
 				If Included( ctype.transFile ) Continue
 				
 				Local cname:=ClassName( ctype )
 				Emit( "struct "+cname+";" )
 				
 				If GenTypeInfo( ctype ) 
-					Emit( "#ifdef BB_NEWREFLECTION" )
 					If ctype.IsStruct 
-						Emit( "bbTypeInfo *bbGetType( "+cname+" const& );" )
+						Emit( "bbTypeInfo *bbGetType("+cname+" const&);" )
 					Else
-						Emit( "bbTypeInfo *bbGetType( "+cname+"* const& );" )
+						Emit( "bbTypeInfo *bbGetType("+cname+"* const&);" )
 					Endif
-					Emit( "#endif" )
 				Endif
 				
-				If _debug And Not ctype.cdecl.IsExtern
+				If _debug
 					Local tname:=cname
 					If Not ctype.IsStruct tname+="*"
 					Emit( "bbString bbDBType("+tname+"*);" )
@@ -364,8 +361,15 @@ Class Translator
 				
 				Local ename:=EnumName( etype )
 				Emit( "enum class "+ename+";" )
-				Emit( "bbString bbDBType("+ename+"*);" )
-				Emit( "bbString bbDBValue("+ename+"*);" )
+				
+				If GenTypeInfo( etype ) 
+					Emit( "bbTypeInfo *bbGetType("+ename+" const&);" )
+				Endif
+				
+				If _debug
+					Emit( "bbString bbDBType("+ename+"*);" )
+					Emit( "bbString bbDBValue("+ename+"*);" )
+				Endif
 				
 				Continue
 			Endif

+ 108 - 17
src/mx2cc/translator_cpp.monkey2

@@ -45,6 +45,7 @@ Class Translator_CPP Extends Translator
 		Reset()
 	
 		Emit( "#include <bbmonkey.h>" )
+		Emit( "#include <bbtypeinfo_r.h>" )
 		Emit( "#include <bbdeclinfo_r.h>" )
 		Emit( "#if BB_NEWREFLECTION" )
 		Emit( "#include ~q_r.h~q" )
@@ -90,6 +91,14 @@ Class Translator_CPP Extends Translator
 		
 				EmitTypeInfo( fdecl )
 		
+				For Local etype:=Eachin fdecl.enums
+					
+					If Not GenTypeInfo( etype ) Continue
+					
+					EmitTypeInfo( etype )
+				
+				Next
+				
 				For Local ctype:=Eachin fdecl.classes
 				
 					If Not GenTypeInfo( ctype ) Continue
@@ -106,6 +115,14 @@ Class Translator_CPP Extends Translator
 		
 				EmitNullTypeInfo( fdecl )
 		
+				For Local etype:=Eachin fdecl.enums
+					
+					If Not GenTypeInfo( etype ) Continue
+					
+					EmitNullTypeInfo( etype )
+				
+				Next
+				
 				For Local ctype:=Eachin fdecl.classes
 				
 					If Not GenTypeInfo( ctype ) Continue
@@ -130,30 +147,34 @@ Class Translator_CPP Extends Translator
 	Method EmitNullTypeInfo( fdecl:FileDecl )
 		
 	End
+
+	Method EmitNullTypeInfo( etype:EnumType )
+		
+		Local ename:=EnumName( etype )
+		
+		Emit( "bbTypeInfo *bbGetType("+ename+" const&){" )
+		Emit( "return bbGetUnknownType<"+ename+">();" )
+		Emit( "}" )
+	End
 	
 	Method EmitNullTypeInfo( ctype:ClassType )
 
 		Local cname:=ClassName( ctype )
-		Local rname:=""
-		
+
 		If ctype.IsStruct
 			Emit( "bbTypeInfo *bbGetType("+cname+" const&){" )
-			rname="bbVoidTypeInfo"
 		Else
 			Emit( "bbTypeInfo *bbGetType("+cname+"* const&){" )
-			rname="bbObjectTypeInfo"
 		Endif
-						
-		Emit( "return &"+rname+"::instance;" )
+
+		Emit( "return bbGetUnknownType<"+cname+">();" )
 		Emit( "}" )
 		
 		Emit( "bbTypeInfo *"+cname+"::typeof()const{" )
-		Emit( "return &"+rname+"::instance;" )
+		Emit( "return bbGetUnknownType<"+cname+">();" )
 		Emit( "}" )
-		
 	End
 	
-	
 	Method TranslateFile( fdecl:FileDecl )
 	
 		Reset()
@@ -193,10 +214,19 @@ Class Translator_CPP Extends Translator
 
 		EmitBr()
 		For Local etype:=Eachin fdecl.enums
+			
 			Local ename:=EnumName( etype )
+			
 			Emit( "enum class "+ename+";" )
-			Emit( "bbString bbDBType("+ename+"*);" )
-			Emit( "bbString bbDBValue("+ename+"*);" )
+			
+			If GenTypeInfo( etype )
+				Emit( "bbTypeInfo *bbGetType("+ename+" const&);" )
+			Endif
+			
+			If _debug
+				Emit( "bbString bbDBType("+ename+"*);" )
+				Emit( "bbString bbDBValue("+ename+"*);" )
+			Endif
 		Next
 		
 		EmitBr()
@@ -660,9 +690,9 @@ Class Translator_CPP Extends Translator
 		
 		If GenTypeInfo( ctype )
 			If ctype.IsStruct
-				Emit( "bbTypeInfo *bbGetType( "+cname+" const& );" )
+				Emit( "bbTypeInfo *bbGetType("+cname+" const&);" )
 			Else
-				Emit( "bbTypeInfo *bbGetType( "+cname+"* const& );" )
+				Emit( "bbTypeInfo *bbGetType("+cname+"* const&);" )
 			Endif
 		Endif
 		
@@ -937,6 +967,55 @@ Class Translator_CPP Extends Translator
 		
 		Emit( "}_"+tname+";" )
 	End
+	
+	Method EmitTypeInfo( etype:EnumType )
+		
+		UsesRefInfo( etype )
+		
+		Local edecl:=etype.edecl
+		Local ename:=EnumName( etype )
+		Local rname:="e"+ename
+		
+		EmitBr()
+
+		Emit( "struct "+rname+" : public bbEnumTypeInfo{" )
+		
+		Emit( "static "+rname+" instance;" )
+		
+		'struct decls_t
+		Emit( "static struct decls_t : public bbClassDecls{" )
+		
+		Emit( "decls_t():bbClassDecls(&instance){}" )
+		
+		'initDecls()
+		Emit( "bbDeclInfo **initDecls(){" )
+		
+		Local decls:=New StringStack
+		
+		For Local it:=Eachin etype.scope.nodes
+			
+			decls.Add( "bbLiteralDecl<"+ename+">(~q"+it.Key+"~q,("+ename+")"+Cast<LiteralValue>( it.Value ).value+")" )
+		Next
+
+		Emit( "return bbMembers("+decls.Join( "," )+");" )
+		Emit( "}" )
+		Emit( "}decls;" )
+		
+		'Ctor
+		Emit( rname+"():bbEnumTypeInfo(~q"+etype.Name+"~q){" )
+		Emit( "}" )
+		
+		Emit( "};" )
+		
+		Emit( rname+" "+rname+"::instance;" )
+		Emit( rname+"::decls_t "+rname+"::decls;" )
+		
+		EmitBr()
+		
+		Emit( "bbTypeInfo *bbGetType("+ename+" const&){" )
+		Emit( "return &"+rname+"::instance;" )
+		Emit( "}" )
+	End
 
 	Method EmitTypeInfo( ctype:ClassType )
 	
@@ -1101,7 +1180,7 @@ Class Translator_CPP Extends Translator
 		
 		Emit( "}decls;" )
 
-		'Ctor		
+		'Ctor
 		Local name:=ctype.Name
 		Local kind:=cdecl.kind.Capitalize()
 		If cdecl.IsExtension 
@@ -1145,9 +1224,9 @@ Class Translator_CPP Extends Translator
 		EmitBr()
 
 		If ctype.IsStruct
-			Emit( "bbTypeInfo *bbGetType( "+cname+" const& ){" )
+			Emit( "bbTypeInfo *bbGetType("+cname+" const&){" )
 		Else
-			Emit( "bbTypeInfo *bbGetType( "+cname+"* const& ){" )
+			Emit( "bbTypeInfo *bbGetType("+cname+"* const&){" )
 		Endif
 
 		Emit( "return &"+rcname+"::instance;" )
@@ -2384,13 +2463,24 @@ Function GenTypeInfo:Bool( func:FuncValue )
 	Return True
 End
 
+Function GenTypeInfo:Bool( etype:EnumType )
+
+	'disable native enums	
+	If etype.edecl.IsExtern Return False
+	
+	'disable enums in generic scopes
+	If etype.scope.IsInstanceOf Return False
+	
+	Return True
+End
+
 Function GenTypeInfo:Bool( ctype:ClassType )
 
 	'disable native types
 	If ctype.ExtendsVoid Return False
 	
 	'disable generic type instances (for now - almost working!)
-	If ctype.types Return False
+	If ctype.types Or ctype.scope.IsInstanceOf Return False
 
 	'disable structs
 	'If ctype.IsStruct Return False
@@ -2400,3 +2490,4 @@ Function GenTypeInfo:Bool( ctype:ClassType )
 	
 	Return True
 End
+