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.collections.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 }