mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-08 23:39:39 +07:00
[java-rd] IDEA-322563 Improve editing experience in Remote Dev for Java
- lexer, parser, IElementType for frontend GitOrigin-RevId: 8842d018eab3ca17749660520820174d4f792437
This commit is contained in:
committed by
intellij-monorepo-bot
parent
d247cc9ab7
commit
e23e60a0eb
35
java/java-frontback-impl/intellij.java.frontback.impl.iml
Normal file
35
java/java-frontback-impl/intellij.java.frontback.impl.iml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="5" platform="JVM 17" allPlatforms="JVM [17]" useProjectSettings="false">
|
||||
<compilerSettings>
|
||||
<option name="additionalArguments" value="-Xjvm-default=all -opt-in=com.intellij.openapi.util.IntellijInternalApi" />
|
||||
</compilerSettings>
|
||||
<compilerArguments>
|
||||
<stringArguments>
|
||||
<stringArg name="jvmTarget" arg="17" />
|
||||
<stringArg name="apiVersion" arg="1.8" />
|
||||
<stringArg name="languageVersion" arg="1.8" />
|
||||
</stringArguments>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/resource" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="intellij.java.frontback.psi" exported="" />
|
||||
<orderEntry type="module" module-name="intellij.java.frontback.psi.impl" exported="" />
|
||||
<orderEntry type="module" module-name="intellij.platform.core.impl" exported="" />
|
||||
<orderEntry type="module" module-name="intellij.platform.lang.impl" />
|
||||
<orderEntry type="module" module-name="intellij.platform.core.ui" />
|
||||
<orderEntry type="module" module-name="intellij.xml.frontback" exported="" />
|
||||
<orderEntry type="module" module-name="intellij.platform.core" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,6 @@
|
||||
<idea-plugin package="com.intellij.codeInsight.definition">
|
||||
<module value="com.intellij.java.frontback.impl" />
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="com.intellij.java.definitions" interface="com.intellij.codeInsight.definition.AbstractBasicJavaDefinitionService" dynamic="true"/>
|
||||
</extensionPoints>
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij;
|
||||
|
||||
import com.intellij.lang.xml.XmlTokenElementMarkTypes;
|
||||
import com.intellij.psi.impl.source.BasicJavaTokenSet;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
|
||||
|
||||
public interface BaseJavaJspElementType {
|
||||
BasicJavaTokenSet WHITE_SPACE_BIT_SET = BasicJavaTokenSet.orSet(
|
||||
BasicJavaTokenSet.create(TokenSet.WHITE_SPACE),
|
||||
BasicJavaTokenSet.create(XmlTokenElementMarkTypes.XML_WHITE_SPACE_MARK));
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.definition;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@ApiStatus.Experimental
|
||||
public abstract class AbstractBasicJavaDefinitionService {
|
||||
|
||||
public static final ExtensionPointName<AbstractBasicJavaDefinitionService>
|
||||
EP_NAME = ExtensionPointName.create("com.intellij.java.definitions");
|
||||
|
||||
private static class AbstractBasicJavaDefinitionServiceHelper {
|
||||
private static final AbstractBasicJavaDefinitionService INSTANCE = EP_NAME.getExtensionList().get(0);
|
||||
}
|
||||
|
||||
public static AbstractBasicJavaDefinitionService getJavaDefinitionService() {
|
||||
return AbstractBasicJavaDefinitionServiceHelper.INSTANCE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract LanguageLevel getLanguageLevel(@NotNull PsiElement psiElement);
|
||||
|
||||
@NotNull
|
||||
public abstract LanguageLevel getLanguageLevel(@NotNull Project project);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.ide.highlighter;
|
||||
|
||||
import com.intellij.openapi.editor.HighlighterColors;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaDocTokenType;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.StringEscapesTokenTypes;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.ParentProviderElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.intellij.psi.impl.source.BasicElementTypes.*;
|
||||
|
||||
public abstract class AbstractBasicJavaFileHighlighter extends SyntaxHighlighterBase {
|
||||
private final Map<IElementType, TextAttributesKey> ourMap1;
|
||||
private final Map<IElementType, TextAttributesKey> ourMap2;
|
||||
|
||||
protected final LanguageLevel myLanguageLevel;
|
||||
|
||||
public AbstractBasicJavaFileHighlighter(@NotNull LanguageLevel languageLevel) {
|
||||
myLanguageLevel = languageLevel;
|
||||
ourMap1 = new HashMap<>();
|
||||
ourMap2 = new HashMap<>();
|
||||
|
||||
fillMap(ourMap1, KEYWORD_BIT_SET.toTokenSet(), JavaHighlightingColors.KEYWORD);
|
||||
fillMap(ourMap1, LITERAL_BIT_SET.toTokenSet(), JavaHighlightingColors.KEYWORD);
|
||||
fillMap(ourMap1, OPERATION_BIT_SET.toTokenSet(), JavaHighlightingColors.OPERATION_SIGN);
|
||||
|
||||
for (IElementType type : JavaDocTokenType.ALL_JAVADOC_TOKENS.getTypes()) {
|
||||
ourMap1.put(type, JavaHighlightingColors.DOC_COMMENT);
|
||||
}
|
||||
|
||||
ourMap1.put(JavaTokenType.INTEGER_LITERAL, JavaHighlightingColors.NUMBER);
|
||||
ourMap1.put(JavaTokenType.LONG_LITERAL, JavaHighlightingColors.NUMBER);
|
||||
ourMap1.put(JavaTokenType.FLOAT_LITERAL, JavaHighlightingColors.NUMBER);
|
||||
ourMap1.put(JavaTokenType.DOUBLE_LITERAL, JavaHighlightingColors.NUMBER);
|
||||
ourMap1.put(JavaTokenType.STRING_LITERAL, JavaHighlightingColors.STRING);
|
||||
ourMap1.put(JavaTokenType.TEXT_BLOCK_LITERAL, JavaHighlightingColors.STRING);
|
||||
ourMap1.put(JavaTokenType.STRING_TEMPLATE_BEGIN, JavaHighlightingColors.STRING);
|
||||
ourMap1.put(JavaTokenType.STRING_TEMPLATE_MID, JavaHighlightingColors.STRING);
|
||||
ourMap1.put(JavaTokenType.STRING_TEMPLATE_END, JavaHighlightingColors.STRING);
|
||||
ourMap1.put(JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN, JavaHighlightingColors.STRING);
|
||||
ourMap1.put(JavaTokenType.TEXT_BLOCK_TEMPLATE_MID, JavaHighlightingColors.STRING);
|
||||
ourMap1.put(JavaTokenType.TEXT_BLOCK_TEMPLATE_END, JavaHighlightingColors.STRING);
|
||||
|
||||
ourMap1.put(StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN, JavaHighlightingColors.VALID_STRING_ESCAPE);
|
||||
ourMap1.put(StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN, JavaHighlightingColors.INVALID_STRING_ESCAPE);
|
||||
ourMap1.put(StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN, JavaHighlightingColors.INVALID_STRING_ESCAPE);
|
||||
ourMap1.put(JavaTokenType.CHARACTER_LITERAL, JavaHighlightingColors.STRING);
|
||||
|
||||
ourMap1.put(JavaTokenType.LPARENTH, JavaHighlightingColors.PARENTHESES);
|
||||
ourMap1.put(JavaTokenType.RPARENTH, JavaHighlightingColors.PARENTHESES);
|
||||
|
||||
ourMap1.put(JavaTokenType.LBRACE, JavaHighlightingColors.BRACES);
|
||||
ourMap1.put(JavaTokenType.RBRACE, JavaHighlightingColors.BRACES);
|
||||
|
||||
ourMap1.put(JavaTokenType.LBRACKET, JavaHighlightingColors.BRACKETS);
|
||||
ourMap1.put(JavaTokenType.RBRACKET, JavaHighlightingColors.BRACKETS);
|
||||
|
||||
ourMap1.put(JavaTokenType.COMMA, JavaHighlightingColors.COMMA);
|
||||
ourMap1.put(JavaTokenType.DOT, JavaHighlightingColors.DOT);
|
||||
ourMap1.put(JavaTokenType.SEMICOLON, JavaHighlightingColors.JAVA_SEMICOLON);
|
||||
|
||||
ourMap1.put(JavaTokenType.C_STYLE_COMMENT, JavaHighlightingColors.JAVA_BLOCK_COMMENT);
|
||||
ourMap1.put(DOC_COMMENT, JavaHighlightingColors.DOC_COMMENT);
|
||||
ourMap1.put(JavaTokenType.END_OF_LINE_COMMENT, JavaHighlightingColors.LINE_COMMENT);
|
||||
ourMap1.put(TokenType.BAD_CHARACTER, HighlighterColors.BAD_CHARACTER);
|
||||
|
||||
ourMap1.put(JavaDocTokenType.DOC_TAG_NAME, JavaHighlightingColors.DOC_COMMENT);
|
||||
ourMap2.put(JavaDocTokenType.DOC_TAG_NAME, JavaHighlightingColors.DOC_COMMENT_TAG);
|
||||
//noinspection AbstractMethodCallInConstructor
|
||||
initAdditional(ourMap1, ourMap2);
|
||||
}
|
||||
|
||||
protected abstract void initAdditional(@NotNull Map<IElementType, TextAttributesKey> map1,
|
||||
@NotNull Map<IElementType, TextAttributesKey> map2);
|
||||
|
||||
@Override
|
||||
public TextAttributesKey @NotNull [] getTokenHighlights(IElementType tokenType) {
|
||||
while (tokenType instanceof ParentProviderElementType parentProviderElementType) {
|
||||
if (parentProviderElementType.getParents().size() == 1) {
|
||||
tokenType = parentProviderElementType.getParents().iterator().next();
|
||||
}
|
||||
}
|
||||
return pack(ourMap1.get(tokenType), ourMap2.get(tokenType));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.lexer;
|
||||
|
||||
import com.intellij.lang.java.lexer.BasicJavaLexer;
|
||||
import com.intellij.lang.java.lexer.JavaDocLexer;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.JavaTokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class AbstractBasicJavaHighlightingLexer extends LayeredLexer {
|
||||
public AbstractBasicJavaHighlightingLexer(@NotNull LanguageLevel languageLevel,
|
||||
@NotNull BasicJavaLexer javaLexer) {
|
||||
super(javaLexer);
|
||||
|
||||
registerSelfStoppingLayer(new JavaStringLiteralLexer('\"', JavaTokenType.STRING_LITERAL, false, "s{"),
|
||||
new IElementType[]{JavaTokenType.STRING_LITERAL}, IElementType.EMPTY_ARRAY);
|
||||
|
||||
registerSelfStoppingLayer(new JavaStringLiteralLexer('\'', JavaTokenType.STRING_LITERAL, false, "s"),
|
||||
new IElementType[]{JavaTokenType.CHARACTER_LITERAL}, IElementType.EMPTY_ARRAY);
|
||||
|
||||
registerSelfStoppingLayer(new JavaStringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, JavaTokenType.TEXT_BLOCK_LITERAL, true, "s{"),
|
||||
new IElementType[]{JavaTokenType.TEXT_BLOCK_LITERAL}, IElementType.EMPTY_ARRAY);
|
||||
|
||||
registerSelfStoppingLayer(new JavaStringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN, true, "s"),
|
||||
new IElementType[]{JavaTokenType.TEXT_BLOCK_TEMPLATE_BEGIN}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new JavaStringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, JavaTokenType.TEXT_BLOCK_TEMPLATE_MID, true, "s"),
|
||||
new IElementType[]{JavaTokenType.TEXT_BLOCK_TEMPLATE_MID}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new JavaStringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, JavaTokenType.TEXT_BLOCK_TEMPLATE_END, true, "s"),
|
||||
new IElementType[]{JavaTokenType.TEXT_BLOCK_TEMPLATE_END}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new JavaStringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, JavaTokenType.STRING_TEMPLATE_BEGIN, true, "s"),
|
||||
new IElementType[]{JavaTokenType.STRING_TEMPLATE_BEGIN}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new JavaStringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, JavaTokenType.STRING_TEMPLATE_MID, true, "s"),
|
||||
new IElementType[]{JavaTokenType.STRING_TEMPLATE_MID}, IElementType.EMPTY_ARRAY);
|
||||
registerSelfStoppingLayer(new JavaStringLiteralLexer(StringLiteralLexer.NO_QUOTE_CHAR, JavaTokenType.STRING_TEMPLATE_END, true, "s"),
|
||||
new IElementType[]{JavaTokenType.STRING_TEMPLATE_END}, IElementType.EMPTY_ARRAY);
|
||||
|
||||
LayeredLexer docLexer = new LayeredLexer(new JavaDocLexer(languageLevel));
|
||||
|
||||
//noinspection AbstractMethodCallInConstructor
|
||||
registerDocLayers(docLexer);
|
||||
}
|
||||
|
||||
protected abstract void registerDocLayers(@NotNull LayeredLexer docLexer);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.lexer;
|
||||
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.StringEscapesTokenTypes;
|
||||
import com.intellij.psi.impl.source.BasicElementTypes;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
class JavaStringLiteralLexer extends StringLiteralLexer {
|
||||
|
||||
JavaStringLiteralLexer(char quoteChar, IElementType originalLiteralToken) {
|
||||
super(quoteChar, originalLiteralToken);
|
||||
}
|
||||
|
||||
JavaStringLiteralLexer(char quoteChar,
|
||||
IElementType originalLiteralToken,
|
||||
boolean canEscapeEolOrFramingSpaces,
|
||||
String additionalValidEscapes) {
|
||||
super(quoteChar, originalLiteralToken, canEscapeEolOrFramingSpaces, additionalValidEscapes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IElementType getTokenType() {
|
||||
IElementType tokenType = super.getTokenType();
|
||||
if (tokenType == StringEscapesTokenTypes.INVALID_CHARACTER_ESCAPE_TOKEN) {
|
||||
char c = myBuffer.charAt(myStart + 1);
|
||||
if (c == '{' && BasicElementTypes.STRING_TEMPLATE_FRAGMENTS.contains(myOriginalLiteralToken)) {
|
||||
// don't highlight \{ in template fragment as bad escape
|
||||
return myOriginalLiteralToken;
|
||||
}
|
||||
}
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull IElementType getUnicodeEscapeSequenceType() {
|
||||
int start = myStart + 2;
|
||||
while (start < myEnd && myBuffer.charAt(start) == 'u') start++;
|
||||
if (start + 3 >= myEnd) return StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN;
|
||||
if (!StringUtil.isHexDigit(myBuffer.charAt(start)) ||
|
||||
!StringUtil.isHexDigit(myBuffer.charAt(start + 1)) ||
|
||||
!StringUtil.isHexDigit(myBuffer.charAt(start + 2)) ||
|
||||
!StringUtil.isHexDigit(myBuffer.charAt(start + 3))) {
|
||||
return StringEscapesTokenTypes.INVALID_UNICODE_ESCAPE_TOKEN;
|
||||
}
|
||||
return StringEscapesTokenTypes.VALID_STRING_ESCAPE_TOKEN;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int locateUnicodeEscapeSequence(int start, int i) {
|
||||
do {
|
||||
i++;
|
||||
}
|
||||
while (i < myBufferEnd && myBuffer.charAt(i) == 'u');
|
||||
int end = parseUnicodeDigits(i);
|
||||
if (end != i + 4) return end;
|
||||
int code = Integer.parseInt(myBuffer.subSequence(i, end).toString(), 16);
|
||||
i = end;
|
||||
// if escape sequence is not translated to backspace then continue from the next symbol
|
||||
if (code != '\\' || i >= myBufferEnd) return i;
|
||||
char c = myBuffer.charAt(i);
|
||||
if (StringUtil.isOctalDigit(c)) {
|
||||
if (i + 2 < myBufferEnd && StringUtil.isOctalDigit(myBuffer.charAt(i + 1)) && StringUtil.isOctalDigit(myBuffer.charAt(i + 1))) {
|
||||
return i + 3;
|
||||
}
|
||||
}
|
||||
else if (c == '\\' && i + 1 < myBufferEnd && myBuffer.charAt(i + 1) == 'u') {
|
||||
i += 2;
|
||||
while (i < myBufferEnd && myBuffer.charAt(i) == 'u') i++;
|
||||
return parseUnicodeDigits(i);
|
||||
}
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
private int parseUnicodeDigits(int i) {
|
||||
int end = i + 4;
|
||||
for (; i < end; i++) {
|
||||
if (i == myBufferEnd) return i;
|
||||
if (!StringUtil.isHexDigit(myBuffer.charAt(i))) return i;
|
||||
}
|
||||
return end;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user