001    /*
002     * Copyright 2010-2013 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.k2js.translate.intrinsic.functions.patterns;
018    
019    import com.google.common.collect.Lists;
020    import org.jetbrains.annotations.NotNull;
021    import org.jetbrains.annotations.Nullable;
022    import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
023    import org.jetbrains.jet.lang.resolve.DescriptorUtils;
024    import org.jetbrains.jet.lang.resolve.name.Name;
025    
026    import java.util.Arrays;
027    import java.util.List;
028    
029    public final class PatternBuilder {
030    
031        @NotNull
032        private static final NamePredicate JET = new NamePredicate("jet");
033    
034        private PatternBuilder() {
035        }
036    
037        @NotNull
038        public static DescriptorPredicate pattern(@NotNull NamePredicate checker, @NotNull String stringWithPattern) {
039            List<NamePredicate> checkers = Lists.newArrayList(checker);
040            checkers.addAll(parseStringAsCheckerList(stringWithPattern));
041            return pattern(checkers);
042        }
043    
044        @NotNull
045        public static DescriptorPredicate pattern(@NotNull String stringWithPattern, @NotNull NamePredicate checker) {
046            List<NamePredicate> checkers = Lists.newArrayList(parseStringAsCheckerList(stringWithPattern));
047            checkers.add(checker);
048            return pattern(checkers);
049        }
050    
051        @NotNull
052        public static DescriptorPredicate pattern(@NotNull String string) {
053            List<NamePredicate> checkers = parseStringAsCheckerList(string);
054            return pattern(checkers);
055        }
056    
057        @NotNull
058        private static List<NamePredicate> parseStringAsCheckerList(@NotNull String stringWithPattern) {
059            String[] subPatterns = stringWithPattern.split("\\.");
060            List<NamePredicate> checkers = Lists.newArrayList();
061            for (String subPattern : subPatterns) {
062                String[] validNames = subPattern.split("\\|");
063                checkers.add(new NamePredicate(validNames));
064            }
065            return checkers;
066        }
067    
068        @NotNull
069        private static DescriptorPredicate pattern(@NotNull List<NamePredicate> checkers) {
070            final List<NamePredicate> checkersWithPrefixChecker = Lists.newArrayList(JET);
071            checkersWithPrefixChecker.addAll(checkers);
072            return new DescriptorPredicate() {
073                @Override
074                public boolean apply(@Nullable FunctionDescriptor descriptor) {
075                    assert descriptor != null;
076                    //TODO: no need to wrap if we check beforehand
077                    try {
078                        return doApply(descriptor);
079                    }
080                    catch (IllegalArgumentException e) {
081                        return false;
082                    }
083                }
084    
085                private boolean doApply(@NotNull FunctionDescriptor descriptor) {
086                    List<Name> nameParts = DescriptorUtils.getFQName(descriptor).pathSegments();
087                    if (nameParts.size() != checkersWithPrefixChecker.size()) {
088                        return false;
089                    }
090                    if (!allNamePartsValid(nameParts)) return false;
091                    return true;
092                }
093    
094                private boolean allNamePartsValid(@NotNull List<Name> nameParts) {
095                    for (int i = 0; i < nameParts.size(); ++i) {
096                        Name namePart = nameParts.get(i);
097                        NamePredicate correspondingPredicate = checkersWithPrefixChecker.get(i);
098                        if (!correspondingPredicate.apply(namePart)) {
099                            return false;
100                        }
101                    }
102                    return true;
103                }
104            };
105        }
106    
107        @NotNull
108        public static DescriptorPredicate pattern(@NotNull NamePredicate... checkers) {
109            return pattern(Arrays.asList(checkers));
110        }
111    }