Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace DocumentParser impl with a real parser #162

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,9 @@ publishing {
}
}

checkstyle {
toolVersion = "10.12.4"
}

dependencies {
implementation "org.eclipse.lsp4j:org.eclipse.lsp4j:0.23.1"
Expand All @@ -153,6 +156,8 @@ dependencies {
testImplementation "org.hamcrest:hamcrest:2.2"

testRuntimeOnly "org.junit.platform:junit-platform-launcher"

checkstyle "com.puppycrawl.tools:checkstyle:${checkstyle.toolVersion}"
}

tasks.withType(Javadoc).all {
Expand Down
286 changes: 157 additions & 129 deletions src/main/java/software/amazon/smithy/lsp/SmithyLanguageServer.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,12 @@

package software.amazon.smithy.lsp.codeactions;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.Position;
import org.eclipse.lsp4j.Range;
import org.eclipse.lsp4j.TextEdit;
import org.eclipse.lsp4j.WorkspaceEdit;
import software.amazon.smithy.lsp.protocol.LspAdapter;

public final class DefineVersionCodeAction {
private static final int DEFAULT_VERSION = 1;
Expand All @@ -42,10 +40,9 @@ public static CodeAction build(String fileUri) {
codeAction.setKind(SmithyCodeActions.SMITHY_DEFINE_VERSION);
WorkspaceEdit wEdit = new WorkspaceEdit();
TextEdit edit = new TextEdit(
new Range(new Position(0, 0), new Position(0, 0)),
"$version: \"" + DEFAULT_VERSION + "\"\n\n"
);
Map<String, List<TextEdit>> changes = Collections.singletonMap(fileUri, Collections.singletonList(edit));
LspAdapter.origin(),
String.format("$version: \"%s\"%n%n", DEFAULT_VERSION));
Map<String, List<TextEdit>> changes = Map.of(fileUri, List.of(edit));
wEdit.setChanges(changes);
codeAction.setEdit(wEdit);
return codeAction;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,8 @@ public static List<CodeAction> versionCodeActions(CodeActionParams params) {
}
Optional<Diagnostic> updateVersionDiagnostic = params.getContext().getDiagnostics().stream()
.filter(diagnosticCodePredicate(SmithyDiagnostics.UPDATE_VERSION)).findFirst();
if (updateVersionDiagnostic.isPresent()) {
actions.add(
UpdateVersionCodeAction.build(fileUri, updateVersionDiagnostic.get().getRange())
);
}
updateVersionDiagnostic.ifPresent(diagnostic -> actions.add(
UpdateVersionCodeAction.build(fileUri, diagnostic.getRange())));

return actions;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@

package software.amazon.smithy.lsp.codeactions;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.eclipse.lsp4j.CodeAction;
Expand All @@ -41,7 +40,7 @@ public static CodeAction build(String fileUri, Range versionStatementRange) {
codeAction.setKind(SmithyCodeActions.SMITHY_UPDATE_VERSION);
WorkspaceEdit wEdit = new WorkspaceEdit();
TextEdit edit = new TextEdit(versionStatementRange, "$version: \"" + LATEST_VERSION + "\"");
Map<String, List<TextEdit>> changes = Collections.singletonMap(fileUri, Collections.singletonList(edit));
Map<String, List<TextEdit>> changes = Map.of(fileUri, List.of(edit));
wEdit.setChanges(changes);
codeAction.setEdit(wEdit);
return codeAction;
Expand Down
79 changes: 64 additions & 15 deletions src/main/java/software/amazon/smithy/lsp/document/Document.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,12 @@
public final class Document {
private final StringBuilder buffer;
private int[] lineIndices;
private int changeVersion;

private Document(StringBuilder buffer, int[] lineIndices) {
private Document(StringBuilder buffer, int[] lineIndices, int changeVersion) {
this.buffer = buffer;
this.lineIndices = lineIndices;
this.changeVersion = changeVersion;
}

/**
Expand All @@ -36,14 +38,14 @@ private Document(StringBuilder buffer, int[] lineIndices) {
public static Document of(String string) {
StringBuilder buffer = new StringBuilder(string);
int[] lineIndicies = computeLineIndicies(buffer);
return new Document(buffer, lineIndicies);
return new Document(buffer, lineIndicies, 0);
}

/**
* @return A copy of this document
*/
public Document copy() {
return new Document(new StringBuilder(copyText()), lineIndices.clone());
return new Document(new StringBuilder(copyText()), lineIndices.clone(), changeVersion);
}

/**
Expand Down Expand Up @@ -72,6 +74,14 @@ public void applyEdit(Range range, String text) {
this.lineIndices = computeLineIndicies(buffer);
}

public int changeVersion() {
return changeVersion;
}

public void bumpVersion(int to) {
changeVersion = to;
}

/**
* @return The range of the document, from (0, 0) to {@link #end()}
*/
Expand All @@ -97,20 +107,31 @@ public int indexOfLine(int line) {
* doesn't exist
*/
public int lineOfIndex(int idx) {
// TODO: Use binary search or similar
if (idx >= length() || idx < 0) {
return -1;
}

for (int line = 0; line <= lastLine() - 1; line++) {
int currentLineIdx = indexOfLine(line);
int nextLineIdx = indexOfLine(line + 1);
if (idx >= currentLineIdx && idx < nextLineIdx) {
return line;
int low = 0;
int up = lastLine();

while (low <= up) {
int mid = (low + up) / 2;
int midLineIdx = lineIndices[mid];
int midLineEndIdx = lineEndUnchecked(mid);
if (idx >= midLineIdx && idx <= midLineEndIdx) {
return mid;
} else if (idx < midLineIdx) {
up = mid - 1;
} else {
low = mid + 1;
}
}

return lastLine();
return -1;
}

private int lineEndUnchecked(int line) {
if (line == lastLine()) {
return length() - 1;
} else {
return lineIndices[line + 1] - 1;
}
}

/**
Expand Down Expand Up @@ -167,6 +188,34 @@ public Position positionAtIndex(int index) {
return new Position(line, character);
}

/**
* @param start The start character offset
* @param end The end character offset
* @return The range between the two given offsets
*/
public Range rangeBetween(int start, int end) {
if (end < start || start < 0) {
return null;
}

// The start is inclusive, so it should be within the bounds of the document
Position startPos = positionAtIndex(start);
if (startPos == null) {
return null;
}

Position endPos;
if (end == length()) {
int lastLine = lastLine();
int lastCol = length() - lineIndices[lastLine];
endPos = new Position(lastLine, lastCol);
} else {
endPos = positionAtIndex(end);
}

return new Range(startPos, endPos);
}

/**
* @param line The line to find the end of
* @return The index of the end of the given line, or {@code -1} if the
Expand Down Expand Up @@ -322,7 +371,7 @@ public CharBuffer borrowId(Position position) {
if (id == null) {
return null;
}
return id.borrowIdValue();
return id.idSlice();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* inaccurate in the sense that the string value it references isn't
* necessarily a valid identifier, it just looks like an identifier.
*/
public final class DocumentId {
public record DocumentId(Type type, CharBuffer idSlice, Range range) {
/**
* Represents the different kinds of identifiers that can be used to match.
*/
Expand Down Expand Up @@ -41,32 +41,10 @@ public enum Type {
/**
* Same as {@link Type#ID}, but with a member - will have a {@code $}.
*/
RELATIVE_WITH_MEMBER;
}

private final Type type;
private final CharBuffer buffer;
private final Range range;

DocumentId(Type type, CharBuffer buffer, Range range) {
this.type = type;
this.buffer = buffer;
this.range = range;
}

public Type type() {
return type;
RELATIVE_WITH_MEMBER
}

public String copyIdValue() {
return buffer.toString();
}

public CharBuffer borrowIdValue() {
return buffer;
}

public Range range() {
return range;
return idSlice.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,28 +10,8 @@

/**
* The imports of a document, including the range they occupy.
*
* @param importsRange The range of the imports
* @param imports The set of imported shape ids. They are not guaranteed to be valid shape ids
*/
public final class DocumentImports {
private final Range importsRange;
private final Set<String> imports;

DocumentImports(Range importsRange, Set<String> imports) {
this.importsRange = importsRange;
this.imports = imports;
}

/**
* @return The range of the imports
*/
public Range importsRange() {
return importsRange;
}

/**
* @return The set of imported shape ids. They are not guaranteed
* to be valid shape ids
*/
public Set<String> imports() {
return imports;
}
}
public record DocumentImports(Range importsRange, Set<String> imports) {}
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,8 @@

/**
* The namespace of the document, including the range it occupies.
*
* @param statementRange The range of the statement, including {@code namespace}
* @param namespace The namespace of the document. Not guaranteed to be a valid namespace
*/
public final class DocumentNamespace {
private final Range statementRange;
private final CharSequence namespace;

DocumentNamespace(Range statementRange, CharSequence namespace) {
this.statementRange = statementRange;
this.namespace = namespace;
}

/**
* @return The range of the statement, including {@code namespace}
*/
public Range statementRange() {
return statementRange;
}

/**
* @return The namespace of the document. Not guaranteed to be
* a valid namespace
*/
public CharSequence namespace() {
return namespace;
}
}
public record DocumentNamespace(Range statementRange, CharSequence namespace) {}
Loading
Loading