private SoftLocationXRefs getBaseLocations()

in src/main/java/com/jetbrains/jdi/ConcreteMethodImpl.java [463:546]


    private SoftLocationXRefs getBaseLocations() {
        SoftLocationXRefs info = (softBaseLocationXRefsRef == null) ? null :
                                     softBaseLocationXRefsRef.get();
        if (info != null) {
            return info;
        }

        JDWP.Method.LineTable lntab;
        try {
            lntab = JDWP.Method.LineTable.process(vm, declaringType, ref);
        } catch (JDWPException exc) {
            /*
             * Note: the absent info error shouldn't happen here
             * because the first and last index are always available.
             */
            throw exc.toJDIException();
        }

        int count  = lntab.lines.length;

        List<Location> lineLocations = new ArrayList<>(count);
        Map<Integer, List<Location>>lineMapper = new HashMap<>();
        int lowestLine = -1;
        int highestLine = -1;
        for (int i = 0; i < count; i++) {
            long bci = lntab.lines[i].lineCodeIndex;
            int lineNumber = lntab.lines[i].lineNumber;

            /*
             * Some compilers will point multiple consecutive
             * lines at the same location. We need to choose
             * one of them so that we can consistently map back
             * and forth between line and location. So we choose
             * to record only the last line entry at a particular
             * location.
             */
            if ((i + 1 == count) || (bci != lntab.lines[i+1].lineCodeIndex)) {
                // Remember the largest/smallest line number
                if (lineNumber > highestLine) {
                    highestLine = lineNumber;
                }
                if ((lineNumber < lowestLine) || (lowestLine == -1)) {
                    lowestLine = lineNumber;
                }
                LocationImpl loc =
                    new LocationImpl(virtualMachine(), this, bci);
                loc.addBaseLineInfo(
                    new BaseLineInfo(lineNumber, declaringType));

                // Add to the location list
                lineLocations.add(loc);

                // Add to the line -> locations map
                lineMapper.computeIfAbsent(lineNumber, k -> new ArrayList<>(1)).add(loc);
            }
        }

        /*
         * firstIndex, lastIndex, and startLocation need to be
         * retrieved only once since they are strongly referenced.
         */
        if (location == null) {
            firstIndex = lntab.start;
            lastIndex = lntab.end;
            /*
             * The startLocation is the first one in the
             * location list if we have one;
             * otherwise, we construct a location for a
             * method start with no line info
             */
            if (count > 0) {
                location = lineLocations.get(0);
            } else {
                location = new LocationImpl(virtualMachine(), this,
                                            firstIndex);
            }
        }

        info = new SoftLocationXRefs(SDE.BASE_STRATUM_NAME,
                                     lineMapper, lineLocations,
                                     lowestLine, highestLine);
        softBaseLocationXRefsRef = vm.createSoftReference(info);
        return info;
    }