Java Code Examples for org.codehaus.groovy.ast.ClassNode#isGenericsPlaceHolder()
The following examples show how to use
org.codehaus.groovy.ast.ClassNode#isGenericsPlaceHolder() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: InstanceOfVerifier.java From groovy with Apache License 2.0 | 6 votes |
@Override public void visitBinaryExpression(BinaryExpression expression) { if (expression.getOperation().isA(Types.INSTANCEOF_OPERATOR) && expression.getRightExpression() instanceof ClassExpression) { ClassNode referenceType = expression.getRightExpression().getType(); if (ClassHelper.isPrimitiveType(referenceType)) { addTypeError(expression.getRightExpression(), "primitive type " + referenceType.getName()); } else { while (referenceType.isArray()) { referenceType = referenceType.getComponentType(); } if (referenceType.isGenericsPlaceHolder()) { addTypeError(expression.getRightExpression(), "type parameter " + referenceType.getUnresolvedName() + ". Use its erasure " + referenceType.getNameWithoutPackage() + " instead since further generic type information will be erased at runtime"); } else if (referenceType.getGenericsTypes() != null) { // TODO: Cannot perform instanceof check against parameterized type Class<Type>. Use the form Class<?> instead since further eneric type information will be erased at runtime } } } super.visitBinaryExpression(expression); }
Example 2
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 6 votes |
/** * Returns true if the provided class node, when considered as a receiver of a message or as a parameter, * is using a placeholder in its generics type. In this case, we're facing unchecked generics and type * checking is limited (ex: void foo(Set s) { s.keySet() } * * @param node the node to test * @return true if it is using any placeholder in generics types */ public static boolean isUsingUncheckedGenerics(final ClassNode node) { if (node.isArray()) return isUsingUncheckedGenerics(node.getComponentType()); GenericsType[] genericsTypes = node.getGenericsTypes(); if (genericsTypes != null) { for (GenericsType genericsType : genericsTypes) { if (genericsType.isPlaceholder()) return true; if (genericsType.isWildcard()) { ClassNode lowerBound = genericsType.getLowerBound(); ClassNode[] upperBounds = genericsType.getUpperBounds(); if (lowerBound != null) { if (lowerBound.isGenericsPlaceHolder() || isUsingUncheckedGenerics(lowerBound)) return true; } else if (upperBounds != null) { if (upperBounds[0].isGenericsPlaceHolder() || isUsingUncheckedGenerics(upperBounds[0])) return true; } } else { if (isUsingUncheckedGenerics(genericsType.getType())) return true; } } } return false; }
Example 3
Source File: BytecodeHelper.java From groovy with Apache License 2.0 | 6 votes |
public static String getGenericsMethodSignature(MethodNode node) { GenericsType[] generics = node.getGenericsTypes(); Parameter[] param = node.getParameters(); ClassNode returnType = node.getReturnType(); if (generics == null && !hasGenerics(param) && !hasGenerics(returnType)) return null; StringBuilder ret = new StringBuilder(100); getGenericsTypeSpec(ret, generics); GenericsType[] paramTypes = new GenericsType[param.length]; for (int i = 0; i < param.length; i++) { ClassNode pType = param[i].getType(); if (pType.getGenericsTypes() == null || !pType.isGenericsPlaceHolder()) { paramTypes[i] = new GenericsType(pType); } else { paramTypes[i] = pType.getGenericsTypes()[0]; } } addSubTypes(ret, paramTypes, "(", ")"); addSubTypes(ret, new GenericsType[]{new GenericsType(returnType)}, "", ""); return ret.toString(); }
Example 4
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 6 votes |
/** * Uses supplied type to make a connection from usage to declaration. * <p> * The method operates in two modes: * <ul> * <li>For type !instanceof target a structural compare will be done * (for example Type<T> and List<E> to get E -> T) * <li>If type equals target, a structural match is done as well * (for example Collection<T> and Collection<E> to get E -> T) * <li>Otherwise we climb the hierarchy to find a case of type equals target * to then execute the structural match, while applying possibly existing * generics contexts on the way (for example for IntRange and Collection<E> * to get E -> Integer, since IntRange is an AbstractList<Integer>) * </ul> * Should the target not have any generics this method does nothing. */ static void extractGenericsConnections(final Map<GenericsTypeName, GenericsType> connections, final ClassNode type, final ClassNode target) { if (target == null || type == target || !isUsingGenericsOrIsArrayUsingGenerics(target)) return; if (type == null || type == UNKNOWN_PARAMETER_TYPE) return; if (target.isGenericsPlaceHolder()) { connections.put(new GenericsTypeName(target.getGenericsTypes()[0].getName()), new GenericsType(type)); } else if (type.isArray() && target.isArray()) { extractGenericsConnections(connections, type.getComponentType(), target.getComponentType()); } else if (type.equals(target) || !implementsInterfaceOrIsSubclassOf(type, target)) { extractGenericsConnections(connections, type.getGenericsTypes(), target.getGenericsTypes()); } else { // first find matching super class or interface ClassNode superClass = getSuperClass(type, target); if (superClass != null) { extractGenericsConnections(connections, getCorrectedClassNode(type, superClass, true), target); } else { // if we reach here, we have an unhandled case throw new GroovyBugError("The type " + type + " seems not to normally extend " + target + ". Sorry, I cannot handle this."); } } }
Example 5
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 6 votes |
static ClassNode applyGenericsContext(final Map<GenericsTypeName, GenericsType> spec, final ClassNode bound) { if (bound == null) return null; if (bound.isArray()) { return applyGenericsContext(spec, bound.getComponentType()).makeArray(); } if (!bound.isUsingGenerics()) return bound; ClassNode newBound = bound.getPlainNodeReference(); newBound.setGenericsTypes(applyGenericsContext(spec, bound.getGenericsTypes())); if (bound.isGenericsPlaceHolder()) { GenericsType[] gt = newBound.getGenericsTypes(); boolean hasBounds = hasNonTrivialBounds(gt[0]); if (hasBounds || !gt[0].isPlaceholder()) return getCombinedBoundType(gt[0]); String placeHolderName = newBound.getGenericsTypes()[0].getName(); if (!placeHolderName.equals(newBound.getUnresolvedName())) { // we should produce a clean placeholder ClassNode here ClassNode clean = make(placeHolderName); clean.setGenericsTypes(newBound.getGenericsTypes()); clean.setRedirect(newBound); newBound = clean; } newBound.setGenericsPlaceHolder(true); } return newBound; }
Example 6
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 6 votes |
public static boolean missesGenericsTypes(final ClassNode cn) { if (cn.isArray()) return missesGenericsTypes(cn.getComponentType()); GenericsType[] cnTypes = cn.getGenericsTypes(); GenericsType[] rnTypes = cn.redirect().getGenericsTypes(); if (rnTypes != null && cnTypes == null) return true; if (cnTypes != null) { for (GenericsType genericsType : cnTypes) { if (genericsType.isPlaceholder()) return true; if (genericsType.isWildcard()) { ClassNode lowerBound = genericsType.getLowerBound(); ClassNode[] upperBounds = genericsType.getUpperBounds(); if (lowerBound != null) { if (lowerBound.isGenericsPlaceHolder() || missesGenericsTypes(lowerBound)) return true; } else if (upperBounds != null) { if (upperBounds[0].isGenericsPlaceHolder() || missesGenericsTypes(upperBounds[0])) return true; } } } } return false; }
Example 7
Source File: BytecodeHelper.java From groovy with Apache License 2.0 | 5 votes |
private static void writeGenericsBoundType(StringBuilder ret, ClassNode printType, boolean writeInterfaceMarker) { if (writeInterfaceMarker && printType.isInterface()) ret.append(":"); if (printType.isGenericsPlaceHolder() && printType.getGenericsTypes()!=null) { ret.append("T"); ret.append(printType.getGenericsTypes()[0].getName()); ret.append(";"); } else { ret.append(getTypeDescription(printType, false)); addSubTypes(ret, printType.getGenericsTypes(), "<", ">"); if (!ClassHelper.isPrimitiveType(printType)) ret.append(";"); } }
Example 8
Source File: GroovyVirtualSourceProvider.java From netbeans with Apache License 2.0 | 5 votes |
private void writeGenericsBounds(PrintWriter out, ClassNode type, boolean skipName) { if (!skipName) { printTypeName(type, out); } if (java5 && !type.isGenericsPlaceHolder()) { writeGenericsBounds(out, type.getGenericsTypes()); } }
Example 9
Source File: BytecodeHelper.java From groovy with Apache License 2.0 | 5 votes |
public static String getGenericsBounds(ClassNode type) { GenericsType[] genericsTypes = type.getGenericsTypes(); if (genericsTypes == null) return null; StringBuilder ret = new StringBuilder(100); if (type.isGenericsPlaceHolder()) { addSubTypes(ret, type.getGenericsTypes(), "", ""); } else { GenericsType gt = new GenericsType(type); writeGenericsBounds(ret, gt, false); } return ret.toString(); }
Example 10
Source File: GenericsUtils.java From groovy with Apache License 2.0 | 5 votes |
private static void extractSuperClassGenerics(ClassNode[] usage, ClassNode[] declaration, Map<String, ClassNode> spec) { if (usage == null || declaration == null || declaration.length == 0) return; // both have generics for (int i = 0; i < usage.length; i++) { ClassNode ui = usage[i]; ClassNode di = declaration[i]; if (di.isGenericsPlaceHolder()) { spec.put(di.getGenericsTypes()[0].getName(), di); } else if (di.isUsingGenerics()) { extractSuperClassGenerics(ui.getGenericsTypes(), di.getGenericsTypes(), spec); } } }
Example 11
Source File: BinaryExpressionHelper.java From groovy with Apache License 2.0 | 5 votes |
private VariableSlotLoader loadWithSubscript(final Expression expression) { AsmClassGenerator acg = controller.getAcg(); // if we have a BinaryExpression, check if it is with subscription if (expression instanceof BinaryExpression) { BinaryExpression bexp = (BinaryExpression) expression; if (bexp.getOperation().getType() == LEFT_SQUARE_BRACKET) { // right expression is the subscript expression // we store the result of the subscription on the stack Expression subscript = bexp.getRightExpression(); subscript.visit(acg); OperandStack operandStack = controller.getOperandStack(); ClassNode subscriptType = operandStack.getTopOperand(); if (subscriptType.isGenericsPlaceHolder() || GenericsUtils.hasPlaceHolders(subscriptType)) { subscriptType = controller.getTypeChooser().resolveType(bexp, controller.getClassNode()); } int id = controller.getCompileStack().defineTemporaryVariable("$subscript", subscriptType, true); VariableSlotLoader subscriptExpression = new VariableSlotLoader(subscriptType, id, operandStack); BinaryExpression rewrite = binX(bexp.getLeftExpression(), bexp.getOperation(), subscriptExpression); rewrite.copyNodeMetaData(bexp); rewrite.setSourcePosition(bexp); rewrite.visit(acg); return subscriptExpression; } } // normal loading of expression expression.visit(acg); return null; }
Example 12
Source File: GenericsUtils.java From groovy with Apache License 2.0 | 5 votes |
public static Map<String, ClassNode> addMethodGenerics(MethodNode current, Map<String, ClassNode> oldSpec) { Map<String, ClassNode> newSpec = new HashMap<>(oldSpec); GenericsType[] gts = current.getGenericsTypes(); if (gts != null) { for (GenericsType gt : gts) { String name = gt.getName(); ClassNode type = gt.getType(); if (gt.isPlaceholder()) { ClassNode redirect; if (gt.getUpperBounds() != null) { redirect = gt.getUpperBounds()[0]; } else if (gt.getLowerBound() != null) { redirect = gt.getLowerBound(); } else { redirect = ClassHelper.OBJECT_TYPE; } if (redirect.isGenericsPlaceHolder()) { // "T extends U" or "T super U" type = redirect; } else { // "T" or "T extends Thing" or "T super Thing" type = ClassHelper.makeWithoutCaching(name); type.setGenericsPlaceHolder(true); type.setRedirect(redirect); } } newSpec.put(name, type); } } return newSpec; }
Example 13
Source File: GenericsUtils.java From groovy with Apache License 2.0 | 5 votes |
public static ClassNode correctToGenericsSpec(Map<String, ClassNode> genericsSpec, ClassNode type) { if (type.isArray()) { return correctToGenericsSpec(genericsSpec, type.getComponentType()).makeArray(); } if (type.isGenericsPlaceHolder() && type.getGenericsTypes() != null) { String name = type.getGenericsTypes()[0].getName(); type = genericsSpec.get(name); if (type != null && type.isGenericsPlaceHolder() && !name.equals(type.getUnresolvedName())) { return correctToGenericsSpec(genericsSpec, type); } } if (type == null) type = ClassHelper.OBJECT_TYPE; return type; }
Example 14
Source File: JavaStubGenerator.java From groovy with Apache License 2.0 | 5 votes |
private void printType(PrintWriter out, ClassNode type) { if (type.isArray()) { printType(out, type.getComponentType()); out.print("[]"); } else if (java5 && type.isGenericsPlaceHolder()) { out.print(type.getUnresolvedName()); } else { printGenericsBounds(out, type, false); } }
Example 15
Source File: MemberSignatureParser.java From groovy with Apache License 2.0 | 5 votes |
private static ClassNode applyErasure(ClassNode genericType, ClassNode erasure) { if (genericType.isArray() && erasure.isArray() && genericType.getComponentType().isGenericsPlaceHolder()) { genericType.setRedirect(erasure); genericType.getComponentType().setRedirect(erasure.getComponentType()); } else if (genericType.isGenericsPlaceHolder()) { genericType.setRedirect(erasure); } return genericType; }
Example 16
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 5 votes |
private static void extractGenericsConnections(final Map<GenericsTypeName, GenericsType> connections, final ClassNode[] usage, final ClassNode[] declaration) { if (usage == null || declaration == null || declaration.length == 0) return; // both have generics for (int i = 0, n = usage.length; i < n; i += 1) { ClassNode ui = usage[i]; ClassNode di = declaration[i]; if (di.isGenericsPlaceHolder()) { GenericsType gt = new GenericsType(di); gt.setPlaceholder(di.isGenericsPlaceHolder()); connections.put(new GenericsTypeName(di.getGenericsTypes()[0].getName()), gt); } else if (di.isUsingGenerics()) { extractGenericsConnections(connections, ui.getGenericsTypes(), di.getGenericsTypes()); } } }
Example 17
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 5 votes |
private static boolean equalIncludingGenerics(final ClassNode orig, final ClassNode copy) { if (orig == copy) return true; if (orig.isGenericsPlaceHolder() != copy.isGenericsPlaceHolder()) return false; if (!orig.equals(copy)) return false; GenericsType[] gt1 = orig.getGenericsTypes(); GenericsType[] gt2 = orig.getGenericsTypes(); if ((gt1 == null) ^ (gt2 == null)) return false; if (gt1 != gt2) { if (gt1.length != gt2.length) return false; for (int i = 0, n = gt1.length; i < n; i += 1) { if (!equalIncludingGenerics(gt1[i], gt2[i])) return false; } } return true; }
Example 18
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 5 votes |
private static boolean inferenceCheck(final Set<GenericsTypeName> fixedGenericsPlaceHolders, final Map<GenericsTypeName, GenericsType> resolvedMethodGenerics, ClassNode type, ClassNode wrappedArgument, final boolean lastArg) { Map<GenericsTypeName, GenericsType> connections = new HashMap<>(); if (isPrimitiveType(wrappedArgument)) wrappedArgument = getWrapper(wrappedArgument); if (lastArg && type.isArray() && type.getComponentType().isGenericsPlaceHolder() && !wrappedArgument.isArray() && wrappedArgument.isGenericsPlaceHolder()) { // GROOVY-8090: handle generics varargs, e.g. "U x = ...; Arrays.asList(x)" // we should connect the type of vararg(e.g. T is the type of T...) to the argument type type = type.getComponentType(); } // the context we compare with in the end is the one of the callsite // so far we specified the context of the method declaration only // thus for each argument, we try to find the connected generics first extractGenericsConnections(connections, wrappedArgument, type); // each found connection must comply with already found connections boolean failure = !compatibleConnections(connections, resolvedMethodGenerics, fixedGenericsPlaceHolders); // and then apply the found information to refine the method level // information. This way the method level information slowly turns // into information for the callsite applyGenericsConnections(connections, resolvedMethodGenerics); // since it is possible that the callsite uses some generics as well, // we may have to add additional elements here addMissingEntries(connections, resolvedMethodGenerics); // to finally see if the parameter and the argument fit together, // we use the provided information to transform the parameter // into something that can exist in the callsite context type = applyGenericsContext(resolvedMethodGenerics, type); // there of course transformed parameter type and argument must fit failure = failure || !typeCheckMethodArgumentWithGenerics(type, wrappedArgument, lastArg); return failure; }
Example 19
Source File: GenericsUtils.java From groovy with Apache License 2.0 | 4 votes |
public static ClassNode correctToGenericsSpecRecurse(Map<String, ClassNode> genericsSpec, ClassNode type, List<String> exclusions) { if (type.isArray()) { return correctToGenericsSpecRecurse(genericsSpec, type.getComponentType(), exclusions).makeArray(); } if (type.isGenericsPlaceHolder() && !exclusions.contains(type.getUnresolvedName())) { String name = type.getGenericsTypes()[0].getName(); exclusions = plus(exclusions, name); // GROOVY-7722 type = genericsSpec.get(name); if (type != null && type.isGenericsPlaceHolder()) { if (type.getGenericsTypes() == null) { ClassNode placeholder = ClassHelper.makeWithoutCaching(type.getUnresolvedName()); placeholder.setGenericsPlaceHolder(true); return makeClassSafeWithGenerics(type, new GenericsType(placeholder)); } else if (!name.equals(type.getUnresolvedName())) { return correctToGenericsSpecRecurse(genericsSpec, type, exclusions); } } } if (type == null) type = ClassHelper.OBJECT_TYPE; GenericsType[] oldgTypes = type.getGenericsTypes(); GenericsType[] newgTypes = EMPTY_GENERICS_ARRAY; if (oldgTypes != null) { newgTypes = new GenericsType[oldgTypes.length]; for (int i = 0; i < newgTypes.length; i++) { GenericsType oldgType = oldgTypes[i]; if (oldgType.isWildcard()) { ClassNode[] oldUpper = oldgType.getUpperBounds(); ClassNode[] upper = null; if (oldUpper != null) { // correct "? extends T" or "? extends T & I" upper = new ClassNode[oldUpper.length]; for (int j = 0; j < oldUpper.length; j++) { upper[j] = correctToGenericsSpecRecurse(genericsSpec, oldUpper[j], exclusions); } } ClassNode oldLower = oldgType.getLowerBound(); ClassNode lower = null; if (oldLower != null) { // correct "? super T" lower = correctToGenericsSpecRecurse(genericsSpec, oldLower, exclusions); } GenericsType fixed = new GenericsType(oldgType.getType(), upper, lower); fixed.setWildcard(true); newgTypes[i] = fixed; } else if (oldgType.isPlaceholder()) { // correct "T" newgTypes[i] = new GenericsType(genericsSpec.getOrDefault(oldgType.getName(), ClassHelper.OBJECT_TYPE)); } else { // correct "List<T>", etc. newgTypes[i] = new GenericsType(correctToGenericsSpecRecurse(genericsSpec, correctToGenericsSpec(genericsSpec, oldgType), exclusions)); } } } return makeClassSafeWithGenerics(type, newgTypes); }
Example 20
Source File: StaticTypeCheckingSupport.java From groovy with Apache License 2.0 | 4 votes |
public static boolean checkCompatibleAssignmentTypes(final ClassNode left, final ClassNode right, final Expression rightExpression, final boolean allowConstructorCoercion) { ClassNode leftRedirect = left.redirect(); ClassNode rightRedirect = right.redirect(); if (leftRedirect == rightRedirect) return true; if (leftRedirect.isArray() && rightRedirect.isArray()) { return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType(), rightExpression, false); } if (right == VOID_TYPE || right == void_WRAPPER_TYPE) { return left == VOID_TYPE || left == void_WRAPPER_TYPE; } if ((isNumberType(rightRedirect) || WideningCategories.isNumberCategory(rightRedirect))) { if (BigDecimal_TYPE == leftRedirect) { // any number can be assigned to a big decimal return true; } if (BigInteger_TYPE == leftRedirect) { return WideningCategories.isBigIntCategory(getUnwrapper(rightRedirect)) || rightRedirect.isDerivedFrom(BigInteger_TYPE); } } // if rightExpression is null and leftExpression is not a primitive type, it's ok boolean rightExpressionIsNull = (rightExpression instanceof ConstantExpression && ((ConstantExpression) rightExpression).isNullExpression()); if (rightExpressionIsNull && !isPrimitiveType(left)) { return true; } // on an assignment everything that can be done by a GroovyCast is allowed // anything can be assigned to an Object, String, Boolean or Class typed variable if (isWildcardLeftHandSide(leftRedirect) && !(boolean_TYPE.equals(left) && rightExpressionIsNull)) return true; // char as left expression if (leftRedirect == char_TYPE && rightRedirect == STRING_TYPE) { if (rightExpression instanceof ConstantExpression) { String value = rightExpression.getText(); return value.length() == 1; } } if (leftRedirect == Character_TYPE && (rightRedirect == STRING_TYPE || rightExpressionIsNull)) { return rightExpressionIsNull || (rightExpression instanceof ConstantExpression && rightExpression.getText().length() == 1); } // if left is Enum and right is String or GString we do valueOf if (leftRedirect.isDerivedFrom(Enum_Type) && (rightRedirect == GSTRING_TYPE || rightRedirect == STRING_TYPE)) { return true; } // if right is array, map or collection we try invoking the constructor if (allowConstructorCoercion && isGroovyConstructorCompatible(rightExpression)) { // TODO: in case of the array we could maybe make a partial check if (leftRedirect.isArray() && rightRedirect.isArray()) { return checkCompatibleAssignmentTypes(leftRedirect.getComponentType(), rightRedirect.getComponentType()); } else if (rightRedirect.isArray() && !leftRedirect.isArray()) { return false; } return true; } // simple check on being subclass if (right.isDerivedFrom(left) || (left.isInterface() && right.implementsInterface(left))) return true; // if left and right are primitives or numbers allow if (isPrimitiveType(leftRedirect) && isPrimitiveType(rightRedirect)) return true; if (isNumberType(leftRedirect) && isNumberType(rightRedirect)) return true; // left is a float/double and right is a BigDecimal if (WideningCategories.isFloatingCategory(leftRedirect) && BigDecimal_TYPE.equals(rightRedirect)) { return true; } if (GROOVY_OBJECT_TYPE.equals(leftRedirect) && isBeingCompiled(right)) { return true; } if (left.isGenericsPlaceHolder()) { // GROOVY-7307 GenericsType[] genericsTypes = left.getGenericsTypes(); if (genericsTypes != null && genericsTypes.length == 1) { // should always be the case, but safe guard is better return genericsTypes[0].isCompatibleWith(right); } } // GROOVY-7316: It is an apparently legal thing to allow this. It's not type safe, but it is allowed... return right.isGenericsPlaceHolder(); }