private static ClassNode applyErasure(ClassNode genericType, ClassNode erasure) { if (genericType.isGenericsPlaceHolder()) { genericType.setRedirect(erasure); } return genericType; }
private boolean resolveFromDefaultImports(final ClassNode type, boolean testDefaultImports) { // test default imports testDefaultImports &= !type.hasPackageName(); // we do not resolve a vanilla name starting with a lower case letter // try to resolve against a default import, because we know that the // default packages do not contain classes like these testDefaultImports &= !(type instanceof LowerCaseClass); if (testDefaultImports) { if (resolveFromDefaultImports(type)) return true; final String typeName = type.getName(); if (BIGINTEGER_STR.equals(typeName)) { type.setRedirect(ClassHelper.BigInteger_TYPE); return true; } else if (BIGDECIMAL_STR.equals(typeName)) { type.setRedirect(ClassHelper.BigDecimal_TYPE); return true; } } return false; }
public static ClassNode makeWithoutCaching(Class c, boolean includeGenerics) { if (c.isArray()) { ClassNode cn = makeWithoutCaching(c.getComponentType(), includeGenerics); return cn.makeArray(); } final ClassNode cached = makeCached(c); if (includeGenerics) { return cached; } else { ClassNode t = makeWithoutCaching(c.getName()); t.setRedirect(cached); return t; } }
private boolean resolveToNested(ClassNode enclosingType, ClassNode type) { if (type instanceof ConstructedNestedClass) return false; // GROOVY-3110: It may be an inner enum defined by this class itself, in which case it does not need to be // explicitly qualified by the currentClass name String name = type.getName(); if (enclosingType != type && !name.contains(".") && type.getClass().equals(ClassNode.class)) { ClassNode tmp = new ConstructedNestedClass(enclosingType,name); if (resolve(tmp)) { if (!checkInnerTypeVisibility(enclosingType, tmp)) return false; type.setRedirect(tmp); return true; } } return false; }
private boolean resolveFromCompileUnit(ClassNode type) { // look into the compile unit if there is a class with that name CompileUnit compileUnit = currentClass.getCompileUnit(); if (compileUnit == null) return false; ClassNode cuClass = compileUnit.getClass(type.getName()); if (cuClass != null) { if (type != cuClass) type.setRedirect(cuClass); return true; } return false; }
private static GenericsType makePlaceholder(int i) { ClassNode type = ClassHelper.makeWithoutCaching("T" + i); type.setRedirect(OBJECT_TYPE); type.setGenericsPlaceHolder(true); return new GenericsType(type); }
private static GenericsType createWildcard(ClassNode[] upper, ClassNode lower) { ClassNode base = ClassHelper.makeWithoutCaching("?"); base.setRedirect(ClassHelper.OBJECT_TYPE); GenericsType t = new GenericsType(base, upper, lower); t.setWildcard(true); return t; }
private ClassNode makeClassNode(CompileUnit cu, Type t, Class c) { ClassNode back = null; if (cu != null) back = cu.getClass(c.getName()); if (back == null) back = ClassHelper.make(c); if (!(t instanceof Class)) { ClassNode front = configureType(t); front.setRedirect(back); return front; } return back.getPlainNodeReference(); }
public static GenericsType configureTypeVariableDefinition(ClassNode base, ClassNode[] cBounds) { ClassNode redirect = base.redirect(); base.setRedirect(null); GenericsType gt; if (cBounds == null || cBounds.length == 0) { gt = new GenericsType(base); } else { gt = new GenericsType(base, cBounds, null); gt.setName(base.getName()); gt.setPlaceholder(true); } base.setRedirect(redirect); return gt; }
private void ambiguousClass(ClassNode type, ClassNode iType, String name) { if (type.getName().equals(iType.getName())) { addError("reference to " + name + " is ambiguous, both class " + type.getName() + " and " + iType.getName() + " match", type); } else { type.setRedirect(iType); } }
private void resolveHelperClassIfNecessary(final ClassNode helperClassNode) { if (helperClassNode == null) { return; } for (ClassNode cNode : unit.getAST().getClasses()) { ClassNode unresolvedHelperNode = cNode.getNodeMetaData(UNRESOLVED_HELPER_CLASS); if (unresolvedHelperNode != null && unresolvedHelperNode.getName().equals(helperClassNode.getName())) { unresolvedHelperNode.setRedirect(helperClassNode); } } }
private boolean setRedirect(ClassNode type, ClassNode classToCheck) { ClassNode val = new ConstructedNestedClass(classToCheck, type.getName()); if (resolveFromCompileUnit(val)) { type.setRedirect(val); return true; } // also check interfaces in case we have interfaces with nested classes for (ClassNode next : classToCheck.getAllInterfaces()) { if (type.getName().contains(next.getName())) continue; val = new ConstructedNestedClass(next, type.getName()); if (resolve(val, false, false, false)) { type.setRedirect(val); return true; } } return false; }
private ClassNode configureWildcardType(WildcardType wildcardType) { ClassNode base = ClassHelper.makeWithoutCaching("?"); base.setRedirect(ClassHelper.OBJECT_TYPE); //TODO: more than one lower bound for wildcards? ClassNode[] lowers = configureTypes(wildcardType.getLowerBounds()); ClassNode lower = null; // TODO: is it safe to remove this? What was the original intention? if (lowers != null) lower = lowers[0]; ClassNode[] upper = configureTypes(wildcardType.getUpperBounds()); GenericsType t = new GenericsType(base, upper, lower); t.setWildcard(true); ClassNode ref = ClassHelper.makeWithoutCaching(Object.class, false); ref.setGenericsTypes(new GenericsType[]{t}); return ref; }
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; }
public static ClassNode configureTypeVariableReference(String name) { ClassNode cn = ClassHelper.makeWithoutCaching(name); cn.setGenericsPlaceHolder(true); ClassNode cn2 = ClassHelper.makeWithoutCaching(name); cn2.setGenericsPlaceHolder(true); GenericsType[] gts = new GenericsType[]{new GenericsType(cn2)}; cn.setGenericsTypes(gts); cn.setRedirect(ClassHelper.OBJECT_TYPE); return cn; }
public static ClassNode makeEnumNode(String name, int modifiers, ClassNode[] interfaces, ClassNode outerClass) { modifiers = modifiers | Opcodes.ACC_FINAL | Opcodes.ACC_ENUM; ClassNode enumClass; if (outerClass==null) { enumClass = new ClassNode(name,modifiers,null,interfaces,MixinNode.EMPTY_ARRAY); } else { name = outerClass.getName() + "$" + name; modifiers |= Opcodes.ACC_STATIC; enumClass = new InnerClassNode(outerClass,name,modifiers,null,interfaces,MixinNode.EMPTY_ARRAY); } // set super class and generics info // "enum X" -> class X extends Enum<X> GenericsType gt = new GenericsType(enumClass); ClassNode superClass = ClassHelper.makeWithoutCaching("java.lang.Enum"); superClass.setGenericsTypes(new GenericsType[]{gt}); enumClass.setSuperClass(superClass); superClass.setRedirect(ClassHelper.Enum_Type); return enumClass; }
private boolean resolveToOuter(ClassNode type) { String name = type.getName(); // We do not need to check instances of LowerCaseClass // to be a Class, because unless there was an import for // for this we do not lookup these cases. This was a decision // made on the mailing list. To ensure we will not visit this // method again we set a NO_CLASS for this name if (type instanceof LowerCaseClass) { classNodeResolver.cacheClass(name, ClassNodeResolver.NO_CLASS); return false; } if (currentClass.getModule().hasPackageName() && name.indexOf('.') == -1) return false; LookupResult lr = classNodeResolver.resolveName(name, compilationUnit); if (lr != null) { if (lr.isSourceUnit()) { SourceUnit su = lr.getSourceUnit(); currentClass.getCompileUnit().addClassNodeToCompile(type, su); } else { type.setRedirect(lr.getClassNode()); } return true; } return false; }
private ClassNode getHelper(final ClassNode traitReceiver) { if (helperClassNotCreatedYet(traitReceiver)) { // GROOVY-7909 A Helper class in same compilation unit may have not been created when referenced // Here create a symbol as a "placeholder" and it will be resolved later. ClassNode ret = new InnerClassNode( traitReceiver, Traits.helperClassName(traitReceiver), ACC_PUBLIC | ACC_STATIC | ACC_ABSTRACT | ACC_SYNTHETIC, ClassHelper.OBJECT_TYPE, ClassNode.EMPTY_ARRAY, null ).getPlainNodeReference(); ret.setRedirect(null); traitReceiver.redirect().setNodeMetaData(UNRESOLVED_HELPER_CLASS, ret); return ret; } else { TraitHelpersTuple helpers = Traits.findHelpers(traitReceiver); return helpers.getHelper(); } }
public static ClassNode nonGeneric(ClassNode type) { if (type.isUsingGenerics()) { final ClassNode nonGen = ClassHelper.makeWithoutCaching(type.getName()); nonGen.setRedirect(type); nonGen.setGenericsTypes(null); nonGen.setUsingGenerics(false); return nonGen; } if (type.isArray() && type.getComponentType().isUsingGenerics()) { return type.getComponentType().getPlainNodeReference().makeArray(); } return type; }
protected ClassNode makeType(AST typeNode) { ClassNode answer = ClassHelper.DYNAMIC_TYPE; AST node = typeNode.getFirstChild(); if (node != null) { if (isType(INDEX_OP, node) || isType(ARRAY_DECLARATOR, node)) { answer = makeType(node).makeArray(); } else { checkTypeArgs(node, false); answer = ClassHelper.make(qualifiedName(node)); if (answer.isUsingGenerics()) { ClassNode newAnswer = ClassHelper.makeWithoutCaching(answer.getName()); newAnswer.setRedirect(answer); answer = newAnswer; } } configureAST(answer, node); } return answer; }