Skip to content

Commit f2fb40a

Browse files
committed
work on tags and comments
1 parent 63e0925 commit f2fb40a

15 files changed

Lines changed: 630 additions & 39 deletions

File tree

buildSrc/src/main/kotlin/org/spongepowered/configurate/build/Extensions.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package org.spongepowered.configurate.build
22

33
import org.gradle.api.GradleException
44
import org.gradle.api.JavaVersion
5+
import org.gradle.api.Project
56
import org.gradle.api.artifacts.Dependency
67
import org.gradle.api.artifacts.dsl.DependencyHandler
78
import org.gradle.api.artifacts.dsl.RepositoryHandler
9+
import org.gradle.api.plugins.JavaPlugin
810
import org.gradle.api.tasks.javadoc.Javadoc
911
import org.gradle.external.javadoc.StandardJavadocDocletOptions
1012
import org.gradle.kotlin.dsl.maven
@@ -49,3 +51,11 @@ fun Javadoc.applyCommonAttributes() {
4951
options.linkSource()
5052
}
5153
}
54+
55+
fun Project.useAutoValue() {
56+
val autoValueVersion = properties["autoValueVersion"]
57+
dependencies.apply {
58+
add(JavaPlugin.COMPILE_ONLY_CONFIGURATION_NAME, "com.google.auto.value:auto-value-annotations:$autoValueVersion")
59+
add(JavaPlugin.ANNOTATION_PROCESSOR_CONFIGURATION_NAME, "com.google.auto.value:auto-value:$autoValueVersion")
60+
}
61+
}

core/build.gradle.kts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
import org.spongepowered.configurate.build.useAutoValue
2+
13
plugins {
24
id("org.spongepowered.configurate.build.component")
35
}
46

7+
useAutoValue()
58
dependencies {
69
api("io.leangen.geantyref:geantyref:1.3.11")
710
compileOnlyApi("org.checkerframework:checker-qual:3.7.0")
8-
compileOnly("com.google.auto.value:auto-value-annotations:1.7.4")
9-
annotationProcessor("com.google.auto.value:auto-value:1.7.4")
1011
testImplementation("com.google.guava:guava:30.0-jre")
1112
}
1213

format/yaml/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import net.ltgt.gradle.errorprone.errorprone
22
import org.spongepowered.configurate.build.core
3+
import org.spongepowered.configurate.build.useAutoValue
34

45
plugins {
56
id("org.spongepowered.configurate.build.component")
67
}
78

9+
useAutoValue()
810
dependencies {
911
api(core())
12+
// When updating snakeyaml, check ConfigurateScanner for changes against upstream
1013
implementation("org.yaml:snakeyaml:1.27")
1114
}
1215

format/yaml/src/main/java/org/spongepowered/configurate/yaml/ConfigurateScanner.java

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,46 @@ final class ConfigurateScanner implements Scanner { // Configurate: rename + pac
238238
*/
239239
private Map<Integer, SimpleKey> possibleSimpleKeys;
240240

241+
// Configurate start -- comment capture
242+
private boolean captureComments = true;
243+
private final StringBuilder comments = new StringBuilder();
244+
245+
public String popComments() {
246+
if (this.comments.length() == 0) {
247+
return null;
248+
} else {
249+
final String ret = this.comments.toString();
250+
this.comments.delete(0, Integer.MAX_VALUE);
251+
return ret;
252+
}
253+
}
254+
255+
private void pushComment(int length) {
256+
if (!this.captureComments) {
257+
this.reader.forward(length);
258+
return;
259+
}
260+
261+
if (this.comments.length() > 0) {
262+
this.comments.append(org.spongepowered.configurate.loader.AbstractConfigurationLoader.CONFIGURATE_LINE_SEPARATOR);
263+
}
264+
final String comment = this.reader.prefixForward(length);
265+
if (comment.startsWith(" ")) {
266+
this.comments.append(comment, 1, comment.length());
267+
} else {
268+
this.comments.append(comment);
269+
}
270+
}
271+
272+
void setCaptureComments(boolean capture) {
273+
this.captureComments = capture;
274+
if (!capture && this.comments.length() > 0) {
275+
this.comments.delete(0, Integer.MAX_VALUE);
276+
}
277+
}
278+
279+
// Configurate end -- comment capture
280+
241281
public ConfigurateScanner(StreamReader reader) { // Configurate: rename
242282
this.reader = reader;
243283
this.tokens = new ArrayList<Token>(100);
@@ -1222,11 +1262,12 @@ private void scanToNextToken() {
12221262
// past the comment.
12231263
if (reader.peek() == '#') {
12241264
ff = 0;
1265+
reader.forward(); // skip comment character
12251266
while (Constant.NULL_OR_LINEBR.hasNo(reader.peek(ff))) {
12261267
ff++;
12271268
}
12281269
if (ff > 0) {
1229-
reader.forward(ff);
1270+
this.pushComment(ff); // Configurate: capture comment
12301271
}
12311272
}
12321273
// If we scanned a line break, then (depending on flow level),
@@ -1428,9 +1469,14 @@ private void scanDirectiveIgnoredLine(Mark startMark) {
14281469
reader.forward();
14291470
}
14301471
if (reader.peek() == '#') {
1472+
// Configurate start -- comments
1473+
reader.forward(); // skip '#'
1474+
int ff = 0;
14311475
while (Constant.NULL_OR_LINEBR.hasNo(reader.peek())) {
1432-
reader.forward();
1476+
ff++;
14331477
}
1478+
if (ff > 0) pushComment(ff);
1479+
// Configurate end
14341480
}
14351481
int c = reader.peek();
14361482
String lineBreak = scanLineBreak();
@@ -1743,9 +1789,15 @@ private String scanBlockScalarIgnoredLine(Mark startMark) {
17431789

17441790
// If a comment occurs, scan to just before the end of line.
17451791
if (reader.peek() == '#') {
1792+
// Configurate start -- comments
1793+
reader.forward();
1794+
1795+
int ff = 0;
17461796
while (Constant.NULL_OR_LINEBR.hasNo(reader.peek())) {
1747-
reader.forward();
1797+
ff++;
17481798
}
1799+
if (ff > 0) pushComment(ff);
1800+
// Configurate end
17491801
}
17501802
// If the next character is not a null or line break, an error has
17511803
// occurred.
@@ -2008,7 +2060,7 @@ private Token scanPlain() {
20082060
int c;
20092061
int length = 0;
20102062
// A comment indicates the end of the scalar.
2011-
if (reader.peek() == '#') {
2063+
if (reader.peek() == '#') { // Configurate: comment captured in scanToNextToken
20122064
break;
20132065
}
20142066
while (true) {
@@ -2029,7 +2081,7 @@ private Token scanPlain() {
20292081
endMark = reader.getMark();
20302082
spaces = scanPlainSpaces();
20312083
// System.out.printf("spaces[%s]\n", spaces);
2032-
if (spaces.length() == 0 || reader.peek() == '#'
2084+
if (spaces.length() == 0 || reader.peek() == '#' // Configurate: comment captured in next token
20332085
|| (this.flowLevel == 0 && this.reader.getColumn() < indent)) {
20342086
break;
20352087
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
/*
2+
* Configurate
3+
* Copyright (C) zml and Configurate contributors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.spongepowered.configurate.yaml;
18+
19+
import com.google.auto.value.AutoValue;
20+
21+
import java.lang.reflect.Type;
22+
import java.net.URI;
23+
import java.net.URISyntaxException;
24+
import java.util.regex.Pattern;
25+
26+
/**
27+
* A YAML 1.1/1.2 tag
28+
*
29+
* @apiNote Design based on §3.2.1.1 of the YAML 1.1 spec
30+
*/
31+
@AutoValue
32+
public abstract class Tag {
33+
34+
public static Tag.Builder builder() {
35+
return new AutoValue_Tag.Builder();
36+
}
37+
38+
// TODO: non-scalar tags, look into tagged unions?
39+
Tag() {}
40+
41+
/**
42+
* The canonical tag URI.
43+
*
44+
* @return tag uri, with `tag:` schema
45+
*/
46+
public abstract URI getUri();
47+
48+
/**
49+
* The native type that maps to this tag.
50+
*
51+
* @return native type for tag
52+
*/
53+
public abstract Type getNativeType();
54+
55+
/**
56+
* Pattern to test scalar values against when resolving this tag.
57+
*
58+
* @return match pattern
59+
* @apiNote See §3.3.2 of YAML 1.1 spec
60+
*/
61+
public abstract Pattern getTargetPattern();
62+
63+
/**
64+
* Whether this tag is a global tag with a full namespace or a local one.
65+
*
66+
* @return if this is a global tag
67+
*/
68+
public final boolean isGlobal() {
69+
return getUri().getScheme().equals("tag");
70+
}
71+
72+
@AutoValue.Builder
73+
public abstract static class Builder {
74+
75+
public abstract Builder setUri(URI url);
76+
77+
public final Builder setUri(final String tagUrl) {
78+
try {
79+
if (tagUrl.startsWith("!")) {
80+
return this.setUri(new URI(tagUrl.substring(1)));
81+
} else {
82+
return this.setUri(new URI(tagUrl));
83+
}
84+
} catch (final URISyntaxException e) {
85+
throw new RuntimeException(e);
86+
}
87+
}
88+
89+
public abstract Builder setNativeType(Type type);
90+
91+
public abstract Builder setTargetPattern(Pattern targetPattern);
92+
93+
public abstract Tag build();
94+
95+
}
96+
97+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* Configurate
3+
* Copyright (C) zml and Configurate contributors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.spongepowered.configurate.yaml;
18+
19+
import static io.leangen.geantyref.GenericTypeReflector.erase;
20+
21+
import org.checkerframework.checker.nullness.qual.Nullable;
22+
import org.spongepowered.configurate.util.UnmodifiableCollections;
23+
24+
import java.util.List;
25+
import java.util.Map;
26+
27+
public final class TagRepository {
28+
29+
private final List<Tag> tags;
30+
private final Map<Class<?>, Tag> byErasedType;
31+
private final Map<String, Tag> byName;
32+
33+
34+
/**
35+
* Create a new tag repository.
36+
*
37+
* @param tags known tags
38+
* @return new tag repository
39+
*/
40+
public static TagRepository of(final List<Tag> tags) {
41+
return new TagRepository(UnmodifiableCollections.copyOf(tags));
42+
}
43+
44+
TagRepository(final List<Tag> tags) {
45+
this.tags = tags;
46+
this.byErasedType = UnmodifiableCollections.buildMap(map -> {
47+
for (final Tag tag : this.tags) {
48+
map.put(erase(tag.getNativeType()), tag);
49+
}
50+
});
51+
this.byName = UnmodifiableCollections.buildMap(map -> {
52+
for (final Tag tag : this.tags) {
53+
map.put(tag.getUri().toString(), tag);
54+
}
55+
});
56+
}
57+
58+
public @Nullable Tag forInput(final String scalar) {
59+
for (final Tag tag : this.tags) {
60+
if (tag.getTargetPattern().matcher(scalar).matches()) {
61+
return tag;
62+
}
63+
}
64+
65+
return null;
66+
}
67+
68+
}

0 commit comments

Comments
 (0)