Browse Source

+ support for nested Java classes
o tobjectdef.jvm_full_typename() now gets an extra parameter to determine
whether or not the package name should be prepended, so it can be easily
used to generate the name of the .j file and of the class name inside it

git-svn-id: branches/jvmbackend@18384 -

Jonas Maebe 14 years ago
parent
commit
be4a27657b
5 changed files with 65 additions and 23 deletions
  1. 40 11
      compiler/agjasmin.pas
  2. 1 1
      compiler/jvm/njvmcal.pas
  3. 2 2
      compiler/jvmdef.pas
  4. 3 3
      compiler/pdecobj.pas
  5. 19 6
      compiler/symdef.pas

+ 40 - 11
compiler/agjasmin.pas

@@ -54,6 +54,7 @@ interface
         function VisibilityToStr(vis: tvisibility): string;
         function VisibilityToStr(vis: tvisibility): string;
         function MethodDefinition(pd: tprocdef): string;
         function MethodDefinition(pd: tprocdef): string;
         function FieldDefinition(sym: tabstractvarsym): string;
         function FieldDefinition(sym: tabstractvarsym): string;
+        function InnerObjDef(obj: tobjectdef): string;
 
 
         procedure WriteProcDef(pd: tprocdef);
         procedure WriteProcDef(pd: tprocdef);
         procedure WriteFieldSym(sym: tabstractvarsym);
         procedure WriteFieldSym(sym: tabstractvarsym);
@@ -433,7 +434,7 @@ implementation
             case obj.objecttype of
             case obj.objecttype of
               odt_javaclass:
               odt_javaclass:
                 begin
                 begin
-                  AsmWriteLn('.class '+obj.objextname^);
+                  AsmWriteLn('.class '+obj.jvm_full_typename(false));
                   superclass:=obj.childof;
                   superclass:=obj.childof;
                 end;
                 end;
               odt_interfacejava:
               odt_interfacejava:
@@ -466,6 +467,13 @@ implementation
                     AsmWriteln(intf.objextname^);
                     AsmWriteln(intf.objextname^);
                   end;
                   end;
               end;
               end;
+            { in case of nested class: relation to parent class }
+            if obj.owner.symtabletype=objectsymtable then
+              AsmWriteln(InnerObjDef(obj));
+            { all all nested classes }
+            for i:=0 to obj.symtable.deflist.count-1 do
+              if is_java_class_or_interface(tdef(obj.symtable.deflist[i])) then
+                AsmWriteln(InnerObjDef(tobjectdef(obj.symtable.deflist[i])));
           end;
           end;
         AsmLn;
         AsmLn;
       end;
       end;
@@ -525,16 +533,7 @@ implementation
         else
         else
           AsmClear;
           AsmClear;
 
 
-        AsmFileName:=obj.objextname^;
-        st:=obj.owner;
-        while assigned(st) and
-              (st.symtabletype=objectsymtable) do
-          begin
-            { nested classes are named as "OuterClass$InnerClass" }
-            enclosingobj:=tobjectdef(st.defowner);
-            AsmFileName:=enclosingobj.objextname^+'$'+AsmFileName;
-            st:=enclosingobj.owner;
-          end;
+        AsmFileName:=obj.jvm_full_typename(false);
         AsmFileName:=Path+FixFileName(AsmFileName)+target_info.asmext;
         AsmFileName:=Path+FixFileName(AsmFileName)+target_info.asmext;
         AsmCreate(cut_normal);
         AsmCreate(cut_normal);
       end;
       end;
@@ -611,6 +610,36 @@ implementation
       end;
       end;
 
 
 
 
+    function TJasminAssembler.InnerObjDef(obj: tobjectdef): string;
+      var
+        kindname: string;
+      begin
+        if obj.owner.defowner.typ<>objectdef then
+          internalerror(2011021701);
+        case obj.objecttype of
+          odt_javaclass:
+            kindname:='class ';
+          odt_interfacejava:
+            kindname:='interface ';
+          else
+            internalerror(2011021702);
+        end;
+        result:=
+          '.inner '+
+          kindname+
+          VisibilityToStr(obj.typesym.visibility)+
+          { Nested classes in the Pascal sense are equivalent to "static"
+            inner classes in Java -- will be changed when support for
+            Java-style non-static classes is added }
+         ' static '+
+         obj.objextname^+
+         ' inner '+
+         obj.jvm_full_typename(true)+
+         ' outer '+
+         tobjectdef(obj.owner.defowner).jvm_full_typename(true);
+      end;
+
+
     procedure TJasminAssembler.WriteProcDef(pd: tprocdef);
     procedure TJasminAssembler.WriteProcDef(pd: tprocdef);
       begin
       begin
         if not assigned(pd.exprasmlist) and
         if not assigned(pd.exprasmlist) and

+ 1 - 1
compiler/jvm/njvmcal.pas

@@ -68,7 +68,7 @@ implementation
           exit;
           exit;
         if (methodpointer.resultdef.typ<>classrefdef) then
         if (methodpointer.resultdef.typ<>classrefdef) then
           exit;
           exit;
-        current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_new,current_asmdata.RefAsmSymbol(tobjectdef(tprocdef(procdefinition).owner.defowner).jvm_full_typename)));
+        current_asmdata.CurrAsmList.concat(taicpu.op_sym(a_new,current_asmdata.RefAsmSymbol(tobjectdef(tprocdef(procdefinition).owner.defowner).jvm_full_typename(true))));
         { the constructor doesn't return anything, so put a duplicate of the
         { the constructor doesn't return anything, so put a duplicate of the
           self pointer on the evaluation stack for use as function result
           self pointer on the evaluation stack for use as function result
           after the constructor has run }
           after the constructor has run }

+ 2 - 2
compiler/jvmdef.pas

@@ -195,7 +195,7 @@ implementation
             case tobjectdef(def).objecttype of
             case tobjectdef(def).objecttype of
               odt_javaclass,
               odt_javaclass,
               odt_interfacejava:
               odt_interfacejava:
-                encodedstr:=encodedstr+'L'+tobjectdef(def).jvm_full_typename+';'
+                encodedstr:=encodedstr+'L'+tobjectdef(def).jvm_full_typename(true)+';'
               else
               else
                 result:=false;
                 result:=false;
             end;
             end;
@@ -241,7 +241,7 @@ implementation
               odt_javaclass,
               odt_javaclass,
               odt_interfacejava:
               odt_interfacejava:
                 begin
                 begin
-                  tmpresult:=tobjectdef(owner.defowner).jvm_full_typename+'/'
+                  tmpresult:=tobjectdef(owner.defowner).jvm_full_typename(true)+'/'
                 end
                 end
               else
               else
                 internalerror(2010122606);
                 internalerror(2010122606);

+ 3 - 3
compiler/pdecobj.pas

@@ -764,14 +764,14 @@ implementation
           case token of
           case token of
             _TYPE :
             _TYPE :
               begin
               begin
-                if not(current_objectdef.objecttype in [odt_class,odt_object,odt_helper]) then
+                if not(current_objectdef.objecttype in [odt_class,odt_object,odt_helper,odt_javaclass]) then
                   Message(parser_e_type_var_const_only_in_records_and_classes);
                   Message(parser_e_type_var_const_only_in_records_and_classes);
                 consume(_TYPE);
                 consume(_TYPE);
                 object_member_blocktype:=bt_type;
                 object_member_blocktype:=bt_type;
               end;
               end;
             _VAR :
             _VAR :
               begin
               begin
-                if not(current_objectdef.objecttype in [odt_class,odt_object,odt_helper]) then
+                if not(current_objectdef.objecttype in [odt_class,odt_object,odt_helper,odt_javaclass]) then
                   Message(parser_e_type_var_const_only_in_records_and_classes);
                   Message(parser_e_type_var_const_only_in_records_and_classes);
                 consume(_VAR);
                 consume(_VAR);
                 fields_allowed:=true;
                 fields_allowed:=true;
@@ -781,7 +781,7 @@ implementation
               end;
               end;
             _CONST:
             _CONST:
               begin
               begin
-                if not(current_objectdef.objecttype in [odt_class,odt_object,odt_helper]) then
+                if not(current_objectdef.objecttype in [odt_class,odt_object,odt_helper,odt_javaclass]) then
                   Message(parser_e_type_var_const_only_in_records_and_classes);
                   Message(parser_e_type_var_const_only_in_records_and_classes);
                 consume(_CONST);
                 consume(_CONST);
                 object_member_blocktype:=bt_const;
                 object_member_blocktype:=bt_const;

+ 19 - 6
compiler/symdef.pas

@@ -337,7 +337,7 @@ interface
           { C++ }
           { C++ }
           procedure finish_cpp_data;
           procedure finish_cpp_data;
           { JVM }
           { JVM }
-          function jvm_full_typename: string;
+          function jvm_full_typename(with_package_name: boolean): string;
        end;
        end;
 
 
        tclassrefdef = class(tabstractpointerdef)
        tclassrefdef = class(tabstractpointerdef)
@@ -5510,12 +5510,25 @@ implementation
       end;
       end;
 
 
 
 
-    function tobjectdef.jvm_full_typename: string;
+    function tobjectdef.jvm_full_typename(with_package_name: boolean): string;
+      var
+        st: tsymtable;
+        enclosingobj: tobjectdef;
       begin
       begin
-        result:='';
-        if assigned(import_lib) then
-          result:=import_lib^+'/';
-        result:=result+objextname^;
+        result:=objextname^;
+        st:=owner;
+        while assigned(st) and
+              (st.symtabletype=objectsymtable) do
+          begin
+            { nested classes are named as "OuterClass$InnerClass" }
+            enclosingobj:=tobjectdef(st.defowner);
+            result:=enclosingobj.objextname^+'$'+result;
+            st:=enclosingobj.owner;
+          end;
+
+        if with_package_name and
+           assigned(import_lib) then
+          result:=import_lib^+'/'+result;
       end;
       end;
 
 
 {****************************************************************************
 {****************************************************************************