aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/lombok/core/LombokConfiguration.java3
-rw-r--r--src/core/lombok/core/configuration/BubblingConfigurationResolver.java1
-rw-r--r--src/core/lombok/core/configuration/ConfigurationApp.java14
-rw-r--r--src/core/lombok/core/configuration/ConfigurationFile.java164
-rw-r--r--src/core/lombok/core/configuration/ConfigurationParser.java30
-rw-r--r--src/core/lombok/core/configuration/ConfigurationSource.java3
-rw-r--r--src/core/lombok/core/configuration/FileSystemSourceCache.java29
-rw-r--r--src/core/lombok/core/configuration/SingleConfigurationSource.java (renamed from src/core/lombok/core/configuration/StringConfigurationSource.java)23
8 files changed, 235 insertions, 32 deletions
diff --git a/src/core/lombok/core/LombokConfiguration.java b/src/core/lombok/core/LombokConfiguration.java
index 4a79c797..7b4cd154 100644
--- a/src/core/lombok/core/LombokConfiguration.java
+++ b/src/core/lombok/core/LombokConfiguration.java
@@ -26,6 +26,7 @@ import java.util.Collections;
import lombok.core.configuration.BubblingConfigurationResolver;
import lombok.core.configuration.ConfigurationKey;
+import lombok.core.configuration.ConfigurationParser;
import lombok.core.configuration.ConfigurationProblemReporter;
import lombok.core.configuration.ConfigurationResolver;
import lombok.core.configuration.ConfigurationResolverFactory;
@@ -74,7 +75,7 @@ public class LombokConfiguration {
private static ConfigurationResolverFactory createFileSystemBubblingResolverFactory() {
return new ConfigurationResolverFactory() {
@Override public ConfigurationResolver createResolver(URI sourceLocation) {
- return new BubblingConfigurationResolver(cache.sourcesForJavaFile(sourceLocation, ConfigurationProblemReporter.CONSOLE));
+ return new BubblingConfigurationResolver(cache.sourcesForJavaFile(sourceLocation, new ConfigurationParser(ConfigurationProblemReporter.CONSOLE)));
}
};
}
diff --git a/src/core/lombok/core/configuration/BubblingConfigurationResolver.java b/src/core/lombok/core/configuration/BubblingConfigurationResolver.java
index a5a5f1d6..20a94477 100644
--- a/src/core/lombok/core/configuration/BubblingConfigurationResolver.java
+++ b/src/core/lombok/core/configuration/BubblingConfigurationResolver.java
@@ -43,6 +43,7 @@ public class BubblingConfigurationResolver implements ConfigurationResolver {
List<List<ListModification>> listModificationsList = null;
outer:
for (ConfigurationSource source : sources) {
+ source.imports();
Result result = source.resolve(key);
if (result == null) continue;
if (isList) {
diff --git a/src/core/lombok/core/configuration/ConfigurationApp.java b/src/core/lombok/core/configuration/ConfigurationApp.java
index e3b18408..8ff2307a 100644
--- a/src/core/lombok/core/configuration/ConfigurationApp.java
+++ b/src/core/lombok/core/configuration/ConfigurationApp.java
@@ -22,6 +22,7 @@
package lombok.core.configuration;
import java.io.File;
+import java.io.IOException;
import java.io.PrintStream;
import java.net.URI;
import java.util.ArrayList;
@@ -188,6 +189,7 @@ public class ConfigurationApp extends LombokApp {
};
FileSystemSourceCache cache = new FileSystemSourceCache();
+ ConfigurationParser parser = new ConfigurationParser(reporter);
boolean first = true;
for (Entry<URI, Set<String>> entry : sharedDirectories.entrySet()) {
if (!first) {
@@ -202,7 +204,7 @@ public class ConfigurationApp extends LombokApp {
out.println();
}
URI directory = entry.getKey();
- ConfigurationResolver resolver = new BubblingConfigurationResolver(cache.sourcesForDirectory(directory, reporter));
+ ConfigurationResolver resolver = new BubblingConfigurationResolver(cache.sourcesForDirectory(directory, parser));
Map<ConfigurationKey<?>, ? extends Collection<String>> traces = trace(keys, directory);
boolean printed = false;
for (ConfigurationKey<?> key : keys) {
@@ -257,7 +259,7 @@ public class ConfigurationApp extends LombokApp {
if (!configFile.exists() || !configFile.isFile()) continue;
ConfigurationFile context = ConfigurationFile.fromFile(configFile);
- Map<ConfigurationKey<?>, List<String>> traces = trace(context.contents(), context, keys);
+ Map<ConfigurationKey<?>, List<String>> traces = trace(context, keys);
stopBubbling = stopBubbling(traces.get(ConfigurationKeys.STOP_BUBBLING));
for (ConfigurationKey<?> key : keys) {
@@ -286,10 +288,13 @@ public class ConfigurationApp extends LombokApp {
return result;
}
- private Map<ConfigurationKey<?>, List<String>> trace(String content, ConfigurationFile context, final Collection<ConfigurationKey<?>> keys) {
+ private Map<ConfigurationKey<?>, List<String>> trace(ConfigurationFile context, final Collection<ConfigurationKey<?>> keys) throws IOException {
final Map<ConfigurationKey<?>, List<String>> result = new HashMap<ConfigurationKey<?>, List<String>>();
Collector collector = new Collector() {
+ @Override public void addImport(ConfigurationFile importFile, ConfigurationFile context, int lineNumber) {
+ // TODO Trace imports
+ }
@Override public void clear(ConfigurationKey<?> key, ConfigurationFile context, int lineNumber) {
trace(key, "clear " + key.getKeyName(), lineNumber);
}
@@ -315,8 +320,9 @@ public class ConfigurationApp extends LombokApp {
}
traces.add(String.format("%4d: %s", lineNumber, message));
}
+
};
- new ConfigurationParser(VOID).parse(content, context, collector);
+ new ConfigurationParser(VOID).parse(context, collector);
return result;
}
diff --git a/src/core/lombok/core/configuration/ConfigurationFile.java b/src/core/lombok/core/configuration/ConfigurationFile.java
new file mode 100644
index 00000000..eed2e6c4
--- /dev/null
+++ b/src/core/lombok/core/configuration/ConfigurationFile.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2020 The Project Lombok Authors.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+package lombok.core.configuration;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+public abstract class ConfigurationFile {
+ private static final ThreadLocal<byte[]> buffers = new ThreadLocal<byte[]>() {
+ protected byte[] initialValue() {
+ return new byte[65536];
+ }
+ };
+
+ private final String identifier;
+
+ public static ConfigurationFile fromFile(File file) {
+ return new RegularConfigurationFile(file);
+ }
+
+ public static ConfigurationFile fromCharSequence(String identifier, CharSequence contents, long lastModified) {
+ return new CharSequenceConfigurationFile(identifier, contents, lastModified);
+ }
+
+ private ConfigurationFile(String identifier) {
+ this.identifier = identifier;
+ }
+
+ abstract long getLastModifiedOrMissing();
+ abstract boolean exists();
+ abstract CharSequence contents() throws IOException;
+ public abstract ConfigurationFile resolve(String path);
+
+ final String description() {
+ return identifier;
+ }
+
+ @Override public boolean equals(Object obj) {
+ if (!(obj instanceof ConfigurationFile)) return false;
+ return identifier.equals(((ConfigurationFile)obj).identifier);
+ }
+
+ @Override public int hashCode() {
+ return identifier.hashCode();
+ }
+
+ public static long getLastModifiedOrMissing(File file) {
+ if (!fileExists(file)) return FileSystemSourceCache.MISSING;
+ return file.lastModified();
+ }
+
+ private static boolean fileExists(File file) {
+ return file.exists() && file.isFile();
+ }
+
+ private static String read(InputStream is) throws IOException {
+ byte[] b = buffers.get();
+ try {
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ while (true) {
+ int r = is.read(b);
+ if (r == -1) break;
+ out.write(b, 0, r);
+ }
+ return new String(out.toByteArray(), "UTF-8");
+ } finally {
+ is.close();
+ }
+ }
+
+ private static class RegularConfigurationFile extends ConfigurationFile {
+ private final File file;
+
+ private RegularConfigurationFile(File file) {
+ super(file.getPath());
+ this.file = file;
+ }
+
+ @Override boolean exists() {
+ return fileExists(file);
+ }
+
+ public ConfigurationFile resolve(String path) {
+ File file = resolveFile(path);
+ return file == null ? null : fromFile(file);
+ }
+
+ private File resolveFile(String path) {
+ boolean absolute = false;
+ int colon = path.indexOf(':');
+ if (colon != -1) {
+ if (colon != 1 || path.indexOf(':', colon + 1) != -1) return null;
+ char firstCharacter = Character.toLowerCase(path.charAt(0));
+ if (firstCharacter < 'a' || firstCharacter > 'z') return null;
+ absolute = true;
+ }
+ if (path.charAt(0) == '/') absolute = true;
+ try {
+ return absolute ? new File(path) : new File(file.toURI().resolve(path));
+ } catch (Exception e) {
+ return null;
+ }
+ }
+
+ @Override
+ long getLastModifiedOrMissing() {
+ return getLastModifiedOrMissing(file);
+ }
+
+ @Override
+ CharSequence contents() throws IOException {
+ return read(new FileInputStream(file));
+ }
+ }
+
+ private static class CharSequenceConfigurationFile extends ConfigurationFile {
+ private final CharSequence contents;
+ private final long lastModified;
+
+ private CharSequenceConfigurationFile(String identifier, CharSequence contents, long lastModified) {
+ super(identifier);
+ this.contents = contents;
+ this.lastModified = lastModified;
+ }
+
+ @Override long getLastModifiedOrMissing() {
+ return lastModified;
+ }
+
+ @Override CharSequence contents() throws IOException {
+ return contents;
+ }
+
+ @Override boolean exists() {
+ return true;
+ }
+
+ @Override public ConfigurationFile resolve(String path) {
+ return null;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/core/lombok/core/configuration/ConfigurationParser.java b/src/core/lombok/core/configuration/ConfigurationParser.java
index a19e48d8..4b9846d9 100644
--- a/src/core/lombok/core/configuration/ConfigurationParser.java
+++ b/src/core/lombok/core/configuration/ConfigurationParser.java
@@ -21,6 +21,7 @@
*/
package lombok.core.configuration;
+import java.io.IOException;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -37,13 +38,17 @@ public class ConfigurationParser {
this.reporter = reporter;
}
- public void parse(CharSequence content, ConfigurationFile context, Collector collector) {
+ public void parse(ConfigurationFile context, Collector collector) {
+ CharSequence contents = contents(context);
+ if (contents == null) {
+ return;
+ }
Map<String, ConfigurationKey<?>> registeredKeys = ConfigurationKey.registeredKeys();
int lineNumber = 0;
- Matcher lineMatcher = NEWLINE_FINDER.matcher(content);
+ Matcher lineMatcher = NEWLINE_FINDER.matcher(contents);
boolean importsAllowed = true;
while (lineMatcher.find()) {
- CharSequence line = content.subSequence(lineMatcher.start(1), lineMatcher.end(1));
+ CharSequence line = contents.subSequence(lineMatcher.start(1), lineMatcher.end(1));
lineNumber++;
if (line.length() == 0 || line.charAt(0) == '#') continue;
@@ -54,9 +59,16 @@ public class ConfigurationParser {
continue;
}
String imported = importMatcher.group(1);
- if (!context.importResolves(imported)) {
+ ConfigurationFile importFile = context.resolve(imported);
+ if (importFile == null) {
+ reporter.report(context.description(), "Import is not valid", lineNumber, line);
+ continue;
+ }
+ if (!importFile.exists()) {
reporter.report(context.description(), "Imported file does not exist", lineNumber, line);
+ continue;
}
+ collector.addImport(importFile, context, lineNumber);
continue;
}
@@ -116,7 +128,17 @@ public class ConfigurationParser {
}
}
+ private CharSequence contents(ConfigurationFile context) {
+ try {
+ return context.contents();
+ } catch (IOException e) {
+ reporter.report(context.description(), "Exception while reading file: " + e.getMessage(), 0, null);
+ }
+ return null;
+ }
+
public interface Collector {
+ void addImport(ConfigurationFile importFile, ConfigurationFile context, int lineNumber);
void clear(ConfigurationKey<?> key, ConfigurationFile context, int lineNumber);
void set(ConfigurationKey<?> key, Object value, ConfigurationFile context, int lineNumber);
void add(ConfigurationKey<?> key, Object value, ConfigurationFile context, int lineNumber);
diff --git a/src/core/lombok/core/configuration/ConfigurationSource.java b/src/core/lombok/core/configuration/ConfigurationSource.java
index 1e7f9150..7fcfc0fd 100644
--- a/src/core/lombok/core/configuration/ConfigurationSource.java
+++ b/src/core/lombok/core/configuration/ConfigurationSource.java
@@ -21,9 +21,12 @@
*/
package lombok.core.configuration;
+import java.util.List;
+
public interface ConfigurationSource {
Result resolve(ConfigurationKey<?> key);
+ List<ConfigurationFile> imports();
public static final class Result {
private final Object value;
diff --git a/src/core/lombok/core/configuration/FileSystemSourceCache.java b/src/core/lombok/core/configuration/FileSystemSourceCache.java
index 0dfc54ab..e18cf9c9 100644
--- a/src/core/lombok/core/configuration/FileSystemSourceCache.java
+++ b/src/core/lombok/core/configuration/FileSystemSourceCache.java
@@ -57,7 +57,7 @@ public class FileSystemSourceCache {
}
}
- public Iterable<ConfigurationSource> sourcesForJavaFile(URI javaFile, ConfigurationProblemReporter reporter) {
+ public Iterable<ConfigurationSource> sourcesForJavaFile(URI javaFile, ConfigurationParser parser) {
if (javaFile == null) return Collections.emptyList();
cacheClear();
File dir = uriCache.get(javaFile);
@@ -86,7 +86,7 @@ public class FileSystemSourceCache {
if (dir != null) {
try {
- return sourcesForDirectory(dir, reporter);
+ return sourcesForDirectory(dir, parser);
} catch (Exception e) {
// Especially for eclipse's sake, exceptions here make eclipse borderline unusable, so let's play nice.
ProblemReporter.error("Can't resolve config stack for dir: " + dir.getAbsolutePath(), e);
@@ -96,11 +96,11 @@ public class FileSystemSourceCache {
return Collections.emptyList();
}
- public Iterable<ConfigurationSource> sourcesForDirectory(URI directory, ConfigurationProblemReporter reporter) {
- return sourcesForJavaFile(directory, reporter);
+ public Iterable<ConfigurationSource> sourcesForDirectory(URI directory, ConfigurationParser parser) {
+ return sourcesForJavaFile(directory, parser);
}
- private Iterable<ConfigurationSource> sourcesForDirectory(final File directory, final ConfigurationProblemReporter reporter) {
+ private Iterable<ConfigurationSource> sourcesForDirectory(final File directory, final ConfigurationParser parser) {
return new Iterable<ConfigurationSource>() {
@Override
public Iterator<ConfigurationSource> iterator() {
@@ -127,7 +127,7 @@ public class FileSystemSourceCache {
private ConfigurationSource findNext() {
while (currentDirectory != null && next == null) {
- next = getSourceForDirectory(currentDirectory, reporter);
+ next = getSourceForDirectory(currentDirectory, parser);
currentDirectory = currentDirectory.getParentFile();
}
if (next != null) {
@@ -146,11 +146,11 @@ public class FileSystemSourceCache {
};
}
- ConfigurationSource getSourceForDirectory(File directory, ConfigurationProblemReporter reporter) {
- return getSourceForConfigFile(ConfigurationFile.fromFile(new File(directory, LOMBOK_CONFIG_FILENAME)), reporter);
+ ConfigurationSource getSourceForDirectory(File directory,ConfigurationParser parser) {
+ return getSourceForConfigFile(ConfigurationFile.fromFile(new File(directory, LOMBOK_CONFIG_FILENAME)), parser);
}
- private ConfigurationSource getSourceForConfigFile(ConfigurationFile context, ConfigurationProblemReporter reporter) {
+ private ConfigurationSource getSourceForConfigFile(ConfigurationFile context, ConfigurationParser parser) {
long now = System.currentTimeMillis();
Content content = ensureContent(context);
synchronized (content) {
@@ -160,7 +160,7 @@ public class FileSystemSourceCache {
content.lastChecked = now;
long previouslyModified = content.lastModified;
content.lastModified = context.getLastModifiedOrMissing();
- if (content.lastModified != previouslyModified) content.source = content.lastModified == MISSING ? null : parse(context, reporter);
+ if (content.lastModified != previouslyModified) content.source = content.lastModified == MISSING ? null : parse(context, parser);
return content.source;
}
}
@@ -174,13 +174,8 @@ public class FileSystemSourceCache {
return fileCache.get(context);
}
- private ConfigurationSource parse(ConfigurationFile context, ConfigurationProblemReporter reporter) {
- try {
- return StringConfigurationSource.forString(context.contents(), reporter, context);
- } catch (Exception e) {
- reporter.report(context.description(), "Exception while reading file: " + e.getMessage(), 0, null);
- return null;
- }
+ private ConfigurationSource parse(ConfigurationFile context, ConfigurationParser parser) {
+ return SingleConfigurationSource.parse(context, parser);
}
private static class Content {
diff --git a/src/core/lombok/core/configuration/StringConfigurationSource.java b/src/core/lombok/core/configuration/SingleConfigurationSource.java
index c1bd498e..a5298339 100644
--- a/src/core/lombok/core/configuration/StringConfigurationSource.java
+++ b/src/core/lombok/core/configuration/SingleConfigurationSource.java
@@ -30,13 +30,18 @@ import java.util.Map.Entry;
import lombok.core.configuration.ConfigurationParser.Collector;
-public class StringConfigurationSource implements ConfigurationSource {
+public final class SingleConfigurationSource implements ConfigurationSource {
private final Map<ConfigurationKey<?>, Result> values;
+ private final List<ConfigurationFile> imports;
- public static ConfigurationSource forString(CharSequence content, ConfigurationProblemReporter reporter, ConfigurationFile context) {
+ public static ConfigurationSource parse(ConfigurationFile context, ConfigurationParser parser) {
final Map<ConfigurationKey<?>, Result> values = new HashMap<ConfigurationKey<?>, Result>();
-
+ final List<ConfigurationFile> imports = new ArrayList<ConfigurationFile>();
Collector collector = new Collector() {
+ @Override public void addImport(ConfigurationFile importFile, ConfigurationFile context, int lineNumber) {
+ imports.add(importFile);
+ }
+
@Override public void clear(ConfigurationKey<?> key, ConfigurationFile context, int lineNumber) {
values.put(key, new Result(null, true));
}
@@ -66,11 +71,11 @@ public class StringConfigurationSource implements ConfigurationSource {
list.add(new ListModification(value, add));
}
};
- new ConfigurationParser(reporter).parse(content, context, collector);
- return new StringConfigurationSource(values);
+ parser.parse(context, collector);
+ return new SingleConfigurationSource(values, imports);
}
- private StringConfigurationSource(Map<ConfigurationKey<?>, Result> values) {
+ private SingleConfigurationSource(Map<ConfigurationKey<?>, Result> values, List<ConfigurationFile> imports) {
this.values = new HashMap<ConfigurationKey<?>, Result>();
for (Entry<ConfigurationKey<?>, Result> entry : values.entrySet()) {
Result result = entry.getValue();
@@ -80,10 +85,16 @@ public class StringConfigurationSource implements ConfigurationSource {
this.values.put(entry.getKey(), result);
}
}
+ this.imports = Collections.unmodifiableList(imports);
}
@Override
public Result resolve(ConfigurationKey<?> key) {
return values.get(key);
}
+
+ @Override
+ public List<ConfigurationFile> imports() {
+ return imports;
+ }
}