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 }