summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorahaase2008-01-23 08:25:04 (EST)
committerahaase2008-01-23 08:25:04 (EST)
commitcbe865cc9ec0088c44b47f7deeea6edaacadf03e (patch)
tree63854bfbf0b46f9c8b3e46b9351fc9a0c7ee86da
parent16a3cfa5bacb192068c9876acc3fe194e9208f32 (diff)
downloadorg.eclipse.xpand-cbe865cc9ec0088c44b47f7deeea6edaacadf03e.zip
org.eclipse.xpand-cbe865cc9ec0088c44b47f7deeea6edaacadf03e.tar.gz
org.eclipse.xpand-cbe865cc9ec0088c44b47f7deeea6edaacadf03e.tar.bz2
enhanced Xpand middle end: calling templates across file boundaries now works
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF3
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java124
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java11
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java36
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java15
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandDefinitionName.java117
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/.project6
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java2
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/aTemplate.xpt6
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/otherTemplate.xpt3
-rw-r--r--tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/sub/templateInOtherPackage.xpt4
11 files changed, 258 insertions, 69 deletions
diff --git a/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF
index f73250c..19ccfaa 100644
--- a/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.xtend.middleend.old/META-INF/MANIFEST.MF
@@ -11,5 +11,6 @@ Require-Bundle: org.eclipse.xtend.backend,
org.eclipse.xtend,
org.eclipse.xpand,
org.eclipse.xtend.typesystem.emf,
- org.eclipse.emf.mwe.core
+ org.eclipse.emf.mwe.core,
+ org.eclipse.xtend.backend.xtendlib
Export-Package: org.eclipse.xtend.middleend.old
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java
index 4c1eec3..2e5defb 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java
@@ -14,6 +14,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Set;
import org.eclipse.internal.xpand2.ast.Definition;
import org.eclipse.internal.xpand2.ast.ErrorStatement;
@@ -50,9 +51,11 @@ import org.eclipse.xtend.backend.expr.NewLocalVarDefExpression;
import org.eclipse.xtend.backend.functions.FunctionDefContextImpl;
import org.eclipse.xtend.backend.functions.SourceDefinedFunction;
import org.eclipse.xtend.backend.syslib.FileIoOperations;
-import org.eclipse.xtend.backend.syslib.XtendIterator;
+import org.eclipse.xtend.backend.syslib.SysLibNames;
import org.eclipse.xtend.backend.types.builtin.ObjectType;
import org.eclipse.xtend.backend.util.SyntaxConstants;
+import org.eclipse.xtend.backend.xtendlib.XtendIterator;
+import org.eclipse.xtend.backend.xtendlib.XtendLibNames;
import org.eclipse.xtend.expression.AnalysationIssue;
import org.eclipse.xtend.expression.ExecutionContext;
import org.eclipse.xtend.expression.Variable;
@@ -66,7 +69,7 @@ import org.eclipse.xtend.typesystem.Type;
* @author Arno Haase (http://www.haase-consulting.com)
*/
final class OldDefinitionConverter {
- private ExecutionContext _ctx;
+ private XpandExecutionContext _ctx;
private final TypeToBackendType _typeConverter;
private String _definitionName;
@@ -74,7 +77,7 @@ final class OldDefinitionConverter {
private int _localVarCounter = 0;
- public OldDefinitionConverter (ExecutionContext ctx, TypeToBackendType typeConverter) {
+ public OldDefinitionConverter (XpandExecutionContext ctx, TypeToBackendType typeConverter) {
_ctx = ctx;
_typeConverter = typeConverter;
}
@@ -83,74 +86,75 @@ final class OldDefinitionConverter {
/**
* converts an extension to a function, taking care of mutual registration with its fdc
*/
- public NamedFunction create (XpandDefinition def, FunctionDefContextImpl fdc) {
- final NamedFunction result = createUnregistered (def, fdc);
+ public NamedFunction create (XpandDefinition def, FunctionDefContextImpl fdc, Set<XpandDefinitionName> referencedDefinitions) {
+ final NamedFunction result = createUnregistered (def, fdc, referencedDefinitions);
fdc.register (result);
return result;
}
- private NamedFunction createUnregistered (XpandDefinition def, FunctionDefContextImpl fdc) {
- if (def instanceof Definition)
- return new NamedFunction (def.getName(), createNormalDefinition ((Definition) def, fdc));
+ private NamedFunction createUnregistered (XpandDefinition def, FunctionDefContextImpl fdc, Set<XpandDefinitionName> referencedDefinitions) {
+ if (def instanceof Definition) {
+ final String canonicalName = new XpandDefinitionName (def).getCanonicalDefinitionName();
+ return new NamedFunction (canonicalName, createNormalDefinition ((Definition) def, fdc, referencedDefinitions));
+ }
throw new IllegalArgumentException ("unsupported definition type " + def.getClass().getName());
}
//TODO imported namespaces (probably one level up)
- //TODO included extensions (probably one level up)
- private Function createNormalDefinition (Definition def, FunctionDefContext fdc) {
- final ExecutionContext oldCtx = _ctx;
+ private Function createNormalDefinition (Definition def, FunctionDefContext fdc, Set<XpandDefinitionName> referencedDefinitions) {
+ final XpandExecutionContext oldCtx = _ctx;
try {
final List<String> paramNames = new ArrayList<String>();
final List<BackendType> paramTypes = new ArrayList<BackendType>();
final Type ft = _ctx.getTypeForName (def.getTargetType());
- _ctx = _ctx.cloneWithVariable (new Variable (ExecutionContext.IMPLICIT_VARIABLE, ft));
+ _ctx = (XpandExecutionContext) _ctx.cloneWithVariable (new Variable (ExecutionContext.IMPLICIT_VARIABLE, ft));
paramNames.add (SyntaxConstants.THIS);
paramTypes.add (_typeConverter.convertToBackendType(ft));
for (DeclaredParameter dp: def.getParams()) {
final Type pt = _ctx.getTypeForName (dp.getType().getValue());
- _ctx = _ctx.cloneWithVariable (new Variable (dp.getName().getValue(), pt));
+ _ctx = (XpandExecutionContext) _ctx.cloneWithVariable (new Variable (dp.getName().getValue(), pt));
paramNames.add (dp.getName().getValue());
paramTypes.add (_typeConverter.convertToBackendType (pt));
}
- return new SourceDefinedFunction (def.getName(), paramNames, paramTypes, fdc, convertStatmentSequence (def.getBody(), def), false, null);
+ return new SourceDefinedFunction (def.getName(), paramNames, paramTypes, fdc, convertStatmentSequence (def.getBody(), def, referencedDefinitions), false, null);
}
finally {
_ctx = oldCtx;
}
}
- private ExpressionBase convertStatmentSequence (Statement[] statements, SyntaxElement oldPos) {
+ private ExpressionBase convertStatmentSequence (Statement[] statements, SyntaxElement oldPos, Set<XpandDefinitionName> referencedDefinitions) {
final List<ExpressionBase> parts = new ArrayList<ExpressionBase> ();
for (Statement stmt: statements)
- parts.add(convertStatement (stmt));
+ parts.add (convertStatement (stmt, referencedDefinitions));
return new ConcatExpression (parts, getSourcePos(oldPos));
}
- private ExpressionBase convertStatement (Statement stmt) {
+ private ExpressionBase convertStatement (Statement stmt, Set<XpandDefinitionName> referencedDefinitions) {
if (stmt instanceof ErrorStatement)
return convertErrorStatement((ErrorStatement) stmt);
if (stmt instanceof ExpandStatement)
- return convertExpandStatement ((ExpandStatement) stmt);
+ return convertExpandStatement ((ExpandStatement) stmt, referencedDefinitions);
if (stmt instanceof ExpressionStatement)
return convertExpressionStatement ((ExpressionStatement) stmt);
if (stmt instanceof FileStatement)
- return convertFileStatement ((FileStatement) stmt);
+ return convertFileStatement ((FileStatement) stmt, referencedDefinitions);
if (stmt instanceof ForEachStatement)
- return convertForEachStatement ((ForEachStatement) stmt);
+ return convertForEachStatement ((ForEachStatement) stmt, referencedDefinitions);
if (stmt instanceof IfStatement)
- return convertIfStatement ((IfStatement) stmt);
+ return convertIfStatement ((IfStatement) stmt, referencedDefinitions);
if (stmt instanceof LetStatement)
- return convertLetStatement ((LetStatement) stmt);
+ return convertLetStatement ((LetStatement) stmt, referencedDefinitions);
if (stmt instanceof ProtectStatement)
- return convertProtectStatement ((ProtectStatement) stmt);
+ return convertProtectStatement ((ProtectStatement) stmt, referencedDefinitions);
if (stmt instanceof TextStatement)
return convertTextStatement ((TextStatement) stmt);
@@ -169,9 +173,7 @@ final class OldDefinitionConverter {
};
}
- private ExpressionBase convertExpandStatement (ExpandStatement stmt) {
- //TODO mitloggen, was aufgerufen wird --> in den fdc ziehen
-
+ private ExpressionBase convertExpandStatement (ExpandStatement stmt, Set<XpandDefinitionName> referencedDefinitions) {
if (stmt.isForeach()) {
final ExpressionBase separator = (stmt.getSeparator() != null) ? convertExpression (stmt.getSeparator()) : null;
final ExpressionBase target = convertExpression (stmt.getTarget());
@@ -182,13 +184,24 @@ final class OldDefinitionConverter {
for (Expression e: stmt.getParameters())
params.add (convertExpression (e));
- final ExpressionBase invocationExpression = new InvocationOnObjectExpression (stmt.getDefinition().getValue(), params, getSourcePos(stmt));
+
+ final Type targetType = ((ParameterizedType) stmt.getTarget().analyze (_ctx, new HashSet<AnalysationIssue> ())).getInnerType();
+
+ final Type[] argTypes = new Type[stmt.getParametersAsList().size()];
+ for (int i=0; i<stmt.getParametersAsList().size(); i++)
+ argTypes[i] = stmt.getParametersAsList().get(i).analyze (_ctx, new HashSet<AnalysationIssue> ());
+
+ final XpandDefinitionName called = new XpandDefinitionName (stmt.getDefinition().getValue(), targetType, argTypes, _ctx);
+ referencedDefinitions.add (called);
+
+
+ final ExpressionBase invocationExpression = new InvocationOnObjectExpression (called.getCanonicalDefinitionName(), params, getSourcePos(stmt));
final ExpressionBase loopBody = new InitClosureExpression (Arrays.asList(closureParamName), Arrays.asList(ObjectType.INSTANCE), invocationExpression, getSourcePos(stmt));
if (separator == null)
- return new InvocationOnObjectExpression (SyntaxConstants.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, loopBody), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, loopBody), getSourcePos (stmt));
else
- return new InvocationOnObjectExpression (SyntaxConstants.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, loopBody, separator), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, loopBody, separator), getSourcePos (stmt));
}
else {
final List<ExpressionBase> params = new ArrayList<ExpressionBase>();
@@ -200,11 +213,12 @@ final class OldDefinitionConverter {
for (Expression e: stmt.getParameters())
params.add (convertExpression (e));
- return new InvocationOnObjectExpression (stmt.getDefinition().getValue(), params, getSourcePos(stmt));
+ final XpandDefinitionName called = new XpandDefinitionName (stmt.getDefinition().getValue(), stmt.getTarget(), stmt.getParametersAsList(), _ctx);
+ referencedDefinitions.add (called);
+ return new InvocationOnObjectExpression (called.getCanonicalDefinitionName(), params, getSourcePos(stmt));
}
}
-
private String createUniqueLocalVarName () {
return "$localVar_" + _localVarCounter++;
}
@@ -214,8 +228,8 @@ final class OldDefinitionConverter {
return convertExpression (stmt.getExpression());
}
- private ExpressionBase convertForEachStatement (ForEachStatement stmt) {
- final ExecutionContext oldContext = _ctx;
+ private ExpressionBase convertForEachStatement (ForEachStatement stmt, Set<XpandDefinitionName> referencedDefinitions) {
+ final XpandExecutionContext oldContext = _ctx;
final ExpressionBase separator = (stmt.getSeparator() != null) ? convertExpression (stmt.getSeparator()) : null;
final ExpressionBase target = convertExpression (stmt.getTarget());
@@ -229,9 +243,9 @@ final class OldDefinitionConverter {
if (stmt.getIteratorName() == null) {
// forEach without an iterator
- _ctx = _ctx.cloneWithVariable (new Variable (varName, eleType));
+ _ctx = (XpandExecutionContext) _ctx.cloneWithVariable (new Variable (varName, eleType));
try {
- body = convertStatmentSequence (stmt.getBody(), stmt);
+ body = convertStatmentSequence (stmt.getBody(), stmt, referencedDefinitions);
}
finally {
_ctx = oldContext;
@@ -239,16 +253,16 @@ final class OldDefinitionConverter {
final ExpressionBase closureCreation = new InitClosureExpression (Arrays.asList (varName), Arrays.asList (_typeConverter.convertToBackendType(eleType)), body, getSourcePos (stmt));
if (separator == null)
- return new InvocationOnObjectExpression (SyntaxConstants.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, closureCreation), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, closureCreation), getSourcePos (stmt));
else
- return new InvocationOnObjectExpression (SyntaxConstants.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, closureCreation, separator), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITHOUT_ITERATOR, Arrays.asList(target, closureCreation, separator), getSourcePos (stmt));
}
else {
// forEach with an iterator
- _ctx = _ctx.cloneWithVariable (new Variable (varName, eleType));
- _ctx = _ctx.cloneWithVariable (new Variable (stmt.getIteratorName().getValue(), _ctx.getTypeForName (IteratorType.TYPE_NAME)));
+ _ctx = (XpandExecutionContext) _ctx.cloneWithVariable (new Variable (varName, eleType));
+ _ctx = (XpandExecutionContext) _ctx.cloneWithVariable (new Variable (stmt.getIteratorName().getValue(), _ctx.getTypeForName (IteratorType.TYPE_NAME)));
try {
- body = convertStatmentSequence (stmt.getBody(), stmt);
+ body = convertStatmentSequence (stmt.getBody(), stmt, referencedDefinitions);
}
finally {
_ctx = oldContext;
@@ -260,37 +274,37 @@ final class OldDefinitionConverter {
final ExpressionBase closureCreation = new InitClosureExpression (paramNames, paramTypes, body, getSourcePos (stmt));
if (separator == null)
- return new InvocationOnObjectExpression (SyntaxConstants.FOREACH_WITH_ITERATOR, Arrays.asList(target, closureCreation), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITH_ITERATOR, Arrays.asList(target, closureCreation), getSourcePos (stmt));
else
- return new InvocationOnObjectExpression (SyntaxConstants.FOREACH_WITH_ITERATOR, Arrays.asList(target, closureCreation, separator), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (XtendLibNames.FOREACH_WITH_ITERATOR, Arrays.asList(target, closureCreation, separator), getSourcePos (stmt));
}
}
- private ExpressionBase convertIfStatement (IfStatement stmt) {
+ private ExpressionBase convertIfStatement (IfStatement stmt, Set<XpandDefinitionName> referencedDefinitions) {
if (stmt.getCondition() != null) {
final ExpressionBase condExpr = convertExpression (stmt.getCondition());
- final ExpressionBase ifExpr = convertStatement (stmt.getUpperIf());
- final ExpressionBase elseExpr = stmt.getElseIf() != null ? convertStatement (stmt.getElseIf()) : new LiteralExpression (null, getSourcePos (stmt));
+ final ExpressionBase ifExpr = convertStatement (stmt.getUpperIf(), referencedDefinitions);
+ final ExpressionBase elseExpr = stmt.getElseIf() != null ? convertStatement (stmt.getElseIf(), referencedDefinitions) : new LiteralExpression (null, getSourcePos (stmt));
return new IfExpression (condExpr, ifExpr, elseExpr, getSourcePos (stmt));
}
else {
// the else part is an IfStatement with null condition
- return convertStatmentSequence (stmt.getBody(), stmt);
+ return convertStatmentSequence (stmt.getBody(), stmt, referencedDefinitions);
}
}
- private ExpressionBase convertLetStatement (LetStatement stmt) {
+ private ExpressionBase convertLetStatement (LetStatement stmt, Set<XpandDefinitionName> referencedDefinitions) {
final String varName = stmt.getVarName().getValue();
final Type type = stmt.getVarValue().analyze (_ctx, new HashSet<AnalysationIssue> ());
- final ExecutionContext oldContext = _ctx;
- _ctx = _ctx.cloneWithVariable (new Variable (varName, type));
+ final XpandExecutionContext oldContext = _ctx;
+ _ctx = (XpandExecutionContext) _ctx.cloneWithVariable (new Variable (varName, type));
try {
final ExpressionBase def = convertExpression (stmt.getVarValue());
- final ExpressionBase body = convertStatmentSequence (stmt.getBody(), stmt);
+ final ExpressionBase body = convertStatmentSequence (stmt.getBody(), stmt, referencedDefinitions);
if (oldContext.getVisibleVariables().containsKey (varName))
return new HidingLocalVarDefExpression (varName, def, body, getSourcePos (stmt));
@@ -302,11 +316,11 @@ final class OldDefinitionConverter {
}
}
- private ExpressionBase convertFileStatement (FileStatement stmt) {
- final ExpressionBase body = convertStatmentSequence (stmt.getBody(), stmt);
+ private ExpressionBase convertFileStatement (FileStatement stmt, Set<XpandDefinitionName> referencedDefinitions) {
+ final ExpressionBase body = convertStatmentSequence (stmt.getBody(), stmt, referencedDefinitions);
final ExpressionBase filename = convertExpression (stmt.getTargetFileName());
- final Outlet outlet = ((XpandExecutionContext) _ctx).getOutput().getOutlet (stmt.getOutletName());
+ final Outlet outlet = _ctx.getOutput().getOutlet (stmt.getOutletName());
if (outlet == null) {
if (stmt.getOutletName() == null)
throw new IllegalStateException ("no default outlet was registered");
@@ -318,10 +332,10 @@ final class OldDefinitionConverter {
final ExpressionBase append = new LiteralExpression (outlet.isAppend(), getSourcePos(stmt));
//TODO register the outlets
- return new InvocationOnObjectExpression (SyntaxConstants.WRITE_TO_FILE, Arrays.asList(outletName, filename, append, body), getSourcePos (stmt));
+ return new InvocationOnObjectExpression (SysLibNames.WRITE_TO_FILE, Arrays.asList(outletName, filename, append, body), getSourcePos (stmt));
}
- private ExpressionBase convertProtectStatement (ProtectStatement stmt) {
+ private ExpressionBase convertProtectStatement (ProtectStatement stmt, Set<XpandDefinitionName> referencedDefinitions) {
throw new UnsupportedOperationException(); //TODO implement ProtectStatement
}
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java
index 3b33f2d..d795042 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java
@@ -60,6 +60,7 @@ import org.eclipse.xtend.backend.expr.PropertyOnCollectionExpression;
import org.eclipse.xtend.backend.expr.PropertyOnObjectExpression;
import org.eclipse.xtend.backend.expr.PropertyOnWhateverExpression;
import org.eclipse.xtend.backend.expr.SequenceExpression;
+import org.eclipse.xtend.backend.syslib.SysLibNames;
import org.eclipse.xtend.backend.types.builtin.ObjectType;
import org.eclipse.xtend.backend.util.Pair;
import org.eclipse.xtend.expression.AnalysationIssue;
@@ -169,15 +170,15 @@ final class OldExpressionConverter {
//TODO make "!" a built-in operation?
if ("+".equals (functionName))
- return org.eclipse.xtend.backend.util.SyntaxConstants.OPERATOR_PLUS;
+ return SysLibNames.OPERATOR_PLUS;
if ("-".equals (functionName))
- return org.eclipse.xtend.backend.util.SyntaxConstants.OPERATOR_MINUS;
+ return SysLibNames.OPERATOR_MINUS;
if ("*".equals (functionName))
- return org.eclipse.xtend.backend.util.SyntaxConstants.OPERATOR_MULT;
+ return SysLibNames.OPERATOR_MULT;
if ("/".equals (functionName))
- return org.eclipse.xtend.backend.util.SyntaxConstants.OPERATOR_DIV;
+ return SysLibNames.OPERATOR_DIV;
if ("%".equals (functionName))
- return org.eclipse.xtend.backend.util.SyntaxConstants.OPERATOR_MOD;
+ return SysLibNames.OPERATOR_MOD;
return functionName;
}
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java
index de2def7..9fab5f7 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXpandRegistry.java
@@ -13,8 +13,10 @@ package org.eclipse.xtend.middleend.old;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.eclipose.xtend.middleend.FunctionDefContextFactory;
import org.eclipse.internal.xpand2.ast.Template;
@@ -63,7 +65,7 @@ final class OldXpandRegistry {
/**
- * parses and converts an Xpand file and all other files it depends on.
+ * parses and converts an Xpand file and all other files it depends on.
*/
public void registerXpandFile (String xpandFile) {
xpandFile = OldXtendHelper.normalizeXpandResourceName (xpandFile);
@@ -71,9 +73,12 @@ final class OldXpandRegistry {
if (_functionsByResource.containsKey (xpandFile))
return;
- final Template file = (Template) _ctx.getResourceManager().loadResource (xpandFile, XpandUtil.TEMPLATE_EXTENSION);
+ System.err.println ("registering xpand file " + xpandFile);
+
+ final String xpandResourceName = OldXtendHelper.xpandFileAsOldResourceName(xpandFile);
+ final Template file = (Template) _ctx.getResourceManager().loadResource (xpandResourceName, XpandUtil.TEMPLATE_EXTENSION);
if (file == null)
- throw new IllegalArgumentException ("could not find extension '" + xpandFile + "'");
+ throw new IllegalArgumentException ("could not find Xpand file '" + xpandResourceName + "'");
final XpandExecutionContext ctx = (XpandExecutionContext) _ctx.cloneWithResource (file);
@@ -84,10 +89,11 @@ final class OldXpandRegistry {
final FunctionDefContextImpl fdc = getFunctionDefContext (xpandFile);
//TODO imported namespaces
- //TODO referenced other template files
+
+ final Set<XpandDefinitionName> referenced = new HashSet<XpandDefinitionName> ();
for (XpandDefinition ext: file.getDefinitions ())
- defined.add (definitionFactory.create (ext, fdc));
+ defined.add (definitionFactory.create (ext, fdc, referenced));
_functionsByResource.put (xpandFile, defined);
@@ -101,10 +107,26 @@ final class OldXpandRegistry {
for (NamedFunction f: _extensions.getContributedFunctions(imported))
fdc.register (f);
}
- }
+ System.err.println ("referenced template definitions: " + referenced);
+
+ // read all referenced template files...
+ final Set<String> xpandFileNames = new HashSet<String> ();
+ for (XpandDefinitionName n: referenced)
+ xpandFileNames.add (n.getCanonicalTemplateFileName());
+
+ for (String xpandFileName: xpandFileNames)
+ registerXpandFile (xpandFileName);
+
+ // ... and register all registered extensions in this fdc
+ for (String xpandFileName: xpandFileNames)
+ for (NamedFunction f: _functionsByResource.get (xpandFileName))
+ fdc.register(f);
+ }
+
+
public Collection<NamedFunction> getContributedFunctions (String xpandFile) {
- return _functionsByResource.get (OldXtendHelper.normalizeXpandResourceName (xpandFile));
+ return _functionsByResource.get (xpandFile);
}
}
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java
index b8cfb3c..45b5b8b 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldXtendHelper.java
@@ -12,6 +12,7 @@ package org.eclipse.xtend.middleend.old;
import org.eclipse.internal.xtend.expression.parser.SyntaxConstants;
import org.eclipse.internal.xtend.xtend.XtendFile;
+import org.eclipse.xpand2.XpandUtil;
/**
@@ -28,6 +29,20 @@ final class OldXtendHelper {
}
public static String normalizeXpandResourceName (String xpandName) {
+ if (! xpandName.endsWith("." + XpandUtil.TEMPLATE_EXTENSION))
+ xpandName += "." + XpandUtil.TEMPLATE_EXTENSION;
+
+ xpandName = xpandName.replace (SyntaxConstants.NS_DELIM, "/");
+
+ return xpandName;
+ }
+
+ public static String xpandFileAsOldResourceName (String xpandName) {
+ if (xpandName.toLowerCase().endsWith (XpandUtil.TEMPLATE_EXTENSION))
+ xpandName = xpandName.substring (0, xpandName.length() - XpandUtil.TEMPLATE_EXTENSION.length() - 1);
+
+ xpandName = xpandName.replace ("/", SyntaxConstants.NS_DELIM);
+
return xpandName;
}
}
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandDefinitionName.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandDefinitionName.java
new file mode 100644
index 0000000..48497b7
--- /dev/null
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/XpandDefinitionName.java
@@ -0,0 +1,117 @@
+/*
+Copyright (c) 2008 Arno Haase.
+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:
+ Arno Haase - initial API and implementation
+*/
+package org.eclipse.xtend.middleend.old;
+
+import java.util.HashSet;
+import java.util.List;
+
+import org.eclipse.internal.xpand2.model.XpandDefinition;
+import org.eclipse.internal.xtend.expression.ast.Expression;
+import org.eclipse.internal.xtend.expression.ast.FeatureCall;
+import org.eclipse.internal.xtend.expression.ast.Identifier;
+import org.eclipse.xpand2.XpandExecutionContext;
+import org.eclipse.xtend.expression.AnalysationIssue;
+import org.eclipse.xtend.expression.ExecutionContext;
+import org.eclipse.xtend.typesystem.Type;
+
+
+/**
+ * This class serves as a representation of an Xpand definition name. It takes
+ * care of the intricacies and ambiguities of Xpand template referencing
+ * (fully qualified, relative, ...) by providing a normalized, canonical
+ * name.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+final class XpandDefinitionName {
+ private final String _canonicalDefinitionName;
+ private final String _canonicalTemplateFileName;
+
+
+ public XpandDefinitionName (XpandDefinition def) {
+ _canonicalTemplateFileName = def.getFileName();
+ _canonicalDefinitionName = _canonicalTemplateFileName.substring (0, _canonicalTemplateFileName.length() - 4) + "/" + def.getName();
+ }
+
+ /**
+ * @param rawDefName the name as it appears in Xpand code
+ * @param targetType may not be null
+ * @param argTypes
+ * @param ctx the XpandExecutionContext that is valid at the place from which the definition is called. This
+ * is necessary to resolve relative references.
+ */
+ public XpandDefinitionName (String rawDefName, Type targetType, Type[] argTypes, XpandExecutionContext ctx) {
+ this (ctx.findDefinition(rawDefName, targetType, argTypes));
+ }
+
+ public XpandDefinitionName (String rawDefName, Expression target, List<Expression> args, XpandExecutionContext ctx) {
+ this (rawDefName, typeForTargetExpression (target, ctx), typesForArgExpressions(args, ctx), ctx);
+ }
+
+ private static Type typeForTargetExpression (Expression target, XpandExecutionContext ctx) {
+ if (target == null)
+ target = new FeatureCall (new Identifier (ExecutionContext.IMPLICIT_VARIABLE), null); // no target is treated as a 'this' reference
+
+ return target.analyze (ctx, new HashSet<AnalysationIssue> ());
+ }
+
+ private static Type[] typesForArgExpressions (List<Expression> args, XpandExecutionContext ctx) {
+ final Type[] result = new Type[args.size()];
+ for (int i=0; i<args.size(); i++)
+ result[i] = args.get(i).analyze(ctx, new HashSet<AnalysationIssue> ());
+ return result;
+ }
+
+
+ public String getCanonicalDefinitionName () {
+ return _canonicalDefinitionName;
+ }
+
+ public String getCanonicalTemplateFileName () {
+ return _canonicalTemplateFileName;
+ }
+
+ @Override
+ public String toString () {
+ return _canonicalDefinitionName;
+ }
+
+ @Override
+ public int hashCode () {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((_canonicalDefinitionName == null) ? 0 : _canonicalDefinitionName.hashCode());
+ result = prime * result + ((_canonicalTemplateFileName == null) ? 0 : _canonicalTemplateFileName.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals (Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final XpandDefinitionName other = (XpandDefinitionName) obj;
+ if (_canonicalDefinitionName == null) {
+ if (other._canonicalDefinitionName != null)
+ return false;
+ } else if (!_canonicalDefinitionName.equals(other._canonicalDefinitionName))
+ return false;
+ if (_canonicalTemplateFileName == null) {
+ if (other._canonicalTemplateFileName != null)
+ return false;
+ } else if (!_canonicalTemplateFileName.equals(other._canonicalTemplateFileName))
+ return false;
+ return true;
+ }
+}
diff --git a/tests/org.eclipse.xtend.middleend.old.test/.project b/tests/org.eclipse.xtend.middleend.old.test/.project
index 1fff577..5117e9c 100644
--- a/tests/org.eclipse.xtend.middleend.old.test/.project
+++ b/tests/org.eclipse.xtend.middleend.old.test/.project
@@ -20,9 +20,15 @@
<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>
diff --git a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java
index ff1c49f..26ab737 100644
--- a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java
+++ b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/FirstAttempt.java
@@ -36,7 +36,7 @@ public class FirstAttempt {
final XpandBackendContributor xp = new XpandBackendContributor ("org::eclipse::xtend::middleend::old::first::aTemplate", mms, ts, new ArrayList<Outlet>());
final ExecutionContext ctx = BackendFacade.createExecutionContext (xp.getFunctionDefContext(), ts);
- System.err.println (BackendFacade.invoke (ctx, "greeting", Arrays.asList("Arno")));
+ System.err.println (BackendFacade.invoke (ctx, "org/eclipse/xtend/middleend/old/first/aTemplate/greeting", Arrays.asList("Arno")));
}
{
diff --git a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/aTemplate.xpt b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/aTemplate.xpt
index 6e31bfe..bceb21a 100644
--- a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/aTemplate.xpt
+++ b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/aTemplate.xpt
@@ -3,6 +3,12 @@
«DEFINE greeting FOR String»
Hello, «this»: «test(this)»
«EXPAND name FOR this»
+
+«EXPAND otherTemplate::ot FOR this»
+«EXPAND sub::templateInOtherPackage::other FOR this»
+«EXPAND sub::templateInOtherPackage::other»
+«EXPAND org::eclipse::xtend::middleend::old::first::sub::templateInOtherPackage::other»
+
«ENDDEFINE»
«DEFINE name FOR String»
diff --git a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/otherTemplate.xpt b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/otherTemplate.xpt
new file mode 100644
index 0000000..1040463
--- /dev/null
+++ b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/otherTemplate.xpt
@@ -0,0 +1,3 @@
+«DEFINE ot FOR String»
+ ... output from otherTemplate.xpt...
+«ENDDEFINE» \ No newline at end of file
diff --git a/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/sub/templateInOtherPackage.xpt b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/sub/templateInOtherPackage.xpt
new file mode 100644
index 0000000..3e7ae2c
--- /dev/null
+++ b/tests/org.eclipse.xtend.middleend.old.test/src/org/eclipse/xtend/middleend/old/first/sub/templateInOtherPackage.xpt
@@ -0,0 +1,4 @@
+«DEFINE other FOR String»
+ This is a message from another package!
+«ENDDEFINE»
+