public final Set<VariableElement> findBoundVariableElements() { final Set<VariableElement> variables = new HashSet<>(); this.accept(new AbstractDSLExpressionVisitor() { @Override public void visitVariable(Variable variable) { if (variable.getReceiver() == null) { variables.add(variable.getResolvedVariable()); } } }); return variables; }
public boolean isDynamicParameterBound(DSLExpression expression) { Set<VariableElement> boundVariables = expression.findBoundVariableElements(); for (Parameter parameter : getDynamicParameters()) { if (boundVariables.contains(parameter.getVariableElement())) { return true; } } return false; }
private static boolean isVariableBoundIn(SpecializationData specialization, DSLExpression expression, String localName, LocalContext currentValues) throws AssertionError { Map<Variable, LocalVariable> boundValues = bindExpressionValues(expression, specialization, currentValues); for (Variable var : expression.findBoundVariables()) { LocalVariable target = boundValues.get(var); if (target != null && localName.equals(target.getName())) { return true; } } return false; }
public boolean isConstantTrueInSlowPath(ProcessorContext context) { DSLExpression reducedExpression = getExpression().reduce(new AbstractDSLExpressionReducer() { Object o = reducedExpression.resolveConstant(); if (o instanceof Boolean) { if (((Boolean) o).booleanValue()) {
private void initializeGuards(SpecializationData specialization, DSLExpressionResolver resolver) { final TypeMirror booleanType = context.getType(boolean.class); List<String> guardDefinitions = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards"); List<GuardExpression> guardExpressions = new ArrayList<>(); for (String guard : guardDefinitions) { GuardExpression guardExpression; DSLExpression expression = null; try { expression = DSLExpression.parse(guard); expression.accept(resolver); guardExpression = new GuardExpression(specialization, expression); if (!ElementUtils.typeEquals(expression.getResolvedType(), booleanType)) { guardExpression.addError("Incompatible return type %s. Guards must return %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(booleanType)); } } catch (InvalidExpressionException e) { guardExpression = new GuardExpression(specialization, null); guardExpression.addError("Error parsing expression '%s': %s", guard, e.getMessage()); } guardExpressions.add(guardExpression); } specialization.setGuards(guardExpressions); }
DSLExpression expression = null; try { expression = DSLExpression.parse(initializer); expression.accept(localResolver); cacheExpression = new CacheExpression(parameter, annotationMirror, expression); if (!ElementUtils.typeEquals(expression.getResolvedType(), parameter.getType())) { cacheExpression.addError("Incompatible return type %s. The expression type must be equal to the parameter type %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(parameter.getType())); Set<VariableElement> boundVariables = currentExpression.getExpression().findBoundVariableElements(); for (int j = i + 1; j < expressions.size(); j++) { CacheExpression boundExpression = expressions.get(j);
@Override public TypeMirror getResolvedType() { return receiver.getResolvedType(); }
lookupMethods = this.methods; } else { TypeMirror type = receiver.getResolvedType(); if (type.getKind() == TypeKind.DECLARED) { TypeMirror sourceType = expression.getResolvedType(); TypeMirror targetType = parameters.get(parameterIndex).asType(); if (!ElementUtils.isAssignable(sourceType, targetType)) { continue outer; expression.setResolvedTargetType(targetType); parameterIndex++; String sep = ""; for (DSLExpression expression : call.getParameters()) { arguments.append(sep).append(ElementUtils.getSimpleName(expression.getResolvedType())); sep = ", ";
@Override public DSLExpression reduce(DSLExpressionReducer visitor) { DSLExpression newReceiver = receiver.reduceImpl(visitor); DSLExpression negate = this; if (newReceiver != receiver) { negate = new Negate(newReceiver); negate.setResolvedTargetType(getResolvedTargetType()); } return negate; }
@Override public Object resolveConstant() { Object constant = receiver.resolveConstant(); if (constant instanceof Integer) { return -(int) constant; } return super.resolveConstant(); }
private DSLExpression reduceImpl(DSLExpressionReducer reducer) { DSLExpression expression = reduce(reducer); if (expression == null) { return this; } return expression; }
@Override public String toString() { return "Guard[" + (expression != null ? expression.asString() : "null") + "]"; }
private void avoidFindbugsProblems(CodeTypeElement clazz) { TypeElement type = context.getEnvironment().getElementUtils().getTypeElement(SuppressFBWarnings.class.getName()); boolean foundComparison = false; outer: for (SpecializationData specialization : node.getSpecializations()) { for (GuardExpression guard : specialization.getGuards()) { if (guard.getExpression().containsComparisons()) { foundComparison = true; break outer; } } } if (foundComparison) { CodeAnnotationMirror annotation = new CodeAnnotationMirror((DeclaredType) type.asType()); annotation.setElementValue(annotation.findExecutableElement("value"), new CodeAnnotationValue("SA_LOCAL_SELF_COMPARISON")); clazz.addAnnotationMirror(annotation); } }
private void initializeGuards(SpecializationData specialization, DSLExpressionResolver resolver) { final TypeMirror booleanType = context.getType(boolean.class); List<String> guardDefinitions = ElementUtils.getAnnotationValueList(String.class, specialization.getMarkerAnnotation(), "guards"); List<GuardExpression> guardExpressions = new ArrayList<>(); for (String guard : guardDefinitions) { GuardExpression guardExpression; DSLExpression expression = null; try { expression = DSLExpression.parse(guard); expression.accept(resolver); guardExpression = new GuardExpression(specialization, expression); if (!ElementUtils.typeEquals(expression.getResolvedType(), booleanType)) { guardExpression.addError("Incompatible return type %s. Guards must return %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(booleanType)); } } catch (InvalidExpressionException e) { guardExpression = new GuardExpression(specialization, null); guardExpression.addError("Error parsing expression '%s': %s", guard, e.getMessage()); } guardExpressions.add(guardExpression); } specialization.setGuards(guardExpressions); }
DSLExpression expression = null; try { expression = DSLExpression.parse(initializer); expression.accept(localResolver); cacheExpression = new CacheExpression(parameter, annotationMirror, expression); if (!ElementUtils.typeEquals(expression.getResolvedType(), parameter.getType())) { cacheExpression.addError("Incompatible return type %s. The expression type must be equal to the parameter type %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(parameter.getType())); Set<VariableElement> boundVariables = currentExpression.getExpression().findBoundVariableElements(); for (int j = i + 1; j < expressions.size(); j++) { CacheExpression boundExpression = expressions.get(j);
@Override public TypeMirror getResolvedType() { return receiver.getResolvedType(); }
lookupMethods = this.methods; } else { TypeMirror type = receiver.getResolvedType(); if (type.getKind() == TypeKind.DECLARED) { TypeMirror sourceType = expression.getResolvedType(); TypeMirror targetType = parameters.get(parameterIndex).asType(); if (!ElementUtils.isAssignable(sourceType, targetType)) { continue outer; expression.setResolvedTargetType(targetType); parameterIndex++; String sep = ""; for (DSLExpression expression : call.getParameters()) { arguments.append(sep).append(ElementUtils.getSimpleName(expression.getResolvedType())); sep = ", ";
public boolean isConstantLimit() { if (isGuardBindsCache()) { DSLExpression expression = getLimitExpression(); if (expression == null) { return true; } else { Object constant = expression.resolveConstant(); if (constant != null && constant instanceof Integer) { return true; } } return false; } else { return true; } }
private void initializeLimit(SpecializationData specialization, DSLExpressionResolver resolver) { AnnotationValue annotationValue = ElementUtils.getAnnotationValue(specialization.getMessageAnnotation(), "limit"); String limitValue; if (annotationValue == null) { limitValue = ""; } else { limitValue = (String) annotationValue.getValue(); } if (limitValue.isEmpty()) { limitValue = "3"; } else if (!specialization.hasMultipleInstances()) { specialization.addWarning(annotationValue, "The limit expression has no effect. Multiple specialization instantiations are impossible for this specialization."); return; } TypeMirror expectedType = context.getType(int.class); try { DSLExpression expression = DSLExpression.parse(limitValue); expression.accept(resolver); if (!ElementUtils.typeEquals(expression.getResolvedType(), expectedType)) { specialization.addError(annotationValue, "Incompatible return type %s. Limit expressions must return %s.", ElementUtils.getSimpleName(expression.getResolvedType()), ElementUtils.getSimpleName(expectedType)); } if (specialization.isDynamicParameterBound(expression)) { specialization.addError(annotationValue, "Limit expressions must not bind dynamic parameter values."); } specialization.setLimitExpression(expression); } catch (InvalidExpressionException e) { specialization.addError(annotationValue, "Error parsing expression '%s': %s", limitValue, e.getMessage()); } }
public final Set<Variable> findBoundVariables() { final Set<Variable> variables = new HashSet<>(); this.accept(new AbstractDSLExpressionVisitor() { @Override public void visitVariable(Variable variable) { if (variable.getReceiver() == null) { variables.add(variable); } } }); return variables; }