1
1
/*
2
- * Copyright 2002-2017 the original author or authors.
2
+ * Copyright 2002-2018 the original author or authors.
3
3
*
4
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
5
* you may not use this file except in compliance with the License.
41
41
public abstract class Operator extends SpelNodeImpl {
42
42
43
43
private final String operatorName ;
44
-
44
+
45
45
// The descriptors of the runtime operand values are used if the discovered declared
46
46
// descriptors are not providing enough information (for example a generic type
47
47
// whose accessors seem to only be returning 'Object' - the actual descriptors may
@@ -73,7 +73,8 @@ public final String getOperatorName() {
73
73
}
74
74
75
75
/**
76
- * String format for all operators is the same '(' [operand] [operator] [operand] ')'
76
+ * String format for all operators is the same
77
+ * {@code '(' [operand] [operator] [operand] ')'}.
77
78
*/
78
79
@ Override
79
80
public String toStringAST () {
@@ -103,29 +104,29 @@ protected boolean isCompilableOperatorUsingNumerics() {
103
104
return (dc .areNumbers && dc .areCompatible );
104
105
}
105
106
106
- /**
107
- * Numeric comparison operators share very similar generated code, only differing in
107
+ /**
108
+ * Numeric comparison operators share very similar generated code, only differing in
108
109
* two comparison instructions.
109
110
*/
110
111
protected void generateComparisonCode (MethodVisitor mv , CodeFlow cf , int compInstruction1 , int compInstruction2 ) {
111
112
SpelNodeImpl left = getLeftOperand ();
112
113
SpelNodeImpl right = getRightOperand ();
113
114
String leftDesc = left .exitTypeDescriptor ;
114
115
String rightDesc = right .exitTypeDescriptor ;
115
-
116
+
116
117
boolean unboxLeft = !CodeFlow .isPrimitive (leftDesc );
117
118
boolean unboxRight = !CodeFlow .isPrimitive (rightDesc );
118
119
DescriptorComparison dc = DescriptorComparison .checkNumericCompatibility (
119
120
leftDesc , rightDesc , this .leftActualDescriptor , this .rightActualDescriptor );
120
121
char targetType = dc .compatibleType ; // CodeFlow.toPrimitiveTargetDesc(leftDesc);
121
-
122
+
122
123
cf .enterCompilationScope ();
123
124
left .generateCode (mv , cf );
124
125
cf .exitCompilationScope ();
125
126
if (unboxLeft ) {
126
127
CodeFlow .insertUnboxInsns (mv , targetType , leftDesc );
127
128
}
128
-
129
+
129
130
cf .enterCompilationScope ();
130
131
right .generateCode (mv , cf );
131
132
cf .exitCompilationScope ();
@@ -141,11 +142,11 @@ protected void generateComparisonCode(MethodVisitor mv, CodeFlow cf, int compIns
141
142
mv .visitJumpInsn (compInstruction1 , elseTarget );
142
143
}
143
144
else if (targetType == 'F' ) {
144
- mv .visitInsn (FCMPG );
145
+ mv .visitInsn (FCMPG );
145
146
mv .visitJumpInsn (compInstruction1 , elseTarget );
146
147
}
147
148
else if (targetType == 'J' ) {
148
- mv .visitInsn (LCMP );
149
+ mv .visitInsn (LCMP );
149
150
mv .visitJumpInsn (compInstruction1 , elseTarget );
150
151
}
151
152
else if (targetType == 'I' ) {
@@ -217,6 +218,10 @@ else if (leftNumber instanceof Byte || rightNumber instanceof Byte) {
217
218
return left .toString ().equals (right .toString ());
218
219
}
219
220
221
+ if (left instanceof Boolean && right instanceof Boolean ) {
222
+ return left .equals (right );
223
+ }
224
+
220
225
if (ObjectUtils .nullSafeEquals (left , right )) {
221
226
return true ;
222
227
}
@@ -230,7 +235,7 @@ else if (leftNumber instanceof Byte || rightNumber instanceof Byte) {
230
235
231
236
return false ;
232
237
}
233
-
238
+
234
239
235
240
/**
236
241
* A descriptor comparison encapsulates the result of comparing descriptor
@@ -253,7 +258,7 @@ private DescriptorComparison(boolean areNumbers, boolean areCompatible, char com
253
258
this .areCompatible = areCompatible ;
254
259
this .compatibleType = compatibleType ;
255
260
}
256
-
261
+
257
262
/**
258
263
* Return an object that indicates whether the input descriptors are compatible.
259
264
* <p>A declared descriptor is what could statically be determined (e.g. from looking
@@ -277,7 +282,7 @@ public static DescriptorComparison checkNumericCompatibility(
277
282
278
283
boolean leftNumeric = CodeFlow .isPrimitiveOrUnboxableSupportedNumberOrBoolean (ld );
279
284
boolean rightNumeric = CodeFlow .isPrimitiveOrUnboxableSupportedNumberOrBoolean (rd );
280
-
285
+
281
286
// If the declared descriptors aren't providing the information, try the actual descriptors
282
287
if (!leftNumeric && !ObjectUtils .nullSafeEquals (ld , leftActualDescriptor )) {
283
288
ld = leftActualDescriptor ;
@@ -287,7 +292,7 @@ public static DescriptorComparison checkNumericCompatibility(
287
292
rd = rightActualDescriptor ;
288
293
rightNumeric = CodeFlow .isPrimitiveOrUnboxableSupportedNumberOrBoolean (rd );
289
294
}
290
-
295
+
291
296
if (leftNumeric && rightNumeric ) {
292
297
if (CodeFlow .areBoxingCompatible (ld , rd )) {
293
298
return new DescriptorComparison (true , true , CodeFlow .toPrimitiveTargetDesc (ld ));
@@ -298,7 +303,7 @@ public static DescriptorComparison checkNumericCompatibility(
298
303
}
299
304
else {
300
305
return DescriptorComparison .NOT_NUMBERS ;
301
- }
306
+ }
302
307
}
303
308
}
304
309
0 commit comments