Improve Parser implementation (#1508)

- Make leaf AST classes final
- Make protected Lexer fields private and add getter
- Split Parser into Parser and ParserImpl
- Using a fresh ParserImpl instance per parse simplifies reasoning
(important) and makes the Parser API thread-safe (nice to have)
- Split GenericParser into GenericParser and GenericParserImpl
  - Same motivation as for Parser

Some of these changes will facilitate the move to JSpecify, which has
proven challenging for this package.
This commit is contained in:
odenix
2026-04-08 08:13:39 -07:00
committed by GitHub
parent e793f4bd04
commit 24e69fd1e2
20 changed files with 3486 additions and 3429 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@ package org.pkl.parser;
import org.pkl.parser.syntax.generic.FullSpan;
public class GenericParserError extends RuntimeException {
public final class GenericParserError extends RuntimeException {
private final FullSpan span;
public GenericParserError(String msg, FullSpan span) {

File diff suppressed because it is too large Load Diff

View File

@@ -20,12 +20,12 @@ import java.util.Deque;
import org.pkl.parser.syntax.generic.FullSpan;
import org.pkl.parser.util.ErrorMessages;
public class Lexer {
public final class Lexer {
private final char[] source;
private final int size;
protected int cursor = 0;
protected int sCursor = 0;
private int cursor = 0;
private int sCursor = 0;
private int line = 1;
private int sLine = 1;
private int col = 1;
@@ -36,7 +36,7 @@ public class Lexer {
private boolean stringEnded = false;
private boolean isEscape = false;
// how many newlines exist between two subsequent tokens
protected int newLinesBetween = 0;
private int newLinesBetween = 0;
private static final int EOF = -1;
@@ -73,6 +73,10 @@ public class Lexer {
return cursor;
}
public int getNewLinesBetween() {
return newLinesBetween;
}
public char[] getSource() {
return source;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package org.pkl.parser;
import org.pkl.parser.syntax.Module;
import org.pkl.parser.util.Nullable;
public class ParserError extends RuntimeException {
public final class ParserError extends RuntimeException {
private final Span span;
private @Nullable Module partialParseResult;

File diff suppressed because it is too large Load Diff

View File

@@ -20,7 +20,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class Annotation extends AbstractNode {
public final class Annotation extends AbstractNode {
public Annotation(List<Node> nodes, Span span) {
super(span, nodes);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class ArgumentList extends AbstractNode {
public final class ArgumentList extends AbstractNode {
public ArgumentList(List<Expr> arguments, Span span) {
super(span, arguments);

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,7 +21,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class ClassBody extends AbstractNode {
public final class ClassBody extends AbstractNode {
public ClassBody(List<Node> nodes, Span span) {
super(span, nodes);

View File

@@ -20,7 +20,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class ClassMethod extends AbstractNode {
public final class ClassMethod extends AbstractNode {
private final int modifiersOffset;
private final int nameOffset;
private final Span headerSpan;

View File

@@ -21,7 +21,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class ExtendsOrAmendsClause extends AbstractNode {
public final class ExtendsOrAmendsClause extends AbstractNode {
private final Type type;
public ExtendsOrAmendsClause(StringConstant url, Type type, Span span) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package org.pkl.parser.syntax;
import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
public class Keyword extends AbstractNode {
public final class Keyword extends AbstractNode {
public Keyword(Span span) {
super(span, null);

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class ParameterList extends AbstractNode {
public final class ParameterList extends AbstractNode {
public ParameterList(List<Parameter> parameters, Span span) {
super(span, parameters);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class ReplInput extends AbstractNode {
public final class ReplInput extends AbstractNode {
public ReplInput(List<Node> nodes, Span span) {
super(span, nodes);
}

View File

@@ -20,7 +20,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class StringConstant extends AbstractNode {
public final class StringConstant extends AbstractNode {
private final String string;
public StringConstant(String string, Span span) {

View File

@@ -20,7 +20,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class TypeAnnotation extends AbstractNode {
public final class TypeAnnotation extends AbstractNode {
public TypeAnnotation(Type type, Span span) {
super(span, List.of(type));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ import java.util.List;
import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
public class TypeArgumentList extends AbstractNode {
public final class TypeArgumentList extends AbstractNode {
public TypeArgumentList(List<Type> children, Span span) {
super(span, children);

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import org.pkl.parser.ParserVisitor;
import org.pkl.parser.Span;
import org.pkl.parser.util.Nullable;
public class TypeParameterList extends AbstractNode {
public final class TypeParameterList extends AbstractNode {
public TypeParameterList(List<TypeParameter> parameters, Span span) {
super(span, parameters);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright © 2025 Apple Inc. and the Pkl project authors. All rights reserved.
* Copyright © 2025-2026 Apple Inc. and the Pkl project authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,7 +20,7 @@ import java.util.List;
import java.util.Objects;
import org.pkl.parser.util.Nullable;
public class Node {
public final class Node {
public final List<Node> children;
public final FullSpan span;
public final NodeType type;