aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Herzig <me@johni0702.de>2019-04-29 19:37:39 +0200
committerJonas Herzig <me@johni0702.de>2019-04-29 19:39:47 +0200
commit626a2983f14aff02fe61231bee6d04fb47a27b44 (patch)
tree01d8f4736bf8146baeb3d6e9f2519f1d94589390
parent0f2cc5e5ae889ede5f8079fc91ee153fa9a1d4ae (diff)
downloadRemap-626a2983f14aff02fe61231bee6d04fb47a27b44.tar.gz
Remap-626a2983f14aff02fe61231bee6d04fb47a27b44.tar.bz2
Remap-626a2983f14aff02fe61231bee6d04fb47a27b44.zip
Prevent local variables from shadowing of implicit member references
E.g. `Entity#posX` is remapped to `x` which may then be shadowed by a local variable with the same name. Since I cannot figure out how to get JDT to give me a list of all variables in scope at a particular node, the solution employed is to just forbid any implicit references to remapped members. This finds quite a few false positives (but not too many to manually deal with), so I'd be quite happy to switch to another solution if one becomes available.
-rw-r--r--src/main/java/com/replaymod/gradle/remap/Transformer.java22
1 files changed, 20 insertions, 2 deletions
diff --git a/src/main/java/com/replaymod/gradle/remap/Transformer.java b/src/main/java/com/replaymod/gradle/remap/Transformer.java
index 02075bc..0cb9afe 100644
--- a/src/main/java/com/replaymod/gradle/remap/Transformer.java
+++ b/src/main/java/com/replaymod/gradle/remap/Transformer.java
@@ -28,6 +28,7 @@ import java.util.stream.Collectors;
class Transformer {
private Map<String, Mapping> map;
private String[] classpath;
+ private boolean fail;
public static void main(String[] args) throws IOException, BadLocationException {
Map<String, Mapping> mappings;
@@ -72,6 +73,10 @@ class Transformer {
System.out.println(line);
}
}
+
+ if (transformer.fail) {
+ System.exit(1);
+ }
}
public Transformer(Map<String, Mapping> mappings) {
@@ -135,7 +140,7 @@ class Transformer {
CompilationUnit cu = entry.getValue();
cu.recordModifications();
- if (remapClass(cu)) {
+ if (remapClass(unitName, cu)) {
Document document = new Document(sources.get(unitName));
TextEdit edit = cu.rewrite(document, JavaCore.getDefaultOptions());
edit.apply(document);
@@ -372,7 +377,7 @@ class Transformer {
return paramIndex != -1 ? name.substring(0, paramIndex) : name;
}
- private boolean remapClass(CompilationUnit cu) {
+ private boolean remapClass(String unitName, CompilationUnit cu) {
AtomicBoolean changed = new AtomicBoolean(false);
Map<String, String> mappedImports = new HashMap<>();
Map<String, Mapping> mixinMappings = new HashMap<>();
@@ -484,6 +489,19 @@ class Transformer {
}
if (mapping == null) return true;
mapped = mapping.fields.get(node.getIdentifier());
+ if (mapped != null) {
+ ASTNode parent = node.getParent();
+ if (!(parent instanceof FieldAccess // qualified access is fine
+ || parent instanceof QualifiedName // qualified access is fine
+ || parent instanceof VariableDeclarationFragment // shadow member declarations are fine
+ || parent instanceof SwitchCase) // referencing constants in case statements is fine
+ ) {
+ System.err.println(unitName + ": Implicit member reference to remapped field \"" + node.getIdentifier() + "\". " +
+ "This can cause issues if the remapped reference becomes shadowed by a local variable and is therefore forbidden. " +
+ "Use \"this." + node.getIdentifier() + "\" instead.");
+ fail = true;
+ }
+ }
} else if (binding instanceof IMethodBinding) {
ITypeBinding declaringClass = ((IMethodBinding) binding).getDeclaringClass();
if (declaringClass == null) return true;