001    /*
002     * Copyright 2010-2015 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.kotlin.cfg;
018    
019    import org.jetbrains.annotations.NotNull;
020    import org.jetbrains.annotations.Nullable;
021    import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue;
022    import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode;
023    import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.*;
024    import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
025    import org.jetbrains.kotlin.psi.*;
026    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
027    import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant;
028    import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
029    
030    import java.util.List;
031    import java.util.Map;
032    
033    public interface JetControlFlowBuilder {
034        // Subroutines
035        void enterSubroutine(@NotNull JetElement subroutine);
036    
037        @NotNull
038        Pseudocode exitSubroutine(@NotNull JetElement subroutine);
039    
040        @NotNull
041        JetElement getCurrentSubroutine();
042        @Nullable
043        JetElement getReturnSubroutine();
044    
045        // Lexical scopes
046        void enterLexicalScope(@NotNull JetElement element);
047        void exitLexicalScope(@NotNull JetElement element);
048    
049        // Entry/exit points
050        @NotNull
051        Label getEntryPoint(@NotNull JetElement labelElement);
052        @NotNull
053        Label getExitPoint(@NotNull JetElement labelElement);
054        @NotNull
055        Label getConditionEntryPoint(@NotNull JetElement labelElement);
056    
057        // Declarations
058        void declareParameter(@NotNull JetParameter parameter);
059        void declareVariable(@NotNull JetVariableDeclaration property);
060        void declareFunction(@NotNull JetElement subroutine, @NotNull Pseudocode pseudocode);
061    
062        // Labels
063        @NotNull
064        Label createUnboundLabel();
065        @NotNull
066        Label createUnboundLabel(@NotNull String name);
067    
068        void bindLabel(@NotNull Label label);
069    
070        // Jumps
071        void jump(@NotNull Label label, @NotNull JetElement element);
072        void jumpOnFalse(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue conditionValue);
073        void jumpOnTrue(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue conditionValue);
074        void nondeterministicJump(@NotNull Label label, @NotNull JetElement element, @Nullable PseudoValue inputValue); // Maybe, jump to label
075        void nondeterministicJump(@NotNull List<Label> label, @NotNull JetElement element);
076        void jumpToError(@NotNull JetElement element);
077    
078        void returnValue(@NotNull JetExpression returnExpression, @NotNull PseudoValue returnValue, @NotNull JetElement subroutine);
079        void returnNoValue(@NotNull JetReturnExpression returnExpression, @NotNull JetElement subroutine);
080    
081        void throwException(@NotNull JetThrowExpression throwExpression, @NotNull PseudoValue thrownValue);
082    
083        // Loops
084        @NotNull
085        LoopInfo enterLoop(@NotNull JetLoopExpression expression);
086        void enterLoopBody(@NotNull JetLoopExpression expression);
087        void exitLoopBody(@NotNull JetLoopExpression expression);
088        @Nullable
089        JetLoopExpression getCurrentLoop();
090    
091        // Try-Finally
092        void enterTryFinally(@NotNull GenerationTrigger trigger);
093        void exitTryFinally();
094    
095        void repeatPseudocode(@NotNull Label startLabel, @NotNull Label finishLabel);
096    
097        // Reading values
098        void mark(@NotNull JetElement element);
099    
100        @Nullable
101        PseudoValue getBoundValue(@Nullable JetElement element);
102        void bindValue(@NotNull PseudoValue value, @NotNull JetElement element);
103        @NotNull
104        PseudoValue newValue(@Nullable JetElement element);
105    
106        void loadUnit(@NotNull JetExpression expression);
107    
108        @NotNull
109        InstructionWithValue loadConstant(@NotNull JetExpression expression, @Nullable CompileTimeConstant<?> constant);
110        @NotNull
111        InstructionWithValue createAnonymousObject(@NotNull JetObjectLiteralExpression expression);
112        @NotNull
113        InstructionWithValue createLambda(@NotNull JetFunction expression);
114        @NotNull
115        InstructionWithValue loadStringTemplate(@NotNull JetStringTemplateExpression expression, @NotNull List<PseudoValue> inputValues);
116    
117        @NotNull
118        MagicInstruction magic(
119                @NotNull JetElement instructionElement,
120                @Nullable JetElement valueElement,
121                @NotNull List<PseudoValue> inputValues,
122                @NotNull MagicKind kind
123        );
124    
125        @NotNull
126        MergeInstruction merge(
127                @NotNull JetExpression expression,
128                @NotNull List<PseudoValue> inputValues
129        );
130    
131        @NotNull
132        ReadValueInstruction readVariable(
133                @NotNull JetExpression expression,
134                @NotNull ResolvedCall<?> resolvedCall,
135                @NotNull Map<PseudoValue, ReceiverValue> receiverValues
136        );
137    
138        @NotNull
139        CallInstruction call(
140                @NotNull JetElement valueElement,
141                @NotNull ResolvedCall<?> resolvedCall,
142                @NotNull Map<PseudoValue, ReceiverValue> receiverValues,
143                @NotNull Map<PseudoValue, ValueParameterDescriptor> arguments
144        );
145    
146        enum PredefinedOperation {
147            AND,
148            OR,
149            NOT_NULL_ASSERTION
150        }
151        @NotNull
152        OperationInstruction predefinedOperation(
153                @NotNull JetExpression expression,
154                @NotNull PredefinedOperation operation,
155                @NotNull List<PseudoValue> inputValues
156        );
157    
158        void write(
159                @NotNull JetElement assignment,
160                @NotNull JetElement lValue,
161                @NotNull PseudoValue rValue,
162                @NotNull AccessTarget target,
163                @NotNull Map<PseudoValue, ReceiverValue> receiverValues);
164    }