public void visitPropertyExpression(PropertyExpression expression) { buffer.append(expression.getPropertyAsString()); }
public void visitPropertyExpression(PropertyExpression expression) { buffer.append(expression.getPropertyAsString()); }
private static Expression correctClassClassChain(PropertyExpression pe) { LinkedList<Expression> stack = new LinkedList<Expression>(); ClassExpression found = null; for (Expression it = pe; it != null; it = ((PropertyExpression) it).getObjectExpression()) { if (it instanceof ClassExpression) { found = (ClassExpression) it; break; } else if (!(it.getClass() == PropertyExpression.class)) { return pe; } stack.addFirst(it); } if (found == null) return pe; if (stack.isEmpty()) return pe; Object stackElement = stack.removeFirst(); if (!(stackElement.getClass() == PropertyExpression.class)) return pe; PropertyExpression classPropertyExpression = (PropertyExpression) stackElement; String propertyNamePart = classPropertyExpression.getPropertyAsString(); if (propertyNamePart == null || !propertyNamePart.equals("class")) return pe; found.setSourcePosition(classPropertyExpression); if (stack.isEmpty()) return found; stackElement = stack.removeFirst(); if (!(stackElement.getClass() == PropertyExpression.class)) return pe; PropertyExpression classPropertyExpressionContainer = (PropertyExpression) stackElement; classPropertyExpressionContainer.setObjectExpression(found); return pe; }
private boolean isTraitSuperPropertyExpression(Expression exp) { if (exp instanceof PropertyExpression) { PropertyExpression pexp = (PropertyExpression) exp; Expression objectExpression = pexp.getObjectExpression(); if (objectExpression instanceof ClassExpression) { ClassNode type = objectExpression.getType(); if (Traits.isTrait(type) && "super".equals(pexp.getPropertyAsString())) { return true; } } } return false; } }
private static Visibility getVisibility(Expression e) { if (e instanceof PropertyExpression) { PropertyExpression pe = (PropertyExpression) e; if (pe.getObjectExpression() instanceof ClassExpression && pe.getObjectExpression().getText().equals("groovy.transform.options.Visibility")) { return Visibility.valueOf(pe.getPropertyAsString()); } } return Visibility.UNDEFINED; } }
private boolean addedReadOnlyPropertyError(Expression expr) { // if expr is of READONLY_PROPERTY_RETURN type, then it means we are on a missing property if (expr.getNodeMetaData(StaticTypesMarker.READONLY_PROPERTY) == null) return false; String name; if (expr instanceof VariableExpression) { name = ((VariableExpression) expr).getName(); } else { name = ((PropertyExpression) expr).getPropertyAsString(); } addStaticTypeError("Cannot set read-only property: " + name, expr); return true; }
@Override public void visitPropertyExpression(PropertyExpression expr) { result = new ExpressionInfo( TextRegion.of(expr), TextPosition.startOf(expr.getProperty()), expr.getPropertyAsString(), expr.isImplicitThis() ? Collections.<ExpressionInfo>emptyList() : Collections.singletonList(convert(expr.getObjectExpression()))); }
/** * a property on "this", like this.x is transformed to a * direct field access, so we need to check the * static context here * * @param pe the property expression to check */ private void checkPropertyOnExplicitThis(PropertyExpression pe) { if (!currentScope.isInStaticContext()) return; Expression object = pe.getObjectExpression(); if (!(object instanceof VariableExpression)) return; VariableExpression ve = (VariableExpression) object; if (!ve.getName().equals("this")) return; String name = pe.getPropertyAsString(); if (name == null || name.equals("class")) return; Variable member = findClassMember(currentClass, name); if (member == null) return; checkVariableContextAccess(member, pe); }
private static AnnotationCollectorMode getMode(AnnotationNode node) { final Expression member = node.getMember("mode"); if (member instanceof PropertyExpression) { PropertyExpression prop = (PropertyExpression) member; Expression oe = prop.getObjectExpression(); if (oe instanceof ClassExpression) { ClassExpression ce = (ClassExpression) oe; if (ce.getType().getName().equals("groovy.transform.AnnotationCollectorMode")) { return AnnotationCollectorMode.valueOf(prop.getPropertyAsString()); } } } return null; }
private static AutoCloneStyle getStyle(AnnotationNode node, String name) { final Expression member = node.getMember(name); if (member instanceof PropertyExpression) { PropertyExpression prop = (PropertyExpression) member; Expression oe = prop.getObjectExpression(); if (oe instanceof ClassExpression) { ClassExpression ce = (ClassExpression) oe; if (ce.getType().getName().equals("groovy.transform.AutoCloneStyle")) { return AutoCloneStyle.valueOf(prop.getPropertyAsString()); } } } return null; }
public void configureAnnotationNodeFromDefinition(AnnotationNode definition, AnnotationNode root) { ClassNode type = definition.getClassNode(); if ("java.lang.annotation.Retention".equals(type.getName())) { Expression exp = definition.getMember("value"); if (!(exp instanceof PropertyExpression)) return; PropertyExpression pe = (PropertyExpression) exp; String name = pe.getPropertyAsString(); RetentionPolicy policy = RetentionPolicy.valueOf(name); setRetentionPolicy(policy, root); } else if ("java.lang.annotation.Target".equals(type.getName())) { Expression exp = definition.getMember("value"); if (!(exp instanceof ListExpression)) return; ListExpression le = (ListExpression) exp; int bitmap = 0; for (Expression e : le.getExpressions()) { if (!(e instanceof PropertyExpression)) return; PropertyExpression element = (PropertyExpression) e; String name = element.getPropertyAsString(); ElementType value = ElementType.valueOf(name); bitmap |= getElementCode(value); } root.setAllowedTargets(bitmap); } }
public boolean isSkipMode(final AnnotatedNode node) { if (node == null) return false; for (ClassNode tca : getTypeCheckingAnnotations()) { List<AnnotationNode> annotations = node.getAnnotations(tca); if (annotations != null) { for (AnnotationNode annotation : annotations) { Expression value = annotation.getMember("value"); if (value != null) { if (value instanceof ConstantExpression) { ConstantExpression ce = (ConstantExpression) value; if (TypeCheckingMode.SKIP.toString().equals(ce.getValue().toString())) return true; } else if (value instanceof PropertyExpression) { PropertyExpression pe = (PropertyExpression) value; if (TypeCheckingMode.SKIP.toString().equals(pe.getPropertyAsString())) return true; } } } } } if (node instanceof MethodNode) { return isSkipMode(node.getDeclaringClass()); } if (isSkippedInnerClass(node)) return true; return false; }
private ClassNode getTypeForMapPropertyExpression(ClassNode testClass, ClassNode objectExpressionType, PropertyExpression pexp) { if (!implementsInterfaceOrIsSubclassOf(testClass, MAP_TYPE)) return null; ClassNode intf; if (objectExpressionType.getGenericsTypes() != null) { intf = GenericsUtils.parameterizeType(objectExpressionType, MAP_TYPE.getPlainNodeReference()); } else { intf = MAP_TYPE.getPlainNodeReference(); } // 0 is the key, 1 is the value GenericsType[] types = intf.getGenericsTypes(); if (types == null || types.length != 2) return OBJECT_TYPE; if (pexp.isSpreadSafe()) { // map*.property syntax // only "key" and "value" are allowed if ("key".equals(pexp.getPropertyAsString())) { ClassNode listKey = LIST_TYPE.getPlainNodeReference(); listKey.setGenericsTypes(new GenericsType[]{types[0]}); return listKey; } else if ("value".equals(pexp.getPropertyAsString())) { ClassNode listValue = LIST_TYPE.getPlainNodeReference(); listValue.setGenericsTypes(new GenericsType[]{types[1]}); return listValue; } else { addStaticTypeError("Spread operator on map only allows one of [key,value]", pexp); } } else { return types[1].getType(); } return null; }
private ClassNode getTypeForListPropertyExpression(ClassNode testClass, ClassNode objectExpressionType, PropertyExpression pexp) { if (!implementsInterfaceOrIsSubclassOf(testClass, LIST_TYPE)) return null; ClassNode intf = GenericsUtils.parameterizeType(objectExpressionType, LIST_TYPE.getPlainNodeReference()); GenericsType[] types = intf.getGenericsTypes(); if (types == null || types.length != 1) return OBJECT_TYPE; PropertyExpression subExp = new PropertyExpression(varX("{}", types[0].getType()), pexp.getPropertyAsString()); AtomicReference<ClassNode> result = new AtomicReference<ClassNode>(); if (existsProperty(subExp, true, new PropertyLookupVisitor(result))) { intf = LIST_TYPE.getPlainNodeReference(); ClassNode itemType = result.get(); intf.setGenericsTypes(new GenericsType[]{new GenericsType(wrapTypeIfNecessary(itemType))}); return intf; } return null; }
@Override public void visitPropertyExpression(final PropertyExpression pexp) { typeCheckingContext.pushEnclosingPropertyExpression(pexp); try { if (visitPropertyExpressionSilent(pexp, pexp)) return; if (!extension.handleUnresolvedProperty(pexp)) { Expression objectExpression = pexp.getObjectExpression(); addStaticTypeError("No such property: " + pexp.getPropertyAsString() + " for class: " + findCurrentInstanceOfClass(objectExpression, getType(objectExpression)).toString(false), pexp); } } finally { typeCheckingContext.popEnclosingPropertyExpression(); } }
private ClassNode getTypeForSpreadExpression(ClassNode testClass, ClassNode objectExpressionType, PropertyExpression pexp) { if (!pexp.isSpreadSafe()) return null; MethodCallExpression mce = callX(varX("_", testClass), "iterator", ArgumentListExpression.EMPTY_ARGUMENTS); mce.setImplicitThis(false); mce.visit(this); ClassNode callType = getType(mce); if (!implementsInterfaceOrIsSubclassOf(callType, Iterator_TYPE)) return null; GenericsType[] types = callType.getGenericsTypes(); ClassNode contentType = OBJECT_TYPE; if (types != null && types.length == 1) contentType = types[0].getType(); PropertyExpression subExp = new PropertyExpression(varX("{}", contentType), pexp.getPropertyAsString()); AtomicReference<ClassNode> result = new AtomicReference<ClassNode>(); if (existsProperty(subExp, true, new PropertyLookupVisitor(result))) { ClassNode intf = LIST_TYPE.getPlainNodeReference(); intf.setGenericsTypes(new GenericsType[]{new GenericsType(getWrapper(result.get()))}); return intf; } return null; }
private void checkThisAndSuperAsPropertyAccess(PropertyExpression expression) { if (expression.isImplicitThis()) return; String prop = expression.getPropertyAsString(); if (prop == null) return; if (!prop.equals("this") && !prop.equals("super")) return; ClassNode type = expression.getObjectExpression().getType(); if (expression.getObjectExpression() instanceof ClassExpression) { if (!(currentClass instanceof InnerClassNode) && !Traits.isTrait(type)) { addError("The usage of 'Class.this' and 'Class.super' is only allowed in nested/inner classes.", expression); return; } if (currentScope!=null && !currentScope.isInStaticContext() && Traits.isTrait(type) && "super".equals(prop) && directlyImplementsTrait(type)) { return; } ClassNode iterType = currentClass; while (iterType != null) { if (iterType.equals(type)) break; iterType = iterType.getOuterClass(); } if (iterType == null) { addError("The class '" + type.getName() + "' needs to be an outer class of '" + currentClass.getName() + "' when using '.this' or '.super'.", expression); } if ((currentClass.getModifiers() & Opcodes.ACC_STATIC) == 0) return; if (currentScope != null && !currentScope.isInStaticContext()) return; addError("The usage of 'Class.this' and 'Class.super' within static nested class '" + currentClass.getName() + "' is not allowed in a static context.", expression); } }
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; }
protected void checkGroovyConstructorMap(final Expression receiver, final ClassNode receiverType, final MapExpression mapExpression) { // workaround for map-style checks putting setter info on wrong AST nodes typeCheckingContext.pushEnclosingBinaryExpression(null); for (MapEntryExpression entryExpression : mapExpression.getMapEntryExpressions()) { Expression keyExpr = entryExpression.getKeyExpression(); if (!(keyExpr instanceof ConstantExpression)) { addStaticTypeError("Dynamic keys in map-style constructors are unsupported in static type checking", keyExpr); } else { AtomicReference<ClassNode> lookup = new AtomicReference<ClassNode>(); PropertyExpression pexp = new PropertyExpression(varX("_", receiverType), keyExpr.getText()); boolean hasProperty = existsProperty(pexp, false, new PropertyLookupVisitor(lookup)); if (!hasProperty) { addStaticTypeError("No such property: " + keyExpr.getText() + " for class: " + receiverType.getName(), receiver); } else { ClassNode valueType = getType(entryExpression.getValueExpression()); MethodNode setter = receiverType.getSetterMethod("set" + MetaClassHelper.capitalize(pexp.getPropertyAsString()), false); ClassNode toBeAssignedTo = setter == null ? lookup.get() : setter.getParameters()[0].getType(); if (!isAssignableTo(valueType, toBeAssignedTo) && !extension.handleIncompatibleAssignment(toBeAssignedTo, valueType, entryExpression)) { addAssignmentError(toBeAssignedTo, valueType, entryExpression); } } } } typeCheckingContext.popEnclosingBinaryExpression(); }
private void setPropertyOfSuperClass(ClassNode classNode, PropertyExpression expression, MethodVisitor mv) { String fieldName = expression.getPropertyAsString(); FieldNode fieldNode = classNode.getSuperClass().getField(fieldName); if (null == fieldNode) { throw new RuntimeParserException("Failed to find field[" + fieldName + "] of " + classNode.getName() + "'s super class", expression); } if (fieldNode.isFinal()) { throw new RuntimeParserException("Cannot modify final field[" + fieldName + "] of " + classNode.getName() + "'s super class", expression); } MethodNode setter = findSetterOfSuperClass(classNode, fieldNode); MethodNode getter = findGetterOfSuperClass(classNode, fieldNode); if (fieldNode.isPrivate() && !getterAndSetterExists(setter, getter)) { throw new RuntimeParserException("Cannot access private field[" + fieldName + "] of " + classNode.getName() + "'s super class", expression); } OperandStack operandStack = controller.getOperandStack(); operandStack.doAsType(fieldNode.getType()); mv.visitVarInsn(ALOAD, 0); operandStack.push(classNode); operandStack.swap(); String owner = BytecodeHelper.getClassInternalName(classNode.getSuperClass().getName()); String desc = BytecodeHelper.getTypeDescription(fieldNode.getType()); if (fieldNode.isPublic() || fieldNode.isProtected()) { mv.visitFieldInsn(PUTFIELD, owner, fieldName, desc); } else { mv.visitMethodInsn(INVOKESPECIAL, owner, setter.getName(), BytecodeHelper.getMethodDescriptor(setter), false); } }