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.jet.lang.descriptors.impl;
018    
019    import com.google.common.collect.Lists;
020    import com.google.common.collect.Maps;
021    import com.intellij.openapi.diagnostic.Logger;
022    import org.jetbrains.annotations.NotNull;
023    import org.jetbrains.annotations.Nullable;
024    import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
025    import org.jetbrains.jet.lang.descriptors.*;
026    import org.jetbrains.jet.lang.descriptors.annotations.Annotations;
027    import org.jetbrains.jet.lang.resolve.ImportPath;
028    import org.jetbrains.jet.lang.resolve.name.FqName;
029    import org.jetbrains.jet.lang.resolve.name.Name;
030    import org.jetbrains.jet.lang.types.TypeSubstitutor;
031    
032    import java.util.ArrayList;
033    import java.util.List;
034    import java.util.Map;
035    
036    public class ModuleDescriptorImpl extends DeclarationDescriptorImpl implements ModuleDescriptor {
037        private static final Logger LOG = Logger.getInstance(ModuleDescriptorImpl.class);
038    
039        private final Map<DependencyKind, List<PackageFragmentProvider>> prioritizedFragmentProviders = Maps.newHashMap();
040        private final List<PackageFragmentProvider> fragmentProviders = Lists.newArrayList();
041        private final CompositePackageFragmentProvider packageFragmentProvider = new CompositePackageFragmentProvider(fragmentProviders);
042        private final List<ImportPath> defaultImports;
043        private final PlatformToKotlinClassMap platformToKotlinClassMap;
044    
045        public ModuleDescriptorImpl(
046                @NotNull Name name,
047                @NotNull List<ImportPath> defaultImports,
048                @NotNull PlatformToKotlinClassMap platformToKotlinClassMap
049        ) {
050            super(Annotations.EMPTY, name);
051            if (!name.isSpecial()) {
052                throw new IllegalArgumentException("module name must be special: " + name);
053            }
054            this.defaultImports = defaultImports;
055            this.platformToKotlinClassMap = platformToKotlinClassMap;
056        }
057    
058        public void addFragmentProvider(@NotNull DependencyKind dependencyKind, @NotNull PackageFragmentProvider provider) {
059            if (fragmentProviders.contains(provider)) {
060                LOG.error("Trying to add already present fragment provider: " + provider);
061            }
062            List<PackageFragmentProvider> providers = prioritizedFragmentProviders.get(dependencyKind);
063            if (providers == null) {
064                providers = new ArrayList<PackageFragmentProvider>(1);
065                prioritizedFragmentProviders.put(dependencyKind, providers);
066            }
067            providers.add(provider);
068            buildProvidersList();
069        }
070    
071        private void buildProvidersList() {
072            fragmentProviders.clear();
073            for (DependencyKind dependencyKind : DependencyKind.values()) {
074                List<PackageFragmentProvider> providers = prioritizedFragmentProviders.get(dependencyKind);
075                if (providers != null) {
076                    fragmentProviders.addAll(providers);
077                }
078            }
079        }
080    
081        @Override
082        @Nullable
083        public DeclarationDescriptor getContainingDeclaration() {
084            return null;
085        }
086    
087        @NotNull
088        @Override
089        public PackageFragmentProvider getPackageFragmentProvider() {
090            return packageFragmentProvider;
091        }
092    
093        @Nullable
094        @Override
095        public PackageViewDescriptor getPackage(@NotNull FqName fqName) {
096            List<PackageFragmentDescriptor> fragments = packageFragmentProvider.getPackageFragments(fqName);
097            return !fragments.isEmpty() ? new PackageViewDescriptorImpl(this, fqName, fragments) : null;
098        }
099    
100        @NotNull
101        @Override
102        public List<ImportPath> getDefaultImports() {
103            return defaultImports;
104        }
105    
106        @NotNull
107        @Override
108        public PlatformToKotlinClassMap getPlatformToKotlinClassMap() {
109            return platformToKotlinClassMap;
110        }
111    
112        @NotNull
113        @Override
114        public ModuleDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
115            return this;
116        }
117    
118        @Override
119        public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
120            return visitor.visitModuleDeclaration(this, data);
121        }
122    }