From 4b24c96ccadca38ed5266e86d7c892be0d308cd3 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 24 Sep 2014 18:02:40 +0400 Subject: [PATCH] Type capabilities introduced to facilitate extensibility of the type representation This approach: returning adapter objects by class is crucial, because it is delegation-proof. Simply extending interfaces in particular implementations fails when we wrap types in DelegatedType subclasses --- .../jet/lang/types/AbstractJetType.java | 12 +++++++++++ .../jet/lang/types/DelegatingType.java | 11 ++++++++++ .../jetbrains/jet/lang/types/ErrorUtils.java | 6 ++++++ .../org/jetbrains/jet/lang/types/JetType.java | 4 ++++ .../jet/lang/types/TypeCapabilities.kt | 21 +++++++++++++++++++ .../jetbrains/jet/lang/types/TypeUtils.java | 6 ++++++ 6 files changed, 60 insertions(+) create mode 100644 core/descriptors/src/org/jetbrains/jet/lang/types/TypeCapabilities.kt diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java index d72b6c6655f..12083b48c02 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/AbstractJetType.java @@ -16,12 +16,24 @@ package org.jetbrains.jet.lang.types; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import java.util.Iterator; import java.util.List; public abstract class AbstractJetType extends InflexibleType { + @Nullable + @Override + public T getCapability(@NotNull Class capabilityClass) { + if (capabilityClass.isInstance(this)) { + //noinspection unchecked + return (T) this; + } + return null; + } + @Override public final int hashCode() { int result = getConstructor().hashCode(); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java index 4217a45c566..c0206fbad3d 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/DelegatingType.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.annotations.Annotations; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -76,6 +77,16 @@ public abstract class DelegatingType implements JetType { return getDelegate().getAnnotations(); } + @Override + @Nullable + public T getCapability(@NotNull Class capabilityClass) { + if (capabilityClass.isInstance(this)) { + //noinspection unchecked + return (T) this; + } + return getDelegate().getCapability(capabilityClass); + } + @Override public int hashCode() { return getDelegate().hashCode(); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java index 5f52963d46d..559faa8421e 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -421,6 +421,12 @@ public class ErrorUtils { return Annotations.EMPTY; } + @Nullable + @Override + public T getCapability(@NotNull Class capabilityClass) { + return null; + } + @Override public String toString() { return constructor.toString(); diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java b/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java index 9d2d4348273..0e0a58d75f4 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/JetType.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.types; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.ReadOnly; import org.jetbrains.jet.lang.descriptors.annotations.Annotated; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -53,4 +54,7 @@ public interface JetType extends Annotated { // isFlexible() == false <=> getLowerBound() == getUpperBound() boolean isFlexible(); + + @Nullable + T getCapability(@NotNull Class capabilityClass); } diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeCapabilities.kt b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeCapabilities.kt new file mode 100644 index 00000000000..125f30cdf64 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeCapabilities.kt @@ -0,0 +1,21 @@ +/* + * Copyright 2010-2014 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.types + +import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor + +public trait TypeCapability \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java index 33965c7dfdf..8208b931b9c 100644 --- a/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java +++ b/core/descriptors/src/org/jetbrains/jet/lang/types/TypeUtils.java @@ -85,6 +85,12 @@ public class TypeUtils { throw new IllegalStateException(name); } + @Nullable + @Override + public T getCapability(@NotNull Class capabilityClass) { + return null; + } + @Override public String toString() { return name;