001    /*
002     * Copyright 2010-2013 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.di.InjectorForJvmCodegen;
026    import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
027    import org.jetbrains.jet.lang.psi.JetFile;
028    import org.jetbrains.jet.lang.resolve.BindingContext;
029    import org.jetbrains.jet.lang.resolve.BindingTrace;
030    import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
031    
032    import java.util.List;
033    
034    public class GenerationState {
035        private boolean used = false;
036    
037        @NotNull
038        private final Progress progress;
039    
040        @NotNull
041        private final List<JetFile> files;
042    
043        @NotNull
044        private final ClassBuilderMode classBuilderMode;
045    
046        @NotNull
047        private final BindingContext bindingContext;
048    
049        @NotNull
050        private final ClassFileFactory classFileFactory;
051    
052        @NotNull
053        private final Project project;
054    
055        @NotNull
056        private final IntrinsicMethods intrinsics;
057    
058        @NotNull
059        private final SamWrapperClasses samWrapperClasses = new SamWrapperClasses(this);
060    
061        @NotNull
062        private final BindingTrace bindingTrace;
063    
064        @NotNull
065        private final JetTypeMapper typeMapper;
066    
067        private final boolean generateNotNullAssertions;
068    
069        private final boolean generateNotNullParamAssertions;
070    
071        private final boolean generateDeclaredClasses;
072    
073        private final boolean inlineEnabled;
074    
075        @Nullable
076        private List<ScriptDescriptor> earlierScriptsForReplInterpreter;
077    
078        public GenerationState(Project project, ClassBuilderFactory builderFactory, BindingContext bindingContext, List<JetFile> files, boolean inlineEnabled) {
079            this(project, builderFactory, Progress.DEAF, bindingContext, files, true, false, true, inlineEnabled);
080        }
081    
082        public GenerationState(
083                @NotNull Project project,
084                @NotNull ClassBuilderFactory builderFactory,
085                @NotNull Progress progress,
086                @NotNull BindingContext bindingContext,
087                @NotNull List<JetFile> files,
088                boolean generateNotNullAssertions,
089                boolean generateNotNullParamAssertions,
090                boolean generateDeclaredClasses,
091                boolean inlineEnabled
092        ) {
093            this.project = project;
094            this.progress = progress;
095            this.files = files;
096            this.classBuilderMode = builderFactory.getClassBuilderMode();
097            this.inlineEnabled = inlineEnabled;
098    
099            bindingTrace = new DelegatingBindingTrace(bindingContext, "trace in GenerationState");
100            this.bindingContext = bindingTrace.getBindingContext();
101    
102            this.typeMapper = new JetTypeMapper(bindingTrace, classBuilderMode);
103    
104            InjectorForJvmCodegen injector = new InjectorForJvmCodegen(typeMapper, this, builderFactory, project);
105    
106            this.intrinsics = injector.getIntrinsics();
107            this.classFileFactory = injector.getClassFileFactory();
108    
109            this.generateNotNullAssertions = generateNotNullAssertions;
110            this.generateNotNullParamAssertions = generateNotNullParamAssertions;
111            this.generateDeclaredClasses = generateDeclaredClasses;
112        }
113    
114        @NotNull
115        public ClassFileFactory getFactory() {
116            return classFileFactory;
117        }
118    
119        @NotNull
120        public Progress getProgress() {
121            return progress;
122        }
123    
124        @NotNull
125        public BindingContext getBindingContext() {
126            return bindingContext;
127        }
128    
129        @NotNull
130        public ClassBuilderMode getClassBuilderMode() {
131            return classBuilderMode;
132        }
133    
134        @NotNull
135        public List<JetFile> getFiles() {
136            return files;
137        }
138    
139        @NotNull
140        public BindingTrace getBindingTrace() {
141            return bindingTrace;
142        }
143    
144        @NotNull
145        public JetTypeMapper getTypeMapper() {
146            return typeMapper;
147        }
148    
149        @NotNull
150        public Project getProject() {
151            return project;
152        }
153    
154        @NotNull
155        public IntrinsicMethods getIntrinsics() {
156            return intrinsics;
157        }
158    
159        @NotNull
160        public SamWrapperClasses getSamWrapperClasses() {
161            return samWrapperClasses;
162        }
163    
164        public boolean isGenerateNotNullAssertions() {
165            return generateNotNullAssertions;
166        }
167    
168        public boolean isGenerateNotNullParamAssertions() {
169            return generateNotNullParamAssertions;
170        }
171    
172        public boolean isGenerateDeclaredClasses() {
173            return generateDeclaredClasses;
174        }
175    
176        public boolean isInlineEnabled() {
177            return inlineEnabled;
178        }
179    
180        public void beforeCompile() {
181            markUsed();
182    
183            //noinspection unchecked
184            CodegenBinding.initTrace(getBindingTrace(), getFiles());
185        }
186    
187        private void markUsed() {
188            if (used) {
189                throw new IllegalStateException(GenerationState.class + " cannot be used more than once");
190            }
191            used = true;
192        }
193    
194        public void destroy() {
195        }
196    
197        @Nullable
198        public List<ScriptDescriptor> getEarlierScriptsForReplInterpreter() {
199            return earlierScriptsForReplInterpreter;
200        }
201    
202        public void setEarlierScriptsForReplInterpreter(@Nullable List<ScriptDescriptor> earlierScriptsForReplInterpreter) {
203            this.earlierScriptsForReplInterpreter = earlierScriptsForReplInterpreter;
204        }
205    }