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 JvmRuntimeTypes runtimeTypes; 121 122 @NotNull 123 private final ModuleDescriptor module; 124 125 @NotNull 126 private final Collection<FqName> packagesWithObsoleteParts; 127 128 @Nullable 129 private final String moduleId; // for PackageCodegen in incremental compilation mode 130 131 @Nullable 132 private final File outDirectory; // TODO: temporary hack, see JetTypeMapperWithOutDirectory state for details 133 134 public GenerationState( 135 @NotNull Project project, 136 @NotNull ClassBuilderFactory builderFactory, 137 @NotNull ModuleDescriptor module, 138 @NotNull BindingContext bindingContext, 139 @NotNull List<JetFile> files 140 ) { 141 this(project, builderFactory, Progress.DEAF, module, bindingContext, files, true, true, GenerateClassFilter.GENERATE_ALL, 142 false, false, null, null, DiagnosticSink.DO_NOTHING, null); 143 } 144 145 public GenerationState( 146 @NotNull Project project, 147 @NotNull ClassBuilderFactory builderFactory, 148 @NotNull Progress progress, 149 @NotNull ModuleDescriptor module, 150 @NotNull BindingContext bindingContext, 151 @NotNull List<JetFile> files, 152 boolean disableCallAssertions, 153 boolean disableParamAssertions, 154 GenerateClassFilter generateClassFilter, 155 boolean disableInline, 156 boolean disableOptimization, 157 @Nullable Collection<FqName> packagesWithObsoleteParts, 158 @Nullable String moduleId, 159 @NotNull DiagnosticSink diagnostics, 160 @Nullable File outDirectory 161 ) { 162 this.project = project; 163 this.progress = progress; 164 this.module = module; 165 this.files = files; 166 this.moduleId = moduleId; 167 this.packagesWithObsoleteParts = packagesWithObsoleteParts == null ? Collections.<FqName>emptySet() : packagesWithObsoleteParts; 168 this.classBuilderMode = builderFactory.getClassBuilderMode(); 169 this.disableInline = disableInline; 170 171 this.bindingTrace = new DelegatingBindingTrace(bindingContext, "trace in GenerationState"); 172 this.bindingContext = bindingTrace.getBindingContext(); 173 174 this.outDirectory = outDirectory; 175 this.typeMapper = new JetTypeMapperWithOutDirectory(this.bindingContext, classBuilderMode, outDirectory); 176 177 this.intrinsics = new IntrinsicMethods(); 178 179 if (!disableOptimization) { 180 builderFactory = new OptimizationClassBuilderFactory(builderFactory); 181 } 182 183 this.classFileFactory = new ClassFileFactory(this, new BuilderFactoryForDuplicateSignatureDiagnostics( 184 builderFactory, this.bindingContext, diagnostics)); 185 186 this.disableCallAssertions = disableCallAssertions; 187 this.disableParamAssertions = disableParamAssertions; 188 this.generateClassFilter = generateClassFilter; 189 190 ReflectionTypes reflectionTypes = new ReflectionTypes(module); 191 this.runtimeTypes = new JvmRuntimeTypes(reflectionTypes); 192 } 193 194 @NotNull 195 public ClassFileFactory getFactory() { 196 return classFileFactory; 197 } 198 199 @NotNull 200 public Progress getProgress() { 201 return progress; 202 } 203 204 @NotNull 205 public BindingContext getBindingContext() { 206 return bindingContext; 207 } 208 209 @NotNull 210 public ClassBuilderMode getClassBuilderMode() { 211 return classBuilderMode; 212 } 213 214 @NotNull 215 public List<JetFile> getFiles() { 216 return files; 217 } 218 219 @NotNull 220 public BindingTrace getBindingTrace() { 221 return bindingTrace; 222 } 223 224 @NotNull 225 public JetTypeMapper getTypeMapper() { 226 return typeMapper; 227 } 228 229 @NotNull 230 public Project getProject() { 231 return project; 232 } 233 234 @NotNull 235 public IntrinsicMethods getIntrinsics() { 236 return intrinsics; 237 } 238 239 @NotNull 240 public SamWrapperClasses getSamWrapperClasses() { 241 return samWrapperClasses; 242 } 243 244 @NotNull 245 public MappingsClassesForWhenByEnum getMappingsClassesForWhenByEnum() { 246 return mappingsClassesForWhenByEnum; 247 } 248 249 public boolean isCallAssertionsEnabled() { 250 return !disableCallAssertions; 251 } 252 253 public boolean isParamAssertionsEnabled() { 254 return !disableParamAssertions; 255 } 256 257 @NotNull 258 public GenerateClassFilter getGenerateDeclaredClassFilter() { 259 return generateClassFilter; 260 } 261 262 @NotNull 263 public JvmRuntimeTypes getJvmRuntimeTypes() { 264 return runtimeTypes; 265 } 266 267 public boolean isInlineEnabled() { 268 return !disableInline; 269 } 270 271 public void beforeCompile() { 272 markUsed(); 273 274 CodegenBinding.initTrace(this); 275 } 276 277 private void markUsed() { 278 if (used) { 279 throw new IllegalStateException(GenerationState.class + " cannot be used more than once"); 280 } 281 used = true; 282 } 283 284 public void destroy() { 285 } 286 287 @Nullable 288 public List<ScriptDescriptor> getEarlierScriptsForReplInterpreter() { 289 return earlierScriptsForReplInterpreter; 290 } 291 292 public void setEarlierScriptsForReplInterpreter(@Nullable List<ScriptDescriptor> earlierScriptsForReplInterpreter) { 293 this.earlierScriptsForReplInterpreter = earlierScriptsForReplInterpreter; 294 } 295 296 @NotNull 297 public ModuleDescriptor getModule() { 298 return module; 299 } 300 301 @NotNull 302 public Collection<FqName> getPackagesWithObsoleteParts() { 303 return packagesWithObsoleteParts; 304 } 305 306 @Nullable 307 public String getModuleId() { 308 return moduleId; 309 } 310 311 @Nullable 312 public File getOutDirectory() { 313 return outDirectory; 314 } 315 }