Fixed metamodel registration in AcceleoTextDocument.

Change-Id: I737cb0ddc091565a07a7db7edaad6b658f38b15a
diff --git a/plugins/org.eclipse.acceleo.aql.ide.ui/src/org/eclipse/acceleo/aql/ide/ui/EclipseWorkspace2AcceleoWorkspace.java b/plugins/org.eclipse.acceleo.aql.ide.ui/src/org/eclipse/acceleo/aql/ide/ui/EclipseWorkspace2AcceleoWorkspace.java
index e32a726..86df98e 100644
--- a/plugins/org.eclipse.acceleo.aql.ide.ui/src/org/eclipse/acceleo/aql/ide/ui/EclipseWorkspace2AcceleoWorkspace.java
+++ b/plugins/org.eclipse.acceleo.aql.ide.ui/src/org/eclipse/acceleo/aql/ide/ui/EclipseWorkspace2AcceleoWorkspace.java
@@ -18,10 +18,6 @@
 import java.util.Map;
 import java.util.Objects;
 
-import org.eclipse.acceleo.aql.AcceleoEnvironment;
-import org.eclipse.acceleo.aql.IAcceleoEnvironment;
-import org.eclipse.acceleo.aql.evaluation.AcceleoEvaluator;
-import org.eclipse.acceleo.aql.evaluation.writer.DefaultGenerationStrategy;
 import org.eclipse.acceleo.aql.ide.AcceleoPlugin;
 import org.eclipse.acceleo.aql.ls.services.textdocument.AcceleoTextDocument;
 import org.eclipse.acceleo.aql.ls.services.workspace.AcceleoProject;
@@ -29,8 +25,6 @@
 import org.eclipse.acceleo.aql.parser.AcceleoParser;
 import org.eclipse.acceleo.aql.parser.ModuleLoader;
 import org.eclipse.acceleo.query.ide.QueryPlugin;
-import org.eclipse.acceleo.query.runtime.impl.namespace.QualifiedNameQueryEnvironment;
-import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameQueryEnvironment;
 import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameResolver;
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
@@ -432,7 +426,7 @@
 			AcceleoProject acceleoProject = this.projectsTrace.get(workspaceProject);
 
 			acceleoProject.setLabel(getAcceleoProjectLabelFor(workspaceProject));
-			acceleoProject.setAcceleoEnvironment(this.createAcceleoEnvironmentFor(workspaceProject));
+			acceleoProject.setResolver(this.createResolver(workspaceProject));
 
 			// The contained documents are updated on their own.
 		}
@@ -530,35 +524,26 @@
 		 * @return the corresponding {@link AcceleoProject}.
 		 */
 		private AcceleoProject transform(IProject workspaceProject) {
-			return new AcceleoProject(getAcceleoProjectLabelFor(workspaceProject), this
-					.createAcceleoEnvironmentFor(workspaceProject));
+			return new AcceleoProject(getAcceleoProjectLabelFor(workspaceProject), this.createResolver(
+					workspaceProject));
 		}
 
 		/**
-		 * Creates a new {@link IAcceleoEnvironment} for the given {@link IResource}.
+		 * Creates a new {@link IQualifiedNameResolver} for the given {@link IProject}.
 		 * 
-		 * @param workspaceResource
-		 *            the (non-{@code null}) {@link IResource}.
-		 * @return the corresponding {@link IAcceleoEnvironment}.
+		 * @param project
+		 *            the (non-{@code null}) {@link IProject}.
+		 * @return the corresponding {@link IQualifiedNameResolver}.
 		 */
-		public IAcceleoEnvironment createAcceleoEnvironmentFor(IResource workspaceResource) {
-			final IProject project = workspaceResource.getProject();
+		public IQualifiedNameResolver createResolver(IProject project) {
+			Objects.nonNull(project);
 			final IQualifiedNameResolver resolver = QueryPlugin.getPlugin().createQualifiedNameResolver(
 					AcceleoPlugin.getPlugin().getClass().getClassLoader(), project,
 					AcceleoParser.QUALIFIER_SEPARATOR);
-			final IQualifiedNameQueryEnvironment queryEnvironment = new QualifiedNameQueryEnvironment(
-					resolver);
-			final org.eclipse.emf.common.util.URI target = org.eclipse.emf.common.util.URI.createURI(
-					workspaceResource.getWorkspace().getRoot().getLocationURI().toString());
-			IAcceleoEnvironment acceleoEnvironment = new AcceleoEnvironment(queryEnvironment,
-					new DefaultGenerationStrategy(), target);
-
-			final AcceleoEvaluator evaluator = new AcceleoEvaluator(acceleoEnvironment, queryEnvironment
-					.getLookupEngine());
-			resolver.addLoader(new ModuleLoader(new AcceleoParser(), evaluator));
+			resolver.addLoader(new ModuleLoader(new AcceleoParser(), null));
 			resolver.addLoader(QueryPlugin.getPlugin().createJavaLoader(AcceleoParser.QUALIFIER_SEPARATOR));
 
-			return acceleoEnvironment;
+			return resolver;
 		}
 
 		/**
diff --git a/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocument.java b/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocument.java
index 8efb191..b7ddbf2 100644
--- a/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocument.java
+++ b/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/textdocument/AcceleoTextDocument.java
@@ -16,6 +16,7 @@
 import java.util.List;
 import java.util.Objects;
 
+import org.eclipse.acceleo.Metamodel;
 import org.eclipse.acceleo.Module;
 import org.eclipse.acceleo.ModuleElement;
 import org.eclipse.acceleo.aql.AcceleoEnvironment;
@@ -29,7 +30,9 @@
 import org.eclipse.acceleo.aql.parser.AcceleoParser;
 import org.eclipse.acceleo.aql.validation.AcceleoValidator;
 import org.eclipse.acceleo.aql.validation.IAcceleoValidationResult;
+import org.eclipse.acceleo.query.runtime.impl.namespace.QualifiedNameQueryEnvironment;
 import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameLookupEngine;
+import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameQueryEnvironment;
 import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameResolver;
 import org.eclipse.lsp4j.Range;
 import org.eclipse.lsp4j.TextDocumentContentChangeEvent;
@@ -59,6 +62,11 @@
 	private AcceleoProject ownerProject;
 
 	/**
+	 * The {@link IAcceleoEnvironment} for this text document.
+	 */
+	private IAcceleoEnvironment acceleoEnvironment;
+
+	/**
 	 * The {@link String} contents of the text document.
 	 */
 	private String contents;
@@ -130,15 +138,15 @@
 		this.ownerProject = acceleoProject;
 		if ((acceleoProject == null && oldProject != null) || !acceleoProject.equals(oldProject)) {
 			// When the project changes, the environment changes.
-			this.environmentChanged();
+			this.resolverChanged();
 		}
 	}
 
 	/**
 	 * This is called to notify this {@link AcceleoTextDocument} that its contextual
-	 * {@link IAcceleoEnvironment} has changed. As a result, it needs to be re-parsed and re-validated.
+	 * {@link IQualifiedNameResolver} has changed. As a result, it needs to be re-parsed and re-validated.
 	 */
-	public void environmentChanged() {
+	public void resolverChanged() {
 		this.documentChanged();
 	}
 
@@ -166,9 +174,16 @@
 	 */
 	private void parseContents() {
 		AcceleoAstResult parsingResult = null;
-		if (this.getAcceleoEnvironment() != null) {
-			parsingResult = doParsing(this.getModuleQualifiedName(), this.contents, this
-					.getAcceleoEnvironment());
+		parsingResult = doParsing(this.getModuleQualifiedName(), this.contents);
+
+		final IQualifiedNameQueryEnvironment queryEnvironment = new QualifiedNameQueryEnvironment(getProject()
+				.getResolver());
+		acceleoEnvironment = new AcceleoEnvironment(queryEnvironment, null, null);
+
+		for (Metamodel metamodel : parsingResult.getModule().getMetamodels()) {
+			if (metamodel.getReferencedPackage() != null) {
+				queryEnvironment.registerEPackage(metamodel.getReferencedPackage());
+			}
 		}
 		this.acceleoAstResult = parsingResult;
 	}
@@ -180,16 +195,11 @@
 	 *            the (non-{@code null}) qualified name of the document we are parsing.
 	 * @param documentContents
 	 *            the (non-{@code null}) contents of the document we are parsing.
-	 * @param acceleoEnvironment
-	 *            the (non-{@code null}) {@link IAcceleoEnvironment} of the document we are parsing.
 	 * @return the resulting {@link AcceleoAstResult}.
 	 */
-	private static AcceleoAstResult doParsing(String moduleQualifiedName, String documentContents,
-			IAcceleoEnvironment acceleoEnvironment) {
+	private static AcceleoAstResult doParsing(String moduleQualifiedName, String documentContents) {
 		Objects.requireNonNull(moduleQualifiedName);
 		Objects.requireNonNull(documentContents);
-		Objects.requireNonNull(acceleoEnvironment);
-
 		AcceleoParser acceleoParser = new AcceleoParser();
 		return acceleoParser.parse(documentContents, moduleQualifiedName);
 	}
@@ -277,15 +287,10 @@
 	 *         {@link IAcceleoEnvironment}.
 	 */
 	public String getModuleQualifiedName() {
-		if (this.getAcceleoEnvironment() == null || this.getAcceleoEnvironment().getQueryEnvironment() == null
-				|| this.getAcceleoEnvironment().getQueryEnvironment().getLookupEngine() == null || this
-						.getAcceleoEnvironment().getQueryEnvironment().getLookupEngine()
-						.getResolver() == null) {
+		if (getProject() == null) {
 			return null;
 		} else {
-			final IQualifiedNameResolver resolver = this.getAcceleoEnvironment().getQueryEnvironment()
-					.getLookupEngine().getResolver();
-			return resolver.getQualifiedName(this.getUrl());
+			return getProject().getResolver().getQualifiedName(this.getUrl());
 		}
 	}
 
@@ -404,11 +409,7 @@
 	 *         {@link AcceleoTextDocument}.
 	 */
 	public IAcceleoEnvironment getAcceleoEnvironment() {
-		if (this.ownerProject != null) {
-			return this.ownerProject.getAcceleoEnvironment();
-		} else {
-			return null;
-		}
+		return acceleoEnvironment;
 	}
 
 	/**
diff --git a/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/workspace/AcceleoProject.java b/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/workspace/AcceleoProject.java
index e2af6fc..7d6527b 100644
--- a/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/workspace/AcceleoProject.java
+++ b/plugins/org.eclipse.acceleo.aql.ls/src/org/eclipse/acceleo/aql/ls/services/workspace/AcceleoProject.java
@@ -26,6 +26,7 @@
 import org.eclipse.acceleo.aql.ls.AcceleoLanguageServer;
 import org.eclipse.acceleo.aql.ls.services.textdocument.AcceleoTextDocument;
 import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameLookupEngine;
+import org.eclipse.acceleo.query.runtime.namespace.IQualifiedNameResolver;
 
 /**
  * A representation, in the {@link AcceleoLanguageServer} of a container of {@link AcceleoTextDocument
@@ -52,21 +53,21 @@
 	private String label;
 
 	/**
-	 * The {@link IAcceleoEnvironment} of this {@link AcceleoProject}.
+	 * The {@link IQualifiedNameResolver} of this {@link AcceleoProject}.
 	 */
-	private IAcceleoEnvironment acceleoEnvironment;
+	private IQualifiedNameResolver resolver;
 
 	/**
 	 * The constructor.
 	 *
 	 * @param label
 	 *            the (non-{@code null}) {@link String label} for the project.
-	 * @param acceleoEnvironment
-	 *            the (non-{@code null}) {@link IAcceleoEnvironment} for the project.
+	 * @param resolver
+	 *            the (non-{@code null}) {@link IQualifiedNameResolver} for the project.
 	 */
-	public AcceleoProject(String label, IAcceleoEnvironment acceleoEnvironment) {
+	public AcceleoProject(String label, IQualifiedNameResolver resolver) {
 		this.label = Objects.requireNonNull(label);
-		this.acceleoEnvironment = Objects.requireNonNull(acceleoEnvironment);
+		this.resolver = Objects.requireNonNull(resolver);
 	}
 
 	/**
@@ -111,16 +112,16 @@
 		this.workspace = acceleoWorkspace;
 
 		// The workspace has changed so the environment has implicitly changed.
-		this.getTextDocuments().forEach(textDocument -> textDocument.environmentChanged());
+		this.getTextDocuments().forEach(textDocument -> textDocument.resolverChanged());
 	}
 
 	/**
-	 * Provides the {@link IAcceleoEnvironment} of this {@link AcceleoProject}.
+	 * Provides the {@link IQualifiedNameResolver} of this {@link AcceleoProject}.
 	 * 
-	 * @return the (non-{@code null}) {@link IAcceleoEnvironment} of this {@link AcceleoProject}.
+	 * @return the (non-{@code null}) {@link IQualifiedNameResolver} of this {@link AcceleoProject}.
 	 */
-	public IAcceleoEnvironment getAcceleoEnvironment() {
-		return this.acceleoEnvironment;
+	public IQualifiedNameResolver getResolver() {
+		return this.resolver;
 	}
 
 	/**
@@ -134,16 +135,16 @@
 	}
 
 	/**
-	 * Sets the {@link IAcceleoEnvironment} of this {@link AcceleoProject}.
+	 * Sets the {@link IQualifiedNameResolver} of this {@link AcceleoProject}.
 	 * 
-	 * @param newAcceleoEnvironment
-	 *            the new {@link IAcceleoEnvironment} of this {@link AcceleoProject}.
+	 * @param resolver
+	 *            the new {@link IQualifiedNameResolver} of this {@link AcceleoProject}.
 	 */
-	public void setAcceleoEnvironment(IAcceleoEnvironment newAcceleoEnvironment) {
-		this.acceleoEnvironment = newAcceleoEnvironment;
+	public void setResolver(IQualifiedNameResolver resolver) {
+		this.resolver = resolver;
 
-		// The environment has changed so we notify our documents.
-		this.getTextDocuments().forEach(textDocument -> textDocument.environmentChanged());
+		// The resolver has changed so we notify our documents.
+		this.getTextDocuments().forEach(textDocument -> textDocument.resolverChanged());
 	}
 
 	/**
@@ -211,8 +212,8 @@
 	 */
 	public void documentSaved(AcceleoTextDocument savedTextDocument) {
 		final String qualifiedNameOfSavedModule = savedTextDocument.getModuleQualifiedName();
-		final IQualifiedNameLookupEngine lookupEngine = this.getAcceleoEnvironment().getQueryEnvironment()
-				.getLookupEngine();
+		final IQualifiedNameLookupEngine lookupEngine = savedTextDocument.getAcceleoEnvironment()
+				.getQueryEnvironment().getLookupEngine();
 
 		// First clear the environment for the document that was changed.
 		lookupEngine.clearContext(qualifiedNameOfSavedModule);
@@ -225,7 +226,7 @@
 		// Re-validate all modules that depend on the changed module.
 		Set<AcceleoTextDocument> consumers = getTextDocumentsThatDependOn(qualifiedNameOfSavedModule);
 		for (AcceleoTextDocument consumer : consumers) {
-			consumer.environmentChanged();
+			consumer.resolverChanged();
 		}
 
 		// If the saved document belongs to us, we propagate the notification up to the workspace.
@@ -243,8 +244,8 @@
 	 *            the (non-{@code null}) {@link AcceleoTextDocument} that has been removed.
 	 */
 	public void documentRemoved(AcceleoTextDocument removedTextDocument) {
-		final IQualifiedNameLookupEngine lookupEngine = this.getAcceleoEnvironment().getQueryEnvironment()
-				.getLookupEngine();
+		final IQualifiedNameLookupEngine lookupEngine = removedTextDocument.getAcceleoEnvironment()
+				.getQueryEnvironment().getLookupEngine();
 
 		// Since the qualified name of a module depends on its environment, we want the qualified name
 		// according to our environment.
@@ -258,7 +259,7 @@
 		// Re-validate all modules that depend on the changed module.
 		Set<AcceleoTextDocument> consumers = getTextDocumentsThatDependOn(removedModuleQualifiedName);
 		for (AcceleoTextDocument consumer : consumers) {
-			consumer.environmentChanged();
+			consumer.resolverChanged();
 		}
 
 		// Unlike in documentSaved, we do not need to propagate the notification as it cannot come from the