public static int getVisibility(FieldNode field) { return field.getModifiers() & (Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE); }
public static void setVisibility(FieldNode field, int visibility) { int modifiers = field.getModifiers(); modifiers &= ~(Opcodes.ACC_PUBLIC | Opcodes.ACC_PROTECTED | Opcodes.ACC_PRIVATE); field.setModifiers(modifiers | visibility); }
private static void revertVisibility(FieldNode fNode) { fNode.setModifiers(fNode.getModifiers() & ~ACC_PRIVATE); }
private void checkInterfaceFieldModifiers(FieldNode node) { if (!currentClass.isInterface()) return; if ((node.getModifiers() & (ACC_PUBLIC | ACC_STATIC | ACC_FINAL)) == 0 || (node.getModifiers() & (ACC_PRIVATE | ACC_PROTECTED)) != 0) { addError("The " + getDescription(node) + " is not 'public static final' but is defined in " + getDescription(currentClass) + ".", node); } }
private void printFields(PrintWriter out, ClassNode classNode) { boolean isInterface = isInterfaceOrTrait(classNode); List<FieldNode> fields = classNode.getFields(); if (fields == null) return; List<FieldNode> enumFields = new ArrayList<FieldNode>(fields.size()); List<FieldNode> normalFields = new ArrayList<FieldNode>(fields.size()); for (FieldNode field : fields) { boolean isSynthetic = (field.getModifiers() & Opcodes.ACC_SYNTHETIC) != 0; if (field.isEnum()) { enumFields.add(field); } else if (!isSynthetic) { normalFields.add(field); } } printEnumFields(out, enumFields); for (FieldNode normalField : normalFields) { printField(out, normalField, isInterface); } }
private static boolean isValidFieldNodeForByteCodeAccess(FieldNode fn, ClassNode accessingNode) { if (fn == null) return false; ClassNode declaringClass = fn.getDeclaringClass(); // same class is always allowed access if (Modifier.isPublic(fn.getModifiers()) || declaringClass.equals(accessingNode)) return true; boolean samePackages = samePackages(declaringClass.getPackageName(), accessingNode.getPackageName()); // protected means same class or same package, or subclass if (Modifier.isProtected(fn.getModifiers()) && (samePackages || accessingNode.isDerivedFrom(declaringClass))) { return true; } if (!fn.isPrivate()) { // package private is the only modifier left. It means same package is allowed, subclass not, same class is return samePackages; } return false; }
private static FieldNode checkFieldDoesNotExist(ClassNode node, String fieldName) { FieldNode ret = node.getDeclaredField(fieldName); if (ret != null) { if (isPublic(ret.getModifiers()) && ret.getType().redirect() == ClassHelper.boolean_TYPE) { return ret; } throw new RuntimeParserException("The class " + node.getName() + " cannot declare field '" + fieldName + "' as this" + " field is needed for internal groovy purposes", ret); } return null; }
public void visitField(FieldNode fieldNode) { cv.visitField( fieldNode.getModifiers(), fieldNode.getName(), BytecodeHelper.getTypeDescription(fieldNode.getType()), null, //fieldValue, //br all the sudden that one cannot init the field here. init is done in static initializer and instance initializer. null); }
private void checkProps(List<FieldNode> list, List<String> excludes, boolean checkPropertyTypes) { for (FieldNode fNode : list) { if (excludes != null && excludes.contains(fNode.getName())) continue; if ((fNode.getModifiers() & ACC_TRANSIENT) != 0) continue; if ((fNode.getModifiers() & ACC_FINAL) != 0) { addError(MY_TYPE_NAME + ": The Externalizable property (or field) '" + fNode.getName() + "' cannot be final", fNode); } ClassNode propType = fNode.getType(); if (checkPropertyTypes && !isPrimitiveType(propType) && !implementsExternalizable(propType) && !implementsSerializable(propType)) { addError(MY_TYPE_NAME + ": strict type checking is enabled and the non-primitive property (or field) '" + fNode.getName() + "' in an Externalizable class has the type '" + propType.getName() + "' which isn't Externalizable or Serializable", fNode); } } }
private static void makeSharedFieldProtectedAndVolatile(Field field) { AstUtil.setVisibility(field.getAst(), Opcodes.ACC_PROTECTED); field.getAst().setModifiers(field.getAst().getModifiers() | Opcodes.ACC_VOLATILE); }
@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 static void visitDeprecation(AnnotatedNode node, AnnotationNode visited) { if (visited.getClassNode().isResolved() && visited.getClassNode().getName().equals("java.lang.Deprecated")) { if (node instanceof MethodNode) { MethodNode mn = (MethodNode) node; mn.setModifiers(mn.getModifiers() | Opcodes.ACC_DEPRECATED); } else if (node instanceof FieldNode) { FieldNode fn = (FieldNode) node; fn.setModifiers(fn.getModifiers() | Opcodes.ACC_DEPRECATED); } else if (node instanceof ClassNode) { ClassNode cn = (ClassNode) node; cn.setModifiers(cn.getModifiers() | Opcodes.ACC_DEPRECATED); } } }
private static FieldNode createFieldCopy(ClassNode buildee, FieldNode fNode) { Map<String,ClassNode> genericsSpec = createGenericsSpec(fNode.getDeclaringClass()); extractSuperClassGenerics(fNode.getType(), buildee, genericsSpec); ClassNode correctedType = correctToGenericsSpecRecurse(genericsSpec, fNode.getType()); return new FieldNode(fNode.getName(), fNode.getModifiers(), correctedType, buildee, DEFAULT_INITIAL_VALUE); }
private static FieldNode getMetaClassField(ClassNode node) { FieldNode ret = node.getDeclaredField("metaClass"); if (ret != null) { ClassNode mcFieldType = ret.getType(); if (!mcFieldType.equals(ClassHelper.METACLASS_TYPE)) { throw new RuntimeParserException("The class " + node.getName() + " cannot declare field 'metaClass' of type " + mcFieldType.getName() + " as it needs to be of " + "the type " + ClassHelper.METACLASS_TYPE.getName() + " for internal groovy purposes", ret); } return ret; } ClassNode current = node; while (current != ClassHelper.OBJECT_TYPE) { current = current.getSuperClass(); if (current == null) break; ret = current.getDeclaredField("metaClass"); if (ret == null) continue; if (isPrivate(ret.getModifiers())) continue; return ret; } return null; }
private static void createReadExternal(ClassNode cNode, List<String> excludes, List<FieldNode> list) { final BlockStatement body = new BlockStatement(); Parameter oin = param(OBJECTINPUT_TYPE, "oin"); for (FieldNode fNode : list) { if (excludes != null && excludes.contains(fNode.getName())) continue; if ((fNode.getModifiers() & ACC_TRANSIENT) != 0) continue; String suffix = suffixForField(fNode); MethodCallExpression readObject = callX(varX(oin), "read" + suffix); readObject.setImplicitThis(false); body.addStatement(assignS(varX(fNode), suffix.equals("Object") ? castX(GenericsUtils.nonGeneric(fNode.getType()), readObject) : readObject)); } addGeneratedMethod(cNode, "readExternal", ACC_PUBLIC, ClassHelper.VOID_TYPE, params(oin), ClassNode.EMPTY_ARRAY, body); }
private static void createWriteExternal(ClassNode cNode, List<String> excludes, List<FieldNode> list) { final BlockStatement body = new BlockStatement(); Parameter out = param(OBJECTOUTPUT_TYPE, "out"); for (FieldNode fNode : list) { if (excludes != null && excludes.contains(fNode.getName())) continue; if ((fNode.getModifiers() & ACC_TRANSIENT) != 0) continue; MethodCallExpression writeObject = callX(varX(out), "write" + suffixForField(fNode), varX(fNode)); writeObject.setImplicitThis(false); body.addStatement(stmt(writeObject)); } ClassNode[] exceptions = {make(IOException.class)}; addGeneratedMethod(cNode, "writeExternal", ACC_PUBLIC, ClassHelper.VOID_TYPE, params(out), exceptions, body); }
private void addListenerToClass(SourceUnit source, ClassNode classNode) { if (needsPropertyChangeSupport(classNode, source)) { addPropertyChangeSupport(classNode); } for (PropertyNode propertyNode : classNode.getProperties()) { FieldNode field = propertyNode.getField(); // look to see if per-field handlers will catch this one... if (hasBindableAnnotation(field) || ((field.getModifiers() & Opcodes.ACC_FINAL) != 0) || field.isStatic() || VetoableASTTransformation.hasVetoableAnnotation(field)) { // explicitly labeled properties are already handled, // don't transform final properties // don't transform static properties // VetoableASTTransformation will handle both @Bindable and @Vetoable continue; } createListenerSetter(classNode, propertyNode); } }
/** * Handles the bulk of the processing, mostly delegating to other methods. * * @param nodes the AST nodes * @param source the source unit for the nodes */ public void visit(ASTNode[] nodes, SourceUnit source) { if (!(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) { throw new RuntimeException("Internal error: wrong types: $node.class / $parent.class"); } AnnotationNode node = (AnnotationNode) nodes[0]; if (nodes[1] instanceof ClassNode) { addListenerToClass(source, (ClassNode) nodes[1]); } else { if ((((FieldNode)nodes[1]).getModifiers() & Opcodes.ACC_FINAL) != 0) { source.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage( new SyntaxException("@groovy.beans.Vetoable cannot annotate a final property.", node.getLineNumber(), node.getColumnNumber(), node.getLastLineNumber(), node.getLastColumnNumber()), source)); } addListenerToProperty(source, node, (AnnotatedNode) nodes[1]); } }
static void visitField(ErrorCollecting xform, AnnotationNode node, FieldNode fieldNode) { final Expression soft = node.getMember("soft"); final Expression init = getInitExpr(xform, fieldNode); String backingFieldName = "$" + fieldNode.getName(); fieldNode.rename(backingFieldName); fieldNode.setModifiers(ACC_PRIVATE | (fieldNode.getModifiers() & (~(ACC_PUBLIC | ACC_PROTECTED)))); PropertyNode pNode = fieldNode.getDeclaringClass().getProperty(backingFieldName); if (pNode != null) { fieldNode.getDeclaringClass().getProperties().remove(pNode); } if (soft instanceof ConstantExpression && ((ConstantExpression) soft).getValue().equals(true)) { createSoft(fieldNode, init); } else { create(fieldNode, init); // @Lazy not meaningful with primitive so convert to wrapper if needed if (ClassHelper.isPrimitiveType(fieldNode.getType())) { fieldNode.setType(ClassHelper.getWrapper(fieldNode.getType())); } } }
/** * 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); } }