Bug 575354: [Ltk-Model] Improve extensible reconciler

Change-Id: I2bac57834e9d79a5d1c5c0177ca3586ebb7fdc43
diff --git a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/build/ExtensibleReconciler.java b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/build/ExtensibleReconciler.java
index 413fcb9..35d5577 100644
--- a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/build/ExtensibleReconciler.java
+++ b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/build/ExtensibleReconciler.java
@@ -39,19 +39,21 @@
 import org.eclipse.statet.ltk.ast.core.util.AstPrinter;
 import org.eclipse.statet.ltk.core.SourceContent;
 import org.eclipse.statet.ltk.model.core.ModelManager;
-import org.eclipse.statet.ltk.model.core.element.SourceUnit;
 import org.eclipse.statet.ltk.model.core.element.WorkspaceSourceUnit;
 import org.eclipse.statet.ltk.project.core.LtkProject;
 
 
 @NonNullByDefault
-public abstract class ExtensibleReconciler<TProject extends LtkProject,
-		TModelContainer extends SourceUnitModelContainer<?, ?>,
-		TEmbeddedModelReconciler extends SourceUnitEmbeddedModelReconciler<?>> {
+public abstract class ExtensibleReconciler<
+			TProject extends LtkProject,
+			TModelContainer extends SourceUnitModelContainer<?, ?>,
+			TEmbeddedModelReconciler extends SourceUnitEmbeddedModelReconciler<TProject, ?>> {
 	
 	
-	protected static final class ExtensionData<TConfig extends ReconcileConfig<?>,
-			TReconciler extends SourceUnitEmbeddedModelReconciler<TConfig>> {
+	protected static final class ExtensionData<
+				TProject extends LtkProject,
+				TConfig extends ReconcileConfig<?>,
+				TReconciler extends SourceUnitEmbeddedModelReconciler<TProject, TConfig>> {
 		
 		public final String modelTypeId;
 		
@@ -68,7 +70,7 @@
 		}
 		
 		
-		public static <T extends ExtensionData<?, ?>> boolean contains(final ImList<T> list, final String modelTypeId) {
+		public static <T extends ExtensionData<?, ?, ?>> boolean contains(final ImList<T> list, final String modelTypeId) {
 			for (final var data : list) {
 				if (data.modelTypeId == modelTypeId) {
 					return true;
@@ -77,7 +79,7 @@
 			return false;
 		}
 		
-		public static <T extends ExtensionData<?, ?>> @Nullable T get(final ImList<T> list, final String modelTypeId) {
+		public static <T extends ExtensionData<?, ?, ?>> @Nullable T get(final ImList<T> list, final String modelTypeId) {
 			for (final var data : list) {
 				if (data.modelTypeId == modelTypeId) {
 					return data;
@@ -88,14 +90,16 @@
 		
 	}
 	
-	private static class ExtensionItem<TConfig extends ReconcileConfig<?>,
-			TReconciler extends SourceUnitEmbeddedModelReconciler<TConfig>> {
+	private static class ExtensionItem<
+				TProject extends LtkProject,
+				TConfig extends ReconcileConfig<?>,
+				TReconciler extends SourceUnitEmbeddedModelReconciler<TProject, TConfig>> {
 		
 		private final String modelTypeId;
 		
 		private final @Nullable TReconciler reconciler;
 		
-		private @Nullable ExtensionData<TConfig, TReconciler> projectData;
+		private @Nullable ExtensionData<TProject, TConfig, TReconciler> projectData;
 		
 		public ExtensionItem(final String modelTypeId, @Nullable final TReconciler reconciler) {
 			this.modelTypeId= modelTypeId;
@@ -107,20 +111,23 @@
 			this.projectData= null;
 		}
 		
-		public ExtensionData<TConfig, TReconciler> init(final LtkProject project) {
+		public ExtensionData<TProject, TConfig, TReconciler> init(final TProject wsProject) {
 			var projectData= this.projectData;
 			if (projectData == null) {
-				projectData= createData(project.getProject(),
+				projectData= createData(wsProject.getProject(), wsProject,
 						ModelManager.MODEL_DEPENDENCIES | ModelManager.RECONCILE );
 				this.projectData= projectData;
 			}
 			return projectData;
 		}
 		
-		public ExtensionData<TConfig, TReconciler> createData(final @Nullable IProject project, final int level) {
+		public ExtensionData<TProject, TConfig, TReconciler> createData(
+				final @Nullable IProject wsProject, final @Nullable TProject ltkProject,
+				final int level) {
 			@SuppressWarnings({ "null" })
 			final TReconciler reconciler= this.reconciler;
-			return new ExtensionData<>(reconciler, reconciler.createConfig(project, level));
+			return new ExtensionData<>(reconciler,
+					reconciler.createConfig(wsProject, ltkProject, level) );
 		}
 		
 	}
@@ -128,7 +135,7 @@
 	
 	protected boolean stop= false;
 	
-	private final Map<String, ExtensionItem<?, TEmbeddedModelReconciler>> extensions= new HashMap<>();
+	private final Map<String, ExtensionItem<TProject, ?, TEmbeddedModelReconciler>> extensions= new HashMap<>();
 	
 	private @Nullable TProject project;
 	private @Nullable MultiStatus statusCollector;
@@ -157,10 +164,13 @@
 	}
 	
 	
+	protected abstract @Nullable TProject getProject(IProject wsProject);
+	
 	protected abstract @Nullable TEmbeddedModelReconciler createEmbeddedModelReconciler(
 			final String modelTypeId);
 	
-	protected @Nullable ExtensionItem<?, TEmbeddedModelReconciler> getExtension(final String modelTypeId) {
+	protected @Nullable ExtensionItem<TProject, ?, TEmbeddedModelReconciler> getExtension(
+			final String modelTypeId) {
 		synchronized (this.extensions) {
 			var item= this.extensions.get(modelTypeId);
 			if (item== null) {
@@ -171,10 +181,10 @@
 		}
 	}
 	
-	protected ImList<ExtensionData<?, TEmbeddedModelReconciler>> initExtensions(
+	protected ImList<ExtensionData<TProject, ?, TEmbeddedModelReconciler>> initExtensions(
 			final ImCollection<String> modelTypeIds,
 			final TModelContainer adapter, final int flags) {
-		final var items= new ArrayList<ExtensionItem<?, TEmbeddedModelReconciler>>();
+		final var items= new ArrayList<ExtensionItem<TProject, ?, TEmbeddedModelReconciler>>();
 		for (final String modelTypeId : modelTypeIds) {
 			final var extension= getExtension(modelTypeId);
 			if (extension != null) {
@@ -183,20 +193,20 @@
 		}
 		
 		@SuppressWarnings("unchecked")
-		final @NonNull ExtensionData<?, TEmbeddedModelReconciler>[] dataArray= new @NonNull ExtensionData[items.size()];
-		final var project= this.project;
-		if (project != null) {
+		final @NonNull ExtensionData<TProject, ?, TEmbeddedModelReconciler>[] dataArray= new @NonNull ExtensionData[items.size()];
+		var ltkProject= this.project;
+		if (ltkProject != null) {
 			for (int i= 0; i < dataArray.length; i++) {
-				dataArray[i]= items.get(i).init(project);
+				dataArray[i]= items.get(i).init(ltkProject);
 			}
 		}
 		else {
-			final SourceUnit sourceUnit= adapter.getSourceUnit();
-			final IProject wsProject= (sourceUnit instanceof WorkspaceSourceUnit) ?
-					((WorkspaceSourceUnit)sourceUnit).getResource().getProject() :
-					null;
+			final var sourceUnit= adapter.getSourceUnit();
+			final var wsProject= (sourceUnit instanceof WorkspaceSourceUnit) ?
+					((WorkspaceSourceUnit)sourceUnit).getResource().getProject() : null;
+			ltkProject= (wsProject != null) ? getProject(wsProject) : null;
 			for (int i= 0; i < dataArray.length; i++) {
-				dataArray[i]= items.get(i).createData(wsProject, flags);
+				dataArray[i]= items.get(i).createData(wsProject, ltkProject, flags);
 			}
 		}
 		return ImCollections.newList(dataArray);
@@ -204,7 +214,7 @@
 	
 	
 	protected ImList<Object> createSourceConfig(final Object mainSourceConfig,
-			final ImList<ExtensionData<?, TEmbeddedModelReconciler>> extensions) {
+			final ImList<ExtensionData<TProject, ?, TEmbeddedModelReconciler>> extensions) {
 		final var configArray= new @NonNull Object[1 + extensions.size()];
 		int i= 0;
 		configArray[i++]= mainSourceConfig;
diff --git a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/build/SourceUnitEmbeddedModelReconciler.java b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/build/SourceUnitEmbeddedModelReconciler.java
index d125ce1..cc370f4 100644
--- a/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/build/SourceUnitEmbeddedModelReconciler.java
+++ b/ltk/org.eclipse.statet.ltk.core/src/org/eclipse/statet/ltk/model/core/build/SourceUnitEmbeddedModelReconciler.java
@@ -20,14 +20,19 @@
 import org.eclipse.statet.jcommons.lang.NonNullByDefault;
 import org.eclipse.statet.jcommons.lang.Nullable;
 
+import org.eclipse.statet.ltk.project.core.LtkProject;
+
 
 @NonNullByDefault
-public interface SourceUnitEmbeddedModelReconciler<TConfig extends ReconcileConfig<?>> {
+public interface SourceUnitEmbeddedModelReconciler<
+			TProject extends LtkProject,
+			TConfig extends ReconcileConfig<?>> {
 	
 	
 	String getModelTypeId();
 	
-	@NonNull TConfig createConfig(@Nullable IProject project, int level);
+	@NonNull TConfig createConfig(@Nullable IProject wsProject, @Nullable TProject ltkProject,
+			int level);
 	
 	
 }