001 /*
002 * Copyright 2010-2016 JetBrains s.r.o.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017 package org.jetbrains.kotlin.types.expressions;
018
019 import com.google.common.collect.ImmutableBiMap;
020 import com.google.common.collect.ImmutableSet;
021 import org.jetbrains.annotations.NotNull;
022 import org.jetbrains.annotations.Nullable;
023 import org.jetbrains.kotlin.lexer.KtSingleValueToken;
024 import org.jetbrains.kotlin.lexer.KtToken;
025 import org.jetbrains.kotlin.lexer.KtTokens;
026 import org.jetbrains.kotlin.name.Name;
027
028 import static org.jetbrains.kotlin.util.OperatorNameConventions.*;
029
030 public class OperatorConventions {
031
032 private OperatorConventions() {}
033
034 // Names for primitive type conversion properties
035 public static final Name DOUBLE = Name.identifier("toDouble");
036 public static final Name FLOAT = Name.identifier("toFloat");
037 public static final Name LONG = Name.identifier("toLong");
038 public static final Name INT = Name.identifier("toInt");
039 public static final Name CHAR = Name.identifier("toChar");
040 public static final Name SHORT = Name.identifier("toShort");
041 public static final Name BYTE = Name.identifier("toByte");
042
043
044 public static final ImmutableSet<Name> NUMBER_CONVERSIONS = ImmutableSet.of(
045 DOUBLE, FLOAT, LONG, INT, SHORT, BYTE, CHAR
046 );
047
048 // If you add new unary, binary or assignment operators, add it to OperatorConventionNames as well
049
050 public static final ImmutableBiMap<KtSingleValueToken, Name> UNARY_OPERATION_NAMES = ImmutableBiMap.<KtSingleValueToken, Name>builder()
051 .put(KtTokens.PLUSPLUS, INC)
052 .put(KtTokens.MINUSMINUS, DEC)
053 .put(KtTokens.PLUS, UNARY_PLUS)
054 .put(KtTokens.MINUS, UNARY_MINUS)
055 .put(KtTokens.EXCL, NOT)
056 .build();
057
058 public static final ImmutableBiMap<KtSingleValueToken, Name> BINARY_OPERATION_NAMES = ImmutableBiMap.<KtSingleValueToken, Name>builder()
059 .put(KtTokens.MUL, TIMES)
060 .put(KtTokens.PLUS, PLUS)
061 .put(KtTokens.MINUS, MINUS)
062 .put(KtTokens.DIV, DIV)
063 .put(KtTokens.PERC, REM)
064 .put(KtTokens.RANGE, RANGE_TO)
065 .build();
066
067 public static final ImmutableBiMap<Name, Name> REM_TO_MOD_OPERATION_NAMES = ImmutableBiMap.<Name, Name>builder()
068 .put(REM, MOD)
069 .put(REM_ASSIGN, MOD_ASSIGN)
070 .build();
071
072 public static final ImmutableSet<KtSingleValueToken> NOT_OVERLOADABLE =
073 ImmutableSet.of(KtTokens.ANDAND, KtTokens.OROR, KtTokens.ELVIS, KtTokens.EQEQEQ, KtTokens.EXCLEQEQEQ);
074
075 public static final ImmutableSet<KtSingleValueToken> INCREMENT_OPERATIONS =
076 ImmutableSet.of(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS);
077
078 public static final ImmutableSet<KtSingleValueToken> COMPARISON_OPERATIONS =
079 ImmutableSet.of(KtTokens.LT, KtTokens.GT, KtTokens.LTEQ, KtTokens.GTEQ);
080
081 public static final ImmutableSet<KtSingleValueToken> EQUALS_OPERATIONS =
082 ImmutableSet.of(KtTokens.EQEQ, KtTokens.EXCLEQ);
083
084 public static final ImmutableSet<KtSingleValueToken> IDENTITY_EQUALS_OPERATIONS =
085 ImmutableSet.of(KtTokens.EQEQEQ, KtTokens.EXCLEQEQEQ);
086
087 public static final ImmutableSet<KtSingleValueToken> IN_OPERATIONS =
088 ImmutableSet.<KtSingleValueToken>of(KtTokens.IN_KEYWORD, KtTokens.NOT_IN);
089
090 public static final ImmutableBiMap<KtSingleValueToken, Name> ASSIGNMENT_OPERATIONS = ImmutableBiMap.<KtSingleValueToken, Name>builder()
091 .put(KtTokens.MULTEQ, TIMES_ASSIGN)
092 .put(KtTokens.DIVEQ, DIV_ASSIGN)
093 .put(KtTokens.PERCEQ, REM_ASSIGN)
094 .put(KtTokens.PLUSEQ, PLUS_ASSIGN)
095 .put(KtTokens.MINUSEQ, MINUS_ASSIGN)
096 .build();
097
098 public static final ImmutableBiMap<KtSingleValueToken, KtSingleValueToken> ASSIGNMENT_OPERATION_COUNTERPARTS = ImmutableBiMap.<KtSingleValueToken, KtSingleValueToken>builder()
099 .put(KtTokens.MULTEQ, KtTokens.MUL)
100 .put(KtTokens.DIVEQ, KtTokens.DIV)
101 .put(KtTokens.PERCEQ, KtTokens.PERC)
102 .put(KtTokens.PLUSEQ, KtTokens.PLUS)
103 .put(KtTokens.MINUSEQ, KtTokens.MINUS)
104 .build();
105
106 public static final ImmutableBiMap<KtSingleValueToken, Name> BOOLEAN_OPERATIONS = ImmutableBiMap.<KtSingleValueToken, Name>builder()
107 .put(KtTokens.ANDAND, AND)
108 .put(KtTokens.OROR, OR)
109 .build();
110
111 public static final ImmutableSet<Name> CONVENTION_NAMES = ImmutableSet.<Name>builder()
112 .add(GET, SET, INVOKE, CONTAINS, ITERATOR, NEXT, HAS_NEXT, EQUALS, COMPARE_TO, GET_VALUE, SET_VALUE)
113 .addAll(UNARY_OPERATION_NAMES.values())
114 .addAll(BINARY_OPERATION_NAMES.values())
115 .addAll(ASSIGNMENT_OPERATIONS.values())
116 .build();
117
118 @Nullable
119 public static Name getNameForOperationSymbol(@NotNull KtToken token) {
120 return getNameForOperationSymbol(token, true, true);
121 }
122
123 @Nullable
124 public static Name getNameForOperationSymbol(@NotNull KtToken token, boolean unaryOperations, boolean binaryOperations) {
125 Name name;
126
127 if (binaryOperations) {
128 name = BINARY_OPERATION_NAMES.get(token);
129 if (name != null) return name;
130 }
131
132 if (unaryOperations) {
133 name = UNARY_OPERATION_NAMES.get(token);
134 if (name != null) return name;
135 }
136
137 name = ASSIGNMENT_OPERATIONS.get(token);
138 if (name != null) return name;
139 if (COMPARISON_OPERATIONS.contains(token)) return COMPARE_TO;
140 if (EQUALS_OPERATIONS.contains(token)) return EQUALS;
141 if (IN_OPERATIONS.contains(token)) return CONTAINS;
142 return null;
143 }
144
145 public static boolean isConventionName(@NotNull Name name) {
146 return CONVENTION_NAMES.contains(name) || COMPONENT_REGEX.matches(name.asString());
147 }
148 }