private static boolean checkIsConditionBlock(MethodCallExpression methodCallExpr) { ClassNode targetType = methodCallExpr.getObjectExpression().getType(); String methodName = methodCallExpr.getMethodAsString(); List<MethodNode> methods = targetType.getMethods(methodName); for (MethodNode method : methods) { for (AnnotationNode annotation : method.getAnnotations()) { if (annotation.getClassNode().getName().equals(ConditionBlock.class.getName())) return true; } } return false; } }
public ClassNode getPlainNodeReference() { if (ClassHelper.isPrimitiveType(this)) return this; ClassNode n = new ClassNode(name, modifiers, superClass,null,null); n.isPrimaryNode = false; n.setRedirect(redirect()); if (isArray()) { n.componentType = redirect().getComponentType(); } return n; }
private static boolean hasUsableImplementation(ClassNode c, MethodNode m) { if (c == m.getDeclaringClass()) return false; MethodNode found = c.getDeclaredMethod(m.getName(), m.getParameters()); if (found == null) return false; int asp = found.getModifiers() & ABSTRACT_STATIC_PRIVATE; int visible = found.getModifiers() & VISIBILITY; if (visible != 0 && asp == 0) return true; if (c.equals(OBJECT_TYPE)) return false; return hasUsableImplementation(c.getSuperClass(), m); }
public List<AnnotationNode> getAnnotations(ClassNode type) { if (redirect!=null) return redirect.getAnnotations(type); lazyClassInit(); return super.getAnnotations(type); }
/** * @return the list of FieldNode's associated with this ClassNode */ public List<FieldNode> getFields() { if (redirect!=null) return redirect().getFields(); lazyClassInit(); if (fields == null) fields = new LinkedList<FieldNode> (); return fields; }
protected ClassNode createStatementsClass() { ClassNode classNode = getScriptClassDummy(); if (classNode.getName().endsWith("package-info")) { return classNode; classNode.addMethod( new MethodNode( "main", ACC_PUBLIC | ACC_STATIC, ClassHelper.VOID_TYPE, new Parameter[] { new Parameter(ClassHelper.STRING_TYPE.makeArray(), "args")}, ClassNode.EMPTY_ARRAY, new ExpressionStatement( new MethodCallExpression( new ClassExpression(ClassHelper.make(InvokerHelper.class)), "runScript", MethodNode methodNode = new MethodNode("run", ACC_PUBLIC, ClassHelper.OBJECT_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, statementBlock); methodNode.setIsScriptBody(); classNode.addMethod(methodNode); classNode.addConstructor(ACC_PUBLIC, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, new BlockStatement()); if (classNode.getSuperClass().getDeclaredConstructor(SCRIPT_CONTEXT_CTOR) != null) { stmt = new ExpressionStatement( new ConstructorCallExpression(ClassNode.SUPER, new ArgumentListExpression( classNode.addConstructor( ACC_PUBLIC,
private void createSharedFieldSetter(Field field) { String setterName = "set" + MetaClassHelper.capitalize(field.getName()); Parameter[] params = new Parameter[] { new Parameter(field.getAst().getType(), "$spock_value") }; MethodNode setter = spec.getAst().getMethod(setterName, params); if (setter != null) { errorReporter.error(field.getAst(), "@Shared field '%s' conflicts with method '%s'; please rename either of them", field.getName(), setter.getName()); return; } BlockStatement setterBlock = new BlockStatement(); setter = new MethodNode(setterName, determineVisibilityForSharedFieldAccessor(field) | Opcodes.ACC_SYNTHETIC, ClassHelper.VOID_TYPE, params, ClassNode.EMPTY_ARRAY, setterBlock); setterBlock.addStatement( new ExpressionStatement( new BinaryExpression( new AttributeExpression( getSharedInstance(), // use internal name new ConstantExpression(field.getAst().getName())), Token.newSymbol(Types.ASSIGN, -1, -1), new VariableExpression("$spock_value")))); setter.setSourcePosition(field.getAst()); spec.getAst().addMethod(setter); }
protected void assertIterate(String methodName, Expression listExpression) throws Exception { ClassNode classNode = new ClassNode("Foo", ACC_PUBLIC, ClassHelper.OBJECT_TYPE); classNode.addConstructor(new ConstructorNode(ACC_PUBLIC, null)); classNode.addProperty(new PropertyNode("bar", ACC_PUBLIC, ClassHelper.STRING_TYPE, classNode, null, null, null)); Statement loopStatement = createPrintlnStatement(new VariableExpression("i")); BlockStatement block = new BlockStatement(); block.addStatement(new ExpressionStatement(new DeclarationExpression(new VariableExpression("list"), Token.newSymbol("=", 0, 0), listExpression))); block.addStatement(new ForStatement(new Parameter(ClassHelper.DYNAMIC_TYPE, "i"), new VariableExpression("list"), loopStatement)); classNode.addMethod(new MethodNode(methodName, ACC_PUBLIC, ClassHelper.VOID_TYPE, Parameter.EMPTY_ARRAY, ClassNode.EMPTY_ARRAY, block)); Class fooClass = loadClass(classNode); assertTrue("Loaded a new class", fooClass != null); Object bean = fooClass.newInstance(); assertTrue("Managed to create bean", bean != null); System.out.println("################ Now about to invoke method"); try { InvokerHelper.invokeMethod(bean, methodName, null); } catch (InvokerInvocationException e) { System.out.println("Caught: " + e.getCause()); e.getCause().printStackTrace(); fail("Should not have thrown an exception"); } System.out.println("################ Done"); }
@SuppressWarnings("unchecked") private boolean makeGetPrivateFieldWithBridgeMethod(final Expression receiver, final ClassNode receiverType, final String fieldName, final boolean safe, final boolean implicitThis) { FieldNode field = receiverType.getField(fieldName); ClassNode outerClass = receiverType.getOuterClass(); if (field==null && implicitThis && outerClass !=null && !receiverType.isStaticClass()) { Expression pexp; if (controller.isInClosure()) { MethodCallExpression mce = new MethodCallExpression( new VariableExpression("this"), "getThisObject", ArgumentListExpression.EMPTY_ARGUMENTS ); mce.putNodeMetaData(StaticTypesMarker.INFERRED_TYPE, controller.getOutermostClass()); mce.setImplicitThis(true); } else { pexp = new PropertyExpression( new ClassExpression(outerClass), "this" ); if (field!=null && Modifier.isPrivate(field.getModifiers()) && (StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(receiverType, classNode) || StaticInvocationWriter.isPrivateBridgeMethodsCallAllowed(classNode,receiverType)) && !receiverType.equals(classNode)) { Map<String, MethodNode> accessors = receiverType.redirect().getNodeMetaData(StaticCompilationMetadataKeys.PRIVATE_FIELDS_ACCESSORS); if (accessors!=null) { MethodNode methodNode = accessors.get(fieldName); if (methodNode!=null) { MethodCallExpression mce = new MethodCallExpression(receiver, methodNode.getName(),
private static Statement createDelegatingForwarder(final MethodNode forwarderMethod, final ClassNode next) { // generates --> next$Trait$Helper.method(this, arg1, arg2) TraitHelpersTuple helpers = Traits.findHelpers(next); ArgumentListExpression args = new ArgumentListExpression(); args.addExpression(new VariableExpression("this")); Parameter[] forwarderMethodParameters = forwarderMethod.getParameters(); for (final Parameter forwarderMethodParameter : forwarderMethodParameters) { args.addExpression(new VariableExpression(forwarderMethodParameter)); } StaticMethodCallExpression delegateCall = new StaticMethodCallExpression( helpers.getHelper(), forwarderMethod.getName(), args ); Statement result; if (ClassHelper.VOID_TYPE.equals(forwarderMethod.getReturnType())) { BlockStatement stmt = new BlockStatement(); stmt.addStatement(new ExpressionStatement(delegateCall)); stmt.addStatement(new ReturnStatement(new ConstantExpression(null))); result = stmt; } else { result = new ReturnStatement(delegateCall); } return result; }
ClassNode helper = helpers.getHelper(); String setterName = MetaProperty.getSetterName(leftPropertyExpression.getPropertyAsString()); List<MethodNode> methods = helper.getMethods(setterName); for (MethodNode method : methods) { Parameter[] parameters = method.getParameters(); if (parameters.length==2 && parameters[0].getType().equals(traitReceiver)) { ArgumentListExpression args = new ArgumentListExpression( new VariableExpression("this"), transform(exp.getRightExpression()) ); MethodCallExpression setterCall = new MethodCallExpression( new ClassExpression(helper), setterName, args ); setterCall.setMethodTarget(method); setterCall.setImplicitThis(false); return setterCall;
public void testLoop() throws Exception { ClassNode classNode = new ClassNode("Foo", ACC_PUBLIC, ClassHelper.OBJECT_TYPE); classNode.addConstructor(new ConstructorNode(ACC_PUBLIC, null)); Parameter[] parameters = {new Parameter(ClassHelper.OBJECT_TYPE.makeArray(), "coll")}; Statement loopStatement = createPrintlnStatement(new VariableExpression("i")); ForStatement statement = new ForStatement(new Parameter(ClassHelper.OBJECT_TYPE, "i"), new VariableExpression("coll"), loopStatement); classNode.addMethod(new MethodNode("iterateDemo", ACC_PUBLIC, ClassHelper.VOID_TYPE, parameters, ClassNode.EMPTY_ARRAY, statement)); Class fooClass = loadClass(classNode); assertTrue("Loaded a new class", fooClass != null); Object bean = fooClass.newInstance(); assertTrue("Managed to create bean", bean != null); System.out.println("################ Now about to invoke a method with looping"); Object[] array = {new Integer(1234), "abc", "def"}; try { InvokerHelper.invokeMethod(bean, "iterateDemo", new Object[]{array}); } catch (InvokerInvocationException e) { System.out.println("Caught: " + e.getCause()); e.getCause().printStackTrace(); fail("Should not have thrown an exception"); } System.out.println("################ Done"); }
private void visitOverride(AnnotatedNode node, AnnotationNode visited) { ClassNode annotationClassNode = visited.getClassNode(); if (annotationClassNode.isResolved() && annotationClassNode.getName().equals("java.lang.Override")) { if (node instanceof MethodNode && !Boolean.TRUE.equals(node.getNodeMetaData(Verifier.DEFAULT_PARAMETER_GENERATED))) { boolean override = false; MethodNode origMethod = (MethodNode) node; ClassNode cNode = origMethod.getDeclaringClass(); if (origMethod.hasDefaultValue()) { List<MethodNode> variants = cNode.getDeclaredMethods(origMethod.getName()); for (MethodNode m : variants) { if (m.getAnnotations().contains(visited) && isOverrideMethod(m)) { override = true; break; } } } else { override = isOverrideMethod(origMethod); } if (!override) { addError("Method '" + origMethod.getName() + "' from class '" + cNode.getName() + "' does not override " + "method from its superclass or interfaces but is annotated with @Override.", visited); } } } }
/** * Identifies a method call expression on {@link DefaultGroovyMethods#is(Object, Object)} and if recognized, transforms it into a {@link CompareIdentityExpression}. * @param call a method call to be transformed * @return null if the method call is not DGM#is, or {@link CompareIdentityExpression} */ private static Expression tryTransformIsToCompareIdentity(MethodCallExpression call) { if (call.isSafe()) return null; MethodNode methodTarget = call.getMethodTarget(); if (methodTarget instanceof ExtensionMethodNode && "is".equals(methodTarget.getName()) && methodTarget.getParameters().length==1) { methodTarget = ((ExtensionMethodNode) methodTarget).getExtensionMethodNode(); ClassNode owner = methodTarget.getDeclaringClass(); if (DGM_CLASSNODE.equals(owner)) { Expression args = call.getArguments(); if (args instanceof ArgumentListExpression) { ArgumentListExpression arguments = (ArgumentListExpression) args; List<Expression> exprs = arguments.getExpressions(); if (exprs.size() == 1) { CompareIdentityExpression cid = new CompareIdentityExpression(call.getObjectExpression(), exprs.get(0)); cid.setSourcePosition(call); return cid; } } } } return null; } }
private void checkMethodsForOverridingFinal(ClassNode cn) { for (MethodNode method : cn.getMethods()) { Parameter[] params = method.getParameters(); for (MethodNode superMethod : cn.getSuperClass().getMethods(method.getName())) { Parameter[] superParams = superMethod.getParameters(); if (!hasEqualParameterTypes(params, superParams)) continue; if (!superMethod.isFinal()) break; addInvalidUseOfFinalError(method, params, superMethod.getDeclaringClass()); return; } } }
private TryCatchStatement surroundSpecialTryCatch(Expression executeAndVerify) { final TryCatchStatement tryCatchStatement = new TryCatchStatement( new ExpressionStatement(executeAndVerify), EmptyStatement.INSTANCE ); tryCatchStatement.addCatch( new CatchStatement( new Parameter(new ClassNode(Throwable.class), "throwable"), new ExpressionStatement( AstUtil.createDirectMethodCall( new ClassExpression(resources.getAstNodeCache().SpockRuntime), resources.getAstNodeCache().SpockRuntime_GroupConditionFailedWithException, new ArgumentListExpression(Arrays.<Expression>asList( new VariableExpression(SpockNames.ERROR_COLLECTOR), new VariableExpression("throwable") // throwable )) ) ) ) ); return tryCatchStatement; }
private void checkRepetitiveMethod(MethodNode node) { if (isConstructor(node)) return; for (MethodNode method : currentClass.getMethods(node.getName())) { if (method == node) continue; if (!method.getDeclaringClass().equals(node.getDeclaringClass())) continue; Parameter[] p1 = node.getParameters(); Parameter[] p2 = method.getParameters(); if (p1.length != p2.length) continue; addErrorIfParamsAndReturnTypeEqual(p2, p1, node, method); } }
public void visit(ASTNode[] nodes, SourceUnit source) { init(nodes, source); AnnotatedNode parent = (AnnotatedNode) nodes[1]; AnnotationNode node = (AnnotationNode) nodes[0]; boolean legacyMode = LEGACY_TYPE_NAME.equals(node.getClassNode().getName()); if (!MY_TYPE.equals(node.getClassNode()) && !legacyMode) return; Expression value = node.getMember("value"); if (parent instanceof ClassNode) { List<groovy.transform.PackageScopeTarget> targets; if (value == null) targets = Collections.singletonList(legacyMode ? PackageScopeTarget.FIELDS : PackageScopeTarget.CLASS); else targets = determineTargets(value); visitClassNode((ClassNode) parent, targets); parent.getAnnotations(); } else { if (value != null) { addError("Error during " + MY_TYPE_NAME + " processing: " + TARGET_CLASS_NAME + " only allowed at class level.", parent); return; } if (parent instanceof MethodNode) { visitMethodNode((MethodNode) parent); } else if (parent instanceof FieldNode) { visitFieldNode((FieldNode) parent); } } }
public void buildMethod(BuilderASTTransformation transform, MethodNode mNode, AnnotationNode anno) { if (transform.getMemberValue(anno, "includes") != null || transform.getMemberValue(anno, "excludes") != null) { transform.addError("Error during " + BuilderASTTransformation.MY_TYPE_NAME + " processing: includes/excludes only allowed on classes", anno); } ClassNode buildee = mNode.getDeclaringClass(); ClassNode builder = createBuilder(anno, buildee); createBuilderFactoryMethod(anno, buildee, builder); for (Parameter parameter : mNode.getParameters()) { builder.addField(createFieldCopy(buildee, parameter)); builder.addMethod(createBuilderMethodForProp(builder, new PropertyInfo(parameter.getName(), parameter.getType()), getPrefix(anno))); } builder.addMethod(createBuildMethodForMethod(anno, buildee, mNode, mNode.getParameters())); }
public void visitAnnotations(AnnotatedNode node) { List<AnnotationNode> annotations = node.getAnnotations(); if (annotations.isEmpty()) return; Map<String, AnnotationNode> tmpAnnotations = new HashMap<String, AnnotationNode>(); ClassNode annType; for (AnnotationNode an : annotations) { // skip built-in properties if (an.isBuiltIn()) continue; annType = an.getClassNode(); resolveOrFail(annType, ", unable to find class for annotation", an); for (Map.Entry<String, Expression> member : an.getMembers().entrySet()) { Expression newValue = transform(member.getValue()); Expression adjusted = transformInlineConstants(newValue); member.setValue(adjusted); checkAnnotationMemberValue(adjusted); } if (annType.isResolved()) { Class annTypeClass = annType.getTypeClass(); Retention retAnn = (Retention) annTypeClass.getAnnotation(Retention.class); if (retAnn != null && retAnn.value().equals(RetentionPolicy.RUNTIME) && !isRepeatable(annTypeClass)) { // remember runtime/non-repeatable annos (auto collecting of Repeatable annotations is handled elsewhere) AnnotationNode anyPrevAnnNode = tmpAnnotations.put(annTypeClass.getName(), an); if (anyPrevAnnNode != null) { addError("Cannot specify duplicate annotation on the same member : " + annType.getName(), an); } } } } }