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.codegen.state; 018 019 import com.intellij.openapi.project.Project; 020 import org.jetbrains.annotations.NotNull; 021 import org.jetbrains.annotations.Nullable; 022 import org.jetbrains.kotlin.builtins.ReflectionTypes; 023 import org.jetbrains.kotlin.codegen.*; 024 import org.jetbrains.kotlin.codegen.binding.CodegenBinding; 025 import org.jetbrains.kotlin.codegen.extensions.ClassBuilderInterceptorExtension; 026 import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods; 027 import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory; 028 import org.jetbrains.kotlin.codegen.when.MappingsClassesForWhenByEnum; 029 import org.jetbrains.kotlin.descriptors.ModuleDescriptor; 030 import org.jetbrains.kotlin.descriptors.ScriptDescriptor; 031 import org.jetbrains.kotlin.diagnostics.DiagnosticSink; 032 import org.jetbrains.kotlin.name.FqName; 033 import org.jetbrains.kotlin.psi.JetClassOrObject; 034 import org.jetbrains.kotlin.psi.JetFile; 035 import org.jetbrains.kotlin.psi.JetScript; 036 import org.jetbrains.kotlin.resolve.BindingContext; 037 import org.jetbrains.kotlin.resolve.BindingTrace; 038 import org.jetbrains.kotlin.resolve.DelegatingBindingTrace; 039 040 import java.io.File; 041 import java.util.Collection; 042 import java.util.Collections; 043 import java.util.List; 044 045 public class GenerationState { 046 public interface GenerateClassFilter { 047 boolean shouldAnnotateClass(JetClassOrObject classOrObject); 048 boolean shouldGenerateClass(JetClassOrObject classOrObject); 049 boolean shouldGeneratePackagePart(JetFile jetFile); 050 boolean shouldGenerateScript(JetScript script); 051 052 GenerateClassFilter GENERATE_ALL = new GenerateClassFilter() { 053 @Override 054 public boolean shouldAnnotateClass(JetClassOrObject classOrObject) { 055 return true; 056 } 057 058 @Override 059 public boolean shouldGenerateClass(JetClassOrObject classOrObject) { 060 return true; 061 } 062 063 @Override 064 public boolean shouldGenerateScript(JetScript script) { 065 return true; 066 } 067 068 @Override 069 public boolean shouldGeneratePackagePart(JetFile jetFile) { 070 return true; 071 } 072 }; 073 } 074 075 private boolean used = false; 076 077 @NotNull 078 private final Progress progress; 079 080 @NotNull 081 private final List<JetFile> files; 082 083 @NotNull 084 private final ClassBuilderMode classBuilderMode; 085 086 @NotNull 087 private final BindingContext bindingContext; 088 089 @NotNull 090 private final ClassFileFactory classFileFactory; 091 092 @NotNull 093 private final Project project; 094 095 @NotNull 096 private final IntrinsicMethods intrinsics; 097 098 @NotNull 099 private final SamWrapperClasses samWrapperClasses = new SamWrapperClasses(this); 100 101 @NotNull 102 private final InlineCycleReporter inlineCycleReporter; 103 104 @NotNull 105 private final MappingsClassesForWhenByEnum mappingsClassesForWhenByEnum = new MappingsClassesForWhenByEnum(this); 106 107 @NotNull 108 private final BindingTrace bindingTrace; 109 110 @NotNull 111 private final JetTypeMapper typeMapper; 112 113 private final boolean disableCallAssertions; 114 115 private final boolean disableParamAssertions; 116 117 private final GenerateClassFilter generateClassFilter; 118 119 private final boolean disableInline; 120 121 @Nullable 122 private List<ScriptDescriptor> earlierScriptsForReplInterpreter; 123 124 private final ReflectionTypes reflectionTypes; 125 126 private final JvmRuntimeTypes runtimeTypes; 127 128 @NotNull 129 private final ModuleDescriptor module; 130 131 private final DiagnosticSink diagnostics; 132 133 @NotNull 134 private final Collection<FqName> packagesWithObsoleteParts; 135 136 @Nullable 137 private final String moduleId; // for PackageCodegen in incremental compilation mode 138 139 @Nullable 140 private final File outDirectory; // TODO: temporary hack, see JetTypeMapperWithOutDirectory state for details 141 142 @NotNull 143 private final ClassBuilderFactory interceptedBuilderFactory; 144 145 public GenerationState( 146 @NotNull Project project, 147 @NotNull ClassBuilderFactory builderFactory, 148 @NotNull ModuleDescriptor module, 149 @NotNull BindingContext bindingContext, 150 @NotNull List<JetFile> files 151 ) { 152 this(project, builderFactory, Progress.DEAF, module, bindingContext, files, true, true, GenerateClassFilter.GENERATE_ALL, 153 false, false, null, null, DiagnosticSink.DO_NOTHING, null); 154 } 155 156 public GenerationState( 157 @NotNull Project project, 158 @NotNull ClassBuilderFactory builderFactory, 159 @NotNull Progress progress, 160 @NotNull ModuleDescriptor module, 161 @NotNull BindingContext bindingContext, 162 @NotNull List<JetFile> files, 163 boolean disableCallAssertions, 164 boolean disableParamAssertions, 165 GenerateClassFilter generateClassFilter, 166 boolean disableInline, 167 boolean disableOptimization, 168 @Nullable Collection<FqName> packagesWithObsoleteParts, 169 @Nullable String moduleId, 170 @NotNull DiagnosticSink diagnostics, 171 @Nullable File outDirectory 172 ) { 173 this.project = project; 174 this.progress = progress; 175 this.module = module; 176 this.files = files; 177 this.moduleId = moduleId; 178 this.packagesWithObsoleteParts = packagesWithObsoleteParts == null ? Collections.<FqName>emptySet() : packagesWithObsoleteParts; 179 this.classBuilderMode = builderFactory.getClassBuilderMode(); 180 this.disableInline = disableInline; 181 182 this.bindingTrace = new DelegatingBindingTrace(bindingContext, "trace in GenerationState"); 183 this.bindingContext = bindingTrace.getBindingContext(); 184 185 this.outDirectory = outDirectory; 186 this.typeMapper = new JetTypeMapperWithOutDirectory(this.bindingContext, classBuilderMode, outDirectory); 187 188 this.intrinsics = new IntrinsicMethods(); 189 190 if (!disableOptimization) { 191 builderFactory = new OptimizationClassBuilderFactory(builderFactory); 192 } 193 194 ClassBuilderFactory interceptedBuilderFactory = new BuilderFactoryForDuplicateSignatureDiagnostics( 195 builderFactory, this.bindingContext, diagnostics); 196 197 Collection<ClassBuilderInterceptorExtension> interceptExtensions = 198 ClassBuilderInterceptorExtension.Companion.getInstances(project); 199 200 for (ClassBuilderInterceptorExtension extension : interceptExtensions) { 201 interceptedBuilderFactory = extension.interceptClassBuilderFactory(interceptedBuilderFactory, bindingContext, diagnostics); 202 } 203 204 this.interceptedBuilderFactory = interceptedBuilderFactory; 205 206 this.diagnostics = diagnostics; 207 this.classFileFactory = new ClassFileFactory(this, interceptedBuilderFactory); 208 209 this.disableCallAssertions = disableCallAssertions; 210 this.disableParamAssertions = disableParamAssertions; 211 this.generateClassFilter = generateClassFilter; 212 213 this.reflectionTypes = new ReflectionTypes(module); 214 this.runtimeTypes = new JvmRuntimeTypes(); 215 216 this.inlineCycleReporter = new InlineCycleReporter(diagnostics); 217 } 218 219 @NotNull 220 public ClassFileFactory getFactory() { 221 return classFileFactory; 222 } 223 224 @NotNull 225 public Progress getProgress() { 226 return progress; 227 } 228 229 @NotNull 230 public BindingContext getBindingContext() { 231 return bindingContext; 232 } 233 234 @NotNull 235 public ClassBuilderMode getClassBuilderMode() { 236 return classBuilderMode; 237 } 238 239 @NotNull 240 public List<JetFile> getFiles() { 241 return files; 242 } 243 244 @NotNull 245 public BindingTrace getBindingTrace() { 246 return bindingTrace; 247 } 248 249 @NotNull 250 public JetTypeMapper getTypeMapper() { 251 return typeMapper; 252 } 253 254 @NotNull 255 public Project getProject() { 256 return project; 257 } 258 259 @NotNull 260 public IntrinsicMethods getIntrinsics() { 261 return intrinsics; 262 } 263 264 @NotNull 265 public SamWrapperClasses getSamWrapperClasses() { 266 return samWrapperClasses; 267 } 268 269 @NotNull 270 public InlineCycleReporter getInlineCycleReporter() { 271 return inlineCycleReporter; 272 } 273 274 @NotNull 275 public MappingsClassesForWhenByEnum getMappingsClassesForWhenByEnum() { 276 return mappingsClassesForWhenByEnum; 277 } 278 279 public boolean isCallAssertionsEnabled() { 280 return !disableCallAssertions; 281 } 282 283 public boolean isParamAssertionsEnabled() { 284 return !disableParamAssertions; 285 } 286 287 @NotNull 288 public GenerateClassFilter getGenerateDeclaredClassFilter() { 289 return generateClassFilter; 290 } 291 292 @NotNull 293 public ReflectionTypes getReflectionTypes() { 294 return reflectionTypes; 295 } 296 297 @NotNull 298 public JvmRuntimeTypes getJvmRuntimeTypes() { 299 return runtimeTypes; 300 } 301 302 @NotNull 303 public DiagnosticSink getDiagnostics() { 304 return diagnostics; 305 } 306 307 public boolean isInlineEnabled() { 308 return !disableInline; 309 } 310 311 public void beforeCompile() { 312 markUsed(); 313 314 CodegenBinding.initTrace(this); 315 } 316 317 private void markUsed() { 318 if (used) { 319 throw new IllegalStateException(GenerationState.class + " cannot be used more than once"); 320 } 321 used = true; 322 } 323 324 public void destroy() { 325 interceptedBuilderFactory.close(); 326 } 327 328 @Nullable 329 public List<ScriptDescriptor> getEarlierScriptsForReplInterpreter() { 330 return earlierScriptsForReplInterpreter; 331 } 332 333 public void setEarlierScriptsForReplInterpreter(@Nullable List<ScriptDescriptor> earlierScriptsForReplInterpreter) { 334 this.earlierScriptsForReplInterpreter = earlierScriptsForReplInterpreter; 335 } 336 337 @NotNull 338 public ModuleDescriptor getModule() { 339 return module; 340 } 341 342 @NotNull 343 public Collection<FqName> getPackagesWithObsoleteParts() { 344 return packagesWithObsoleteParts; 345 } 346 347 @Nullable 348 public String getModuleId() { 349 return moduleId; 350 } 351 352 @Nullable 353 public File getOutDirectory() { 354 return outDirectory; 355 } 356 }