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