Project

General

Profile

static_method_lookup_quirk.patch

Greg Shah, 07/02/2021 02:46 PM

Download (11 KB)

View differences:

new/rules/annotations/oo_references.rules 2021-07-01 21:41:38 +0000
7 7
**
8 8
** Copyright (c) 2018-2021, Golden Code Development Corporation.
9 9
**
10
** _#_ _I_ __Date__ _______________________________Description_________________________________
10
** _#_ _I_ __Date__ ______________________________________Description________________________________________
11 11
** 001 GES 20181206 First version.
12 12
**      OM 20181217 Wrapped the literals passed as parameters to OO methods.
13 13
** 002 GES 20190119 Fixed direct property access within getters and setters.
......
37 37
**                  INPUT modifier exists or not.
38 38
**     CA  20210428 When a property is part of a lvalue for an assign-style stmt, save the setter javaname so
39 39
**                  later on, when that is injected, the proper javaname is used.
40
**     GES 20210701 Fix class name references which are to static members of a parent class. This is a 4GL
41
**                  quirk.
40 42
*/
41 43
 -->
42 44
 
......
115 117
   <variable name="ename"     type="java.lang.String" />
116 118
   <variable name="pmodes"    type="java.lang.String" />
117 119
   <variable name="pmode"     type="java.lang.String" />
120
   <variable name="clsname"   type="java.lang.String" />
121
   <variable name="foundIn"   type="java.lang.String" />
122
   <variable name="javacls"   type="java.lang.String" />
118 123
   <variable name="propref"   type="com.goldencode.ast.Aast" />
119 124
   <variable name="ref"       type="com.goldencode.ast.Aast" />
120 125
   <variable name="ref2"      type="com.goldencode.ast.Aast" />
......
126 131
   <variable name="subref"    type="com.goldencode.ast.Aast" />
127 132
   <variable name="idxref"    type="com.goldencode.ast.Aast" />
128 133
   <variable name="eref"      type="com.goldencode.ast.Aast" />
134
   <variable name="member"    type="com.goldencode.ast.Aast" />
129 135
   <variable name="idxpos"    type="java.lang.Integer" />
130 136
   <variable name="paramIdx"  type="java.lang.Integer" />
131 137
   <variable name="getter"    type="com.goldencode.ast.Aast" />
......
241 247
         <action>usingClasses.addAll(getAllClassesInPackage(usingPkg))</action>
242 248
         
243 249
      </rule>
250
      
251
      <!-- the 4GL has a quirk where a qualified static reference to a parent class member can be made
252
           using a child class name as the referent; see #4978; rewrite the CLASS_NAME details to point to 
253
           the actual class; this MUST be above the next section where CLASS_NAME references will be
254
           annotated in more detail -->
255
      <rule>evalLib("isStaticClassReference", this)
256
         <action>member = copy.nextSibling</action>
257
         
258
         <!-- at this time we limit this to method calls; it may need to be opened up if this is also
259
              possible for data members -->
260
         <rule>member.type &gt; prog.begin_oo_meth and member.type &lt; prog.end_oo_meth
261
            <action>clsname = copy.getAnnotation("qualified")</action>
262
            <action>foundIn = member.getAnnotation("found-in-cls")</action>
263
            <rule>clsname != null and foundIn != null and !foundIn.toLowerCase().equals(clsname)
264
               <!-- rewrite the CLASS_NAME annotations to be the correct class -->
265
               <action>putNote("qualified", foundIn.toLowerCase())</action>
266
               <action>
267
                  putNote("source-file", #(java.lang.String) member.getAnnotation("found-in-source-file"))
268
               </action>
269
            </rule>
270
         </rule>
271
      </rule>      
244 272
   
245 273
      <rule>(evalLib("isObjectType", this) or this.type == prog.kw_funct) and
246 274
            isNote("qualified") and isNote("source-file")
new/rules/convert/oo_calls.rules 2021-07-01 22:35:18 +0000
7 7
**
8 8
** Copyright (c) 2018-2021, Golden Code Development Corporation.
9 9
**
10
** _#_ _I_ __Date__ _______________________________Description_________________________________
10
** _#_ _I_ __Date__ ______________________________________Description________________________________________
11 11
** 001 CA  20181214 First version.
12 12
** 002 CA  20190219 NEW statement requires parameter modes as set at the referenced constructor.
13 13
**                  Changed class event subscribe/unsubscribe to emit first argument as an legacy
......
29 29
**                  for OO properties/variables (static and non-static).
30 30
**     CA  20210216 Fix for the 'cast-to-object' case for a single extent argument in a dynamic call, when
31 31
**                  INPUT modifier exists or not.
32
**     GES 20210701 Moved code into a common function isStaticClassReference().
32 33
*/
33 34
 -->
34 35
 
......
149 150
         </rule>
150 151
      </rule>
151 152
      
152
      <rule>this.type == prog.class_name                           and 
153
            parent.type == prog.object_invocation                  and
154
            this.indexPos == 0
155
            <!-- 
156
               following is required to not emit in case of a SUBSCRIBE(oo.Bar:staticMethod) 
157
            -->
158
            and not(parent.parent.type == prog.object_invocation and 
159
                    parent.parent.firstChild.type == prog.class_event)
153
      <!-- emit class names as referents for a static member -->
154
      <rule>evalLib("isStaticClassReference", this)
160 155
         <action>
161 156
            createJavaAst(java.reference, 
162 157
                          #(java.lang.String) execLib("resolveClassReference", copy, null), 
new/rules/include/common-progress.rules 2021-07-01 22:34:25 +0000
450 450
**                           in favor of runtime evaluation.
451 451
**     OM  20210410          Added KW_COL_CP to temp-table field's set of attributes.
452 452
**     ME  20210504          Added override names for logging and web OO builtins.
453
**     GES 20210701          Added isStaticClassReference().
453 454
*/
454 455
 -->
455 456
 
......
3113 3114
         evalLib('bin_operators', optype)
3114 3115
      </function>
3115 3116
      
3117
      <function name="isStaticClassReference">
3118
         <parameter name="target"  type="com.goldencode.ast.Aast" />
3119
         <return    name="clsref"  type="java.lang.Boolean" />
3120
         
3121
         <!-- the class_event check is required to not emit in case of a SUBSCRIBE(oo.Bar:staticMethod) -->
3122
         <rule>
3123
            clsref = (target.type == prog.class_name                      and 
3124
                      target.parent.type == prog.object_invocation        and
3125
                      target.indexPos == 0                                and
3126
                      not(target.parent.parent.type == prog.object_invocation   and 
3127
                          target.parent.parent.firstChild.type == prog.class_event))
3128
         </rule>
3129
      </function>
3130
      
3116 3131
      <function name="resolveClassReference">
3117 3132
         <parameter name="target"  type="com.goldencode.ast.Aast" />
3118 3133
         <parameter name="fmt"     type="java.lang.String" />
new/src/com/goldencode/p2j/uast/ClassDefinition.java 2021-07-02 18:43:04 +0000
103 103
**     CA  20210609          Reworked INPUT/INPUT-OUTPUT parameters to a new approach, where they are explicitly 
104 104
**                           initialized at the method's execution, and not at the caller's arguments.
105 105
**     CA  20210616          Fixed incremental conversion for enums - do not mark them as static.
106
**     GES 20210702          Allow parent hierarchy lookup for static methods.  This is a 4GL quirk that is not
107
**                           present in Java. See #4978.  Removed dead code and some debugging code.
106 108
*/
107 109

  
108 110
/*
......
2206 2212
   }
2207 2213

  
2208 2214
   /**
2209
    * Reports if the given method is a static member of the given class.
2210
    *
2211
    * @param    name
2212
    *           Member name to lookup.
2213
    * @param    access
2214
    *           Access mode (<code>KW_PUBLIC</code>, <code>KW_PROTECTD</code>
2215
    *           or <code>KW_PRIVATE</code>).
2216
    * @param    internal
2217
    *           <code>true</code> if the lookup is internal to the current class definition.
2218
    *
2219
    * @return   <code>true</code> if the member is static.  <code>false</code> otherwise
2220
    *           including the case where the member does not exist at all.
2221
    */
2222
   public boolean isStaticMethod(String name, int access, boolean internal)
2223
   {
2224
      MemberData dat = guessMethod(name, access, true, internal);
2225
      
2226
      // TODO: this is not authoritative and could give a false even though there is a static
2227
      //       method of the same name
2228
      return (dat == null) ? false : dat.isStatic;
2229
   }
2230
   
2231
   /**
2232 2215
    * Get all defined methods in this class.
2233 2216
    * 
2234 2217
    * @return   All defined method names.
......
3007 2990
            }
3008 2991
         }
3009 2992
         
3010
         // there was no match in the current class, look up the parent hierarchy; static lookups
3011
         // only work for internal usage, non-static lookups always work
3012
         if (parents != null && (!isStatic || internal))
2993
         // there was no match in the current class, look up the parent hierarchy
2994
         if (parents != null)
3013 2995
         {
3014 2996
            // change access mode since we aren't allowed to see private stuff in parent
3015 2997
            int _access = (access == KW_PRIVATE) ? KW_PROTECTD : access;
......
3143 3125
         
3144 3126
         // only look up the parent hierarchy if we haven't got a match yet; static lookups only
3145 3127
         // work for internal usage, non-static lookups always work
3146
         if (mdat == null && parents != null && (!isStatic || internal))
3128
         if (mdat == null && parents != null)
3147 3129
         {
3148 3130
            // change access mode since we aren't allowed to see private stuff in parent
3149 3131
            int _access = (access == KW_PRIVATE) ? KW_PROTECTD : access;
......
3257 3239
      
3258 3240
      boolean first = isSetParam(name);
3259 3241
      
3260
      if ("Progress.Json.ObjectModel.JsonObject".equalsIgnoreCase(this.name) &&
3261
          "write".equalsIgnoreCase(name) &&
3262
          caller.length == 2 &&
3263
          caller[0].type.equals("longchar") &&
3264
          caller[1].type.equals("logical"))
3265
      {
3266
         int bogus = 14;
3267
      }
3268
      
3269 3242
      List<MemberData> list = candidates(name, caller.length, access, isStatic, internal, first, null);
3270 3243
            
3271 3244
      // quick out if there are no possible matches
......
3689 3662
         }
3690 3663
         
3691 3664
         // fuzzy matches are processed up the the parent hierarchy even if there are possible matches in
3692
         // the current class; static lookups only work for internal usage, non-static lookups always work
3693
         if (parents != null && (!isStatic || internal))
3665
         // the current class
3666
         if (parents != null)
3694 3667
         {
3695 3668
            // change access mode since we aren't allowed to see private stuff in parent
3696 3669
            int _access = (access == KW_PRIVATE) ? KW_PROTECTD : access;