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    }