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.collections.CollectionsKt;
024 import kotlin.jvm.functions.Function1;
025 import org.jetbrains.annotations.NotNull;
026 import org.jetbrains.annotations.Nullable;
027 import org.jetbrains.kotlin.config.LanguageVersionSettingsImpl;
028 import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
029 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
030 import org.jetbrains.kotlin.js.resolve.JsPlatform;
031 import org.jetbrains.kotlin.name.Name;
032 import org.jetbrains.kotlin.psi.KtFile;
033 import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration;
034 import org.jetbrains.kotlin.resolve.TargetPlatformKt;
035 import org.jetbrains.kotlin.serialization.js.JsModuleDescriptor;
036 import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil;
037 import org.jetbrains.kotlin.serialization.js.ModuleKind;
038 import org.jetbrains.kotlin.storage.LockBasedStorageManager;
039 import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata;
040 import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils;
041
042 import java.util.ArrayList;
043 import java.util.Collection;
044 import java.util.Collections;
045 import java.util.List;
046
047 /**
048 * Base class representing a configuration of translator.
049 */
050 public abstract class JsConfig {
051 private final boolean inlineEnabled;
052 @NotNull
053 private final Project project;
054 @NotNull
055 private final LockBasedStorageManager storageManager = new LockBasedStorageManager();
056 @NotNull
057 private final List<KtFile> sourceFilesFromLibraries = new SmartList<KtFile>();
058 @NotNull
059 private final EcmaVersion target;
060
061 @NotNull
062 private final String moduleId;
063
064 @NotNull
065 private final ModuleKind moduleKind;
066
067 private final boolean sourcemap;
068 private final boolean metaInfo;
069 private final boolean kjsm;
070
071 @NotNull
072 protected final List<KotlinJavascriptMetadata> metadata = new SmartList<KotlinJavascriptMetadata>();
073
074 @Nullable
075 private List<JsModuleDescriptor<ModuleDescriptorImpl>> moduleDescriptors = null;
076
077 private boolean initialized = false;
078
079 protected JsConfig(
080 @NotNull Project project,
081 @NotNull String moduleId,
082 @NotNull ModuleKind moduleKind,
083 @NotNull EcmaVersion ecmaVersion,
084 boolean sourcemap,
085 boolean inlineEnabled,
086 boolean metaInfo,
087 boolean kjsm
088 ) {
089 this.project = project;
090 this.target = ecmaVersion;
091 this.moduleId = moduleId;
092 this.moduleKind = moduleKind;
093 this.sourcemap = sourcemap;
094 this.inlineEnabled = inlineEnabled;
095 this.metaInfo = metaInfo;
096 this.kjsm = kjsm;
097 }
098
099 public boolean isSourcemap() {
100 return sourcemap;
101 }
102
103 public boolean isMetaInfo() {
104 return metaInfo;
105 }
106
107 public boolean isKjsm() {
108 return kjsm;
109 }
110
111 public boolean isInlineEnabled() {
112 return inlineEnabled;
113 }
114
115 @NotNull
116 public Project getProject() {
117 return project;
118 }
119
120 @NotNull
121 public String getModuleId() {
122 return moduleId;
123 }
124
125 @NotNull
126 public ModuleKind getModuleKind() {
127 return moduleKind;
128 }
129
130 public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report);
131
132 protected abstract void init(@NotNull List<KtFile> sourceFilesInLibraries, @NotNull List<KotlinJavascriptMetadata> metadata);
133
134 @NotNull
135 public List<JsModuleDescriptor<ModuleDescriptorImpl>> getModuleDescriptors() {
136 init();
137 if (moduleDescriptors != null) return moduleDescriptors;
138
139 moduleDescriptors = new SmartList<JsModuleDescriptor<ModuleDescriptorImpl>>();
140 List<ModuleDescriptorImpl> kotlinModuleDescriptors = new ArrayList<ModuleDescriptorImpl>();
141 for (KotlinJavascriptMetadata metadataEntry : metadata) {
142 JsModuleDescriptor<ModuleDescriptorImpl> descriptor = createModuleDescriptor(metadataEntry);
143 moduleDescriptors.add(descriptor);
144 kotlinModuleDescriptors.add(descriptor.getData());
145 }
146
147 for (JsModuleDescriptor<ModuleDescriptorImpl> module : moduleDescriptors) {
148 // TODO: remove downcast
149 setDependencies(module.getData(), kotlinModuleDescriptors);
150 }
151
152 moduleDescriptors = Collections.unmodifiableList(moduleDescriptors);
153
154 return moduleDescriptors;
155 }
156
157 @NotNull
158 public List<KtFile> getSourceFilesFromLibraries() {
159 init();
160 return sourceFilesFromLibraries;
161 }
162
163
164 public boolean isTestConfig() {
165 return false;
166 }
167
168 private void init() {
169 if (initialized) return;
170
171 init(sourceFilesFromLibraries, metadata);
172 initialized = true;
173 }
174
175 private JsModuleDescriptor<ModuleDescriptorImpl> createModuleDescriptor(KotlinJavascriptMetadata metadata) {
176 assert metadata.isAbiVersionCompatible() :
177 "expected abi version " + KotlinJavascriptMetadataUtils.ABI_VERSION +
178 ", but metadata.abiVersion = " + metadata.getAbiVersion();
179
180 ModuleDescriptorImpl moduleDescriptor = TargetPlatformKt.createModule(
181 JsPlatform.INSTANCE, Name.special("<" + metadata.getModuleName() + ">"), storageManager
182 );
183
184 JsModuleDescriptor<PackageFragmentProvider> rawDescriptor = KotlinJavascriptSerializationUtil.readModule(
185 metadata.getBody(), storageManager, moduleDescriptor, new CompilerDeserializationConfiguration(
186 LanguageVersionSettingsImpl.DEFAULT
187 )
188 );
189
190 PackageFragmentProvider provider = rawDescriptor.getData();
191 moduleDescriptor.initialize(provider != null ? provider : PackageFragmentProvider.Empty.INSTANCE);
192
193 return rawDescriptor.copy(moduleDescriptor);
194 }
195
196 private static void setDependencies(ModuleDescriptorImpl module, List<ModuleDescriptorImpl> modules) {
197 module.setDependencies(CollectionsKt.plus(modules, JsPlatform.INSTANCE.getBuiltIns().getBuiltInsModule()));
198 }
199
200 @NotNull
201 public static Collection<KtFile> withJsLibAdded(@NotNull Collection<KtFile> files, @NotNull JsConfig config) {
202 Collection<KtFile> allFiles = Lists.newArrayList();
203 allFiles.addAll(files);
204 allFiles.addAll(config.getSourceFilesFromLibraries());
205 return allFiles;
206 }
207 }