static_method_lookup_quirk.patch
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 > prog.begin_oo_meth and member.type < 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; |