/* * Copyright 2003-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jetbrains.mps.classloading; import jetbrains.mps.CoreMpsTest; import jetbrains.mps.project.Project; import jetbrains.mps.smodel.Generator; import jetbrains.mps.smodel.Language; import jetbrains.mps.testbench.junit.runners.FromProjectPathProjectStrategy; import jetbrains.mps.tool.environment.Environment; import jetbrains.mps.tool.environment.EnvironmentConfig; import jetbrains.mps.tool.environment.MpsEnvironment; import jetbrains.mps.util.PathManager; import org.junit.After; import org.junit.Before; import org.junit.Test; import static org.junit.Assert.assertTrue; public class ClassLoadingDescriptorChangedTest extends CoreMpsTest { private Project myProject; @Before public void beforeTest() { Environment env = MpsEnvironment.getOrCreate(EnvironmentConfig.defaultConfig()); String homePath = PathManager.getHomePath(); assert homePath != null; // env.openProject doesn't make project, while FromProjectPathProjectStrategy does. // createProject seems to be just a mechanism to employ a strategy, and it's up to strategy to decide whether to open a project or create a new one myProject = env.createProject(new FromProjectPathProjectStrategy(homePath)); } @After public void afterTest() { myProject.dispose(); } /** * We have languages L1 and L2. They have generators G1 and G2, correspondingly. G1 has a dependency on L2 and G2. * The test asserts, that after reloading file descriptor of the language L2 we are still able to get the QueriesGenerated * class from the generators G1 and G2. */ @Test public void testClassLoadingDescriptorChanged() { final Language language1 = getLanguage(myProject, "L1"); assert language1 != null; final Language language2 = getLanguage(myProject, "L2"); assert language2 != null; Generator generator1 = new TakeGenerator(language1).get(); performCheck(generator1); reloadAfterDescriptorChange(language2); generator1 = new TakeGenerator(language1).get(); performCheck(generator1); } private void reloadAfterDescriptorChange(final Language language2) { myProject.getModelAccess().runWriteAction(language2::reloadAfterDescriptorChange); } private void performCheck(Generator generator1) { Class aClass = ClassLoaderManager.getInstance().getClass(generator1, "L1.generator.template.main.QueriesGenerated"); Class aClass2 = ClassLoaderManager.getInstance().getClass(generator1, "L2.generator.template.main.QueriesGenerated"); assertTrue(aClass != null); assertTrue(aClass2 != null); } private class TakeGenerator implements Runnable { private final Language myLanguage; private Generator myGenerator; TakeGenerator(Language language) { myLanguage = language; } @Override public void run() { myGenerator = myLanguage.getGenerators().iterator().next(); } Generator get() { myProject.getModelAccess().runReadAction(this); return myGenerator; } } }