001 /*
002 * Copyright 2010-2015 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.js.translate.general;
018
019 import com.google.common.collect.Lists;
020 import com.intellij.util.Function;
021 import com.intellij.util.containers.ContainerUtil;
022 import org.jetbrains.annotations.NotNull;
023 import org.jetbrains.kotlin.descriptors.ClassDescriptor;
024 import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
025 import org.jetbrains.kotlin.descriptors.FunctionDescriptor;
026 import org.jetbrains.kotlin.descriptors.Modality;
027 import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
028 import org.jetbrains.kotlin.descriptors.annotations.Annotations;
029 import org.jetbrains.kotlin.js.translate.utils.BindingUtils;
030 import org.jetbrains.kotlin.psi.JetClass;
031 import org.jetbrains.kotlin.psi.JetDeclaration;
032 import org.jetbrains.kotlin.psi.JetFile;
033 import org.jetbrains.kotlin.resolve.BindingContext;
034 import org.jetbrains.kotlin.resolve.scopes.JetScope;
035 import org.jetbrains.kotlin.types.JetType;
036
037 import java.util.Collection;
038 import java.util.List;
039
040 /**
041 * Helps find functions which are annotated with a @Test annotation from junit
042 */
043 public class JetTestFunctionDetector {
044 private JetTestFunctionDetector() {
045 }
046
047 private static boolean isTest(@NotNull FunctionDescriptor functionDescriptor) {
048 Annotations annotations = functionDescriptor.getAnnotations();
049 for (AnnotationDescriptor annotation : annotations) {
050 // TODO ideally we should find the fully qualified name here...
051 JetType type = annotation.getType();
052 String name = type.toString();
053 if (name.equals("Test")) {
054 return true;
055 }
056 }
057
058 /*
059 if (function.getName().startsWith("test")) {
060 List<JetParameter> parameters = function.getValueParameters();
061 return parameters.size() == 0;
062 }
063 */
064 return false;
065 }
066
067 @NotNull
068 public static List<FunctionDescriptor> getTestFunctionDescriptors(
069 @NotNull BindingContext bindingContext,
070 @NotNull Collection<JetFile> files
071 ) {
072 List<FunctionDescriptor> answer = Lists.newArrayList();
073 for (JetFile file : files) {
074 answer.addAll(getTestFunctions(bindingContext, file.getDeclarations()));
075 }
076 return answer;
077 }
078
079 @NotNull
080 private static List<FunctionDescriptor> getTestFunctions(
081 @NotNull BindingContext bindingContext,
082 @NotNull List<JetDeclaration> declarations
083 ) {
084 List<FunctionDescriptor> answer = Lists.newArrayList();
085 for (JetDeclaration declaration : declarations) {
086 JetScope scope = null;
087
088 if (declaration instanceof JetClass) {
089 JetClass klass = (JetClass) declaration;
090 ClassDescriptor classDescriptor = BindingUtils.getClassDescriptor(bindingContext, klass);
091
092 if (classDescriptor.getModality() != Modality.ABSTRACT) {
093 scope = classDescriptor.getDefaultType().getMemberScope();
094 }
095 }
096
097 if (scope != null) {
098 Collection<DeclarationDescriptor> allDescriptors = scope.getAllDescriptors();
099 List<FunctionDescriptor> testFunctions = ContainerUtil.mapNotNull(
100 allDescriptors,
101 new Function<DeclarationDescriptor, FunctionDescriptor>() {
102 @Override
103 public FunctionDescriptor fun(DeclarationDescriptor descriptor) {
104 if (descriptor instanceof FunctionDescriptor) {
105 FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor;
106 if (isTest(functionDescriptor)) return functionDescriptor;
107 }
108
109 return null;
110 }
111 });
112
113 answer.addAll(testFunctions);
114 }
115 }
116 return answer;
117 }
118 }