Permalink
Browse files

Fixes problems related to newer Xtext version wrt linking & build clean.

Closes #318

The UI module now binds a ResourceFactory for PPResource that takes over
the responsability of linking "the pp way". It also overrides the
bindings of the (non ui aware) dsl module that perform linking via the
PPLinker.
class.
  • Loading branch information...
hlindberg committed Apr 28, 2012
1 parent 9c970fc commit 68a98810529caab52d2f618efc4f224502ac5c14
@@ -1,5 +1,5 @@
/**
- * Copyright (c) 2011 Cloudsmith, Inc. and others.
+ * Copyright (c) 2011, 2012 Cloudsmith, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -33,12 +33,17 @@
import org.cloudsmith.geppetto.pp.dsl.ui.linking.PPUISearchPathProvider;
import org.cloudsmith.geppetto.pp.dsl.ui.outline.PPLocationInFileProvider;
import org.cloudsmith.geppetto.pp.dsl.ui.preferences.PPPreferencesHelper;
+import org.cloudsmith.geppetto.pp.dsl.ui.resource.PPResource;
+import org.cloudsmith.geppetto.pp.dsl.ui.resource.PPResourceFactory;
import org.cloudsmith.geppetto.pp.dsl.ui.validation.PreferenceBasedPotentialProblemsAdvisor;
import org.cloudsmith.geppetto.pp.dsl.ui.validation.PreferenceBasedValidationAdvisorProvider;
import org.cloudsmith.geppetto.pp.dsl.validation.IPotentialProblemsAdvisor;
import org.cloudsmith.geppetto.pp.dsl.validation.IValidationAdvisor;
import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.eclipse.xtext.linking.lazy.LazyLinker;
import org.eclipse.xtext.resource.ILocationInFileProvider;
+import org.eclipse.xtext.resource.IResourceFactory;
+import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.XtextEditor;
import org.eclipse.xtext.ui.editor.autoedit.AbstractEditStrategyProvider;
import org.eclipse.xtext.ui.editor.folding.IFoldingRegionProvider;
@@ -65,20 +70,24 @@ public PPUiModule(AbstractUIPlugin plugin) {
super(plugin);
}
- // public Class<? extends IContainer.Manager> bindIContainer$Manager() {
- // return StateBasedContainerManager.class;
- // }
-
- // Make auto edit configurable with preferences
+ /**
+ * This binding makes auto edit configurable with preferences
+ */
@Override
public Class<? extends AbstractEditStrategyProvider> bindAbstractEditStrategyProvider() {
return PPEditStrategyProvider.class;
}
+ /**
+ * This binding makes SL comments fold as expected.
+ */
public Class<? extends IFoldingRegionProvider> bindIFoldingRegionProvider() {
return PPFoldingRegionProvider.class;
}
+ /**
+ * This binding adds ability to find/cross reference PP elements (since they do not use EReferences).
+ */
public Class<? extends IHyperlinkHelper> bindIHyperlinkHelper() {
return PPHyperlinkHelper.class;
}
@@ -88,7 +97,21 @@ public PPUiModule(AbstractUIPlugin plugin) {
}
/**
- * Add specialization that selects better "significant part" per semantic object.
+ * The runtime module uses PPLinker.class which performs PP linking and documentation association
+ * as part of the linking process. This is not suitable for use in the UI, where the PPResource is
+ * instead taking over the responsibility. <br/>
+ * Overrides the default runtime module's binding
+ *
+ * @see #bindIResourceFactory()
+ */
+ public Class<? extends org.eclipse.xtext.linking.ILinker> bindILinker() {
+ return LazyLinker.class;
+ }
+
+ /**
+ * Add specialization that selects better "significant part" per semantic object than the default.
+ * (This is used when a location in a file is wanted for selection when opening the file and there is a reference
+ * to the object - which of each features / text should be selected).
*
*/
public Class<? extends ILocationInFileProvider> bindILocationInFileProvider() {
@@ -100,15 +123,24 @@ public PPUiModule(AbstractUIPlugin plugin) {
}
/**
- * Deal with dependency on JDT.
+ * This is an override of the runtime module's configuration as the UI should use PPResource instead of
+ * LazyLinkingResource for PP linking to work correctly with the global build index.
+ *
+ */
+ public Class<? extends IResourceFactory> bindIResourceFactory() {
+ return PPResourceFactory.class;
+ }
+
+ /**
+ * Deal with dependency on JDT (not wanted)
*/
@Override
public Class<? extends IResourceForEditorInputFactory> bindIResourceForEditorInputFactory() {
return ResourceForIEditorInputFactory.class;
}
/**
- * Deal with dependency on JDT.
+ * Deal with dependency on JDT (not wanted)
*/
@Override
public Class<? extends IResourceSetProvider> bindIResourceSetProvider() {
@@ -150,17 +182,26 @@ public PPUiModule(AbstractUIPlugin plugin) {
return PPTokenToAttributeIdMapper.class;
}
+ /**
+ * This is an override of the runtime modules binding (using a regular LazyLinkingResource).
+ */
+ public Class<? extends XtextResource> bindXtextResource() {
+ return PPResource.class;
+ }
+
/**
* Override that injects a wrapper for the external lexer used by the main parser.
- * contributed by org.eclipse.xtext.generator.parser.antlr.ex.ca.ContentAssistParserGeneratorFragment
+ * contributed by org.eclipse.xtext.generator.parser.antlr.ex.ca.ContentAssistParserGeneratorFragment.
+ *
+ * Without this override, a default generated lexer will be used and this lexer will not be correct as
+ * PP parsing requires an external lexer. The binding reuses the main lexer.
*/
@Override
public void configureContentAssistLexer(com.google.inject.Binder binder) {
- // Need to use the external lexer here
- // TODO:
binder.bind(org.eclipse.xtext.ui.editor.contentassist.antlr.internal.Lexer.class).annotatedWith(
com.google.inject.name.Names.named(org.eclipse.xtext.ui.LexerUIBindings.CONTENT_ASSIST)).to(
PPContentAssistLexer.class);
+ // This is the default generated one:
// org.cloudsmith.geppetto.pp.dsl.ui.contentassist.antlr.lexer.InternalPPLexer.class);
}
@@ -199,7 +240,7 @@ public void configureHighlightingLexer(com.google.inject.Binder binder) {
}
/**
- * Deal with dependency on JDT.
+ * Deal with dependency on JDT (not wanted).
*/
@Override
public com.google.inject.Provider<org.eclipse.xtext.resource.containers.IAllContainersState> provideIAllContainersState() {
@@ -209,11 +250,8 @@ public void configureHighlightingLexer(com.google.inject.Binder binder) {
/**
* A Provider of validation compliance based on preferences.
- *
- * @return
*/
public com.google.inject.Provider<IValidationAdvisor> provideValidationAdvisor() {
return PreferenceBasedValidationAdvisorProvider.create();
}
-
}
@@ -0,0 +1,140 @@
+/**
+ * Copyright (c) 2012 Cloudsmith Inc. and other contributors, as listed below.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith
+ *
+ */
+package org.cloudsmith.geppetto.pp.dsl.ui.resource;
+
+import org.cloudsmith.geppetto.pp.dsl.linking.DiagnosticConsumerBasedMessageAcceptor;
+import org.cloudsmith.geppetto.pp.dsl.linking.DocumentationAssociator;
+import org.cloudsmith.geppetto.pp.dsl.linking.IMessageAcceptor;
+import org.cloudsmith.geppetto.pp.dsl.linking.PPLinker;
+import org.cloudsmith.geppetto.pp.dsl.linking.PPResourceLinker;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.xtext.diagnostics.Severity;
+import org.eclipse.xtext.linking.lazy.LazyLinkingResource;
+import org.eclipse.xtext.parser.IParseResult;
+import org.eclipse.xtext.resource.impl.ListBasedDiagnosticConsumer;
+import org.eclipse.xtext.util.CancelIndicator;
+import org.eclipse.xtext.util.IResourceScopeCache;
+import org.eclipse.xtext.util.OnChangeEvictingCache;
+
+import com.google.inject.Inject;
+
+/**
+ * A PP Resource that performs PP specific linking when the resource is loaded (the first time), and
+ * when the parse result is updated.
+ * Note that this is UI specific, in headless runtime, the same functionality is triggered by the @link {@link PPLinker}.
+ *
+ */
+public class PPResource extends LazyLinkingResource {
+ @Inject
+ private DocumentationAssociator documentationAssociator;
+
+ @Inject
+ PPResourceLinker resourceLinker;
+
+ /**
+ * True if the pp linking has been performed.
+ */
+ protected volatile boolean fullyLinked = false;
+
+ /**
+ * Protects against code calling back to this resource while it is performing pp linking
+ */
+ protected volatile boolean isLinking = false;
+
+ /**
+ * By calling this method, the next call to {@link #resolveLazyCrossReferences(CancelIndicator)} will
+ * perform PP linking.
+ */
+ protected void discardLinkedState() {
+ if(fullyLinked && !isLinking) {
+ fullyLinked = false;
+ isLinking = false;
+ getCache().clear(this);
+ }
+ }
+
+ protected void ensureLinkedState(CancelIndicator mon) {
+ if(isLoaded && !isLoading && !isLinking && !isUpdating && !fullyLinked) {
+ try {
+ isLinking = true;
+ performPPLinking(mon);
+ fullyLinked = true;
+ }
+ finally {
+ isLinking = false;
+ getCache().clear(this);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ * <p>
+ * Overridden to make sure that a resource is not initialized just to compute the root URI fragment for the parse result.
+ */
+ @Override
+ protected String getURIFragmentRootSegment(EObject eObject) {
+ if(unloadingContents == null) {
+ IParseResult parseResult = getParseResult();
+ if(parseResult != null && eObject == parseResult.getRootASTElement()) {
+ return "0";
+ }
+ }
+ return super.getURIFragmentRootSegment(eObject);
+ }
+
+ /**
+ * Performs PP linking, and processes documentation
+ *
+ * @param mon
+ */
+ protected void performPPLinking(CancelIndicator mon) {
+ final ListBasedDiagnosticConsumer diagnosticsConsumer = new ListBasedDiagnosticConsumer();
+ IMessageAcceptor acceptor = new DiagnosticConsumerBasedMessageAcceptor(diagnosticsConsumer);
+ EObject model = this.getParseResult().getRootASTElement();
+ documentationAssociator.linkDocumentation(model, acceptor);
+ resourceLinker.link(model, acceptor, false);
+
+ if(!isValidationDisabled()) {
+ getErrors().addAll(diagnosticsConsumer.getResult(Severity.ERROR));
+ getWarnings().addAll(diagnosticsConsumer.getResult(Severity.WARNING));
+ }
+ }
+
+ @Override
+ public void resolveLazyCrossReferences(CancelIndicator mon) {
+ super.resolveLazyCrossReferences(mon);
+ ensureLinkedState(mon);
+ }
+
+ /**
+ * Overridden to make sure that the cache is initialized during {@link #isLoading() loading}.
+ */
+ @Override
+ protected void updateInternalState(IParseResult newParseResult) {
+ super.updateInternalState(newParseResult);
+ // make sure that the cache adapter is installed on this resource
+ IResourceScopeCache cache = getCache();
+ if(cache instanceof OnChangeEvictingCache) {
+ ((OnChangeEvictingCache) cache).getOrCreate(this);
+ }
+ }
+
+ @Override
+ protected void updateInternalState(IParseResult oldParseResult, IParseResult newParseResult) {
+ if(fullyLinked) {
+ discardLinkedState();
+ }
+ super.updateInternalState(oldParseResult, newParseResult);
+ }
+
+}
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2012 Cloudsmith Inc. and other contributors, as listed below.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith
+ *
+ */
+package org.cloudsmith.geppetto.pp.dsl.ui.resource;
+
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.xtext.resource.IResourceFactory;
+import org.eclipse.xtext.resource.XtextResource;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+/**
+ * A Provider of a PP specific Resource
+ *
+ */
+public class PPResourceFactory implements IResourceFactory {
+ private Provider<PPResource> provider;
+
+ @Inject
+ public PPResourceFactory(Provider<PPResource> resourceProvider) {
+ this.provider = resourceProvider;
+ }
+
+ public Resource createResource(URI uri) {
+ XtextResource xtextResource = provider.get();
+ xtextResource.setURI(uri);
+ return xtextResource;
+ }
+
+}

0 comments on commit 68a9881

Please sign in to comment.