java 2 kt: InlineAnalyzerExtension, convert

This commit is contained in:
Dmitry Petrov
2016-04-19 11:12:07 +03:00
parent 4c1694493a
commit ef0f512201
@@ -16,134 +16,113 @@
package org.jetbrains.kotlin.resolve.inline; package org.jetbrains.kotlin.resolve.inline;
import com.intellij.psi.PsiElement; import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.diagnostics.Errors; import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.lexer.KtTokens; import org.jetbrains.kotlin.resolve.FunctionAnalyzerExtension
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.annotations.isInlineOnlyOrReified
import org.jetbrains.kotlin.resolve.BindingTrace; import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
import org.jetbrains.kotlin.resolve.FunctionAnalyzerExtension;
import org.jetbrains.kotlin.resolve.annotations.AnnotationUtilKt;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilsKt;
import java.util.List; object InlineAnalyzerExtension : FunctionAnalyzerExtension.AnalyzerExtension {
public class InlineAnalyzerExtension implements FunctionAnalyzerExtension.AnalyzerExtension { override fun process(descriptor: FunctionDescriptor, function: KtNamedFunction, trace: BindingTrace) {
assert(InlineUtil.isInline(descriptor)) { "This method should be invoked on inline function: " + descriptor }
public static final InlineAnalyzerExtension INSTANCE = new InlineAnalyzerExtension(); checkDefaults(descriptor, function, trace)
checkNotVirtual(descriptor, function, trace)
checkHasInlinableAndNullability(descriptor, function, trace)
private InlineAnalyzerExtension() { val visitor = object : KtVisitorVoid() {
} override fun visitKtElement(element: KtElement) {
super.visitKtElement(element)
@Override element.acceptChildren(this)
public void process(
@NotNull final FunctionDescriptor descriptor, @NotNull KtNamedFunction function, @NotNull final BindingTrace trace
) {
assert InlineUtil.isInline(descriptor) : "This method should be invoked on inline function: " + descriptor;
checkDefaults(descriptor, function, trace);
checkNotVirtual(descriptor, function, trace);
checkHasInlinableAndNullability(descriptor, function, trace);
KtVisitorVoid visitor = new KtVisitorVoid() {
@Override
public void visitKtElement(@NotNull KtElement element) {
super.visitKtElement(element);
element.acceptChildren(this);
} }
@Override override fun visitClass(klass: KtClass) {
public void visitClass(@NotNull KtClass klass) { trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(klass, klass, descriptor))
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(klass, klass, descriptor));
} }
@Override override fun visitNamedFunction(function: KtNamedFunction) {
public void visitNamedFunction(@NotNull KtNamedFunction function) { if (function.parent.parent is KtObjectDeclaration) {
if (function.getParent().getParent() instanceof KtObjectDeclaration) { super.visitNamedFunction(function)
super.visitNamedFunction(function); }
} else { else {
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(function, function, descriptor)); trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(function, function, descriptor))
} }
} }
}; }
function.acceptChildren(visitor); function.acceptChildren(visitor)
} }
private static void checkDefaults( private fun checkDefaults(
@NotNull FunctionDescriptor functionDescriptor, functionDescriptor: FunctionDescriptor,
@NotNull KtFunction function, function: KtFunction,
@NotNull BindingTrace trace trace: BindingTrace) {
) { val ktParameters = function.valueParameters
List<KtParameter> jetParameters = function.getValueParameters(); for (parameter in functionDescriptor.valueParameters) {
for (ValueParameterDescriptor parameter : functionDescriptor.getValueParameters()) { if (parameter.hasDefaultValue()) {
if (DescriptorUtilsKt.hasDefaultValue(parameter)) { val ktParameter = ktParameters[parameter.index]
KtParameter jetParameter = jetParameters.get(parameter.getIndex()); //report unsupported default only on inlinable lambda and on parameter with inherited default (there is some problems to inline it)
//report not supported default only on inlinable lambda and on parameter with inherited default (there is some problems to inline it) if (checkInlinableParameter(parameter, ktParameter, functionDescriptor, null) || !parameter.declaresDefaultValue()) {
if (checkInlinableParameter(parameter, jetParameter, functionDescriptor, null) || !parameter.declaresDefaultValue()) { trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(ktParameter, ktParameter, functionDescriptor))
trace.report(Errors.NOT_YET_SUPPORTED_IN_INLINE.on(jetParameter, jetParameter, functionDescriptor));
} }
} }
} }
} }
private static void checkNotVirtual( private fun checkNotVirtual(
@NotNull FunctionDescriptor functionDescriptor, functionDescriptor: FunctionDescriptor,
@NotNull KtFunction function, function: KtFunction,
@NotNull BindingTrace trace trace: BindingTrace) {
) { if (Visibilities.isPrivate(functionDescriptor.visibility) || functionDescriptor.modality === Modality.FINAL) {
if (Visibilities.isPrivate(functionDescriptor.getVisibility()) || functionDescriptor.getModality() == Modality.FINAL) { return
return;
} }
if (functionDescriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor) { if (functionDescriptor.containingDeclaration is PackageFragmentDescriptor) {
return; return
} }
trace.report(Errors.DECLARATION_CANT_BE_INLINED.on(function)); trace.report(Errors.DECLARATION_CANT_BE_INLINED.on(function))
} }
private static void checkHasInlinableAndNullability( private fun checkHasInlinableAndNullability(
@NotNull FunctionDescriptor functionDescriptor, functionDescriptor: FunctionDescriptor,
@NotNull KtFunction function, function: KtFunction,
@NotNull BindingTrace trace trace: BindingTrace) {
) { var hasInlinable = false
boolean hasInlinable = false; val parameters = functionDescriptor.valueParameters
List<ValueParameterDescriptor> parameters = functionDescriptor.getValueParameters(); var index = 0
int index = 0; for (parameter in parameters) {
for (ValueParameterDescriptor parameter : parameters) { hasInlinable = hasInlinable or checkInlinableParameter(parameter, function.valueParameters[index++], functionDescriptor, trace)
hasInlinable |= checkInlinableParameter(parameter, function.getValueParameters().get(index++), functionDescriptor, trace);
} }
hasInlinable |= InlineUtil.containsReifiedTypeParameters(functionDescriptor); hasInlinable = hasInlinable or InlineUtil.containsReifiedTypeParameters(functionDescriptor)
if (!hasInlinable && !AnnotationUtilKt.isInlineOnlyOrReified(functionDescriptor)) { if (!hasInlinable && !functionDescriptor.isInlineOnlyOrReified()) {
KtModifierList modifierList = function.getModifierList(); val modifierList = function.modifierList
PsiElement inlineModifier = modifierList == null ? null : modifierList.getModifier(KtTokens.INLINE_KEYWORD); val inlineModifier = modifierList?.getModifier(KtTokens.INLINE_KEYWORD)
PsiElement reportOn = inlineModifier == null ? function : inlineModifier; val reportOn = inlineModifier ?: function
trace.report(Errors.NOTHING_TO_INLINE.on(reportOn, functionDescriptor)); trace.report(Errors.NOTHING_TO_INLINE.on(reportOn, functionDescriptor))
} }
} }
public static boolean checkInlinableParameter( fun checkInlinableParameter(
@NotNull ParameterDescriptor parameter, parameter: ParameterDescriptor,
@NotNull KtElement expression, expression: KtElement,
@NotNull CallableDescriptor functionDescriptor, functionDescriptor: CallableDescriptor,
@Nullable BindingTrace trace trace: BindingTrace?): Boolean {
) {
if (InlineUtil.isInlineLambdaParameter(parameter)) { if (InlineUtil.isInlineLambdaParameter(parameter)) {
if (parameter.getType().isMarkedNullable()) { if (parameter.type.isMarkedNullable) {
if (trace != null) { trace?.report(Errors.NULLABLE_INLINE_PARAMETER.on(expression, expression, functionDescriptor))
trace.report(Errors.NULLABLE_INLINE_PARAMETER.on(expression, expression, functionDescriptor));
}
} }
else { else {
return true; return true
} }
} }
return false; return false
} }
} }