javafx: initial javascript injection

This commit is contained in:
Anna Kozlova
2013-01-29 12:13:26 +04:00
parent 49b5fa0f1a
commit ba70a9a6ab
5 changed files with 85 additions and 26 deletions
+1
View File
@@ -16,5 +16,6 @@
<psi.referenceContributor implementation="org.jetbrains.plugins.javaFX.fxml.refs.FxmlReferencesContributor"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxEventHandlerReference$JavaFxUnresolvedReferenceHandlerQuickfixProvider"/>
<codeInsight.unresolvedReferenceQuickFixProvider implementation="org.jetbrains.plugins.javaFX.fxml.refs.JavaFxTagNameReference$JavaFxUnresolvedTagRefsProvider"/>
<multiHostInjector implementation="org.jetbrains.plugins.javaFX.fxml.ScriptLanguageInjector"/>
</extensions>
</idea-plugin>
@@ -44,29 +44,6 @@ public class JavaFXNSDescriptor implements XmlNSDescriptor, Validator<XmlDocumen
return null;
}
public static List<String> parseImports(XmlFile file) {
List<String> definedImports = new ArrayList<String>();
XmlDocument document = file.getDocument();
if (document != null) {
XmlProlog prolog = document.getProlog();
final Collection<XmlProcessingInstruction>
instructions = new ArrayList<XmlProcessingInstruction>(PsiTreeUtil.findChildrenOfType(prolog, XmlProcessingInstruction.class));
for (Iterator<XmlProcessingInstruction> iterator = instructions.iterator(); iterator.hasNext(); ) {
final XmlProcessingInstruction instruction = iterator.next();
final ASTNode node = instruction.getNode();
ASTNode xmlNameNode = node.findChildByType(XmlTokenType.XML_NAME);
ASTNode importNode = node.findChildByType(XmlTokenType.XML_TAG_CHARACTERS);
if (xmlNameNode == null || !"import".equals(xmlNameNode.getText()) || importNode == null) {
iterator.remove();
} else {
definedImports.add(importNode.getText());
}
}
}
return definedImports;
}
@NotNull
@Override
public XmlElementDescriptor[] getRootElementsDescriptors(@Nullable XmlDocument document) {
@@ -15,12 +15,18 @@
*/
package org.jetbrains.plugins.javaFX.fxml;
import com.intellij.lang.ASTNode;
import com.intellij.lang.xml.XMLLanguage;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.xml.XmlProcessingInstruction;
import com.intellij.psi.xml.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
/**
* User: anna
@@ -32,4 +38,35 @@ public class JavaFxPsiUtil {
PsiFileFactory.getInstance(project).createFileFromText("a.fxml", XMLLanguage.INSTANCE, importText).getFirstChild();
return PsiTreeUtil.findChildOfType(child, XmlProcessingInstruction.class);
}
public static List<String> parseImports(XmlFile file) {
return parseInstructions(file, "import");
}
public static List<String> parseInjectedLanguages(XmlFile file) {
return parseInstructions(file, "language");
}
private static List<String> parseInstructions(XmlFile file, String instructionName) {
List<String> definedImports = new ArrayList<String>();
XmlDocument document = file.getDocument();
if (document != null) {
XmlProlog prolog = document.getProlog();
final Collection<XmlProcessingInstruction>
instructions = new ArrayList<XmlProcessingInstruction>(PsiTreeUtil.findChildrenOfType(prolog, XmlProcessingInstruction.class));
for (Iterator<XmlProcessingInstruction> iterator = instructions.iterator(); iterator.hasNext(); ) {
final XmlProcessingInstruction instruction = iterator.next();
final ASTNode node = instruction.getNode();
ASTNode xmlNameNode = node.findChildByType(XmlTokenType.XML_NAME);
ASTNode importNode = node.findChildByType(XmlTokenType.XML_TAG_CHARACTERS);
if (xmlNameNode == null || !instructionName.equals(xmlNameNode.getText()) || importNode == null) {
iterator.remove();
} else {
definedImports.add(importNode.getText());
}
}
}
return definedImports;
}
}
@@ -0,0 +1,41 @@
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.patterns.XmlElementPattern;
import com.intellij.patterns.XmlPatterns;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiLanguageInjectionHost;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlText;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public class ScriptLanguageInjector implements MultiHostInjector {
private static final XmlElementPattern.XmlTextPattern SCRIPT_PATTERN = XmlPatterns.xmlText().withParent(
XmlPatterns.xmlTag().withName(FxmlConstants.FX_SCRIPT));
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();
}
}
}
@NotNull
public List<? extends Class<? extends PsiElement>> elementsToInjectIn() {
return Collections.singletonList(XmlText.class);
}
}
@@ -25,8 +25,8 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.javaFX.fxml.FxmlConstants;
import org.jetbrains.plugins.javaFX.fxml.JavaFXNSDescriptor;
import org.jetbrains.plugins.javaFX.fxml.JavaFxCommonClassNames;
import org.jetbrains.plugins.javaFX.fxml.JavaFxPsiUtil;
import java.util.ArrayList;
import java.util.Collections;
@@ -45,7 +45,7 @@ public class JavaFxClassBackedElementDescriptor implements XmlElementDescriptor,
}
public static PsiClass findPsiClass(String name, XmlTag tag) {
return findPsiClass(name, JavaFXNSDescriptor.parseImports((XmlFile)tag.getContainingFile()), tag, tag.getProject());
return findPsiClass(name, JavaFxPsiUtil.parseImports((XmlFile)tag.getContainingFile()), tag, tag.getProject());
}
public JavaFxClassBackedElementDescriptor(String name, PsiClass aClass) {
@@ -161,6 +161,9 @@ public class JavaFxClassBackedElementDescriptor implements XmlElementDescriptor,
}
return null;
}
if (FxmlConstants.FX_DEFAULT_PROPERTIES.contains(name)) {
//return new ;
}
return myPsiClass != null ? new JavaFxPropertyElementDescriptor(myPsiClass, name, false) : null;
}
}