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
017package org.jetbrains.jet.codegen.state;
018
019import com.intellij.openapi.project.Project;
020import org.jetbrains.annotations.NotNull;
021import org.jetbrains.jet.codegen.*;
022import org.jetbrains.jet.codegen.binding.CodegenBinding;
023import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
024import org.jetbrains.jet.di.InjectorForJvmCodegen;
025import org.jetbrains.jet.lang.psi.JetFile;
026import org.jetbrains.jet.lang.resolve.BindingContext;
027import org.jetbrains.jet.lang.resolve.BindingTrace;
028import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
029
030import java.util.List;
031
032public class GenerationState {
033    private boolean used = false;
034
035    @NotNull
036    private final Progress progress;
037
038    @NotNull
039    private final List<JetFile> files;
040
041    @NotNull
042    private final ClassBuilderMode classBuilderMode;
043
044    @NotNull
045    private final BindingContext bindingContext;
046
047    @NotNull
048    private final ClassFileFactory classFileFactory;
049
050    @NotNull
051    private final ScriptCodegen scriptCodegen;
052
053    @NotNull
054    private final Project project;
055
056    @NotNull
057    private final IntrinsicMethods intrinsics;
058
059    @NotNull
060    private final SamWrapperClasses samWrapperClasses = new SamWrapperClasses(this);
061
062    @NotNull
063    private final BindingTrace bindingTrace;
064
065    @NotNull
066    private final JetTypeMapper typeMapper;
067
068    private final boolean generateNotNullAssertions;
069
070    private final boolean generateNotNullParamAssertions;
071
072    private final boolean generateDeclaredClasses;
073
074    public GenerationState(Project project, ClassBuilderFactory builderFactory, BindingContext bindingContext, List<JetFile> files) {
075        this(project, builderFactory, Progress.DEAF, bindingContext, files, BuiltinToJavaTypesMapping.ENABLED, true, false, true);
076    }
077
078    public GenerationState(
079            @NotNull Project project,
080            @NotNull ClassBuilderFactory builderFactory,
081            @NotNull Progress progress,
082            @NotNull BindingContext bindingContext,
083            @NotNull List<JetFile> files,
084            @NotNull BuiltinToJavaTypesMapping builtinToJavaTypesMapping,
085            boolean generateNotNullAssertions,
086            boolean generateNotNullParamAssertions,
087            boolean generateDeclaredClasses
088    ) {
089        this.project = project;
090        this.progress = progress;
091        this.files = files;
092        this.classBuilderMode = builderFactory.getClassBuilderMode();
093
094        bindingTrace = new DelegatingBindingTrace(bindingContext, "trace in GenerationState");
095        this.bindingContext = bindingTrace.getBindingContext();
096
097        this.typeMapper = new JetTypeMapper(bindingTrace, builtinToJavaTypesMapping == BuiltinToJavaTypesMapping.ENABLED, classBuilderMode);
098
099        InjectorForJvmCodegen injector = new InjectorForJvmCodegen(typeMapper, this, builderFactory, project);
100
101        this.scriptCodegen = injector.getScriptCodegen();
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 ScriptCodegen getScriptCodegen() {
137        return scriptCodegen;
138    }
139
140    @NotNull
141    public BindingTrace getBindingTrace() {
142        return bindingTrace;
143    }
144
145    @NotNull
146    public JetTypeMapper getTypeMapper() {
147        return typeMapper;
148    }
149
150    @NotNull
151    public Project getProject() {
152        return project;
153    }
154
155    @NotNull
156    public IntrinsicMethods getIntrinsics() {
157        return intrinsics;
158    }
159
160    @NotNull
161    public SamWrapperClasses getSamWrapperClasses() {
162        return samWrapperClasses;
163    }
164
165    public boolean isGenerateNotNullAssertions() {
166        return generateNotNullAssertions;
167    }
168
169    public boolean isGenerateNotNullParamAssertions() {
170        return generateNotNullParamAssertions;
171    }
172
173    public boolean isGenerateDeclaredClasses() {
174        return generateDeclaredClasses;
175    }
176
177    public void beforeCompile() {
178        markUsed();
179
180        //noinspection unchecked
181        CodegenBinding.initTrace(getBindingTrace(), getFiles());
182    }
183
184    private void markUsed() {
185        if (used) {
186            throw new IllegalStateException(GenerationState.class + " cannot be used more than once");
187        }
188        used = true;
189    }
190
191    public void destroy() {
192    }
193}