private static ConstructorNode getMatchingConstructor(List<ConstructorNode> constructors, List<Expression> argumentList) { ConstructorNode lastMatch = null; for (int i=0; i<constructors.size(); i++) { ConstructorNode cn = constructors.get(i); Parameter[] params = cn.getParameters(); // if number of parameters does not match we have no match if (argumentList.size()!=params.length) continue; if (lastMatch==null) { lastMatch = cn; } else { // we already had a match so we don't make a direct call at all return null; } } return lastMatch; }
public int compare(Object arg0, Object arg1) { ConstructorNode c0 = (ConstructorNode) arg0; ConstructorNode c1 = (ConstructorNode) arg1; String descriptor0 = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, c0.getParameters()); String descriptor1 = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, c1.getParameters()); return descriptor0.compareTo(descriptor1); } };
public static boolean hasNoArgConstructor(ClassNode cNode) { List<ConstructorNode> constructors = cNode.getDeclaredConstructors(); for (ConstructorNode next : constructors) { if (next.getParameters().length == 0) { return true; } } return false; }
private static boolean isExisting(ClassNode classNode, Parameter[] params) { for (ConstructorNode consNode : classNode.getDeclaredConstructors()) { if (matchingTypes(params, consNode.getParameters())) { return true; } } return false; }
/** * Finds a constructor matching the given parameters in this class. * * @return the constructor matching the given parameters or null */ public ConstructorNode getDeclaredConstructor(Parameter[] parameters) { for (ConstructorNode method : getDeclaredConstructors()) { if (parametersEqual(method.getParameters(), parameters)) { return method; } } return null; }
public void visitConstructor(ConstructorNode node) { inConstructor = true; inStaticConstructor = node.isStaticConstructor(); checkGenericsUsage(node, node.getParameters()); super.visitConstructor(node); }
private static MethodNode selectConstructor(ClassNode node, Parameter[] paraTypes) { List<ConstructorNode> cl = node.getDeclaredConstructors(); MethodNode res = null; for (ConstructorNode cn : cl) { if (ParameterUtils.parametersEqual(cn.getParameters(), paraTypes)) { res = cn; break; } } if (res !=null && res.isPublic()) return res; return null; }
private boolean constructorMayHaveBeenAddedByCompiler(ConstructorNode constructor) { Parameter[] params = constructor.getParameters(); Statement firstStat = constructor.getFirstStatement(); return AstUtil.isJointCompiled(spec.getAst()) && constructor.isPublic() && params != null && params.length == 0 && firstStat == null; }
private static ClassNode getConstructorArgumentType(Expression arg, ConstructorNode node) { if (!(arg instanceof VariableExpression)) return arg.getType(); VariableExpression vexp = (VariableExpression) arg; String name = vexp.getName(); for (Parameter param : node.getParameters()) { if (param.getName().equals(name)) { return param.getType(); } } return vexp.getType(); }
private static void doAddConstructor(final ClassNode cNode, final ConstructorNode constructorNode) { markAsGenerated(cNode, constructorNode); cNode.addConstructor(constructorNode); // GROOVY-5814: Immutable is not compatible with @CompileStatic Parameter argsParam = null; for (Parameter p : constructorNode.getParameters()) { if ("args".equals(p.getName())) { argsParam = p; break; } } if (argsParam != null) { final Parameter arg = argsParam; ClassCodeVisitorSupport variableExpressionFix = new ClassCodeVisitorSupport() { @Override protected SourceUnit getSourceUnit() { return cNode.getModule().getContext(); } @Override public void visitVariableExpression(final VariableExpression expression) { super.visitVariableExpression(expression); if ("args".equals(expression.getName())) { expression.setAccessedVariable(arg); } } }; variableExpressionFix.visitConstructor(constructorNode); } }
public void visitConstructor(ConstructorNode node) { visitParameters(node, node.getParameters()); String methodType = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, node.getParameters()); mv = cv.visitMethod(node.getModifiers(), "<init>", methodType, null, null); mv.visitTypeInsn(NEW, "java/lang/RuntimeException"); mv.visitInsn(DUP); mv.visitLdcInsn("not intended for execution"); mv.visitMethodInsn(INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false); mv.visitInsn(ATHROW); mv.visitMaxs(0, 0); }
private void adjustConstructorAndFields(int skipIndex, ClassNode type) { List<ConstructorNode> constructors = type.getDeclaredConstructors(); if (constructors.size() == 1) { ConstructorNode constructor = constructors.get(0); Parameter[] params = constructor.getParameters(); Parameter[] newParams = new Parameter[params.length - 1]; int to = 0; for (int from = 0; from < params.length; from++) { if (from != skipIndex) { newParams[to++] = params[from]; } } type.removeConstructor(constructor); // code doesn't mention the removed param at this point, okay to leave as is addGeneratedConstructor(type, constructor.getModifiers(), newParams, constructor.getExceptions(), constructor.getCode()); type.removeField(variableName); } }
@Override public void visitConstructor(final ConstructorNode node) { if (shouldSkipMethodNode(node)) { // method has already been visited by a static type checking visitor return; } for (Parameter parameter : node.getParameters()) { if (parameter.getInitialExpression() != null) { parameter.getInitialExpression().visit(this); } } super.visitConstructor(node); }
/** * Add map and no-arg constructor or mirror those of the superclass (i.e. base enum). */ private static void addImplicitConstructors(ClassNode enumClass, boolean aic) { if (aic) { ClassNode sn = enumClass.getSuperClass(); List<ConstructorNode> sctors = new ArrayList<ConstructorNode>(sn.getDeclaredConstructors()); if (sctors.isEmpty()) { addMapConstructors(enumClass); } else { for (ConstructorNode constructorNode : sctors) { ConstructorNode init = new ConstructorNode(ACC_PUBLIC, constructorNode.getParameters(), ClassNode.EMPTY_ARRAY, new BlockStatement()); enumClass.addConstructor(init); } } } else { addMapConstructors(enumClass); } }
private boolean writeDirectConstructorCall(ConstructorCallExpression call) { if (!controller.isFastPath()) return false; StatementMeta meta = call.getNodeMetaData(StatementMeta.class); ConstructorNode cn = null; if (meta!=null) cn = (ConstructorNode) meta.target; if (cn==null) return false; String ownerDescriptor = prepareConstructorCall(cn); TupleExpression args = makeArgumentList(call.getArguments()); loadArguments(args.getExpressions(), cn.getParameters()); finnishConstructorCall(cn, ownerDescriptor, args.getExpressions().size()); return true; }
protected void finnishConstructorCall(ConstructorNode cn, String ownerDescriptor, int argsToRemove) { String desc = BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, cn.getParameters()); MethodVisitor mv = controller.getMethodVisitor(); mv.visitMethodInsn(INVOKESPECIAL, ownerDescriptor, "<init>", desc, false); controller.getOperandStack().remove(argsToRemove); controller.getOperandStack().push(cn.getDeclaringClass()); }
private void addConstructorUnlessAlreadyExisting(ClassNode classNode, ConstructorNode consNode, boolean copyConstructorAnnotations, boolean copyParameterAnnotations) { Parameter[] origParams = consNode.getParameters(); if (consNode.isPrivate()) return; Parameter[] params = new Parameter[origParams.length]; Map<String, ClassNode> genericsSpec = createGenericsSpec(classNode); extractSuperClassGenerics(classNode, classNode.getSuperClass(), genericsSpec); List<Expression> theArgs = buildParams(origParams, params, genericsSpec, copyParameterAnnotations); if (isExisting(classNode, params)) return; ConstructorNode added = addGeneratedConstructor(classNode, consNode.getModifiers(), params, consNode.getExceptions(), block(ctorSuperS(args(theArgs)))); if (copyConstructorAnnotations) { added.addAnnotations(copyAnnotatedNodeAnnotations(consNode, MY_TYPE_NAME)); } }
private static Parameter[] selectAccessibleConstructorFromSuper(ConstructorNode node) { ClassNode type = node.getDeclaringClass(); ClassNode superType = type.getUnresolvedSuperClass(); Parameter[] bestMatch = null; for (ConstructorNode c : superType.getDeclaredConstructors()) { // Only look at things we can actually call if (!c.isPublic() && !c.isProtected()) continue; Parameter[] parameters = c.getParameters(); // workaround for GROOVY-5859: remove generic type info Parameter[] copy = new Parameter[parameters.length]; for (int i = 0; i < copy.length; i++) { Parameter orig = parameters[i]; copy[i] = new Parameter(orig.getOriginType().getPlainNodeReference(), orig.getName()); } if (noExceptionToAvoid(node,c)) return copy; if (bestMatch==null) bestMatch = copy; } if (bestMatch!=null) return bestMatch; // fall back for parameterless constructor if (superType.isPrimaryClassNode()) { return Parameter.EMPTY_ARRAY; } return null; }
private void createConstructor(ClassNode classNode, FieldNode field, String propertyName, boolean isStrict) { final List<ConstructorNode> cNodes = classNode.getDeclaredConstructors(); ConstructorNode foundNoArg = null; for (ConstructorNode cNode : cNodes) { final Parameter[] parameters = cNode.getParameters(); if (parameters == null || parameters.length == 0) { foundNoArg = cNode; break; } } if (isStrict && !cNodes.isEmpty()) { for (ConstructorNode cNode : cNodes) { addError("@Singleton didn't expect to find one or more additional constructors: remove constructor(s) or set strict=false", cNode); } } if (foundNoArg == null) { final BlockStatement body = new BlockStatement(); body.addStatement(ifS( notNullX(varX(field)), throwS( ctorX(make(RuntimeException.class), args(constX("Can't instantiate singleton " + classNode.getName() + ". Use " + classNode.getName() + "." + propertyName)))) )); addGeneratedConstructor(classNode, new ConstructorNode(ACC_PRIVATE, body)); } } }
@Override public void writeSpecialConstructorCall(final ConstructorCallExpression call) { MethodNode mn = call.getNodeMetaData(StaticTypesMarker.DIRECT_METHOD_CALL_TARGET); if (mn==null) { super.writeSpecialConstructorCall(call); return; } controller.getCompileStack().pushInSpecialConstructorCall(); ConstructorNode cn; if (mn instanceof ConstructorNode) { cn = (ConstructorNode) mn; } else { cn = new ConstructorNode(mn.getModifiers(), mn.getParameters(), mn.getExceptions(), mn.getCode()); cn.setDeclaringClass(mn.getDeclaringClass()); } // load "this" controller.getMethodVisitor().visitVarInsn(ALOAD, 0); String ownerDescriptor = BytecodeHelper.getClassInternalName(cn.getDeclaringClass()); TupleExpression args = makeArgumentList(call.getArguments()); int before = controller.getOperandStack().getStackLength(); loadArguments(args.getExpressions(), cn.getParameters()); finnishConstructorCall(cn, ownerDescriptor, controller.getOperandStack().getStackLength() - before); // on a special call, there's no object on stack controller.getOperandStack().remove(1); controller.getCompileStack().pop(); }