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