private Statement createConstructorStatementMapSpecial(FieldNode fNode) { final Expression fieldExpr = new VariableExpression(fNode); Expression initExpr = fNode.getInitialValueExpression(); if (initExpr == null) initExpr = new ConstantExpression(null); Expression namedArgs = findArg(fNode.getName()); Expression baseArgs = new VariableExpression("args"); return new IfStatement( equalsNullExpr(baseArgs), new IfStatement( equalsNullExpr(initExpr), new EmptyStatement(), assignStatement(fieldExpr, cloneCollectionExpr(initExpr))), new IfStatement( equalsNullExpr(namedArgs), new IfStatement( isTrueExpr( new MethodCallExpression( baseArgs, "containsKey", new ConstantExpression(fNode.getName()))), assignStatement(fieldExpr, namedArgs), assignStatement(fieldExpr, cloneCollectionExpr(baseArgs))), new IfStatement( isOneExpr( new MethodCallExpression(baseArgs, "size", MethodCallExpression.NO_ARGUMENTS)), assignStatement(fieldExpr, cloneCollectionExpr(namedArgs)), assignStatement(fieldExpr, cloneCollectionExpr(baseArgs))))); }
private Statement createConstructorStatement( ClassNode cNode, PropertyNode pNode, List<String> knownImmutableClasses, List<String> knownImmutables) { FieldNode fNode = pNode.getField(); final ClassNode fieldType = fNode.getType(); Statement statement = null; if (fieldType.isArray() || isOrImplements(fieldType, CLONEABLE_TYPE)) { statement = createConstructorStatementArrayOrCloneable(fNode); } else if (isKnownImmutableClass(fieldType, knownImmutableClasses) || isKnownImmutable(pNode.getName(), knownImmutables)) { statement = createConstructorStatementDefault(fNode); } else if (fieldType.isDerivedFrom(DATE_TYPE)) { statement = createConstructorStatementDate(fNode); } else if (isOrImplements(fieldType, COLLECTION_TYPE) || fieldType.isDerivedFrom(COLLECTION_TYPE) || isOrImplements(fieldType, MAP_TYPE) || fieldType.isDerivedFrom(MAP_TYPE)) { statement = createConstructorStatementCollection(fNode); } else if (fieldType.isResolved()) { addError( createErrorMessage(cNode.getName(), fNode.getName(), fieldType.getName(), "compiling"), fNode); statement = EmptyStatement.INSTANCE; } else { statement = createConstructorStatementGuarded(cNode, fNode); } return statement; }
private Expression checkUnresolved(ClassNode cNode, FieldNode fNode, Expression value) { Expression args = new TupleExpression( new MethodCallExpression( new VariableExpression("this"), "getClass", ArgumentListExpression.EMPTY_ARGUMENTS), new ConstantExpression(fNode.getName()), value); return new StaticMethodCallExpression(SELF_TYPE, "checkImmutable", args); }
private Statement checkFinalArgNotOverridden(ClassNode cNode, FieldNode fNode) { final String name = fNode.getName(); Expression value = findArg(name); return new IfStatement( equalsNullExpr(value), new EmptyStatement(), new ThrowStatement( new ConstructorCallExpression( READONLYEXCEPTION_TYPE, new ArgumentListExpression( new ConstantExpression(name), new ConstantExpression(cNode.getName()))))); }
private void createConstructorMapCommon(ClassNode cNode, BlockStatement body) { final List<FieldNode> fList = cNode.getFields(); for (FieldNode fNode : fList) { if (fNode.isPublic()) continue; // public fields will be rejected elsewhere if (cNode.getProperty(fNode.getName()) != null) continue; // a property if (fNode.isFinal() && fNode.isStatic()) continue; if (fNode.getName().contains("$")) continue; // internal field if (fNode.isFinal() && fNode.getInitialExpression() != null) body.addStatement(checkFinalArgNotOverridden(cNode, fNode)); body.addStatement(createConstructorStatementDefault(fNode)); } final Parameter[] params = new Parameter[] {new Parameter(HASHMAP_TYPE, "args")}; doAddConstructor( cNode, new ConstructorNode( ACC_PUBLIC, params, ClassNode.EMPTY_ARRAY, new IfStatement( equalsNullExpr(new VariableExpression("args")), new EmptyStatement(), body))); }
private Statement createConstructorStatementDate(FieldNode fNode) { final Expression fieldExpr = new VariableExpression(fNode); Expression initExpr = fNode.getInitialValueExpression(); if (initExpr == null) initExpr = new ConstantExpression(null); final Expression date = findArg(fNode.getName()); return new IfStatement( equalsNullExpr(date), new IfStatement( equalsNullExpr(initExpr), assignStatement(fieldExpr, new ConstantExpression(null)), assignStatement(fieldExpr, cloneDateExpr(initExpr))), assignStatement(fieldExpr, cloneDateExpr(date))); }
private Statement createConstructorStatementGuarded(ClassNode cNode, FieldNode fNode) { final Expression fieldExpr = new VariableExpression(fNode); Expression initExpr = fNode.getInitialValueExpression(); if (initExpr == null) initExpr = new ConstantExpression(null); Expression unknown = findArg(fNode.getName()); return new IfStatement( equalsNullExpr(unknown), new IfStatement( equalsNullExpr(initExpr), new EmptyStatement(), assignStatement(fieldExpr, checkUnresolved(cNode, fNode, initExpr))), assignStatement(fieldExpr, checkUnresolved(cNode, fNode, unknown))); }
private Statement createConstructorStatementArrayOrCloneable(FieldNode fNode) { final Expression fieldExpr = new VariableExpression(fNode); Expression initExpr = fNode.getInitialValueExpression(); ClassNode fieldType = fNode.getType(); if (initExpr == null) initExpr = new ConstantExpression(null); final Expression array = findArg(fNode.getName()); return new IfStatement( equalsNullExpr(array), new IfStatement( equalsNullExpr(initExpr), assignStatement(fieldExpr, new ConstantExpression(null)), assignStatement(fieldExpr, cloneArrayOrCloneableExpr(initExpr, fieldType))), assignStatement(fieldExpr, cloneArrayOrCloneableExpr(array, fieldType))); }
private void addProperty(ClassNode cNode, PropertyNode pNode) { final FieldNode fn = pNode.getField(); cNode.getFields().remove(fn); cNode.addProperty( pNode.getName(), pNode.getModifiers() | ACC_FINAL, pNode.getType(), pNode.getInitialExpression(), pNode.getGetterBlock(), pNode.getSetterBlock()); final FieldNode newfn = cNode.getField(fn.getName()); cNode.getFields().remove(newfn); cNode.addField(fn); }
private void ensureNotPublic(String cNode, FieldNode fNode) { String fName = fNode.getName(); // TODO: do we need to lock down things like: $ownClass if (fNode.isPublic() && !fName.contains("$") && !(fNode.isStatic() && fNode.isFinal())) { addError( "Public field '" + fName + "' not allowed for " + MY_TYPE_NAME + " class '" + cNode + "'.", fNode); } }
private Statement createConstructorStatementCollection(FieldNode fNode) { final Expression fieldExpr = new VariableExpression(fNode); Expression initExpr = fNode.getInitialValueExpression(); if (initExpr == null) initExpr = new ConstantExpression(null); Expression collection = findArg(fNode.getName()); ClassNode fieldType = fieldExpr.getType(); return new IfStatement( equalsNullExpr(collection), new IfStatement( equalsNullExpr(initExpr), new EmptyStatement(), assignStatement(fieldExpr, cloneCollectionExpr(initExpr))), new IfStatement( isInstanceOf(collection, CLONEABLE_TYPE), assignStatement( fieldExpr, cloneCollectionExpr(cloneArrayOrCloneableExpr(collection, fieldType))), assignStatement(fieldExpr, cloneCollectionExpr(collection)))); }