use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.
the class JavaStubGenerator method getAnnotationValue.
private String getAnnotationValue(Object memberValue) {
String val = "null";
if (memberValue instanceof ListExpression) {
StringBuilder sb = new StringBuilder("{");
boolean first = true;
ListExpression le = (ListExpression) memberValue;
for (Expression e : le.getExpressions()) {
if (first)
first = false;
else
sb.append(",");
sb.append(getAnnotationValue(e));
}
sb.append("}");
val = sb.toString();
} else if (memberValue instanceof ConstantExpression) {
ConstantExpression ce = (ConstantExpression) memberValue;
Object constValue = ce.getValue();
if (constValue instanceof AnnotationNode) {
StringWriter writer = new StringWriter();
PrintWriter out = new PrintWriter(writer);
printAnnotation(out, (AnnotationNode) constValue);
val = writer.toString();
} else if (constValue instanceof Number || constValue instanceof Boolean)
val = constValue.toString();
else
val = "\"" + escapeSpecialChars(constValue.toString()) + "\"";
} else if (memberValue instanceof PropertyExpression || memberValue instanceof VariableExpression) {
// assume must be static class field or enum value or class that Java can resolve
val = ((Expression) memberValue).getText();
} else if (memberValue instanceof ClosureExpression) {
// annotation closure; replaced with this specific class literal to cover the
// case where annotation type uses Class<? extends Closure> for the closure's type
val = "groovy.lang.Closure.class";
} else if (memberValue instanceof ClassExpression) {
val = ((Expression) memberValue).getText() + ".class";
}
return val;
}
use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.
the class ImmutableASTTransformation method getKnownImmutables.
private List<String> getKnownImmutables(AnnotationNode node) {
final ArrayList<String> immutables = new ArrayList<String>();
final Expression expression = node.getMember(MEMBER_KNOWN_IMMUTABLES);
if (expression == null)
return immutables;
if (!(expression instanceof ListExpression)) {
addError("Use the Groovy list notation [el1, el2] to specify known immutable property names via \"" + MEMBER_KNOWN_IMMUTABLES + "\"", node);
return immutables;
}
final ListExpression listExpression = (ListExpression) expression;
for (Expression listItemExpression : listExpression.getExpressions()) {
if (listItemExpression instanceof ConstantExpression) {
immutables.add((String) ((ConstantExpression) listItemExpression).getValue());
}
}
return immutables;
}
use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.
the class GrabAnnotationTransformation method callGrabAsStaticInitIfNeeded.
private void callGrabAsStaticInitIfNeeded(ClassNode classNode, ClassNode grapeClassNode, List<Map<String, Object>> grabMapsInit, List<Map<String, Object>> grabExcludeMaps) {
List<Statement> grabInitializers = new ArrayList<Statement>();
MapExpression basicArgs = new MapExpression();
if (autoDownload != null) {
basicArgs.addMapEntryExpression(new ConstantExpression(AUTO_DOWNLOAD_SETTING), new ConstantExpression(autoDownload));
}
if (disableChecksums != null) {
basicArgs.addMapEntryExpression(new ConstantExpression(DISABLE_CHECKSUMS_SETTING), new ConstantExpression(disableChecksums));
}
if (!grabExcludeMaps.isEmpty()) {
ListExpression list = new ListExpression();
for (Map<String, Object> map : grabExcludeMaps) {
Set<Map.Entry<String, Object>> entries = map.entrySet();
MapExpression inner = new MapExpression();
for (Map.Entry<String, Object> entry : entries) {
inner.addMapEntryExpression(new ConstantExpression(entry.getKey()), new ConstantExpression(entry.getValue()));
}
list.addExpression(inner);
}
basicArgs.addMapEntryExpression(new ConstantExpression("excludes"), list);
}
List<Expression> argList = new ArrayList<Expression>();
argList.add(basicArgs);
if (grabMapsInit.size() == 0)
return;
for (Map<String, Object> grabMap : grabMapsInit) {
// add Grape.grab(excludeArgs, [group:group, module:module, version:version, classifier:classifier])
// or Grape.grab([group:group, module:module, version:version, classifier:classifier])
MapExpression dependencyArg = new MapExpression();
for (String s : GRAB_REQUIRED) {
dependencyArg.addMapEntryExpression(new ConstantExpression(s), new ConstantExpression(grabMap.get(s)));
}
for (String s : GRAB_OPTIONAL) {
if (grabMap.containsKey(s))
dependencyArg.addMapEntryExpression(new ConstantExpression(s), new ConstantExpression(grabMap.get(s)));
}
argList.add(dependencyArg);
}
ArgumentListExpression grabArgs = new ArgumentListExpression(argList);
grabInitializers.add(new ExpressionStatement(new StaticMethodCallExpression(grapeClassNode, "grab", grabArgs)));
// insert at beginning so we have the classloader set up before the class is called
classNode.addStaticInitializerStatements(grabInitializers, true);
}
use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.
the class GrabAnnotationTransformation method visit.
public void visit(ASTNode[] nodes, SourceUnit source) {
sourceUnit = source;
loader = null;
initContextClassLoader = false;
ModuleNode mn = (ModuleNode) nodes[0];
allowShortGrab = true;
allowShortGrabExcludes = true;
allowShortGrabConfig = true;
allowShortGrapes = true;
allowShortGrabResolver = true;
grabAliases = new HashSet<String>();
grabExcludeAliases = new HashSet<String>();
grabConfigAliases = new HashSet<String>();
grapesAliases = new HashSet<String>();
grabResolverAliases = new HashSet<String>();
for (ImportNode im : mn.getImports()) {
String alias = im.getAlias();
String className = im.getClassName();
if ((className.endsWith(GRAB_DOT_NAME) && ((alias == null) || (alias.length() == 0))) || (GRAB_CLASS_NAME.equals(alias))) {
allowShortGrab = false;
} else if (GRAB_CLASS_NAME.equals(className)) {
grabAliases.add(im.getAlias());
}
if ((className.endsWith(GRAPES_DOT_NAME) && ((alias == null) || (alias.length() == 0))) || (GRAPES_CLASS_NAME.equals(alias))) {
allowShortGrapes = false;
} else if (GRAPES_CLASS_NAME.equals(className)) {
grapesAliases.add(im.getAlias());
}
if ((className.endsWith(GRABRESOLVER_DOT_NAME) && ((alias == null) || (alias.length() == 0))) || (GRABRESOLVER_CLASS_NAME.equals(alias))) {
allowShortGrabResolver = false;
} else if (GRABRESOLVER_CLASS_NAME.equals(className)) {
grabResolverAliases.add(im.getAlias());
}
}
List<Map<String, Object>> grabMaps = new ArrayList<Map<String, Object>>();
List<Map<String, Object>> grabMapsInit = new ArrayList<Map<String, Object>>();
List<Map<String, Object>> grabExcludeMaps = new ArrayList<Map<String, Object>>();
for (ClassNode classNode : sourceUnit.getAST().getClasses()) {
grabAnnotations = new ArrayList<AnnotationNode>();
grabExcludeAnnotations = new ArrayList<AnnotationNode>();
grabConfigAnnotations = new ArrayList<AnnotationNode>();
grapesAnnotations = new ArrayList<AnnotationNode>();
grabResolverAnnotations = new ArrayList<AnnotationNode>();
visitClass(classNode);
ClassNode grapeClassNode = ClassHelper.make(Grape.class);
List<Statement> grabResolverInitializers = new ArrayList<Statement>();
if (!grapesAnnotations.isEmpty()) {
for (AnnotationNode node : grapesAnnotations) {
Expression init = node.getMember("initClass");
Expression value = node.getMember("value");
if (value instanceof ListExpression) {
for (Object o : ((ListExpression) value).getExpressions()) {
if (o instanceof ConstantExpression) {
extractGrab(init, (ConstantExpression) o);
}
}
} else if (value instanceof ConstantExpression) {
extractGrab(init, (ConstantExpression) value);
}
// don't worry if it's not a ListExpression, or AnnotationConstant, etc.
// the rest of GroovyC will flag it as a syntax error later, so we don't
// need to raise the error ourselves
}
}
if (!grabResolverAnnotations.isEmpty()) {
grabResolverAnnotationLoop: for (AnnotationNode node : grabResolverAnnotations) {
Map<String, Object> grabResolverMap = new HashMap<String, Object>();
String sval = getMemberStringValue(node, "value");
if (sval != null && sval.length() > 0) {
for (String s : GRABRESOLVER_REQUIRED) {
String mval = getMemberStringValue(node, s);
if (mval != null && mval.isEmpty())
mval = null;
if (mval != null) {
addError("The attribute \"" + s + "\" conflicts with attribute 'value' in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
continue grabResolverAnnotationLoop;
}
}
grabResolverMap.put("name", sval);
grabResolverMap.put("root", sval);
} else {
for (String s : GRABRESOLVER_REQUIRED) {
String mval = getMemberStringValue(node, s);
if (mval != null && mval.isEmpty())
mval = null;
Expression member = node.getMember(s);
if (member == null || mval == null) {
addError("The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
continue grabResolverAnnotationLoop;
} else if (mval == null) {
addError("Attribute \"" + s + "\" has value " + member.getText() + " but should be an inline constant String in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
continue grabResolverAnnotationLoop;
}
grabResolverMap.put(s, mval);
}
}
// If no scheme is specified for the repository root,
// then turn it into a URI relative to that of the source file.
String root = (String) grabResolverMap.get("root");
if (root != null && !root.contains(":")) {
URI sourceURI = null;
// and those are not hierarchical we can't use them for making an absolute URI.
if (!(getSourceUnit().getSource() instanceof StringReaderSource)) {
// Otherwise let's trust the source to know where it is from.
// And actually InputStreamReaderSource doesn't know what to do and so returns null.
sourceURI = getSourceUnit().getSource().getURI();
}
// then let's use the current working directory, since the repo can be relative to that.
if (sourceURI == null) {
sourceURI = new File(".").toURI();
}
try {
URI rootURI = sourceURI.resolve(new URI(root));
grabResolverMap.put("root", rootURI.toString());
} catch (URISyntaxException e) {
// We'll be silent here.
// If the URI scheme is unknown or not hierarchical, then we just can't help them and shouldn't cause any trouble either.
// addError("Attribute \"root\" has value '" + root + "' which can't be turned into a valid URI relative to it's source '" + getSourceUnit().getName() + "' @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
}
}
Grape.addResolver(grabResolverMap);
addGrabResolverAsStaticInitIfNeeded(grapeClassNode, node, grabResolverInitializers, grabResolverMap);
}
}
if (!grabConfigAnnotations.isEmpty()) {
for (AnnotationNode node : grabConfigAnnotations) {
checkForClassLoader(node);
checkForInitContextClassLoader(node);
checkForAutoDownload(node);
checkForDisableChecksums(node);
}
addInitContextClassLoaderIfNeeded(classNode);
}
if (!grabExcludeAnnotations.isEmpty()) {
grabExcludeAnnotationLoop: for (AnnotationNode node : grabExcludeAnnotations) {
Map<String, Object> grabExcludeMap = new HashMap<String, Object>();
checkForConvenienceForm(node, true);
for (String s : GRABEXCLUDE_REQUIRED) {
Expression member = node.getMember(s);
if (member == null) {
addError("The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
continue grabExcludeAnnotationLoop;
} else if (member != null && !(member instanceof ConstantExpression)) {
addError("Attribute \"" + s + "\" has value " + member.getText() + " but should be an inline constant in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
continue grabExcludeAnnotationLoop;
}
grabExcludeMap.put(s, ((ConstantExpression) member).getValue());
}
grabExcludeMaps.add(grabExcludeMap);
}
}
if (!grabAnnotations.isEmpty()) {
grabAnnotationLoop: for (AnnotationNode node : grabAnnotations) {
Map<String, Object> grabMap = new HashMap<String, Object>();
checkForConvenienceForm(node, false);
for (String s : GRAB_ALL) {
Expression member = node.getMember(s);
String mval = getMemberStringValue(node, s);
if (mval != null && mval.isEmpty())
member = null;
if (member == null && !GRAB_OPTIONAL.contains(s)) {
addError("The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
continue grabAnnotationLoop;
} else if (member != null && !(member instanceof ConstantExpression)) {
addError("Attribute \"" + s + "\" has value " + member.getText() + " but should be an inline constant in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
continue grabAnnotationLoop;
}
if (node.getMember(s) != null) {
grabMap.put(s, ((ConstantExpression) member).getValue());
}
}
grabMaps.add(grabMap);
if ((node.getMember("initClass") == null) || (node.getMember("initClass") == ConstantExpression.TRUE)) {
grabMapsInit.add(grabMap);
}
}
callGrabAsStaticInitIfNeeded(classNode, grapeClassNode, grabMapsInit, grabExcludeMaps);
}
if (!grabResolverInitializers.isEmpty()) {
classNode.addStaticInitializerStatements(grabResolverInitializers, true);
}
}
if (!grabMaps.isEmpty()) {
Map<String, Object> basicArgs = new HashMap<String, Object>();
basicArgs.put("classLoader", loader != null ? loader : sourceUnit.getClassLoader());
if (!grabExcludeMaps.isEmpty())
basicArgs.put("excludes", grabExcludeMaps);
if (autoDownload != null)
basicArgs.put(AUTO_DOWNLOAD_SETTING, autoDownload);
if (disableChecksums != null)
basicArgs.put(DISABLE_CHECKSUMS_SETTING, disableChecksums);
try {
Grape.grab(basicArgs, grabMaps.toArray(new Map[grabMaps.size()]));
// grab may have added more transformations through new URLs added to classpath, so do one more scan
if (compilationUnit != null) {
ASTTransformationVisitor.addGlobalTransformsAfterGrab(compilationUnit.getASTTransformationsContext());
}
} catch (RuntimeException re) {
// Decided against syntax exception since this is not a syntax error.
// The down side is we lose line number information for the offending
// @Grab annotation.
source.addException(re);
}
}
}
use of org.codehaus.groovy.ast.expr.ListExpression in project groovy-core by groovy.
the class BinaryExpressionTransformer method transformBinaryExpression.
Expression transformBinaryExpression(final BinaryExpression bin) {
if (bin instanceof DeclarationExpression) {
Expression optimized = transformDeclarationExpression(bin);
if (optimized != null) {
return optimized;
}
}
Object[] list = bin.getNodeMetaData(BINARY_EXP_TARGET);
Token operation = bin.getOperation();
int operationType = operation.getType();
Expression rightExpression = bin.getRightExpression();
Expression leftExpression = bin.getLeftExpression();
if (bin instanceof DeclarationExpression && leftExpression instanceof VariableExpression) {
ClassNode declarationType = ((VariableExpression) leftExpression).getOriginType();
if (rightExpression instanceof ConstantExpression) {
ClassNode unwrapper = ClassHelper.getUnwrapper(declarationType);
ClassNode wrapper = ClassHelper.getWrapper(declarationType);
if (!rightExpression.getType().equals(declarationType) && wrapper.isDerivedFrom(ClassHelper.Number_TYPE) && WideningCategories.isDoubleCategory(unwrapper)) {
ConstantExpression constant = (ConstantExpression) rightExpression;
if (constant.getValue() != null) {
return optimizeConstantInitialization(bin, operation, constant, leftExpression, declarationType);
}
}
}
}
if (operationType == Types.EQUAL && leftExpression instanceof PropertyExpression) {
MethodNode directMCT = leftExpression.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET);
if (directMCT != null) {
return transformPropertyAssignmentToSetterCall((PropertyExpression) leftExpression, rightExpression, directMCT);
}
}
if (operationType == Types.COMPARE_EQUAL || operationType == Types.COMPARE_NOT_EQUAL) {
// let's check if one of the operands is the null constant
CompareToNullExpression compareToNullExpression = null;
if (isNullConstant(leftExpression)) {
compareToNullExpression = new CompareToNullExpression(staticCompilationTransformer.transform(rightExpression), operationType == Types.COMPARE_EQUAL);
} else if (isNullConstant(rightExpression)) {
compareToNullExpression = new CompareToNullExpression(staticCompilationTransformer.transform(leftExpression), operationType == Types.COMPARE_EQUAL);
}
if (compareToNullExpression != null) {
compareToNullExpression.setSourcePosition(bin);
return compareToNullExpression;
}
} else if (operationType == Types.KEYWORD_IN) {
return convertInOperatorToTernary(bin, rightExpression, leftExpression);
}
if (list != null) {
if (operationType == Types.COMPARE_TO) {
StaticTypesTypeChooser typeChooser = staticCompilationTransformer.getTypeChooser();
ClassNode classNode = staticCompilationTransformer.getClassNode();
ClassNode leftType = typeChooser.resolveType(leftExpression, classNode);
if (leftType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
ClassNode rightType = typeChooser.resolveType(rightExpression, classNode);
if (rightType.implementsInterface(ClassHelper.COMPARABLE_TYPE)) {
Expression left = staticCompilationTransformer.transform(leftExpression);
Expression right = staticCompilationTransformer.transform(rightExpression);
MethodCallExpression call = new MethodCallExpression(left, "compareTo", new ArgumentListExpression(right));
call.setImplicitThis(false);
call.setMethodTarget(COMPARE_TO_METHOD);
CompareIdentityExpression compareIdentity = new CompareIdentityExpression(left, right);
compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.boolean_TYPE);
TernaryExpression result = new TernaryExpression(// a==b
new BooleanExpression(compareIdentity), CONSTANT_ZERO, new TernaryExpression(// a==null
new BooleanExpression(new CompareToNullExpression(left, true)), CONSTANT_MINUS_ONE, new TernaryExpression(// b==null
new BooleanExpression(new CompareToNullExpression(right, true)), CONSTANT_ONE, call)));
compareIdentity.putNodeMetaData(StaticTypesMarker.INFERRED_RETURN_TYPE, ClassHelper.int_TYPE);
result.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
TernaryExpression expr = (TernaryExpression) result.getFalseExpression();
expr.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
expr.getFalseExpression().putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, ClassHelper.int_TYPE);
return result;
}
}
}
boolean isAssignment = StaticTypeCheckingSupport.isAssignment(operationType);
MethodCallExpression call;
MethodNode node = (MethodNode) list[0];
String name = (String) list[1];
Expression left = staticCompilationTransformer.transform(leftExpression);
Expression right = staticCompilationTransformer.transform(rightExpression);
BinaryExpression optimized = tryOptimizeCharComparison(left, right, bin);
if (optimized != null) {
optimized.removeNodeMetaData(BINARY_EXP_TARGET);
return transformBinaryExpression(optimized);
}
call = new MethodCallExpression(left, name, new ArgumentListExpression(right));
call.setImplicitThis(false);
call.setMethodTarget(node);
MethodNode adapter = StaticCompilationTransformer.BYTECODE_BINARY_ADAPTERS.get(operationType);
if (adapter != null) {
ClassExpression sba = new ClassExpression(StaticCompilationTransformer.BYTECODE_ADAPTER_CLASS);
// replace with compareEquals
call = new MethodCallExpression(sba, "compareEquals", new ArgumentListExpression(left, right));
call.setMethodTarget(adapter);
call.setImplicitThis(false);
}
if (!isAssignment)
return call;
// the method represents the operation type only, and we must add an assignment
return new BinaryExpression(left, Token.newSymbol("=", operation.getStartLine(), operation.getStartColumn()), call);
}
if (bin.getOperation().getType() == Types.EQUAL && leftExpression instanceof TupleExpression && rightExpression instanceof ListExpression) {
// multiple assignment
ListOfExpressionsExpression cle = new ListOfExpressionsExpression();
boolean isDeclaration = bin instanceof DeclarationExpression;
List<Expression> leftExpressions = ((TupleExpression) leftExpression).getExpressions();
List<Expression> rightExpressions = ((ListExpression) rightExpression).getExpressions();
Iterator<Expression> leftIt = leftExpressions.iterator();
Iterator<Expression> rightIt = rightExpressions.iterator();
if (isDeclaration) {
while (leftIt.hasNext()) {
Expression left = leftIt.next();
if (rightIt.hasNext()) {
Expression right = rightIt.next();
BinaryExpression bexp = new DeclarationExpression(left, bin.getOperation(), right);
bexp.setSourcePosition(right);
cle.addExpression(bexp);
}
}
} else {
// (next, result) = [ result, next+result ]
// -->
// def tmp1 = result
// def tmp2 = next+result
// next = tmp1
// result = tmp2
int size = rightExpressions.size();
List<Expression> tmpAssignments = new ArrayList<Expression>(size);
List<Expression> finalAssignments = new ArrayList<Expression>(size);
for (int i = 0; i < Math.min(size, leftExpressions.size()); i++) {
Expression left = leftIt.next();
Expression right = rightIt.next();
VariableExpression tmpVar = new VariableExpression("$tmpVar$" + tmpVarCounter++);
BinaryExpression bexp = new DeclarationExpression(tmpVar, bin.getOperation(), right);
bexp.setSourcePosition(right);
tmpAssignments.add(bexp);
bexp = new BinaryExpression(left, bin.getOperation(), new VariableExpression(tmpVar));
bexp.setSourcePosition(left);
finalAssignments.add(bexp);
}
for (Expression tmpAssignment : tmpAssignments) {
cle.addExpression(tmpAssignment);
}
for (Expression finalAssignment : finalAssignments) {
cle.addExpression(finalAssignment);
}
}
return staticCompilationTransformer.transform(cle);
}
return staticCompilationTransformer.superTransform(bin);
}
Aggregations