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.psi.JetClassOrObject;
029    import org.jetbrains.jet.lang.psi.JetFile;
030    import org.jetbrains.jet.lang.reflect.ReflectionTypes;
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        private final JvmFunctionImplTypes functionImplTypes;
100    
101        public GenerationState(
102                @NotNull Project project,
103                @NotNull ClassBuilderFactory builderFactory,
104                @NotNull ModuleDescriptor module,
105                @NotNull BindingContext bindingContext,
106                @NotNull List<JetFile> files
107        ) {
108            this(project, builderFactory, Progress.DEAF, module, bindingContext, files, true, false, GenerateClassFilter.GENERATE_ALL,
109                 InlineCodegenUtil.DEFAULT_INLINE_FLAG);
110        }
111    
112        public GenerationState(
113                @NotNull Project project,
114                @NotNull ClassBuilderFactory builderFactory,
115                @NotNull Progress progress,
116                @NotNull ModuleDescriptor module,
117                @NotNull BindingContext bindingContext,
118                @NotNull List<JetFile> files,
119                boolean generateNotNullAssertions,
120                boolean generateNotNullParamAssertions,
121                GenerateClassFilter generateClassFilter,
122                boolean inlineEnabled
123        ) {
124            this.project = project;
125            this.progress = progress;
126            this.files = files;
127            this.classBuilderMode = builderFactory.getClassBuilderMode();
128            this.inlineEnabled = inlineEnabled;
129    
130            this.bindingTrace = new DelegatingBindingTrace(bindingContext, "trace in GenerationState");
131            this.bindingContext = bindingTrace.getBindingContext();
132    
133            this.typeMapper = new JetTypeMapper(this.bindingContext, classBuilderMode);
134    
135            this.intrinsics = new IntrinsicMethods();
136            this.classFileFactory = new ClassFileFactory(this, builderFactory);
137    
138            this.generateNotNullAssertions = generateNotNullAssertions;
139            this.generateNotNullParamAssertions = generateNotNullParamAssertions;
140            this.generateClassFilter = generateClassFilter;
141    
142            ReflectionTypes reflectionTypes = new ReflectionTypes(module);
143            this.functionImplTypes = new JvmFunctionImplTypes(reflectionTypes);
144        }
145    
146        @NotNull
147        public ClassFileFactory getFactory() {
148            return classFileFactory;
149        }
150    
151        @NotNull
152        public Progress getProgress() {
153            return progress;
154        }
155    
156        @NotNull
157        public BindingContext getBindingContext() {
158            return bindingContext;
159        }
160    
161        @NotNull
162        public ClassBuilderMode getClassBuilderMode() {
163            return classBuilderMode;
164        }
165    
166        @NotNull
167        public List<JetFile> getFiles() {
168            return files;
169        }
170    
171        @NotNull
172        public BindingTrace getBindingTrace() {
173            return bindingTrace;
174        }
175    
176        @NotNull
177        public JetTypeMapper getTypeMapper() {
178            return typeMapper;
179        }
180    
181        @NotNull
182        public Project getProject() {
183            return project;
184        }
185    
186        @NotNull
187        public IntrinsicMethods getIntrinsics() {
188            return intrinsics;
189        }
190    
191        @NotNull
192        public SamWrapperClasses getSamWrapperClasses() {
193            return samWrapperClasses;
194        }
195    
196        public boolean isGenerateNotNullAssertions() {
197            return generateNotNullAssertions;
198        }
199    
200        public boolean isGenerateNotNullParamAssertions() {
201            return generateNotNullParamAssertions;
202        }
203    
204        @NotNull
205        public GenerateClassFilter getGenerateDeclaredClassFilter() {
206            return generateClassFilter;
207        }
208    
209        @NotNull
210        public JvmFunctionImplTypes getJvmFunctionImplTypes() {
211            return functionImplTypes;
212        }
213    
214        public boolean isInlineEnabled() {
215            return inlineEnabled;
216        }
217    
218        public void beforeCompile() {
219            markUsed();
220    
221            CodegenBinding.initTrace(this);
222        }
223    
224        private void markUsed() {
225            if (used) {
226                throw new IllegalStateException(GenerationState.class + " cannot be used more than once");
227            }
228            used = true;
229        }
230    
231        public void destroy() {
232        }
233    
234        @Nullable
235        public List<ScriptDescriptor> getEarlierScriptsForReplInterpreter() {
236            return earlierScriptsForReplInterpreter;
237        }
238    
239        public void setEarlierScriptsForReplInterpreter(@Nullable List<ScriptDescriptor> earlierScriptsForReplInterpreter) {
240            this.earlierScriptsForReplInterpreter = earlierScriptsForReplInterpreter;
241        }
242    }