mirror of
https://github.com/ilyakooo0/intellij-haskell.git
synced 2024-08-17 10:40:44 +03:00
QuasiQuote injection, not sure if implemented correctly
This commit is contained in:
parent
dd951e98d0
commit
c48dfeea40
@ -2706,14 +2706,14 @@ public class HaskellParser implements PsiParser, LightPsiParser {
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// QUASIQUOTE | q_name | symbol_reserved_op | reserved_id | LEFT_PAREN | RIGHT_PAREN | FLOAT |
|
||||
// quasi_quote | q_name | symbol_reserved_op | reserved_id | LEFT_PAREN | RIGHT_PAREN | FLOAT |
|
||||
// SEMICOLON | LEFT_BRACKET | RIGHT_BRACKET | literal | LEFT_BRACE | RIGHT_BRACE |
|
||||
// COMMA | QUOTE | BACKQUOTE | fixity |
|
||||
// pragma | DIRECTIVE | DOUBLE_QUOTES
|
||||
static boolean general_id(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "general_id")) return false;
|
||||
boolean r;
|
||||
r = consumeToken(b, HS_QUASIQUOTE);
|
||||
r = quasi_quote(b, l + 1);
|
||||
if (!r) r = q_name(b, l + 1);
|
||||
if (!r) r = symbol_reserved_op(b, l + 1);
|
||||
if (!r) r = reserved_id(b, l + 1);
|
||||
@ -4819,6 +4819,18 @@ public class HaskellParser implements PsiParser, LightPsiParser {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// QUASIQUOTE
|
||||
public static boolean quasi_quote(PsiBuilder b, int l) {
|
||||
if (!recursion_guard_(b, l, "quasi_quote")) return false;
|
||||
if (!nextTokenIs(b, HS_QUASIQUOTE)) return false;
|
||||
boolean r;
|
||||
Marker m = enter_section_(b);
|
||||
r = consumeToken(b, HS_QUASIQUOTE);
|
||||
exit_section_(b, m, HS_QUASI_QUOTE, r);
|
||||
return r;
|
||||
}
|
||||
|
||||
/* ********************************************************** */
|
||||
// CASE | CLASS | DATA | DEFAULT | DERIVING | DO | ELSE | IF | IMPORT | IN | INSTANCE | LET | MODULE | NEWTYPE | OF | THEN | TYPE | WHERE | UNDERSCORE
|
||||
public static boolean reserved_id(PsiBuilder b, int l) {
|
||||
|
@ -29,6 +29,9 @@ public interface HaskellCidecl extends HaskellCompositeElement {
|
||||
@NotNull
|
||||
List<HaskellQName> getQNameList();
|
||||
|
||||
@NotNull
|
||||
List<HaskellQuasiQuote> getQuasiQuoteList();
|
||||
|
||||
@NotNull
|
||||
List<HaskellReservedId> getReservedIdList();
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package intellij.haskell.psi;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
|
||||
public interface HaskellExpression extends HaskellExpressionElement {
|
||||
|
||||
@ -16,6 +16,9 @@ public interface HaskellExpression extends HaskellExpressionElement {
|
||||
@NotNull
|
||||
List<HaskellQName> getQNameList();
|
||||
|
||||
@NotNull
|
||||
List<HaskellQuasiQuote> getQuasiQuoteList();
|
||||
|
||||
@NotNull
|
||||
List<HaskellReservedId> getReservedIdList();
|
||||
|
||||
|
8
gen/intellij/haskell/psi/HaskellQuasiQuote.java
Normal file
8
gen/intellij/haskell/psi/HaskellQuasiQuote.java
Normal file
@ -0,0 +1,8 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package intellij.haskell.psi;
|
||||
|
||||
import com.intellij.psi.PsiLanguageInjectionHost;
|
||||
|
||||
public interface HaskellQuasiQuote extends HaskellQuasiQuoteElement, PsiLanguageInjectionHost {
|
||||
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package intellij.haskell.psi;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.*;
|
||||
import com.intellij.psi.PsiElement;
|
||||
|
||||
public interface HaskellShebangLine extends HaskellCompositeElement {
|
||||
|
||||
@ -16,6 +16,9 @@ public interface HaskellShebangLine extends HaskellCompositeElement {
|
||||
@NotNull
|
||||
List<HaskellQName> getQNameList();
|
||||
|
||||
@NotNull
|
||||
List<HaskellQuasiQuote> getQuasiQuoteList();
|
||||
|
||||
@NotNull
|
||||
List<HaskellReservedId> getReservedIdList();
|
||||
|
||||
|
@ -61,6 +61,7 @@ public interface HaskellTypes {
|
||||
IElementType HS_NEWTYPE_DECLARATION = new HaskellCompositeElementType("HS_NEWTYPE_DECLARATION");
|
||||
IElementType HS_PRAGMA = new HaskellCompositeElementType("HS_PRAGMA");
|
||||
IElementType HS_QUALIFIER = new HaskellCompositeElementType("HS_QUALIFIER");
|
||||
IElementType HS_QUASI_QUOTE = new HaskellCompositeElementType("HS_QUASI_QUOTE");
|
||||
IElementType HS_Q_CON = new HaskellCompositeElementType("HS_Q_CON");
|
||||
IElementType HS_Q_CON_QUALIFIER = new HaskellCompositeElementType("HS_Q_CON_QUALIFIER");
|
||||
IElementType HS_Q_CON_QUALIFIER_1 = new HaskellCompositeElementType("HS_Q_CON_QUALIFIER_1");
|
||||
@ -273,6 +274,8 @@ public interface HaskellTypes {
|
||||
return new HaskellPragmaImpl(node);
|
||||
} else if (type == HS_QUALIFIER) {
|
||||
return new HaskellQualifierImpl(node);
|
||||
} else if (type == HS_QUASI_QUOTE) {
|
||||
return new HaskellQuasiQuoteImpl(node);
|
||||
} else if (type == HS_Q_CON) {
|
||||
return new HaskellQConImpl(node);
|
||||
} else if (type == HS_Q_CON_QUALIFIER) {
|
||||
|
@ -260,6 +260,11 @@ public class HaskellVisitor extends PsiElementVisitor {
|
||||
// visitNamedElement(o);
|
||||
}
|
||||
|
||||
public void visitQuasiQuote(@NotNull HaskellQuasiQuote o) {
|
||||
visitQuasiQuoteElement(o);
|
||||
// visitPsiLanguageInjectionHost(o);
|
||||
}
|
||||
|
||||
public void visitReservedId(@NotNull HaskellReservedId o) {
|
||||
visitCompositeElement(o);
|
||||
}
|
||||
@ -365,6 +370,10 @@ public class HaskellVisitor extends PsiElementVisitor {
|
||||
visitCompositeElement(o);
|
||||
}
|
||||
|
||||
public void visitQuasiQuoteElement(@NotNull HaskellQuasiQuoteElement o) {
|
||||
visitCompositeElement(o);
|
||||
}
|
||||
|
||||
public void visitStringLiteralElement(@NotNull HaskellStringLiteralElement o) {
|
||||
visitCompositeElement(o);
|
||||
}
|
||||
|
@ -67,6 +67,12 @@ public class HaskellCideclImpl extends HaskellCompositeElementImpl implements Ha
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, HaskellQName.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<HaskellQuasiQuote> getQuasiQuoteList() {
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, HaskellQuasiQuote.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<HaskellReservedId> getReservedIdList() {
|
||||
|
@ -1,14 +1,13 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package intellij.haskell.psi.impl;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import static intellij.haskell.psi.HaskellTypes.*;
|
||||
import intellij.haskell.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HaskellExpressionImpl extends HaskellExpressionElementImpl implements HaskellExpression {
|
||||
|
||||
@ -43,6 +42,12 @@ public class HaskellExpressionImpl extends HaskellExpressionElementImpl implemen
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, HaskellQName.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<HaskellQuasiQuote> getQuasiQuoteList() {
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, HaskellQuasiQuote.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<HaskellReservedId> getReservedIdList() {
|
||||
|
25
gen/intellij/haskell/psi/impl/HaskellQuasiQuoteImpl.java
Normal file
25
gen/intellij/haskell/psi/impl/HaskellQuasiQuoteImpl.java
Normal file
@ -0,0 +1,25 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package intellij.haskell.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import intellij.haskell.psi.HaskellQuasiQuote;
|
||||
import intellij.haskell.psi.HaskellVisitor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class HaskellQuasiQuoteImpl extends HaskellQuasiQuoteElementImpl implements HaskellQuasiQuote {
|
||||
|
||||
public HaskellQuasiQuoteImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public void accept(@NotNull HaskellVisitor visitor) {
|
||||
visitor.visitQuasiQuote(this);
|
||||
}
|
||||
|
||||
public void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof HaskellVisitor) accept((HaskellVisitor) visitor);
|
||||
else super.accept(visitor);
|
||||
}
|
||||
|
||||
}
|
@ -1,14 +1,13 @@
|
||||
// This is a generated file. Not intended for manual editing.
|
||||
package intellij.haskell.psi.impl;
|
||||
|
||||
import java.util.List;
|
||||
import org.jetbrains.annotations.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import static intellij.haskell.psi.HaskellTypes.*;
|
||||
import intellij.haskell.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class HaskellShebangLineImpl extends HaskellCompositeElementImpl implements HaskellShebangLine {
|
||||
|
||||
@ -43,6 +42,12 @@ public class HaskellShebangLineImpl extends HaskellCompositeElementImpl implemen
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, HaskellQName.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<HaskellQuasiQuote> getQuasiQuoteList() {
|
||||
return PsiTreeUtil.getChildrenOfTypeAsList(this, HaskellQuasiQuote.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<HaskellReservedId> getReservedIdList() {
|
||||
|
@ -307,6 +307,8 @@
|
||||
implementationClass="intellij.haskell.alex.lang.psi.impl.AlexElementManipulator"/>
|
||||
<lang.elementManipulator forClass="intellij.haskell.psi.impl.HaskellStringLiteralElementImpl"
|
||||
implementationClass="intellij.haskell.psi.impl.HaskellStringLiteralManipulator"/>
|
||||
<lang.elementManipulator forClass="intellij.haskell.psi.impl.HaskellQuasiQuoteElementImpl"
|
||||
implementationClass="intellij.haskell.psi.impl.HaskellQuasiQuoteManipulator"/>
|
||||
<lang.namesValidator language="Haskell" implementationClass="intellij.haskell.refactor.HaskellNamesValidator"/>
|
||||
<languageInjector implementation="intellij.haskell.alex.lang.psi.AlexHaskellInjector"/>
|
||||
|
||||
|
@ -47,6 +47,9 @@
|
||||
|
||||
implements("text_literal")=["intellij.haskell.psi.HaskellStringLiteralElement" "com.intellij.psi.PsiLanguageInjectionHost"]
|
||||
mixin("text_literal")="intellij.haskell.psi.impl.HaskellStringLiteralElementImpl"
|
||||
|
||||
implements("quasi_quote")=["intellij.haskell.psi.HaskellQuasiQuoteElement" "com.intellij.psi.PsiLanguageInjectionHost"]
|
||||
mixin("quasi_quote")="intellij.haskell.psi.impl.HaskellQuasiQuoteElementImpl"
|
||||
}
|
||||
|
||||
program ::= onl shebang_line? onl file_header onl module_body
|
||||
@ -124,6 +127,7 @@ type_family_declaration ::= TYPE_FAMILY onls type_family_type (onls (WHERE |
|
||||
deriving_declaration ::= DERIVING INSTANCE (scontext onls DOUBLE_RIGHT_ARROW)? onls q_name onls inst
|
||||
|
||||
text_literal ::= STRING_LITERAL
|
||||
quasi_quote ::= QUASIQUOTE
|
||||
|
||||
private literal ::= DECIMAL | HEXADECIMAL | OCTAL | FLOAT | CHARACTER_LITERAL | text_literal
|
||||
|
||||
@ -237,7 +241,7 @@ cidecl ::= pragma | instance_declaration | default_declarat
|
||||
expression ::= line_expression (nls line_expression)*
|
||||
private line_expression ::= general_id+
|
||||
|
||||
private general_id ::= QUASIQUOTE | q_name | symbol_reserved_op | reserved_id | LEFT_PAREN | RIGHT_PAREN | FLOAT |
|
||||
private general_id ::= quasi_quote | q_name | symbol_reserved_op | reserved_id | LEFT_PAREN | RIGHT_PAREN | FLOAT |
|
||||
SEMICOLON | LEFT_BRACKET | RIGHT_BRACKET | literal | LEFT_BRACE | RIGHT_BRACE |
|
||||
COMMA | QUOTE | BACKQUOTE | fixity |
|
||||
pragma | DIRECTIVE | DOUBLE_QUOTES
|
||||
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2014-2019 Rik van der Kleij
|
||||
*
|
||||
* 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 intellij.haskell.psi
|
||||
|
||||
trait HaskellQuasiQuoteElement extends HaskellCompositeElement {
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package intellij.haskell.psi.impl
|
||||
|
||||
import com.intellij.lang.ASTNode
|
||||
import com.intellij.psi.{ElementManipulators, LiteralTextEscaper, PsiLanguageInjectionHost}
|
||||
import intellij.haskell.psi.HaskellQuasiQuoteElement
|
||||
|
||||
abstract class HaskellQuasiQuoteElementImpl private[impl](node: ASTNode)
|
||||
extends HaskellCompositeElementImpl(node)
|
||||
with HaskellQuasiQuoteElement
|
||||
with PsiLanguageInjectionHost {
|
||||
override def isValidHost: Boolean = {
|
||||
true
|
||||
}
|
||||
|
||||
override def updateText(text: String): HaskellQuasiQuoteElementImpl = {
|
||||
ElementManipulators.handleContentChange(this, text)
|
||||
}
|
||||
|
||||
override def createLiteralTextEscaper(): LiteralTextEscaper[HaskellQuasiQuoteElementImpl] = {
|
||||
LiteralTextEscaper.createSimple(this)
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package intellij.haskell.psi.impl
|
||||
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.{AbstractElementManipulator, PsiFileFactory}
|
||||
import com.intellij.util.IncorrectOperationException
|
||||
import intellij.haskell.HaskellLanguage
|
||||
import org.jetbrains.annotations.Nullable
|
||||
|
||||
/**
|
||||
* @author ice1000
|
||||
*/
|
||||
class HaskellQuasiQuoteManipulator extends AbstractElementManipulator[HaskellQuasiQuoteElementImpl] {
|
||||
@Nullable
|
||||
@throws[IncorrectOperationException]
|
||||
override def handleContentChange(psi: HaskellQuasiQuoteElementImpl,
|
||||
range: TextRange,
|
||||
newContent: String): HaskellQuasiQuoteElementImpl = {
|
||||
val oldText = psi.getText
|
||||
val newText = oldText.substring(0, range.getStartOffset) + newContent + oldText.substring(range.getEndOffset)
|
||||
val newElement = PsiFileFactory
|
||||
.getInstance(psi.getProject)
|
||||
.createFileFromText("a.hs", HaskellLanguage.Instance, newText, false, false)
|
||||
.getLastChild
|
||||
.getLastChild
|
||||
psi.replace(newElement).asInstanceOf[HaskellQuasiQuoteElementImpl]
|
||||
}
|
||||
|
||||
override def getRangeInElement(element: HaskellQuasiQuoteElementImpl): TextRange = {
|
||||
val text = element.getText
|
||||
new TextRange(text.indexOf('|') + 1, text.lastIndexOf('|'))
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ public class HaskellStringEscaper extends LiteralTextEscaper<HaskellStringLitera
|
||||
public int getOffsetInHost(int offsetInDecoded, @NotNull final TextRange rangeInsideHost) {
|
||||
int result = offsetInDecoded < outSourceOffsets.length ? outSourceOffsets[offsetInDecoded] : -1;
|
||||
if (result == -1) return -1;
|
||||
return (result <= rangeInsideHost.getLength() ? result : rangeInsideHost.getLength()) + rangeInsideHost.getStartOffset();
|
||||
return Math.min(result, rangeInsideHost.getLength()) + rangeInsideHost.getStartOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user