@Override protected SourceUnit getSourceUnit() { return cNode.getModule().getContext(); }
public static void markAsGenerated(ClassNode containingClass, AnnotatedNode nodeToMark) { boolean shouldAnnotate = containingClass.getModule() != null && containingClass.getModule().getContext() != null; if (shouldAnnotate && !hasAnnotation(nodeToMark, GENERATED_TYPE)) { nodeToMark.addAnnotation(new AnnotationNode(GENERATED_TYPE)); } }
protected List<PropertyInfo> getPropertyInfos(BuilderASTTransformation transform, AnnotationNode anno, ClassNode buildee, List<String> excludes, List<String> includes, boolean allNames, boolean allProperties) { if (buildee.getModule() == null) { return getPropertyInfoFromBeanInfo(buildee, includes, excludes, allNames); } return getPropertyInfoFromClassNode(transform, anno, buildee, includes, excludes, allNames, allProperties); }
private String getPath(Class clazz, Map<String, String> precompiledEntries) { CompilationUnit cu = getLocalData().get().cu; String name = clazz.getName(); ClassNode classNode = cu.getClassNode(name); if (classNode == null) { // this is a precompiled class! String path = precompiledEntries.get(name); if (path == null) throw new GroovyBugError("Precompiled class " + name + " should be available in precompiled entries map, but was not."); return path; } else { return classNode.getModule().getContext().getName(); } }
public static boolean isJointCompiled(ClassNode clazz) { return clazz.getModule().getUnit().getConfig().getJointCompilationOptions() != null; }
public boolean addInnerClass(ClassNode innerClass) { ModuleNode mn = controller.getClassNode().getModule(); innerClass.setModule(mn); mn.getUnit().addGeneratedInnerClass((InnerClassNode)innerClass); return innerClasses.add(innerClass); } }
private static void createBuilderFactoryMethod(AnnotationNode anno, ClassNode buildee, ClassNode builder) { buildee.getModule().addClass(builder); buildee.addMethod(createBuilderMethod(anno, builder)); }
private static void printImports(PrintWriter out, ClassNode classNode) { List<String> imports = new ArrayList<String>(); ModuleNode moduleNode = classNode.getModule(); for (ImportNode importNode : moduleNode.getStarImports()) { imports.add(importNode.getPackageName()); } for (ImportNode imp : moduleNode.getImports()) { if (imp.getAlias() == null) imports.add(imp.getType().getName()); } imports.addAll(Arrays.asList(ResolveVisitor.DEFAULT_IMPORTS)); for (Map.Entry<String, ImportNode> entry : moduleNode.getStaticImports().entrySet()) { if (entry.getKey().equals(entry.getValue().getFieldName())) imports.add("static "+entry.getValue().getType().getName()+"."+entry.getKey()); } for (Map.Entry<String, ImportNode> entry : moduleNode.getStaticStarImports().entrySet()) { imports.add("static "+entry.getValue().getType().getName()+"."); } for (String imp : imports) { String s = ("import " + imp + ((imp.charAt(imp.length() - 1) == '.') ? "*;" : ";")) .replace('$', '.'); out.println(s); } out.println(); }
/** * Loads the given class node returning the implementation Class. * <p> * WARNING: this compilation is not synchronized * * @param classNode * @return a class */ public Class defineClass(ClassNode classNode, String file, String newCodeBase) { CodeSource codeSource = null; try { codeSource = new CodeSource(new URL("file", "", newCodeBase), (java.security.cert.Certificate[]) null); } catch (MalformedURLException e) { //swallow } CompilationUnit unit = createCompilationUnit(config, codeSource); ClassCollector collector = createCollector(unit, classNode.getModule().getContext()); try { unit.addClassNode(classNode); unit.setClassgenCallback(collector); unit.compile(Phases.CLASS_GENERATION); definePackageInternal(collector.generatedClass.getName()); return collector.generatedClass; } catch (CompilationFailedException e) { throw new RuntimeException(e); } }
private void addSpecMetadata(Spec spec) { AnnotationNode ann = new AnnotationNode(nodeCache.SpecMetadata); String pathname = spec.getAst().getModule().getContext().getName(); String filename = new File(pathname).getName(); ann.setMember(SpecMetadata.FILENAME, new ConstantExpression(filename)); ann.setMember(SpecMetadata.LINE, new ConstantExpression(spec.getAst().getLineNumber())); spec.getAst().addAnnotation(ann); }
/** * Given a method node, checks if we are calling a private method from an inner class. */ private void checkOrMarkPrivateAccess(Expression source, MethodNode mn) { if (mn == null) { return; } ClassNode declaringClass = mn.getDeclaringClass(); ClassNode enclosingClassNode = typeCheckingContext.getEnclosingClassNode(); if (declaringClass != enclosingClassNode || typeCheckingContext.getEnclosingClosure() != null) { int mods = mn.getModifiers(); boolean sameModule = declaringClass.getModule() == enclosingClassNode.getModule(); String packageName = declaringClass.getPackageName(); if (packageName == null) { packageName = ""; } if ((Modifier.isPrivate(mods) && sameModule)) { addPrivateFieldOrMethodAccess(source, declaringClass, StaticTypesMarker.PV_METHODS_ACCESS, mn); } else if (Modifier.isProtected(mods) && !packageName.equals(enclosingClassNode.getPackageName()) && !implementsInterfaceOrIsSubclassOf(enclosingClassNode, declaringClass)) { ClassNode cn = enclosingClassNode; while ((cn = cn.getOuterClass()) != null) { if (implementsInterfaceOrIsSubclassOf(cn, declaringClass)) { addPrivateFieldOrMethodAccess(source, cn, StaticTypesMarker.PV_METHODS_ACCESS, mn); break; } } } } }
public void visitClass(ClassNode node) { visitAnnotations(node); visitPackage(node.getPackage()); visitImports(node.getModule()); node.visitContents(this); visitObjectInitializerStatements(node); }
private void buildCommon(ClassNode buildee, AnnotationNode anno, List<FieldNode> fieldNodes, ClassNode builder) { String prefix = getMemberStringValue(anno, "prefix", ""); String buildMethodName = getMemberStringValue(anno, "buildMethodName", "create"); createBuilderConstructors(builder, buildee, fieldNodes); buildee.getModule().addClass(builder); String builderMethodName = getMemberStringValue(anno, "builderMethodName", "createInitializer"); buildee.addMethod(createBuilderMethod(buildMethodName, builder, fieldNodes.size(), builderMethodName)); for (int i = 0; i < fieldNodes.size(); i++) { builder.addMethod(createBuilderMethodForField(builder, fieldNodes, prefix, i)); } builder.addMethod(createBuildMethod(builder, buildMethodName, fieldNodes)); }
protected Class createClass(byte[] code, ClassNode classNode) { BytecodeProcessor bytecodePostprocessor = unit.getConfiguration().getBytecodePostprocessor(); byte[] fcode = code; if (bytecodePostprocessor!=null) { fcode = bytecodePostprocessor.processBytecode(classNode.getName(), fcode); } GroovyClassLoader cl = getDefiningClassLoader(); Class theClass = cl.defineClass(classNode.getName(), fcode, 0, fcode.length, unit.getAST().getCodeSource()); this.loadedClasses.add(theClass); if (generatedClass == null) { ModuleNode mn = classNode.getModule(); SourceUnit msu = null; if (mn != null) msu = mn.getContext(); ClassNode main = null; if (mn != null) main = (ClassNode) mn.getClasses().get(0); if (msu == su && main == classNode) generatedClass = theClass; } return theClass; }
private Expression transformMapEntryExpression(MapEntryExpression me, ClassNode constructorCallType) { Expression key = me.getKeyExpression(); Expression value = me.getValueExpression(); ModuleNode module = currentClass.getModule(); if (module != null && key instanceof ConstantExpression) { Map<String, ImportNode> importNodes = module.getStaticImports(); if (importNodes.containsKey(key.getText())) { ImportNode importNode = importNodes.get(key.getText()); if (importNode.getType().equals(constructorCallType)) { String newKey = importNode.getFieldName(); return new MapEntryExpression(new ConstantExpression(newKey), value.transformExpression(this)); } } } return me; }
/** * Given a field node, checks if we are accessing or setting a private field from an inner class. */ private void checkOrMarkPrivateAccess(Expression source, FieldNode fn, boolean lhsOfAssignment) { ClassNode enclosingClassNode = typeCheckingContext.getEnclosingClassNode(); ClassNode declaringClass = fn.getDeclaringClass(); if (fn != null && Modifier.isPrivate(fn.getModifiers()) && (declaringClass != enclosingClassNode || typeCheckingContext.getEnclosingClosure() != null) && declaringClass.getModule() == enclosingClassNode.getModule()) { if (!lhsOfAssignment && enclosingClassNode.isDerivedFrom(declaringClass)) { // check for a public/protected getter since JavaBean getters haven't been recognised as properties // at this point and we don't want private field access for that case which will be handled later boolean isPrimBool = fn.getOriginType().equals(ClassHelper.boolean_TYPE); String suffix = Verifier.capitalize(fn.getName()); MethodNode getterNode = findValidGetter(enclosingClassNode, "get" + suffix); if (getterNode == null && isPrimBool) { getterNode = findValidGetter(enclosingClassNode, "is" + suffix); } if (getterNode != null) { source.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, getterNode.getReturnType()); return; } } StaticTypesMarker marker = lhsOfAssignment ? StaticTypesMarker.PV_FIELDS_MUTATION : StaticTypesMarker.PV_FIELDS_ACCESS; addPrivateFieldOrMethodAccess(source, declaringClass, marker, fn); } }
private boolean resolveToOuter(ClassNode type) { String name = type.getName(); // We do not need to check instances of LowerCaseClass // to be a Class, because unless there was an import for // for this we do not lookup these cases. This was a decision // made on the mailing list. To ensure we will not visit this // method again we set a NO_CLASS for this name if (type instanceof LowerCaseClass) { classNodeResolver.cacheClass(name, ClassNodeResolver.NO_CLASS); return false; } if (currentClass.getModule().hasPackageName() && name.indexOf('.') == -1) return false; LookupResult lr = classNodeResolver.resolveName(name, compilationUnit); if (lr != null) { if (lr.isSourceUnit()) { SourceUnit su = lr.getSourceUnit(); currentClass.getCompileUnit().addClassNodeToCompile(type, su); } else { type.setRedirect(lr.getClassNode()); } return true; } return false; }
private static void addHolderClassIdiomBody(BlockStatement body, FieldNode fieldNode, Expression initExpr) { final ClassNode declaringClass = fieldNode.getDeclaringClass(); final ClassNode fieldType = fieldNode.getType(); final int visibility = ACC_PRIVATE | ACC_STATIC; final String fullName = declaringClass.getName() + "$" + fieldType.getNameWithoutPackage() + "Holder_" + fieldNode.getName().substring(1); final InnerClassNode holderClass = new InnerClassNode(declaringClass, fullName, visibility, ClassHelper.OBJECT_TYPE); final String innerFieldName = "INSTANCE"; // we have two options: // (1) embed initExpr within holder class but redirect field access/method calls to declaring class members // (2) keep initExpr within a declaring class method that is only called by the holder class // currently we have gone with (2) for simplicity with only a slight memory footprint increase in the declaring class final String initializeMethodName = (fullName + "_initExpr").replace('.', '_'); addGeneratedMethod(declaringClass, initializeMethodName, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, fieldType, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(initExpr)); holderClass.addField(innerFieldName, ACC_PRIVATE | ACC_STATIC | ACC_FINAL, fieldType, callX(declaringClass, initializeMethodName)); final Expression innerField = propX(classX(holderClass), innerFieldName); declaringClass.getModule().addClass(holderClass); body.addStatement(returnS(innerField)); }
private static void createComparatorFor(ClassNode classNode, PropertyNode property, boolean reversed) { String propName = StringGroovyMethods.capitalize((CharSequence) property.getName()); String className = classNode.getName() + "$" + propName + "Comparator"; ClassNode superClass = makeClassSafeWithGenerics(AbstractComparator.class, classNode); InnerClassNode cmpClass = new InnerClassNode(classNode, className, ACC_PRIVATE | ACC_STATIC, superClass); classNode.getModule().addClass(cmpClass); addGeneratedMethod(cmpClass, "compare", ACC_PUBLIC, ClassHelper.int_TYPE, params(param(newClass(classNode), ARG0), param(newClass(classNode), ARG1)), ClassNode.EMPTY_ARRAY, createCompareMethodBody(property, reversed) ); String fieldName = "this$" + propName + "Comparator"; // private final Comparator this$<property>Comparator = new <type>$<property>Comparator(); FieldNode cmpField = classNode.addField( fieldName, ACC_STATIC | ACC_FINAL | ACC_PRIVATE | ACC_SYNTHETIC, COMPARATOR_TYPE, ctorX(cmpClass)); addGeneratedMethod(classNode, "comparatorBy" + propName, ACC_PUBLIC | ACC_STATIC, COMPARATOR_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, returnS(fieldX(cmpField)) ); }