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