initial commit

This commit is contained in:
sefftinge 2008-05-09 15:57:38 +00:00
commit b6618a76b0
32 changed files with 1607 additions and 0 deletions

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="model"/>
<classpathentry kind="src" path="emf-gen"/>
<classpathentry kind="src" path="src-gen"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.xtext</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.openarchitectureware.base.oawBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.openarchitectureware.base.oawNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
#Thu May 08 15:38:19 CEST 2008
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

View file

@ -0,0 +1,21 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.xtext;singleton:=true
Bundle-Version: 1.0.0
Bundle-ClassPath: .
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Export-Package: org.eclipse.xtext,
org.eclipse.xtext.parser,
org.eclipse.xtext.util,
org.eclipse.xtext.xtextutil,
org.eclipse.xtext.xtextutil.util
Require-Bundle: org.eclipse.emf.ecore;visibility:=reexport,
org.antlr,
org.apache.commons.logging,
org.openarchitectureware.util.stdlib,
org.eclipse.xtext.core;bundle-version="1.0.0",
org.eclipse.emf.ecore.xmi;bundle-version="2.3.2"
Eclipse-LazyStart: true

View file

@ -0,0 +1,14 @@
# <copyright>
# </copyright>
#
# $Id: build.properties,v 1.1 2008/05/09 15:57:38 sefftinge Exp $
bin.includes = .,\
model/,\
META-INF/,\
plugin.xml,\
plugin.properties
jars.compile.order = .
source.. = src/, emf-gen/, model/, src-gen/
output.. = bin/

View file

@ -0,0 +1,65 @@
<?xml version="1.0" encoding="UTF-8"?>
<genmodel:GenModel xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.xtext/emf-gen"
editDirectory="/org.eclipse.xtext.edit/emf-gen" modelPluginID="org.eclipse.xtext"
modelName="Xtext" importerID="org.eclipse.emf.importer.ecore" complianceLevel="5.0"
copyrightFields="false" providerRootExtendsClass="">
<foreignModel>../src-gen/org/eclipse/xtext/xtext.ecore</foreignModel>
<genPackages prefix="Xtext" basePackage="org.eclipse" disposableProviderFactory="true"
ecorePackage="../src-gen/org/eclipse/xtext/xtext.ecore#/">
<genClasses image="false" ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//AbstractRule">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//AbstractRule/name"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//AbstractElement">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//AbstractElement/cardinality"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//TypeRef">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//TypeRef/name"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//ParserRule">
<genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference ../src-gen/org/eclipse/xtext/xtext.ecore#//ParserRule/alternatives"/>
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ../src-gen/org/eclipse/xtext/xtext.ecore#//ParserRule/type"/>
</genClasses>
<genClasses image="false" ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//AbstractMetamodelDeclaration">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//AbstractMetamodelDeclaration/alias"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//LexerRule">
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//LexerRule/body"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//Grammar">
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ../src-gen/org/eclipse/xtext/xtext.ecore#//Grammar/parserRules"/>
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ../src-gen/org/eclipse/xtext/xtext.ecore#//Grammar/metamodelDeclarations"/>
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ../src-gen/org/eclipse/xtext/xtext.ecore#//Grammar/lexerRules"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//GeneratedMetamodel">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//GeneratedMetamodel/nsURI"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//GeneratedMetamodel/name"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//ReferencedMetamodel">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//ReferencedMetamodel/uri"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//Assignment">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//Assignment/feature"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//Assignment/operator"/>
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ../src-gen/org/eclipse/xtext/xtext.ecore#//Assignment/terminal"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//Action">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//Action/operator"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//Action/feature"/>
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ../src-gen/org/eclipse/xtext/xtext.ecore#//Action/typeName"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//Keyword">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//Keyword/value"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//RuleCall">
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute ../src-gen/org/eclipse/xtext/xtext.ecore#//RuleCall/name"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//Group">
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ../src-gen/org/eclipse/xtext/xtext.ecore#//Group/abstractTokens"/>
</genClasses>
<genClasses ecoreClass="../src-gen/org/eclipse/xtext/xtext.ecore#//Alternatives">
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference ../src-gen/org/eclipse/xtext/xtext.ecore#//Alternatives/groups"/>
</genClasses>
</genPackages>
</genmodel:GenModel>

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="xtextutil"
nsURI="http://www.eclipse.org/2008/Xtext/Utilities" nsPrefix="xtextutil">
<eClassifiers xsi:type="ecore:EClass" name="ResolvedType" eSuperTypes="#//AbstractType">
<eStructuralFeatures xsi:type="ecore:EReference" name="metaModel" eType="#//MetaModel"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="MetaModel">
<eStructuralFeatures xsi:type="ecore:EReference" name="ePackage" eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EPackage"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="alias" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="referenced" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
<eStructuralFeatures xsi:type="ecore:EReference" name="declaration" eType="ecore:EClass ../src-gen/org/eclipse/xtext/xtext.ecore#//AbstractMetamodelDeclaration"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="AbstractType" abstract="true">
<eStructuralFeatures xsi:type="ecore:EReference" name="eClassifier" eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EClassifier"/>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="BuiltinType" eSuperTypes="#//AbstractType"/>
</ecore:EPackage>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<genmodel:GenModel xmi:version="2.0"
xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.xtext/emf-gen"
modelPluginID="org.eclipse.xtext" modelName="Xtextutil" importerID="org.eclipse.emf.importer.ecore"
complianceLevel="5.0" copyrightFields="false" usedGenPackages="xtext.genmodel#//xtext">
<foreignModel>xtextutil.ecore</foreignModel>
<genPackages prefix="Xtextutil" basePackage="org.eclipse.xtext" disposableProviderFactory="true"
ecorePackage="xtextutil.ecore#/">
<genClasses ecoreClass="xtextutil.ecore#//ResolvedType">
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference xtextutil.ecore#//ResolvedType/metaModel"/>
</genClasses>
<genClasses ecoreClass="xtextutil.ecore#//MetaModel">
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference xtextutil.ecore#//MetaModel/ePackage"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute xtextutil.ecore#//MetaModel/alias"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute xtextutil.ecore#//MetaModel/referenced"/>
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference xtextutil.ecore#//MetaModel/declaration"/>
</genClasses>
<genClasses image="false" ecoreClass="xtextutil.ecore#//AbstractType">
<genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference xtextutil.ecore#//AbstractType/eClassifier"/>
<genFeatures createChild="false" ecoreFeature="ecore:EAttribute xtextutil.ecore#//AbstractType/name"/>
</genClasses>
<genClasses ecoreClass="xtextutil.ecore#//BuiltinType"/>
</genPackages>
</genmodel:GenModel>

View file

@ -0,0 +1,20 @@
# <copyright>
# </copyright>
#
# $Id: plugin.properties,v 1.1 2008/05/09 15:57:38 sefftinge Exp $
# ====================================================================
# To code developer:
# Do NOT change the properties between this line and the
# "%%% END OF TRANSLATED PROPERTIES %%%" line.
# Make a new property name, append to the end of the file and change
# the code to use the new property.
# ====================================================================
# ====================================================================
# %%% END OF TRANSLATED PROPERTIES %%%
# ====================================================================
pluginName = Xtext2 Model
providerName = www.example.org

View file

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.0"?>
<!--
<copyright>
</copyright>
$Id: plugin.xml,v 1.1 2008/05/09 15:57:38 sefftinge Exp $
-->
<plugin>
<extension point="org.eclipse.emf.ecore.generated_package">
<package
uri = "http://www.ecipse.org/tmf/xtext2"
class = "org.eclispe.tmf.xtext2.Xtext2Package"
genModel = "model/xtext2.genmodel" />
</extension>
</plugin>

View file

@ -0,0 +1,85 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* committers of openArchitectureWare - initial API and implementation
*******************************************************************************/
generate xtext "http://www.eclipse.org/2008/Xtext"
Grammar :
metamodelDeclarations+=AbstractMetamodelDeclaration*
parserRules+=ParserRule*
('lexing' ':'
lexerRules+=LexerRule+)?
;
AbstractRule : LexerRule | ParserRule;
AbstractMetamodelDeclaration :
GeneratedMetamodel | ReferencedMetamodel;
GeneratedMetamodel :
'generate' name=ID nsURI=STRING ('as' alias=ID)?;
ReferencedMetamodel :
'import' uri=STRING ('as' alias=ID)?;
LexerRule :
name=ID ':'
body=LEXER_BODY
;
ParserRule :
name=ID ('returns' type=TypeRef)? ':'
alternatives=Alternatives
';'
;
TypeRef :
name=ID
;
Alternatives returns AbstractElement:
Group ({Alternatives.groups+=current} '|' groups+=Group)*
;
Group returns AbstractElement:
AbstractToken ( {current=Group.abstractTokens+=current} abstractTokens+=AbstractToken)*
;
AbstractToken returns AbstractElement:
(Assignment |
Action |
AbstractTerminal) (cardinality=('?'|'*'|'+'))?;
Assignment returns Assignment:
feature=ID operator=('+='|'='|'?=') terminal=AbstractTerminal;
Action returns Action:
'{' ('current' '=')? typeName=TypeRef '.' feature=ID operator=('='|'+=') 'current' '}';
AbstractTerminal returns AbstractElement:
Keyword | RuleCall | ParenthesizedElement
;
ParenthesizedElement returns AbstractElement:
'(' Alternatives ')'
;
Keyword :
value=STRING
;
RuleCall :
name=ID ;
// lexing:
// Problem: LEXER_BODY kann nicht in xtxt beschrieben werden, da das erste '#>' bereits matcht
// Lösung: built-in lexer token
// LEXER_BODY : <# '<#' ( options {greedy=false;} : . )* '#>' #>

View file

@ -0,0 +1,137 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* committers of openArchitectureWare - initial API and implementation
*******************************************************************************/
import ecore;
import xtext;
import xtextutil;
extension org::openarchitectureware::util::stdlib::io;
// ***********************************************************************************
// Containers
Grammar grammar(emf::EObject e) :
(Grammar) e.eRootContainer
;
Grammar grammar(ResolvedType t) :
t.metaModel.grammar()
;
Grammar grammar(MetaModel mm) :
mm.declaration.grammar()
;
ParserRule containingParserRule(emf::EObject e) :
if e.metaType==ParserRule then
e
else
if e.eContainer != null then
e.eContainer.containingParserRule()
else
null
;
Assignment containingAssignment(emf::EObject e) :
if e.metaType==Assignment then
e
else
if e.eContainer != null then
e.eContainer.containingAssignment()
else
null
;
// ***********************************************************************************
// Containment
List[Action] allActions(emf::EObject o) :
o.eAllContents.typeSelect(Action)
;
List[RuleCall] allRuleCalls(emf::EObject o) :
o.eAllContents.typeSelect(RuleCall)
;
List[Assignment] allAssignments(emf::EObject o) :
o.eAllContents.typeSelect(Assignment)
;
List[AbstractRule] allRules(Grammar this) :
parserRules.union(allLexerRules());
// ***********************************************************************************
// Shortcuts
ParserRule calledParserRule(RuleCall this) :
if ParserRule.isInstance(calledRule()) then calledRule();
AbstractRule calledRule(RuleCall this) :
grammar().allRules().select(p | p.name == name).first()
;
String getReturnTypeName(ParserRule p) :
if p.type != null then
p.type.name
else
p.name
;
boolean referenced(ResolvedType t) :
t.metaModel.referenced
;
boolean isKeywordAssignment(Assignment a) :
Keyword.isInstance(a.terminal) ||
a.eAllContents.forAll(e | !(RuleCall.isInstance(e)));
boolean isRuleAssignment(Assignment a) :
RuleCall.isInstance(a.terminal);
withoutQuotes(Keyword this) :
value.trimFromStartAndEnd(1);
trimFromStartAndEnd(String this, Integer i) :
this.subString(i,this.length-i);
isAssigned(RuleCall this) : isAssigned(eContainer);
isAssigned(Alternatives this) : isAssigned(eContainer);
isAssigned(Assignment this) : true;
isAssigned(Object this) : false;
// ***********************************************************************************
// Built-in lexer Rules
cached allLexerRules(Grammar this) :
lexerRules.union(builtinRules().select(e|lexerRules.forAll(e1|e1.name != e.name)));
private create LexerRule lr(String name, String body) :
setName(name) ->
setBody(body);
cached builtinRules() :
{
lr('ID',"('^')?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*"),
lr('INT',"('0'..'9')+"),
lr('LEXER_BODY',"'<#' ( options {greedy=false;} : . )* '#>'"),
lr('STRING', "'"+dq()+"' ( '"+bs2()+"' ('b'|'t'|'n'|'f'|'r'|'"+bs()+""+dq()+"'|'"+bs()+"''|'"+bs2()+"') | ~('"+bs2()+"'|'"+dq()+"') )* '"+dq()+"' |
'"+bs()+"'' ( '"+bs2()+"' ('b'|'t'|'n'|'f'|'r'|'"+bs()+""+dq()+"'|'"+bs()+"''|'"+bs2()+"') | ~('"+bs2()+"'|'"+bs()+"'') )* '"+bs()+"''"),
lr('ML_COMMENT',"'/*' ( options {greedy=false;} : . )* '*/' {$channel=HIDDEN;}"),
lr('SL_COMMENT',"'//' ~('"+bs()+"n'|'"+bs()+"r')* '"+bs()+"r'? '"+bs()+"n' {$channel=HIDDEN;}"),
lr('WS',"(' '|'"+bs()+"t'|'"+bs()+"r'|'"+bs()+"n')+ {$channel=HIDDEN;}")
};
private dq() : '"';
private bs() : '\\';
private bs2() : bs()+bs();

View file

@ -0,0 +1,229 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* committers of openArchitectureWare - initial API and implementation
*******************************************************************************/
import ecore;
import xtext;
import xtextutil;
extension org::openarchitectureware::util::stdlib::io;
extension org::eclipse::xtext::Extensions;
// ***********************************************************************************
// Assignment
cached List[Assignment] assignments(ResolvedType t) :
t.grammar().allAssignments().select(a | a.currentType() == t)
;
boolean isBoolean(Assignment a) :
a.operator == "?="
;
boolean featureIsReference(Assignment a) :
!a.isBoolean()
&& a.isRuleAssignment()
&& ParserRule.isInstance(((RuleCall) a.terminal).calledRule())
;
AbstractType featureType(Assignment a) :
if a.featureIsReference() then
((RuleCall) a.terminal).calledParserRule().resolveReturnType()
else if a.isBoolean() then
BuiltinBoolean()
else if a.isKeywordAssignment() then
BuiltinString()
else
((RuleCall) a.terminal).calledRule().resolveReturnType()
;
// ***********************************************************************************
// Supertype inference
cached Set[ResolvedType] inferredSuperTypes(ResolvedType t) :
allActionsReturning(t).inferredSuperType().removeNulls().union(
allRuleCallsReturning(t).inferredSuperType().removeNulls()).toSet().remove(t)
;
private ResolvedType inferredSuperType(Action a) :
a.containingParserRule().resolveReturnType()
;
private ResolvedType inferredSuperType(RuleCall r) :
if r.containingAssignment() == null then
r.containingParserRule().resolveReturnType()
else
null
;
private List[ResolvedType] removeNulls(List[ResolvedType] l) :
l.reject(t|t==null)
;
// ***********************************************************************************
// Lookup
List[Action] allActionsReturning(ResolvedType t) :
t.grammar().allActions().select(a | a.resolveCreatedType() == t)
;
List[RuleCall] allRuleCallsReturning(ResolvedType t) :
t.grammar().allRuleCalls().select(r | r.calledParserRule() != null
&& r.calledParserRule().resolveReturnType() == t)
;
// ***********************************************************************************
// Current type
ResolvedType currentType(emf::EObject o) :
let containmentList = o.eContainer.eContents:
let index = containmentList.indexOf(o) :
if index==0 then
currentType(o.eContainer)
else
currentType(getLastChild(containmentList.get(index - 1)))
;
emf::EObject getLastChild(emf::EObject o) :
if o.eContents.isEmpty then
o
else getLastChild(o.eContents.last())
;
ResolvedType currentType(Action a) :
a.resolveCreatedType()
;
ResolvedType currentType(ParserRule p) :
p.resolveReturnType()
;
Boolean isAbstract(ResolvedType type) :
!type.grammar().allActions().resolveCreatedType().contains(type)
&& !type.grammar().allAssignments().currentType().contains(type)
;
// ***********************************************************************************
// Type resolution
cached ResolvedType resolveReturnType(ParserRule p) :
resolveType(p.grammar(), p.getReturnTypeName())
;
cached ResolvedType resolveReturnType(LexerRule p) :
if p.name == "INT" then
BuiltinInteger()
else if p.name == "REAL" then
BuiltinDouble()
else
BuiltinString()
;
cached ResolvedType resolveReturnType(AbstractRule p) :
error("AbstractRule must be either ParserRule or LexerRule") ->
null
;
cached ResolvedType resolveCreatedType(Action a) :
resolveType(a.grammar(), a.typeName.name)
;
cached ResolvedType resolveType(Grammar g, String name) :
if name.isQualified() then
g.allMetamodels().select(mm | mm.alias == name.getAlias())
.resolveType(name.getClassName()).first()
else
g.allMetamodels().select(mm | mm.alias == null || mm.alias == "")
.resolveType(name.getClassName()).first()
// TODO handle first / null
;
private cached ResolvedType resolveType(MetaModel mm, String className) :
//info("resolveType " + mm.alias + "::" + className) ->
if !mm.referenced then
// type has to be created
createResolvedType(mm, null, className)
else
let eClass = mm.ePackage.eClassifiers.typeSelect(EClass).select(c|c.name == className).first():
if eClass != null then
createResolvedType(mm, eClass, className)
else
null
;
private create ResolvedType createResolvedType(MetaModel mm, EClass eClass, String className) :
setEClassifier(eClass) ->
setName(className) ->
setMetaModel(mm)
;
// ***********************************************************************************
// Builtin Types
BuiltinType BuiltinBoolean() :
JAVA org.eclipse.xtext.Xtext2Extensions.BuiltinEBoolean();
BuiltinType BuiltinInteger() :
JAVA org.eclipse.xtext.Xtext2Extensions.BuiltinEInt();
BuiltinType BuiltinDouble() :
JAVA org.eclipse.xtext.Xtext2Extensions.BuiltinEDouble();
BuiltinType BuiltinString() :
JAVA org.eclipse.xtext.Xtext2Extensions.BuiltinEString();
// ***********************************************************************************
// Type names
private boolean isQualified(String name) :
name.contains("::")
;
private String getClassName(String fqn) :
fqn.split("::").last()
;
private String getAlias(String fqn) :
fqn.split("::").first()
;
// ***********************************************************************************
// Metamodels
cached List[MetaModel] allMetamodels(Grammar g) :
g.referencedMetamodels().union(g.createdMetamodels())
;
cached List[MetaModel] referencedMetamodels(Grammar g) :
g.metamodelDeclarations.typeSelect(ReferencedMetamodel).loadMetaModel()
;
cached List[MetaModel] createdMetamodels(Grammar g) :
g.metamodelDeclarations.typeSelect(GeneratedMetamodel).createMetamodel()
;
private create MetaModel createMetamodel(GeneratedMetamodel gmm) :
setReferenced(false) ->
setAlias(alias)->
setDeclaration(gmm)
;
create MetaModel loadMetaModel(ReferencedMetamodel rmm) :
setEPackage(loadEPackage(rmm.uri)) ->
setReferenced(true) ->
setAlias(rmm.alias) ->
setDeclaration(rmm)
;
cached EPackage loadEPackage(String uri) :
JAVA org.eclipse.xtext.Xtext2Extensions.loadEPackage(java.lang.String)
;

View file

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* committers of openArchitectureWare - initial API and implementation
*******************************************************************************/
import ecore;
import xtext;
import xtextutil;
extension org::eclipse::xtext::Extensions;
extension org::eclipse::xtext::TypeResolution;
context Action ERROR "Created class " + typeName.name + " cannot be resolved" :
resolveCreatedType() != null;
context Action if resolveCreatedType() != null ERROR "Created class does not inherit from the rule's return type" :
!resolveCreatedType().referenced()
|| ((EClass) containingParserRule().resolveReturnType().eClassifier).isSuperTypeOf((EClass) resolveCreatedType().eClassifier);
context Assignment ERROR "Assigned token must be a keyword or a rule call" :
Keyword.isInstance(terminal) || RuleCall.isInstance(terminal);
context GeneratedMetamodel ERROR "Only one generated metamodel can have default alias" :
alias != null
|| alias != ""
|| grammar().metamodelDeclarations.typeSelect(GeneratedMetamodel).select(gmm|gmm.alias == null || gmm.alias =="").size == 1;
context GeneratedMetamodel ERROR "Duplicate aliases are only allowed for referenced metamodels" :
grammar().metamodelDeclarations.typeSelect(GeneratedMetamodel).select(gmm|gmm.alias == alias).size == 1;
context Group ERROR "Group cannot contain more than one action" :
eAllContents.typeSelect(Action).size <= 1;
context ParserRule ERROR "Name mut be unique" :
grammar().parserRules.select(p | p.name == name).size==1;
context ParserRule ERROR "Returned class " + getReturnTypeName() + " cannot be resolved" :
resolveReturnType() != null;
// referenced EPackages must not contain duplicate classifiers
context ReferencedMetamodel ERROR "Metamodels with same alias must not have a classifier in common" :
loadMetaModel().ePackage.eClassifiers.name.intersect(
grammar().referencedMetamodels().select(mm|mm.alias==alias && mm.declaration != this).ePackage.eClassifiers.name.flatten()).isEmpty;

View file

@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* committers of openArchitectureWare - initial API and implementation
*******************************************************************************/
package org.eclipse.xtext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.xtext.xtextutil.BuiltinType;
import org.eclipse.xtext.xtextutil.XtextutilFactory;
/**
* @author Jan Köhnlein
*
*/
public class Xtext2Extensions {
private static Log log = LogFactory.getLog(Xtext2Extensions.class);;
private static final BuiltinType BUILTIN_EBOOLEAN;
private static final BuiltinType BUILTIN_EINT;
private static final BuiltinType BUILTIN_EDOUBLE;
private static final BuiltinType BUILTIN_ESTRING;
static {
BUILTIN_EBOOLEAN = XtextutilFactory.eINSTANCE.createBuiltinType();
BUILTIN_EBOOLEAN.setName("EBoolean");
BUILTIN_EBOOLEAN.setEClassifier(EcorePackage.Literals.EBOOLEAN);
BUILTIN_EINT = XtextutilFactory.eINSTANCE.createBuiltinType();
BUILTIN_EINT.setName("EInt");
BUILTIN_EINT.setEClassifier(EcorePackage.Literals.EINT);
BUILTIN_EDOUBLE = XtextutilFactory.eINSTANCE.createBuiltinType();
BUILTIN_EDOUBLE.setName("EDouble");
BUILTIN_EDOUBLE.setEClassifier(EcorePackage.Literals.EDOUBLE);
BUILTIN_ESTRING = XtextutilFactory.eINSTANCE.createBuiltinType();
BUILTIN_ESTRING.setName("EString");
BUILTIN_ESTRING.setEClassifier(EcorePackage.Literals.ESTRING);
};
public static BuiltinType BuiltinEBoolean() {
return BUILTIN_EBOOLEAN;
}
public static BuiltinType BuiltinEInt() {
return BUILTIN_EINT;
}
public static BuiltinType BuiltinEDouble() {
return BUILTIN_EDOUBLE;
}
public static BuiltinType BuiltinEString() {
return BUILTIN_ESTRING;
}
public static final EPackage loadEPackage(String uriAsString) {
URI uri = URI.createURI(uriAsString);
Resource resource = new ResourceSetImpl().getResource(uri, true);
for (TreeIterator<EObject> allContents = resource.getAllContents(); allContents
.hasNext();) {
EObject next = allContents.next();
if (next instanceof EPackage) {
EPackage ePackage = (EPackage) next;
if (ePackage.getNsURI() != null
&& ePackage.getNsURI().equals(uriAsString)) {
return ePackage;
}
}
}
log.error("Could not load EPackage with nsURI" + uriAsString);
return null;
}
}

View file

@ -0,0 +1,61 @@
Model Xtext2
This model description is not a real EMF artifact. It was generated by the
org.eclipse.emf.examples.generator.validator plug-in to illustrate how EMF's
code generator can be extended.
This can be disabled with -vmargs -Dorg.eclipse.emf.examples.generator.validator=false.
Package xtext2 <http://www.ecipse.org/tmf/xtext2>
Class Grammar
Reference metamodelDeclarations : AbstractMetamodelDeclaration<<0..*>>
Reference parserRules : ParserRule<<0..*>>
Reference lexerRules : LexerRule<<0..*>>
Class AbstractMetamodelDeclaration
Attribute alias : EString
Class GeneratedMetamodel -> AbstractMetamodelDeclaration
Attribute name : EString
Attribute nsURI : EString
Class ReferencedMetamodel -> AbstractMetamodelDeclaration
Attribute uri : EString
Class AbstractRule
Attribute name : EString
Class LexerRule -> AbstractRule
Attribute body : EString
Class ParserRule -> AbstractRule
Reference type : TypeRef
Reference alternatives : AbstractElement
Class TypeRef
Attribute name : EString
Class Alternatives -> AbstractElement
Reference groups : AbstractElement<<0..*>>
Class Group -> AbstractElement
Reference abstractTokens : AbstractElement<<0..*>>
Class AbstractElement
Attribute cardinality : EString
Class Assignment -> AbstractElement
Attribute feature : EString
Attribute operator : EString
Reference terminal : AbstractElement
Class Action -> AbstractElement
Reference typeName : TypeRef
Attribute feature : EString
Attribute operator : EString
Class Keyword -> AbstractElement
Attribute value : EString
Class RuleCall -> AbstractElement
Attribute name : EString

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="src-gen"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.eclipse.xtext.generator.tests</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.api.tools.apiAnalysisBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.pde.api.tools.apiAnalysisNature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,7 @@
#Wed May 07 16:13:48 CEST 2008
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.5

View file

@ -0,0 +1,19 @@
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Xtext2 Generator Tests Plug-in
Bundle-SymbolicName: org.eclipse.xtext.generator.tests
Bundle-Version: 1.0.0
Bundle-Vendor: eclipse.org
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Require-Bundle: org.eclipse.xtext.core;bundle-version="1.0.0",
org.eclipse.xtext;bundle-version="1.0.0",
org.eclipse.xtext.generator;bundle-version="1.0.0",
org.openarchitectureware.xtext.core;bundle-version="4.3.0",
org.openarchitectureware.xtext.core.base;bundle-version="4.3.0",
org.openarchitectureware.xtext.generator;bundle-version="4.3.0",
org.junit,
org.antlr;bundle-version="3.0.0",
org.openarchitectureware.dependencies;bundle-version="4.3.0",
org.eclipse.emf.compare,
org.eclipse.emf.compare.diff,
org.eclipse.emf.compare.match

View file

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View file

@ -0,0 +1,86 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.xtext;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.m2t.type.emf.EmfRegistryMetaModel;
import org.eclipse.xtext.generator.tests.AbstractGeneratorTest;
import org.eclipse.xtext.generator.tests.Invocation;
import org.eclipse.xtext.parser.XtextGrammarTestFactory;
import org.openarchitectureware.expression.ExecutionContextImpl;
import org.openarchitectureware.xtend.XtendFacade;
/**
* @author Sven Efftinge - Initial contribution and API
*
*/
public class XtextGrammarTest extends AbstractGeneratorTest {
public void testBootstrapping() throws Exception {
List<Invocation> parse = parse("generate foo 'bar' Foo : name=ID;");
Iterator<Invocation> iter = parse.iterator();
for (Invocation invocation : parse) {
System.out.println(invocation);
}
assertEquals("create(GeneratedMetamodel)", iter.next().toString());
assertEquals("set(name,[@2,9:11='foo',<4>,1:9])", iter.next().toString());
assertEquals("set(nsURI,[@4,13:17=''bar'',<5>,1:13])", iter.next().toString());
assertEquals("create(Grammar)", iter.next().toString());
assertEquals("add(metamodelDeclarations,GeneratedMetamodel)", iter.next().toString());
assertEquals("create(ParserRule)", iter.next().toString());
assertEquals("set(name,[@6,19:21='Foo',<4>,1:19])", iter.next().toString());
assertEquals("create(Assignment)", iter.next().toString());
assertEquals("set(feature,[@10,25:28='name',<4>,1:25])", iter.next().toString());
assertEquals("set(operator,[@11,29:29='=',<23>,1:29])", iter.next().toString());
assertEquals("create(RuleCall)", iter.next().toString());
assertEquals("set(name,[@12,30:31='ID',<4>,1:30])", iter.next().toString());
assertEquals("set(terminal,RuleCall)", iter.next().toString());
assertEquals("set(alternatives,Assignment)", iter.next().toString());
assertEquals("add(parserRules,ParserRule)", iter.next().toString());
}
public void testInstantiate() throws Exception {
EObject grammar = (EObject) parse("generate foo 'bar' Foo : name=ID;", new XtextGrammarTestFactory());
assertWithXtend("'Foo'","parserRules.first().name",grammar);
assertWithXtend("'name'","parserRules.first().alternatives.feature",grammar);
}
public void testInstantiateXtextGrammar() throws Exception {
InputStream bootGrammar = getClass().getClassLoader().getResourceAsStream(getClass().getName().replace('.','/')+".xtext");
EObject grammar = (EObject) parse(bootGrammar , new XtextGrammarTestFactory());
assertWithXtend("true","parserRules.select(e|e.name=='AbstractToken').first()!=null",grammar);
assertWithXtend("'AbstractElement'","parserRules.select(e|e.name=='AbstractToken').first().type.name",grammar);
// Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put(
// "xmi", new XMIResourceFactoryImpl());
// Resource resource = new ResourceSetImpl().createResource(URI.createURI("foo.xmi"));
// resource.getContents().add(grammar);
// resource.save(null);
}
@Override
protected XtendFacade getXtendFacade() {
ExecutionContextImpl ctx = new ExecutionContextImpl();
ctx.registerMetaModel(new EmfRegistryMetaModel() {
@Override
protected EPackage[] allPackages() {
return new EPackage[]{XtextGrammarTestEPackageAccess.getXtextTestEPackage()};
}
});
return XtendFacade.create(ctx);
}
}

View file

@ -0,0 +1,83 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
generate XtextTest "http://www.eclipse.org/2008/Test/XtextTest"
Grammar :
metamodelDeclarations+=AbstractMetamodelDeclaration*
parserRules+=ParserRule*
('lexing' ':'
lexerRules+=LexerRule+)?
;
AbstractRule : LexerRule | ParserRule;
AbstractMetamodelDeclaration :
GeneratedMetamodel | ReferencedMetamodel;
GeneratedMetamodel :
'generate' name=ID nsURI=STRING ('as' alias=ID)?;
ReferencedMetamodel :
'import' uri=STRING ('as' alias=ID)?;
LexerRule :
name=ID ':'
body=LEXER_BODY
;
ParserRule :
name=ID ('returns' type=TypeRef)? ':'
alternatives=Alternatives
';'
;
TypeRef :
name=ID
;
Alternatives returns AbstractElement:
Group ({Alternatives.groups+=current} '|' groups+=Group)*
;
Group returns AbstractElement:
AbstractToken ( {current=Group.abstractTokens+=current} abstractTokens+=AbstractToken)*
;
AbstractToken returns AbstractElement:
(Assignment |
Action |
AbstractTerminal) cardinality=('?'|'*'|'+')?;
Assignment returns Assignment:
feature=ID operator=('+='|'='|'?=') terminal=AbstractTerminal;
Action returns Action:
'{' ('current' '=')? typeName=TypeRef ('.' feature=ID operator=('='|'+=') 'current')? '}';
AbstractTerminal returns AbstractElement:
Keyword | RuleCall | ParenthesizedElement
;
ParenthesizedElement returns AbstractElement:
'(' Alternatives ')'
;
Keyword :
value=STRING
;
RuleCall :
name=ID ;
// lexing:
// Problem: LEXER_BODY kann nicht in xtxt beschrieben werden, da das erste '#>' bereits matcht
// Lösung: built-in lexer token
// LEXER_BODY : <# '<#' ( options {greedy=false;} : . )* '#>' #>

View file

@ -0,0 +1,80 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.xtext.generator.tests;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.apache.tools.ant.filters.StringInputStream;
import org.eclipse.xtext.core.parser.IElementFactory;
import org.openarchitectureware.xtend.XtendFacade;
/**
* @author Sven Efftinge - Initial contribution and API
*
*/
public abstract class AbstractGeneratorTest extends TestCase {
public Object parse(String model, IElementFactory factory) throws Exception {
String name = getClass().getPackage().getName() + ".parser." + getClass().getSimpleName();
String parser = name + "Parser";
Class<?> parserClass = getClass().getClassLoader().loadClass(parser);
Object parserInstance = parserClass.newInstance();
return parserClass.getMethod("parse", InputStream.class, IElementFactory.class).invoke(parserInstance,
new StringInputStream(model), factory);
}
public Object parse(InputStream model, IElementFactory factory) throws Exception {
String name = getClass().getPackage().getName() + ".parser." + getClass().getSimpleName();
String parser = name + "Parser";
Class<?> parserClass = getClass().getClassLoader().loadClass(parser);
Object parserInstance = parserClass.newInstance();
return parserClass.getMethod("parse", InputStream.class, IElementFactory.class).invoke(parserInstance,
model, factory);
}
public List<Invocation> parse(String model) throws Exception {
final List<Invocation> calls = new ArrayList<Invocation>();
parse(model, new IElementFactory() {
public void add(Object _this, String feature, Object value) {
calls.add(new Invocation("add", feature, value));
}
public Object create(String typeName) {
calls.add(new Invocation("create", typeName, null));
return typeName;
}
public void set(Object _this, String feature, Object value) {
calls.add(new Invocation("set", feature, value));
}
});
return calls;
}
protected void assertWithXtend(String left, String right, Object _this) {
assertWithXtend(left+" != "+right, left, right, _this);
}
protected void assertWithXtend(String message, String left, String right, Object _this) {
XtendFacade f = getXtendFacade();
f = f.cloneWithExtensions("__compare(Object this) : __left(this) == __right(this);__left(Object this) : "+left+"; __right(Object this) :"+right+";");
assertTrue(message,(Boolean) f.call("__compare",_this));
}
protected XtendFacade getXtendFacade() {
throw new UnsupportedOperationException();
}
}

View file

@ -0,0 +1,48 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.xtext.generator.tests;
import java.io.InputStream;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.xtext.GeneratorFacade;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.XtextEPackageAccess;
import org.eclipse.xtext.XtextGrammarTest;
import org.eclipse.xtext.XtextPackage;
import org.eclipse.xtext.grammargen.tests.SimpleTest;
import org.eclipse.xtext.grammargen.tests.SimpleTest2;
import org.eclipse.xtext.parser.XtextFactory;
import org.eclipse.xtext.parser.XtextParser;
/**
* @author Sven Efftinge - Initial contribution and API
*
*/
public class GenerateAllTestGrammars {
private static final String PATH = "./src-gen";
private final static Class<?>[] testclasses = new Class[] { SimpleTest.class, SimpleTest2.class, XtextGrammarTest.class };
public static void main(String[] args) throws Exception {
for (Class<?> c : testclasses) {
String filename = c.getName().replace('.', '/') + ".xtext";
System.out.println("loading " + filename);
InputStream resourceAsStream = c.getClassLoader().getResourceAsStream(filename);
//TODO make Xtext2Factory manual so one can overwrite 'getEPackages' in order to support generated epackages
EPackage.Registry.INSTANCE.put(XtextEPackageAccess.XTEXT_NS_URI, XtextPackage.eINSTANCE);
XtextParser xtext2Parser= new XtextParser();
Grammar grammarModel = (Grammar) xtext2Parser.parse(resourceAsStream, new XtextFactory());
GeneratorFacade.generate(grammarModel,c.getSimpleName(),c.getPackage().getName().replace('.', '/'),PATH);
}
}
}

View file

@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.xtext.generator.tests;
/**
* @author Sven Efftinge - Initial contribution and API
*
*/
public class Invocation {
public final String method;
public final String feature;
public final Object param;
Invocation(String method, String feature, Object param) {
super();
this.feature = feature;
this.method = method;
this.param = param;
}
@Override
public String toString() {
return method+"("+feature+(param!=null?","+param:"")+")";
}
}

View file

@ -0,0 +1,36 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.xtext.grammargen.tests;
import java.util.List;
import org.antlr.runtime.CommonToken;
import org.eclipse.xtext.generator.tests.AbstractGeneratorTest;
import org.eclipse.xtext.generator.tests.Invocation;
/**
* @author Sven Efftinge - Initial contribution and API
*
*/
public class SimpleTest extends AbstractGeneratorTest {
public void testFoo() throws Exception {
List<Invocation> parse = parse("HOLLA");
assertEquals("create", parse.get(0).method);
assertEquals("Foo", parse.get(0).feature);
assertEquals("set", parse.get(1).method);
assertEquals("name", parse.get(1).feature);
assertEquals("HOLLA", ((CommonToken)parse.get(1).param).getText());
}
}

View file

@ -0,0 +1,11 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
generate SimpleTest "http://eclipse.org/xtext/tests/SimpleTest"
Foo : name=ID;

View file

@ -0,0 +1,47 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
package org.eclipse.xtext.grammargen.tests;
import java.util.List;
import org.antlr.runtime.CommonToken;
import org.eclipse.xtext.generator.tests.AbstractGeneratorTest;
import org.eclipse.xtext.generator.tests.Invocation;
/**
* @author Sven Efftinge - Initial contribution and API
*
*/
public class SimpleTest2 extends AbstractGeneratorTest {
public void testFoo() throws Exception {
List<Invocation> parse = parse("keyword bla 3 {}");
assertEquals("create", parse.get(0).method);
assertEquals("Child", parse.get(0).feature);
assertEquals("set", parse.get(1).method);
assertEquals("name", parse.get(1).feature);
assertEquals("bla", ((CommonToken)parse.get(1).param).getText());
assertEquals("set", parse.get(2).method);
assertEquals("number", parse.get(2).feature);
assertEquals("3", ((CommonToken)parse.get(2).param).getText());
assertEquals("create", parse.get(3).method);
assertEquals("Model", parse.get(3).feature);
assertEquals("add", parse.get(4).method);
assertEquals("contents", parse.get(4).feature);
assertEquals("Child",parse.get(4).param);
}
}

View file

@ -0,0 +1,17 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG (http://www.itemis.eu) 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
* http://www.eclipse.org/legal/epl-v10.html
*
*******************************************************************************/
generate SimpleTest2 "http://eclipse.org/xtext/tests/SimpleTest2"
Model :
(contents+=Child)*;
Child :
(optional?='optional')? "keyword" name=ID number=INT '{'
'}';

View file

@ -0,0 +1,109 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* committers of openArchitectureWare - initial API and implementation
*******************************************************************************/
package org.eclipse.xtext.xtext2ecore;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.compare.diff.metamodel.AttributeChange;
import org.eclipse.emf.compare.diff.metamodel.DiffElement;
import org.eclipse.emf.compare.diff.metamodel.DiffGroup;
import org.eclipse.emf.compare.diff.metamodel.DiffModel;
import org.eclipse.emf.compare.diff.metamodel.ReferenceChange;
import org.eclipse.emf.compare.diff.service.DiffService;
import org.eclipse.emf.compare.match.api.IMatchEngine;
import org.eclipse.emf.compare.match.api.MatchOptions;
import org.eclipse.emf.compare.match.engine.GenericMatchEngine;
import org.eclipse.emf.compare.match.metamodel.MatchModel;
import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
/**
* @author Jan Köhnlein
*
*/
public class EcoreModelComparator {
private Map<String, Object> options;
private IMatchEngine matchEngine;
private List<EStructuralFeature> ignoredFeatures = new ArrayList<EStructuralFeature>();
public EcoreModelComparator() {
options = new HashMap<String, Object>();
options.put(MatchOptions.OPTION_DISTINCT_METAMODELS, Boolean.TRUE);
matchEngine = new GenericMatchEngine();
}
public boolean modelsDiffer(Resource left, Resource right)
throws InterruptedException {
boolean modelsDiffer = false;
MatchModel matchModel = matchEngine.resourceMatch(left, right, options);
DiffModel diffModel = DiffService.doDiff(matchModel);
if (diffModel != null) {
for (DiffElement diffElement : diffModel.getOwnedElements()) {
modelsDiffer |= checkDiff(diffElement);
}
}
return modelsDiffer;
}
public void addIgnoredFeature(EStructuralFeature feature) {
ignoredFeatures.add(feature);
}
private boolean checkDiff(DiffElement diffElement) {
boolean hasDiff = false;
if (!ignoreDiff(diffElement)) {
printDiff(diffElement);
hasDiff = true;
}
for (DiffElement childDiffElement : diffElement.getSubDiffElements()) {
hasDiff |= checkDiff(childDiffElement);
}
return hasDiff;
}
private boolean ignoreDiff(DiffElement diffElement) {
if (diffElement instanceof AttributeChange) {
return ignoredFeatures.contains(((AttributeChange) diffElement)
.getAttribute());
} else if (diffElement instanceof ReferenceChange) {
return ignoredFeatures.contains(((ReferenceChange) diffElement)
.getReference());
}
return diffElement instanceof DiffGroup;
}
private void printDiff(DiffElement diffElement) {
if (diffElement instanceof AttributeChange) {
AttributeChange change = (AttributeChange) diffElement;
EAttribute attribute = change.getAttribute();
System.err.println("Detected attribute difference: "
+ attribute.getName());
System.err.println("\t" + change.getLeftElement());
System.err.println("\t" + change.getRightElement());
} else if (diffElement instanceof ReferenceChange) {
ReferenceChange change = (ReferenceChange) diffElement;
EReference reference = change.getReference();
System.err.println("Detected reference difference: "
+ reference.getName());
System.err.println("\t" + change.getLeftElement());
System.err.println("\t" + change.getRightElement());
} else {
// TODO: add more sysouts here...
System.err.println(diffElement.getClass());
}
}
}

View file

@ -0,0 +1,98 @@
/*******************************************************************************
* Copyright (c) 2008 itemis AG 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* committers of openArchitectureWare - initial API and implementation
*******************************************************************************/
package org.eclipse.xtext.xtext2ecore;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import junit.framework.TestCase;
import org.antlr.runtime.RecognitionException;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceFactoryImpl;
import org.eclipse.m2t.type.emf.EmfRegistryMetaModel;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.XtextEPackageAccess;
import org.eclipse.xtext.XtextPackage;
import org.eclipse.xtext.parser.XtextFactory;
import org.eclipse.xtext.parser.XtextParser;
import org.eclipse.xtext.xtextutil.XtextutilPackage;
import org.openarchitectureware.expression.ExecutionContextImpl;
import org.openarchitectureware.xtend.XtendFacade;
/**
* @author Jan Köhnlein
*
*/
public class TestBootstrapModel extends TestCase {
@SuppressWarnings("unchecked")
public void testParseXtextGrammarTransformXtend() throws IOException, RecognitionException, InterruptedException {
InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(
"org/eclipse/xtext/XTextGrammarTest.xtext");
// TODO make Xtext2Factory manual so one can overwrite' getEPackages' in
// order to support generated epackages
EPackage.Registry.INSTANCE.put(XtextEPackageAccess.XTEXT_NS_URI, XtextPackage.eINSTANCE);
XtextParser xtext2Parser = new XtextParser();
Grammar grammarModel = (Grammar) xtext2Parser.parse(resourceAsStream, new XtextFactory());
ResourceSetImpl resourceSet = new ResourceSetImpl();
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("xmi", new XMIResourceFactoryImpl());
Resource grammarResource = resourceSet.createResource(URI.createFileURI("xtext.xmi"));
grammarResource.getContents().add(grammarModel);
// grammarResource.save(null);
Resource.Factory.Registry.INSTANCE.getExtensionToFactoryMap().put("ecore", new XMIResourceFactoryImpl());
EmfRegistryMetaModel emfRegistryMetaModel = new EmfRegistryMetaModel() {
EPackage[] packages = new EPackage[] { XtextPackage.eINSTANCE, XtextutilPackage.eINSTANCE,
EcorePackage.eINSTANCE };
@Override
protected EPackage[] allPackages() {
return packages;
}
};
ExecutionContextImpl executionContext = new ExecutionContextImpl();
executionContext.registerMetaModel(emfRegistryMetaModel);
XtendFacade facade = XtendFacade.create(executionContext, "org::eclipse::xtext::xtext2ecore::Xtext2Ecore");
List<EPackage> result = (List<EPackage>) facade.call("transform", grammarModel);
Resource generatedGrammarMetaModelResource = resourceSet.createResource(URI
.createFileURI("xtext_generated.ecore"));
generatedGrammarMetaModelResource.getContents().addAll(result);
// generatedGrammarMetaModelResource.save(null);
Resource originalGrammarMetaModelResource;
if (XtextPackage.eINSTANCE.eResource() == null) {
originalGrammarMetaModelResource = resourceSet.createResource(URI.createURI(XtextPackage.eINSTANCE
.getNsURI()));
} else {
originalGrammarMetaModelResource = XtextPackage.eINSTANCE.eResource();
}
EcoreModelComparator ecoreModelComparator = new EcoreModelComparator();
ecoreModelComparator.addIgnoredFeature(EcorePackage.Literals.ECLASSIFIER__INSTANCE_CLASS_NAME);
ecoreModelComparator.addIgnoredFeature(EcorePackage.Literals.ECLASSIFIER__INSTANCE_TYPE_NAME);
ecoreModelComparator.addIgnoredFeature(EcorePackage.Literals.EPACKAGE__NS_URI);
ecoreModelComparator.addIgnoredFeature(EcorePackage.Literals.ENAMED_ELEMENT__NAME);
ecoreModelComparator.addIgnoredFeature(EcorePackage.Literals.EPACKAGE__NS_PREFIX);
assertFalse(ecoreModelComparator.modelsDiffer(originalGrammarMetaModelResource,
generatedGrammarMetaModelResource));
}
}