@Override public FieldNode getDeclaredField(final String name) { for (ClassNode delegate : delegates) { FieldNode node = delegate.getDeclaredField(name); if (node != null) return node; } return null; }
/** * @return the field node on the outer class or null if this is not an inner class */ public FieldNode getOuterField(String name) { return outerClass.getDeclaredField(name); }
@Override public FieldNode getDeclaredField(String name) { lazyInitMembers(); return super.getDeclaredField(name); }
/** * Finds a field matching the given name in this class or a parent class. * * @param name the name of the field of interest * @return the method matching the given name and parameters or null */ public FieldNode getField(String name) { ClassNode node = this; while (node != null) { FieldNode fn = node.getDeclaredField(name); if (fn != null) return fn; node = node.getSuperClass(); } return null; }
private static FieldNode tryGetFieldNode(final ClassNode weavedType, final String fieldName) { FieldNode fn = weavedType.getDeclaredField(fieldName); if (fn == null && ClassHelper.CLASS_Type.equals(weavedType)) { GenericsType[] genericsTypes = weavedType.getGenericsTypes(); if (genericsTypes != null && genericsTypes.length == 1) { // for static properties fn = genericsTypes[0].getType().getDeclaredField(fieldName); } } return fn; }
private static FieldNode getDeclaredOrInheritedField(ClassNode cn, String fieldName) { ClassNode node = cn; while (node != null) { FieldNode fn = node.getDeclaredField(fieldName); if (fn != null) return fn; List<ClassNode> interfacesToCheck = new ArrayList<ClassNode>(Arrays.asList(node.getInterfaces())); while (!interfacesToCheck.isEmpty()) { ClassNode nextInterface = interfacesToCheck.remove(0); fn = nextInterface.getDeclaredField(fieldName); if (fn != null) return fn; interfacesToCheck.addAll(Arrays.asList(nextInterface.getInterfaces())); } node = node.getSuperClass(); } return null; }
/** * Finds a field matching the given name in this class. * * @param name the name of the field of interest * @return the method matching the given name and parameters or null */ public FieldNode getDeclaredField(String name) { if (redirect != null) return redirect().getDeclaredField(name); lazyClassInit(); return fieldIndex == null ? null : fieldIndex.get(name); }
public static FieldNode getDeclaredFieldOfCurrentClassOrAccessibleFieldOfSuper(ClassNode accessingNode, ClassNode current, String name, boolean skipCurrent) { if (!skipCurrent) { FieldNode currentClassField = current.getDeclaredField(name); if (isValidFieldNodeForByteCodeAccess(currentClassField, accessingNode)) return currentClassField; } for (ClassNode node = current.getSuperClass(); node!=null; node = node.getSuperClass()) { FieldNode fn = node.getDeclaredField(name); if (isValidFieldNodeForByteCodeAccess(fn, accessingNode)) return fn; } return null; }
/** * Return the (potentially inherited) field of the classnode. * * @param classNode the classnode * @param fieldName the name of the field * @return the field or null if not found */ public static FieldNode getField(ClassNode classNode, String fieldName) { ClassNode node = classNode; Set<String> visited = new HashSet<String>(); while (node != null) { FieldNode fn = node.getDeclaredField(fieldName); if (fn != null) return fn; ClassNode[] interfaces = node.getInterfaces(); for (ClassNode iNode : interfaces) { if (visited.contains(iNode.getName())) continue; FieldNode ifn = getField(iNode, fieldName); visited.add(iNode.getName()); if (ifn != null) return ifn; } node = node.getSuperClass(); } return null; } }
protected boolean isClosureCall(final String name, final Expression objectExpression, final Expression arguments) { if (objectExpression instanceof ClosureExpression && ("call".equals(name) || "doCall".equals(name))) return true; if (objectExpression == VariableExpression.THIS_EXPRESSION) { FieldNode fieldNode = typeCheckingContext.getEnclosingClassNode().getDeclaredField(name); if (fieldNode != null) { ClassNode type = fieldNode.getType(); if (CLOSURE_TYPE.equals(type) && !typeCheckingContext.getEnclosingClassNode().hasPossibleMethod(name, arguments)) { return true; } } } else { if (!"call".equals(name) && !"doCall".equals(name)) return false; } return (getType(objectExpression).equals(CLOSURE_TYPE)); }
public void visitField(final FieldNode node) { if (visitor!=null) visitor.visitField(node); ClassNode declaringClass = node.getDeclaringClass(); if (declaringClass!=null) { if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(declaringClass, ClassHelper.LIST_TYPE)) { boolean spread = declaringClass.getDeclaredField(node.getName()) != node; pexp.setSpreadSafe(spread); } rType.set(declaringClass); } }
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; }
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; }
/** * Loads either this object or if we're inside a closure then load the top level owner */ protected void loadThisOrOwner() { if (isInnerClass()) { visitFieldExpression(new FieldExpression(controller.getClassNode().getDeclaredField("owner"))); } else { loadThis(null); } }
private void setConstField(ConstantExpression constantExpression) { final Object n = constantExpression.getValue(); if (!(n instanceof Number)) return; if (n instanceof Integer || n instanceof Double) return; if (n instanceof Long && (0L == (Long) n || 1L == (Long) n)) return; // LCONST_0, LCONST_1 boolean isPrimitive = isPrimitiveType(constantExpression.getType()); FieldNode field = isPrimitive ? const2Prims.get(n) : const2Objects.get(n); if (field != null) { constantExpression.setConstantName(field.getName()); return; } String name; do { name = "$const$" + index++; } while (currentClass.getDeclaredField(name) != null); // TODO consider moving initcode to <clinit> and remaking field final field = new FieldNode(name, Opcodes.ACC_PRIVATE | Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC, constantExpression.getType(), currentClass, constantExpression); field.setSynthetic(true); missingFields.add(field); constantExpression.setConstantName(field.getName()); if (isPrimitive) { const2Prims.put(n, field); } else { const2Objects.put(n, field); } }
protected void addTimeStamp(ClassNode node) { if (node.getDeclaredField(Verifier.__TIMESTAMP) == null) { // in case if verifier visited the call already FieldNode timeTagField = new FieldNode( Verifier.__TIMESTAMP, ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, ClassHelper.long_TYPE, //"", node, new ConstantExpression(System.currentTimeMillis())); // alternatively, FieldNode timeTagField = SourceUnit.createFieldNode("public static final long __timeStamp = " + System.currentTimeMillis() + "L"); timeTagField.setSynthetic(true); node.addField(timeTagField); timeTagField = new FieldNode( Verifier.__TIMESTAMP__ + String.valueOf(System.currentTimeMillis()), ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, ClassHelper.long_TYPE, //"", node, new ConstantExpression((long) 0)); // alternatively, FieldNode timeTagField = SourceUnit.createFieldNode("public static final long __timeStamp = " + System.currentTimeMillis() + "L"); timeTagField.setSynthetic(true); node.addField(timeTagField); } }
private boolean isClosureCall(MethodCallExpression call) { // are we a local variable? // it should not be an explicitly "this" qualified method call // and the current class should have a possible method ClassNode classNode = controller.getClassNode(); String methodName = call.getMethodAsString(); if (methodName==null) return false; if (!call.isImplicitThis()) return false; if (!AsmClassGenerator.isThisExpression(call.getObjectExpression())) return false; FieldNode field = classNode.getDeclaredField(methodName); if (field == null) return false; if (isStaticInvocation(call) && !field.isStatic()) return false; Expression arguments = call.getArguments(); return ! classNode.hasPossibleMethod(methodName, arguments); }
public void visitField(FieldNode node) { if (currentClass.getDeclaredField(node.getName()) != node) { addError("The " + getDescription(node) + " is declared multiple times.", node); } checkInterfaceFieldModifiers(node); checkGenericsUsage(node, node.getType()); if (node.getType().equals(VOID_TYPE)) { addError("The " + getDescription(node) + " has invalid type void", node); } super.visitField(node); }
private boolean validateEnumConstant(Expression exp) { if (exp instanceof PropertyExpression) { PropertyExpression pe = (PropertyExpression) exp; String name = pe.getPropertyAsString(); if (pe.getObjectExpression() instanceof ClassExpression && name != null) { ClassExpression ce = (ClassExpression) pe.getObjectExpression(); ClassNode type = ce.getType(); if (type.isEnum()) { boolean ok = false; try { FieldNode enumField = type.getDeclaredField(name); ok = enumField != null && enumField.getType().equals(type); } catch(Exception ex) { // ignore } if(!ok) { addError("No enum const " + type.getName() + "." + name, pe); return false; } } } } return true; }
public static void loadReference(String name, WriterController controller) { CompileStack compileStack = controller.getCompileStack(); MethodVisitor mv = controller.getMethodVisitor(); ClassNode classNode = controller.getClassNode(); AsmClassGenerator acg = controller.getAcg(); // compileStack.containsVariable(name) means to ask if the variable is already declared // compileStack.getScope().isReferencedClassVariable(name) means to ask if the variable is a field // If it is no field and is not yet declared, then it is either a closure shared variable or // an already declared variable. if (!compileStack.containsVariable(name) && compileStack.getScope().isReferencedClassVariable(name)) { acg.visitFieldExpression(new FieldExpression(classNode.getDeclaredField(name))); } else { BytecodeVariable v = compileStack.getVariable(name, !classNodeUsesReferences(controller.getClassNode())); if (v == null) { // variable is not on stack because we are // inside a nested Closure and this variable // was not used before // then load it from the Closure field FieldNode field = classNode.getDeclaredField(name); mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(GETFIELD, controller.getInternalClassName(), name, BytecodeHelper.getTypeDescription(field.getType())); } else { mv.visitVarInsn(ALOAD, v.getIndex()); } controller.getOperandStack().push(ClassHelper.REFERENCE_TYPE); } }