diff --git a/build.gradle b/build.gradle index 6508e95d..78b7e140 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,7 @@ def pluginsForIdeaVersion = [ // Branch Number: 172 'com.jetbrains.php:172.3317.83', 'yaml', + 'IntelliLang', // test dependencies 'CSS', @@ -56,7 +57,7 @@ def pluginsForIdeaVersion = [ 'properties', // DEV dependencies: UNCOMMENT the following lines during development // to install additional plugins for development - // 'PsiViewer:3.28.93' + 'PsiViewer:3.28.93' ], '2017.1.3': [ // Branch Number: 171 diff --git a/src/main/grammars/FusionLexer.flex b/src/main/grammars/FusionLexer.flex index 09910744..0dd5c9ac 100644 --- a/src/main/grammars/FusionLexer.flex +++ b/src/main/grammars/FusionLexer.flex @@ -209,6 +209,7 @@ IF_SEPARATOR = {COLON} {LEFT_BRACE} { yybegin(YYINITIAL); return FusionTypes.LEFT_BRACE; } } + { {OBJECT_TYPE_PART} { return FusionTypes.UNQUALIFIED_TYPE; } {OBJECT_TYPE_PART}/{COLON} { yybegin(OBJECT_TYPE_IN_PROTOTYPE_FOUND); return FusionTypes.OBJECT_TYPE_NAMESPACE; } diff --git a/src/main/grammars/FusionParser.bnf b/src/main/grammars/FusionParser.bnf index 34714617..d5695926 100644 --- a/src/main/grammars/FusionParser.bnf +++ b/src/main/grammars/FusionParser.bnf @@ -76,13 +76,17 @@ value_dsl ::= DSL_IDENTIFIER BACKTICK value_dsl_content BACKTICK { pin=1 } -value_dsl_content ::= (VALUE_STRING | CRLF | ESCAPED_BACKTICK)* +value_dsl_content ::= (VALUE_STRING | CRLF | ESCAPED_BACKTICK)* { + implements = [ "com.intellij.psi.PsiLanguageInjectionHost" ] + mixin = "de.vette.idea.neos.lang.fusion.psi.impl.ext.FusionValueDslContentImplMixin" +} value_string_line ::= VALUE_STRING_QUOTE value_string_line_content VALUE_STRING_QUOTE { pin=1 implements = [ "de.vette.idea.neos.lang.fusion.psi.FusionReferenceElement" ] mixin = "de.vette.idea.neos.lang.fusion.psi.impl.ext.FusionValueStringLineImplMixin" } + value_string_line_content ::= (VALUE_STRING | CRLF | VALUE_STRING_ESCAPED_QUOTE)* value_string_single_line ::= VALUE_STRING_QUOTE (VALUE_STRING | VALUE_STRING_ESCAPED_QUOTE)* VALUE_STRING_QUOTE {pin=1} diff --git a/src/main/java/de/vette/idea/neos/lang/fusion/injection/FusionDslTextEscaper.java b/src/main/java/de/vette/idea/neos/lang/fusion/injection/FusionDslTextEscaper.java new file mode 100644 index 00000000..6e126a50 --- /dev/null +++ b/src/main/java/de/vette/idea/neos/lang/fusion/injection/FusionDslTextEscaper.java @@ -0,0 +1,50 @@ +/* + * IntelliJ IDEA plugin to support the Neos CMS. + * Copyright (C) 2016 Christian Vette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.vette.idea.neos.lang.fusion.injection; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.LiteralTextEscaper; +import de.vette.idea.neos.lang.fusion.psi.FusionValueDslContent; +import org.jetbrains.annotations.NotNull; + +public class FusionDslTextEscaper extends LiteralTextEscaper { + + public FusionDslTextEscaper(@NotNull FusionValueDslContent host) { + super(host); + } + + @Override + public boolean decode(@NotNull TextRange rangeInsideHost, @NotNull StringBuilder outChars) { + outChars.append(myHost.getText(), rangeInsideHost.getStartOffset(), rangeInsideHost.getEndOffset()); + return true; + } + + @Override + public int getOffsetInHost(int offsetInDecoded, @NotNull TextRange rangeInsideHost) { + int offset = offsetInDecoded + rangeInsideHost.getStartOffset(); + if (offset < rangeInsideHost.getStartOffset()) offset = rangeInsideHost.getStartOffset(); + if (offset > rangeInsideHost.getEndOffset()) offset = rangeInsideHost.getEndOffset(); + return offset; + } + + @Override + public boolean isOneLine() { + return false; + } +} diff --git a/src/main/java/de/vette/idea/neos/lang/fusion/injection/FusionLanguageInjectionSupport.java b/src/main/java/de/vette/idea/neos/lang/fusion/injection/FusionLanguageInjectionSupport.java new file mode 100644 index 00000000..9a195d33 --- /dev/null +++ b/src/main/java/de/vette/idea/neos/lang/fusion/injection/FusionLanguageInjectionSupport.java @@ -0,0 +1,44 @@ +/* + * IntelliJ IDEA plugin to support the Neos CMS. + * Copyright (C) 2016 Christian Vette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.vette.idea.neos.lang.fusion.injection; + +import com.intellij.psi.PsiLanguageInjectionHost; +import de.vette.idea.neos.lang.fusion.patterns.FusionPatterns; +import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport; +import org.jetbrains.annotations.NotNull; + +public class FusionLanguageInjectionSupport extends AbstractLanguageInjectionSupport { + private final String SUPPORT_ID = "fusion"; + + @NotNull + @Override + public String getId() { + return SUPPORT_ID; + } + + @NotNull + @Override + public Class[] getPatternClasses() { + return new Class[]{FusionPatterns.class}; + } + + @Override + public boolean useDefaultInjector(PsiLanguageInjectionHost host) { + return false; + } +} diff --git a/src/main/java/de/vette/idea/neos/lang/fusion/injection/FusionLanguageInjector.java b/src/main/java/de/vette/idea/neos/lang/fusion/injection/FusionLanguageInjector.java new file mode 100644 index 00000000..4d0dfa87 --- /dev/null +++ b/src/main/java/de/vette/idea/neos/lang/fusion/injection/FusionLanguageInjector.java @@ -0,0 +1,54 @@ +/* + * IntelliJ IDEA plugin to support the Neos CMS. + * Copyright (C) 2016 Christian Vette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version.eadzc + * + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package de.vette.idea.neos.lang.fusion.injection; + +import com.intellij.lang.Language; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.InjectedLanguagePlaces; +import com.intellij.psi.LanguageInjector; +import com.intellij.psi.PsiLanguageInjectionHost; +import org.intellij.plugins.intelliLang.Configuration; +import org.intellij.plugins.intelliLang.inject.InjectedLanguage; +import org.intellij.plugins.intelliLang.inject.config.BaseInjection; +import org.jetbrains.annotations.NotNull; + +import java.util.*; + +public class FusionLanguageInjector implements LanguageInjector { + + private final Configuration myInjectionConfiguration; + + public FusionLanguageInjector(Configuration configuration) { + myInjectionConfiguration = configuration; + } + + @Override + public void getLanguagesToInject(@NotNull PsiLanguageInjectionHost host, @NotNull InjectedLanguagePlaces injectionPlacesRegistrar) { + Iterator it = myInjectionConfiguration.getInjections("fusion").iterator(); + while(it.hasNext()) { + BaseInjection injection = (BaseInjection) it.next(); + if (injection.acceptsPsiElement(host)) { + Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId()); + if (language != null) { + injectionPlacesRegistrar.addPlace(language, new TextRange(0, host.getTextLength()), "", ""); + } + } + } + } +} diff --git a/src/main/java/de/vette/idea/neos/lang/fusion/patterns/FusionElementPattern.java b/src/main/java/de/vette/idea/neos/lang/fusion/patterns/FusionElementPattern.java new file mode 100644 index 00000000..dae4ea91 --- /dev/null +++ b/src/main/java/de/vette/idea/neos/lang/fusion/patterns/FusionElementPattern.java @@ -0,0 +1,45 @@ +/* + * IntelliJ IDEA plugin to support the Neos CMS. + * Copyright (C) 2016 Christian Vette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.vette.idea.neos.lang.fusion.patterns; + +import com.intellij.patterns.InitialPatternCondition; +import com.intellij.patterns.PsiElementPattern; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +public class FusionElementPattern> extends PsiElementPattern { + + public FusionElementPattern(Class aClass) { + super(aClass); + } + + public FusionElementPattern(@NotNull InitialPatternCondition condition) { + super(condition); + } + + public static class Capture extends FusionElementPattern> { + public Capture(Class aClass) { + super(aClass); + } + + public Capture(@NotNull InitialPatternCondition condition) { + super(condition); + } + } +} diff --git a/src/main/java/de/vette/idea/neos/lang/fusion/patterns/FusionPatterns.java b/src/main/java/de/vette/idea/neos/lang/fusion/patterns/FusionPatterns.java new file mode 100644 index 00000000..b61212ec --- /dev/null +++ b/src/main/java/de/vette/idea/neos/lang/fusion/patterns/FusionPatterns.java @@ -0,0 +1,43 @@ +/* + * IntelliJ IDEA plugin to support the Neos CMS. + * Copyright (C) 2016 Christian Vette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.vette.idea.neos.lang.fusion.patterns; + +import com.intellij.patterns.InitialPatternCondition; +import com.intellij.patterns.PlatformPatterns; +import com.intellij.util.ProcessingContext; +import de.vette.idea.neos.lang.fusion.psi.FusionValueDsl; +import de.vette.idea.neos.lang.fusion.patterns.FusionElementPattern.Capture; +import de.vette.idea.neos.lang.fusion.psi.FusionValueDslContent; +import org.jetbrains.annotations.Nullable; + +public class FusionPatterns extends PlatformPatterns { + + public static FusionElementPattern fusionValueDsl(final String identifier) { + return new Capture(new InitialPatternCondition(FusionValueDslContent.class) { + public boolean accepts(@Nullable Object o, ProcessingContext context) { + if (o instanceof FusionValueDslContent) { + FusionValueDsl s = (FusionValueDsl) ((FusionValueDslContent) o).getParent(); + return s.getDslIdentifier().getText().equals(identifier); + } + + return false; + } + }); + } +} diff --git a/src/main/java/de/vette/idea/neos/lang/fusion/psi/impl/ext/FusionValueDslContentImplMixin.java b/src/main/java/de/vette/idea/neos/lang/fusion/psi/impl/ext/FusionValueDslContentImplMixin.java new file mode 100644 index 00000000..fbb28a29 --- /dev/null +++ b/src/main/java/de/vette/idea/neos/lang/fusion/psi/impl/ext/FusionValueDslContentImplMixin.java @@ -0,0 +1,50 @@ +/* + * IntelliJ IDEA plugin to support the Neos CMS. + * Copyright (C) 2016 Christian Vette + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package de.vette.idea.neos.lang.fusion.psi.impl.ext; + +import com.intellij.lang.ASTNode; +import com.intellij.psi.LiteralTextEscaper; +import com.intellij.psi.PsiLanguageInjectionHost; +import de.vette.idea.neos.lang.fusion.injection.FusionDslTextEscaper; +import de.vette.idea.neos.lang.fusion.psi.FusionValueDslContent; +import de.vette.idea.neos.lang.fusion.psi.impl.FusionCompositeElementImpl; +import org.jetbrains.annotations.NotNull; + +public class FusionValueDslContentImplMixin extends FusionCompositeElementImpl implements FusionValueDslContent { + + public FusionValueDslContentImplMixin(@NotNull ASTNode astNode) { + super(astNode); + } + + @Override + public boolean isValidHost() { + return true; + } + + @Override + public PsiLanguageInjectionHost updateText(@NotNull String text) { + return null; + } + + @NotNull + @Override + public LiteralTextEscaper createLiteralTextEscaper() { + return new FusionDslTextEscaper(this); + } +} diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 16c9ef02..fc165a31 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -43,6 +43,11 @@ com.jetbrains.php org.jetbrains.plugins.yaml + + + + + + + + diff --git a/src/main/resources/de/vette/idea/neos/lang/fusion/injection/fusionInjections.xml b/src/main/resources/de/vette/idea/neos/lang/fusion/injection/fusionInjections.xml new file mode 100644 index 00000000..425f5b00 --- /dev/null +++ b/src/main/resources/de/vette/idea/neos/lang/fusion/injection/fusionInjections.xml @@ -0,0 +1,8 @@ + + + + + AFX + + + \ No newline at end of file