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