public static MarkerAnnotation createValAnnotation( AST ast, Annotation original, int start, int end) { MarkerAnnotation out = null; try { out = Reflection.markerAnnotationConstructor.newInstance(ast); } catch (InstantiationException e) { throw Lombok.sneakyThrow(e); } catch (IllegalAccessException e) { throw Lombok.sneakyThrow(e); } catch (InvocationTargetException e) { throw Lombok.sneakyThrow(e); } if (out != null) { SimpleName valName = ast.newSimpleName("val"); valName.setSourceRange(start, end - start + 1); if (original.type instanceof SingleTypeReference) { out.setTypeName(valName); setIndex(valName, 1); } else { SimpleName lombokName = ast.newSimpleName("lombok"); lombokName.setSourceRange(start, end - start + 1); setIndex(lombokName, 1); setIndex(valName, 2); QualifiedName fullName = ast.newQualifiedName(lombokName, valName); setIndex(fullName, 1); fullName.setSourceRange(start, end - start + 1); out.setTypeName(fullName); } out.setSourceRange(start, end - start + 1); } return out; }
public static ASTNode getGeneratedBy(ASTNode node) { try { return (ASTNode) generatedByField.get(node); } catch (Exception t) { throw Lombok.sneakyThrow(t); } }
static { try { generatedByField = ASTNode.class.getDeclaredField("$generatedBy"); } catch (Throwable t) { throw Lombok.sneakyThrow(t); } }
private void placePostCompileAndDontMakeForceRoundDummiesHook() { stopJavacProcessingEnvironmentFromClosingOurClassloader(); forceMultipleRoundsInNetBeansEditor(); Context context = processingEnv.getContext(); disablePartialReparseInNetBeansEditor(context); try { Method keyMethod = Context.class.getDeclaredMethod("key", Class.class); keyMethod.setAccessible(true); Object key = keyMethod.invoke(context, JavaFileManager.class); Field htField = Context.class.getDeclaredField("ht"); htField.setAccessible(true); @SuppressWarnings("unchecked") Map<Object, Object> ht = (Map<Object, Object>) htField.get(context); final JavaFileManager originalFiler = (JavaFileManager) ht.get(key); if (!(originalFiler instanceof InterceptingJavaFileManager)) { final Messager messager = processingEnv.getMessager(); DiagnosticsReceiver receiver = new MessagerDiagnosticsReceiver(messager); JavaFileManager newFiler = new InterceptingJavaFileManager(originalFiler, receiver); ht.put(key, newFiler); Field filerFileManagerField = JavacFiler.class.getDeclaredField("fileManager"); filerFileManagerField.setAccessible(true); filerFileManagerField.set(processingEnv.getFiler(), newFiler); } } catch (Exception e) { throw Lombok.sneakyThrow(e); } }
public static ASTNode setGeneratedBy(ASTNode node, ASTNode source) { try { generatedByField.set(node, source); } catch (Exception t) { throw Lombok.sneakyThrow(t); } return node; }
public static Modifier createModifier(AST ast, ModifierKeyword keyword, int start, int end) { Modifier modifier = null; try { modifier = Reflection.modifierConstructor.newInstance(ast); } catch (InstantiationException e) { throw Lombok.sneakyThrow(e); } catch (IllegalAccessException e) { throw Lombok.sneakyThrow(e); } catch (InvocationTargetException e) { throw Lombok.sneakyThrow(e); } if (modifier != null) { modifier.setKeyword(keyword); modifier.setSourceRange(start, end - start + 1); } return modifier; }
private void forceMultipleRoundsInNetBeansEditor() { try { Field f = JavacProcessingEnvironment.class.getDeclaredField("isBackgroundCompilation"); f.setAccessible(true); f.set(processingEnv, true); } catch (NoSuchFieldException e) { // only NetBeans has it } catch (Throwable t) { throw Lombok.sneakyThrow(t); } }
private void stopJavacProcessingEnvironmentFromClosingOurClassloader() { try { Field f = JavacProcessingEnvironment.class.getDeclaredField("processorClassLoader"); f.setAccessible(true); ClassLoader unwrapped = (ClassLoader) f.get(processingEnv); ClassLoader wrapped = new WrappingClassLoader(unwrapped); f.set(processingEnv, wrapped); } catch (NoSuchFieldException e) { // Some versions of javac have this (and call close on it), some don't. I guess this one // doesn't have it. } catch (Throwable t) { throw Lombok.sneakyThrow(t); } }
private void disablePartialReparseInNetBeansEditor(Context context) { try { Class<?> cancelServiceClass = Class.forName("com.sun.tools.javac.util.CancelService"); Method cancelServiceInstace = cancelServiceClass.getDeclaredMethod("instance", Context.class); Object cancelService = cancelServiceInstace.invoke(null, context); if (cancelService == null) return; Field parserField = cancelService.getClass().getDeclaredField("parser"); parserField.setAccessible(true); Object parser = parserField.get(cancelService); Field supportsReparseField = parser.getClass().getDeclaredField("supportsReparse"); supportsReparseField.setAccessible(true); supportsReparseField.set(parser, false); } catch (ClassNotFoundException e) { // only NetBeans has it } catch (NoSuchFieldException e) { // only NetBeans has it } catch (Throwable t) { throw Lombok.sneakyThrow(t); } }
public static void addFinalAndValAnnotationToModifierList( Object converter, List<IExtendedModifier> modifiers, AST ast, LocalDeclaration in) { // First check that 'in' has the final flag on, and a @val / @lombok.val annotation. if ((in.modifiers & ClassFileConstants.AccFinal) == 0) return; if (in.annotations == null) return; boolean found = false; Annotation valAnnotation = null; for (Annotation ann : in.annotations) { if (PatchVal.couldBeVal(ann.type)) { found = true; valAnnotation = ann; break; } } if (!found) return; // Now check that 'out' is missing either of these. if (modifiers == null) return; // This is null only if the project is 1.4 or less. Lombok doesn't work in that. boolean finalIsPresent = false; boolean valIsPresent = false; for (Object present : modifiers) { if (present instanceof Modifier) { ModifierKeyword keyword = ((Modifier) present).getKeyword(); if (keyword == null) continue; if (keyword.toFlagValue() == Modifier.FINAL) finalIsPresent = true; } if (present instanceof org.eclipse.jdt.core.dom.Annotation) { Name typeName = ((org.eclipse.jdt.core.dom.Annotation) present).getTypeName(); if (typeName != null) { String fullyQualifiedName = typeName.getFullyQualifiedName(); if ("val".equals(fullyQualifiedName) || "lombok.val".equals(fullyQualifiedName)) { valIsPresent = true; } } } } if (!finalIsPresent) { modifiers.add( createModifier( ast, ModifierKeyword.FINAL_KEYWORD, valAnnotation.sourceStart, valAnnotation.sourceEnd)); } if (!valIsPresent) { MarkerAnnotation newAnnotation = createValAnnotation( ast, valAnnotation, valAnnotation.sourceStart, valAnnotation.sourceEnd); try { Reflection.astConverterRecordNodes.invoke(converter, newAnnotation, valAnnotation); Reflection.astConverterRecordNodes.invoke( converter, newAnnotation.getTypeName(), valAnnotation.type); } catch (IllegalAccessException e) { throw Lombok.sneakyThrow(e); } catch (InvocationTargetException e) { throw Lombok.sneakyThrow(e.getCause()); } modifiers.add(newAnnotation); } }