langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Operators.java
author jlahoda
Tue, 09 Jun 2015 11:52:13 +0200
changeset 31114 d4045e8aaf1e
parent 29051 7244db2ab176
child 33018 9790ed482dd0
permissions -rw-r--r--
8082311: NPE when compiling expression with \"^\" Summary: Using BinaryNumericOperator for numeric bitwise operators and BinaryBooleanOperator for boolean bitwise operators, as the common BinaryBitwiseOperator allowed to incorrectly combine numeric and boolean operands Reviewed-by: mcimadamore
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
29051
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
     1
/*
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
     2
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
     4
 *
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    10
 *
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    15
 * accompanied this code).
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    16
 *
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    20
 *
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    23
 * questions.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    24
 */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    25
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    26
package com.sun.tools.javac.comp;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    27
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    28
import com.sun.tools.javac.code.Symbol;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    29
import com.sun.tools.javac.code.Symbol.OperatorSymbol;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    30
import com.sun.tools.javac.code.Symtab;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    31
import com.sun.tools.javac.code.Type;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    32
import com.sun.tools.javac.code.Type.MethodType;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    33
import com.sun.tools.javac.code.TypeTag;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    34
import com.sun.tools.javac.code.Types;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    35
import com.sun.tools.javac.jvm.ByteCodes;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    36
import com.sun.tools.javac.resources.CompilerProperties.Errors;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    37
import com.sun.tools.javac.tree.JCTree;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    38
import com.sun.tools.javac.tree.JCTree.Tag;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    39
import com.sun.tools.javac.util.Assert;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    40
import com.sun.tools.javac.util.Context;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    41
import com.sun.tools.javac.util.JCDiagnostic;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    42
import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    43
import com.sun.tools.javac.util.List;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    44
import com.sun.tools.javac.util.Log;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    45
import com.sun.tools.javac.util.Name;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    46
import com.sun.tools.javac.util.Names;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    47
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    48
import java.util.HashMap;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    49
import java.util.Map;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    50
import java.util.Optional;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    51
import java.util.function.BiPredicate;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    52
import java.util.function.Function;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    53
import java.util.function.Predicate;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    54
import java.util.function.Supplier;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    55
import java.util.stream.Stream;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    56
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    57
import static com.sun.tools.javac.jvm.ByteCodes.*;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    58
import static com.sun.tools.javac.comp.Operators.OperatorType.*;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    59
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    60
/**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    61
 * This class contains the logic for unary and binary operator resolution/lookup.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    62
 *
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    63
 * <p><b>This is NOT part of any supported API.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    64
 * If you write code that depends on this, you do so at your own risk.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    65
 * This code and its internal interfaces are subject to change or
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    66
 * deletion without notice.</b>
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    67
 */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    68
public class Operators {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    69
    protected static final Context.Key<Operators> operatorsKey = new Context.Key<>();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    70
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    71
    private final Names names;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    72
    private final Log log;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    73
    private final Symtab syms;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    74
    private final Types types;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    75
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    76
    /** Unary operators map. */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    77
    private Map<Name, List<UnaryOperatorHelper>> unaryOperators = new HashMap<>(Tag.getNumberOfOperators());
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    78
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    79
    /** Binary operators map. */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    80
    private Map<Name, List<BinaryOperatorHelper>> binaryOperators = new HashMap<>(Tag.getNumberOfOperators());
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    81
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    82
    /** The names of all operators. */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    83
    private Name[] opname = new Name[Tag.getNumberOfOperators()];
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    84
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    85
    public static Operators instance(Context context) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    86
        Operators instance = context.get(operatorsKey);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    87
        if (instance == null)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    88
            instance = new Operators(context);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    89
        return instance;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    90
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    91
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    92
    protected Operators(Context context) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    93
        context.put(operatorsKey, this);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    94
        syms = Symtab.instance(context);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    95
        names = Names.instance(context);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    96
        log = Log.instance(context);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    97
        types = Types.instance(context);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    98
        initOperatorNames();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
    99
        initUnaryOperators();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   100
        initBinaryOperators();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   101
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   102
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   103
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   104
     * Perform unary promotion of a type; this routine implements JLS 5.6.1.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   105
     * If the input type is not supported by unary promotion, it is returned unaltered.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   106
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   107
    Type unaryPromotion(Type t) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   108
        Type unboxed = types.unboxedTypeOrType(t);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   109
        switch (unboxed.getTag()) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   110
            case BYTE:
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   111
            case SHORT:
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   112
            case CHAR:
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   113
                return syms.intType;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   114
            default:
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   115
                return unboxed;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   116
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   117
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   118
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   119
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   120
     * Perform binary promotion of a pair of types; this routine implements JLS 5.6.2.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   121
     * If the input types are not supported by unary promotion, if such types are identical to
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   122
     * a type C, then C is returned, otherwise Object is returned.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   123
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   124
    Type binaryPromotion(Type t1, Type t2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   125
        Type unboxedT1 = types.unboxedTypeOrType(t1);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   126
        Type unboxedT2 = types.unboxedTypeOrType(t2);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   127
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   128
        if (unboxedT1.isNumeric() && unboxedT2.isNumeric()) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   129
            if (unboxedT1.hasTag(TypeTag.DOUBLE) || unboxedT2.hasTag(TypeTag.DOUBLE)) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   130
                return syms.doubleType;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   131
            } else if (unboxedT1.hasTag(TypeTag.FLOAT) || unboxedT2.hasTag(TypeTag.FLOAT)) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   132
                return syms.floatType;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   133
            } else if (unboxedT1.hasTag(TypeTag.LONG) || unboxedT2.hasTag(TypeTag.LONG)) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   134
                return syms.longType;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   135
            } else {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   136
                return syms.intType;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   137
            }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   138
        } else if (types.isSameType(unboxedT1, unboxedT2)) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   139
            return unboxedT1;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   140
        } else {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   141
            return syms.objectType;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   142
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   143
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   144
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   145
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   146
     * Entry point for resolving a unary operator given an operator tag and an argument type.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   147
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   148
    Symbol resolveUnary(DiagnosticPosition pos, JCTree.Tag tag, Type op) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   149
        return resolve(tag,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   150
                unaryOperators,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   151
                unop -> unop.test(op),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   152
                unop -> unop.resolve(op),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   153
                () -> reportErrorIfNeeded(pos, tag, op));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   154
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   155
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   156
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   157
     * Entry point for resolving a binary operator given an operator tag and a pair of argument types.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   158
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   159
    Symbol resolveBinary(DiagnosticPosition pos, JCTree.Tag tag, Type op1, Type op2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   160
        return resolve(tag,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   161
                binaryOperators,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   162
                binop -> binop.test(op1, op2),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   163
                binop -> binop.resolve(op1, op2),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   164
                () -> reportErrorIfNeeded(pos, tag, op1, op2));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   165
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   166
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   167
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   168
     * Main operator lookup routine; lookup an operator (either unary or binary) in its corresponding
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   169
     * map. If there's a matching operator, its resolve routine is called and the result is returned;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   170
     * otherwise the result of a fallback function is returned.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   171
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   172
    private <O> Symbol resolve(Tag tag, Map<Name, List<O>> opMap, Predicate<O> opTestFunc,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   173
                       Function<O, Symbol> resolveFunc, Supplier<Symbol> noResultFunc) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   174
        return opMap.get(operatorName(tag)).stream()
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   175
                .filter(opTestFunc)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   176
                .map(resolveFunc)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   177
                .findFirst()
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   178
                .orElseGet(noResultFunc);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   179
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   180
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   181
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   182
     * Creates an operator symbol.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   183
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   184
    private Symbol makeOperator(Name name, List<OperatorType> formals, OperatorType res, int... opcodes) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   185
        MethodType opType = new MethodType(
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   186
                formals.stream()
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   187
                        .map(o -> o.asType(syms))
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   188
                        .collect(List.collector()),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   189
                res.asType(syms), List.nil(), syms.methodClass);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   190
        return new OperatorSymbol(name, opType, mergeOpcodes(opcodes), syms.noSymbol);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   191
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   192
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   193
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   194
     * Fold two opcodes in a single int value (if required).
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   195
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   196
    private int mergeOpcodes(int... opcodes) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   197
        int opcodesLen = opcodes.length;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   198
        Assert.check(opcodesLen == 1 || opcodesLen == 2);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   199
        return (opcodesLen == 1) ?
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   200
                opcodes[0] :
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   201
                ((opcodes[0] << ByteCodes.preShift) | opcodes[1]);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   202
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   203
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   204
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   205
     * Report an operator lookup error.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   206
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   207
    private Symbol reportErrorIfNeeded(DiagnosticPosition pos, Tag tag, Type... args) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   208
        if (Stream.of(args).noneMatch(Type::isErroneous)) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   209
            Name opName = operatorName(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   210
            JCDiagnostic.Error opError = (args.length) == 1 ?
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   211
                    Errors.OperatorCantBeApplied(opName, args[0]) :
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   212
                    Errors.OperatorCantBeApplied1(opName, args[0], args[1]);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   213
            log.error(pos, opError);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   214
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   215
        return syms.noSymbol;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   216
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   217
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   218
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   219
     * Return name of operator with given tree tag.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   220
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   221
    public Name operatorName(JCTree.Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   222
        return opname[tag.operatorIndex()];
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   223
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   224
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   225
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   226
     * The constants in this enum represent the types upon which all the operator helpers
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   227
     * operate upon. This allows lazy and consise mapping between a type name and a type instance.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   228
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   229
    enum OperatorType {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   230
        BYTE(syms -> syms.byteType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   231
        SHORT(syms -> syms.shortType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   232
        INT(syms -> syms.intType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   233
        LONG(syms -> syms.longType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   234
        FLOAT(syms -> syms.floatType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   235
        DOUBLE(syms -> syms.doubleType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   236
        CHAR(syms -> syms.charType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   237
        BOOLEAN(syms -> syms.booleanType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   238
        OBJECT(syms -> syms.objectType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   239
        STRING(syms -> syms.stringType),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   240
        BOT(syms -> syms.botType);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   241
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   242
        final Function<Symtab, Type> asTypeFunc;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   243
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   244
        OperatorType(Function<Symtab, Type> asTypeFunc) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   245
            this.asTypeFunc = asTypeFunc;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   246
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   247
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   248
        Type asType(Symtab syms) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   249
            return asTypeFunc.apply(syms);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   250
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   251
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   252
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   253
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   254
     * Common root for all operator helpers. An operator helper instance is associated with a
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   255
     * given operator (i.e. '+'); it contains routines to perform operator lookup, i.e. find
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   256
     * which version of the '+' operator is the best given an argument type list. Supported
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   257
     * operator symbols are initialized lazily upon first lookup request - this is in order to avoid
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   258
     * initialization circularities between this class and {@code Symtab}.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   259
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   260
    abstract class OperatorHelper {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   261
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   262
        /** The operator name. */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   263
        final Name name;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   264
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   265
        /** The list of symbols associated with this operator (lazily populated). */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   266
        Optional<Symbol[]> alternatives = Optional.empty();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   267
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   268
        /** An array of operator symbol suppliers (used to lazily populate the symbol list). */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   269
        List<Supplier<Symbol>> operatorSuppliers = List.nil();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   270
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   271
        @SuppressWarnings("varargs")
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   272
        OperatorHelper(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   273
            this.name = operatorName(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   274
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   275
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   276
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   277
         * This routine implements the main operator lookup process. Each operator is tested
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   278
         * using an applicability predicate; if the test suceeds that same operator is returned,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   279
         * otherwise a dummy symbol is returned.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   280
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   281
        final Symbol doLookup(Predicate<Symbol> applicabilityTest) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   282
            return Stream.of(alternatives.orElseGet(this::initOperators))
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   283
                    .filter(applicabilityTest)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   284
                    .findFirst()
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   285
                    .orElse(syms.noSymbol);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   286
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   287
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   288
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   289
         * This routine performs lazy instantiation of the operator symbols supported by this helper.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   290
         * After initialization is done, the suppliers are cleared, to free up memory.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   291
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   292
        private Symbol[] initOperators() {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   293
            Symbol[] operators = operatorSuppliers.stream()
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   294
                    .map(op -> op.get())
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   295
                    .toArray(Symbol[]::new);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   296
            alternatives = Optional.of(operators);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   297
            operatorSuppliers = null; //let GC do its work
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   298
            return operators;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   299
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   300
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   301
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   302
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   303
     * Common superclass for all unary operator helpers.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   304
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   305
    abstract class UnaryOperatorHelper extends OperatorHelper implements Predicate<Type> {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   306
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   307
        UnaryOperatorHelper(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   308
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   309
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   310
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   311
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   312
         * This routine implements the unary operator lookup process. It customizes the behavior
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   313
         * of the shared lookup routine in {@link OperatorHelper}, by using an unary applicability test
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   314
         * (see {@link UnaryOperatorHelper#isUnaryOperatorApplicable(OperatorSymbol, Type)}
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   315
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   316
        final Symbol doLookup(Type t) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   317
            return doLookup(op -> isUnaryOperatorApplicable((OperatorSymbol)op, t));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   318
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   319
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   320
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   321
         * Unary operator applicability test - is the input type the same as the expected operand type?
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   322
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   323
        boolean isUnaryOperatorApplicable(OperatorSymbol op, Type t) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   324
            return types.isSameType(op.type.getParameterTypes().head, t);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   325
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   326
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   327
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   328
         * Adds a unary operator symbol.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   329
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   330
        final UnaryOperatorHelper addUnaryOperator(OperatorType arg, OperatorType res, int... opcode) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   331
            operatorSuppliers = operatorSuppliers.prepend(() -> makeOperator(name, List.of(arg), res, opcode));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   332
            return this;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   333
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   334
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   335
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   336
         * This method will be overridden by unary operator helpers to provide custom resolution
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   337
         * logic.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   338
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   339
        abstract Symbol resolve(Type t);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   340
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   341
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   342
    abstract class BinaryOperatorHelper extends OperatorHelper implements BiPredicate<Type, Type> {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   343
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   344
        BinaryOperatorHelper(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   345
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   346
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   347
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   348
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   349
         * This routine implements the binary operator lookup process. It customizes the behavior
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   350
         * of the shared lookup routine in {@link OperatorHelper}, by using an unary applicability test
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   351
         * (see {@link BinaryOperatorHelper#isBinaryOperatorApplicable(OperatorSymbol, Type, Type)}
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   352
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   353
        final Symbol doLookup(Type t1, Type t2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   354
            return doLookup(op -> isBinaryOperatorApplicable((OperatorSymbol)op, t1, t2));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   355
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   356
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   357
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   358
         * Binary operator applicability test - are the input types the same as the expected operand types?
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   359
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   360
        boolean isBinaryOperatorApplicable(OperatorSymbol op, Type t1, Type t2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   361
            List<Type> formals = op.type.getParameterTypes();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   362
            return types.isSameType(formals.head, t1) &&
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   363
                    types.isSameType(formals.tail.head, t2);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   364
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   365
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   366
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   367
         * Adds a binary operator symbol.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   368
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   369
        final BinaryOperatorHelper addBinaryOperator(OperatorType arg1, OperatorType arg2, OperatorType res, int... opcode) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   370
            operatorSuppliers = operatorSuppliers.prepend(() -> makeOperator(name, List.of(arg1, arg2), res, opcode));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   371
            return this;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   372
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   373
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   374
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   375
         * This method will be overridden by binary operator helpers to provide custom resolution
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   376
         * logic.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   377
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   378
        abstract Symbol resolve(Type t1, Type t2);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   379
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   380
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   381
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   382
     * Class representing unary operator helpers that operate on reference types.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   383
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   384
    class UnaryReferenceOperator extends UnaryOperatorHelper {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   385
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   386
        UnaryReferenceOperator(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   387
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   388
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   389
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   390
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   391
        public boolean test(Type type) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   392
            return type.isNullOrReference();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   393
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   394
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   395
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   396
        public Symbol resolve(Type arg) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   397
            return doLookup(syms.objectType);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   398
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   399
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   400
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   401
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   402
     * Class representing unary operator helpers that operate on numeric types (either boxed or unboxed).
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   403
     * Operator lookup is performed after applying numeric promotion of the input type.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   404
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   405
    class UnaryNumericOperator extends UnaryOperatorHelper {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   406
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   407
        UnaryNumericOperator(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   408
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   409
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   410
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   411
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   412
        public boolean test(Type type) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   413
            return unaryPromotion(type).isNumeric();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   414
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   415
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   416
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   417
        public Symbol resolve(Type arg) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   418
            return doLookup(unaryPromotion(arg));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   419
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   420
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   421
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   422
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   423
     * Class representing unary operator helpers that operate on boolean types  (either boxed or unboxed).
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   424
     * Operator lookup is performed assuming the input type is a boolean type.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   425
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   426
    class UnaryBooleanOperator extends UnaryOperatorHelper {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   427
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   428
        UnaryBooleanOperator(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   429
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   430
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   431
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   432
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   433
        public boolean test(Type type) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   434
            return types.unboxedTypeOrType(type).hasTag(TypeTag.BOOLEAN);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   435
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   436
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   437
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   438
        public Symbol resolve(Type arg) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   439
            return doLookup(syms.booleanType);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   440
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   441
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   442
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   443
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   444
     * Class representing prefix/postfix unary operator helpers. Operates on numeric types (either
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   445
     * boxed or unboxed). Operator lookup is performed on the unboxed version of the input type.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   446
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   447
    class UnaryPrefixPostfixOperator extends UnaryNumericOperator {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   448
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   449
        UnaryPrefixPostfixOperator(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   450
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   451
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   452
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   453
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   454
        public Symbol resolve(Type arg) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   455
            return doLookup(types.unboxedTypeOrType(arg));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   456
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   457
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   458
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   459
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   460
     * Class representing binary operator helpers that operate on numeric types (either boxed or unboxed).
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   461
     * Operator lookup is performed after applying binary numeric promotion of the input types.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   462
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   463
    class BinaryNumericOperator extends BinaryOperatorHelper {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   464
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   465
        BinaryNumericOperator(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   466
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   467
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   468
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   469
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   470
        public Symbol resolve(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   471
            Type t = binaryPromotion(arg1, arg2);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   472
            return doLookup(t, t);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   473
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   474
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   475
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   476
        public boolean test(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   477
            return unaryPromotion(arg1).isNumeric() && unaryPromotion(arg2).isNumeric();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   478
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   479
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   480
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   481
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   482
     * Class representing bitwise operator helpers that operate on boolean types (either boxed or unboxed).
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   483
     * Operator lookup is performed assuming both input types are boolean types.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   484
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   485
    class BinaryBooleanOperator extends BinaryOperatorHelper {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   486
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   487
        BinaryBooleanOperator(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   488
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   489
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   490
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   491
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   492
        public Symbol resolve(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   493
            return doLookup(syms.booleanType, syms.booleanType);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   494
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   495
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   496
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   497
        public boolean test(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   498
            return types.unboxedTypeOrType(arg1).hasTag(TypeTag.BOOLEAN) &&
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   499
                    types.unboxedTypeOrType(arg2).hasTag(TypeTag.BOOLEAN);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   500
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   501
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   502
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   503
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   504
     * Class representing string concatenation operator helper that operates on at least an
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   505
     * string operand. Input types subject to an operator lookup undergoes a special string promotion
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   506
     * (see {@link BinaryStringOperator#stringPromotion(Type)}.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   507
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   508
    class BinaryStringOperator extends BinaryOperatorHelper {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   509
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   510
        BinaryStringOperator(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   511
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   512
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   513
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   514
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   515
        public Symbol resolve(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   516
            return doLookup(stringPromotion(arg1), stringPromotion(arg2));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   517
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   518
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   519
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   520
        public boolean test(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   521
            return types.isSameType(arg1, syms.stringType) ||
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   522
                    types.isSameType(arg2, syms.stringType);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   523
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   524
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   525
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   526
         * This routine applies following mappings:
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   527
         * - if input type is primitive, apply numeric promotion
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   528
         * - if input type is either 'null' or 'String' leave it untouched
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   529
         * - otherwise return 'Object'
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   530
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   531
        private Type stringPromotion(Type t) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   532
            if (t.isPrimitive()) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   533
                return unaryPromotion(t);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   534
            } else if (t.hasTag(TypeTag.BOT) ||
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   535
                    types.isSameType(t, syms.stringType)) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   536
                return t;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   537
            } else if (t.hasTag(TypeTag.TYPEVAR)) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   538
                return stringPromotion(t.getUpperBound());
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   539
            } else {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   540
                return syms.objectType;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   541
            }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   542
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   543
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   544
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   545
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   546
     * Class representing shift operator helper that operates on integral operand types (either boxed
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   547
     * or unboxed). Operator lookup is performed after applying unary numeric promotion to each input type.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   548
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   549
    class BinaryShiftOperator extends BinaryOperatorHelper {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   550
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   551
        BinaryShiftOperator(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   552
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   553
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   554
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   555
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   556
        public Symbol resolve(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   557
            return doLookup(unaryPromotion(arg1), unaryPromotion(arg2));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   558
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   559
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   560
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   561
        public boolean test(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   562
            TypeTag op1 = unaryPromotion(arg1).getTag();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   563
            TypeTag op2 = unaryPromotion(arg2).getTag();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   564
            return (op1 == TypeTag.LONG || op1 == TypeTag.INT) &&
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   565
                    (op2 == TypeTag.LONG || op2 == TypeTag.INT);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   566
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   567
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   568
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   569
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   570
     * This enum represent the possible kinds of an comparison test ('==' and '!=').
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   571
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   572
    enum ComparisonKind {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   573
        /** equality between numeric or boolean operands. */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   574
        NUMERIC_OR_BOOLEAN,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   575
        /** equality between reference operands. */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   576
        REFERENCE,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   577
        /** erroneous equality */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   578
        INVALID
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   579
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   580
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   581
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   582
     * Class representing equality operator helper that operates on either numeric, boolean or reference
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   583
     * types. Operator lookup for numeric/boolean equality test is performed after binary numeric
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   584
     * promotion to the input types. Operator lookup for reference equality test is performed assuming
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   585
     * the input type is 'Object'.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   586
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   587
    class BinaryEqualityOperator extends BinaryOperatorHelper {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   588
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   589
        BinaryEqualityOperator(Tag tag) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   590
            super(tag);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   591
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   592
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   593
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   594
        public boolean test(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   595
            return getKind(arg1, arg2) != ComparisonKind.INVALID;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   596
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   597
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   598
        @Override
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   599
        public Symbol resolve(Type t1, Type t2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   600
            ComparisonKind kind = getKind(t1, t2);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   601
            Type t = (kind == ComparisonKind.NUMERIC_OR_BOOLEAN) ?
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   602
                    binaryPromotion(t1, t2) :
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   603
                    syms.objectType;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   604
            return doLookup(t, t);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   605
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   606
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   607
        /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   608
         * Retrieve the comparison kind associated with the given argument type pair.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   609
         */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   610
        private ComparisonKind getKind(Type arg1, Type arg2) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   611
            boolean arg1Primitive = arg1.isPrimitive();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   612
            boolean arg2Primitive = arg2.isPrimitive();
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   613
            if (arg1Primitive && arg2Primitive) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   614
                return ComparisonKind.NUMERIC_OR_BOOLEAN;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   615
            } else if (arg1Primitive) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   616
                return unaryPromotion(arg2).isPrimitive() ?
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   617
                        ComparisonKind.NUMERIC_OR_BOOLEAN : ComparisonKind.INVALID;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   618
            } else if (arg2Primitive) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   619
                return unaryPromotion(arg1).isPrimitive() ?
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   620
                        ComparisonKind.NUMERIC_OR_BOOLEAN : ComparisonKind.INVALID;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   621
            } else {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   622
                return arg1.isNullOrReference() && arg2.isNullOrReference() ?
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   623
                        ComparisonKind.REFERENCE : ComparisonKind.INVALID;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   624
            }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   625
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   626
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   627
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   628
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   629
     * Initialize all unary operators.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   630
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   631
    private void initUnaryOperators() {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   632
        initOperators(unaryOperators,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   633
                new UnaryNumericOperator(Tag.POS)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   634
                        .addUnaryOperator(DOUBLE, DOUBLE, nop)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   635
                        .addUnaryOperator(FLOAT, FLOAT, nop)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   636
                        .addUnaryOperator(LONG, LONG, nop)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   637
                        .addUnaryOperator(INT, INT, nop),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   638
                new UnaryNumericOperator(Tag.NEG)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   639
                        .addUnaryOperator(DOUBLE, DOUBLE, dneg)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   640
                        .addUnaryOperator(FLOAT, FLOAT, fneg)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   641
                        .addUnaryOperator(LONG, LONG, lneg)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   642
                        .addUnaryOperator(INT, INT, ineg),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   643
                new UnaryNumericOperator(Tag.COMPL)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   644
                        .addUnaryOperator(LONG, LONG, lxor)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   645
                        .addUnaryOperator(INT, INT, ixor),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   646
                new UnaryPrefixPostfixOperator(Tag.POSTINC)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   647
                        .addUnaryOperator(DOUBLE, DOUBLE, dadd)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   648
                        .addUnaryOperator(FLOAT, FLOAT, fadd)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   649
                        .addUnaryOperator(LONG, LONG, ladd)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   650
                        .addUnaryOperator(INT, INT, iadd)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   651
                        .addUnaryOperator(CHAR, CHAR, iadd)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   652
                        .addUnaryOperator(SHORT, SHORT, iadd)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   653
                        .addUnaryOperator(BYTE, BYTE, iadd),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   654
                new UnaryPrefixPostfixOperator(Tag.POSTDEC)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   655
                        .addUnaryOperator(DOUBLE, DOUBLE, dsub)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   656
                        .addUnaryOperator(FLOAT, FLOAT, fsub)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   657
                        .addUnaryOperator(LONG, LONG, lsub)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   658
                        .addUnaryOperator(INT, INT, isub)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   659
                        .addUnaryOperator(CHAR, CHAR, isub)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   660
                        .addUnaryOperator(SHORT, SHORT, isub)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   661
                        .addUnaryOperator(BYTE, BYTE, isub),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   662
                new UnaryBooleanOperator(Tag.NOT)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   663
                        .addUnaryOperator(BOOLEAN, BOOLEAN, bool_not),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   664
                new UnaryReferenceOperator(Tag.NULLCHK)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   665
                        .addUnaryOperator(OBJECT, OBJECT, nullchk));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   666
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   667
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   668
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   669
     * Initialize all binary operators.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   670
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   671
    private void initBinaryOperators() {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   672
        initOperators(binaryOperators,
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   673
            new BinaryStringOperator(Tag.PLUS)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   674
                    .addBinaryOperator(STRING, OBJECT, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   675
                    .addBinaryOperator(OBJECT, STRING, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   676
                    .addBinaryOperator(STRING, STRING, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   677
                    .addBinaryOperator(STRING, INT, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   678
                    .addBinaryOperator(STRING, LONG, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   679
                    .addBinaryOperator(STRING, FLOAT, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   680
                    .addBinaryOperator(STRING, DOUBLE, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   681
                    .addBinaryOperator(STRING, BOOLEAN, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   682
                    .addBinaryOperator(STRING, BOT, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   683
                    .addBinaryOperator(INT, STRING, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   684
                    .addBinaryOperator(LONG, STRING, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   685
                    .addBinaryOperator(FLOAT, STRING, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   686
                    .addBinaryOperator(DOUBLE, STRING, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   687
                    .addBinaryOperator(BOOLEAN, STRING, STRING, string_add)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   688
                    .addBinaryOperator(BOT, STRING, STRING, string_add),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   689
            new BinaryNumericOperator(Tag.PLUS)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   690
                    .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, dadd)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   691
                    .addBinaryOperator(FLOAT, FLOAT, FLOAT, fadd)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   692
                    .addBinaryOperator(LONG, LONG, LONG, ladd)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   693
                    .addBinaryOperator(INT, INT, INT, iadd),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   694
            new BinaryNumericOperator(Tag.MINUS)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   695
                    .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, dsub)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   696
                    .addBinaryOperator(FLOAT, FLOAT, FLOAT, fsub)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   697
                    .addBinaryOperator(LONG, LONG, LONG, lsub)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   698
                    .addBinaryOperator(INT, INT, INT, isub),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   699
            new BinaryNumericOperator(Tag.MUL)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   700
                    .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, dmul)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   701
                    .addBinaryOperator(FLOAT, FLOAT, FLOAT, fmul)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   702
                    .addBinaryOperator(LONG, LONG, LONG, lmul)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   703
                    .addBinaryOperator(INT, INT, INT, imul),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   704
            new BinaryNumericOperator(Tag.DIV)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   705
                    .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, ddiv)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   706
                    .addBinaryOperator(FLOAT, FLOAT, FLOAT, fdiv)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   707
                    .addBinaryOperator(LONG, LONG, LONG, ldiv)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   708
                    .addBinaryOperator(INT, INT, INT, idiv),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   709
            new BinaryNumericOperator(Tag.MOD)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   710
                    .addBinaryOperator(DOUBLE, DOUBLE, DOUBLE, dmod)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   711
                    .addBinaryOperator(FLOAT, FLOAT, FLOAT, fmod)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   712
                    .addBinaryOperator(LONG, LONG, LONG, lmod)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   713
                    .addBinaryOperator(INT, INT, INT, imod),
31114
d4045e8aaf1e 8082311: NPE when compiling expression with \"^\"
jlahoda
parents: 29051
diff changeset
   714
            new BinaryBooleanOperator(Tag.BITAND)
d4045e8aaf1e 8082311: NPE when compiling expression with \"^\"
jlahoda
parents: 29051
diff changeset
   715
                    .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, iand),
d4045e8aaf1e 8082311: NPE when compiling expression with \"^\"
jlahoda
parents: 29051
diff changeset
   716
            new BinaryNumericOperator(Tag.BITAND)
29051
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   717
                    .addBinaryOperator(LONG, LONG, LONG, land)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   718
                    .addBinaryOperator(INT, INT, INT, iand),
31114
d4045e8aaf1e 8082311: NPE when compiling expression with \"^\"
jlahoda
parents: 29051
diff changeset
   719
            new BinaryBooleanOperator(Tag.BITOR)
d4045e8aaf1e 8082311: NPE when compiling expression with \"^\"
jlahoda
parents: 29051
diff changeset
   720
                    .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ior),
d4045e8aaf1e 8082311: NPE when compiling expression with \"^\"
jlahoda
parents: 29051
diff changeset
   721
            new BinaryNumericOperator(Tag.BITOR)
29051
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   722
                    .addBinaryOperator(LONG, LONG, LONG, lor)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   723
                    .addBinaryOperator(INT, INT, INT, ior),
31114
d4045e8aaf1e 8082311: NPE when compiling expression with \"^\"
jlahoda
parents: 29051
diff changeset
   724
            new BinaryBooleanOperator(Tag.BITXOR)
d4045e8aaf1e 8082311: NPE when compiling expression with \"^\"
jlahoda
parents: 29051
diff changeset
   725
                    .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, ixor),
d4045e8aaf1e 8082311: NPE when compiling expression with \"^\"
jlahoda
parents: 29051
diff changeset
   726
            new BinaryNumericOperator(Tag.BITXOR)
29051
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   727
                    .addBinaryOperator(LONG, LONG, LONG, lxor)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   728
                    .addBinaryOperator(INT, INT, INT, ixor),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   729
            new BinaryShiftOperator(Tag.SL)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   730
                    .addBinaryOperator(INT, INT, INT, ishl)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   731
                    .addBinaryOperator(INT, LONG, INT, ishll)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   732
                    .addBinaryOperator(LONG, INT, LONG, lshl)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   733
                    .addBinaryOperator(LONG, LONG, LONG, lshll),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   734
            new BinaryShiftOperator(Tag.SR)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   735
                    .addBinaryOperator(INT, INT, INT, ishr)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   736
                    .addBinaryOperator(INT, LONG, INT, ishrl)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   737
                    .addBinaryOperator(LONG, INT, LONG, lshr)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   738
                    .addBinaryOperator(LONG, LONG, LONG, lshrl),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   739
            new BinaryShiftOperator(Tag.USR)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   740
                    .addBinaryOperator(INT, INT, INT, iushr)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   741
                    .addBinaryOperator(INT, LONG, INT, iushrl)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   742
                    .addBinaryOperator(LONG, INT, LONG, lushr)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   743
                    .addBinaryOperator(LONG, LONG, LONG, lushrl),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   744
            new BinaryNumericOperator(Tag.LT)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   745
                    .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpg, iflt)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   746
                    .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpg, iflt)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   747
                    .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, iflt)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   748
                    .addBinaryOperator(INT, INT, BOOLEAN, if_icmplt),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   749
            new BinaryNumericOperator(Tag.GT)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   750
                    .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpl, ifgt)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   751
                    .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpl, ifgt)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   752
                    .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifgt)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   753
                    .addBinaryOperator(INT, INT, BOOLEAN, if_icmpgt),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   754
            new BinaryNumericOperator(Tag.LE)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   755
                    .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpg, ifle)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   756
                    .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpg, ifle)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   757
                    .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifle)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   758
                    .addBinaryOperator(INT, INT, BOOLEAN, if_icmple),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   759
            new BinaryNumericOperator(Tag.GE)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   760
                    .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpl, ifge)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   761
                    .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpl, ifge)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   762
                    .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifge)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   763
                    .addBinaryOperator(INT, INT, BOOLEAN, if_icmpge),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   764
            new BinaryEqualityOperator(Tag.EQ)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   765
                    .addBinaryOperator(OBJECT, OBJECT, BOOLEAN, if_acmpeq)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   766
                    .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, if_icmpeq)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   767
                    .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpl, ifeq)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   768
                    .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpl, ifeq)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   769
                    .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifeq)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   770
                    .addBinaryOperator(INT, INT, BOOLEAN, if_icmpeq),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   771
            new BinaryEqualityOperator(Tag.NE)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   772
                    .addBinaryOperator(OBJECT, OBJECT, BOOLEAN, if_acmpne)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   773
                    .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, if_icmpne)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   774
                    .addBinaryOperator(DOUBLE, DOUBLE, BOOLEAN, dcmpl, ifne)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   775
                    .addBinaryOperator(FLOAT, FLOAT, BOOLEAN, fcmpl, ifne)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   776
                    .addBinaryOperator(LONG, LONG, BOOLEAN, lcmp, ifne)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   777
                    .addBinaryOperator(INT, INT, BOOLEAN, if_icmpne),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   778
            new BinaryBooleanOperator(Tag.AND)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   779
                    .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, bool_and),
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   780
            new BinaryBooleanOperator(Tag.OR)
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   781
                    .addBinaryOperator(BOOLEAN, BOOLEAN, BOOLEAN, bool_or));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   782
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   783
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   784
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   785
     * Complete the initialization of an operator helper by storing it into the corresponding operator map.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   786
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   787
    @SafeVarargs
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   788
    private final <O extends OperatorHelper> void initOperators(Map<Name, List<O>> opsMap, O... ops) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   789
        for (O o : ops) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   790
            Name opName = o.name;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   791
            List<O> helpers = opsMap.getOrDefault(opName, List.nil());
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   792
            opsMap.put(opName, helpers.prepend(o));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   793
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   794
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   795
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   796
    /**
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   797
     * Initialize operator name array.
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   798
     */
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   799
    private void initOperatorNames() {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   800
        setOperatorName(Tag.POS, "+");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   801
        setOperatorName(Tag.NEG, "-");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   802
        setOperatorName(Tag.NOT, "!");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   803
        setOperatorName(Tag.COMPL, "~");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   804
        setOperatorName(Tag.PREINC, "++");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   805
        setOperatorName(Tag.PREDEC, "--");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   806
        setOperatorName(Tag.POSTINC, "++");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   807
        setOperatorName(Tag.POSTDEC, "--");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   808
        setOperatorName(Tag.NULLCHK, "<*nullchk*>");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   809
        setOperatorName(Tag.OR, "||");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   810
        setOperatorName(Tag.AND, "&&");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   811
        setOperatorName(Tag.EQ, "==");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   812
        setOperatorName(Tag.NE, "!=");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   813
        setOperatorName(Tag.LT, "<");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   814
        setOperatorName(Tag.GT, ">");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   815
        setOperatorName(Tag.LE, "<=");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   816
        setOperatorName(Tag.GE, ">=");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   817
        setOperatorName(Tag.BITOR, "|");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   818
        setOperatorName(Tag.BITXOR, "^");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   819
        setOperatorName(Tag.BITAND, "&");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   820
        setOperatorName(Tag.SL, "<<");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   821
        setOperatorName(Tag.SR, ">>");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   822
        setOperatorName(Tag.USR, ">>>");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   823
        setOperatorName(Tag.PLUS, "+");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   824
        setOperatorName(Tag.MINUS, names.hyphen);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   825
        setOperatorName(Tag.MUL, names.asterisk);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   826
        setOperatorName(Tag.DIV, names.slash);
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   827
        setOperatorName(Tag.MOD, "%");
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   828
    }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   829
    //where
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   830
        private void setOperatorName(Tag tag, String name) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   831
            setOperatorName(tag, names.fromString(name));
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   832
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   833
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   834
        private void setOperatorName(Tag tag, Name name) {
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   835
            opname[tag.operatorIndex()] = name;
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   836
        }
7244db2ab176 8071241: Investigate alternate strategy for type-checking operators
mcimadamore
parents:
diff changeset
   837
}