Scope.java

net.minecraft.util.parsing.packrat.Scope

信息

  • 全限定名:net.minecraft.util.parsing.packrat.Scope
  • 类型:public final class
  • 包:net.minecraft.util.parsing.packrat
  • 源码路径:src/main/java/net/minecraft/util/parsing/packrat/Scope.java
  • 起始行号:L10
  • 职责:

    TODO

字段/常量

  • NOT_FOUND

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L11
    • 说明:

      TODO

  • FRAME_START_MARKER

    • 类型: Object
    • 修饰符: private static final public
    • 源码定位: L12
    • 说明:

      TODO

  • ENTRY_STRIDE

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L18
    • 说明:

      TODO

  • stack

    • 类型: Object[]
    • 修饰符: private
    • 源码定位: L19
    • 说明:

      TODO

  • topEntryKeyIndex

    • 类型: int
    • 修饰符: private
    • 源码定位: L20
    • 说明:

      TODO

  • topMarkerKeyIndex

    • 类型: int
    • 修饰符: private
    • 源码定位: L21
    • 说明:

      TODO

内部类/嵌套类型

构造器

public Scope() @ L23

  • 构造器名:Scope
  • 源码定位:L23
  • 修饰符:public

参数:

说明:

TODO

方法

下面的方法块按源码顺序生成。

private int valueIndex(Atom<?> atom) @ L28

  • 方法名:valueIndex
  • 源码定位:L28
  • 返回类型:int
  • 修饰符:private

参数:

  • atom: Atom<?>

说明:

TODO

public int valueIndexForAny(Atom<?>... atoms) @ L42

  • 方法名:valueIndexForAny
  • 源码定位:L42
  • 返回类型:int
  • 修饰符:public

参数:

  • atoms: Atom<?>…

说明:

TODO

private void ensureCapacity(int additionalEntryCount) @ L58

  • 方法名:ensureCapacity
  • 源码定位:L58
  • 返回类型:void
  • 修饰符:private

参数:

  • additionalEntryCount: int

说明:

TODO

private void setupNewFrame() @ L72

  • 方法名:setupNewFrame
  • 源码定位:L72
  • 返回类型:void
  • 修饰符:private

参数:

说明:

TODO

public void pushFrame() @ L79

  • 方法名:pushFrame
  • 源码定位:L79
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private int getPreviousMarkerIndex(int markerKeyIndex) @ L86

  • 方法名:getPreviousMarkerIndex
  • 源码定位:L86
  • 返回类型:int
  • 修饰符:private

参数:

  • markerKeyIndex: int

说明:

TODO

public void popFrame() @ L90

  • 方法名:popFrame
  • 源码定位:L90
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void splitFrame() @ L99

  • 方法名:splitFrame
  • 源码定位:L99
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void clearFrameValues() @ L123

  • 方法名:clearFrameValues
  • 源码定位:L123
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void mergeFrame() @ L133

  • 方法名:mergeFrame
  • 源码定位:L133
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public <T> void put(Atom<T> name, T value) @ L161

  • 方法名:put
  • 源码定位:L161
  • 返回类型: void
  • 修饰符:public

参数:

  • name: Atom
  • value: T

说明:

TODO

public <T> T get(Atom<T> name) @ L175

  • 方法名:get
  • 源码定位:L175
  • 返回类型: T
  • 修饰符:public

参数:

  • name: Atom

说明:

TODO

public <T> T getOrThrow(Atom<T> name) @ L180

  • 方法名:getOrThrow
  • 源码定位:L180
  • 返回类型: T
  • 修饰符:public

参数:

  • name: Atom

说明:

TODO

public <T> T getOrDefault(Atom<T> name, T fallback) @ L189

  • 方法名:getOrDefault
  • 源码定位:L189
  • 返回类型: T
  • 修饰符:public

参数:

  • name: Atom
  • fallback: T

说明:

TODO

public final <T> T getAny(Atom<?extends T>... names) @ L194

  • 方法名:getAny
  • 源码定位:L194
  • 返回类型: T
  • 修饰符:public final

参数:

  • names: Atom<?extends T>…

说明:

TODO

public final <T> T getAnyOrThrow(Atom<?extends T>... names) @ L200

  • 方法名:getAnyOrThrow
  • 源码定位:L200
  • 返回类型: T
  • 修饰符:public final

参数:

  • names: Atom<?extends T>…

说明:

TODO

public String toString() @ L210

  • 方法名:toString
  • 源码定位:L210
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public Map<Atom<?>,?> lastFrame() @ L234

  • 方法名:lastFrame
  • 源码定位:L234
  • 返回类型:Map<Atom,?>
  • 修饰符:public

参数:

说明:

TODO

public boolean hasOnlySingleFrame() @ L247

  • 方法名:hasOnlySingleFrame
  • 源码定位:L247
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

private boolean validateStructure() @ L261

  • 方法名:validateStructure
  • 源码定位:L261
  • 返回类型:boolean
  • 修饰符:private

参数:

说明:

TODO

代码

public final class Scope {
    private static final int NOT_FOUND = -1;
    private static final Object FRAME_START_MARKER = new Object() {
        @Override
        public String toString() {
            return "frame";
        }
    };
    private static final int ENTRY_STRIDE = 2;
    private @Nullable Object[] stack = new Object[128];
    private int topEntryKeyIndex = 0;
    private int topMarkerKeyIndex = 0;
 
    public Scope() {
        this.stack[0] = FRAME_START_MARKER;
        this.stack[1] = null;
    }
 
    private int valueIndex(Atom<?> atom) {
        for (int i = this.topEntryKeyIndex; i > this.topMarkerKeyIndex; i -= 2) {
            Object key = this.stack[i];
 
            assert key instanceof Atom;
 
            if (key == atom) {
                return i + 1;
            }
        }
 
        return -1;
    }
 
    public int valueIndexForAny(Atom<?>... atoms) {
        for (int i = this.topEntryKeyIndex; i > this.topMarkerKeyIndex; i -= 2) {
            Object key = this.stack[i];
 
            assert key instanceof Atom;
 
            for (Atom<?> atom : atoms) {
                if (atom == key) {
                    return i + 1;
                }
            }
        }
 
        return -1;
    }
 
    private void ensureCapacity(int additionalEntryCount) {
        int currentSize = this.stack.length;
        int currentLastValueIndex = this.topEntryKeyIndex + 1;
        int newLastValueIndex = currentLastValueIndex + additionalEntryCount * 2;
        if (newLastValueIndex >= currentSize) {
            int newSize = Util.growByHalf(currentSize, newLastValueIndex + 1);
            Object[] newStack = new Object[newSize];
            System.arraycopy(this.stack, 0, newStack, 0, currentSize);
            this.stack = newStack;
        }
 
        assert this.validateStructure();
    }
 
    private void setupNewFrame() {
        this.topEntryKeyIndex += 2;
        this.stack[this.topEntryKeyIndex] = FRAME_START_MARKER;
        this.stack[this.topEntryKeyIndex + 1] = this.topMarkerKeyIndex;
        this.topMarkerKeyIndex = this.topEntryKeyIndex;
    }
 
    public void pushFrame() {
        this.ensureCapacity(1);
        this.setupNewFrame();
 
        assert this.validateStructure();
    }
 
    private int getPreviousMarkerIndex(int markerKeyIndex) {
        return (Integer)this.stack[markerKeyIndex + 1];
    }
 
    public void popFrame() {
        assert this.topMarkerKeyIndex != 0;
 
        this.topEntryKeyIndex = this.topMarkerKeyIndex - 2;
        this.topMarkerKeyIndex = this.getPreviousMarkerIndex(this.topMarkerKeyIndex);
 
        assert this.validateStructure();
    }
 
    public void splitFrame() {
        int currentFrameMarkerIndex = this.topMarkerKeyIndex;
        int nonMarkerEntriesInFrame = (this.topEntryKeyIndex - this.topMarkerKeyIndex) / 2;
        this.ensureCapacity(nonMarkerEntriesInFrame + 1);
        this.setupNewFrame();
        int sourceCursor = currentFrameMarkerIndex + 2;
        int targetCursor = this.topEntryKeyIndex;
 
        for (int i = 0; i < nonMarkerEntriesInFrame; i++) {
            targetCursor += 2;
            Object key = this.stack[sourceCursor];
 
            assert key != null;
 
            this.stack[targetCursor] = key;
            this.stack[targetCursor + 1] = null;
            sourceCursor += 2;
        }
 
        this.topEntryKeyIndex = targetCursor;
 
        assert this.validateStructure();
    }
 
    public void clearFrameValues() {
        for (int i = this.topEntryKeyIndex; i > this.topMarkerKeyIndex; i -= 2) {
            assert this.stack[i] instanceof Atom;
 
            this.stack[i + 1] = null;
        }
 
        assert this.validateStructure();
    }
 
    public void mergeFrame() {
        int previousMarkerIndex = this.getPreviousMarkerIndex(this.topMarkerKeyIndex);
        int previousFrameCursor = previousMarkerIndex;
        int currentFrameCursor = this.topMarkerKeyIndex;
 
        while (currentFrameCursor < this.topEntryKeyIndex) {
            previousFrameCursor += 2;
            currentFrameCursor += 2;
            Object newKey = this.stack[currentFrameCursor];
 
            assert newKey instanceof Atom;
 
            Object newValue = this.stack[currentFrameCursor + 1];
            Object oldKey = this.stack[previousFrameCursor];
            if (oldKey != newKey) {
                this.stack[previousFrameCursor] = newKey;
                this.stack[previousFrameCursor + 1] = newValue;
            } else if (newValue != null) {
                this.stack[previousFrameCursor + 1] = newValue;
            }
        }
 
        this.topEntryKeyIndex = previousFrameCursor;
        this.topMarkerKeyIndex = previousMarkerIndex;
 
        assert this.validateStructure();
    }
 
    public <T> void put(Atom<T> name, @Nullable T value) {
        int valueIndex = this.valueIndex(name);
        if (valueIndex != -1) {
            this.stack[valueIndex] = value;
        } else {
            this.ensureCapacity(1);
            this.topEntryKeyIndex += 2;
            this.stack[this.topEntryKeyIndex] = name;
            this.stack[this.topEntryKeyIndex + 1] = value;
        }
 
        assert this.validateStructure();
    }
 
    public <T> @Nullable T get(Atom<T> name) {
        int valueIndex = this.valueIndex(name);
        return (T)(valueIndex != -1 ? this.stack[valueIndex] : null);
    }
 
    public <T> T getOrThrow(Atom<T> name) {
        int valueIndex = this.valueIndex(name);
        if (valueIndex == -1) {
            throw new IllegalArgumentException("No value for atom " + name);
        } else {
            return (T)this.stack[valueIndex];
        }
    }
 
    public <T> T getOrDefault(Atom<T> name, T fallback) {
        int valueIndex = this.valueIndex(name);
        return (T)(valueIndex != -1 ? this.stack[valueIndex] : fallback);
    }
 
    @SafeVarargs
    public final <T> @Nullable T getAny(Atom<? extends T>... names) {
        int valueIndex = this.valueIndexForAny(names);
        return (T)(valueIndex != -1 ? this.stack[valueIndex] : null);
    }
 
    @SafeVarargs
    public final <T> T getAnyOrThrow(Atom<? extends T>... names) {
        int valueIndex = this.valueIndexForAny(names);
        if (valueIndex == -1) {
            throw new IllegalArgumentException("No value for atoms " + Arrays.toString((Object[])names));
        } else {
            return (T)this.stack[valueIndex];
        }
    }
 
    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        boolean afterFrame = true;
 
        for (int i = 0; i <= this.topEntryKeyIndex; i += 2) {
            Object key = this.stack[i];
            Object value = this.stack[i + 1];
            if (key == FRAME_START_MARKER) {
                result.append('|');
                afterFrame = true;
            } else {
                if (!afterFrame) {
                    result.append(',');
                }
 
                afterFrame = false;
                result.append(key).append(':').append(value);
            }
        }
 
        return result.toString();
    }
 
    @VisibleForTesting
    public Map<Atom<?>, ?> lastFrame() {
        HashMap<Atom<?>, Object> result = new HashMap<>();
 
        for (int i = this.topEntryKeyIndex; i > this.topMarkerKeyIndex; i -= 2) {
            Object key = this.stack[i];
            Object value = this.stack[i + 1];
            result.put((Atom<?>)key, value);
        }
 
        return result;
    }
 
    public boolean hasOnlySingleFrame() {
        for (int i = this.topEntryKeyIndex; i > 0; i--) {
            if (this.stack[i] == FRAME_START_MARKER) {
                return false;
            }
        }
 
        if (this.stack[0] != FRAME_START_MARKER) {
            throw new IllegalStateException("Corrupted stack");
        } else {
            return true;
        }
    }
 
    private boolean validateStructure() {
        assert this.topMarkerKeyIndex >= 0;
 
        assert this.topEntryKeyIndex >= this.topMarkerKeyIndex;
 
        for (int i = 0; i <= this.topEntryKeyIndex; i += 2) {
            Object key = this.stack[i];
            if (key != FRAME_START_MARKER && !(key instanceof Atom)) {
                return false;
            }
        }
 
        for (int marker = this.topMarkerKeyIndex; marker != 0; marker = this.getPreviousMarkerIndex(marker)) {
            Object key = this.stack[marker];
            if (key != FRAME_START_MARKER) {
                return false;
            }
        }
 
        return true;
    }
}

引用的其他类

  • LoggedChatMessage

    • 引用位置: 方法调用
    • 关联成员: System.arraycopy()
  • Util

    • 引用位置: 方法调用
    • 关联成员: Util.growByHalf()
  • Atom

    • 引用位置: 参数/返回值