protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) { if (code instanceof ExpressionStatement) {//GROOVY-4508 Statement temp = code; code = new BlockStatement(); ((BlockStatement) code).addStatement(temp); } ConstructorNode ctrNode = new ConstructorNode(ctor.getModifiers(), newParams, ctor.getExceptions(), code); ctrNode.setDeclaringClass(node); constructors.add(ctrNode); }
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; }
boolean chainedThisConstructorCall = false; ConstructorCallExpression cce = null; if (ctor.firstStatementIsSpecialConstructorCall()) { Statement code = ctor.getFirstStatement(); cce = (ConstructorCallExpression) ((ExpressionStatement) code).getExpression(); if (cce.isSuperCall()) return; Parameter[] oldP = ctor.getParameters(); Parameter[] newP = new Parameter[oldP.length + 2]; String stringParameterName = getUniqueVariableName("__str", ctor.getCode()); newP[0] = new Parameter(ClassHelper.STRING_TYPE, stringParameterName); String intParameterName = getUniqueVariableName("__int", ctor.getCode()); newP[1] = new Parameter(ClassHelper.int_TYPE, intParameterName); System.arraycopy(oldP, 0, newP, 2, oldP.length); ctor.setParameters(newP); VariableExpression stringVariable = new VariableExpression(newP[0]); VariableExpression intVariable = new VariableExpression(newP[1]); BlockStatement code = new BlockStatement(); code.addStatement(new ExpressionStatement(cce)); Statement oldCode = ctor.getCode(); if (oldCode != null) code.addStatement(oldCode); ctor.setCode(code);
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; }
public void visitConstructor(ConstructorNode node) { inConstructor = true; inStaticConstructor = node.isStaticConstructor(); checkGenericsUsage(node, node.getParameters()); super.visitConstructor(node); }
if (ctors.size()==0) { ConstructorNode init = new ConstructorNode(Opcodes.ACC_PRIVATE,new Parameter[0],ClassNode.EMPTY_ARRAY,new BlockStatement()); enumClass.addConstructor(init); ctors.add(init); if (ctor.firstStatementIsSpecialConstructorCall()) continue; Parameter[] oldP = ctor.getParameters(); Parameter[] newP = new Parameter[oldP.length+2]; String stringParameterName = getUniqueVariableName("__str",ctor.getCode()); newP[0] = new Parameter(ClassHelper.STRING_TYPE,stringParameterName); String intParameterName = getUniqueVariableName("__int",ctor.getCode()); newP[1] = new Parameter(ClassHelper.int_TYPE,intParameterName); System.arraycopy(oldP, 0, newP, 2, oldP.length); ctor.setParameters(newP); BlockStatement code = new BlockStatement(); code.addStatement(new ExpressionStatement(cce)); Statement oldCode = ctor.getCode(); if (oldCode!=null) code.addStatement(oldCode); ctor.setCode(code);
@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(); }
public ConstructorNode addConstructor(int modifiers, Parameter[] parameters, ClassNode[] exceptions, Statement code) { ConstructorNode node = new ConstructorNode(modifiers, parameters, exceptions, code); addConstructor(node); return node; }
ConstructorNode syntheticConstructor = new ConstructorNode(Modifier.PUBLIC, new BlockStatement()); declaredConstructors = Collections.singletonList(syntheticConstructor); classNode.addConstructor(syntheticConstructor); Statement code = c.getCode(); List<Statement> body; if (code instanceof BlockStatement) { Parameter[] origParams = c.getParameters(); for (Parameter p : origParams) { thisArgs.add(new VariableExpression(p)); c.setCode(new BlockStatement(new Statement[] {new ExpressionStatement(new ConstructorCallExpression(ClassNode.THIS, new TupleExpression(thisArgs)))}, c.getVariableScope())); Parameter[] params = new Parameter[origParams.length + 1]; params[0] = new Parameter(new ClassNode(Checker.SuperConstructorWrapper.class), "$scw"); body2.add(s); ConstructorNode c2 = new ConstructorNode(Modifier.PRIVATE, params, c.getExceptions(), new BlockStatement(body2, c.getVariableScope()));
protected void addInitialization(ClassNode node, ConstructorNode constructorNode) { Statement firstStatement = constructorNode.getFirstStatement(); Statement code = constructorNode.getCode(); BlockStatement block = new BlockStatement(); List<Statement> otherStatements = block.getStatements(); constructorNode.setCode(newBlock);
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 void addThisReference(ConstructorNode node) { if (!shouldHandleImplicitThisForInnerClass(classNode)) return; Statement code = node.getCode(); Parameter[] params = node.getParameters(); Parameter[] newParams = new Parameter[params.length + 1]; System.arraycopy(params, 0, newParams, 1, params.length); node.setParameters(newParams); node.setCode(block);
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); } }
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 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; }
/** * 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); } }
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()); }
Expression transformConstructorCall(final ConstructorCallExpression expr) { ConstructorNode node = (ConstructorNode) expr.getNodeMetaData(DIRECT_METHOD_CALL_TARGET); if (node == null) return expr; Parameter[] params = node.getParameters(); if ((params.length == 1 || params.length == 2) // 2 is for inner class case && StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(params[params.length - 1].getType(), ClassHelper.MAP_TYPE) && node.getCode() == StaticTypeCheckingVisitor.GENERATED_EMPTY_STATEMENT) { Expression arguments = expr.getArguments(); if (arguments instanceof TupleExpression) { MapExpression map = (MapExpression) expression; ClassNode declaringClass = node.getDeclaringClass(); for (ConstructorNode constructorNode : declaringClass.getDeclaredConstructors()) { if (constructorNode == node) {
private static ConstructorCallExpression getConstructorCallExpression(ConstructorNode constructorNode) { Statement code = constructorNode.getCode(); if (!(code instanceof BlockStatement)) return null; BlockStatement block = (BlockStatement) code; List stats = block.getStatements(); if (stats == null || stats.isEmpty()) return null; Statement stat = (Statement) stats.get(0); if (!(stat instanceof ExpressionStatement)) return null; Expression expr = ((ExpressionStatement) stat).getExpression(); if (!(expr instanceof ConstructorCallExpression)) return null; return (ConstructorCallExpression) expr; }
protected void addConstructor(Parameter[] newParams, ConstructorNode ctor, Statement code, ClassNode node) { ConstructorNode genConstructor = node.addConstructor(ctor.getModifiers(), newParams, ctor.getExceptions(), code); markAsGenerated(node, genConstructor); }