Ver código fonte

[cpp] Add fileXml meta for injecting attributes into the Build.xml file elements. Add stackOnly meta for extern classes that must have destructors called. Make spaces in native names work again. Add some initial support fot std::string classes

Hugh 9 anos atrás
pai
commit
7b114eab55

+ 40 - 19
src/generators/gencpp.ml

@@ -492,13 +492,6 @@ List.filter (function (t,pl) ->
 );;
 
 
-
-let rec is_function_expr expr =
-   match expr.eexpr with
-   | TParenthesis expr | TMeta(_,expr) -> is_function_expr expr
-   | TFunction _ -> true
-   | _ -> false;;
-
 let is_var_field field =
    match field.cf_kind with
    | Var _ -> true
@@ -1959,6 +1952,14 @@ let cpp_debug_var_visible var =
 ;;
 
 
+let only_stack_access ctx haxe_type = 
+   let tcpp = cpp_type_of ctx haxe_type in
+   match tcpp with
+   | TCppInst(klass) -> has_meta_key klass.cl_meta Meta.StackOnly
+   | _ -> false;
+;;
+ 
+
 
 let cpp_member_name_of member =
    let rename = get_meta_string member.cf_meta Meta.Native in
@@ -2569,6 +2570,7 @@ let gen_type ctx haxe_type =
 ;;
 
 
+
 let gen_cpp_ast_expression_tree ctx class_name func_name function_args injection tree =
    let writer = ctx.ctx_writer in
    let out = ctx.ctx_output in
@@ -2713,9 +2715,14 @@ let gen_cpp_ast_expression_tree ctx class_name func_name function_args injection
               gen expr; out (operator ^ (cpp_member_name_of field) );
          | FuncStatic(clazz,_,field) ->
               let rename = get_meta_string field.cf_meta Meta.Native in
-              if rename<>"" then
+              if rename<>"" then begin
+                 (* This is the case if you use @:native('new foo').  c++ wil group the space undesirably *)
+                 if String.contains rename ' ' then begin
+                    out "(";
+                    closeCall := ")"
+                 end;
                  out rename
-              else
+              end else
                  (out (cpp_class_name clazz); out ("::" ^ (cpp_member_name_of field) ))
 
          | FuncFromStaticFunction ->
@@ -3493,8 +3500,12 @@ let gen_member_def ctx class_def is_static is_interface field =
          (* Variable access *)
       | _ ->
          (* Variable access *)
-         gen_type ctx field.cf_type;
-         output (" " ^ remap_name ^ ";\n" );
+         let tcpp = cpp_type_of ctx field.cf_type in
+         let tcppStr = tcpp_to_string tcpp in
+         if not is_static && only_stack_access ctx field.cf_type then
+            error ("Variables of type " ^ tcppStr ^ " may not be used as members") field.cf_pos;
+
+         output (tcppStr ^ " " ^ remap_name ^ ";\n" );
 
          (* Add a "dyn" function for variable to unify variable/function access *)
          (match follow field.cf_type with
@@ -5042,6 +5053,7 @@ let generate_class_files baseCtx super_deps constructor_deps class_def inScripta
             (if class_def.cl_interface && nativeGen then "virtual " else "" ) ^ name, name
       | None when nativeGen && class_def.cl_interface  -> "virtual hx::NativeInterface", "hx::NativeInterface"
       | None when class_def.cl_interface -> "hx::Interface", "hx::Interface"
+      | None when nativeGen -> "", ""
       | None -> "hx::Object", "hx::Object"
       in
    let output_h = (h_file#write) in
@@ -5282,9 +5294,11 @@ let write_resources common_ctx =
 let write_build_data common_ctx filename classes main_deps boot_deps build_extra extern_src exe_name =
    let buildfile = open_out filename in
    let include_prefix = get_include_prefix common_ctx true in
-   let add_class_to_buildfile class_path deps  =
+   let add_class_to_buildfile class_path deps fileXml =
       let cpp = (join_class_path class_path "/") ^ (source_file_extension common_ctx) in
-      output_string buildfile ( "  <file name=\"src/" ^ cpp ^ "\">\n" );
+      output_string buildfile ( "  <file name=\"src/" ^ cpp ^ "\" ");
+      if fileXml<>"" then output_string buildfile fileXml;
+      output_string buildfile (">\n" );
       let project_deps = List.filter (fun path -> not (is_internal_class path) ) deps in
       List.iter (fun path-> output_string buildfile ("   <depend name=\"" ^
       ( match path with
@@ -5293,7 +5307,14 @@ let write_build_data common_ctx filename classes main_deps boot_deps build_extra
       ^ "\"/>\n") ) project_deps;
       output_string buildfile ( "  </file>\n" )
    in
-   let add_classdef_to_buildfile (class_path, deps, _)  = add_class_to_buildfile class_path deps in
+   let add_classdef_to_buildfile (class_path, deps, object_def )  =
+      let fileXml = match object_def with
+         | TClassDecl class_def -> get_meta_string class_def.cl_meta Meta.FileXml
+         | TEnumDecl enum_def -> get_meta_string enum_def.e_meta Meta.FileXml
+         | _ -> ""
+      in
+      add_class_to_buildfile class_path deps fileXml
+   in
 
    output_string buildfile "<xml>\n";
    output_string buildfile ("<set name=\"HXCPP_API_LEVEL\" value=\"" ^
@@ -5301,17 +5322,17 @@ let write_build_data common_ctx filename classes main_deps boot_deps build_extra
    output_string buildfile "<files id=\"haxe\">\n";
    output_string buildfile "<compilerflag value=\"-Iinclude\"/>\n";
    List.iter add_classdef_to_buildfile classes;
-   add_class_to_buildfile ( [] , "__boot__")  boot_deps;
-   add_class_to_buildfile ( [] , "__files__")  [];
-   add_class_to_buildfile ( [] , "__resources__")  [];
+   add_class_to_buildfile ( [] , "__boot__")  boot_deps "";
+   add_class_to_buildfile ( [] , "__files__")  [] "";
+   add_class_to_buildfile ( [] , "__resources__")  [] "";
    output_string buildfile "</files>\n";
    output_string buildfile "<files id=\"__lib__\">\n";
    output_string buildfile "<compilerflag value=\"-Iinclude\"/>\n";
-   add_class_to_buildfile ( [] , "__lib__") main_deps;
+   add_class_to_buildfile ( [] , "__lib__") main_deps "";
    output_string buildfile "</files>\n";
    output_string buildfile "<files id=\"__main__\">\n";
    output_string buildfile "<compilerflag value=\"-Iinclude\"/>\n";
-   add_class_to_buildfile  ( [] , "__main__") main_deps;
+   add_class_to_buildfile  ( [] , "__main__") main_deps "";
    output_string buildfile "</files>\n";
    output_string buildfile "<files id=\"__resources__\">\n";
    let idx = ref 0 in

+ 3 - 1
src/syntax/ast.ml

@@ -73,6 +73,7 @@ module Meta = struct
 		| Extern
 		| FakeEnum
 		| File
+		| FileXml
 		| Final
 		| Fixed
 		| FlatEnum
@@ -159,6 +160,7 @@ module Meta = struct
 		| SkipReflection
 		| Sound
 		| SourceFile
+		| StackOnly
 		| StoredTypedExpr
 		| Strict
 		| Struct
@@ -929,4 +931,4 @@ module Expr = struct
 	let ensure_block e = match fst e with
 		| EBlock _ -> e
 		| _ -> (EBlock [e],pos e)
-end
+end

+ 2 - 0
src/typing/common.ml

@@ -400,6 +400,7 @@ module MetaInfo = struct
 		| Extern -> ":extern",("Marks the field as extern so it is not generated",[UsedOn TClassField])
 		| FakeEnum -> ":fakeEnum",("Treat enum as collection of values of the specified type",[HasParam "Type name";UsedOn TEnum])
 		| File -> ":file",("Includes a given binary file into the target Swf and associates it with the class (must extend flash.utils.ByteArray)",[HasParam "File path";UsedOn TClass;Platform Flash])
+		| FileXml -> ":fileXml",("Include xml attribute snippet in Build.xml entry for file",[UsedOn TClass;Platform Cpp])
 		| Final -> ":final",("Prevents a class from being extended",[UsedOn TClass])
 		| Fixed -> ":fixed",("Delcares an anonymous object to have fixed fields",[ (*UsedOn TObjectDecl(_)*)])
 		| FlatEnum -> ":flatEnum",("Internally used to mark an enum as being flat, i.e. having no function constructors",[UsedOn TEnum; Internal])
@@ -482,6 +483,7 @@ module MetaInfo = struct
 		| RuntimeValue -> ":runtimeValue",("Marks an abstract as being a runtime value",[UsedOn TAbstract])
 		| SelfCall -> ":selfCall",("Translates method calls into calling object directly",[UsedOn TClassField; Platform Js])
 		| Setter -> ":setter",("Generates a native setter function on the given field",[HasParam "Class field name";UsedOn TClassField;Platform Flash])
+		| StackOnly -> ":stackOnly",("Instances of this type can only appear on the stack",[Platform Cpp])
 		| StoredTypedExpr -> ":storedTypedExpr",("Used internally to reference a typed expression returned from a macro",[Internal])
 		| SkipCtor -> ":skipCtor",("Used internally to generate a constructor as if it were a native type (no __hx_ctor)",[Platforms [Java;Cs]; Internal])
 		| SkipReflection -> ":skipReflection",("Used internally to annotate a field that shouldn't have its reflection data generated",[Platforms [Java;Cs]; UsedOn TClassField; Internal])

+ 3 - 0
std/cpp/NativeString.hx

@@ -32,5 +32,8 @@ extern class NativeString {
 	public static inline function fromPointer(inPtr:ConstPointer<Char> ) : String {
       return untyped __global__.String(inPtr.ptr);
    }
+
+   @:native("_hx_string_create")
+	public static function fromPointerLen(inPtr:ConstPointer<Char>, len:Int ) : String;
 }
 

+ 22 - 0
std/cpp/StdString.hx

@@ -0,0 +1,22 @@
+package cpp;
+
+using cpp.NativeString;
+
+@:native("hx::StdString")
+@:include("hx/StdString.h")
+@:stackOnly
+@:structAccess
+extern class StdString extends StdStringRef
+{
+   @:extern @:native("std::string::npos")
+   public static var npos(default,null):Int;
+
+   //public function new(inData:StdStringData);
+
+   @:native("hx::StdString")
+   static public function ofString(s:String) : StdString;
+   //public function toString():String;
+   //public function find(s:String):Int;
+   //public function substr(pos:Int, len:Int):StdString;
+}
+

+ 17 - 0
std/cpp/StdStringRef.hx

@@ -0,0 +1,17 @@
+package cpp;
+
+using cpp.NativeString;
+
+@:native("hx::StdString const &")
+@:include("hx/StdString.h")
+@:structAccess
+extern class StdStringRef
+{
+   public function c_str() : ConstPointer<Char>;
+   public function size() : Int;
+   public function find(s:String):Int;
+   public function substr(pos:Int, len:Int):StdString;
+   public function toString():String;
+   public function toStdString():StdString;
+}
+