|
136 | 136 |
|
137 | 137 | //todo: j2sdoc in static field showing up in default static block only, not in initializer block. |
138 | 138 |
|
| 139 | +//BH 2020.01.09 -- 3.2.7-v2 introduces @j2sAlias as a way of adding a custom method name, as in exports. |
139 | 140 | //BH 2020.01.08 -- 3.2.7-v1 sets generic references to their erasures; adds implicit synthetic default methods to interfaces |
140 | | -//BH 2020.01.05 -- 3.2.6-v2 fixes synthetic methods missing for generics |
141 | | - |
142 | | -// There was a limitation discovered in relation to Spliterators. Specifically, |
143 | | -// Spliterators.EmptySpliterator.OfInt (|Long|Double) did not have the |
144 | | -// synthetic bridge tryAdvance(IntConsumer consumer). This was due to the fact that |
145 | | -// Java considers tryAdvance(C consumer) in the Spliterator.EmptySpliterator superclass<T,C,S> |
146 | | -// to do that: |
147 | | - |
148 | | -// public boolean tryAdvance(C consumer) { |
149 | | -// Objects.requireNonNull(consumer); |
150 | | -// return false; |
151 | | -// } |
152 | | - |
153 | | -// where class OfInt extends EmptySpliterator<Integer, Spliterator.OfInt, IntConsumer> |
154 | | - |
155 | | -// Java handles this with a synthetic bridge in Spliterators$EmptySpliterator$OfInt that maps |
156 | | -// java.util.Spliterators$EmptySpliterator$OfInt.tryAdvance(IntConsumer) |
157 | | -// to Spliterator.OfInt.tryAdvance(Object): |
158 | | - |
159 | | -//// Method descriptor #17 (Ljava/util/function/IntConsumer;)Z |
160 | | -//// Stack: 2, Locals: 2 |
161 | | -//public bridge synthetic boolean tryAdvance(java.util.function.IntConsumer arg0); |
162 | | -// 0 aload_0 [this] |
163 | | -// 1 aload_1 [arg0] |
164 | | -// 2 checkcast java.lang.Object [18] |
165 | | -// 5 invokevirtual java.util.Spliterators$EmptySpliterator$OfInt.tryAdvance(java.lang.Object) : boolean [20] |
166 | | -// 8 ireturn |
167 | | - |
| 141 | + |
| 142 | +// Note: There was a limitation discovered in relation to Spliterators. Specifically, |
| 143 | +// Spliterators$EmptySpliterator$OfInt (OfLong, OfDouble, etc) did not have the |
| 144 | +// the method tryAdvance(IntConsumer consumer). This was due to the fact that |
| 145 | +// interface Spliterator$OfInt.tryAdvance(C consumer) overrides interface Spliterator$ofPrimitive.tryAdvance(C action) |
| 146 | +// but does not have the same signature. |
| 147 | +// Java handles this with a synthetic bridge in Spliterators$EmptySpliterator$OfInt, which maps |
| 148 | +// java.util.Spliterators$EmptySpliterator$OfInt.tryAdvance(IntConsumer) |
| 149 | +// to Spliterator.OfInt.tryAdvance(Object): |
| 150 | +// |
| 151 | +// public bridge synthetic boolean tryAdvance(java.util.function.IntConsumer arg0); |
| 152 | +// 0 aload_0 [this] |
| 153 | +// 1 aload_1 [arg0] |
| 154 | +// 2 checkcast java.lang.Object [18] |
| 155 | +// 5 invokevirtual java.util.Spliterators$EmptySpliterator$OfInt.tryAdvance(java.lang.Object) : boolean [20] |
| 156 | +// 8 ireturn |
| 157 | +// |
| 158 | +// But, actually, we can do one better. All that was necessary was to add to the $defaults$ function of |
| 159 | +// the Spliterator$OfInt interface an alias that equates tryAdvace$java_util_function_IntConsumer |
| 160 | +// to tryAdvance$O: |
| 161 | +// |
| 162 | +// C$.$defaults$ = function(C$){ |
| 163 | +// ... |
| 164 | +// C$.prototype['tryAdvance$java_util_function_IntConsumer']=C$.prototype['tryAdvance$O']; |
| 165 | +// }; |
| 166 | +// |
| 167 | +// In this way, any implementing class gets that synthetic bridge method. Ta-DA! |
| 168 | + |
| 169 | +// BH 2020.01.05 -- 3.2.6-v2 fixes synthetic methods missing for generics |
168 | 170 | // BH 2020.01.03 -- 3.2.6-v1 fixes for $__T and some synthetic methods missing |
169 | 171 | // BH 2020.01.01 3.2.6-v1 fixes for generic varargs with only one parameter |
170 | 172 | // BH 2019.12.19 3.2.6-v0 C$.$clinit$=2 adds C$.$fields$, Clazz._getFields |
@@ -282,8 +284,6 @@ public class Java2ScriptVisitor extends ASTVisitor { |
282 | 284 | private final static int METHOD_ISQUALIFIED = 16; |
283 | 285 | private final static int METHOD_NULLEXPRESSION = 32; |
284 | 286 |
|
285 | | - private final static int METHOD_ALIAS = 64; |
286 | | - |
287 | 287 | private static final int NOT_LOCAL = 0; |
288 | 288 | private static final int REALLY_LOCAL_CLASS = 1; |
289 | 289 | private static final int ANON_CLASS = 2; |
@@ -1292,6 +1292,7 @@ private void processMethodDeclaration(MethodDeclaration mnode, IMethodBinding mB |
1292 | 1292 | String quotedFinalNameOrArray = getMethodNameWithSyntheticBridgeForDeclaration(mBinding, isConstructor, alias, qualification, |
1293 | 1293 | isAbstract ? abstractMethodList : null); |
1294 | 1294 | if (isAbstract) { |
| 1295 | + // allows us to catalog method names for an interface or abstract class |
1295 | 1296 | return; |
1296 | 1297 | } |
1297 | 1298 | boolean isMain = (isStatic && isPublic && mBinding.getName().equals("main") |
@@ -5292,8 +5293,6 @@ private Map<String, Object> getGenericClassTypes(ITypeBinding type) { |
5292 | 5293 | for (int i = 0; i < tokens.length; i++) { |
5293 | 5294 | String key = tokens[i].trim(); |
5294 | 5295 | key = key.substring(0, (key + " ").indexOf(" ")); |
5295 | | -// if (i >= types.length) |
5296 | | -// System.out.println("???getGeneric??? " + i + "/" + types.length + " key=" + key + " temp=" + temp + " sb=" + sb); |
5297 | 5296 | classTypes.put(key, (i < types.length ? types[i] : "O")); |
5298 | 5297 | } |
5299 | 5298 | // note: enabling this line causes an intense memory situation. |
@@ -5324,28 +5323,24 @@ private List<String[]> getGenericMethodList(ITypeBinding methodClass, String met |
5324 | 5323 | * @param node |
5325 | 5324 | * @param mBinding |
5326 | 5325 | * @param isConstructor |
5327 | | - * @param aliases |
| 5326 | + * @param alias name provided using at_j2sAlias |
5328 | 5327 | * @param mode |
5329 | 5328 | * @param declaredMethodList |
5330 | 5329 | * @return j2s-qualified name or an array of j2s-qualified names |
5331 | 5330 | */ |
5332 | 5331 | String getMethodNameWithSyntheticBridgeForDeclaration(IMethodBinding mBinding, boolean isConstructor, |
5333 | | - String aliases, int mode, List<String> declaredMethodList) { |
| 5332 | + String alias, int mode, List<String> declaredMethodList) { |
5334 | 5333 | List<String> names = (declaredMethodList == null ? new ArrayList<String>() : declaredMethodList); |
5335 | 5334 | int pt = names.size(); |
| 5335 | + if (alias != null) |
| 5336 | + names.add(alias); |
5336 | 5337 | String nodeName = mBinding.getName(); |
5337 | 5338 | String methodName = (isConstructor ? "c$" : nodeName); |
5338 | 5339 | String qname = getFinalMethodNameWith$Params(methodName, mBinding, null, false, METHOD_NOTSPECIAL); |
5339 | 5340 | names.add(qname); |
5340 | 5341 | ITypeBinding methodClass = mBinding.getDeclaringClass(); |
5341 | 5342 | List<String[]> methodList = getGenericMethodList(methodClass, nodeName); |
5342 | | - if (aliases != null) { |
5343 | | - String[] types = aliases.split(","); |
5344 | | - String pname = getFinalMethodNameWith$Params(methodName, mBinding, types, false, METHOD_ALIAS); |
5345 | | - if (pname != null) { |
5346 | | - names.add(pname); |
5347 | | - } |
5348 | | - } else if (methodList != null) { |
| 5343 | + if (methodList != null) { |
5349 | 5344 | for (int i = methodList.size(); --i >= 0;) { |
5350 | 5345 | String pname = getFinalMethodNameWith$Params(methodName, mBinding, methodList.get(i), false, METHOD_NOTSPECIAL); |
5351 | 5346 | if (pname != null) |
|
0 commit comments