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