From e90f8a9dcd53e3449a220699792b569f96208182 Mon Sep 17 00:00:00 2001
From: ahaase
Date: Mon, 10 Mar 2008 23:58:51 +0000
Subject: refactored middleend infrastructure to improve reuse between
languages
---
.../org.eclipse.xtend.backend/META-INF/MANIFEST.MF | 12 +-
.../org/eclipose/xtend/middleend/MiddleEnd.java | 139 -------------
.../eclipose/xtend/middleend/MiddleEndFactory.java | 48 -----
.../xtend/middleend/internal/Activator.java | 105 ----------
.../plugins/LanguageSpecificMiddleEnd.java | 58 ------
.../plugins/LanguageSpecificMiddleEndFactory.java | 48 -----
.../eclipse/xtend/backend/aop/AroundAdvice.java | 9 +-
.../org/eclipse/xtend/backend/common/Function.java | 4 +-
.../xtend/backend/expr/CurriedFunction.java | 9 +
.../backend/expr/HidingLocalVarDefExpression.java | 3 +
.../expr/InvocationOnWhateverExpression.java | 3 +
.../backend/expr/PropertyOnWhateverExpression.java | 3 +
.../xtend/backend/functions/AbstractFunction.java | 50 +++++
.../backend/functions/SourceDefinedFunction.java | 48 +----
.../xtend/backend/functions/internal/Closure.java | 35 ++--
.../functions/internal/FunctionDefContextImpl.java | 1 -
.../backend/internal/FunctionInvokerImpl.java | 20 +-
.../xtend/backend/syslib/CollectionOperations.java | 6 +-
.../xtend/backend/syslib/StringOperations.java | 4 +-
.../eclipse/xtend/backend/types/AbstractType.java | 17 ++
.../xtend/backend/types/builtin/FunctionType.java | 9 +
.../xtend/backend/types/builtin/TypeType.java | 9 +
.../backend/types/emf/internal/EClassType.java | 9 +
.../backend/types/java/internal/JavaOperation.java | 22 +-
.../src/org/eclipse/xtend/middleend/MiddleEnd.java | 51 +++++
.../eclipse/xtend/middleend/MiddleEndFactory.java | 49 +++++
.../xtend/middleend/internal/Activator.java | 105 ++++++++++
.../xtend/middleend/internal/MiddleEndImpl.java | 223 +++++++++++++++++++++
.../AbstractExecutionContextAware.java | 2 +
.../javaannotations/JavaDefinedFunction.java | 200 ------------------
.../JavaFunctionClassContributor.java | 64 ++++--
.../middleend/javaannotations/M2tAroundAdvice.java | 31 +++
.../xtend/middleend/javaannotations/M2tCached.java | 27 +++
.../xtend/middleend/javaannotations/M2tHidden.java | 27 ---
.../middleend/javaannotations/M2tNoFunction.java | 27 +++
.../javaannotations/M2tPrivateFunction.java | 28 +++
.../internal/JavaDefinedFunction.java | 152 ++++++++++++++
.../xtend/middleend/plugins/ImportedResource.java | 34 ++++
.../plugins/LanguageSpecificMiddleEnd.java | 46 +++++
.../plugins/LanguageSpecificMiddleEndFactory.java | 48 +++++
.../xtend/middleend/plugins/ParsedResource.java | 46 +++++
.../xtend/middleend/xpand/OldXpandRegistry.java | 118 ++++-------
.../xtend/middleend/xpand/XpandBackendFacade.java | 9 +-
.../xpand/internal/OldDefinitionConverter.java | 23 +--
.../xpand/internal/OldXpandRegistryFactory.java | 4 +-
.../xtend/middleend/xtend/OldXtendRegistry.java | 171 +++-------------
.../xtend/middleend/xtend/XtendBackendFacade.java | 18 +-
.../xtend/internal/OldExpressionConverter.java | 5 +-
.../xtend/middleend/xtend/internal/OldHelper.java | 4 +-
.../xtend/internal/xtend/CheckConverter.java | 5 +-
.../internal/xtend/JavaExtensionFunction.java | 22 +-
.../internal/xtend/OldExtensionConverter.java | 31 +--
.../internal/xtendlib/XtendLibContributor.java | 2 +-
.../xtend/plugin/OldXtendRegistryFactory.java | 4 +-
.../src/org/eclipse/xtend/backend/aop/AopTest.java | 55 ++---
.../backend/expr/InitClosureExpressionTest.java | 16 +-
.../xtend/backend/functions/FunctionTest.java | 15 +-
.../backend/testhelpers/BackendTestHelper.java | 11 +-
.../backend/testhelpers/NamedFunctionFactory.java | 36 ++--
.../xtend/middleend/old/first/FirstAttempt.java | 2 +
60 files changed, 1248 insertions(+), 1134 deletions(-)
delete mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/MiddleEnd.java
delete mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/MiddleEndFactory.java
delete mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/internal/Activator.java
delete mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/plugins/LanguageSpecificMiddleEnd.java
delete mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/plugins/LanguageSpecificMiddleEndFactory.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/AbstractFunction.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/MiddleEnd.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/MiddleEndFactory.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/internal/Activator.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/internal/MiddleEndImpl.java
delete mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/javaannotations/JavaDefinedFunction.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/javaannotations/M2tAroundAdvice.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/javaannotations/M2tCached.java
delete mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/javaannotations/M2tHidden.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/javaannotations/M2tNoFunction.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/javaannotations/M2tPrivateFunction.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/javaannotations/internal/JavaDefinedFunction.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/plugins/ImportedResource.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/plugins/LanguageSpecificMiddleEnd.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/plugins/LanguageSpecificMiddleEndFactory.java
create mode 100644 plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/middleend/plugins/ParsedResource.java
diff --git a/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF b/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF
index fd67501f..0bf9d571 100644
--- a/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.xtend.backend/META-INF/MANIFEST.MF
@@ -3,10 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: Backend Plug-in (Incubation)
Bundle-SymbolicName: org.eclipse.xtend.backend;singleton:=true
Bundle-Version: 0.7.0
-Export-Package: org.eclipose.xtend.middleend,
- org.eclipose.xtend.middleend.internal;x-internal:=true,
- org.eclipose.xtend.middleend.plugins,
- org.eclipse.xtend.backend;uses:="org.eclipse.xtend.backend.common",
+Export-Package: org.eclipse.xtend.backend;uses:="org.eclipse.xtend.backend.common",
org.eclipse.xtend.backend.aop,
org.eclipse.xtend.backend.aop.internal;x-internal:=true,
org.eclipse.xtend.backend.common,
@@ -22,11 +19,14 @@ Export-Package: org.eclipose.xtend.middleend,
org.eclipse.xtend.backend.types.emf.internal;x-internal:=true,
org.eclipse.xtend.backend.types.java.internal;x-internal:=true,
org.eclipse.xtend.backend.util,
- org.eclipse.xtend.middleend.javaannotations
+ org.eclipse.xtend.middleend,
+ org.eclipse.xtend.middleend.internal;x-internal:=true,
+ org.eclipse.xtend.middleend.javaannotations,
+ org.eclipse.xtend.middleend.plugins
Require-Bundle: org.apache.commons.logging,
org.eclipse.emf.ecore,
org.eclipse.osgi,
org.eclipse.equinox.registry,
org.eclipse.emf.mwe.core
Eclipse-LazyStart: true
-Bundle-Activator: org.eclipose.xtend.middleend.internal.Activator
+Bundle-Activator: org.eclipse.xtend.middleend.internal.Activator
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/MiddleEnd.java b/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/MiddleEnd.java
deleted file mode 100644
index 176c2d08..00000000
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/MiddleEnd.java
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
-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.eclipose.xtend.middleend;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.eclipose.xtend.middleend.plugins.LanguageSpecificMiddleEnd;
-import org.eclipse.xtend.backend.BackendFacade;
-import org.eclipse.xtend.backend.aop.AroundAdvice;
-import org.eclipse.xtend.backend.common.BackendTypesystem;
-import org.eclipse.xtend.backend.common.ExecutionContext;
-import org.eclipse.xtend.backend.common.FunctionDefContext;
-import org.eclipse.xtend.backend.common.NamedFunction;
-import org.eclipse.xtend.backend.functions.FunctionDefContextInternal;
-import org.eclipse.xtend.backend.functions.internal.FunctionDefContextImpl;
-import org.eclipse.xtend.backend.syslib.SyslibContributor;
-import org.eclipse.xtend.middleend.javaannotations.JavaFunctionClassContributor;
-
-
-/**
- * This class is the generic entry point for parsing and executing code. Different
- * languages can contribute their specific middle ends using extension points.
- *
- * MiddleEnd instances are stateful in that they preserve caching of the contributed
- * middle ends. They also preserve a single ExecutionContext instance throughout their
- * life span, but they expose it to allows using code to selectively manipulate and / or
- * re-initialize it between invocations.
- *
- * @author Arno Haase (http://www.haase-consulting.com)
- */
-public final class MiddleEnd {
- private static final Log _log = LogFactory.getLog (MiddleEnd.class);
-
- private final List _languageHandlers;
- private final ExecutionContext _ctx;
- private final BackendTypesystem _ts;
-
- /**
- * this flag marks the temporary state while the syslib is added to a newly created fdc. During
- * this phase, newly created fdcs are returned *without* registering the syslib to avoid endless
- * recursion.
- */
- private boolean _isInitializingSyslib = false;
-
- /**
- * The map with "specific params" is used to initialize the contributed middle ends.
- * The key must be the class implementing the LanguageSpecificMiddleEnd interface
- * and contributed via the extension point.
- */
- public MiddleEnd (BackendTypesystem ts, List languageHandlers) {
- if (languageHandlers == null)
- languageHandlers = new ArrayList ();
-
- // this is a "built-in" handler that is, among other things, necessary for the syslib
- languageHandlers.add (new JavaFunctionClassContributor ());
-
- _ts = ts;
- _languageHandlers = languageHandlers;
-
- for (LanguageSpecificMiddleEnd handler: languageHandlers)
- handler.setMiddleEnd (this);
-
- // it is important that the middle end is properly initialized before an fdc is created because
- // syslib registration relies on an initialized middle end.
- _ctx = BackendFacade.createExecutionContext (createEmptyFdc(), ts, false);
- }
-
- private LanguageSpecificMiddleEnd findHandler (String resourceName) {
- for (LanguageSpecificMiddleEnd candidate: _languageHandlers) {
- if (candidate.canHandle (resourceName)) {
- _log.debug ("middle end " + candidate.getName() + " handles resource " + resourceName);
- return candidate;
- }
- }
-
- _log.warn ("no middle end for resource " + resourceName);
- throw new IllegalArgumentException ("no middle end for resource " + resourceName);
- }
-
- /**
- * tells this middle end instance to apply the advice in a given resource to all
- * subsequent invocations.
- */
- public void applyAdvice (String resourceName) {
- for (AroundAdvice advice: findHandler(resourceName).getContributedAdvice(resourceName))
- _ctx.setAdviceContext (_ctx.getAdviceContext().copyWithAdvice (advice));
- }
-
- public FunctionDefContext getFunctions (String resourceName) {
- return findHandler (resourceName).getContributedFunctions (resourceName);
- }
-
-
- /**
- * This method exposes the execution context to using code with the explicit purpose of allowing others to
- * inspect and manipulate / re-initialize it partially or in toto.
- *
- * But beware: This data structure is used directly by the runtime, and modifications can significantly
- * influence behavior at runtime!
- */
- public ExecutionContext getExecutionContext () {
- return _ctx;
- }
-
- public BackendTypesystem getTypesystem () {
- return _ts;
- }
-
- public FunctionDefContextInternal createEmptyFdc () {
- final FunctionDefContextInternal result = new FunctionDefContextImpl ();
-
- if (_isInitializingSyslib)
- return result;
-
- _isInitializingSyslib = true;
-
- try {
- for (String resourceName: SyslibContributor.getSysLibResources())
- for (NamedFunction f: getFunctions(resourceName).getPublicFunctions())
- result.register (f, true);
-
- return result;
- }
- finally {
- _isInitializingSyslib = false;
- }
- }
-}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/MiddleEndFactory.java b/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/MiddleEndFactory.java
deleted file mode 100644
index b2679eff..00000000
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/MiddleEndFactory.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-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.eclipose.xtend.middleend;
-
-import java.util.List;
-import java.util.Map;
-
-import org.eclipose.xtend.middleend.internal.Activator;
-import org.eclipose.xtend.middleend.plugins.LanguageSpecificMiddleEnd;
-import org.eclipse.xtend.backend.common.BackendTypesystem;
-
-
-/**
- * This class encapsulates the OSGi / Eclipse extension registry specific behavior and
- * initialization code. It serves as an optional wrapper / convenience initialization
- * code for the actual MiddleEnd class.
- *
- * @author Arno Haase (http://www.haase-consulting.com)
- */
-public final class MiddleEndFactory {
- /**
- * This method creates a MiddleEnd instance based on an explicitly provided list of handlers. It works without
- * OSGi.
- */
- public static MiddleEnd create (BackendTypesystem ts, List languageHandlers) {
- return new MiddleEnd (ts, languageHandlers);
- }
-
- /**
- * This method creates a middle end based on the handlers registered with the extension point. It relies
- * on OSGi and makes use of the Eclipse extension registry.
- *
- * The map with "specific params" is used to initialize the contributed middle ends.
- * The key must be the class implementing the LanguageSpecificMiddleEnd interface
- * and contributed via the extension point.
- */
- public static MiddleEnd create (BackendTypesystem ts, Map, Object> specificParams) {
- return new MiddleEnd (ts, Activator.getInstance().getFreshMiddleEnds (specificParams));
- }
-}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/internal/Activator.java b/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/internal/Activator.java
deleted file mode 100644
index bad81b2f..00000000
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/internal/Activator.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-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.eclipose.xtend.middleend.internal;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.eclipose.xtend.middleend.plugins.LanguageSpecificMiddleEnd;
-import org.eclipose.xtend.middleend.plugins.LanguageSpecificMiddleEndFactory;
-import org.eclipse.core.runtime.IConfigurationElement;
-import org.eclipse.core.runtime.RegistryFactory;
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-
-/**
- *
- * @author Arno Haase (http://www.haase-consulting.com)
- */
-public class Activator implements BundleActivator {
- private static final Log _log = LogFactory.getLog (Activator.class);
-
- private static Activator _instance = null;
-
- public static Activator getInstance () {
- return _instance;
- }
-
- private final List _middleEndContributions = new ArrayList ();
- private boolean _isInitialized = false;
-
-
- public List getFreshMiddleEnds (Map, Object> specificParams) {
- init ();
-
- final List result = new ArrayList();
-
- for (LanguageSpecificMiddleEndFactory factory: _middleEndContributions) {
- try {
- result.add (factory.create (specificParams.get (factory.getClass())));
- }
- catch (IllegalArgumentException exc) {
- // this is the official way for an implementation to withdraw from the pool for this call
- _log.debug ("middle end implementation " + factory.getName() + " says it is not available: " + exc.getMessage());
- }
- }
-
- return result;
- }
-
- public void start (BundleContext context) throws Exception {
- //TODO Bernd: implement error handling and logging to be both robust and independent of Eclipse
-
- _isInitialized = false;
- _instance = this;
- }
-
- private void init () {
- if (_isInitialized)
- return;
-
- _isInitialized = true;
- _middleEndContributions.clear ();
-
- try {
- final IConfigurationElement[] confEl = RegistryFactory.getRegistry().getConfigurationElementsFor ("org.eclipse.xtend.backend.MiddleEnd");
-
- for (IConfigurationElement curEl: confEl) {
- final Object o = curEl.createExecutableExtension ("class");
- _middleEndContributions.add ((LanguageSpecificMiddleEndFactory) o);
- }
- }
- catch (Exception exc) {
- exc.printStackTrace ();
- }
-
- Collections.sort (_middleEndContributions, new Comparator () {
- public int compare (LanguageSpecificMiddleEndFactory o1, LanguageSpecificMiddleEndFactory o2) {
- return o1.getPriority() - o2.getPriority();
- }
- });
-
- _log.info ("Activating Eclipse Modeling Middle End - the following middle ends are registered:");
- for (LanguageSpecificMiddleEndFactory factory: _middleEndContributions)
- _log.info (" " + factory.getName());
- }
-
- public void stop (BundleContext context) throws Exception {
- _instance = null;
- _middleEndContributions.clear();
- }
-}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/plugins/LanguageSpecificMiddleEnd.java b/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/plugins/LanguageSpecificMiddleEnd.java
deleted file mode 100644
index 351cd174..00000000
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/plugins/LanguageSpecificMiddleEnd.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
-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.eclipose.xtend.middleend.plugins;
-
-import java.util.List;
-
-import org.eclipose.xtend.middleend.MiddleEnd;
-import org.eclipse.xtend.backend.aop.AroundAdvice;
-import org.eclipse.xtend.backend.common.FunctionDefContext;
-
-
-/**
- * This interface is the common abstraction through which all handlers for different
- * languages can contribute their middle ends.
- *
- * @author Arno Haase (http://www.haase-consulting.com)
- */
-public interface LanguageSpecificMiddleEnd {
- /**
- * This method is used to break the circular dependency between MiddleEnd and the
- * language specific handlers. It is called by the MiddleEnd on creation.
- */
- void setMiddleEnd (MiddleEnd middleEnd);
-
- String getName ();
-
- /**
- * gives the middle end a way to declare if it can and wants to handle a given
- * source file / resource. If and only if it returns true, it will be asked for
- * the functions and advice provided in this resource.
- */
- boolean canHandle (String resourceName);
-
- /**
- * This method asks the middle end to parse a resource for which it declared
- * that it is the appropriate handler, and return the functions contained therein.
- *
- * Implementations are encouraged to perform aggressive caching. The calling code
- * takes care of re-initializing the middle end implementations as it deems fit by
- * creating new instances of the contributed middle end implementation classes.
- */
- FunctionDefContext getContributedFunctions (String resourceName);
-
- /**
- * This method is the same as getContributedFunctions, except that it returns advice
- * rather than functions. Since the semantics of advice depends on the order in which
- * it is applied, this method returns a list rather than an arbitrary collection.
- */
- List getContributedAdvice (String resourceName);
-}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/plugins/LanguageSpecificMiddleEndFactory.java b/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/plugins/LanguageSpecificMiddleEndFactory.java
deleted file mode 100644
index feb69150..00000000
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipose/xtend/middleend/plugins/LanguageSpecificMiddleEndFactory.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-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.eclipose.xtend.middleend.plugins;
-
-
-/**
- * This interface is the common abstraction through which all handlers for different
- * languages can contribute their middle ends. Every language should contribute its
- * MiddleEnd implementation factory through the extension point.
- *
- * @author Arno Haase (http://www.haase-consulting.com)
- */
-public interface LanguageSpecificMiddleEndFactory {
- /**
- * a clear text name describing the language / middle end
- */
- String getName ();
-
- /**
- * the priority is a possible way to determine the order in which the middle ends
- * are asked if they can handle a given resource. Typically, only one middle end
- * implementation should declare that it can handle a given resource (i.e. source
- * file), and in this case a priority of 0 should be returned.
- *
- * In the rare case where it is needed, highest priority is asked first.
- */
- int getPriority ();
-
- /**
- * This method creates the actual implementation of the middle end. The specificData parameter is
- * passed through from the MiddleEnd constructor.
- *
- * It is permitted for implementations to throw an IllegalArgumentException,
- * which is the official way for an implementation to say that it views the
- * passed data as insufficient to perform, and therefore needs to be removed
- * from the list of registered middle ends. This is done on a per-call basis
- * and avoids the necessity to always initialize all middle end implementations.
- */
- LanguageSpecificMiddleEnd create (Object specificData);
-}
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
index dff82bb0..5fee28bb 100644
--- 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
@@ -23,7 +23,7 @@ import org.eclipse.xtend.backend.common.SyntaxConstants;
public final class AroundAdvice {
private final ExpressionBase _body;
private final Pointcut _pointcut;
- private final FunctionDefContext _fdc;
+ private FunctionDefContext _fdc;
private final boolean _isCacheable;
@@ -35,11 +35,10 @@ public final class AroundAdvice {
* 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, FunctionDefContext fdc) {
+ public AroundAdvice (ExpressionBase body, Pointcut pointcut, boolean isCacheable) {
_body = body;
_pointcut = pointcut;
_isCacheable = isCacheable;
- _fdc = fdc;
}
/**
@@ -65,6 +64,10 @@ public final class AroundAdvice {
}
}
+ public void setFunctionDefContext (FunctionDefContext fdc) {
+ _fdc = fdc;
+ }
+
public Pointcut getPointcut () {
return _pointcut;
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Function.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Function.java
index 676cd8a1..60be6f59 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Function.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/common/Function.java
@@ -14,7 +14,6 @@ import java.util.List;
/**
- *
* @author Arno Haase (http://www.haase-consulting.com)
*/
public interface Function {
@@ -28,4 +27,7 @@ public interface Function {
/** returns the expression that guards this function - or null, if there is no guard.*/
ExpressionBase getGuard();
+
+ FunctionDefContext getFunctionDefContext ();
+ void setFunctionDefContext (FunctionDefContext fdc);
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/CurriedFunction.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/CurriedFunction.java
index cd1ec273..967fda8c 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/CurriedFunction.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/CurriedFunction.java
@@ -17,6 +17,7 @@ import org.eclipse.xtend.backend.common.BackendType;
import org.eclipse.xtend.backend.common.ExecutionContext;
import org.eclipse.xtend.backend.common.ExpressionBase;
import org.eclipse.xtend.backend.common.Function;
+import org.eclipse.xtend.backend.common.FunctionDefContext;
/**
@@ -71,4 +72,12 @@ final class CurriedFunction implements Function {
public boolean isCached () {
return false;
}
+
+ public FunctionDefContext getFunctionDefContext () {
+ return _inner.getFunctionDefContext();
+ }
+
+ public void setFunctionDefContext (FunctionDefContext fdc) {
+ throw new UnsupportedOperationException ();
+ }
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpression.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpression.java
index 964bf7c2..1e6d96c6 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpression.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/HidingLocalVarDefExpression.java
@@ -16,6 +16,9 @@ import org.eclipse.xtend.backend.common.SourcePos;
import org.eclipse.xtend.backend.common.StacktraceEntry;
+//TODO refactor: middle ends only use this, and a subsequent step differentiates / optimizes to NewLocalVarExpression
+
+
/**
*
* @author Arno Haase (http://www.haase-consulting.com)
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpression.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpression.java
index 406d99e5..817b807e 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpression.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/InvocationOnWhateverExpression.java
@@ -20,6 +20,9 @@ import org.eclipse.xtend.backend.common.SourcePos;
import org.eclipse.xtend.backend.syslib.CollectionOperations;
+//TODO refactor: middle ends only use this, and a subsequent step differentiates / optimizes to the other two
+
+
/**
* This expression invokes a function on the first argument, deciding at runtime whether to do the "collection magic" of
* invoking the function on every member of the collection that is the first argument and returning the collection of
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/PropertyOnWhateverExpression.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/PropertyOnWhateverExpression.java
index 5163e28c..b4f55fe0 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/PropertyOnWhateverExpression.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/expr/PropertyOnWhateverExpression.java
@@ -20,6 +20,9 @@ import org.eclipse.xtend.backend.syslib.CollectionOperations;
import org.eclipse.xtend.backend.types.builtin.CollectionType;
+//TODO refactor: middle ends only use this, and a subsequent step differentiates / optimizes to the other two
+
+
/**
* This class deals with the case where the middle end can not decide statically whether
* a property is to be resolved on a single object or on a collection
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/AbstractFunction.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/AbstractFunction.java
new file mode 100644
index 00000000..f90b212d
--- /dev/null
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/AbstractFunction.java
@@ -0,0 +1,50 @@
+package org.eclipse.xtend.backend.functions;
+
+import java.util.List;
+
+import org.eclipse.xtend.backend.common.BackendType;
+import org.eclipse.xtend.backend.common.ExpressionBase;
+import org.eclipse.xtend.backend.common.Function;
+import org.eclipse.xtend.backend.common.FunctionDefContext;
+
+
+/**
+ * This convenience implementation provides default implementations for many of the
+ * Function methods.
+ *
+ * @author Arno Haase (http://www.haase-consulting.com)
+ */
+public abstract class AbstractFunction implements Function {
+ private final ExpressionBase _guard;
+ private final List extends BackendType> _parameterTypes;
+ private final boolean _cached;
+
+ private FunctionDefContext _fdc;
+
+
+ public AbstractFunction (ExpressionBase guard, List extends BackendType> parameterTypes, boolean cached) {
+ _guard = guard;
+ _parameterTypes = parameterTypes;
+ _cached = cached;
+ }
+
+ public ExpressionBase getGuard () {
+ return _guard;
+ }
+
+ public List extends BackendType> getParameterTypes () {
+ return _parameterTypes;
+ }
+
+ public boolean isCached () {
+ return _cached;
+ }
+
+ public FunctionDefContext getFunctionDefContext () {
+ return _fdc;
+ }
+
+ public void setFunctionDefContext (FunctionDefContext fdc) {
+ _fdc = fdc;
+ }
+}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/SourceDefinedFunction.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/SourceDefinedFunction.java
index ace0b564..5634018f 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/SourceDefinedFunction.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/SourceDefinedFunction.java
@@ -15,8 +15,6 @@ import java.util.List;
import org.eclipse.xtend.backend.common.BackendType;
import org.eclipse.xtend.backend.common.ExecutionContext;
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.LocalVarContext;
import org.eclipse.xtend.backend.common.StacktraceEntry;
@@ -25,53 +23,19 @@ import org.eclipse.xtend.backend.common.StacktraceEntry;
*
* @author Arno Haase (http://www.haase-consulting.com)
*/
-public final class SourceDefinedFunction implements Function {
+public final class SourceDefinedFunction extends AbstractFunction {
private final String _name;
private final List _paramNames;
- private final List _paramTypes;
- private final FunctionDefContext _defContext;
private final ExpressionBase _def;
- private final boolean _cached;
- private final ExpressionBase _guard;
- public SourceDefinedFunction (String name, List paramNames, List paramTypes, FunctionDefContext defContext, ExpressionBase def, boolean cached, ExpressionBase guard) {
+ public SourceDefinedFunction (String name, List paramNames, List paramTypes, ExpressionBase def, boolean cached, ExpressionBase guard) {
+ super (guard, paramTypes, cached);
_name = name;
_paramNames = paramNames;
- _paramTypes = paramTypes;
- _defContext = defContext;
_def = def;
- _cached = cached;
- _guard = guard;
}
- public boolean isCached () {
- return _cached;
- }
-
- public List getParameterTypes() {
- return _paramTypes;
- }
-
- public FunctionDefContext getFunctionDefContext () {
- return _defContext;
- }
-
public Object invoke (ExecutionContext ctx, Object[] params) {
- if (_defContext == ctx.getFunctionDefContext())
- return invokeWithExistingFdc (ctx, params);
- else {
- final FunctionDefContext oldFdc = ctx.getFunctionDefContext ();
- try {
- ctx.setFunctionDefContext (_defContext);
- return invokeWithExistingFdc(ctx, params);
- }
- finally {
- ctx.setFunctionDefContext (oldFdc);
- }
- }
- }
-
- private Object invokeWithExistingFdc (ExecutionContext ctx, Object[] params) {
final LocalVarContext lvc = new LocalVarContext ();
for (int i=0; i<_paramNames.size(); i++) {
lvc.getLocalVars().put(_paramNames.get(i), params[i]);
@@ -94,13 +58,9 @@ public final class SourceDefinedFunction implements Function {
}
}
- public ExpressionBase getGuard() {
- return _guard;
- }
-
@Override
public String toString () {
- return "SourceDefinedFunction '" + _name + "' " + _paramTypes;
+ return "SourceDefinedFunction '" + _name + "' " + getParameterTypes();
}
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/internal/Closure.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/internal/Closure.java
index 82a56a04..8b47c956 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/internal/Closure.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/functions/internal/Closure.java
@@ -15,47 +15,34 @@ import java.util.List;
import org.eclipse.xtend.backend.common.BackendType;
import org.eclipse.xtend.backend.common.ExecutionContext;
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.LocalVarContext;
+import org.eclipse.xtend.backend.functions.AbstractFunction;
/**
*
* @author Arno Haase (http://www.haase-consulting.com)
*/
-public final class Closure implements Function {
+public final class Closure extends AbstractFunction {
private final LocalVarContext _lvcAtDefinitionTime;
private final FunctionDefContext _fdcAtDefinitionTime;
private final List _paramNames;
- private final List extends BackendType> _paramTypes;
private final ExpressionBase _def;
public Closure (LocalVarContext lvcAtDefinitionTime, FunctionDefContext fdcAtDefinitionTime, List paramNames, List extends BackendType> paramTypes, ExpressionBase def) {
+ super (null, paramTypes, false);
+
//freeze local variables at definition time so they will be available in a different context at evaluation time
_lvcAtDefinitionTime = new LocalVarContext();
_lvcAtDefinitionTime.getLocalVars().putAll (lvcAtDefinitionTime.getLocalVars());
_fdcAtDefinitionTime = fdcAtDefinitionTime;
_paramNames = paramNames;
- _paramTypes = paramTypes;
_def = def;
}
-
- public String getName () {
- return "";
- }
-
- public boolean isCached () {
- return false;
- }
-
- public List extends BackendType> getParameterTypes() {
- return _paramTypes;
- }
-
public Object invoke (ExecutionContext ctx, Object[] params) {
if (_fdcAtDefinitionTime == ctx.getFunctionDefContext())
return invokeWithExistingFdc (ctx, params);
@@ -87,8 +74,14 @@ public final class Closure implements Function {
ctx.setLocalVarContext(oldLvc);
}
}
-
- public ExpressionBase getGuard() {
- return null;
- }
+
+ @Override
+ public void setFunctionDefContext (FunctionDefContext fdc) {
+ throw new UnsupportedOperationException ();
+ }
+
+ @Override
+ public FunctionDefContext getFunctionDefContext () {
+ return _fdcAtDefinitionTime;
+ }
}
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 ea01bcb5..e159dffc 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
@@ -114,7 +114,6 @@ public final class FunctionDefContextImpl implements FunctionDefContextInternal
}
return ctx.getAdviceContext().getAdvice (functionName, f).evaluate(ctx, params);
-// return ctx.getFunctionInvoker().invoke (ctx, f, params);
}
/**
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 4a934c1b..37dde12d 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
@@ -15,6 +15,7 @@ import java.util.List;
import org.eclipse.xtend.backend.common.EfficientLazyString;
import org.eclipse.xtend.backend.common.ExecutionContext;
import org.eclipse.xtend.backend.common.Function;
+import org.eclipse.xtend.backend.common.FunctionDefContext;
import org.eclipse.xtend.backend.common.FunctionInvoker;
import org.eclipse.xtend.backend.util.DoubleKeyCache;
@@ -27,7 +28,7 @@ public final class FunctionInvokerImpl implements FunctionInvoker {
private final DoubleKeyCache , Object> _cache = new DoubleKeyCache, Object> () {
@Override
protected Object create (Function f, List> params) {
- final Object result = f.invoke (_ctx, params.toArray());
+ final Object result = invoke (f, _ctx, params);
if (result instanceof EfficientLazyString)
((EfficientLazyString) result).makeImmutable();
@@ -37,14 +38,27 @@ public final class FunctionInvokerImpl implements FunctionInvoker {
};
private ExecutionContext _ctx;
+
+ private Object invoke (Function f, ExecutionContext ctx, List> params) {
+ //TODO optimize for the case when the fdc is == the existing fdc
+
+ final FunctionDefContext oldFdc = ctx.getFunctionDefContext();
+ ctx.setFunctionDefContext (f.getFunctionDefContext());
+ try {
+ return f.invoke(ctx, params.toArray());
+ }
+ finally {
+ ctx.setFunctionDefContext (oldFdc);
+ }
+ }
public Object invoke (ExecutionContext ctx, Function f, List> params) {
if (f.isCached()) {
_ctx = ctx;
- return _cache.get(f, params);
+ return _cache.get (f, params);
}
else {
- return f.invoke(ctx, params.toArray());
+ return invoke (f, ctx, params);
}
}
}
diff --git a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/syslib/CollectionOperations.java b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/syslib/CollectionOperations.java
index 9f3ca6af..a9d32fa8 100644
--- a/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/syslib/CollectionOperations.java
+++ b/plugins/org.eclipse.xtend.backend/src/org/eclipse/xtend/backend/syslib/CollectionOperations.java
@@ -24,7 +24,7 @@ import org.eclipse.xtend.backend.common.EfficientLazyString;
import org.eclipse.xtend.backend.common.Function;
import org.eclipse.xtend.backend.common.Helpers;
import org.eclipse.xtend.middleend.javaannotations.AbstractExecutionContextAware;
-import org.eclipse.xtend.middleend.javaannotations.M2tHidden;
+import org.eclipse.xtend.middleend.javaannotations.M2tNoFunction;
/**
@@ -350,7 +350,7 @@ public final class CollectionOperations extends AbstractExecutionContextAware {
// helpers
///////////////////////////////////
- @M2tHidden
+ @M2tNoFunction
public static void addFlattened (Collection