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