From b3824c9dc1861c0ce6acdf48049e6552d808e448 Mon Sep 17 00:00:00 2001
From: Reinier Zwitserloot <r.zwitserloot@projectlombok.org>
Date: Mon, 15 Jul 2019 22:15:15 +0200
Subject: [fixes #2169] Eclipse 2019-06 + JDK12 + `@Singular` caused a
 cavalcade of error popups

---
 doc/changelog.markdown                             |  1 +
 .../singulars/EclipseJavaUtilListSingularizer.java |  7 +++----
 .../singulars/EclipseJavaUtilSingularizer.java     |  8 ++++----
 src/utils/lombok/eclipse/Eclipse.java              | 24 +++++++++++++++++++++-
 4 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/doc/changelog.markdown b/doc/changelog.markdown
index e486a713..e4323cd3 100644
--- a/doc/changelog.markdown
+++ b/doc/changelog.markdown
@@ -9,6 +9,7 @@ Lombok Changelog
 * ENHANCEMENT: If you mix up eclipse's non-null support, such as `@NonNullByDefault`, with lombok's `@NonNull`, you get a bunch of warnings about dead code that are inappropriate. These warnings are now suppressed, thanks to a contribution from Till Brychcy! [Pull Request #2155](https://github.com/rzwitserloot/lombok/pull/2155)
 * BUGFIX: Delombok would turn something like `List<byte[]>...` in a method parameter to `List<byte...>...` [Issue #2140](https://github.com/rzwitserloot/lombok/issues/2140)
 * BUGFIX: Javac would generate the wrong equals and hashCode if a type-use annotation was put on an array type field [Issue #2165](https://github.com/rzwitserloot/lombok/issues/2165)
+* BUGFIX: Eclipse 2019-06 + JDK-12 compatibility + an `@Singular` builder entry would produce a cascade of error dialogs. [Issue #2169](https://github.com/rzwitserloot/lombok/issues/2169)
 * IMPROBABLE BREAKING CHANGE: Stricter validation of configuration keys dealing with identifiers and types (`lombok.log.fieldName`, `lombok.fieldNameConstants.innerTypeName`, `lombok.copyableAnnotations`).
 >>>>>>> customlog
 
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java
index 7ea04821..bf50aef6 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilListSingularizer.java
@@ -35,7 +35,6 @@ import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
 import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
 import org.eclipse.jdt.internal.compiler.ast.Assignment;
 import org.eclipse.jdt.internal.compiler.ast.BreakStatement;
-import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
 import org.eclipse.jdt.internal.compiler.ast.Expression;
 import org.eclipse.jdt.internal.compiler.ast.FieldReference;
 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
@@ -74,7 +73,7 @@ public class EclipseJavaUtilListSingularizer extends EclipseJavaUtilListSetSingu
 		List<Statement> switchContents = new ArrayList<Statement>();
 		
 		/* case 0: (empty) break; */ {
-			switchContents.add(new CaseStatement(makeIntLiteral(new char[] {'0'}, null), 0, 0));
+			switchContents.add(Eclipse.createCaseStatement(makeIntLiteral(new char[] {'0'}, null)));
 			MessageSend invoke = new MessageSend();
 			invoke.receiver = new QualifiedNameReference(JAVA_UTIL_COLLECTIONS, NULL_POSS, 0, 0);
 			invoke.selector = "emptyList".toCharArray();
@@ -83,7 +82,7 @@ public class EclipseJavaUtilListSingularizer extends EclipseJavaUtilListSetSingu
 		}
 		
 		/* case 1: (singleton) break; */ {
-			switchContents.add(new CaseStatement(makeIntLiteral(new char[] {'1'}, null), 0, 0));
+			switchContents.add(Eclipse.createCaseStatement(makeIntLiteral(new char[] {'1'}, null)));
 			FieldReference thisDotField = new FieldReference(data.getPluralName(), 0L);
 			thisDotField.receiver = getBuilderReference(builderVariable);
 			MessageSend thisDotFieldGet0 = new MessageSend();
@@ -101,7 +100,7 @@ public class EclipseJavaUtilListSingularizer extends EclipseJavaUtilListSetSingu
 		}
 		
 		/* default: Create by passing builder field to constructor. */ {
-			switchContents.add(new CaseStatement(null, 0, 0));
+			switchContents.add(Eclipse.createCaseStatement(null));
 			
 			Expression argToUnmodifiable;
 			/* new j.u.ArrayList<Generics>(this.pluralName); */ {
diff --git a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSingularizer.java b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSingularizer.java
index 8aeffc48..4a143a06 100755
--- a/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSingularizer.java
+++ b/src/core/lombok/eclipse/handlers/singulars/EclipseJavaUtilSingularizer.java
@@ -34,7 +34,6 @@ import org.eclipse.jdt.internal.compiler.ast.Assignment;
 import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
 import org.eclipse.jdt.internal.compiler.ast.Block;
 import org.eclipse.jdt.internal.compiler.ast.BreakStatement;
-import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
 import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
 import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
 import org.eclipse.jdt.internal.compiler.ast.Expression;
@@ -58,6 +57,7 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeConstants;
 import org.eclipse.jdt.internal.compiler.lookup.TypeIds;
 
 import lombok.ConfigurationKeys;
+import lombok.eclipse.Eclipse;
 import lombok.eclipse.EclipseNode;
 import lombok.eclipse.handlers.EclipseSingularsRecipes.EclipseSingularizer;
 import lombok.eclipse.handlers.EclipseSingularsRecipes.SingularData;
@@ -95,7 +95,7 @@ abstract class EclipseJavaUtilSingularizer extends EclipseSingularizer {
 		char[] keyName = mapMode ? (new String(data.getPluralName()) + "$key").toCharArray() : data.getPluralName();
 		
 		if (emptyCollectionMethod != null) { // case 0: (empty); break;
-			switchContents.add(new CaseStatement(makeIntLiteral(new char[] {'0'}, null), 0, 0));
+			switchContents.add(Eclipse.createCaseStatement(makeIntLiteral(new char[] {'0'}, null)));
 			
 			/* pluralName = java.util.Collections.emptyCollectionMethod(); */ {
 				MessageSend invoke = new MessageSend();
@@ -108,7 +108,7 @@ abstract class EclipseJavaUtilSingularizer extends EclipseSingularizer {
 		}
 		
 		if (singletonCollectionMethod != null) { // case 1: (singleton); break;
-			switchContents.add(new CaseStatement(makeIntLiteral(new char[] {'1'}, null), 0, 0));
+			switchContents.add(Eclipse.createCaseStatement(makeIntLiteral(new char[] {'1'}, null)));
 			/* !mapMode: pluralName = java.util.Collections.singletonCollectionMethod(this.pluralName.get(0));
 			   mapMode: pluralName = java.util.Collections.singletonCollectionMethod(this.pluralName$key.get(0), this.pluralName$value.get(0)); */ {
 				FieldReference thisDotKey = new FieldReference(keyName, 0L);
@@ -142,7 +142,7 @@ abstract class EclipseJavaUtilSingularizer extends EclipseSingularizer {
 		}
 		
 		{ // default:
-			switchContents.add(new CaseStatement(null, 0, 0));
+			switchContents.add(Eclipse.createCaseStatement(null));
 			switchContents.addAll(createJavaUtilSimpleCreationAndFillStatements(data, builderType, mapMode, false, true, emptyCollectionMethod == null, targetType, builderVariable));
 		}
 		
diff --git a/src/utils/lombok/eclipse/Eclipse.java b/src/utils/lombok/eclipse/Eclipse.java
index 5b3c453e..31f2518a 100644
--- a/src/utils/lombok/eclipse/Eclipse.java
+++ b/src/utils/lombok/eclipse/Eclipse.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2009-2013 The Project Lombok Authors.
+ * Copyright (C) 2009-2019 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
@@ -29,10 +29,13 @@ import java.util.regex.Pattern;
 
 import lombok.core.ClassLiteral;
 import lombok.core.FieldSelect;
+import lombok.permit.Permit;
+
 import org.eclipse.jdt.internal.compiler.ast.ASTNode;
 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration;
 import org.eclipse.jdt.internal.compiler.ast.Annotation;
+import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
 import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
 import org.eclipse.jdt.internal.compiler.ast.Clinit;
 import org.eclipse.jdt.internal.compiler.ast.Expression;
@@ -262,4 +265,23 @@ public class Eclipse {
 			return false;
 		}
 	}
+	
+	private static boolean caseStatementInit = false;
+	private static Field caseStatementConstantExpressions = null;
+	public static CaseStatement createCaseStatement(Expression expr) {
+		CaseStatement stat = new CaseStatement(expr, 0, 0);
+		if (expr == null) return stat;
+		if (!caseStatementInit) {
+			try {
+				caseStatementConstantExpressions = Permit.getField(CaseStatement.class, "constantExpressions");
+				caseStatementConstantExpressions.setAccessible(true);
+			} catch (NoSuchFieldException ignore) {}
+			caseStatementInit = true;
+		}
+		if (caseStatementConstantExpressions != null) try {
+			caseStatementConstantExpressions.set(stat, new Expression[] {expr});
+		} catch (IllegalArgumentException ignore) {
+		} catch (IllegalAccessException ignore) {}
+		return stat;
+	}
 }
-- 
cgit