Community
Participate
Working Groups
The following test: import static org.junit.Assert.assertEquals; import org.eclipse.xtext.common.types.JvmType; import org.eclipse.xtext.common.types.JvmTypeReference; import org.eclipse.xtext.common.types.access.IJvmTypeProvider; import org.eclipse.xtext.common.types.util.TypeReferences; import org.eclipse.xtext.naming.IQualifiedNameConverter; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.util.CancelIndicator; import org.eclipse.xtext.xbase.XFeatureCall; import org.eclipse.xtext.xbase.XVariableDeclaration; import org.eclipse.xtext.xbase.XbaseFactory; import org.eclipse.xtext.xbase.XbaseStandaloneSetup; import org.eclipse.xtext.xbase.interpreter.IEvaluationContext; import org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter; import org.junit.Test; import com.google.inject.Injector; import com.google.inject.Provider; @SuppressWarnings("restriction") public class TestBug { @Test public void testName() { XVariableDeclaration variable = XbaseFactory.eINSTANCE.createXVariableDeclaration(); String variableName = "foo"; variable.setName(variableName); Injector injector = new XbaseStandaloneSetup().createInjectorAndDoEMFRegistration(); IJvmTypeProvider typeProvider = injector.getInstance(IJvmTypeProvider.Factory.class).createTypeProvider(); JvmType type = typeProvider.findTypeByName(String.class.getName()); TypeReferences typeReferences = injector.getInstance(TypeReferences.class); JvmTypeReference typeReference = typeReferences.createTypeRef(type); variable.setType(typeReference); // new ResourceImpl().getContents().add(variable); // XXX XFeatureCall expression = XbaseFactory.eINSTANCE.createXFeatureCall(); expression.setFeature(variable); XbaseInterpreter interpreter = injector.getInstance(XbaseInterpreter.class); interpreter.setClassLoader(getClass().getClassLoader()); Provider<IEvaluationContext> contextProvider = injector.getProvider(IEvaluationContext.class); IQualifiedNameConverter nameConverter = injector.getInstance(IQualifiedNameConverter.class); IEvaluationContext evaluationContext = contextProvider.get(); QualifiedName qualifiedName = nameConverter.toQualifiedName(variableName); String expectedValue = "Hello World"; evaluationContext.newValue(qualifiedName, expectedValue); assertEquals(expectedValue, interpreter.evaluate(expression, evaluationContext, CancelIndicator.NullImpl).getResult()); } } Fails with the following exception: java.lang.NullPointerException at org.eclipse.xtext.util.OnChangeEvictingCache.getOrCreate(OnChangeEvictingCache.java:110) at org.eclipse.xtext.util.OnChangeEvictingCache.execWithoutCacheClear(OnChangeEvictingCache.java:124) at org.eclipse.xtext.xbase.typesystem.internal.CachingBatchTypeResolver.doResolveTypes(CachingBatchTypeResolver.java:51) at org.eclipse.xtext.xbase.typesystem.internal.AbstractBatchTypeResolver.resolveTypes(AbstractBatchTypeResolver.java:44) at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.internalEvaluate(XbaseInterpreter.java:203) at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.evaluate(XbaseInterpreter.java:188) at com.tttech.rteverify.safetyruleinstancecollector.placeholdercalculator.TestBug.testName(TestBug.java:54) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) If I uncomment the line marked with XXX, it passes.
Hi Denes, EMF Objects that are not contained in a resource cannot work correctly. Basically the resource and its containing resource set belong to the invariant of EObjects. I'm inclined to close this as invalid, but could you please elaborate on your use case before I do that? Maybe I'm missing something.
Thanks for the reply! My use case is very similar to this minimal test case: programmatically building and interpreting an Xbase expression that references a JvmIdentifiableElement (an EMF-IncQuery pattern variable, precisely). Is there a more suitable way to achieve this than the code above? It would be great if this "invariant" was documented somewhere, or maybe Xtext failed earlier when it does not hold.
(In reply to Dénes Harmath from comment #2) > Thanks for the reply! > My use case is very similar to this minimal test case: programmatically > building and interpreting an Xbase expression that references a > JvmIdentifiableElement (an EMF-IncQuery pattern variable, precisely). Is > there a more suitable way to achieve this than the code above? > It would be great if this "invariant" was documented somewhere, or maybe > Xtext failed earlier when it does not hold. The easiest way would be to parse your expression from text. Otherwise I've serious doubts that it will be straight forward to produce a proper AST for a reasonable complex expression. Besides that, this invariant is more or less imposed by EMF. The resource sets describes the context of all its contained resources and EObjects. They are pretty much useless without that.
Okay, thanks for the information! I'll ask on some forum about the way to parse textual Xbase expressions so that my custom JvmIdentifiableElements (in my case, EMF-IncQuery Variables) are resolved properly.