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 }