summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorahaase2008-02-24 08:31:28 (EST)
committer ahaase2008-02-24 08:31:28 (EST)
commitbcde5284f6d93acd376d3e5a652fb09dfc8bf81a (patch)
treedc66730370545dd1bd215c127cc034ab5f55f43d
parent54f73c285509f6c0fc17c957b6ed6eb36903a0be (diff)
downloadorg.eclipse.xpand-bcde5284f6d93acd376d3e5a652fb09dfc8bf81a.zip
org.eclipse.xpand-bcde5284f6d93acd376d3e5a652fb09dfc8bf81a.tar.gz
org.eclipse.xpand-bcde5284f6d93acd376d3e5a652fb09dfc8bf81a.tar.bz2
added AOP support for the backend (not yet in the middle end)
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdviceContextImpl.java91
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdviceParamType.java37
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdvisedFunction.java103
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AroundAdvice.java70
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ExecutionPointcut.java118
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/Pointcut.java26
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ThisJoinPoint.java45
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ThisJoinPointStaticPart.java42
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/AdviceContext.java24
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/ExecutionContext.java5
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/SyntaxConstants.java (renamed from plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/util/SyntaxConstants.java)5
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/internal/FunctionDefContextImpl.java3
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/ExecutionContextImpl.java11
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/FunctionInvokerImpl.java2
-rw-r--r--plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/util/ObjectWrapper.java26
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldDefinitionConverter.java2
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExpressionConverter.java8
-rw-r--r--plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExtensionConverter.java2
18 files changed, 611 insertions, 9 deletions
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdviceContextImpl.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdviceContextImpl.java
new file mode 100644
index 0000000..a5e0de2
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdviceContextImpl.java
@@ -0,0 +1,91 @@
+/*
+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.backend.aop;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.xtend.backend.common.AdviceContext;
+import org.eclipse.xtend.backend.common.Function;
+import org.eclipse.xtend.backend.util.DoubleKeyCache;
+import org.eclipse.xtend.backend.util.ObjectWrapper;
+import org.eclipse.xtend.backend.util.Triplet;
+
+
+/**
+ * This class represents all currently registered advice. It is
+ * designed to efficiently handle dynamically registered advice,
+ * e.g. for the scope of an invocation.<br>
+ *
+ * In order to allow aggressive caching, it is immutable and creates
+ * a copy when additional advice is registered. This design decision
+ * assumes that registering new advice is very infrequent compared to the
+ * invocation of functions.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class AdviceContextImpl implements AdviceContext {
+ private final List<AroundAdvice> _advice = new ArrayList<AroundAdvice> ();
+
+ private final DoubleKeyCache <String, Function, AdvisedFunction> _advisedFunctionCache = new DoubleKeyCache<String, Function, AdvisedFunction> () {
+ @Override
+ protected AdvisedFunction create (String functionName, Function f) {
+ final List<AroundAdvice> applicableAdvice = new ArrayList<AroundAdvice> ();
+
+ for (AroundAdvice advice: _advice)
+ if (advice.getPointcut().matches (functionName, f))
+ applicableAdvice.add (advice);
+
+ return new AdvisedFunction (functionName, f, applicableAdvice);
+ }
+ };
+
+ private final Map<Triplet <Function, AroundAdvice, List<?>>, ObjectWrapper> _resultCache;
+
+
+ public AdviceContextImpl () {
+ this (new HashMap<Triplet<Function,AroundAdvice,List<?>>, ObjectWrapper> ());
+ }
+
+ private AdviceContextImpl (Map<Triplet <Function, AroundAdvice, List<?>>, ObjectWrapper> resultCache) {
+ _resultCache = resultCache;
+ }
+
+ public AdviceContextImpl copyWithAdvice (AroundAdvice advice) {
+ // the result cache survives the addition (and going out-of-scope!) of advice. This
+ // is possible because newly applied advice is applied "around" advice applied earlier.
+ final AdviceContextImpl result = new AdviceContextImpl (_resultCache);
+
+ result._advice.addAll (_advice);
+ result._advice.add (advice);
+
+ return result;
+ }
+
+ //TODO test this (including the order in which advice is applied)!!!
+
+ /**
+ * returns the advice to be applied to this function, starting with the innermost
+ * advice, i.e. the advice that is to be directly applied to the result of the
+ * advised function.
+ */
+ public AdvisedFunction getAdvice (String functionName, Function f) {
+ return _advisedFunctionCache.get (functionName, f);
+ }
+
+ public Map<Triplet<Function, AroundAdvice, List<?>>, ObjectWrapper> getResultCache () {
+ return _resultCache;
+ }
+}
+
+
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdviceParamType.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdviceParamType.java
new file mode 100644
index 0000000..ec195d2
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdviceParamType.java
@@ -0,0 +1,37 @@
+/*
+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.backend.aop;
+
+import org.eclipse.xtend.backend.common.BackendType;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class AdviceParamType {
+ private final BackendType _type;
+ private final boolean _includingSubtypes;
+
+ public AdviceParamType (BackendType type, boolean includingSubtypes) {
+ _type = type;
+ _includingSubtypes = includingSubtypes;
+ }
+
+ //TODO testen!
+
+ public boolean matches (BackendType type) {
+ if (_includingSubtypes)
+ return _type.isAssignableFrom (type);
+ else
+ return _type.equals (type);
+ }
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdvisedFunction.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdvisedFunction.java
new file mode 100644
index 0000000..ddab16f
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AdvisedFunction.java
@@ -0,0 +1,103 @@
+/*
+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.backend.aop;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.Function;
+import org.eclipse.xtend.backend.util.ObjectWrapper;
+import org.eclipse.xtend.backend.util.Triplet;
+
+
+/**
+ * This class represents a function with all applicable Advice.<br>
+ *
+ * It could formally be treated as a function, but it is a conscious design decision
+ * not to do that. The rationale behind that decision is that advice is bound to a
+ * name or context (via its PointCut) whereas a function is not. In other words, if
+ * a function is passed around in a program, the applicable advice can vary - and
+ * for that reason, advice is only applied "just in time", based on the then current
+ * name and context.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class AdvisedFunction {
+ private final Function _function;
+ private final List<AroundAdvice> _advice;
+ private final int _firstCacheableIndex;
+
+ private final ThisJoinPointStaticPart _thisJoinPointStaticPart;
+
+
+ public AdvisedFunction (String functionName, Function function, List<AroundAdvice> advice) {
+ _function = function;
+ _advice = advice;
+
+ _thisJoinPointStaticPart = new ThisJoinPointStaticPart (functionName, _function);
+
+ if (function.isCached()) {
+ int firstCacheableIndex = advice.size();
+ while (firstCacheableIndex > 0 && advice.get (firstCacheableIndex - 1).isCacheable())
+ firstCacheableIndex--;
+
+ _firstCacheableIndex = firstCacheableIndex;
+ }
+ else
+ _firstCacheableIndex = advice.size();
+ }
+
+ public Object evaluate (ExecutionContext ctx, Object[] params) {
+ // the evaluation of the advice is performed in three stages:
+ // 1. all advice that is "outside" the outermost non-cacheable advice
+ // is always actually evaluated
+ // 2. advice that is cacheable but not yet cached is evaluated and cached
+ // (iff the function is cached)
+ // 3. once cached advice is encountered, the evaluation is short-circuited
+ // and the result from the cache is returned
+
+ return proceedInternal (ctx, 0, params);
+ }
+
+ private Object proceedInternal (final ExecutionContext ctx, final int indNextAdvice, final Object[] params) {
+ if (indNextAdvice >= _advice.size())
+ return ctx.getFunctionInvoker().invoke (ctx, _function, Arrays.asList (params));
+
+ if (indNextAdvice >= _firstCacheableIndex) {
+ final ObjectWrapper ow = ctx.getAdviceContext().getResultCache().get (new Triplet<Function, AroundAdvice, List<?>> (_function, _advice.get (indNextAdvice), Arrays.asList(params)));
+ if (ow != null)
+ return ow._content;
+ }
+
+ final ThisJoinPoint thisJoinPoint = new ThisJoinPoint (ctx.getStacktrace(), params) {
+ @Override
+ public Object proceed (Object[] localParams) {
+ return proceedInternal (ctx, indNextAdvice+1, localParams);
+ }
+ };
+
+ final AroundAdvice advice = _advice.get (indNextAdvice);
+ final Object result = advice.evaluate (ctx, thisJoinPoint, _thisJoinPointStaticPart);
+
+ if (indNextAdvice >= _firstCacheableIndex) {
+ final Triplet<Function, AroundAdvice, List<?>> key = new Triplet<Function, AroundAdvice, List<?>> (_function, _advice.get (indNextAdvice), Arrays.asList(params));
+ ctx.getAdviceContext().getResultCache().put (key, new ObjectWrapper (result));
+ }
+
+ return result;
+ }
+}
+
+
+
+
+
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AroundAdvice.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AroundAdvice.java
new file mode 100644
index 0000000..29c9c59
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/AroundAdvice.java
@@ -0,0 +1,70 @@
+/*
+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.backend.aop;
+
+import org.eclipse.xtend.backend.common.ExecutionContext;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.eclipse.xtend.backend.common.SyntaxConstants;
+
+
+/**
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class AroundAdvice {
+ private final ExpressionBase _body;
+ private final Pointcut _pointcut;
+
+ private final boolean _isCacheable;
+
+ /**
+ *
+ * @param body contains the body of this advice
+ * @param pointcut contains the pointcut that guards this advice
+ * @param isCacheable This flag marks the advice as "cacheable". This means that the result of its execution
+ * will be cached iff all advice wrapped by it, and the originally wrapped function,
+ * are cacheable or cached, respectively.
+ */
+ public AroundAdvice (ExpressionBase body, Pointcut pointcut, boolean isCacheable) {
+ _body = body;
+ _pointcut = pointcut;
+ _isCacheable = isCacheable;
+ }
+
+ /**
+ * actually evaluates the advice, regardless of caching - that is context sensitive and must
+ * be taken care of by callers
+ */
+ public Object evaluate (ExecutionContext ctx, ThisJoinPoint thisJoinPoint, ThisJoinPointStaticPart thisJoinPointStaticPart) {
+ ctx.getLocalVarContext().getLocalVars().put (SyntaxConstants.THIS_JOINPOINT, thisJoinPoint);
+ ctx.getLocalVarContext().getLocalVars().put (SyntaxConstants.THIS_JOINPOINT_STATICPART, thisJoinPointStaticPart);
+
+ try {
+ return _body.evaluate (ctx);
+ }
+ finally {
+ ctx.getLocalVarContext ().getLocalVars ().remove (SyntaxConstants.THIS_JOINPOINT);
+ ctx.getLocalVarContext ().getLocalVars ().remove (SyntaxConstants.THIS_JOINPOINT_STATICPART);
+ }
+ }
+
+ public Pointcut getPointcut () {
+ return _pointcut;
+ }
+
+ /**
+ * This flag determines whether the advice is cacheable. It is intentionally
+ * kept separate from the "cached" flag of the implementing function because
+ * of the different semantics.
+ */
+ public boolean isCacheable () {
+ return _isCacheable;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ExecutionPointcut.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ExecutionPointcut.java
new file mode 100644
index 0000000..1357590
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ExecutionPointcut.java
@@ -0,0 +1,118 @@
+/*
+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.backend.aop;
+
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.eclipse.xtend.backend.common.BackendType;
+import org.eclipse.xtend.backend.common.Function;
+import org.eclipse.xtend.backend.util.Pair;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class ExecutionPointcut implements Pointcut {
+ private final String _functionNamePattern;
+ private final boolean _hasCompleteName;
+ private final Pattern _namePattern;
+
+ private final List<Pair<String, AdviceParamType>> _paramTypes;
+
+ private final boolean _hasVarArgs;
+ private final AdviceParamType _varArgsType;
+
+ /**
+ *
+ * @param functionNamePattern is the pattern for the function name that is matched by this pointcut. '*' can
+ * be used as a wildcard.
+ *
+ * @param paramTypes this is the - optionally empty - list of parameters for which an explicit type is given.
+ *
+ * @param hasVarArgs this flag determines if there is a variable number of arguments after the explicitly given
+ * param types. One of the two extreme cases is that all parameters are explicitly given, then this
+ * flag is false. The other extreme case is that the pointcut regardless of
+ *
+ * @param varArgsType
+ */
+ public ExecutionPointcut (String functionNamePattern, List<Pair<String, AdviceParamType>> paramTypes, boolean hasVarArgs, AdviceParamType varArgsType) {
+ _functionNamePattern = functionNamePattern;
+ if (_functionNamePattern.contains ("*")) {
+ _hasCompleteName = false;
+ _namePattern = Pattern.compile (functionNamePattern.replace ("*", ".*"));
+ }
+ else {
+ _hasCompleteName = true;
+ _namePattern = null;
+ }
+
+ _paramTypes = paramTypes;
+ _hasVarArgs = hasVarArgs;
+ _varArgsType = varArgsType;
+ }
+
+ //TODO testen!!!
+
+ public boolean matches (String name, Function function) {
+ if (! matchesName (name))
+ return false;
+
+ if (! matchesParamTypes (function.getParameterTypes()))
+ return false;
+
+ return true;
+ }
+
+ private boolean matchesParamTypes (List<? extends BackendType> paramTypes) {
+ // check the number of parameters
+ if (_hasVarArgs) {
+ if (paramTypes.size() < _paramTypes.size())
+ return false;
+ }
+ else {
+ if (paramTypes.size() != _paramTypes.size())
+ return false;
+ }
+
+ // check the explicitly given parameter types
+ for (int i=0; i<_paramTypes.size(); i++)
+ if (! _paramTypes.get (i).getSecond().matches (paramTypes.get (i)))
+ return false;
+
+ // check the var args type against the remaining parameter types
+ for (int i=_paramTypes.size(); i<paramTypes.size(); i++)
+ if (! _varArgsType.matches (paramTypes.get(i)))
+ return false;
+
+ return true;
+ }
+
+ private boolean matchesName (String functionName) {
+ if (_hasCompleteName)
+ return functionName.equals (_functionNamePattern);
+
+ return _namePattern.matcher (functionName).matches();
+ }
+}
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/Pointcut.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/Pointcut.java
new file mode 100644
index 0000000..4a1af32
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/Pointcut.java
@@ -0,0 +1,26 @@
+/*
+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.backend.aop;
+
+import org.eclipse.xtend.backend.common.Function;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public interface Pointcut {
+
+ /**
+ * checks if this pointcut matches a given function
+ */
+ public boolean matches (String name, Function f);
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ThisJoinPoint.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ThisJoinPoint.java
new file mode 100644
index 0000000..1d36a31
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ThisJoinPoint.java
@@ -0,0 +1,45 @@
+/*
+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.backend.aop;
+
+import java.util.List;
+
+import org.eclipse.xtend.backend.common.StacktraceEntry;
+
+
+/**
+ * This class exposes all dynamic data available for a matched join point.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public abstract class ThisJoinPoint {
+ private final List<StacktraceEntry> _stackTrace;
+ private final Object[] _params;
+
+ public ThisJoinPoint (List<StacktraceEntry> stackTrace, Object[] params) {
+ _stackTrace = stackTrace;
+ _params = params;
+ }
+
+ public List<StacktraceEntry> getStackTrace () {
+ return _stackTrace;
+ }
+
+ public Object[] getParameters () {
+ return _params;
+ }
+
+ public Object proceed () {
+ return proceed (_params);
+ }
+
+ public abstract Object proceed (Object[] params);
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ThisJoinPointStaticPart.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ThisJoinPointStaticPart.java
new file mode 100644
index 0000000..a61f636
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/aop/ThisJoinPointStaticPart.java
@@ -0,0 +1,42 @@
+/*
+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.backend.aop;
+
+import org.eclipse.xtend.backend.common.Function;
+
+
+/**
+ * This class exposes all static information about the matched join point.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class ThisJoinPointStaticPart {
+ private final String _functionName;
+ private final Function _function;
+
+ public ThisJoinPointStaticPart (String functionName, Function function) {
+ _functionName = functionName;
+ _function = function;
+ }
+
+ public String getFunctionName () {
+ return _functionName;
+ }
+
+ public Function getFunction () {
+ return _function;
+ }
+
+ @Override
+ public String toString () {
+ return _functionName + ": " + _function;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/AdviceContext.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/AdviceContext.java
new file mode 100644
index 0000000..2a3c284
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/AdviceContext.java
@@ -0,0 +1,24 @@
+/*
+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.backend.common;
+
+import org.eclipse.xtend.backend.aop.AdvisedFunction;
+import org.eclipse.xtend.backend.aop.AroundAdvice;
+
+
+/**
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public interface AdviceContext {
+ AdviceContext copyWithAdvice (AroundAdvice advice);
+ AdvisedFunction getAdvice (String functionName, Function f);
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/ExecutionContext.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/ExecutionContext.java
index c21df69..26bd22d 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/ExecutionContext.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/ExecutionContext.java
@@ -12,6 +12,8 @@ package org.eclipse.xtend.backend.common;
import java.util.List;
+import org.eclipse.xtend.backend.aop.AdviceContextImpl;
+
/**
*
@@ -28,6 +30,9 @@ public interface ExecutionContext {
FunctionInvoker getFunctionInvoker ();
CreationCache getCreationCache ();
+ AdviceContextImpl getAdviceContext ();
+ void setAdviceContext (AdviceContextImpl ctx);
+
void logNullDeRef (SourcePos pos);
boolean isLogStacktrace ();
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/util/SyntaxConstants.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/SyntaxConstants.java
index fb3818f..56640a8 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/util/SyntaxConstants.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/SyntaxConstants.java
@@ -8,7 +8,7 @@ http://www.eclipse.org/legal/epl-v10.html
Contributors:
Arno Haase - initial API and implementation
*/
-package org.eclipse.xtend.backend.util;
+package org.eclipse.xtend.backend.common;
/**
@@ -18,4 +18,7 @@ package org.eclipse.xtend.backend.util;
public interface SyntaxConstants {
String NS_DELIM = "::";
String THIS = "this";
+
+ String THIS_JOINPOINT = "thisJoinPoint";
+ String THIS_JOINPOINT_STATICPART = "thisJoinPointStaticPart";
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/internal/FunctionDefContextImpl.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/internal/FunctionDefContextImpl.java
index 295bc54..3716a49 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/internal/FunctionDefContextImpl.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/internal/FunctionDefContextImpl.java
@@ -107,11 +107,12 @@ public final class FunctionDefContextImpl implements FunctionDefContextInternal
Function f = null;
try {
- f = new PolymorphicResolver(functionName).evaluateGuards(ctx, candidates);
+ f = new PolymorphicResolver (functionName).evaluateGuards (ctx, candidates);
}
catch (Exception exc) {
ErrorHandler.handle ("could not resolve function '" + functionName + "' for parameter types " + StringHelper.getTypesAsString (params) + " - candidates were " + candidates, exc);
}
+
return ctx.getFunctionInvoker().invoke (ctx, f, params);
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/ExecutionContextImpl.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/ExecutionContextImpl.java
index c27ba97..3658d0c 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/ExecutionContextImpl.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/ExecutionContextImpl.java
@@ -14,6 +14,7 @@ import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.LogFactory;
+import org.eclipse.xtend.backend.aop.AdviceContextImpl;
import org.eclipse.xtend.backend.common.BackendTypesystem;
import org.eclipse.xtend.backend.common.Constants;
import org.eclipse.xtend.backend.common.ContributionStateContext;
@@ -39,6 +40,8 @@ public final class ExecutionContextImpl implements ExecutionContext {
private final boolean _logStacktrace;
private final List<StacktraceEntry> _stacktrace = new ArrayList<StacktraceEntry> ();
+ private AdviceContextImpl _adviceContext = new AdviceContextImpl ();
+
private final ContributionStateContext _contributionStateContext = new ContributionStateContext ();
public ExecutionContextImpl (FunctionDefContext initialFunctionDefContext, BackendTypesystem typesystem, boolean logStacktrace) {
@@ -94,4 +97,12 @@ public final class ExecutionContextImpl implements ExecutionContext {
public boolean isLogStacktrace () {
return _logStacktrace;
}
+
+ public AdviceContextImpl getAdviceContext () {
+ return _adviceContext;
+ }
+
+ public void setAdviceContext (AdviceContextImpl ctx) {
+ _adviceContext = ctx;
+ }
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/FunctionInvokerImpl.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/FunctionInvokerImpl.java
index 4b9b554..4a934c1 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/FunctionInvokerImpl.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/internal/FunctionInvokerImpl.java
@@ -38,7 +38,7 @@ public final class FunctionInvokerImpl implements FunctionInvoker {
private ExecutionContext _ctx;
- public Object invoke(ExecutionContext ctx, Function f, List<?> params) {
+ public Object invoke (ExecutionContext ctx, Function f, List<?> params) {
if (f.isCached()) {
_ctx = ctx;
return _cache.get(f, params);
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/util/ObjectWrapper.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/util/ObjectWrapper.java
new file mode 100644
index 0000000..92ab9d5
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/util/ObjectWrapper.java
@@ -0,0 +1,26 @@
+/*
+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.backend.util;
+
+
+/**
+ * This class was introduced to allow the distinction between a cached "null" value
+ * and no stored value without necessitating two lookups.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public final class ObjectWrapper {
+ public ObjectWrapper (Object content) {
+ _content = content;
+ }
+
+ public Object _content;
+}
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 06f6dbf..a2ead0b 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
@@ -41,6 +41,7 @@ import org.eclipse.xtend.backend.common.Function;
import org.eclipse.xtend.backend.common.FunctionDefContext;
import org.eclipse.xtend.backend.common.NamedFunction;
import org.eclipse.xtend.backend.common.SourcePos;
+import org.eclipse.xtend.backend.common.SyntaxConstants;
import org.eclipse.xtend.backend.expr.ConcatExpression;
import org.eclipse.xtend.backend.expr.HidingLocalVarDefExpression;
import org.eclipse.xtend.backend.expr.IfExpression;
@@ -55,7 +56,6 @@ import org.eclipse.xtend.backend.functions.SourceDefinedFunction;
import org.eclipse.xtend.backend.syslib.FileIoOperations;
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.expression.AnalysationIssue;
import org.eclipse.xtend.expression.ExecutionContext;
import org.eclipse.xtend.expression.Variable;
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 f9e3db6..d4b4e1d 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
@@ -152,7 +152,7 @@ final class OldExpressionConverter {
if (hasMatchingOperationCall (functionName, paramTypes.toArray (new Type[0])))
return new InvocationOnObjectExpression (functionName, params, false, sourcePos);
else {
- final ExpressionBase thisExpression = new LocalVarEvalExpression (org.eclipse.xtend.backend.util.SyntaxConstants.THIS, sourcePos);
+ final ExpressionBase thisExpression = new LocalVarEvalExpression (org.eclipse.xtend.backend.common.SyntaxConstants.THIS, sourcePos);
final Type thisType = (Type) _ctx.getVariable (ExecutionContext.IMPLICIT_VARIABLE).getValue();
return createInvocationOnTargetExpression (functionName, thisExpression, thisType, params, paramTypes, true, sourcePos);
}
@@ -251,7 +251,7 @@ final class OldExpressionConverter {
if (! hasThis())
throw new IllegalStateException ("typeSelect with neither a target nor an implicit 'this'");
- final ExpressionBase thisExpr = new LocalVarEvalExpression (org.eclipse.xtend.backend.util.SyntaxConstants.THIS, sourcePos);
+ final ExpressionBase thisExpr = new LocalVarEvalExpression (org.eclipse.xtend.backend.common.SyntaxConstants.THIS, sourcePos);
return new InvocationOnObjectExpression (SysLibNames.TYPE_SELECT, Arrays.asList (thisExpr, typeExpr), true, sourcePos);
}
else
@@ -324,7 +324,7 @@ final class OldExpressionConverter {
// 4. check for "this"
if (hasThis()) {
- final ExpressionBase thisExpr = new LocalVarEvalExpression (org.eclipse.xtend.backend.util.SyntaxConstants.THIS, sourcePos);
+ final ExpressionBase thisExpr = new LocalVarEvalExpression (org.eclipse.xtend.backend.common.SyntaxConstants.THIS, sourcePos);
return createPropertyExpression (thisExpr, (Type) _ctx.getVisibleVariables().get (ExecutionContext.IMPLICIT_VARIABLE).getValue(), expr.getName().getValue(), sourcePos);
}
@@ -372,7 +372,7 @@ final class OldExpressionConverter {
if (! hasThis())
throw new IllegalStateException (functionName + " with neither a target nor an implicit 'this'");
- final ExpressionBase thisExpr = new LocalVarEvalExpression (org.eclipse.xtend.backend.util.SyntaxConstants.THIS, sourcePos);
+ final ExpressionBase thisExpr = new LocalVarEvalExpression (org.eclipse.xtend.backend.common.SyntaxConstants.THIS, sourcePos);
return new InvocationOnObjectExpression (functionName, Arrays.asList (thisExpr, closureExpr), true, sourcePos);
}
else
diff --git a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExtensionConverter.java b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExtensionConverter.java
index 2579940..d9466bd 100644
--- a/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExtensionConverter.java
+++ b/plugins/org.eclipse.xtend.middleend.old/src/org/eclipse/xtend/middleend/old/OldExtensionConverter.java
@@ -25,12 +25,12 @@ import org.eclipse.xtend.backend.common.ExpressionBase;
import org.eclipse.xtend.backend.common.Function;
import org.eclipse.xtend.backend.common.FunctionDefContext;
import org.eclipse.xtend.backend.common.NamedFunction;
+import org.eclipse.xtend.backend.common.SyntaxConstants;
import org.eclipse.xtend.backend.expr.CreateCachedExpression;
import org.eclipse.xtend.backend.expr.LocalVarEvalExpression;
import org.eclipse.xtend.backend.expr.NewLocalVarDefExpression;
import org.eclipse.xtend.backend.functions.FunctionDefContextInternal;
import org.eclipse.xtend.backend.functions.SourceDefinedFunction;
-import org.eclipse.xtend.backend.util.SyntaxConstants;
import org.eclipse.xtend.expression.AnalysationIssue;
import org.eclipse.xtend.expression.ExecutionContext;
import org.eclipse.xtend.expression.Variable;