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.Function1; 023 import kotlin.Unit; 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.CompositePackageFragmentProvider; 029 import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl; 030 import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS; 031 import org.jetbrains.kotlin.psi.JetFile; 032 import org.jetbrains.kotlin.serialization.js.KotlinJavascriptSerializationUtil; 033 import org.jetbrains.kotlin.utils.KotlinJavascriptMetadata; 034 035 import java.util.Collection; 036 import java.util.List; 037 038 /** 039 * Base class representing a configuration of translator. 040 */ 041 public abstract class Config { 042 private final boolean inlineEnabled; 043 044 @NotNull 045 private final Project project; 046 @NotNull 047 private final List<JetFile> sourceFilesFromLibraries = new SmartList<JetFile>(); 048 @NotNull 049 private final EcmaVersion target; 050 051 @NotNull 052 private final String moduleId; 053 054 private final boolean sourcemap; 055 056 @NotNull 057 protected final List<KotlinJavascriptMetadata> metadata = new SmartList<KotlinJavascriptMetadata>(); 058 059 @Nullable 060 private List<ModuleDescriptorImpl> moduleDescriptors = null; 061 062 private boolean initialized = false; 063 064 public Config( 065 @NotNull Project project, 066 @NotNull String moduleId, 067 @NotNull EcmaVersion ecmaVersion, 068 boolean sourcemap, 069 boolean inlineEnabled 070 ) { 071 this.project = project; 072 this.target = ecmaVersion; 073 this.moduleId = moduleId; 074 this.sourcemap = sourcemap; 075 this.inlineEnabled = inlineEnabled; 076 } 077 078 public boolean isSourcemap() { 079 return sourcemap; 080 } 081 082 public boolean isInlineEnabled() { 083 return inlineEnabled; 084 } 085 086 @NotNull 087 public Project getProject() { 088 return project; 089 } 090 091 @NotNull 092 public EcmaVersion getTarget() { 093 return target; 094 } 095 096 @NotNull 097 public String getModuleId() { 098 return moduleId; 099 } 100 101 public abstract boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report); 102 103 protected abstract void init(@NotNull List<JetFile> sourceFilesInLibraries, @NotNull List<KotlinJavascriptMetadata> metadata); 104 105 @NotNull 106 public List<ModuleDescriptorImpl> getModuleDescriptors() { 107 init(); 108 if (moduleDescriptors != null) return moduleDescriptors; 109 110 moduleDescriptors = new SmartList<ModuleDescriptorImpl>(); 111 for(KotlinJavascriptMetadata metadataEntry : metadata) { 112 moduleDescriptors.add(createModuleDescriptor(metadataEntry)); 113 } 114 115 return moduleDescriptors; 116 } 117 118 @NotNull 119 public List<JetFile> getSourceFilesFromLibraries() { 120 init(); 121 return sourceFilesFromLibraries; 122 } 123 124 125 public boolean isTestConfig() { 126 return false; 127 } 128 129 private void init() { 130 if (initialized) return; 131 132 init(sourceFilesFromLibraries, metadata); 133 initialized = true; 134 } 135 136 private static ModuleDescriptorImpl createModuleDescriptor(KotlinJavascriptMetadata metadata) { 137 ModuleDescriptorImpl moduleDescriptor = TopDownAnalyzerFacadeForJS.createJsModule("<" + metadata.getModuleName() + ">"); 138 139 List<PackageFragmentProvider> providers = KotlinJavascriptSerializationUtil 140 .getPackageFragmentProviders(moduleDescriptor, metadata.getBody()); 141 CompositePackageFragmentProvider compositePackageFragmentProvider = new CompositePackageFragmentProvider(providers); 142 143 moduleDescriptor.initialize(compositePackageFragmentProvider); 144 moduleDescriptor.addDependencyOnModule(moduleDescriptor); 145 moduleDescriptor.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule()); 146 moduleDescriptor.seal(); 147 148 return moduleDescriptor; 149 } 150 151 @NotNull 152 public static Collection<JetFile> withJsLibAdded(@NotNull Collection<JetFile> files, @NotNull Config config) { 153 Collection<JetFile> allFiles = Lists.newArrayList(); 154 allFiles.addAll(files); 155 allFiles.addAll(config.getSourceFilesFromLibraries()); 156 return allFiles; 157 } 158 }