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