diff options
author | Jonas Herzig <me@johni0702.de> | 2019-04-29 19:37:39 +0200 |
---|---|---|
committer | Jonas Herzig <me@johni0702.de> | 2019-04-29 19:39:47 +0200 |
commit | 626a2983f14aff02fe61231bee6d04fb47a27b44 (patch) | |
tree | 01d8f4736bf8146baeb3d6e9f2519f1d94589390 | |
parent | 0f2cc5e5ae889ede5f8079fc91ee153fa9a1d4ae (diff) | |
download | Remap-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.java | 22 |
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; |