private Type getAttrType(@NotNull Type targetType) {
        if (attr == null) {
            Util.msg("attr is null");
            Type t = Indexer.idx.builtins.unknown;
            return t;
        }
        Binding b = targetType.getTable().lookupAttr(attr.getId());
        if (b == null) {
            Indexer.idx.putProblem(attr, "attribute not found in type: " + targetType);
            Type t = Indexer.idx.builtins.unknown;
            t.getTable().setPath(targetType.getTable().extendPath(attr.getId()));
            return t;
        } else {
            Indexer.idx.putLocation(attr, b);
            if (b.getType() == null) {
                Util.msg("b.getType() is null!");
            }
            if (getParent() == null) {
                Util.msg("parent is null!");
            }
            if (targetType == null) {
                Util.msg("targetType is null");
            }
            if (getParent() != null && getParent().isCall() &&
                    b.getType().isFuncType() && targetType.isInstanceType()) {  // method call
                b.getType().asFuncType().setSelfType(targetType);
            }
            return b.getType();
        }
    }