@Override public boolean visit(ClassInstanceCreationExpression c) { ExpressionType clzType; if (c.hasBody()) { clzType = new ExpressionType(cip.getFullName(c.getBody())); } else { clzType = c.getId().getExpressionType(); } if (hasMethods(clzType, c)) { String fqn = clzType.getClassName(); ArgumentList al = c.getArgumentList(); try { MethodInformation mi = findMatchingConstructor(fqn, al); if (mi == null) { diagnostics.report( SourceDiagnostics.error( tree.getOrigin(), c.getParsePosition(), "No matching constructor found")); } else { c.setMethodInformation(mi); } } catch (IOException e) { diagnostics.report( SourceDiagnostics.error( tree.getOrigin(), c.getParsePosition(), "Failed to read class: " + e)); } } return true; }
private ExpressionType getOnType(TreeNode on) { if (on != null) { return on.getExpressionType(); } else { String fqn = cip.getFullName(containingClasses.getLast()); return new ExpressionType(fqn); } }
@Override public boolean visit(FieldAccess f) { ExpressionType retType = cip.getFieldType(f.getFrom().getExpressionType().getClassName(), f.getFieldId()); if (retType == null) { diagnostics.report( SourceDiagnostics.error( tree.getOrigin(), f.getParsePosition(), "Cannot find symbol: %s", f.getFieldId())); } else { f.setReturnType(retType); } return true; }
private MethodInformation findMatching(String fqn, ArgumentList al, MethodFinder mf) throws IOException { Deque<String> typesToCheck = new ArrayDeque<>(); typesToCheck.addLast(fqn); Set<String> visitedTypes = new HashSet<>(); while (!typesToCheck.isEmpty()) { String clz = typesToCheck.removeFirst(); if (visitedTypes.contains(clz)) continue; visitedTypes.add(clz); List<MethodInformation> ls = mf.getAlternatives(clz); if (ls != null) { for (MethodInformation mi : ls) if (match(al, mi)) return mi; } // not found in current class, try super class Optional<List<String>> o = cip.getSuperTypes(clz); if (o.isPresent() && mf.mayUseSuperclassMethods()) typesToCheck.addAll(o.get()); } return null; }