From e1f82ac4d132769cfc272dccfc916aeba7181718 Mon Sep 17 00:00:00 2001 From: Reinier Zwitserloot Date: Fri, 13 Nov 2020 04:44:04 +0100 Subject: [#2645] Fixing the reading of lombok.config on sbt 1.4+ --- doc/changelog.markdown | 3 +- src/core/lombok/javac/JavacAST.java | 81 ++++++++++++++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 3 deletions(-) diff --git a/doc/changelog.markdown b/doc/changelog.markdown index 79407289..94996503 100644 --- a/doc/changelog.markdown +++ b/doc/changelog.markdown @@ -3,7 +3,8 @@ Lombok Changelog ### v1.18.17 "Edgy Guinea Pig" * BUGFIX: Netbeans would not work with 1.18.16 anymore. [Issue #2612](https://github.com/rzwitserloot/lombok/issues/2612) -* (potential) BUGFIX: Using lombok with Maven Tycho now works. With assistance from [Rabea Gransberger](https://github.com/rgra). [Issue #285](https://github.com/rzwitserloot/lombok/issues/285) +* PLATFORM: using `lombok.config` files when compiling with sbt 1.4 now works again. [Issue #2645](https://github.com/rzwitserloot/lombok/issues/2645) +* (potential) BUGFIX: Using lombok with Maven Tycho now works. With assistance from [Rabea Gransberger](https://github.com/rgra). [Issue #285](https://github.com/rzwitserloot/lombok/issues/285) __UPDATE: This doesn't quite work yet, still investigating.__ ### v1.18.16 (October 15th, 2020) * BUGFIX: Version 1.18.14 could not be installed in Eclipse, it would break Eclipse. diff --git a/src/core/lombok/javac/JavacAST.java b/src/core/lombok/javac/JavacAST.java index 22373cbe..b3e8930e 100644 --- a/src/core/lombok/javac/JavacAST.java +++ b/src/core/lombok/javac/JavacAST.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2019 The Project Lombok Authors. + * Copyright (C) 2009-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 @@ -21,6 +21,7 @@ */ package lombok.javac; +import java.io.File; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.net.URI; @@ -110,14 +111,90 @@ public class JavacAST extends AST { return memoizedAbsoluteFileLocation; } + private static Class wrappedFileObjectClass, sbtJavaFileObjectClass, sbtMappedVirtualFileClass, sbtOptionClass; + private static Field wrappedFileObjectField, sbtJavaFileObjectField, sbtMappedVirtualFilePathField, sbtMappedVirtualFileRootsField, sbtOptionField; + private static Method sbtMapGetMethod; + public static URI getAbsoluteFileLocation(JCCompilationUnit cu) { try { - return cu.sourcefile.toUri(); + URI uri = cu.sourcefile.toUri(); + String fn = uri.toString(); + if (fn.startsWith("file:")) return uri; + URI sbtUri = tryGetSbtFile(cu.sourcefile); + if (sbtUri != null) return sbtUri; + return uri; } catch (Exception e) { return null; } } + private static URI tryGetSbtFile(JavaFileObject sourcefile) { + try { + return tryGetSbtFile_(sourcefile); + } catch (Exception e) { + return null; + } + } + + private static URI tryGetSbtFile_(JavaFileObject sourcefile) throws Exception { + Class c = sourcefile.getClass(); + String cn; + + if (wrappedFileObjectClass == null) { + if (!c.getName().equals("com.sun.tools.javac.api.ClientCodeWrapper$WrappedJavaFileObject")) return null; + wrappedFileObjectClass = c; + } + if (c != wrappedFileObjectClass) return null; + + if (wrappedFileObjectField == null) wrappedFileObjectField = Permit.permissiveGetField(wrappedFileObjectClass.getSuperclass(), "clientFileObject"); + if (wrappedFileObjectField == null) return null; + Object fileObject = wrappedFileObjectField.get(sourcefile); + c = fileObject.getClass(); + + if (sbtJavaFileObjectClass == null) { + cn = c.getName(); + if (!cn.startsWith("sbt.") || !cn.endsWith("JavaFileObject")) return null; + sbtJavaFileObjectClass = c; + } + if (sbtJavaFileObjectClass != c) return null; + if (sbtJavaFileObjectField == null) sbtJavaFileObjectField = Permit.permissiveGetField(sbtJavaFileObjectClass, "underlying"); + if (sbtJavaFileObjectField == null) return null; + + Object mappedVirtualFile = sbtJavaFileObjectField.get(fileObject); + c = mappedVirtualFile.getClass(); + + if (sbtMappedVirtualFileClass == null) { + cn = c.getName(); + if (!cn.startsWith("sbt.") || !cn.endsWith("MappedVirtualFile")) return null; + sbtMappedVirtualFileClass = c; + } + if (sbtMappedVirtualFilePathField == null) sbtMappedVirtualFilePathField = Permit.permissiveGetField(sbtMappedVirtualFileClass, "encodedPath"); + if (sbtMappedVirtualFilePathField == null) return null; + if (sbtMappedVirtualFileRootsField == null) sbtMappedVirtualFileRootsField = Permit.permissiveGetField(sbtMappedVirtualFileClass, "rootPathsMap"); + if (sbtMappedVirtualFileRootsField == null) return null; + + String encodedPath = (String) sbtMappedVirtualFilePathField.get(mappedVirtualFile); + if (!encodedPath.startsWith("${")) return null; + int idx = encodedPath.indexOf('}'); + if (idx == -1) return null; + String base = encodedPath.substring(2, idx); + Object roots = sbtMappedVirtualFileRootsField.get(mappedVirtualFile); + if (sbtMapGetMethod == null) sbtMapGetMethod = Permit.getMethod(roots.getClass(), "get", Object.class); + if (sbtMapGetMethod == null) return null; + + Object option = sbtMapGetMethod.invoke(roots, base); + c = option.getClass(); + if (sbtOptionClass == null) { + if (c.getName().equals("scala.Some")) sbtOptionClass = c; + } + if (c != sbtOptionClass) return null; + if (sbtOptionField == null) sbtOptionField = Permit.permissiveGetField(sbtOptionClass, "value"); + if (sbtOptionField == null) return null; + + Object path = sbtOptionField.get(option); + return new File(path.toString() + encodedPath.substring(idx + 1)).toURI(); + } + private static String sourceName(JCCompilationUnit cu) { return cu.sourcefile == null ? null : cu.sourcefile.toString(); } -- cgit