mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
javafx: register page language when fx:script tag is not empty (IDEA-100479)
This commit is contained in:
+12
@@ -18,6 +18,8 @@ package org.jetbrains.plugins.javaFX.fxml;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.application.PluginPathManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
|
||||
import com.intellij.openapi.roots.ContentEntry;
|
||||
import com.intellij.openapi.roots.ModifiableRootModel;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
@@ -33,6 +35,8 @@ public class JavaFXQuickfixTest extends LightCodeInsightFixtureTestCase {
|
||||
public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
|
||||
PsiTestUtil.addLibrary(module, model, "javafx", PluginPathManager.getPluginHomePath("javaFX") + "/testData", "jfxrt.jar");
|
||||
PsiTestUtil.addLibrary(module, model, "groovy", PluginPathManager.getPluginHomePath("groovy") + "/testdata/mockGroovyLib1.8", "groovy-1.8.0-beta-2.jar");
|
||||
final Sdk projectJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
|
||||
PsiTestUtil.addLibrary(module, model, "rt", projectJdk.getHomePath() + "/lib", "rt.jar");
|
||||
super.configureModule(module, model, contentEntry);
|
||||
}
|
||||
};
|
||||
@@ -55,6 +59,14 @@ public class JavaFXQuickfixTest extends LightCodeInsightFixtureTestCase {
|
||||
doTest("Create Field 'btn'", ".java");
|
||||
}
|
||||
|
||||
public void testRegisterPageLanguage() throws Exception {
|
||||
myFixture.configureByFile(getTestName(true) + ".fxml");
|
||||
final IntentionAction intention = myFixture.findSingleIntention("Specify page language");
|
||||
assertNotNull(intention);
|
||||
myFixture.launchAction(intention);
|
||||
myFixture.checkResultByFile(getTestName(true) + ".fxml", getTestName(true) + "_after.fxml", true);
|
||||
}
|
||||
|
||||
public void testWrapWithDefine() throws Exception {
|
||||
final IntentionAction intention =
|
||||
myFixture.getAvailableIntention("Wrap \"lb\" with fx:define", getTestName(true) + ".fxml");
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
|
||||
package org.jetbrains.plugins.javaFX.fxml;
|
||||
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.injection.MultiHostInjector;
|
||||
import com.intellij.lang.injection.MultiHostRegistrar;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.patterns.XmlElementPattern;
|
||||
import com.intellij.patterns.XmlPatterns;
|
||||
import com.intellij.psi.PsiElement;
|
||||
@@ -23,12 +23,17 @@ public class ScriptLanguageInjector implements MultiHostInjector {
|
||||
|
||||
public void getLanguagesToInject(@NotNull final MultiHostRegistrar registrar, @NotNull final PsiElement host) {
|
||||
if (SCRIPT_PATTERN.accepts(host)) {
|
||||
final Language language = Language.findLanguageByID("JavaScript");
|
||||
if (language != null && JavaFxPsiUtil.parseInjectedLanguages((XmlFile)host.getContainingFile()).contains("javascript")) {
|
||||
registrar.startInjecting(language)
|
||||
.addPlace(null, null, (PsiLanguageInjectionHost) host,
|
||||
TextRange.from(0, host.getTextLength() - 1))
|
||||
.doneInjecting();
|
||||
final List<String> registeredLanguages = JavaFxPsiUtil.parseInjectedLanguages((XmlFile)host.getContainingFile());
|
||||
for (Language language : Language.getRegisteredLanguages()) {
|
||||
for (String registeredLanguage : registeredLanguages) {
|
||||
if (StringUtil.equalsIgnoreCase(language.getID(), registeredLanguage)) {
|
||||
registrar.startInjecting(language)
|
||||
.addPlace(null, null, (PsiLanguageInjectionHost) host,
|
||||
TextRange.from(0, host.getTextLength() - 1))
|
||||
.doneInjecting();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+147
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright 2000-2013 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 org.jetbrains.plugins.javaFX.fxml.codeInsight.intentions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.codeInsight.intention.PsiElementBaseIntentionAction;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.OrderEnumerator;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.PsiParserFacade;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlProcessingInstruction;
|
||||
import com.intellij.psi.xml.XmlProlog;
|
||||
import com.intellij.ui.components.JBList;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.lang.UrlClassLoader;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 4/8/13
|
||||
*/
|
||||
public class JavaFxInjectPageLanguageIntention extends PsiElementBaseIntentionAction {
|
||||
public static final Logger LOG = Logger.getInstance("#" + JavaFxInjectPageLanguageIntention.class.getName());
|
||||
|
||||
private static Set<String> getAvailableLanguages(Project project) {
|
||||
final List<ScriptEngineFactory> engineFactories = new ScriptEngineManager(composeUserClassLoader(project)).getEngineFactories();
|
||||
|
||||
if (engineFactories != null) {
|
||||
final Set<String> availableNames = new TreeSet<String>();
|
||||
for (ScriptEngineFactory factory : engineFactories) {
|
||||
final String engineName = (String)factory.getParameter(ScriptEngine.NAME);
|
||||
availableNames.add(engineName);
|
||||
}
|
||||
return availableNames;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static UrlClassLoader composeUserClassLoader(Project project) {
|
||||
final List<URL> urls = new ArrayList<URL>();
|
||||
final List<String> list = OrderEnumerator.orderEntries(project).recursively().runtimeOnly().getPathsList().getPathList();
|
||||
for (String path : list) {
|
||||
try {
|
||||
urls.add(new File(FileUtil.toSystemIndependentName(path)).toURI().toURL());
|
||||
}
|
||||
catch (MalformedURLException e1) {
|
||||
LOG.info(e1);
|
||||
}
|
||||
}
|
||||
|
||||
return new UrlClassLoader(urls, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull final Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
|
||||
if (!CodeInsightUtilBase.preparePsiElementsForWrite(element)) return;
|
||||
final XmlFile containingFile = (XmlFile)element.getContainingFile();
|
||||
|
||||
final Set<String> availableLanguages = getAvailableLanguages(project);
|
||||
if (availableLanguages.size() == 1) {
|
||||
registerPageLanguage(project, containingFile, availableLanguages.iterator().next());
|
||||
} else {
|
||||
final JBList list = new JBList(availableLanguages);
|
||||
JBPopupFactory.getInstance().createListPopupBuilder(list)
|
||||
.setItemChoosenCallback(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
registerPageLanguage(project, containingFile, (String)list.getSelectedValue());
|
||||
}
|
||||
}).createPopup().showInBestPositionFor(editor);
|
||||
}
|
||||
}
|
||||
|
||||
private void registerPageLanguage(final Project project, final XmlFile containingFile, final String languageName) {
|
||||
new WriteCommandAction.Simple(project, getFamilyName()) {
|
||||
@Override
|
||||
protected void run() {
|
||||
final PsiFileFactory factory = PsiFileFactory.getInstance(project);
|
||||
final XmlFile dummyFile = (XmlFile)factory.createFileFromText("_Dummy_.fxml", StdFileTypes.XML,
|
||||
"<?language " + languageName + "?>");
|
||||
final XmlDocument document = dummyFile.getDocument();
|
||||
if (document != null) {
|
||||
final XmlProlog prolog = document.getProlog();
|
||||
final Collection<XmlProcessingInstruction> instructions = PsiTreeUtil.findChildrenOfType(prolog, XmlProcessingInstruction.class);
|
||||
LOG.assertTrue(instructions.size() == 1);
|
||||
final XmlDocument xmlDocument = containingFile.getDocument();
|
||||
if (xmlDocument != null) {
|
||||
final XmlProlog xmlProlog = xmlDocument.getProlog();
|
||||
if (xmlProlog != null) {
|
||||
final PsiElement element = xmlProlog.addBefore(instructions.iterator().next(), xmlProlog.getFirstChild());
|
||||
xmlProlog.addAfter(PsiParserFacade.SERVICE.getInstance(project).createWhiteSpaceFromText("\n\n"), element);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @NotNull PsiElement element) {
|
||||
setText(getFamilyName());
|
||||
return element.isValid();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Specify page language";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ package org.jetbrains.plugins.javaFX.fxml.refs;
|
||||
|
||||
import com.intellij.codeInsight.intention.AddAnnotationFix;
|
||||
import com.intellij.codeInsight.intentions.XmlChooseColorIntentionAction;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.annotation.Annotation;
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
@@ -28,9 +29,7 @@ import com.intellij.openapi.editor.markup.GutterIconRenderer;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.psi.xml.*;
|
||||
import com.intellij.ui.ColorUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.ui.ColorIcon;
|
||||
@@ -40,11 +39,13 @@ import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxFileTypeFactory;
|
||||
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
|
||||
import org.jetbrains.plugins.javaFX.fxml.codeInsight.intentions.JavaFxInjectPageLanguageIntention;
|
||||
import org.jetbrains.plugins.javaFX.fxml.codeInsight.intentions.JavaFxWrapWithDefineIntention;
|
||||
import org.jetbrains.plugins.javaFX.fxml.descriptors.JavaFxDefaultPropertyElementDescriptor;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
@@ -100,6 +101,20 @@ public class JavaFxAnnotator implements Annotator {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (element instanceof XmlTag) {
|
||||
if (FxmlConstants.FX_SCRIPT.equals(((XmlTag)element).getName())) {
|
||||
final XmlTagValue tagValue = ((XmlTag)element).getValue();
|
||||
if (!StringUtil.isEmptyOrSpaces(tagValue.getText())) {
|
||||
final List<String> langs = JavaFxPsiUtil.parseInjectedLanguages((XmlFile)element.getContainingFile());
|
||||
if (langs.isEmpty()) {
|
||||
final ASTNode openTag = element.getNode().findChildByType(XmlTokenType.XML_NAME);
|
||||
final Annotation annotation =
|
||||
holder.createErrorAnnotation(openTag != null ? openTag.getPsi() : element, "Page language not specified.");
|
||||
annotation.registerFix(new JavaFxInjectPageLanguageIntention());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void attachColorIcon(final PsiElement element, AnnotationHolder holder, String attributeValueText) {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<GridPane xmlns:fx="http://javafx.com/fxml">
|
||||
<fx:scr<caret>ipt>
|
||||
var foo;
|
||||
</fx:script>
|
||||
</GridPane>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?language javascript?>
|
||||
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<GridPane xmlns:fx="http://javafx.com/fxml">
|
||||
<fx:script>
|
||||
var foo;
|
||||
</fx:script>
|
||||
</GridPane>
|
||||
Reference in New Issue
Block a user