From 6782aceeb0bc082357bbd3ff20b166c379afb380 Mon Sep 17 00:00:00 2001 From: Rawi01 Date: Tue, 2 Feb 2021 09:15:31 +0100 Subject: Validate that every AST node has a symbol --- test/core/src/lombok/RunTestsViaDelombok.java | 62 +++++++++++++++++++++++++-- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/test/core/src/lombok/RunTestsViaDelombok.java b/test/core/src/lombok/RunTestsViaDelombok.java index 433d8b07..59287f30 100644 --- a/test/core/src/lombok/RunTestsViaDelombok.java +++ b/test/core/src/lombok/RunTestsViaDelombok.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2014 The Project Lombok Authors. + * Copyright (C) 2009-2021 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 @@ -33,31 +33,35 @@ import java.util.Collections; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.Stack; import javax.annotation.processing.AbstractProcessor; import javax.annotation.processing.ProcessingEnvironment; import javax.annotation.processing.RoundEnvironment; import javax.lang.model.SourceVersion; import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; import javax.lang.model.element.TypeElement; import com.sun.source.util.TreePath; import com.sun.source.util.Trees; import com.sun.tools.javac.code.Flags; +import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.tree.JCTree; -import com.sun.tools.javac.tree.TreeScanner; import com.sun.tools.javac.tree.JCTree.JCAnnotation; import com.sun.tools.javac.tree.JCTree.JCAssign; +import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; import com.sun.tools.javac.tree.JCTree.JCIdent; import com.sun.tools.javac.tree.JCTree.JCMethodDecl; import com.sun.tools.javac.tree.JCTree.JCModifiers; import com.sun.tools.javac.tree.JCTree.JCVariableDecl; +import com.sun.tools.javac.tree.TreeScanner; import lombok.delombok.Delombok; import lombok.javac.CapturingDiagnosticListener; -import lombok.javac.Javac; import lombok.javac.CapturingDiagnosticListener.CompilerMessage; +import lombok.javac.Javac; public class RunTestsViaDelombok extends AbstractRunTests { private Delombok delombok = new Delombok(); @@ -74,6 +78,7 @@ public class RunTestsViaDelombok extends AbstractRunTests { delombok.setDiagnosticsListener(new CapturingDiagnosticListener(file, messages)); delombok.addAdditionalAnnotationProcessor(new ValidatePositionProcessor()); + delombok.addAdditionalAnnotationProcessor(new ValidateTypesProcessor()); delombok.addFile(file.getAbsoluteFile().getParentFile(), file.getName()); delombok.setSourcepath(file.getAbsoluteFile().getParent()); @@ -132,6 +137,57 @@ public class RunTestsViaDelombok extends AbstractRunTests { } } + public static class ValidateTypesProcessor extends TreeProcessor { + @Override void processCompilationUnit(final JCCompilationUnit unit) { + final Stack parents = new Stack(); + parents.add(unit); + + unit.accept(new TreeScanner() { + private JCTree parent; + @Override public void scan(JCTree tree) { + parent = parents.peek(); + + parents.push(tree); + super.scan(tree); + parents.pop(); + } + + @Override public void visitClassDef(JCClassDecl tree) { + // Skip anonymous or local classes, they have no symbol + if (!(parent instanceof JCClassDecl || parent instanceof JCCompilationUnit)) return; + + validateSymbol(tree, tree.sym); + super.visitClassDef(tree); + }; + + @Override public void visitMethodDef(JCMethodDecl tree) { + validateSymbol(tree, tree.sym); + super.visitMethodDef(tree); + } + + @Override public void visitVarDef(JCVariableDecl tree) { + // Skip non-field variables + if (!(parent instanceof JCClassDecl)) return; + + validateSymbol(tree, tree.sym); + super.visitVarDef(tree); + } + + private void validateSymbol(JCTree tree, Symbol sym) { + if (sym == null) { + fail("Missing symbol for " + tree); + } + // Skip top level classes + if (sym.owner.getKind() == ElementKind.PACKAGE) return; + + if (!sym.owner.getEnclosedElements().contains(sym)) { + fail(tree + " not added to parent"); + } + } + }); + } + } + public static abstract class TreeProcessor extends AbstractProcessor { private Trees trees; @Override public synchronized void init(ProcessingEnvironment processingEnv) { -- cgit