Script editor and interpreter relies on JvmModelInferrer

Signed-off-by: Oliver Libutzki <oliver@libutzki.de>
This commit is contained in:
Oliver Libutzki 2014-01-31 13:54:52 +01:00
Родитель 978c17f3ab
Коммит e81739fb09
16 изменённых файлов: 138 добавлений и 704 удалений

Просмотреть файл

@ -10,21 +10,15 @@
*/
package org.eclipse.smarthome.model.rule;
import org.eclipse.smarthome.model.rule.scoping.RulesFeatureScopes;
import org.eclipse.smarthome.model.rule.scoping.RulesImplicitlyImportedTypes;
import org.eclipse.smarthome.model.rule.scoping.RulesScopeProvider;
import org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter;
import org.eclipse.smarthome.model.script.jvmmodel.ScriptIdentifiableSimpleNameProvider;
import org.eclipse.smarthome.model.script.scoping.ActionClassLoader;
import org.eclipse.smarthome.model.script.scoping.ActionClasspathBasedTypeScopeProvider;
import org.eclipse.smarthome.model.script.scoping.ActionClasspathTypeProviderFactory;
import org.eclipse.smarthome.model.script.scoping.StateAndCommandProvider;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.generator.IGenerator.NullGenerator;
import org.eclipse.xtext.scoping.IScopeProvider;
import org.eclipse.xtext.xbase.featurecalls.IdentifiableSimpleNameProvider;
import org.eclipse.xtext.xbase.interpreter.IExpressionInterpreter;
import org.eclipse.xtext.xbase.scoping.batch.FeatureScopes;
import org.eclipse.xtext.xbase.scoping.batch.ImplicitlyImportedTypes;
@ -34,25 +28,14 @@ import org.eclipse.xtext.xbase.scoping.batch.ImplicitlyImportedTypes;
@SuppressWarnings("restriction")
public class RulesRuntimeModule extends org.eclipse.smarthome.model.rule.AbstractRulesRuntimeModule {
public Class<? extends IdentifiableSimpleNameProvider> bindIdentifiableSimpleNameProvider() {
return ScriptIdentifiableSimpleNameProvider.class;
}
public Class<? extends ImplicitlyImportedTypes> bindImplicitlyImportedTypes() {
return RulesImplicitlyImportedTypes.class;
}
public Class<StateAndCommandProvider> bindStateAndCommandProvider() {
return StateAndCommandProvider.class;
}
@Override
public Class<? extends IScopeProvider> bindIScopeProvider() {
return RulesScopeProvider.class;
}
/* we need this so that our pluggable actions can be resolved at design time */
@Override
public Class<? extends org.eclipse.xtext.common.types.access.IJvmTypeProvider.Factory> bindIJvmTypeProvider$Factory() {
@ -71,10 +54,6 @@ public class RulesRuntimeModule extends org.eclipse.smarthome.model.rule.Abstrac
return new ActionClassLoader(getClass().getClassLoader());
}
public Class<? extends FeatureScopes> bindFeatureScopes() {
return RulesFeatureScopes.class;
}
@Override
public Class<? extends IGenerator> bindIGenerator() {
return NullGenerator.class;

Просмотреть файл

@ -57,7 +57,8 @@ class RulesJvmModelInferrer extends ScriptJvmModelInferrer {
def dispatch void infer(RuleModel ruleModel, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(ruleModel.toClass("test.TestClass")).initializeLater [
val className = ruleModel.eResource.URI.lastSegment.split("\\.").head.toFirstUpper + "Rules"
acceptor.accept(ruleModel.toClass(className)).initializeLater [
members += ruleModel.variables.filter(XVariableDeclaration).map[
toField(name, type.cloneWithProxies) => [
static = true

Просмотреть файл

@ -1,25 +0,0 @@
/**
* Copyright (c) 2014 openHAB UG (haftungsbeschränkt) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.model.rule.scoping;
import org.eclipse.smarthome.model.script.scoping.ScriptExtensionClassNameProvider;
import com.google.inject.Singleton;
/**
* This class registers all statically available functions as well as the
* extensions for specific jvm types, which should only be available in rules,
* but not in scripts
*
* @author Kai Kreuzer - Initial contribution and API
*
*/
@Singleton
public class RuleExtensionClassNameProvider extends ScriptExtensionClassNameProvider {
}

Просмотреть файл

@ -1,123 +0,0 @@
package org.eclipse.smarthome.model.rule.scoping;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.model.rule.internal.engine.RuleContextHelper;
import org.eclipse.smarthome.model.rule.rules.ChangedEventTrigger;
import org.eclipse.smarthome.model.rule.rules.CommandEventTrigger;
import org.eclipse.smarthome.model.rule.rules.EventTrigger;
import org.eclipse.smarthome.model.rule.rules.Rule;
import org.eclipse.smarthome.model.rule.rules.RuleModel;
import org.eclipse.smarthome.model.script.scoping.ScriptFeatureScopes;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.MapBasedScope;
import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.XVariableDeclaration;
import org.eclipse.xtext.xbase.XbaseFactory;
import org.eclipse.xtext.xbase.scoping.batch.IFeatureScopeSession;
import org.eclipse.xtext.xbase.scoping.featurecalls.LocalVarDescription;
import org.eclipse.xtext.xbase.typesystem.IResolvedTypes;
import com.google.inject.Inject;
public class RulesFeatureScopes extends ScriptFeatureScopes {
//
// @Inject
// private TypeReferences typeReferences;
//
//
// @Override
// public IScope createSimpleFeatureCallScope(EObject context,
// EReference reference, IFeatureScopeSession session,
// IResolvedTypes resolvedTypes) {
// IScope parent = super.createSimpleFeatureCallScope(context, reference, session,
// resolvedTypes);
// Rule rule = EcoreUtil2.getContainerOfType(context,Rule.class);
// if(rule != null) {
//
// List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
// // descriptions.addAll(createVarFeatures(rule.eResource()));
// descriptions.addAll(createTriggerSpecificVars(rule));
// return MapBasedScope.createScope(parent, descriptions);
// } else {
// return parent;
// }
//
// }
//
// private Collection<? extends IEObjectDescription> createVarFeatures(Resource resource) {
// List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
//
// if(resource.getContents().size()>0 && resource.getContents().get(0) instanceof RuleModel) {
// RuleModel ruleModel = (RuleModel) resource.getContents().get(0);
// for(XExpression expr : ruleModel.getVariables()) {
// if (expr instanceof XVariableDeclaration) {
// XVariableDeclaration var = (XVariableDeclaration) expr;
// if(var.getName()!=null && var.getType()!=null) {
// descriptions.add(new LocalVarDescription(QualifiedName.create(var.getName()), var));
// }
// }
// }
// }
//
// return descriptions;
// }
//
// private Collection<? extends IEObjectDescription> createTriggerSpecificVars(Rule rule) {
// List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
// Resource varResource = new XtextResource(URI.createURI("event://specific.vars"));
// if(containsCommandTrigger(rule)) {
// JvmTypeReference commandTypeRef = typeReferences.getTypeForName(Command.class, rule);
// XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
// varDecl.setName(RuleContextHelper.VAR_RECEIVED_COMMAND);
// varDecl.setType(commandTypeRef);
// varDecl.setWriteable(false);
// varResource.getContents().add(varDecl);
// descriptions.add(new LocalVarDescription(QualifiedName.create(varDecl.getName()), varDecl));
// }
// if(containsStateChangeTrigger(rule)) {
// JvmTypeReference stateTypeRef = typeReferences.getTypeForName(State.class, rule);
// XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
// varDecl.setName(RuleContextHelper.VAR_PREVIOUS_STATE);
// varDecl.setType(stateTypeRef);
// varDecl.setWriteable(false);
// varResource.getContents().add(varDecl);
// descriptions.add(new LocalVarDescription(QualifiedName.create(varDecl.getName()), varDecl));
// }
// return descriptions;
// }
//
// private boolean containsCommandTrigger(Rule rule) {
// for(EventTrigger trigger : rule.getEventtrigger()) {
// if(trigger instanceof CommandEventTrigger) {
// return true;
// }
// }
// return false;
// }
//
// private boolean containsStateChangeTrigger(Rule rule) {
// for(EventTrigger trigger : rule.getEventtrigger()) {
// if(trigger instanceof ChangedEventTrigger) {
// return true;
// }
// }
// return false;
// }
//
}

Просмотреть файл

@ -1,129 +0,0 @@
/**
* Copyright (c) 2014 openHAB UG (haftungsbeschr??nkt) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
/*
* generated by Xtext
*/
package org.eclipse.smarthome.model.rule.scoping;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.State;
import org.eclipse.smarthome.model.rule.internal.engine.RuleContextHelper;
import org.eclipse.smarthome.model.script.scoping.ScriptScopeProvider;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.MapBasedScope;
import org.eclipse.xtext.xbase.XExpression;
import org.eclipse.xtext.xbase.XVariableDeclaration;
import org.eclipse.xtext.xbase.XbaseFactory;
import org.eclipse.xtext.xbase.scoping.LocalVariableScopeContext;
import org.eclipse.xtext.xbase.scoping.featurecalls.LocalVarDescription;
import org.eclipse.smarthome.model.rule.rules.ChangedEventTrigger;
import org.eclipse.smarthome.model.rule.rules.CommandEventTrigger;
import org.eclipse.smarthome.model.rule.rules.EventTrigger;
import org.eclipse.smarthome.model.rule.rules.Rule;
import org.eclipse.smarthome.model.rule.rules.RuleModel;
import com.google.inject.Inject;
/**
* This scope provider adds all things to the scope which are specific to rules.
*
* @author Kai Kreuzer - Initial contribution and API
*
*/
@SuppressWarnings("restriction")
public class RulesScopeProvider extends ScriptScopeProvider {
//
// @Inject
// private TypeReferences typeReferences;
//
// @Override
// protected IScope createLocalVarScope(IScope parentScope,
// LocalVariableScopeContext scopeContext) {
// if(scopeContext.getContext() instanceof Rule) {
// IScope parent = super.createLocalVarScope(parentScope, scopeContext);
// List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
// descriptions.addAll(createVarFeatures(scopeContext.getContext().eResource()));
// descriptions.addAll(createTriggerSpecificVars((Rule) scopeContext.getContext()));
// return MapBasedScope.createScope(parent, descriptions);
// } else {
// return super.createLocalVarScope(parentScope, scopeContext);
// }
// }
//
// private Collection<? extends IEObjectDescription> createVarFeatures(Resource resource) {
// List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
//
// if(resource.getContents().size()>0 && resource.getContents().get(0) instanceof RuleModel) {
// RuleModel ruleModel = (RuleModel) resource.getContents().get(0);
// for(XExpression expr : ruleModel.getVariables()) {
// if (expr instanceof XVariableDeclaration) {
// XVariableDeclaration var = (XVariableDeclaration) expr;
// if(var.getName()!=null && var.getType()!=null) {
// descriptions.add(createLocalVarDescription(var));
// }
// }
// }
// }
//
// return descriptions;
// }
//
// private Collection<? extends IEObjectDescription> createTriggerSpecificVars(Rule rule) {
// List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
// Resource varResource = new XtextResource(URI.createURI("event://specific.vars"));
// if(containsCommandTrigger(rule)) {
// JvmTypeReference commandTypeRef = typeReferences.getTypeForName(Command.class, rule);
// XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
// varDecl.setName(RuleContextHelper.VAR_RECEIVED_COMMAND);
// varDecl.setType(commandTypeRef);
// varDecl.setWriteable(false);
// varResource.getContents().add(varDecl);
// descriptions.add(new LocalVarDescription(QualifiedName.create(varDecl.getName()), varDecl));
// }
// if(containsStateChangeTrigger(rule)) {
// JvmTypeReference stateTypeRef = typeReferences.getTypeForName(State.class, rule);
// XVariableDeclaration varDecl = XbaseFactory.eINSTANCE.createXVariableDeclaration();
// varDecl.setName(RuleContextHelper.VAR_PREVIOUS_STATE);
// varDecl.setType(stateTypeRef);
// varDecl.setWriteable(false);
// varResource.getContents().add(varDecl);
// descriptions.add(new LocalVarDescription(QualifiedName.create(varDecl.getName()), varDecl));
// }
// return descriptions;
// }
//
// private boolean containsCommandTrigger(Rule rule) {
// for(EventTrigger trigger : rule.getEventtrigger()) {
// if(trigger instanceof CommandEventTrigger) {
// return true;
// }
// }
// return false;
// }
//
// private boolean containsStateChangeTrigger(Rule rule) {
// for(EventTrigger trigger : rule.getEventtrigger()) {
// if(trigger instanceof ChangedEventTrigger) {
// return true;
// }
// }
// return false;
// }
}

Просмотреть файл

@ -10,10 +10,10 @@
*/
package org.eclipse.smarthome.model.script.ui;
import org.eclipse.smarthome.model.script.scoping.ActionClasspathBasedTypeScopeProvider;
import org.eclipse.smarthome.model.script.scoping.ActionClasspathTypeProviderFactory;
import org.eclipse.smarthome.model.script.ui.contentassist.ActionEObjectHoverProvider;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.xtext.common.types.xtext.ClasspathBasedTypeScopeProvider;
import org.eclipse.xtext.ui.editor.hover.IEObjectHoverProvider;
/**
@ -25,13 +25,12 @@ public class ScriptUiModule extends org.eclipse.smarthome.model.script.ui.Abstra
super(plugin);
}
@Override
public Class<? extends org.eclipse.xtext.common.types.access.IJvmTypeProvider.Factory> bindIJvmTypeProvider$Factory() {
return ActionClasspathTypeProviderFactory.class;
}
public Class<? extends org.eclipse.xtext.common.types.xtext.AbstractTypeScopeProvider> bindAbstractTypeScopeProvider() {
return ClasspathBasedTypeScopeProvider.class;
return ActionClasspathBasedTypeScopeProvider.class;
}
public Class<? extends IEObjectHoverProvider> bindIEObjectHoverProvider() {

Просмотреть файл

@ -13,19 +13,13 @@ package org.eclipse.smarthome.model.script;
import org.eclipse.smarthome.core.scriptengine.Script;
import org.eclipse.smarthome.model.script.internal.engine.ScriptImpl;
import org.eclipse.smarthome.model.script.interpreter.ScriptInterpreter;
import org.eclipse.smarthome.model.script.jvmmodel.ScriptIdentifiableSimpleNameProvider;
import org.eclipse.smarthome.model.script.scoping.ActionClassLoader;
import org.eclipse.smarthome.model.script.scoping.ActionClasspathBasedTypeScopeProvider;
import org.eclipse.smarthome.model.script.scoping.ActionClasspathTypeProviderFactory;
import org.eclipse.smarthome.model.script.scoping.ScriptFeatureScopes;
import org.eclipse.smarthome.model.script.scoping.ScriptImplicitlyImportedTypes;
import org.eclipse.smarthome.model.script.scoping.ScriptScopeProvider;
import org.eclipse.smarthome.model.script.scoping.StateAndCommandProvider;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.generator.IGenerator.NullGenerator;
import org.eclipse.xtext.xbase.featurecalls.IdentifiableSimpleNameProvider;
import org.eclipse.xtext.xbase.interpreter.IExpressionInterpreter;
import org.eclipse.xtext.xbase.scoping.batch.FeatureScopes;
import org.eclipse.xtext.xbase.scoping.batch.ImplicitlyImportedTypes;
/**
@ -39,10 +33,6 @@ public class ScriptRuntimeModule extends org.eclipse.smarthome.model.script.Abst
return ScriptImplicitlyImportedTypes.class;
}
public Class<? extends IdentifiableSimpleNameProvider> bindIdentifiableSimpleNameProvider() {
return ScriptIdentifiableSimpleNameProvider.class;
}
public Class<? extends Script> bindScript() {
return ScriptImpl.class;
}
@ -51,15 +41,6 @@ public class ScriptRuntimeModule extends org.eclipse.smarthome.model.script.Abst
return ScriptInterpreter.class;
}
public Class<StateAndCommandProvider> bindStateAndCommandProvider() {
return StateAndCommandProvider.class;
}
@Override
public Class<? extends org.eclipse.xtext.scoping.IScopeProvider> bindIScopeProvider() {
return ScriptScopeProvider.class;
}
/* we need this so that our pluggable actions can be resolved at design time */
@Override
public Class<? extends org.eclipse.xtext.common.types.access.IJvmTypeProvider.Factory> bindIJvmTypeProvider$Factory() {
@ -78,13 +59,9 @@ public class ScriptRuntimeModule extends org.eclipse.smarthome.model.script.Abst
return new ActionClassLoader(getClass().getClassLoader());
}
public Class<? extends FeatureScopes> bindFeatureScopes() {
return ScriptFeatureScopes.class;
}
@Override
public Class<? extends IGenerator> bindIGenerator() {
return NullGenerator.class;
}
}

Просмотреть файл

@ -17,6 +17,13 @@ import org.eclipse.smarthome.model.script.scoping.StateAndCommandProvider
import org.eclipse.xtext.common.types.JvmField
import org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations
import org.eclipse.xtext.xbase.XAssignment
import org.eclipse.xtext.xbase.interpreter.IEvaluationContext
import org.eclipse.xtext.util.CancelIndicator
import org.eclipse.xtext.xbase.interpreter.impl.EvaluationException
import org.eclipse.xtext.naming.QualifiedName
import org.eclipse.xtext.xbase.XAbstractFeatureCall
import org.eclipse.xtext.xbase.XVariableDeclaration
/**
* The script interpreter handles the openHAB specific script components, which are not known
@ -38,20 +45,26 @@ public class ScriptInterpreter extends XbaseInterpreter {
@Inject
extension IJvmModelAssociations
override protected Object featureCallField(JvmField jvmField, Object receiver) {
override protected _invokeFeature(JvmField jvmField, XAbstractFeatureCall featureCall, Object receiver, IEvaluationContext context, CancelIndicator indicator) {
// Check if the JvmField is inferred
val sourceElement = jvmField.sourceElements.head
if (sourceElement != null) {
// Looks like we have an item field
for(Type type : stateAndCommandProvider.getAllTypes()) {
if (type.toString == jvmField.simpleName) {
return type
switch sourceElement {
XVariableDeclaration : return context.getValue(QualifiedName.create(jvmField.simpleName))
default: {
// Looks like we have an item field
for(Type type : stateAndCommandProvider.getAllTypes()) {
if (type.toString == jvmField.simpleName) {
return type
}
}
return getItem(jvmField.simpleName)
}
}
return getItem(jvmField.simpleName)
} else {
super.featureCallField(jvmField, receiver)
}
super._invokeFeature(jvmField, featureCall, receiver, context, indicator)
}
}
@ -73,4 +86,16 @@ public class ScriptInterpreter extends XbaseInterpreter {
return super.eq(a, b);
}
}
override protected _assigneValueTo(JvmField jvmField, XAssignment assignment, Object value, IEvaluationContext context, CancelIndicator indicator) {
// Check if the JvmField is inferred
val sourceElement = jvmField.sourceElements.head
if (sourceElement != null) {
context.assignValue(QualifiedName.create(jvmField.simpleName), value)
value
} else {
super._assigneValueTo(jvmField, assignment, value, context, indicator)
}
}
}

Просмотреть файл

@ -1,16 +0,0 @@
package org.eclipse.smarthome.model.script.jvmmodel
import org.eclipse.xtext.xbase.featurecalls.IdentifiableSimpleNameProvider
import org.eclipse.xtext.common.types.JvmType
import org.eclipse.xtext.common.types.JvmIdentifiableElement
class ScriptIdentifiableSimpleNameProvider extends IdentifiableSimpleNameProvider {
def dispatch getSimpleName(JvmType element) {
return "this";
}
def dispatch getSimpleName(JvmIdentifiableElement element) {
return super.getSimpleName(element);
}
}

Просмотреть файл

@ -1,9 +1,18 @@
package org.eclipse.smarthome.model.script.jvmmodel
import com.google.inject.Inject
import java.util.Set
import org.eclipse.smarthome.core.types.Command
import org.eclipse.smarthome.core.types.State
import org.eclipse.smarthome.model.script.engine.ItemRegistryProvider
import org.eclipse.smarthome.model.script.scoping.StateAndCommandProvider
import org.eclipse.smarthome.model.script.script.Script
import org.eclipse.xtext.naming.IQualifiedNameProvider
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
import org.slf4j.Logger
import org.slf4j.LoggerFactory
/**
* <p>Infers a JVM model from the source model.</p>
@ -13,11 +22,20 @@ import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder
*/
class ScriptJvmModelInferrer extends AbstractModelInferrer {
static private final Logger logger = LoggerFactory.getLogger(ScriptJvmModelInferrer)
/**
* conveninence API to build and initialize JvmTypes and their members.
*/
@Inject extension JvmTypesBuilder
@Inject extension IQualifiedNameProvider
@Inject extension IQualifiedNameProvider
@Inject
ItemRegistryProvider itemRegistryProvider
@Inject
StateAndCommandProvider stateAndCommandProvider
/**
* Is called for each instance of the first argument's type contained in a resource.
@ -28,6 +46,41 @@ class ScriptJvmModelInferrer extends AbstractModelInferrer {
* @param isPreLinkingPhase - whether the method is called in a pre linking phase, i.e. when the global index isn't fully updated. You
* must not rely on linking using the index if iPrelinkingPhase is <code>true</code>
*/
// def dispatch infer(DecimalLiteral literal, IAcceptor<JvmDeclaredType> acceptor, boolean prelinkingPhase) {
// }
def dispatch void infer(Script script, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
val className = script.eResource.URI.lastSegment.split("\\.").head.toFirstUpper + "Script"
acceptor.accept(script.toClass(className)).initializeLater [
val Set<String> fieldNames = newHashSet()
val types = stateAndCommandProvider.allTypes
types.forEach [ type |
val name = type.toString
if (fieldNames.add(name)) {
members += script.toField(name, script.newTypeRef(type.class)) [
static = true
]
} else {
logger.warn("Duplicate field: '{}'. Ignoring '{}'.", name, type.class.name)
}
]
val itemRegistry = itemRegistryProvider.get
itemRegistry.items.forEach[ item |
val name = item.name
if (fieldNames.add(name)) {
members += script.toField(item.name, script.newTypeRef(item.class)) [
static = true
]
} else {
logger.warn("Duplicate field: '{}'. Ignoring '{}'.", item.name, item.class.name)
}
]
members += script.toMethod("_script", null) [
static = true
body = script
]
]
}
}

Просмотреть файл

@ -7,6 +7,9 @@
*/
package org.eclipse.smarthome.model.script.scoping;
import java.net.MalformedURLException;
import java.net.URL;
import org.eclipse.smarthome.core.scriptengine.action.ActionService;
import org.eclipse.smarthome.model.script.internal.ScriptActivator;
@ -42,4 +45,19 @@ final public class ActionClassLoader extends ClassLoader {
}
throw new ClassNotFoundException();
}
@Override
protected URL findResource(String name) {
Object[] services = ScriptActivator.actionServiceTracker.getServices();
if(services!=null) {
for(Object service : services) {
ActionService actionService = (ActionService) service;
URL url = actionService.getActionClass().getClassLoader().getResource(name);
if (url != null) {
return url;
}
}
}
return null;
}
}

Просмотреть файл

@ -1,99 +0,0 @@
/**
* Copyright (c) 2014 openHAB UG (haftungsbeschränkt) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.model.script.scoping;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.net.URLEncoder;
import java.util.Collection;
import org.apache.commons.lang.StringUtils;
import org.eclipse.smarthome.core.items.Item;
import org.eclipse.smarthome.core.persistence.extensions.PersistenceExtensions;
import org.eclipse.smarthome.core.scriptengine.action.ActionService;
import org.eclipse.smarthome.core.types.Type;
import org.eclipse.smarthome.model.script.actions.BusEvent;
import org.eclipse.smarthome.model.script.actions.LogAction;
import org.eclipse.smarthome.model.script.actions.ScriptExecution;
import org.eclipse.smarthome.model.script.internal.ScriptActivator;
import org.eclipse.smarthome.model.script.lib.NumberExtensions;
import org.eclipse.xtext.xbase.scoping.featurecalls.StaticImplicitMethodsFeatureForTypeProvider.ExtensionClassNameProvider;
import org.joda.time.DateMidnight;
import org.joda.time.DateTime;
import com.google.common.collect.Multimap;
import com.google.inject.Singleton;
/**
* This class registers all statically available functions as well as the
* extensions for specific jvm types.
*
* @author Kai Kreuzer - Initial contribution and API
*
*/
@SuppressWarnings("restriction")
@Singleton
public class ScriptExtensionClassNameProvider extends ExtensionClassNameProvider {
private int trackingCount = -1;
@Override
protected Collection<String> getLiteralClassNames() {
int currentTrackingCount = ScriptActivator.actionServiceTracker.getTrackingCount();
// if something has changed about the tracked services, recompute the list
if(trackingCount != currentTrackingCount) {
trackingCount = currentTrackingCount;
return computeLiteralClassNames();
} else {
return super.getLiteralClassNames();
}
}
@Override
protected Collection<String> computeLiteralClassNames() {
Collection<String> extensions = super.computeLiteralClassNames();
// add all actions that are contributed as OSGi services
Object[] services = ScriptActivator.actionServiceTracker.getServices();
if(services!=null) {
for(Object service : services) {
ActionService actionService = (ActionService) service;
extensions.add(actionService.getActionClassName());
}
}
extensions.add(BusEvent.class.getCanonicalName());
extensions.add(ScriptExecution.class.getCanonicalName());
extensions.add(LogAction.class.getCanonicalName());
// jodatime static functions
extensions.add(DateTime.class.getCanonicalName());
extensions.add(DateMidnight.class.getCanonicalName());
return extensions;
}
@Override
protected Multimap<Class<?>, Class<?>> simpleComputeExtensionClasses() {
Multimap<Class<?>, Class<?>> result = super.simpleComputeExtensionClasses();
result.removeAll(Comparable.class);
result.removeAll(Double.class);
result.removeAll(Integer.class);
result.removeAll(BigInteger.class);
result.removeAll(BigDecimal.class);
result.removeAll(double.class);
result.put(Number.class, NumberExtensions.class);
result.put(Type.class, NumberExtensions.class);
result.put(Comparable.class, NumberExtensions.class);
result.put(String.class, StringUtils.class);
result.put(String.class, URLEncoder.class);
result.put(Item.class, PersistenceExtensions.class);
result.put(Item.class, BusEvent.class);
return result;
}
}

Просмотреть файл

@ -1,72 +0,0 @@
package org.eclipse.smarthome.model.script.scoping;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.smarthome.core.items.Item;
import org.eclipse.smarthome.core.items.ItemRegistry;
import org.eclipse.smarthome.core.types.Type;
import org.eclipse.smarthome.model.script.engine.ItemRegistryProvider;
import org.eclipse.xtext.common.types.access.IJvmTypeProvider;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.MapBasedScope;
import org.eclipse.xtext.xbase.scoping.batch.FeatureScopes;
import org.eclipse.xtext.xbase.scoping.batch.IFeatureScopeSession;
import org.eclipse.xtext.xbase.typesystem.IResolvedTypes;
import com.google.inject.Inject;
public class ScriptFeatureScopes extends FeatureScopes {
@Inject
private IJvmTypeProvider.Factory typeProviderFactory;
@Inject
private ItemRegistryProvider itemRegistryProvider;
@Inject
private StateAndCommandProvider stateAndCommandProvider;
// @Override
// public IScope createSimpleFeatureCallScope(EObject context,
// EReference reference, IFeatureScopeSession session,
// IResolvedTypes resolvedTypes) {
// IScope parent = super.createSimpleFeatureCallScope(context, reference, session,
// resolvedTypes);
// List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
// descriptions.addAll(createItemFeatures(context.eResource().getResourceSet()));
// descriptions.addAll(createTypeFeatures(context.eResource().getResourceSet()));
//
// return MapBasedScope.createScope(parent, descriptions);
// }
//
// private Collection<? extends IEObjectDescription> createTypeFeatures(ResourceSet rs) {
//
// List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
// IJvmTypeProvider provider = typeProviderFactory.findOrCreateTypeProvider(rs);
// for(Type type : stateAndCommandProvider.getAllTypes()) {
// descriptions.add(EObjectDescription.create(type.toString(), provider.findTypeByName(type.getClass().getCanonicalName())));
// }
//
// return descriptions;
// }
//
// private List<IEObjectDescription> createItemFeatures(ResourceSet rs) {
// IJvmTypeProvider provider = typeProviderFactory.findOrCreateTypeProvider(rs);
// List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
// ItemRegistry itemRegistry = itemRegistryProvider.get();
// if(itemRegistry!=null) {
// for(Item item : itemRegistry.getItems()) {
// descriptions.add(EObjectDescription.create(item.getName(), provider.findTypeByName(item.getClass().getCanonicalName())));
// }
// }
// return descriptions;
// }
}

Просмотреть файл

@ -41,10 +41,7 @@ import com.google.inject.Singleton;
@Singleton
public class ScriptImplicitlyImportedTypes extends ImplicitlyImportedTypes {
@Inject
private TypeReferences typeReferences;
private Collection<String> staticImportClassNames = null;
private List<Class<?>> actionClasses = null;
private int trackingCount = -1;
@ -65,24 +62,24 @@ public class ScriptImplicitlyImportedTypes extends ImplicitlyImportedTypes {
return result;
}
@Override
public List<JvmType> getStaticImportClasses(Resource context) {
List<JvmType> result = super.getStaticImportClasses(context);
Collection<String> classNames = getStaticImportClassNames();
result.addAll(getClassNameTypes(classNames, context));
return result;
}
protected Collection<JvmType> getClassNameTypes(Collection<String> classNames, Resource context) {
List<JvmType> result = Lists.newArrayListWithCapacity(classNames.size());
for(String className: classNames) {
JvmType type = typeReferences.findDeclaredType(className, context);
if (type != null)
result.add(type);
}
return result;
}
// @Override
// public List<JvmType> getStaticImportClasses(Resource context) {
// List<JvmType> result = super.getStaticImportClasses(context);
//
// List<Class<?>> actionClasses = getActionClasses();
// result.addAll(getTypes(actionClasses, context));
// return result;
// }
//
// protected Collection<JvmType> getClassNameTypes(Collection<String> classNames, Resource context) {
// List<JvmType> result = Lists.newArrayListWithCapacity(classNames.size());
// for(String className: classNames) {
// JvmType type = typeReferences.findDeclaredType(className, context);
// if (type != null)
// result.add(type);
// }
// return result;
// }
@Override
protected List<Class<?>> getStaticImportClasses() {
@ -94,27 +91,29 @@ public class ScriptImplicitlyImportedTypes extends ImplicitlyImportedTypes {
// jodatime static functions
result.add(DateTime.class);
result.add(DateMidnight.class);
result.addAll(getActionClasses());
return result;
}
protected Collection<String> getStaticImportClassNames() {
protected List<Class<?>> getActionClasses() {
int currentTrackingCount = ScriptActivator.actionServiceTracker.getTrackingCount();
// if something has changed about the tracked services, recompute the list
if(trackingCount != currentTrackingCount) {
trackingCount = currentTrackingCount;
Collection<String> extensions = new ArrayList<String>();
List<Class<?>> privateActionClasses = new ArrayList<Class<?>>();
// add all actions that are contributed as OSGi services
Object[] services = ScriptActivator.actionServiceTracker.getServices();
if(services!=null) {
for(Object service : services) {
ActionService actionService = (ActionService) service;
extensions.add(actionService.getActionClassName());
privateActionClasses.add(actionService.getActionClass());
}
}
staticImportClassNames=extensions;
this.actionClasses=privateActionClasses;
}
return staticImportClassNames;
return this.actionClasses;
}
}

Просмотреть файл

@ -1,62 +0,0 @@
package org.eclipse.smarthome.model.script.scoping;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.smarthome.core.items.Item;
import org.eclipse.smarthome.core.items.ItemRegistry;
import org.eclipse.smarthome.model.script.engine.ItemRegistryProvider;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmIdentifiableElement;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.access.IJvmTypeProvider;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.xbase.scoping.batch.IFeatureNames;
import org.eclipse.xtext.xbase.scoping.batch.IFeatureScopeSession;
import org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver;
import org.eclipse.xtext.xbase.typesystem.internal.ResolvedTypes;
import org.eclipse.xtext.xbase.typesystem.references.ITypeReferenceOwner;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
public class ScriptReentrantTypeResolver extends
LogicalContainerAwareReentrantTypeResolver {
@Inject
private IJvmTypeProvider.Factory typeProviderFactory;
@Inject
private ItemRegistryProvider itemRegistryProvider;
@Override
protected Map<JvmIdentifiableElement, ResolvedTypes> prepare(
ResolvedTypes resolvedTypes,
IFeatureScopeSession featureScopeSession) {
addItems(featureScopeSession, resolvedTypes.getReferenceOwner(), (JvmDeclaredType)getRootJvmType());
return super.prepare(resolvedTypes, featureScopeSession);
}
protected IFeatureScopeSession addItems(IFeatureScopeSession session, ITypeReferenceOwner owner, JvmDeclaredType thisType) {
IFeatureScopeSession childSession = null;
IJvmTypeProvider provider = typeProviderFactory.findOrCreateTypeProvider(thisType.eResource().getResourceSet());
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
ItemRegistry itemRegistry = itemRegistryProvider.get();
if(itemRegistry!=null) {
ImmutableMap.Builder<QualifiedName, JvmIdentifiableElement> builder = ImmutableMap.builder();
for(Item item : itemRegistry.getItems()) {
builder.put(QualifiedName.create(item.getName()), provider.findTypeByName(item.getClass().getCanonicalName()));
}
childSession = session.addLocalElements(builder.build(), owner);
}
childSession = addThisTypeToStaticScope(childSession, thisType);
return childSession;
}
}

Просмотреть файл

@ -1,91 +0,0 @@
/**
* Copyright (c) 2014 openHAB UG (haftungsbeschränkt) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package org.eclipse.smarthome.model.script.scoping;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.smarthome.core.items.Item;
import org.eclipse.smarthome.core.items.ItemRegistry;
import org.eclipse.smarthome.core.types.Type;
import org.eclipse.smarthome.model.script.engine.ItemRegistryProvider;
import org.eclipse.xtext.common.types.TypesFactory;
import org.eclipse.xtext.common.types.access.IJvmTypeProvider;
import org.eclipse.xtext.resource.EObjectDescription;
import org.eclipse.xtext.resource.IEObjectDescription;
import org.eclipse.xtext.scoping.IScope;
import org.eclipse.xtext.scoping.impl.MapBasedScope;
import org.eclipse.xtext.xbase.jvmmodel.IJvmModelAssociations;
import org.eclipse.xtext.xbase.scoping.XbaseScopeProvider;
import com.google.inject.Inject;
/**
* This scope provider adds all items, states and commands to the scope, so that
* these are always available in the scripts.
*
* @author Kai Kreuzer - Initial contribution and API
*
*/
@SuppressWarnings("all")
public class ScriptScopeProvider extends XbaseScopeProvider {
@Inject
private IJvmTypeProvider.Factory typeProviderFactory;
@Inject
private ItemRegistryProvider itemRegistryProvider;
@Inject
private StateAndCommandProvider stateAndCommandProvider;
public ScriptScopeProvider() {
}
@Override
public IScope createSimpleFeatureCallScope(EObject context,
EReference reference, Resource resource,
boolean includeCurrentBlock, int idx) {
IScope parent = super.createSimpleFeatureCallScope(context, reference, resource,
includeCurrentBlock, idx);
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
descriptions.addAll(createItemFeatures(resource.getResourceSet()));
descriptions.addAll(createTypeFeatures(resource.getResourceSet()));
return MapBasedScope.createScope(parent, descriptions);
}
private Collection<? extends IEObjectDescription> createTypeFeatures(ResourceSet rs) {
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
IJvmTypeProvider provider = typeProviderFactory.findOrCreateTypeProvider(rs);
for(Type type : stateAndCommandProvider.getAllTypes()) {
descriptions.add(EObjectDescription.create(type.toString(), provider.findTypeByName(type.getClass().getCanonicalName())));
}
return descriptions;
}
private List<IEObjectDescription> createItemFeatures(ResourceSet rs) {
IJvmTypeProvider provider = typeProviderFactory.findOrCreateTypeProvider(rs);
List<IEObjectDescription> descriptions = new ArrayList<IEObjectDescription>();
ItemRegistry itemRegistry = itemRegistryProvider.get();
if(itemRegistry!=null) {
for(Item item : itemRegistry.getItems()) {
descriptions.add(EObjectDescription.create(item.getName(), provider.findTypeByName(item.getClass().getCanonicalName())));
}
}
return descriptions;
}
}