Skip to content

Commit a1a0bf8

Browse files
echebbidvojtise
authored andcommitted
[Editor] Show a warning when editing a file that is not part of the environment (#175)
A quick fix allows to automatically add the file to the environment. Signed-off-by: Emmanuel Chebbi <emmanuel.chebbi@outlook.fr>
1 parent 728195a commit a1a0bf8

File tree

5 files changed

+129
-14
lines changed

5 files changed

+129
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
3535
- [#115](https://github.com/gemoc/ale-lang/pull/115) The interpreter can be run by right-clicking on an ALE project
3636
- [#129](https://github.com/gemoc/ale-lang/pull/129) The editor warns when the `+=` and `-=` operators ared used on the `result` variable in a void method
3737
- [#131](https://github.com/gemoc/ale-lang/pull/131) The editor autocompletes attributes and methods of local variables and method parameters (support limited to model instances)
38+
- [#153](https://github.com/gemoc/ale-lang/pull/153) The editor shows a warning when editing an _.ale_ source file that is not part of the project's ALE environment. A quick fix allows to automatically add the _.ale_ source file to the project's ALE environment
3839
- [#169](https://github.com/gemoc/ale-lang/pull/169) The editor shows documentation about the _open_ and _behavior_ keywords on hover
3940
- [#169](https://github.com/gemoc/ale-lang/pull/169) The editor shows the fully qualified name of an open class on hover as well as information about its EPackage
4041

plugins/org.eclipse.emf.ecoretools.ale.xtext.ui/src/org/eclipse/emf/ecoretools/ui/quickfix/AleQuickfixProvider.xtend

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,73 @@
33
*/
44
package org.eclipse.emf.ecoretools.ui.quickfix
55

6+
import java.util.Optional
7+
import java.util.Set
8+
import org.eclipse.core.resources.IFile
9+
import org.eclipse.core.resources.ProjectScope
10+
import org.eclipse.core.runtime.preferences.IEclipsePreferences
11+
import org.eclipse.core.runtime.preferences.IScopeContext
12+
import org.eclipse.emf.common.util.URI
13+
import org.eclipse.emf.ecoretools.ale.core.env.IAleEnvironment
14+
import org.eclipse.emf.ecoretools.ale.core.env.impl.FileBasedAleEnvironment
15+
import org.eclipse.emf.ecoretools.ale.core.io.IOResources
16+
import org.eclipse.emf.ecoretools.ale.ide.project.IAleProject
17+
import org.eclipse.emf.ecoretools.ale.xtext.ui.internal.XtextActivator
18+
import org.eclipse.emf.ecoretools.validation.AleMarkerTypes
619
import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider
20+
import org.eclipse.xtext.ui.editor.quickfix.Fix
21+
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor
22+
import org.eclipse.xtext.validation.Issue
23+
import org.osgi.service.prefs.BackingStoreException
24+
25+
import static org.eclipse.emf.ecoretools.ale.ide.project.AleProjectPreferences.ALE_SOURCE_FILES
726

827
/**
928
* Custom quickfixes.
1029
*
1130
* See https://www.eclipse.org/Xtext/documentation/310_eclipse_support.html#quick-fixes
1231
*/
1332
class AleQuickfixProvider extends DefaultQuickfixProvider {
33+
34+
public static final String CORE_PLUGIN_ID = "org.eclipse.emf.ecoretools.ale.core";
1435

15-
// @Fix(AleValidator.INVALID_NAME)
16-
// def capitalizeName(Issue issue, IssueResolutionAcceptor acceptor) {
17-
// acceptor.accept(issue, 'Capitalize name', 'Capitalize the name.', 'upcase.png') [
18-
// context |
19-
// val xtextDocument = context.xtextDocument
20-
// val firstLetter = xtextDocument.get(issue.offset, 1)
21-
// xtextDocument.replace(issue.offset, 1, firstLetter.toUpperCase)
22-
// ]
23-
// }
36+
@Fix(AleMarkerTypes.SOURCE_FILE_NOT_IN_ENV)
37+
def capitalize(Issue issue, IssueResolutionAcceptor acceptor) {
38+
acceptor.accept(issue, 'Add file to ALE environment', 'Adds the file to the project\'s ALE environment (either in the configured .dsl file\nor in project`s preferences)', 'upcase.png') [
39+
context |
40+
val xtextDocument = context.xtextDocument
41+
val Optional<IFile> aleFile = IOResources.toIFile(xtextDocument.resourceURI)
42+
43+
if (aleFile.isPresent) {
44+
val IAleProject project = IAleProject.from(aleFile.get.project)
45+
val IAleEnvironment env = project.environment
46+
47+
val Set<String> aleSourceFilesPath = env.behaviorsSources
48+
val URI aleFileURI = URI.createPlatformResourceURI(aleFile.get.fullPath.toString, true)
49+
aleSourceFilesPath += aleFileURI.toString
50+
51+
if (project.isConfiguredFromPreferences) {
52+
val IScopeContext projectContext = new ProjectScope(aleFile.get.project);
53+
val IEclipsePreferences preferences = projectContext.getNode(CORE_PLUGIN_ID);
54+
val commaSeparatedPaths = aleSourceFilesPath.map[trim].filter[!isEmpty].join(",")
55+
56+
try {
57+
preferences.put(ALE_SOURCE_FILES.property, commaSeparatedPaths)
58+
preferences.flush()
59+
}
60+
catch (IllegalStateException | BackingStoreException unlikelyToHappen) {
61+
XtextActivator.instance.log.error("An unexpected error occurred while saving preferences", unlikelyToHappen);
62+
}
63+
}
64+
else {
65+
val dsl = project.findDslFile
66+
if (dsl.isPresent) {
67+
val FileBasedAleEnvironment dslEnv = IAleEnvironment.fromFile(dsl.get)
68+
val IAleEnvironment newEnv = IAleEnvironment.fromPaths(env.metamodelsSources, aleSourceFilesPath)
69+
dslEnv.save(newEnv)
70+
}
71+
}
72+
}
73+
]
74+
}
2475
}

plugins/org.eclipse.emf.ecoretools.ale.xtext/plugin.xml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@
1414
<super type="org.eclipse.core.resources.problemmarker" />
1515
<super type="org.eclipse.core.resources.textmarker" />
1616
<persistent value="true" />
17+
<super
18+
type="org.eclipse.emf.ecoretools.ale.xtext.ui.ale.check.normal">
19+
</super>
20+
</extension>
21+
22+
<extension point="org.eclipse.core.resources.markers"
23+
id="SourceFileNotInEnvironmentMarker"
24+
name="ALE Problem">
25+
<persistent value="true" />
26+
<super type="org.eclipse.emf.ecoretools.ale.xtext.AleMarker" />
1727
</extension>
18-
1928
</plugin>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package org.eclipse.emf.ecoretools.validation
2+
3+
/**
4+
* IDs of ALE markers.
5+
*/
6+
class AleMarkerTypes {
7+
8+
/**
9+
* Default marker ID.
10+
*/
11+
public static val String DEFAULT = "org.eclipse.emf.ecoretools.ale.xtext.AleMarker"
12+
13+
/**
14+
* Marker indicating that the source file is not in the project's ALE environment.
15+
*/
16+
public static val String SOURCE_FILE_NOT_IN_ENV = "org.eclipse.emf.ecoretools.ale.xtext.SourceFileNotInEnvironmentMarker"
17+
18+
19+
}

plugins/org.eclipse.emf.ecoretools.ale.xtext/src/org/eclipse/emf/ecoretools/validation/AleValidator.xtend

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,13 @@ import org.eclipse.xtext.Keyword
3434
import org.eclipse.xtext.nodemodel.impl.HiddenLeafNode
3535
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
3636
import org.eclipse.xtext.validation.Check
37+
import org.eclipse.xtext.validation.Issue
3738

3839
/**
3940
* Delegate validation to ALE validator
4041
*/
4142
class AleValidator extends AbstractAleValidator {
4243

43-
public static String ALE_MARKER = "org.eclipse.emf.ecoretools.ale.xtext.AleMarker";
44-
4544
@Check
4645
def checkIsValid(Unit root) {
4746

@@ -56,6 +55,13 @@ class AleValidator extends AbstractAleValidator {
5655
interpreter.initScope(Sets.newHashSet(),Sets.newHashSet(#[project.name]))
5756
val parsedSemantics = env.behaviors.parsedFiles
5857

58+
val parsed = parsedSemantics.findFirst[sem | aleFile == IOResources.toIFile(new File(sem.sourceFile))]
59+
val aleFileIsNotInEnv = parsed === null
60+
if (aleFileIsNotInEnv) {
61+
aleFile.createFileNotInEnvMarker()
62+
return
63+
}
64+
5965
/*
6066
* Register services
6167
*/
@@ -92,7 +98,7 @@ class AleValidator extends AbstractAleValidator {
9298
.forEach[msg | markerFactory.doSwitch(msg)]
9399
}
94100
catch (Exception e) {
95-
val marker = aleFile.createMarker(ALE_MARKER)
101+
val marker = aleFile.createMarker(AleMarkerTypes.DEFAULT)
96102
marker.setAttribute(IMarker.MESSAGE, "An internal error occurred while validating the file: " + e.message)
97103
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR)
98104
marker.setAttribute(IMarker.CHAR_START, 0)
@@ -162,6 +168,35 @@ class AleValidator extends AbstractAleValidator {
162168
}
163169

164170
private def cleanUpMarkers(IFile file) {
165-
file.deleteMarkers(ALE_MARKER, true, IResource.DEPTH_ZERO);
171+
file.deleteMarkers(AleMarkerTypes.DEFAULT, true, IResource.DEPTH_ZERO);
172+
file.deleteMarkers(AleMarkerTypes.SOURCE_FILE_NOT_IN_ENV, true, IResource.DEPTH_ZERO);
173+
}
174+
175+
/** Adds a marker warning about the file not being part of ALE environment */
176+
private static def createFileNotInEnvMarker(IFile file) {
177+
val marker = file.createMarker(AleMarkerTypes.SOURCE_FILE_NOT_IN_ENV)
178+
marker.setAttribute(IMarker.MESSAGE, "This file is not part of the project's ALE environment, it won't be validated")
179+
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING)
180+
marker.setAttribute(IMarker.CHAR_START, 0)
181+
marker.setAttribute(IMarker.LINE_NUMBER, 0)
182+
marker.setAttribute(IMarker.LOCATION, "line: " + 0 + " " + file.fullPath.toString())
183+
184+
// Attributes used by Xtext to find the associated quick fix
185+
186+
marker.setAttribute(Issue.CODE_KEY, AleMarkerTypes.SOURCE_FILE_NOT_IN_ENV)
187+
marker.setAttribute(Issue.COLUMN_KEY, 0)
188+
marker.setAttribute(Issue.URI_KEY, URI.createPlatformResourceURI(file.fullPath.toString(), true).toString)
189+
marker.setAttribute("FIXABLE_KEY", true);
190+
191+
/*
192+
* MUST BE SET LAST.
193+
*
194+
* Looks like the editor is updated when CHAR_END is set,
195+
* and the editor must be updated once all other attributes
196+
* are properly set.
197+
*
198+
* See https://www.eclipse.org/forums/index.php?t=msg&th=1104367&goto=1829410&#msg_1829410
199+
*/
200+
marker.setAttribute(IMarker.CHAR_END, 0)
166201
}
167202
}

0 commit comments

Comments
 (0)