use of org.codehaus.groovy.util.ListHashMap in project groovy by apache.
the class StaticTypeCheckingVisitor method visitClosureExpression.
@Override
public void visitClosureExpression(final ClosureExpression expression) {
boolean oldStaticContext = typeCheckingContext.isInStaticContext;
typeCheckingContext.isInStaticContext = false;
// collect every variable expression used in the loop body
final Map<VariableExpression, ClassNode> varOrigType = new HashMap<VariableExpression, ClassNode>();
Statement code = expression.getCode();
code.visit(new VariableExpressionTypeMemoizer(varOrigType));
Map<VariableExpression, List<ClassNode>> oldTracker = pushAssignmentTracking();
// first, collect closure shared variables and reinitialize types
SharedVariableCollector collector = new SharedVariableCollector(getSourceUnit());
collector.visitClosureExpression(expression);
Set<VariableExpression> closureSharedExpressions = collector.getClosureSharedExpressions();
Map<VariableExpression, ListHashMap> typesBeforeVisit = null;
if (!closureSharedExpressions.isEmpty()) {
typesBeforeVisit = new HashMap<VariableExpression, ListHashMap>();
saveVariableExpressionMetadata(closureSharedExpressions, typesBeforeVisit);
}
// perform visit
typeCheckingContext.pushEnclosingClosureExpression(expression);
DelegationMetadata dmd = getDelegationMetadata(expression);
if (dmd == null) {
typeCheckingContext.delegationMetadata = new DelegationMetadata(typeCheckingContext.getEnclosingClassNode(), Closure.OWNER_FIRST, typeCheckingContext.delegationMetadata);
} else {
typeCheckingContext.delegationMetadata = new DelegationMetadata(dmd.getType(), dmd.getStrategy(), typeCheckingContext.delegationMetadata);
}
super.visitClosureExpression(expression);
typeCheckingContext.delegationMetadata = typeCheckingContext.delegationMetadata.getParent();
MethodNode node = new MethodNode("dummy", 0, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, code);
returnAdder.visitMethod(node);
TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
if (!enclosingClosure.getReturnTypes().isEmpty()) {
ClassNode returnType = lowestUpperBound(enclosingClosure.getReturnTypes());
storeInferredReturnType(expression, returnType);
ClassNode inferredType = wrapClosureType(returnType);
storeType(enclosingClosure.getClosureExpression(), inferredType);
}
typeCheckingContext.popEnclosingClosure();
boolean typeChanged = isSecondPassNeededForControlStructure(varOrigType, oldTracker);
if (typeChanged)
visitClosureExpression(expression);
// restore original metadata
restoreVariableExpressionMetadata(typesBeforeVisit);
typeCheckingContext.isInStaticContext = oldStaticContext;
Parameter[] parameters = expression.getParameters();
if (parameters != null) {
for (Parameter parameter : parameters) {
typeCheckingContext.controlStructureVariables.remove(parameter);
}
}
}
use of org.codehaus.groovy.util.ListHashMap in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method visitClosureExpression.
@Override
public void visitClosureExpression(final ClosureExpression expression) {
boolean oldStaticContext = typeCheckingContext.isInStaticContext;
typeCheckingContext.isInStaticContext = false;
// collect every variable expression used in the loop body
final Map<VariableExpression, ClassNode> varOrigType = new HashMap<VariableExpression, ClassNode>();
Statement code = expression.getCode();
code.visit(new VariableExpressionTypeMemoizer(varOrigType));
Map<VariableExpression, List<ClassNode>> oldTracker = pushAssignmentTracking();
// first, collect closure shared variables and reinitialize types
SharedVariableCollector collector = new SharedVariableCollector(getSourceUnit());
collector.visitClosureExpression(expression);
Set<VariableExpression> closureSharedExpressions = collector.getClosureSharedExpressions();
Map<VariableExpression, ListHashMap> typesBeforeVisit = null;
if (!closureSharedExpressions.isEmpty()) {
typesBeforeVisit = new HashMap<VariableExpression, ListHashMap>();
saveVariableExpressionMetadata(closureSharedExpressions, typesBeforeVisit);
}
// perform visit
typeCheckingContext.pushEnclosingClosureExpression(expression);
DelegationMetadata dmd = getDelegationMetadata(expression);
if (dmd == null) {
typeCheckingContext.delegationMetadata = new DelegationMetadata(typeCheckingContext.getEnclosingClassNode(), Closure.OWNER_FIRST, typeCheckingContext.delegationMetadata);
} else {
typeCheckingContext.delegationMetadata = new DelegationMetadata(dmd.getType(), dmd.getStrategy(), typeCheckingContext.delegationMetadata);
}
super.visitClosureExpression(expression);
typeCheckingContext.delegationMetadata = typeCheckingContext.delegationMetadata.getParent();
MethodNode node = new MethodNode("dummy", 0, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, code);
returnAdder.visitMethod(node);
TypeCheckingContext.EnclosingClosure enclosingClosure = typeCheckingContext.getEnclosingClosure();
if (!enclosingClosure.getReturnTypes().isEmpty()) {
ClassNode returnType = lowestUpperBound(enclosingClosure.getReturnTypes());
storeInferredReturnType(expression, returnType);
ClassNode inferredType = wrapClosureType(returnType);
storeType(enclosingClosure.getClosureExpression(), inferredType);
}
typeCheckingContext.popEnclosingClosure();
boolean typeChanged = isSecondPassNeededForControlStructure(varOrigType, oldTracker);
if (typeChanged)
visitClosureExpression(expression);
// restore original metadata
restoreVariableExpressionMetadata(typesBeforeVisit);
typeCheckingContext.isInStaticContext = oldStaticContext;
Parameter[] parameters = expression.getParameters();
if (parameters != null) {
for (Parameter parameter : parameters) {
typeCheckingContext.controlStructureVariables.remove(parameter);
}
}
}
use of org.codehaus.groovy.util.ListHashMap in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method saveVariableExpressionMetadata.
protected void saveVariableExpressionMetadata(final Set<VariableExpression> closureSharedExpressions, final Map<VariableExpression, ListHashMap> typesBeforeVisit) {
for (VariableExpression ve : closureSharedExpressions) {
// GROOVY-6921: We must force a call to getType in order to update closure shared variable which types are
// inferred thanks to closure parameter type inference
ClassNode cn = getType(ve);
ListHashMap<StaticTypesMarker, Object> metadata = new ListHashMap<StaticTypesMarker, Object>();
for (StaticTypesMarker marker : StaticTypesMarker.values()) {
Object value = ve.getNodeMetaData(marker);
if (value != null) {
metadata.put(marker, value);
}
}
typesBeforeVisit.put(ve, metadata);
Variable accessedVariable = ve.getAccessedVariable();
if (accessedVariable != ve && accessedVariable instanceof VariableExpression) {
saveVariableExpressionMetadata(Collections.singleton((VariableExpression) accessedVariable), typesBeforeVisit);
}
}
}
use of org.codehaus.groovy.util.ListHashMap in project groovy-core by groovy.
the class StaticTypeCheckingVisitor method restoreVariableExpressionMetadata.
protected void restoreVariableExpressionMetadata(final Map<VariableExpression, ListHashMap> typesBeforeVisit) {
if (typesBeforeVisit != null) {
for (Map.Entry<VariableExpression, ListHashMap> entry : typesBeforeVisit.entrySet()) {
VariableExpression ve = entry.getKey();
ListHashMap metadata = entry.getValue();
for (StaticTypesMarker marker : StaticTypesMarker.values()) {
ve.removeNodeMetaData(marker);
Object value = metadata.get(marker);
if (value != null)
ve.setNodeMetaData(marker, value);
}
}
}
}
use of org.codehaus.groovy.util.ListHashMap in project groovy by apache.
the class StaticTypeCheckingVisitor method restoreVariableExpressionMetadata.
protected void restoreVariableExpressionMetadata(final Map<VariableExpression, ListHashMap> typesBeforeVisit) {
if (typesBeforeVisit != null) {
for (Map.Entry<VariableExpression, ListHashMap> entry : typesBeforeVisit.entrySet()) {
VariableExpression ve = entry.getKey();
ListHashMap metadata = entry.getValue();
for (StaticTypesMarker marker : StaticTypesMarker.values()) {
ve.removeNodeMetaData(marker);
Object value = metadata.get(marker);
if (value != null)
ve.setNodeMetaData(marker, value);
}
}
}
}
Aggregations