New diagnostic for non-local return annotation

This commit is contained in:
Michael Bogdanov
2014-06-10 11:34:06 +04:00
parent 8092717da4
commit da01a11137
26 changed files with 689 additions and 91 deletions
+8
View File
@@ -24,3 +24,11 @@ public enum class InlineStrategy {
AS_FUNCTION
IN_PLACE
}
public annotation class inlineOptions(vararg val value: InlineOption)
public enum class InlineOption {
LOCAL_CONTINUE_AND_BREAK
ONLY_LOCAL_RETURN
}
@@ -0,0 +1,22 @@
/*
* 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.lang;
public enum InlineOption {
LOCAL_CONTINUE_AND_BREAK,
ONLY_LOCAL_RETURN
}
@@ -23,9 +23,12 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
import org.jetbrains.jet.lang.resolve.constants.ArrayValue;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.EnumValue;
import java.util.List;
public class InlineUtil {
public static boolean hasNoinlineAnnotation(@NotNull CallableDescriptor valueParameterDescriptor) {
@@ -68,6 +71,40 @@ public class InlineUtil {
return null;
}
public static boolean hasOnlyLocalContinueAndBreak(@NotNull ValueParameterDescriptor descriptor) {
return hasInlineOption(descriptor, InlineOption.LOCAL_CONTINUE_AND_BREAK);
}
public static boolean hasOnlyLocalReturn(@NotNull ValueParameterDescriptor descriptor) {
return hasInlineOption(descriptor, InlineOption.ONLY_LOCAL_RETURN);
}
private static boolean hasInlineOption(@NotNull ValueParameterDescriptor descriptor, @NotNull InlineOption option) {
KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance();
ClassDescriptor annotationClass = builtIns.getInlineOptionsClassAnnotation();
AnnotationDescriptor optionsAnnotation = getAnnotation(descriptor.getAnnotations(), annotationClass);
if (optionsAnnotation != null) {
ValueParameterDescriptor parameterDescriptor = annotationClass.getConstructors().iterator().next().getValueParameters().get(0);
CompileTimeConstant<?> argument = optionsAnnotation.getValueArgument(parameterDescriptor);
if (argument == null) {
return false;
} else {
if (argument instanceof ArrayValue) {
List<CompileTimeConstant<?>> values = ((ArrayValue) argument).getValue();
for (CompileTimeConstant<?> value : values) {
if (value instanceof EnumValue) {
if (((EnumValue) value).getValue().getName().asString().equals(option.name())) {
return true;
}
}
}
}
}
}
return false;
}
}
@@ -307,6 +307,11 @@ public class KotlinBuiltIns {
return getBuiltInClassByName("inline");
}
@NotNull
public ClassDescriptor getInlineOptionsClassAnnotation() {
return getBuiltInClassByName("inlineOptions");
}
@NotNull
public ClassDescriptor getTailRecursiveAnnotationClass() {
return getBuiltInClassByName("tailRecursive");