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.config;
018    
019    import com.google.common.collect.Lists;
020    import com.intellij.openapi.project.Project;
021    import com.intellij.util.SmartList;
022    import kotlin.Unit;
023    import kotlin.jvm.functions.Function1;
024    import org.jetbrains.annotations.NotNull;
025    import org.jetbrains.annotations.Nullable;
026    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
027    import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
028    import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
029    import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS;
030    import org.jetbrains.kotlin.name.Name;
031    import org.jetbrains.kotlin.psi.JetFile;
032    import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil;
033    import org.jetbrains.kotlin.storage.LockBasedStorageManager;
034    import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata;
035    
036    import java.util.Collection;
037    import java.util.List;
038    
039    /**
040     * Base class representing a configuration of translator.
041     */
042    public abstract class Config {
043        private final boolean inlineEnabled;
044        @NotNull
045        private final Project project;
046        @NotNull
047        private final LockBasedStorageManager storageManager = new LockBasedStorageManager();
048        @NotNull
049        private final List<JetFile> sourceFilesFromLibraries = new SmartList<JetFile>();
050        @NotNull
051        private final EcmaVersion target;
052    
053        @NotNull
054        private final String moduleId;
055    
056        private final boolean sourcemap;
057        private final boolean metaInfo;
058    
059        @NotNull
060        protected final List<KotlinJavascriptMetadata> metadata = new SmartList<KotlinJavascriptMetadata>();
061    
062        @Nullable
063        private List<ModuleDescriptorImpl> moduleDescriptors = null;
064    
065        private boolean initialized = false;
066    
067        protected Config(
068                @NotNull Project project,
069                @NotNull String moduleId,
070                @NotNull EcmaVersion ecmaVersion,
071                boolean sourcemap,
072                boolean inlineEnabled,
073                boolean metaInfo
074        ) {
075            this.project = project;
076            this.target = ecmaVersion;
077            this.moduleId = moduleId;
078            this.sourcemap = sourcemap;
079            this.inlineEnabled = inlineEnabled;
080            this.metaInfo = metaInfo;
081        }
082    
083        public boolean isSourcemap() {
084            return sourcemap;
085        }
086    
087        public boolean isMetaInfo() {
088            return metaInfo;
089        }
090    
091        public boolean isInlineEnabled() {
092            return inlineEnabled;
093        }
094    
095        @NotNull
096        public Project getProject() {
097            return project;
098        }
099    
100        @NotNull
101        public EcmaVersion getTarget() {
102            return target;
103        }
104    
105        @NotNull
106        public String getModuleId() {
107            return moduleId;
108        }
109    
110        public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report);
111    
112        protected abstract void init(@NotNull List<JetFile> sourceFilesInLibraries, @NotNull List<KotlinJavascriptMetadata> metadata);
113    
114        @NotNull
115        public List<ModuleDescriptorImpl> getModuleDescriptors() {
116            init();
117            if (moduleDescriptors != null) return moduleDescriptors;
118    
119            moduleDescriptors = new SmartList<ModuleDescriptorImpl>();
120            for (KotlinJavascriptMetadata metadataEntry : metadata) {
121                moduleDescriptors.add(createModuleDescriptor(metadataEntry));
122            }
123            for (ModuleDescriptorImpl module : moduleDescriptors) {
124                setDependencies(module, moduleDescriptors);
125            }
126    
127            return moduleDescriptors;
128        }
129    
130        @NotNull
131        public List<JetFile> getSourceFilesFromLibraries() {
132            init();
133            return sourceFilesFromLibraries;
134        }
135    
136    
137        public boolean isTestConfig() {
138            return false;
139        }
140    
141        private void init() {
142            if (initialized) return;
143    
144            init(sourceFilesFromLibraries, metadata);
145            initialized = true;
146        }
147    
148        private ModuleDescriptorImpl createModuleDescriptor(KotlinJavascriptMetadata metadata) {
149            ModuleDescriptorImpl moduleDescriptor = new ModuleDescriptorImpl(
150                    Name.special("<" + metadata.getModuleName() + ">"), storageManager,
151                    TopDownAnalyzerFacadeForJS.JS_MODULE_PARAMETERS
152            );
153    
154            PackageFragmentProvider provider =
155                    KotlinJavascriptSerializationUtil.createPackageFragmentProvider(moduleDescriptor, metadata.getBody(), storageManager);
156    
157            moduleDescriptor.initialize(provider != null ? provider : PackageFragmentProvider.Empty.INSTANCE$);
158    
159            return moduleDescriptor;
160        }
161    
162        private static void setDependencies(ModuleDescriptorImpl module, List<ModuleDescriptorImpl> modules) {
163            for (ModuleDescriptorImpl moduleItem : modules) {
164                module.addDependencyOnModule(moduleItem);
165            }
166            module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule());
167            module.seal();
168        }
169    
170        @NotNull
171        public static Collection<JetFile> withJsLibAdded(@NotNull Collection<JetFile> files, @NotNull Config config) {
172            Collection<JetFile> allFiles = Lists.newArrayList();
173            allFiles.addAll(files);
174            allFiles.addAll(config.getSourceFilesFromLibraries());
175            return allFiles;
176        }
177    }