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