
org.jetbrains.jet.lang.cfg.PseudocodeVariablesData Maven / Gradle / Ivy
/*
* Copyright 2010-2013 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.jet.lang.cfg;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import kotlin.Function1;
import kotlin.Unit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.Edges;
import org.jetbrains.jet.lang.cfg.pseudocodeTraverser.PseudocodeTraverserPackage;
import org.jetbrains.jet.lang.cfg.pseudocode.*;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
import org.jetbrains.jet.lang.psi.JetDeclaration;
import org.jetbrains.jet.lang.psi.JetProperty;
import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder.BACKWARD;
import static org.jetbrains.jet.lang.cfg.pseudocodeTraverser.TraversalOrder.FORWARD;
public class PseudocodeVariablesData {
private final Pseudocode pseudocode;
private final BindingContext bindingContext;
private final PseudocodeVariableDataCollector pseudocodeVariableDataCollector;
private final Map> declaredVariablesForDeclaration = Maps.newHashMap();
private final Map> usedVariablesForDeclaration = Maps.newHashMap();
private Map>> variableInitializers;
public PseudocodeVariablesData(@NotNull Pseudocode pseudocode, @NotNull BindingContext bindingContext) {
this.pseudocode = pseudocode;
this.bindingContext = bindingContext;
this.pseudocodeVariableDataCollector = new PseudocodeVariableDataCollector(bindingContext, pseudocode);
}
@NotNull
public Pseudocode getPseudocode() {
return pseudocode;
}
@NotNull
public LexicalScopeVariableInfo getLexicalScopeVariableInfo() {
return pseudocodeVariableDataCollector.getLexicalScopeVariableInfo();
}
@NotNull
public Set getUsedVariables(@NotNull Pseudocode pseudocode) {
Set usedVariables = usedVariablesForDeclaration.get(pseudocode);
if (usedVariables == null) {
final Set result = Sets.newHashSet();
PseudocodeTraverserPackage.traverse(pseudocode, FORWARD, new Function1() {
@Override
public Unit invoke(@NotNull Instruction instruction) {
VariableDescriptor variableDescriptor = PseudocodeUtil.extractVariableDescriptorIfAny(
instruction, false, bindingContext);
if (variableDescriptor != null) {
result.add(variableDescriptor);
}
return Unit.VALUE;
}
});
usedVariables = Collections.unmodifiableSet(result);
usedVariablesForDeclaration.put(pseudocode, usedVariables);
}
return usedVariables;
}
@NotNull
public Set getDeclaredVariables(@NotNull Pseudocode pseudocode, boolean includeInsideLocalDeclarations) {
if (!includeInsideLocalDeclarations) {
return getUpperLevelDeclaredVariables(pseudocode);
}
Set declaredVariables = Sets.newHashSet();
declaredVariables.addAll(getUpperLevelDeclaredVariables(pseudocode));
for (LocalFunctionDeclarationInstruction localFunctionDeclarationInstruction : pseudocode.getLocalDeclarations()) {
Pseudocode localPseudocode = localFunctionDeclarationInstruction.getBody();
declaredVariables.addAll(getUpperLevelDeclaredVariables(localPseudocode));
}
return declaredVariables;
}
@NotNull
private Set getUpperLevelDeclaredVariables(@NotNull Pseudocode pseudocode) {
Set declaredVariables = declaredVariablesForDeclaration.get(pseudocode);
if (declaredVariables == null) {
declaredVariables = computeDeclaredVariablesForPseudocode(pseudocode);
declaredVariablesForDeclaration.put(pseudocode, declaredVariables);
}
return declaredVariables;
}
@NotNull
private Set computeDeclaredVariablesForPseudocode(Pseudocode pseudocode) {
Set declaredVariables = Sets.newHashSet();
for (Instruction instruction : pseudocode.getInstructions()) {
if (instruction instanceof VariableDeclarationInstruction) {
JetDeclaration variableDeclarationElement = ((VariableDeclarationInstruction) instruction).getVariableDeclarationElement();
DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, variableDeclarationElement);
if (descriptor != null) {
assert descriptor instanceof VariableDescriptor;
declaredVariables.add((VariableDescriptor) descriptor);
}
}
}
return Collections.unmodifiableSet(declaredVariables);
}
// variable initializers
@NotNull
public Map>> getVariableInitializers() {
if (variableInitializers == null) {
variableInitializers = computeVariableInitializers();
}
return variableInitializers;
}
@NotNull
private Map>> computeVariableInitializers() {
final LexicalScopeVariableInfo lexicalScopeVariableInfo = pseudocodeVariableDataCollector.getLexicalScopeVariableInfo();
return pseudocodeVariableDataCollector.collectData(
FORWARD, /*mergeDataWithLocalDeclarations=*/ false,
new InstructionDataMergeStrategy() {
@NotNull
@Override
public Edges
© 2015 - 2025 Weber Informatics LLC | Privacy Policy