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        @Nullable
074        private List<ScriptDescriptor> earlierScriptsForReplInterpreter;
075    
076        public GenerationState(Project project, ClassBuilderFactory builderFactory, BindingContext bindingContext, List<JetFile> files) {
077            this(project, builderFactory, Progress.DEAF, bindingContext, files, true, false, true);
078        }
079    
080        public GenerationState(
081                @NotNull Project project,
082                @NotNull ClassBuilderFactory builderFactory,
083                @NotNull Progress progress,
084                @NotNull BindingContext bindingContext,
085                @NotNull List<JetFile> files,
086                boolean generateNotNullAssertions,
087                boolean generateNotNullParamAssertions,
088                boolean generateDeclaredClasses
089        ) {
090            this.project = project;
091            this.progress = progress;
092            this.files = files;
093            this.classBuilderMode = builderFactory.getClassBuilderMode();
094    
095            bindingTrace = new DelegatingBindingTrace(bindingContext, "trace in GenerationState");
096            this.bindingContext = bindingTrace.getBindingContext();
097    
098            this.typeMapper = new JetTypeMapper(bindingTrace, classBuilderMode);
099    
100            InjectorForJvmCodegen injector = new InjectorForJvmCodegen(typeMapper, this, builderFactory, project);
101    
102            this.intrinsics = injector.getIntrinsics();
103            this.classFileFactory = injector.getClassFileFactory();
104    
105            this.generateNotNullAssertions = generateNotNullAssertions;
106            this.generateNotNullParamAssertions = generateNotNullParamAssertions;
107            this.generateDeclaredClasses = generateDeclaredClasses;
108        }
109    
110        @NotNull
111        public ClassFileFactory getFactory() {
112            return classFileFactory;
113        }
114    
115        @NotNull
116        public Progress getProgress() {
117            return progress;
118        }
119    
120        @NotNull
121        public BindingContext getBindingContext() {
122            return bindingContext;
123        }
124    
125        @NotNull
126        public ClassBuilderMode getClassBuilderMode() {
127            return classBuilderMode;
128        }
129    
130        @NotNull
131        public List<JetFile> getFiles() {
132            return files;
133        }
134    
135        @NotNull
136        public BindingTrace getBindingTrace() {
137            return bindingTrace;
138        }
139    
140        @NotNull
141        public JetTypeMapper getTypeMapper() {
142            return typeMapper;
143        }
144    
145        @NotNull
146        public Project getProject() {
147            return project;
148        }
149    
150        @NotNull
151        public IntrinsicMethods getIntrinsics() {
152            return intrinsics;
153        }
154    
155        @NotNull
156        public SamWrapperClasses getSamWrapperClasses() {
157            return samWrapperClasses;
158        }
159    
160        public boolean isGenerateNotNullAssertions() {
161            return generateNotNullAssertions;
162        }
163    
164        public boolean isGenerateNotNullParamAssertions() {
165            return generateNotNullParamAssertions;
166        }
167    
168        public boolean isGenerateDeclaredClasses() {
169            return generateDeclaredClasses;
170        }
171    
172        public void beforeCompile() {
173            markUsed();
174    
175            //noinspection unchecked
176            CodegenBinding.initTrace(getBindingTrace(), getFiles());
177        }
178    
179        private void markUsed() {
180            if (used) {
181                throw new IllegalStateException(GenerationState.class + " cannot be used more than once");
182            }
183            used = true;
184        }
185    
186        public void destroy() {
187        }
188    
189        @Nullable
190        public List<ScriptDescriptor> getEarlierScriptsForReplInterpreter() {
191            return earlierScriptsForReplInterpreter;
192        }
193    
194        public void setEarlierScriptsForReplInterpreter(@Nullable List<ScriptDescriptor> earlierScriptsForReplInterpreter) {
195            this.earlierScriptsForReplInterpreter = earlierScriptsForReplInterpreter;
196        }
197    }