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.base.Predicates; 020 import com.intellij.openapi.project.Project; 021 import com.intellij.openapi.util.text.StringUtil; 022 import com.intellij.openapi.vfs.VirtualFile; 023 import com.intellij.psi.PsiFile; 024 import com.intellij.psi.PsiManager; 025 import kotlin.Function1; 026 import kotlin.Unit; 027 import org.jetbrains.annotations.NotNull; 028 import org.jetbrains.annotations.Nullable; 029 import org.jetbrains.kotlin.analyzer.AnalysisResult; 030 import org.jetbrains.kotlin.descriptors.ModuleDescriptor; 031 import org.jetbrains.kotlin.js.analyze.TopDownAnalyzerFacadeForJS; 032 import org.jetbrains.kotlin.psi.JetFile; 033 import org.jetbrains.kotlin.psi.JetPsiFactory; 034 import org.jetbrains.kotlin.resolve.BindingContext; 035 import org.jetbrains.kotlin.utils.PathUtil; 036 037 import java.io.IOException; 038 import java.util.Arrays; 039 import java.util.Collections; 040 import java.util.List; 041 042 public class LibrarySourcesConfigWithCaching extends LibrarySourcesConfig { 043 public static final List<String> JS_STDLIB = 044 Arrays.asList(PathUtil.getKotlinPathsForDistDirectory().getJsStdLibJarPath().getAbsolutePath()); 045 046 private static List<JetFile> jsLibFiles; 047 private static AnalysisResult result; 048 049 private BindingContext libraryContext; 050 private ModuleDescriptor libraryModule; 051 052 private final boolean isUnitTestConfig; 053 054 public LibrarySourcesConfigWithCaching( 055 @NotNull Project project, 056 @NotNull String moduleId, 057 @NotNull EcmaVersion ecmaVersion, 058 boolean sourcemap, 059 boolean inlineEnabled, 060 boolean isUnitTestConfig 061 ) { 062 super(project, moduleId, JS_STDLIB, ecmaVersion, sourcemap, inlineEnabled); 063 this.isUnitTestConfig = isUnitTestConfig; 064 } 065 066 @NotNull 067 @Override 068 public List<JetFile> generateLibFiles() { 069 if (jsLibFiles == null) { 070 //noinspection AssignmentToStaticFieldFromInstanceMethod 071 jsLibFiles = super.generateLibFiles(); 072 } 073 return jsLibFiles; 074 } 075 076 077 078 @Nullable 079 @Override 080 public ModuleDescriptor getLibraryModule() { 081 if (libraryModule == null) { 082 libraryModule = getResult().getModuleDescriptor(); 083 } 084 085 return libraryModule; 086 } 087 088 @Nullable 089 @Override 090 public BindingContext getLibraryContext() { 091 if (libraryContext == null) { 092 //TODO check errors? 093 // TopDownAnalyzerFacadeForJS.checkForErrors(allLibFiles, result.getBindingContext()); 094 libraryContext = getResult().getBindingContext(); 095 } 096 097 return libraryContext; 098 } 099 100 @Override 101 public boolean isTestConfig() { 102 return isUnitTestConfig; 103 } 104 105 @Override 106 protected JetFile getJetFileByVirtualFile(VirtualFile file, String moduleName, PsiManager psiManager) { 107 JetFile jetFile; 108 try { 109 String text = StringUtil.convertLineSeparators(new String(file.contentsToByteArray(false), file.getCharset())); 110 jetFile = new JetPsiFactory(getProject()).createPhysicalFile(file.getName(), text); 111 } 112 catch (IOException e) { 113 JetFile jetFileByVirtualFile = super.getJetFileByVirtualFile(file, moduleName, psiManager); 114 jetFile = new JetPsiFactory(getProject()).createPhysicalFile(file.getPath(), jetFileByVirtualFile.getText()); 115 } 116 117 setupPsiFile(jetFile, moduleName); 118 return jetFile; 119 } 120 121 private AnalysisResult getResult() { 122 if (result == null) { 123 //noinspection AssignmentToStaticFieldFromInstanceMethod 124 result = TopDownAnalyzerFacadeForJS.analyzeFiles( 125 generateLibFiles(), 126 Predicates.<PsiFile>alwaysFalse(), 127 createConfigWithoutLibFiles(getProject(), getModuleId(), getTarget()) 128 ); 129 } 130 131 return result; 132 } 133 134 @NotNull 135 private static Config createConfigWithoutLibFiles(@NotNull Project project, @NotNull String moduleId, @NotNull EcmaVersion ecmaVersion) { 136 return new Config(project, moduleId, ecmaVersion, /* generate sourcemaps = */ false, /* inlineEnabled = */ false) { 137 @NotNull 138 @Override 139 protected List<JetFile> generateLibFiles() { 140 return Collections.emptyList(); 141 } 142 @Override 143 public boolean checkLibFilesAndReportErrors(@NotNull Function1<String, Unit> report) { 144 return false; 145 } 146 }; 147 } 148 }