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 }