77 | | @Check |
78 | | |
79 | | '''defvoid'''checkUnusedRule(Rule rule) { |
80 | | |
81 | | ''' var''' List<!RuleReference > references = !EbnfAnalysisUtils .'' findReferences'' (rule); |
82 | | |
83 | | ''' var''' List<Rule> references1 = !EbnfAnalysisUtils .'' findReferences'' (rule,resourceDescriptions); |
84 | | |
85 | | ''' if''' ((references.size+references1.size ==0) && (rule.getRulenumber() !=1)) |
86 | | warning(''unusedRuleDescription'', !EbnfPackage$Literals::''RULE!__NAME'',''unusedRuleDescription'', rule.name); |
87 | | |
| 58 | {{{ |
| 59 | @CheckdefvoidcheckUnusedRule(Rule rule) { var List<RuleReference > references = EbnfAnalysisUtils . findReferences (rule); var List<Rule> references1 = EbnfAnalysisUtils . findReferences (rule,resourceDescriptions); if ((references.size+references1.size ==0) && (rule.getRulenumber() !=1)) warning( unusedRuleDescription , EbnfPackage $Literals:: RULE__ NAME , unusedRuleDescription , rule.name);}For this the@Checkannotation defines that the next function is a Validationcheck. |
| 60 | }}} |
| 61 | The parameter can be any Entity from the previously defined Grammar and every Entity of this Type will be checked this way. |
| 62 | |
| 63 | And if the Check finds some inconsistency awarningwill be displayed to this Entity Instance in the Editor. |
| 64 | |
| 65 | The other files in the Package contain supporting Methodes for the validation |
| 66 | |
| 67 | like |
| 68 | |
| 69 | {{{ |
| 70 | EbnfAnalysisUtils.findReferences(rule); |
| 71 | }}} |
| 72 | or |
| 73 | |
| 74 | {{{ |
| 75 | EbnfAnalysisUtils.findReferences(rule,resourceDescriptions); |
| 76 | }}} |
| 77 | Which find the Rule references inside a BNF-File or outside a BNF-File. |
| 78 | |
| 79 | == Quickfixing can be applied to warnings given by Validations: == |
| 80 | In the File de.ugoe.cs.swe.bnftools.ebnf.ui/de.ugoe.cs.swe.bnftools.ui.quickfix/!EbnfQuickfixProvider.xtend |
| 81 | |
| 82 | quickfixes for validation-warnings can be defined e.g.: |
| 83 | |
| 84 | {{{ |
| 85 | @Fix(EbnfValidator.unusedRuleDescription) |
| 86 | def void fixUnusedRule(Issue issue, IssueResolutionAcceptor acceptor) { |
| 87 | |
| 88 | acceptor.accept(issue, "Remove unused rule", "Delete the unused rule", "upcase.png", |
| 89 | [ element, context | |
| 90 | var Rule rule = element as Rule; |
| 91 | var IXtextDocument xtextDocument = context.getXtextDocument(); |
| 92 | var ICompositeNode node = NodeModelUtils.findActualNodeFor(rule); |
| 93 | var int offset = node.textRegion.offset; |
| 94 | var String nodeText = node.text; |
| 95 | var int textLength = nodeText.length - 2; |
| 96 | xtextDocument.replace(offset, textLength, ""); |
| 97 | ]) |
| 98 | } |
| 99 | }}} |
| 100 | The@Fix(''String token'')annotation definies that the following method is a quickfix for a validationwarning, with that''token''as code parameter: |
| 101 | |
| 102 | {{{ |
| 103 | warning(unusedRuleDescription, EbnfPackage$Literals::RULE__NAME, unusedRuleDescription, rule.name); |
| 104 | }}} |
| 105 | {{{ |
| 106 | @Fix(EbnfValidator.unusedRuleDescription) |
| 107 | }}} |
| 108 | The accaptor inside applies the changes, via two possible ways: |
| 109 | |
| 110 | 1. Change the Document itself (like the example shows). |
| 111 | |
| 112 | 1. Change the underlying ecoremodel. |
| 113 | |
| 114 | == Generation allows to generate other files from a BNF-Document: == |
| 115 | In our case we create a .fo document, that can be transformed into a PDF-Document using Apache FOP. |
| 116 | |
| 117 | It can be customized in the File de.ugoe.cs.swe.bnftools.ebnf/de.ugoe.cs.swe.ebnf.generator/!EbnfGenerator.xtend |
| 118 | |
| 119 | Where thedoGeneratemethode defines how the files given by a Resource and a !IfileSystemAccess should generate a new file. While for every relevant Entity from the |
| 120 | |
| 121 | BNF a compile Methode handles the generation in the new file, while it calls the compile Methode for every related Entity e.g.: |
| 122 | |
| 123 | {{{ |
| 124 | def void doGenerate(Resource resource, IFileSystemAccess fsa,boolean mode) { |
| 125 | var String workspacePath = WorkspaceResolver.getWorkspace(); |
| 126 | for (e : resource.allContents.toIterable.filter(EtsiBnf)) { |
| 127 | if (e.bnfEntry.size != 0) { |
| 128 | fsa.generateFile(e.name + ".fo", e.compile) |
| 129 | } |
| 130 | } |
| 131 | } |
| 132 | }}} |
| 133 | Based on the generated .fo file a PDF-document can be generated for this the class de.ugoe.cs.swe.bnftools.ebnf/de.ugoe.cs.swe.ebnf.generator/foToPDF can be used, either by giving the .fo file and the output URI without Ending or simply the giving the classpath of the file. |
| 134 | |
| 135 | For this the doGenerateMethode needed an upgrade to access the filesystem via URIs: |
| 136 | |
| 137 | {{{ |
| 138 | def void doGenerate(Resource resource, IFileSystemAccess fsa,boolean mode) { |
| 139 | var String workspacePath = WorkspaceResolver.getWorkspace(); |
| 140 | for (e : resource.allContents.toIterable.filter(EtsiBnf)) { |
| 141 | if (e.bnfEntry.size != 0) { |
| 142 | fsa.generateFile(e.name + ".fo", e.compile) |
| 143 | |
| 144 | //generate pdf |
| 145 | var uri = (fsa as IFileSystemAccessExtension2).getURI(e.name + ".fo"); |
| 146 | var String fullUri = workspacePath + uri.path.substring(10, uri.path.length); |
| 147 | var File file = new File(fullUri); |
| 148 | |
| 149 | if (file.exists) { |
| 150 | //true -> pdf, false -> rtf |
| 151 | |
| 152 | if(mode){ |
| 153 | FoToPdfOrRtf.createRtfFromFo(fullUri.substring(0, fullUri.length - 3)); |
| 154 | }else{ |
| 155 | FoToPdfOrRtf.createPdfFromFo(fullUri.substring(0, fullUri.length - 3)); |
| 156 | } |
| 157 | |
| 158 | // fsa.deleteFile(e.name + ".fo"); |
| 159 | } |
| 160 | } |
| 161 | } |
| 162 | } |
| 163 | }}} |
| 164 | To include apache fop you need to add all the jars in a folder e.g. Libs in your project, add this folder to your buildpath, cofigure buildpath and add the jars to it and add them in the plugin.xml on the page runtime at classpath. |
| 165 | |
| 166 | == Formatting or Prittey Printing is to format the BNF-Document: == |
| 167 | In the File de.ugoe.cs.swe.bnftools.ebnf/de.ugoe.cs.swe.ebnf.formatting/!EbnfFormatter.xtend |
| 168 | |
| 169 | the Method configureFormatting(!FormattingConfig c)allows to define formatting rules |
| 170 | |
| 171 | before, after or between Enteties or Keywords. |
| 172 | |
| 173 | e.g.: |
| 174 | |
| 175 | {{{ |
| 176 | @Inject extension EbnfGrammarAccess override protected voidconfigureFormatting(FormattingConfig c) |
| 177 | { |
| 178 | c.setLinewrap(0,1,2).before(SL_COMMENTRule); |
| 179 | c.setLinewrap(0,1,2).before(ML_COMMENTRule); |
| 180 | c.setLinewrap(0,1,1).after(ML_COMMENTRule); |
| 181 | var EbnfGrammarAccess f = getGrammarAccess as EbnfGrammarAccess;c.setLinewrap.before(f.ruleRule); |
| 182 | c.setLinewrap.before(f.importRule);c.setNoSpace.after(f.ruleAccess.rulenumberINTTerminalRuleCall_0_0_0); |
89 | | |
90 | | For this the@Checkannotation defines that the next function is a Validationcheck. |
91 | | |
92 | | The parameter can be any Entity from the previously defined Grammar and every Entity of this Type will be checked this way. |
93 | | |
94 | | And if the Check finds some inconsistency awarningwill be displayed to this Entity Instance in the Editor. |
95 | | |
96 | | The other files in the Package contain supporting Methodes for the validation |
97 | | |
98 | | like |
99 | | |
100 | | !EbnfAnalysisUtils.''findReferences''(rule); |
101 | | |
102 | | or |
103 | | |
104 | | !EbnfAnalysisUtils.''findReferences''(rule,resourceDescriptions); |
105 | | |
106 | | Which find the Rule references inside a BNF-File or outside a BNF-File. |
107 | | |
108 | | [[BR]]== Quickfixing can be applied to warnings given by Validations: == |
109 | | |
110 | | In the File de.ugoe.cs.swe.bnftools.ebnf.ui/de.ugoe.cs.swe.bnftools.ui.quickfix/!EbnfQuickfixProvider.xtend |
111 | | |
112 | | quickfixes for validation-warnings can be defined e.g.: |
113 | | |
114 | | @Fix(!EbnfValidator.''unusedRuleDescription'') |
115 | | |
116 | | ''' defvoid'''fixUnusedRule(Issue issue, !IssueResolutionAcceptor acceptor) { |
117 | | |
118 | | acceptor.accept(issue,"Remove unused rule","Delete the unused rule", |
119 | | |
120 | | "upcase.png",[ element, context | |
121 | | |
122 | | ''' var''' Rule rule = element''' as''' Rule; |
123 | | |
124 | | ''' var''' IXtextDocument xtextDocument = context.getXtextDocument(); |
125 | | |
126 | | ''' var''' ICompositeNode node = !NodeModelUtils .'' findActualNodeFor'' (rule); |
127 | | |
128 | | ''' varint''' offset = node.textRegion.offset; |
129 | | |
130 | | ''' var''' String nodeText = node.text; |
131 | | |
132 | | ''' varint''' textLength = nodeText.length -2; |
133 | | |
134 | | xtextDocument.replace(offset, textLength,""); |
135 | | |
136 | | ]) |
137 | | |
| 184 | }}} |
| 185 | The Entities are recieved via an Inector that gives access to The Grammar. |
| 186 | |
| 187 | == Outlining and Labeling are Features, that show the document Structure of the BNF-Document: == |
| 188 | Outlinining can be customized in the File |
| 189 | |
| 190 | de.ugoe.cs.swe.bnftools.ebnf.ui/de.ugoe.cs.swe.bnftools.ui.outline/!EbnfOutlineTreeProvider.xtend. |
| 191 | |
| 192 | Here you can define a_createChildren()with the rootNode and the BNF-Entity of the Grammar to change the outline sequence: |
| 193 | |
| 194 | {{{ |
| 195 | def void_createChildren(DocumentRootNode parentNode, EtsiBnf bnf) { |
| 196 | createNode(parentNode,bnf); |
139 | | |
140 | | The@Fix(''String token'')annotation definies that the following method is a quickfix for a validationwarning, with that''token''as code parameter: |
141 | | |
142 | | warning(''unusedRuleDescription'', !EbnfPackage$Literals::''RULE!__NAME'', ''__unusedRuleDescription__'', rule.name); |
143 | | |
144 | | @Fix(!EbnfValidator.''__unusedRuleDescription__'') |
145 | | |
146 | | The accaptor inside applies the changes, via two possible ways: |
147 | | |
148 | | 1. Change the Document itself (like the example shows). |
149 | | |
150 | | 1. Change the underlying ecoremodel. |
151 | | |
152 | | [[BR]]== Generation allows to generate other files from a BNF-Document: == |
153 | | |
154 | | In our case we create a .fo document, that can be transformed into a PDF-Document |
155 | | |
156 | | using Apache FOP. |
157 | | |
158 | | It can be customized in the File de.ugoe.cs.swe.bnftools.ebnf/de.ugoe.cs.swe.ebnf.generator/!EbnfGenerator.xtend |
159 | | |
160 | | Where thedoGeneratemethode defines how the files given by a Resource and a !IfileSystemAccess should generate a new file. While for every relevant Entity from the |
161 | | |
162 | | BNF a |
163 | | |
164 | | compile |
165 | | |
166 | | Methode handles the generation in the new file, while it calls the compile Methode for every related Entity e.g.: |
167 | | |
168 | | '''override''' '''void''' doGenerate(Resource resource, IFileSystemAccess fsa) { |
169 | | |
170 | | ''' for''' (e : resource.allContents.'' toIterable'' .'' filter'' (!EtsiBnf )) { |
171 | | |
172 | | ''' if''' (e.bnfEntry.size !=0) { |
173 | | fsa.generateFile(e.name +".fo", e.compile) |
174 | | |
175 | | } |
176 | | |
177 | | } |
178 | | |
179 | | } |
180 | | |
181 | | '''def '''compile(!DefinitionList dList)!'''«'''FOR'''sDef : ist.singleDefinition»«sDef.compile» «'''IF''' !sDef.equals(dList.singleDefinition.''last'')»|«'''ENDIF'''»«'''ENDFOR'''»!''' |
182 | | |
183 | | Based on the generated .fo file a PDF-document can be generated for this the class de.ugoe.cs.swe.bnftools.ebnf/de.ugoe.cs.swe.ebnf.generator/foToPDF can be used, either by giving the .fo file and the output URI without Ending or simply the giving the classpath of the file. |
184 | | |
185 | | For this the dodoGenerateMethode needed an upgrade to access the filesystem via URIs: |
186 | | |
187 | | '''overridevoid'''doGenerate(Resource resource, IFileSystemAccess fsa) { |
188 | | |
189 | | ''' var'''String workspacePath = !WorkspaceResolver.''getWorkspace''(); |
190 | | |
191 | | ''' for'''(e : resource.allContents.''toIterable''.''filter''(!EtsiBnf)) { |
192 | | |
193 | | ''' if'''(e.bnfEntry.size !=0) { |
194 | | |
195 | | fsa.generateFile(e.name +".__fo__", e.compile) |
196 | | |
197 | | //generate__pdf__ |
198 | | |
199 | | ''' var '''uri = (fsa'''as'''IFileSystemAccessExtension2).getURI(e.name +".__fo__"); |
200 | | |
201 | | ''' var '''String fullUri = workspacePath + uri.path.substring(10, uri.path.length); |
202 | | |
203 | | ''' var '''File file ='''new'''File(fullUri); |
204 | | |
205 | | ''' if'''(file.exists) { |
206 | | |
207 | | foToPdf.''createPdfFromFo''(fullUri.substring(0, fullUri.length -3)); |
208 | | |
209 | | } |
210 | | |
211 | | } |
212 | | |
213 | | } |
214 | | |
215 | | } |
216 | | |
217 | | To include apache fop you need to add all the jars in a folder e.g. Libs in your project, add this folder to your buildpath, cofigure buildpath and add the jars to it and add them in the plugin.xml on the page runtime at classpath. |
218 | | |
219 | | [[BR]]== Formatting or Prittey Printing is to format the BNF-Document: == |
220 | | |
221 | | In the File de.ugoe.cs.swe.bnftools.ebnf/de.ugoe.cs.swe.ebnf.formatting/!EbnfFormatter.xtend |
222 | | |
223 | | the Method configureFormatting(!FormattingConfig c)allows to define formatting rules |
224 | | |
225 | | before, after or between Enteties or Keywords. |
226 | | |
227 | | e.g.: |
228 | | |
229 | | @Inject''' extension '''!EbnfGrammarAccess |
230 | | |
231 | | ''' override protected void'''configureFormatting(!FormattingConfig c) { |
232 | | |
233 | | c.setLinewrap(0,1,2).before(SL_COMMENTRule) |
234 | | |
235 | | c.setLinewrap(0,1,2).before(ML_COMMENTRule) |
236 | | |
237 | | c.setLinewrap(0,1,1).after(ML_COMMENTRule) |
238 | | |
239 | | ''' var '''!EbnfGrammarAccess f = getGrammarAccess''' as '''!EbnfGrammarAccess; |
240 | | |
241 | | c.setLinewrap.before(f.ruleRule); |
242 | | |
243 | | c.setLinewrap.before(f.importRule); |
244 | | |
245 | | c.setNoSpace.after(f.ruleAccess.rulenumberINTTerminalRuleCall_0_0_0) |
246 | | |
247 | | } |
248 | | |
249 | | The Entities are recieved via an Inector that gives access to The Grammar. |
250 | | |
251 | | [[BR]]== Outlining and Labeling are Features, that show the document Structure of the BNF-Document: == |
252 | | |
253 | | Outlinining can be customized in the File |
254 | | |
255 | | de.ugoe.cs.swe.bnftools.ebnf.ui/de.ugoe.cs.swe.bnftools.ui.outline/!EbnfOutlineTreeProvider.xtend. |
256 | | |
257 | | Here you can define a_createChildren()with the rootNode and the BNF-Entity of the Grammar to change the outline sequence: |
258 | | |
259 | | '''defvoid'''_createChildren(!DocumentRootNode parentNode, !EtsiBnf bnf) { |
260 | | |
261 | | createNode(parentNode,bnf); |
262 | | |
263 | | } |
264 | | |
| 198 | }}} |
306 | | |
307 | | In the File de.ugoe.cs.swe.bnftools.ebnf.ui/plugin.xml new extensions to the UI can be created in the plugin.xml tab. e.g.: |
308 | | |
309 | | <extension |
310 | | |
311 | | point="org.eclipse.ui.handlers"> |
312 | | |
313 | | <handler |
314 | | |
315 | | class="!de.ugoe.cs.swe.bnftools.ui.EbnfExecutableExtensionFactory:de.ugoe.cs.swe.bnftools.ui.handler.GenerationHandler" |
316 | | |
317 | | commandId="de.ugoe.cs.swe.bnftools.ui.handler.!GenerationCommand"> |
318 | | |
319 | | </handler> |
320 | | |
321 | | </extension> |
322 | | |
323 | | <extension |
324 | | |
325 | | point="org.eclipse.ui.commands"> |
326 | | |
327 | | <commandname="Generate Code" |
328 | | |
329 | | id="de.ugoe.cs.swe.bnftools.ui.handler.!GenerationCommand"> |
330 | | |
331 | | </command> |
332 | | |
333 | | </extension> |
334 | | |
335 | | <extensionpoint="org.eclipse.ui.menus"> |
336 | | |
337 | | <menuContributionlocationURI="!popup:org.eclipse.jdt.ui.PackageExplorer"> |
338 | | |
339 | | <command |
340 | | |
341 | | commandId="de.ugoe.cs.swe.bnftools.ui.handler.!GenerationCommand" |
342 | | |
343 | | style="push"> |
344 | | |
345 | | <visibleWhen |
346 | | |
347 | | checkEnabled="false"> |
348 | | |
349 | | <iterate> |
350 | | |
351 | | <adapttype="org.eclipse.core.resources.IResource"> |
352 | | |
353 | | <testproperty="org.eclipse.core.resources.name" |
354 | | |
355 | | value="*.bnf"/> |
356 | | |
357 | | </adapt> |
358 | | |
359 | | </iterate> |
360 | | |
361 | | </visibleWhen> |
362 | | |
363 | | </command> |
364 | | |
365 | | </menuContribution> |
366 | | |
367 | | </extension> |
368 | | |
369 | | This extension creates a new button in the popupmenu that opens when |
370 | | |
371 | | rightclicking a .bnf file which triggers a handlerde.ugoe.cs.swe.bnftools.ui.handler.!GenerationHandler |
372 | | |
373 | | for this File that should call the Generator of the Grammar for this File. |
374 | | |
375 | | @Override |
376 | | |
377 | | '''public '''Object execute(!ExecutionEvent event) '''throws '''!ExecutionException { |
378 | | |
379 | | ISelection selection = !HandlerUtil.''getCurrentSelection''(event); |
380 | | |
381 | | ''' if'''(selection''' instanceof '''IStructuredSelection) { |
382 | | |
383 | | IStructuredSelection structuredSelection = (IStructuredSelection) selection; |
384 | | |
385 | | Object firstElement = structuredSelection.getFirstElement(); |
386 | | |
387 | | ''' if'''(firstElement '''instanceof''' IFile) { |
388 | | |
389 | | IFile file = (IFile) firstElement; |
390 | | |
391 | | IProject project = file.getProject(); |
392 | | |
393 | | IFolder srcGenFolder = project.getFolder("src-gen"); |
394 | | |
395 | | ''' if'''(!srcGenFolder.exists()) { |
396 | | |
397 | | ''' try'''{ |
398 | | |
399 | | srcGenFolder.create('''true''','''true''','''new'''!NullProgressMonitor()); |
400 | | |
401 | | }'''catch'''(!CoreException e) { |
402 | | |
403 | | ''' returnnull'''; |
404 | | |
405 | | } |
406 | | |
407 | | } |
408 | | |
409 | | ''' final'''!EclipseResourceFileSystemAccess2 fsa =fileAccessProvider.get(); |
410 | | |
411 | | fsa.setOutputPath(srcGenFolder.getFullPath().toString()); |
412 | | |
413 | | URI uri = URI.''createPlatformResourceURI''(file.getFullPath().toString(),'''true'''); |
414 | | |
415 | | !ResourceSet rs =resourceSetProvider.get(project); |
416 | | |
417 | | Resource r = rs.getResource(uri,'''true'''); |
418 | | |
419 | | generator.doGenerate(r, fsa); |
420 | | |
421 | | } |
422 | | |
423 | | } |
424 | | |
425 | | ''' returnnull'''; |
426 | | |
427 | | } |
428 | | |
429 | | Here is a Problem since the!EclipseResourceFileSystemAccess2does not contain all the needed inforamtion. Maybe it can be looked up in the normal call of the generator. |
| 235 | Therefor i recomend reading this Guide http://flipsomel.wordpress.com/. |
| 236 | |
| 237 | But don't use the @Override annotation! |
441 | | First create your__xText Project__, then create a new__Plug-in Project.__Give it a name, |
442 | | |
443 | | e.g. de.ugoe.cs.swe.bnftools.ebnf.product. Click next, and unchoose__Generate an Activator, a Java Class that controls the plug-in-s life cycle__and__This plug-in will make contributions to the UI.__Also choose__no__at__Rich client Platform__. Press finish. |
444 | | |
445 | | now open the__Manifest.MF__, go to the__Overview page__and choose__This plug-in in a singleton__. Then go to the__Dependencies page__and add__org.eclipse.core.runtime__. |
446 | | |
447 | | Now create a product configuration in your product project, on its__Overview Page__click new, choose a fitting name and ID, your product project as defining Plugin and org.eclipse.ui.ide.workbench as application. Now go back to the__Manifest.MF__and open the__Extensions Page__. There you should now see 1 Extension__org.eclipse.core.runtime.products__with a product inside. This should have__org.eclipse.ui.ide.workbench__as application and the given name of the product configuration as name. Rightclick the product and create a new property and if you want you can give it a customized name and value. |
448 | | |
449 | | Now back to the p__roduct configuration__and its dependencies page. There you add all your xtext projects and your product, then click__add Requiered Plug-ins__. After this you still need to add the Plugins__org.eclipse.ui.ide.application__and__org.eclipse.core.net__ |
450 | | |
451 | | . now you can test your product by running it as a Runtime Eclipse, if there is a missing plugin you can find it using the__validate plugins option__in the run configurations plug-ins page . Deploy it using__Export as an Eclipse Product__in the__product configuration__. |
| 247 | First create your __xText Project__, then create a new __Plug-in Project__. Give it a name, |
| 248 | |
| 249 | e.g. de.ugoe.cs.swe.bnftools.ebnf.product. Click next, and unchoose __Generate an Activator, a Java Class that controls the plug-in-s life cycle__ and __This plug-in will make contributions to the UI__. Also choose __no__ at __Rich client Platform__. Press finish. |
| 250 | |
| 251 | now open the __Manifest.MF__, go to the __Overview page__ and choose __This plug-in in a singleton__. Then go to the __Dependencies page__ and add __org.eclipse.core.runtime__. |
| 252 | |
| 253 | Now create a product configuration in your product project, on its __Overview Page__click new, choose a fitting name and ID, your product project as defining Plugin and org.eclipse.ui.ide.workbench as application. Now go back to the __Manifest.MF__and open the __Extensions Page__. There you should now see 1 Extension __org.eclipse.core.runtime.products__ with a product inside. This should have __org.eclipse.ui.ide.workbench__ as application and the given name of the product configuration as name. Rightclick the product and create a new property and if you want you can give it a customized name and value. |
| 254 | |
| 255 | Now back to the p __roduct configuration__ and its dependencies page. There you add all your xtext projects and your product, then click __add Requiered Plug-ins__. After this you still need to add the Plugins __org.eclipse.ui.ide.application__ and __org.eclipse.core.net__. Now you can test your product by running it as a Runtime Eclipse, if there is a missing plugin you can find it using the_ _validate plugins option__ in the run configurations plug-ins page . Deploy it using __Export as an Eclipse Product__ in the __product configuration__.__ |