Failed to resolve implemented inner interface in the same enclosing class in a scratch editor

Issue #1733 resolved
Scott Wells repo owner created an issue

I've extracted this from #1425 (which was already resolved) as it's a different issue, albeit similar in nature. Here's the code that easily reproduces it:

public class Filters {
    public interface Filter {
        Boolean apply(Object toFilter);
    }

    public interface Function {
        Object call(Object functionObject);
    }

    public abstract class ObjectFilter implements Function, Filter {
        public Object call(Object functionObject) {
            return apply(functionObject) ? functionObject : null;
        }

        public abstract Boolean apply(Object toFilter);
    }

    public abstract class SObjectFilter extends ObjectFilter {

        public override Boolean apply(Object toFilter) {
            return apply((SObject) toFilter);
        }

        public abstract Boolean apply(SObject toFilter);
    }

    private class FilterException extends Exception {
    }

    public abstract class StandardFilter extends SObjectFilter {
        protected final SObjectField field;
        protected final Object value;

        public StandardFilter(SObjectField field, Object value) {
            this.field = field;
            this.value = value;
        }

        public abstract override Boolean apply(SObject obj);
    }

    public virtual class EqualsFilter extends StandardFilter {
        public EqualsFilter(SObjectField field, Object value) {
            super(field, value);
        }

        public virtual override Boolean apply(SObject record) {
            Object leftValue = ((SObject) record).get(this.field);
            return leftValue == this.value;
        }
    }

    public virtual class NotEqual extends StandardFilter {
        public NotEqual(SObjectField field, Object value) {
            super(field, value);
        }

        public virtual override Boolean apply(SObject record) {
            Object leftValue = ((SObject) record).get(this.field);
            return leftValue != this.value;
        }
    }

    public class isNull extends EqualsFilter {
        public isNull(SObjectField field) {
            super(field, null);
        }
    }

    public class NotNull extends NotEqual {
        public NotNull(SObjectField field) {
            super(field, null);
        }
    }
}

Comments (14)

  1. Scott Wells reporter

    @{557058:9ed459fc-ae5b-41bb-90f8-a1e259edbdfe}, I can reproduce this in a scratch file but not in an actual source file under a configured source root. In the latter case the only issue is that NotEqual is missing which is actually the case. Just to clarify, are you seeing this outside of scratch files as well?

  2. Scott Wells reporter

    I've updated the example to include NotEqual and I don't get any errors when in a normal editor window, only when I'm in a scratch editor. I'll certainly fix that, but it lowers the priority a bit.

  3. Justin Julicher

    Yes I am - It might be because I had the interfaces in separate files initially but for the issue I put it in all together.

    But the concrete implementations were all in the Filters file.

  4. Scott Wells reporter

    Gotcha. I have part of a fix already implemented where it wasn't finding the inner types properly during resolution because types in scratch files aren't indexed. There's still an issue even with that fix where it's not properly determining the implementation/override relationships within that same scratch file. I'll take a look at that again when I come up for air on my current major set of work, probably in the next few weeks.

  5. Justin Julicher

    Weirdly I was looking at this issue again and it seems to have resolved itself after a full generation of the OST. Although I’m 100% sure I already tried that again previously - were there any changes in the version you just released that might affect this?

  6. Scott Wells reporter

    No, I haven't released anything in this area. I have a shelved changelist with half of a fix, but that hasn't been shipped. I'm also able to reproduce this so it's even more curious that it's not happening for you anymore.

  7. Justin Julicher

    I think I know what it was.

    I had my directory structure like this:

    force-app/utils/main/classes

    and my sfdx-project.json had

    force-app/utils

    as the package directory location.

    However, with sfdx if you have any package directories outside of that there is a bug where it won’t deploy changes under your objects directory (fields etc) in source format.

    Since I moved it back to force-app/main/default/ it has resolved the issue.

  8. Scott Wells reporter

    Ah, okay. It's always a good day if you learn something new! There's still an issue here for resolution from within scratch files that I'll plan to address even if it's not quite the issue that was hitting you. I'll keep this open to take care of that.

  9. Scott Wells reporter

    The remaining aspect of this one occurs because the Apex derived declaration index only indexes types from files under registered source roots, and scrarch files are not under source roots. Similarly we wouldn't index the types from scratch files. I'm going to resolve this one as working-as-designed.

  10. Log in to comment