提交 d7d3a50d 编写于 作者: A Andrey Breslav

?: supported

上级 1e0d077a
......@@ -17,6 +17,7 @@ public class JetTypeChecker {
this.standardLibrary = standardLibrary;
}
@NotNull
private Map<TypeConstructor, Set<TypeConstructor>> getConversionMap() {
// if (conversionMap.size() == 0) {
// addConversion(standardLibrary.getByte(),
......@@ -62,7 +63,13 @@ public class JetTypeChecker {
// conversionMap.put(actual.getTypeConstructor(), new HashSet<TypeConstructor>(Arrays.asList(constructors)));
// }
//
public JetType commonSupertype(Collection<JetType> types) {
@NotNull
public JetType commonSupertype(@NotNull JetType... types) {
return commonSupertype(Arrays.asList(types));
}
@NotNull
public JetType commonSupertype(@NotNull Collection<JetType> types) {
Collection<JetType> typeSet = new HashSet<JetType>(types);
assert !typeSet.isEmpty();
boolean nullable = false;
......@@ -98,7 +105,8 @@ public class JetTypeChecker {
return TypeUtils.makeNullableIfNeeded(result, nullable);
}
private JetType computeSupertypeProjections(TypeConstructor constructor, Set<JetType> types) {
@NotNull
private JetType computeSupertypeProjections(@NotNull TypeConstructor constructor, @NotNull Set<JetType> types) {
// we assume that all the given types are applications of the same type constructor
assert !types.isEmpty();
......@@ -127,7 +135,8 @@ public class JetTypeChecker {
return new JetTypeImpl(Collections.<Attribute>emptyList(), constructor, nullable, newProjections, JetStandardClasses.STUB);
}
private TypeProjection computeSupertypeProjection(TypeParameterDescriptor parameterDescriptor, Set<TypeProjection> typeProjections) {
@NotNull
private TypeProjection computeSupertypeProjection(@NotNull TypeParameterDescriptor parameterDescriptor, @NotNull Set<TypeProjection> typeProjections) {
if (typeProjections.size() == 1) {
return typeProjections.iterator().next();
}
......@@ -183,7 +192,8 @@ public class JetTypeChecker {
}
}
private Map<TypeConstructor, Set<JetType>> computeCommonRawSupertypes(Collection<JetType> types) {
@NotNull
private Map<TypeConstructor, Set<JetType>> computeCommonRawSupertypes(@NotNull Collection<JetType> types) {
assert !types.isEmpty();
final Map<TypeConstructor, Set<JetType>> constructorToAllInstances = new HashMap<TypeConstructor, Set<JetType>>();
......@@ -244,19 +254,19 @@ public class JetTypeChecker {
return result;
}
private void markAll(TypeConstructor typeConstructor, Set<TypeConstructor> markerSet) {
private void markAll(@NotNull TypeConstructor typeConstructor, @NotNull Set<TypeConstructor> markerSet) {
markerSet.add(typeConstructor);
for (JetType type : typeConstructor.getSupertypes()) {
markAll(type.getConstructor(), markerSet);
}
}
private <R> R dfs(JetType current, Set<TypeConstructor> visited, DfsNodeHandler<R> handler) {
private <R> R dfs(@NotNull JetType current, @NotNull Set<TypeConstructor> visited, @NotNull DfsNodeHandler<R> handler) {
doDfs(current, visited, handler);
return handler.result();
}
private void doDfs(JetType current, Set<TypeConstructor> visited, DfsNodeHandler<?> handler) {
private void doDfs(@NotNull JetType current, @NotNull Set<TypeConstructor> visited, @NotNull DfsNodeHandler<?> handler) {
if (!visited.add(current.getConstructor())) {
return;
}
......@@ -307,7 +317,7 @@ public class JetTypeChecker {
// This method returns the supertype of the first parameter that has the same constructor
// as the second parameter, applying the substitution of type arguments to it
@Nullable
private JetType findCorrespondingSupertype(JetType subtype, JetType supertype) {
private JetType findCorrespondingSupertype(@NotNull JetType subtype, @NotNull JetType supertype) {
TypeConstructor constructor = subtype.getConstructor();
if (constructor.equals(supertype.getConstructor())) {
return subtype;
......@@ -321,7 +331,7 @@ public class JetTypeChecker {
return null;
}
private boolean checkSubtypeForTheSameConstructor(JetType subtype, JetType supertype) {
private boolean checkSubtypeForTheSameConstructor(@NotNull JetType subtype, @NotNull JetType supertype) {
TypeConstructor constructor = subtype.getConstructor();
assert constructor.equals(supertype.getConstructor());
......
......@@ -728,6 +728,18 @@ public class JetTypeInferrer {
}
result = semanticServices.getStandardLibrary().getBooleanType();
}
else if (operationType == JetTokens.ELVIS) {
JetType leftType = getType(scope, left, false);
JetType rightType = right == null ? null : getType(scope, right, false);
if (leftType != null) {
if (!leftType.isNullable()) {
semanticServices.getErrorHandler().genericWarning(left.getNode(), "Elvis operator (?:) is always returns the left operand of non-nullable type " + leftType);
}
if (rightType != null) {
result = TypeUtils.makeNullableAsSpecified(semanticServices.getTypeChecker().commonSupertype(leftType, rightType), rightType.isNullable());
}
}
}
else {
semanticServices.getErrorHandler().genericError(operationSign.getNode(), "Unknown operation");
}
......
......@@ -12,17 +12,18 @@ import java.util.Set;
*/
public class TypeUtils {
public static JetType makeNullable(JetType type) {
if (type.isNullable()) {
return type;
}
return new JetTypeImpl(type.getAttributes(), type.getConstructor(), true, type.getArguments(), type.getMemberScope());
return makeNullableAsSpecified(type, true);
}
public static JetType makeNotNullable(JetType type) {
if (!type.isNullable()) {
return makeNullableAsSpecified(type, false);
}
public static JetType makeNullableAsSpecified(JetType type, boolean nullable) {
if (type.isNullable() == nullable) {
return type;
}
return new JetTypeImpl(type.getAttributes(), type.getConstructor(), false, type.getArguments(), type.getMemberScope());
return new JetTypeImpl(type.getAttributes(), type.getConstructor(), nullable, type.getArguments(), type.getMemberScope());
}
@Nullable
......
......@@ -405,6 +405,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
assertType("1 !== null", "Boolean");
assertType("true && false", "Boolean");
assertType("true || false", "Boolean");
assertType("null ?: false", "Boolean");
}
private void assertSubtype(String type1, String type2) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册