public static boolean isVisible(SourceUnit source, String className) { try { source.getClassLoader().loadClass(className); return true; } catch (ClassNotFoundException e) { return false; } }
public void visit(ASTNode[] nodes, final SourceUnit source) { init(nodes, source); AnnotatedNode targetClass = (AnnotatedNode) nodes[1]; AnnotationNode logAnnotation = (AnnotationNode) nodes[0]; final GroovyClassLoader classLoader = compilationUnit != null ? compilationUnit.getTransformLoader() : source.getClassLoader(); final LoggingStrategy loggingStrategy = createLoggingStrategy(logAnnotation, classLoader); if (loggingStrategy == null) return; final String logFieldName = lookupLogFieldName(logAnnotation); final String categoryName = lookupCategoryName(logAnnotation); if (!(targetClass instanceof ClassNode)) throw new GroovyBugError( "Class annotation " + logAnnotation.getClassNode().getName() + " annotated no Class, this must not happen."); final ClassNode classNode = (ClassNode) targetClass; ClassCodeExpressionTransformer transformer = new ClassCodeExpressionTransformer() { private FieldNode logNode; @Override protected SourceUnit getSourceUnit() { return source; } public Expression transform(Expression exp) { if (exp == null) return null; if (exp instanceof MethodCallExpression) { return transformMethodCallExpression(exp); } if (exp instanceof ClosureExpression) { return transformClosureExpression((ClosureExpression) exp); } return super.transform(exp); } @Override public void visitClass(ClassNode node) { FieldNode logField = node.getField(logFieldName); if (logField != null && logField.getOwner().equals(node)) { addError( "Class annotated with Log annotation cannot have log field declared", logField); } else if (logField != null && !Modifier.isPrivate(logField.getModifiers())) { addError( "Class annotated with Log annotation cannot have log field declared because the field exists in the parent class: " + logField.getOwner().getName(), logField); } else { logNode = loggingStrategy.addLoggerFieldToClass(node, logFieldName, categoryName); } super.visitClass(node); } private Expression transformClosureExpression(ClosureExpression exp) { if (exp.getCode() instanceof BlockStatement) { BlockStatement code = (BlockStatement) exp.getCode(); super.visitBlockStatement(code); } return exp; } private Expression transformMethodCallExpression(Expression exp) { MethodCallExpression mce = (MethodCallExpression) exp; if (!(mce.getObjectExpression() instanceof VariableExpression)) { return exp; } VariableExpression variableExpression = (VariableExpression) mce.getObjectExpression(); if (!variableExpression.getName().equals(logFieldName) || !(variableExpression.getAccessedVariable() instanceof DynamicVariable)) { return exp; } String methodName = mce.getMethodAsString(); if (methodName == null) return exp; if (usesSimpleMethodArgumentsOnly(mce)) return exp; variableExpression.setAccessedVariable(logNode); if (!loggingStrategy.isLoggingMethod(methodName)) return exp; return loggingStrategy.wrapLoggingMethodCall(variableExpression, methodName, exp); } private boolean usesSimpleMethodArgumentsOnly(MethodCallExpression mce) { Expression arguments = mce.getArguments(); if (arguments instanceof TupleExpression) { TupleExpression tuple = (TupleExpression) arguments; for (Expression exp : tuple.getExpressions()) { if (!isSimpleExpression(exp)) return false; } return true; } return !isSimpleExpression(arguments); } private boolean isSimpleExpression(Expression exp) { if (exp instanceof ConstantExpression) return true; if (exp instanceof VariableExpression) return true; return false; } }; transformer.visitClass(classNode); // GROOVY-6373: references to 'log' field are normally already FieldNodes by now, so revisit // scoping new VariableScopeVisitor(sourceUnit, true).visitClass(classNode); }
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>> 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>(); Expression value = node.getMember("value"); ConstantExpression ce = null; if (value != null && value instanceof ConstantExpression) { ce = (ConstantExpression) value; } String sval = null; if (ce != null && ce.getValue() instanceof String) { sval = (String) ce.getValue(); } if (sval != null && sval.length() > 0) { for (String s : GRABRESOLVER_REQUIRED) { Expression member = node.getMember(s); if (member != 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) { Expression member = node.getMember(s); if (member == null) { addError( "The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node); continue grabResolverAnnotationLoop; } 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 grabResolverAnnotationLoop; } grabResolverMap.put(s, ((ConstantExpression) member).getValue()); } } 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); 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); callGrabAsStaticInitIfNeeded(classNode, grapeClassNode, node, 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); } } }
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; // Since we use the data: scheme for StringReaderSources (which are fairly common) // 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(); } // If source doesn't know how to get a reference to itself, // 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); } } }