public ResolvedFieldDeclaration getField(String name) { for (Field field : clazz.getDeclaredFields()) { if (field.getName().equals(name)) { return new ReflectionFieldDeclaration(field, typeSolver); } } for (ResolvedReferenceType ancestor : typeDeclaration.getAllAncestors()) { if (ancestor.getTypeDeclaration().hasField(name)) { ReflectionFieldDeclaration reflectionFieldDeclaration = (ReflectionFieldDeclaration) ancestor.getTypeDeclaration().getField(name); return reflectionFieldDeclaration.replaceType(ancestor.getFieldType(name).get()); } } throw new UnsolvedSymbolException(name, "Field in " + this); }
public ResolvedFieldDeclaration getField(String name) { for (Field field : clazz.getDeclaredFields()) { if (field.getName().equals(name)) { return new ReflectionFieldDeclaration(field, typeSolver); } } for (ResolvedReferenceType ancestor : typeDeclaration.getAllAncestors()) { if (ancestor.getTypeDeclaration().hasField(name)) { ReflectionFieldDeclaration reflectionFieldDeclaration = (ReflectionFieldDeclaration) ancestor.getTypeDeclaration().getField(name); return reflectionFieldDeclaration.replaceType(ancestor.getFieldType(name).get()); } } throw new UnsolvedSymbolException(name, "Field in " + this); }
public ResolvedFieldDeclaration getField(String name) { for (Field field : clazz.getDeclaredFields()) { if (field.getName().equals(name)) { return new ReflectionFieldDeclaration(field, typeSolver); } } for (ResolvedReferenceType ancestor : typeDeclaration.getAllAncestors()) { if (ancestor.getTypeDeclaration().hasField(name)) { ReflectionFieldDeclaration reflectionFieldDeclaration = (ReflectionFieldDeclaration) ancestor.getTypeDeclaration().getField(name); return reflectionFieldDeclaration.replaceType(ancestor.getFieldType(name).get()); } } throw new UnsolvedSymbolException(name, "Field in " + this); }
public SymbolReference<ResolvedValueDeclaration> solveField(String name) { Collection<ResolvedReferenceTypeDeclaration> rrtds = findTypeDeclarations(Optional.of(wrappedNode.getScope())); for (ResolvedReferenceTypeDeclaration rrtd : rrtds) { if (rrtd.isEnum()) { Optional<ResolvedEnumConstantDeclaration> enumConstant = rrtd.asEnum().getEnumConstants().stream().filter(c -> c.getName().equals(name)).findFirst(); if (enumConstant.isPresent()) { return SymbolReference.solved(enumConstant.get()); } } try { return SymbolReference.solved(rrtd.getField(wrappedNode.getName().getId())); } catch (Throwable t) { } } return SymbolReference.unsolved(ResolvedFieldDeclaration.class); } }
public SymbolReference<ResolvedFieldDeclaration> solveField(String name, TypeSolver typeSolver) { Collection<ResolvedReferenceTypeDeclaration> rrtds = findTypeDeclarations(Optional.of(wrappedNode.getScope()), typeSolver); for (ResolvedReferenceTypeDeclaration rrtd : rrtds) { try { return SymbolReference.solved(rrtd.getField(wrappedNode.getName().getId())); } catch (Throwable t) { } } return SymbolReference.unsolved(ResolvedFieldDeclaration.class); } }
@Override public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name) { if (typeSolver == null) throw new IllegalArgumentException(); // among constants for (EnumConstantDeclaration constant : wrappedNode.getEntries()) { if (constant.getName().getId().equals(name)) { return SymbolReference.solved(new JavaParserEnumConstantDeclaration(constant, typeSolver)); } } if (this.getDeclaration().hasField(name)) { return SymbolReference.solved(this.getDeclaration().getField(name)); } // then to parent return getParent().solveSymbol(name); }
@Override public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { if (typeSolver == null) throw new IllegalArgumentException(); // among constants for (EnumConstantDeclaration constant : wrappedNode.getEntries()) { if (constant.getName().getId().equals(name)) { return SymbolReference.solved(new JavaParserEnumConstantDeclaration(constant, typeSolver)); } } if (this.getDeclaration().hasField(name)) { return SymbolReference.solved(this.getDeclaration().getField(name)); } // then to parent return getParent().solveSymbol(name, typeSolver); }
@Override public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { if (typeSolver == null) throw new IllegalArgumentException(); // among constants for (EnumConstantDeclaration constant : wrappedNode.getEntries()) { if (constant.getName().getId().equals(name)) { return SymbolReference.solved(new JavaParserEnumConstantDeclaration(constant, typeSolver)); } } if (this.getDeclaration().hasField(name)) { return SymbolReference.solved(this.getDeclaration().getField(name)); } // then to parent return getParent().solveSymbol(name, typeSolver); }
@Test public void findAllInheritedFieldsAndGenerics() throws ParseException { CompilationUnit cu = parseSample("AClassWithFieldsAndGenerics"); ClassOrInterfaceDeclaration classC = Navigator.demandClass(cu, "C"); ResolvedReferenceTypeDeclaration typeDeclaration = JavaParserFacade.get(new ReflectionTypeSolver()).getTypeDeclaration(classC); assertEquals(3, typeDeclaration.getAllFields().size()); assertEquals(ImmutableSet.of("a", "b", "c"), typeDeclaration.getAllFields().stream().map(ResolvedDeclaration::getName).collect(Collectors.toSet())); assertEquals("java.util.List<java.lang.String>", typeDeclaration.getField("b").getType().describe()); } }
/** * Java Parser can't differentiate between packages, internal types, and fields. * All three are lumped together into FieldAccessExpr. We need to differentiate them. */ private ResolvedType solveDotExpressionType(ResolvedReferenceTypeDeclaration parentType, FieldAccessExpr node) { // Fields and internal type declarations cannot have the same name. // Thus, these checks will always be mutually exclusive. if (parentType.hasField(node.getName().getId())) { return parentType.getField(node.getName().getId()).getType(); } else if (parentType.hasInternalType(node.getName().getId())) { return new ReferenceTypeImpl(parentType.getInternalType(node.getName().getId()), typeSolver); } else { throw new UnsolvedSymbolException(node.getName().getId()); } }
/** * Java Parser can't differentiate between packages, internal types, and fields. * All three are lumped together into FieldAccessExpr. We need to differentiate them. */ private ResolvedType solveDotExpressionType(ResolvedReferenceTypeDeclaration parentType, FieldAccessExpr node) { // Fields and internal type declarations cannot have the same name. // Thus, these checks will always be mutually exclusive. if (parentType.hasField(node.getName().getId())) { return parentType.getField(node.getName().getId()).getType(); } else if (parentType.hasInternalType(node.getName().getId())) { return new ReferenceTypeImpl(parentType.getInternalType(node.getName().getId()), typeSolver); } else { throw new UnsolvedSymbolException(node.getName().getId()); } }
@Test public void testGetFieldDeclarationTypeVariableInheritance() { class Foo<E> { E field; } class Bar extends Foo<String> { } TypeSolver typeResolver = new ReflectionTypeSolver(); ResolvedReferenceTypeDeclaration foo = new ReflectionClassDeclaration(Foo.class, typeResolver); ResolvedReferenceTypeDeclaration bar = new ReflectionClassDeclaration(Bar.class, typeResolver); ResolvedFieldDeclaration fooField = foo.getField("field"); assertEquals(true, fooField.getType().isTypeVariable()); assertEquals("E", fooField.getType().asTypeParameter().getName()); ResolvedFieldDeclaration barField = bar.getField("field"); assertEquals(true, barField.getType().isReferenceType()); assertEquals(String.class.getCanonicalName(), barField.getType().asReferenceType().getQualifiedName()); }
@Override public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { SwitchStmt switchStmt = (SwitchStmt) getParentNode(wrappedNode); ResolvedType type = JavaParserFacade.get(typeSolver).getType(switchStmt.getSelector()); if (type.isReferenceType() && type.asReferenceType().getTypeDeclaration().isEnum()) { if (type instanceof ReferenceTypeImpl) { ReferenceTypeImpl typeUsageOfTypeDeclaration = (ReferenceTypeImpl) type; if (typeUsageOfTypeDeclaration.getTypeDeclaration().hasField(name)) { return SymbolReference.solved(typeUsageOfTypeDeclaration.getTypeDeclaration().getField(name)); } } else { throw new UnsupportedOperationException(); } } // look for declaration in other switch statements for (SwitchEntryStmt seStmt : switchStmt.getEntries()) { if (!seStmt.equals(wrappedNode)) { for (Statement stmt : seStmt.getStatements()) { SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(stmt, typeSolver); SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name); if (symbolReference.isSolved()) { return symbolReference; } } } } return getParent().solveSymbol(name, typeSolver); }
@Override public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) { SwitchStmt switchStmt = (SwitchStmt) getParentNode(wrappedNode); ResolvedType type = JavaParserFacade.get(typeSolver).getType(switchStmt.getSelector()); if (type.isReferenceType() && type.asReferenceType().getTypeDeclaration().isEnum()) { if (type instanceof ReferenceTypeImpl) { ReferenceTypeImpl typeUsageOfTypeDeclaration = (ReferenceTypeImpl) type; if (typeUsageOfTypeDeclaration.getTypeDeclaration().hasField(name)) { return SymbolReference.solved(typeUsageOfTypeDeclaration.getTypeDeclaration().getField(name)); } } else { throw new UnsupportedOperationException(); } } // look for declaration in other switch statements for (SwitchEntryStmt seStmt : switchStmt.getEntries()) { if (!seStmt.equals(wrappedNode)) { for (Statement stmt : seStmt.getStatements()) { SymbolDeclarator symbolDeclarator = JavaParserFactory.getSymbolDeclarator(stmt, typeSolver); SymbolReference<? extends ResolvedValueDeclaration> symbolReference = solveWith(symbolDeclarator, name); if (symbolReference.isSolved()) { return symbolReference; } } } } return getParent().solveSymbol(name, typeSolver); }
return SymbolReference.solved(typeUsageOfTypeDeclaration.getTypeDeclaration().getField(name));
/** * Java Parser can't differentiate between packages, internal types, and fields. * All three are lumped together into FieldAccessExpr. We need to differentiate them. */ private ResolvedType solveDotExpressionType(ResolvedReferenceTypeDeclaration parentType, FieldAccessExpr node) { // Fields and internal type declarations cannot have the same name. // Thus, these checks will always be mutually exclusive. if (parentType.isEnum() && parentType.asEnum().hasEnumConstant(node.getName().getId())) { return parentType.asEnum().getEnumConstant(node.getName().getId()).getType(); } else if (parentType.hasField(node.getName().getId())) { return parentType.getField(node.getName().getId()).getType(); } else if (parentType.hasInternalType(node.getName().getId())) { return new ReferenceTypeImpl(parentType.getInternalType(node.getName().getId()), typeSolver); } else { throw new UnsolvedSymbolException(node.getName().getId()); } }