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.ClassBuilderFactory; 023 import org.jetbrains.jet.codegen.ClassBuilderMode; 024 import org.jetbrains.jet.codegen.ClassFileFactory; 025 import org.jetbrains.jet.codegen.SamWrapperClasses; 026 import org.jetbrains.jet.codegen.binding.CodegenBinding; 027 import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods; 028 import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; 029 import org.jetbrains.jet.lang.psi.JetClassOrObject; 030 import org.jetbrains.jet.lang.psi.JetFile; 031 import org.jetbrains.jet.lang.resolve.BindingContext; 032 import org.jetbrains.jet.lang.resolve.BindingTrace; 033 import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; 034 035 import java.util.List; 036 037 public class GenerationState { 038 public interface GenerateClassFilter { 039 boolean shouldProcess(JetClassOrObject classOrObject); 040 041 GenerateClassFilter ONLY_PACKAGE_CLASS = new GenerateClassFilter() { 042 @Override 043 public boolean shouldProcess(JetClassOrObject classOrObject) { 044 return false; 045 } 046 }; 047 048 GenerateClassFilter GENERATE_ALL = new GenerateClassFilter() { 049 @Override 050 public boolean shouldProcess(JetClassOrObject classOrObject) { 051 return true; 052 } 053 }; 054 } 055 056 private boolean used = false; 057 058 @NotNull 059 private final Progress progress; 060 061 @NotNull 062 private final List<JetFile> files; 063 064 @NotNull 065 private final ClassBuilderMode classBuilderMode; 066 067 @NotNull 068 private final BindingContext bindingContext; 069 070 @NotNull 071 private final ClassFileFactory classFileFactory; 072 073 @NotNull 074 private final Project project; 075 076 @NotNull 077 private final IntrinsicMethods intrinsics; 078 079 @NotNull 080 private final SamWrapperClasses samWrapperClasses = new SamWrapperClasses(this); 081 082 @NotNull 083 private final BindingTrace bindingTrace; 084 085 @NotNull 086 private final JetTypeMapper typeMapper; 087 088 private final boolean generateNotNullAssertions; 089 090 private final boolean generateNotNullParamAssertions; 091 092 private final GenerateClassFilter generateClassFilter; 093 094 private final boolean inlineEnabled; 095 096 @Nullable 097 private List<ScriptDescriptor> earlierScriptsForReplInterpreter; 098 099 public GenerationState( 100 @NotNull Project project, 101 @NotNull ClassBuilderFactory builderFactory, 102 @NotNull BindingContext bindingContext, 103 @NotNull List<JetFile> files, 104 boolean inlineEnabled 105 ) { 106 this(project, builderFactory, Progress.DEAF, bindingContext, files, true, false, GenerateClassFilter.GENERATE_ALL, inlineEnabled); 107 } 108 109 public GenerationState( 110 @NotNull Project project, 111 @NotNull ClassBuilderFactory builderFactory, 112 @NotNull Progress progress, 113 @NotNull BindingContext bindingContext, 114 @NotNull List<JetFile> files, 115 boolean generateNotNullAssertions, 116 boolean generateNotNullParamAssertions, 117 GenerateClassFilter generateClassFilter, 118 boolean inlineEnabled 119 ) { 120 this.project = project; 121 this.progress = progress; 122 this.files = files; 123 this.classBuilderMode = builderFactory.getClassBuilderMode(); 124 this.inlineEnabled = inlineEnabled; 125 126 bindingTrace = new DelegatingBindingTrace(bindingContext, "trace in GenerationState"); 127 this.bindingContext = bindingTrace.getBindingContext(); 128 129 this.typeMapper = new JetTypeMapper(bindingTrace, classBuilderMode); 130 131 this.intrinsics = new IntrinsicMethods(); 132 this.classFileFactory = new ClassFileFactory(this); 133 this.classFileFactory.setBuilderFactory(builderFactory); 134 135 this.generateNotNullAssertions = generateNotNullAssertions; 136 this.generateNotNullParamAssertions = generateNotNullParamAssertions; 137 this.generateClassFilter = generateClassFilter; 138 } 139 140 @NotNull 141 public ClassFileFactory getFactory() { 142 return classFileFactory; 143 } 144 145 @NotNull 146 public Progress getProgress() { 147 return progress; 148 } 149 150 @NotNull 151 public BindingContext getBindingContext() { 152 return bindingContext; 153 } 154 155 @NotNull 156 public ClassBuilderMode getClassBuilderMode() { 157 return classBuilderMode; 158 } 159 160 @NotNull 161 public List<JetFile> getFiles() { 162 return files; 163 } 164 165 @NotNull 166 public BindingTrace getBindingTrace() { 167 return bindingTrace; 168 } 169 170 @NotNull 171 public JetTypeMapper getTypeMapper() { 172 return typeMapper; 173 } 174 175 @NotNull 176 public Project getProject() { 177 return project; 178 } 179 180 @NotNull 181 public IntrinsicMethods getIntrinsics() { 182 return intrinsics; 183 } 184 185 @NotNull 186 public SamWrapperClasses getSamWrapperClasses() { 187 return samWrapperClasses; 188 } 189 190 public boolean isGenerateNotNullAssertions() { 191 return generateNotNullAssertions; 192 } 193 194 public boolean isGenerateNotNullParamAssertions() { 195 return generateNotNullParamAssertions; 196 } 197 198 public GenerateClassFilter getGenerateDeclaredClassFilter() { 199 return generateClassFilter; 200 } 201 202 public boolean isInlineEnabled() { 203 return inlineEnabled; 204 } 205 206 public void beforeCompile() { 207 markUsed(); 208 209 //noinspection unchecked 210 CodegenBinding.initTrace(getBindingTrace(), getFiles(), getGenerateDeclaredClassFilter()); 211 } 212 213 private void markUsed() { 214 if (used) { 215 throw new IllegalStateException(GenerationState.class + " cannot be used more than once"); 216 } 217 used = true; 218 } 219 220 public void destroy() { 221 } 222 223 @Nullable 224 public List<ScriptDescriptor> getEarlierScriptsForReplInterpreter() { 225 return earlierScriptsForReplInterpreter; 226 } 227 228 public void setEarlierScriptsForReplInterpreter(@Nullable List<ScriptDescriptor> earlierScriptsForReplInterpreter) { 229 this.earlierScriptsForReplInterpreter = earlierScriptsForReplInterpreter; 230 } 231 }