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.KotlinPackage;
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.builtins.KotlinBuiltIns;
028 import org.jetbrains.kotlin.descriptors.PackageFragmentProvider;
029 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl;
030 import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS;
031 import org.jetbrains.kotlin.name.Name;
032 import org.jetbrains.kotlin.psi.JetFile;
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<JetFile> sourceFilesFromLibraries = new SmartList<JetFile>();
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
061 @NotNull
062 protected final List<KotlinJavascriptMetadata> metadata = new SmartList<KotlinJavascriptMetadata>();
063
064 @Nullable
065 private List<ModuleDescriptorImpl> moduleDescriptors = null;
066
067 private boolean initialized = false;
068
069 protected Config(
070 @NotNull Project project,
071 @NotNull String moduleId,
072 @NotNull EcmaVersion ecmaVersion,
073 boolean sourcemap,
074 boolean inlineEnabled,
075 boolean metaInfo
076 ) {
077 this.project = project;
078 this.target = ecmaVersion;
079 this.moduleId = moduleId;
080 this.sourcemap = sourcemap;
081 this.inlineEnabled = inlineEnabled;
082 this.metaInfo = metaInfo;
083 }
084
085 public boolean isSourcemap() {
086 return sourcemap;
087 }
088
089 public boolean isMetaInfo() {
090 return metaInfo;
091 }
092
093 public boolean isInlineEnabled() {
094 return inlineEnabled;
095 }
096
097 @NotNull
098 public Project getProject() {
099 return project;
100 }
101
102 @NotNull
103 public EcmaVersion getTarget() {
104 return target;
105 }
106
107 @NotNull
108 public String getModuleId() {
109 return moduleId;
110 }
111
112 public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report);
113
114 protected abstract void init(@NotNull List<JetFile> sourceFilesInLibraries, @NotNull List<KotlinJavascriptMetadata> metadata);
115
116 @NotNull
117 public List<ModuleDescriptorImpl> getModuleDescriptors() {
118 init();
119 if (moduleDescriptors != null) return moduleDescriptors;
120
121 moduleDescriptors = new SmartList<ModuleDescriptorImpl>();
122 for (KotlinJavascriptMetadata metadataEntry : metadata) {
123 moduleDescriptors.add(createModuleDescriptor(metadataEntry));
124 }
125 for (ModuleDescriptorImpl module : moduleDescriptors) {
126 setDependencies(module, moduleDescriptors);
127 }
128
129 return moduleDescriptors;
130 }
131
132 @NotNull
133 public List<JetFile> getSourceFilesFromLibraries() {
134 init();
135 return sourceFilesFromLibraries;
136 }
137
138
139 public boolean isTestConfig() {
140 return false;
141 }
142
143 private void init() {
144 if (initialized) return;
145
146 init(sourceFilesFromLibraries, metadata);
147 initialized = true;
148 }
149
150 private ModuleDescriptorImpl createModuleDescriptor(KotlinJavascriptMetadata metadata) {
151 assert metadata.getIsAbiVersionCompatible() :
152 "expected abi version " + KotlinJavascriptMetadataUtils.ABI_VERSION + ", but metadata.abiVersion = " + metadata.getAbiVersion();
153
154 ModuleDescriptorImpl moduleDescriptor = new ModuleDescriptorImpl(
155 Name.special("<" + metadata.getModuleName() + ">"), storageManager,
156 TopDownAnalyzerFacadeForJS.JS_MODULE_PARAMETERS
157 );
158
159 PackageFragmentProvider provider =
160 KotlinJavascriptSerializationUtil.createPackageFragmentProvider(moduleDescriptor, metadata.getBody(), storageManager);
161
162 moduleDescriptor.initialize(provider != null ? provider : PackageFragmentProvider.Empty.INSTANCE$);
163
164 return moduleDescriptor;
165 }
166
167 private static void setDependencies(ModuleDescriptorImpl module, List<ModuleDescriptorImpl> modules) {
168 module.setDependencies(KotlinPackage.plus(modules, KotlinBuiltIns.getInstance().getBuiltInsModule()));
169 }
170
171 @NotNull
172 public static Collection<JetFile> withJsLibAdded(@NotNull Collection<JetFile> files, @NotNull Config config) {
173 Collection<JetFile> allFiles = Lists.newArrayList();
174 allFiles.addAll(files);
175 allFiles.addAll(config.getSourceFilesFromLibraries());
176 return allFiles;
177 }
178 }