diff --git a/idea/spg-schema-idea-plugin/README.md b/idea/spg-schema-idea-plugin/README.md index 15b04ba..ae88b5c 100644 --- a/idea/spg-schema-idea-plugin/README.md +++ b/idea/spg-schema-idea-plugin/README.md @@ -7,7 +7,7 @@ An IDEA plugin for OpenSPG Schema Mark Language ## Preview
- screenshot + screenshot
## Features: @@ -22,6 +22,7 @@ An IDEA plugin for OpenSPG Schema Mark Language - Syntax highlighter - Structure view - Preview +- Folding ## TODO diff --git a/idea/spg-schema-idea-plugin/build.gradle.kts b/idea/spg-schema-idea-plugin/build.gradle.kts index 1b35f1e..9a3e3a4 100644 --- a/idea/spg-schema-idea-plugin/build.gradle.kts +++ b/idea/spg-schema-idea-plugin/build.gradle.kts @@ -1,4 +1,3 @@ -import org.jetbrains.kotlin.ir.backend.js.compile plugins { id("java") @@ -7,14 +6,14 @@ plugins { } group = "org.openspg.idea" -version = "0.0.9" +version = "0.0.11" repositories { mavenCentral() } dependencies { - implementation("com.alibaba:fastjson:1.2.83") + implementation("com.alibaba:fastjson:2.0.57") } sourceSets { @@ -29,7 +28,7 @@ sourceSets { // Configure Gradle IntelliJ Plugin // Read more: https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html intellij { - version.set("2024.1.7") + version.set("2023.1") type.set("IC") // Target IDE Platform plugins.set(listOf("com.intellij.java")) @@ -46,7 +45,7 @@ tasks { } patchPluginXml { - sinceBuild.set("222") + sinceBuild.set("231") untilBuild.set("") } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleBundle.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleBundle.java new file mode 100644 index 0000000..871078c --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleBundle.java @@ -0,0 +1,27 @@ +package org.openspg.idea.conceptRule; + +import com.intellij.DynamicBundle; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.PropertyKey; + +import java.util.function.Supplier; + +public class ConceptRuleBundle { + + private static final @NonNls String BUNDLE = "messages.ConceptRuleBundle"; + private static final DynamicBundle INSTANCE = new DynamicBundle(ConceptRuleBundle.class, BUNDLE); + + private ConceptRuleBundle() { + } + + public static @NotNull @Nls String message(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) { + return INSTANCE.getMessage(key, params); + } + + public static @NotNull Supplier<@Nls String> messagePointer(@NotNull @PropertyKey(resourceBundle = BUNDLE) String key, Object @NotNull ... params) { + return INSTANCE.getLazyMessage(key, params); + } + +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleCommenter.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleCommenter.java index 9444aef..81e0fdf 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleCommenter.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleCommenter.java @@ -7,7 +7,7 @@ final class ConceptRuleCommenter implements Commenter { @Override public String getLineCommentPrefix() { - return "#"; + return "//"; } @Override diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleFileType.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleFileType.java index fd200d2..11b81a3 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleFileType.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleFileType.java @@ -17,13 +17,13 @@ private ConceptRuleFileType() { @NotNull @Override public String getName() { - return "OpenSPG Schema Rule File"; + return "OpenSPG Concept Rule File"; } @NotNull @Override public String getDescription() { - return "OpenSPG Schema rule file"; + return "OpenSPG Concept rule file"; } @NotNull diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleFoldingBuilder.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleFoldingBuilder.java new file mode 100644 index 0000000..28c9cf2 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleFoldingBuilder.java @@ -0,0 +1,125 @@ +package org.openspg.idea.conceptRule; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.folding.FoldingBuilderEx; +import com.intellij.lang.folding.FoldingDescriptor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.DumbAware; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.openspg.idea.conceptRule.lang.psi.*; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Set; + +public class ConceptRuleFoldingBuilder extends FoldingBuilderEx implements DumbAware { + + private final Set> adapters = Set.of( + new ConceptRuleCommentFoldingAdapter(), + new ConceptRuleRuleWrapperFoldingAdapter(), + new ConceptRuleTheDefineStructureFoldingAdapter(), + new ConceptRuleTheGraphStructureFoldingAdapter(), + new ConceptRuleTheRuleFoldingAdapter(), + new ConceptRuleCreateActionFoldingAdapter() + ); + + @Override + @SuppressWarnings("unchecked") + public FoldingDescriptor @NotNull [] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { + Class[] classes = adapters + .stream() + .map(FoldingAdapter::getType) + .toArray(Class[]::new); + + return PsiTreeUtil.findChildrenOfAnyType(root, classes) + .stream() + .map(element -> new FoldingDescriptor(element, element.getTextRange())) + .toArray(FoldingDescriptor[]::new); + } + + @Override + public @Nullable String getPlaceholderText(@NotNull ASTNode node) { + PsiElement element = node.getPsi(); + for (FoldingAdapter adapter : adapters) { + if (adapter.getType().isInstance(element)) { + return adapter.getPlaceholderText(node, element); + } + } + throw new IllegalArgumentException("Unknown PsiElement type: " + element.getClass()); + } + + @Override + public boolean isCollapsedByDefault(@NotNull ASTNode node) { + return node.getPsi() instanceof PsiComment; + } + + public abstract static class FoldingAdapter { + + @SuppressWarnings("unchecked") + public Class getType() { + Type superClass = getClass().getGenericSuperclass(); + Type[] params = ((ParameterizedType) superClass).getActualTypeArguments(); + return (Class) params[0]; + } + + @SuppressWarnings("unchecked") + public String getPlaceholderText(@NotNull ASTNode node, @NotNull PsiElement element) { + assert getType().isInstance(element); + return getPlaceholderText((T) element); + } + + protected abstract String getPlaceholderText(T element); + } + + public static class ConceptRuleCommentFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull PsiComment element) { + return "#..."; + } + } + + public static class ConceptRuleRuleWrapperFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull ConceptRuleRuleWrapper element) { + String placeHolder = element.getRuleWrapperHead().getText(); + if (element.getRuleWrapperBody() != null) { + placeHolder += " ..."; + } + return placeHolder; + } + } + + public static class ConceptRuleTheDefineStructureFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull ConceptRuleTheDefineStructure element) { + return "Define " + element.getPredicatedDefine().getText() + " {...}"; + } + } + + public static class ConceptRuleTheGraphStructureFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull ConceptRuleTheGraphStructure element) { + return element.getGraphStructureHead().getText() + " {...}"; + } + } + + public static class ConceptRuleTheRuleFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull ConceptRuleTheRule element) { + return element.getRuleHead().getText() + " {...}"; + } + } + + public static class ConceptRuleCreateActionFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull ConceptRuleCreateAction element) { + return element.getCreateActionSymbol().getText() + " {...}"; + } + } + +} + diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleLanguage.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleLanguage.java index d3a975f..aecf046 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleLanguage.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/ConceptRuleLanguage.java @@ -7,7 +7,7 @@ public final class ConceptRuleLanguage extends Language { public static final ConceptRuleLanguage INSTANCE = new ConceptRuleLanguage(); private ConceptRuleLanguage() { - super("OpenSPG Schema Rule"); + super("OpenSPG Concept Rule"); } } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/codeStyle/ConceptRuleCodeStyleSettings.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/codeStyle/ConceptRuleCodeStyleSettings.java new file mode 100644 index 0000000..1aecbf5 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/codeStyle/ConceptRuleCodeStyleSettings.java @@ -0,0 +1,23 @@ +package org.openspg.idea.conceptRule.codeStyle; + + +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; + + +public class ConceptRuleCodeStyleSettings extends CustomCodeStyleSettings { + + public static final int DEFAULT_INDENT_SIZE = 4; + public static final boolean DEFAULT_SPACE_BEFORE_COMMA = false; + public static final boolean DEFAULT_SPACE_AFTER_COMMA = false; + public static final boolean DEFAULT_SPACE_BEFORE_COLON = false; + public static final boolean DEFAULT_SPACE_AFTER_COLON = false; + public static final boolean DEFAULT_SPACE_WITHIN_BRACKETS = false; + public static final boolean DEFAULT_SPACE_WITHIN_PARENTHESES = false; + + + public ConceptRuleCodeStyleSettings(CodeStyleSettings container) { + super("ConceptRuleCodeStyleSettings", container); + } + +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/codeStyle/ConceptRuleCodeStyleSettingsProvider.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/codeStyle/ConceptRuleCodeStyleSettingsProvider.java new file mode 100644 index 0000000..a5a3e78 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/codeStyle/ConceptRuleCodeStyleSettingsProvider.java @@ -0,0 +1,52 @@ +package org.openspg.idea.conceptRule.codeStyle; + +import com.intellij.application.options.CodeStyleAbstractConfigurable; +import com.intellij.application.options.CodeStyleAbstractPanel; +import com.intellij.application.options.TabbedLanguageCodeStylePanel; +import com.intellij.psi.codeStyle.CodeStyleConfigurable; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsProvider; +import com.intellij.psi.codeStyle.CustomCodeStyleSettings; +import org.jetbrains.annotations.NotNull; +import org.openspg.idea.conceptRule.ConceptRuleLanguage; + + +public final class ConceptRuleCodeStyleSettingsProvider extends CodeStyleSettingsProvider { + + @Override + public CustomCodeStyleSettings createCustomSettings(@NotNull CodeStyleSettings settings) { + return new ConceptRuleCodeStyleSettings(settings); + } + + @Override + public String getConfigurableDisplayName() { + return "OpenSPG Concept Rule"; + } + + @NotNull + public CodeStyleConfigurable createConfigurable(@NotNull CodeStyleSettings settings, + @NotNull CodeStyleSettings modelSettings) { + return new CodeStyleAbstractConfigurable(settings, modelSettings, this.getConfigurableDisplayName()) { + @Override + protected @NotNull CodeStyleAbstractPanel createPanel(@NotNull CodeStyleSettings settings) { + return new SchemaCodeStyleMainPanel(getCurrentSettings(), settings); + } + }; + } + + private static class SchemaCodeStyleMainPanel extends TabbedLanguageCodeStylePanel { + + public SchemaCodeStyleMainPanel(CodeStyleSettings currentSettings, CodeStyleSettings settings) { + super(ConceptRuleLanguage.INSTANCE, currentSettings, settings); + } + + @Override + protected void initTabs(CodeStyleSettings settings) { + addIndentOptionsTab(settings); + addSpacesTab(settings); + addBlankLinesTab(settings); + } + + } + +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/codeStyle/ConceptRuleLanguageCodeStyleSettingsProvider.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/codeStyle/ConceptRuleLanguageCodeStyleSettingsProvider.java new file mode 100644 index 0000000..3fd91e1 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/codeStyle/ConceptRuleLanguageCodeStyleSettingsProvider.java @@ -0,0 +1,79 @@ +package org.openspg.idea.conceptRule.codeStyle; + +import com.intellij.application.options.IndentOptionsEditor; +import com.intellij.lang.Language; +import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider; +import org.jetbrains.annotations.NotNull; +import org.openspg.idea.conceptRule.ConceptRuleBundle; +import org.openspg.idea.conceptRule.ConceptRuleLanguage; +import org.openspg.idea.conceptRule.demo.ConceptRuleDemo; + +import static org.openspg.idea.conceptRule.codeStyle.ConceptRuleCodeStyleSettings.*; + +public final class ConceptRuleLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSettingsProvider { + + @NotNull + @Override + public Language getLanguage() { + return ConceptRuleLanguage.INSTANCE; + } + + @Override + public void customizeSettings(@NotNull CodeStyleSettingsCustomizable consumer, @NotNull SettingsType settingsType) { + if (settingsType == SettingsType.INDENT_SETTINGS) { + consumer.showStandardOptions("INDENT_SIZE"); + + } else if (settingsType == SettingsType.SPACING_SETTINGS) { + consumer.showStandardOptions( + "SPACE_AFTER_COMMA", + "SPACE_BEFORE_COMMA", + "SPACE_AFTER_COLON", + "SPACE_BEFORE_COLON", + "SPACE_WITHIN_BRACKETS", + "SPACE_WITHIN_PARENTHESES" + ); + + } else if (settingsType == SettingsType.BLANK_LINES_SETTINGS) { + consumer.showStandardOptions( + "BLANK_LINES_AFTER_PACKAGE", + "BLANK_LINES_AFTER_IMPORTS" + ); + + consumer.renameStandardOption( + "BLANK_LINES_AFTER_PACKAGE", + ConceptRuleBundle.message("ConceptRuleCodeStyleSettings.blankLines.after.namespace") + ); + consumer.renameStandardOption( + "BLANK_LINES_AFTER_IMPORTS", + ConceptRuleBundle.message("ConceptRuleCodeStyleSettings.blankLines.after.schema") + ); + } + } + + @Override + public @NotNull IndentOptionsEditor getIndentOptionsEditor() { + return new IndentOptionsEditor(this); + } + + @Override + public String getCodeSample(@NotNull SettingsType settingsType) { + return ConceptRuleDemo.getCodeStyleText(); + } + + @Override + protected void customizeDefaults(@NotNull CommonCodeStyleSettings commonSettings, @NotNull CommonCodeStyleSettings.IndentOptions indentOptions) { + super.customizeDefaults(commonSettings, indentOptions); + + commonSettings.SPACE_BEFORE_COMMA = DEFAULT_SPACE_BEFORE_COMMA; + commonSettings.SPACE_AFTER_COMMA = DEFAULT_SPACE_AFTER_COMMA; + commonSettings.SPACE_BEFORE_COLON = DEFAULT_SPACE_BEFORE_COLON; + commonSettings.SPACE_AFTER_COLON = DEFAULT_SPACE_AFTER_COLON; + commonSettings.SPACE_WITHIN_BRACKETS = DEFAULT_SPACE_WITHIN_BRACKETS; + commonSettings.SPACE_WITHIN_PARENTHESES = DEFAULT_SPACE_WITHIN_PARENTHESES; + + indentOptions.INDENT_SIZE = DEFAULT_INDENT_SIZE; + } + +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/demo/ConceptRuleDemo.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/demo/ConceptRuleDemo.java index f0f7e9d..14224bc 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/demo/ConceptRuleDemo.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/demo/ConceptRuleDemo.java @@ -7,7 +7,11 @@ public static String getHighlighterText() { namespace SupplyChain `TaxOfProdEvent`/`价格上涨`: + // 定义规则 rule: [[ + /** + * 定义 + **/ Define (e:ProductChainEvent)-[p:belongTo]->(o:`TaxOfProdEvent`/`价格上涨`) { Structure { } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/formatter/ConceptRuleBlock.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/formatter/ConceptRuleBlock.java new file mode 100644 index 0000000..2c7fbad --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/formatter/ConceptRuleBlock.java @@ -0,0 +1,112 @@ +package org.openspg.idea.conceptRule.formatter; + +import com.intellij.formatting.*; +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import com.intellij.psi.TokenType; +import com.intellij.psi.formatter.common.AbstractBlock; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleRuleWrapperBody; + +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +import static org.openspg.idea.conceptRule.grammar.psi.ConceptRuleTypes.*; + + +public class ConceptRuleBlock extends AbstractBlock { + + private static final Set NONBLOCK_ELEMENT_TYPES = Set.of( + TokenType.WHITE_SPACE, EOL + ); + + private static final Set NORMAL_INDENT_BLOCK_ELEMENT_TYPES = Set.of( + RULE_WRAPPER_BODY, BASE_RULE_DEFINE, RULE_EXPRESSION_BODY, PATH_PATTERN_LIST + ); + + private final Indent myIndent; + private final SpacingBuilder mySpacingBuilder; + + protected ConceptRuleBlock( + @NotNull ASTNode node, + @Nullable Wrap wrap, + @Nullable Alignment alignment, + @Nullable SpacingBuilder spacingBuilder + ) { + this(node, wrap, alignment, spacingBuilder, null); + } + + protected ConceptRuleBlock( + @NotNull ASTNode node, + @Nullable Wrap wrap, + @Nullable Alignment alignment, + @Nullable SpacingBuilder spacingBuilder, + @Nullable Indent indent + ) { + super(node, wrap, alignment); + mySpacingBuilder = spacingBuilder; + myIndent = indent; + this.setBuildIndentsOnly(true); + } + + @Override + protected List buildChildren() { + List blocks = new ArrayList<>(); + + ASTNode[] children = myNode.getChildren(null); + for (ASTNode child : children) { + Block childBlock = buildBlock(child); + if (childBlock != null) { + blocks.add(childBlock); + } + } + + return blocks; + } + + private Block buildBlock(ASTNode node) { + IElementType type = node.getElementType(); + if (NONBLOCK_ELEMENT_TYPES.contains(type)) { + return null; + } + + Indent indent = null; + if (NORMAL_INDENT_BLOCK_ELEMENT_TYPES.contains(type)) { + indent = Indent.getNormalIndent(); + + } else if (type == THE_DEFINE_STRUCTURE) { + PsiElement parent = node.getPsi().getParent(); + if (parent instanceof ConceptRuleRuleWrapperBody) { + indent = Indent.getNormalIndent(); + } + } + + return new ConceptRuleBlock( + node, + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + mySpacingBuilder, + indent + ); + } + + @Override + public Indent getIndent() { + return myIndent == null ? Indent.getNoneIndent() : myIndent; + } + + @Nullable + @Override + public Spacing getSpacing(@Nullable Block firstChild, @NotNull Block secondChild) { + return mySpacingBuilder == null ? null : mySpacingBuilder.getSpacing(this, firstChild, secondChild); + } + + @Override + public boolean isLeaf() { + return myNode.getFirstChildNode() == null; + } + +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/formatter/ConceptRuleFormattingModelBuilder.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/formatter/ConceptRuleFormattingModelBuilder.java new file mode 100644 index 0000000..e6470c9 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/formatter/ConceptRuleFormattingModelBuilder.java @@ -0,0 +1,118 @@ +package org.openspg.idea.conceptRule.formatter; + +import com.intellij.formatting.*; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CommonCodeStyleSettings; +import com.intellij.psi.tree.TokenSet; +import org.jetbrains.annotations.NotNull; +import org.openspg.idea.conceptRule.ConceptRuleLanguage; +import org.openspg.idea.conceptRule.codeStyle.ConceptRuleCodeStyleSettings; +import org.openspg.idea.conceptRule.grammar.psi.ConceptRuleTypes; + +import static org.openspg.idea.conceptRule.grammar.psi.ConceptRuleTypes.*; + +public final class ConceptRuleFormattingModelBuilder implements FormattingModelBuilder { + + @Override + public @NotNull FormattingModel createModel(@NotNull FormattingContext formattingContext) { + final CodeStyleSettings codeStyleSettings = formattingContext.getCodeStyleSettings(); + return FormattingModelProvider.createFormattingModelForPsiFile( + formattingContext.getContainingFile(), + new ConceptRuleBlock( + formattingContext.getNode(), + Wrap.createWrap(WrapType.NONE, false), + Alignment.createAlignment(), + createSpaceBuilder(codeStyleSettings) + ), + codeStyleSettings + ); + } + + @NotNull + private static SpacingBuilder createSpaceBuilder(CodeStyleSettings settings) { + SpacingBuilder builder = new SpacingBuilder(settings, ConceptRuleLanguage.INSTANCE); + + CommonCodeStyleSettings commonSetting = settings.getCommonSettings(ConceptRuleLanguage.INSTANCE.getID()); + + ConceptRuleCodeStyleSettings customSettings = settings.getCustomSettings(ConceptRuleCodeStyleSettings.class); + + builder = builder.after(NAMESPACE_KEYWORD).spaces(1); + + int blankLinesAfterNamespace = Math.max(0, commonSetting.BLANK_LINES_AFTER_PACKAGE) + 1; + builder = builder.after(TokenSet.create(NAMESPACE)) + .spacing(0, 0, blankLinesAfterNamespace, false, 0); + + int blankLinesAfterSchemaPattern = Math.max(0, commonSetting.BLANK_LINES_AFTER_IMPORTS) + 1; + builder = builder.after(TokenSet.create(RULE_WRAPPER)) + .spacing(0, 0, blankLinesAfterSchemaPattern, false, 0); + + builder = builder + .before(TokenSet.create(OPEN_RULE_BLOCK)) + .spacing(1, 1, 0, false, 0) + .after(TokenSet.create(OPEN_RULE_BLOCK)) + .spacing(0, 0, 1, false, 0) + + .around(TokenSet.create(CLOSE_RULE_BLOCK)) + .spacing(0, 0, 1, false, 0) + + .before(TokenSet.create(LBRACE)) + .spacing(1, 1, 0, false, 0) + .after(TokenSet.create(LBRACE)) + .spacing(0, 0, 1, false, 0) + .before(TokenSet.create(RBRACE)) + .lineBreakInCode(); + + builder = initSpaceBuilderByComma(builder, commonSetting); + builder = initSpaceBuilderByColon(builder, commonSetting); + + boolean spaceAroundBrackets = commonSetting.SPACE_WITHIN_BRACKETS; + if (spaceAroundBrackets) { + builder = builder + .after(ConceptRuleTypes.LBRACKET).spaces(1) + .before(ConceptRuleTypes.RBRACKET).spaces(1); + } else { + builder = builder + .after(ConceptRuleTypes.LBRACKET).spaces(0) + .before(ConceptRuleTypes.RBRACKET).spaces(0); + } + + boolean spaceAroundParentheses = commonSetting.SPACE_WITHIN_PARENTHESES; + if (spaceAroundParentheses) { + builder = builder + .after(ConceptRuleTypes.LPARENTH).spaces(1) + .before(ConceptRuleTypes.RPARENTH).spaces(1); + } else { + builder = builder + .after(ConceptRuleTypes.LPARENTH).spaces(0) + .before(ConceptRuleTypes.RPARENTH).spaces(0); + } + + builder = builder.around(ConceptRuleTypes.IDENTIFIER).spaces(0); + + return builder; + } + + private static SpacingBuilder initSpaceBuilderByComma(SpacingBuilder builder, CommonCodeStyleSettings settings) { + if (settings.SPACE_BEFORE_COMMA) { + builder = builder.before(COMMA).spaces(1); + } + + if (settings.SPACE_AFTER_COMMA) { + builder = builder.after(COMMA).spaces(1); + } + + return builder; + } + + private static SpacingBuilder initSpaceBuilderByColon(SpacingBuilder builder, CommonCodeStyleSettings settings) { + if (settings.SPACE_BEFORE_COLON) { + builder = builder.before(COLON).spaces(1); + } + + if (settings.SPACE_AFTER_COLON) { + builder = builder.after(COLON).spaces(1); + } + return builder; + } + +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/grammar/ConceptRuleParserDefinition.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/grammar/ConceptRuleParserDefinition.java index 9326285..1f99369 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/grammar/ConceptRuleParserDefinition.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/grammar/ConceptRuleParserDefinition.java @@ -13,10 +13,10 @@ import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; import org.openspg.idea.conceptRule.ConceptRuleLanguage; +import org.openspg.idea.conceptRule.grammar.psi.ConceptRuleTypes; +import org.openspg.idea.conceptRule.lang.parser.ConceptRuleParser; import org.openspg.idea.conceptRule.lexer.ConceptRuleLexerAdapter; import org.openspg.idea.conceptRule.psi.ConceptRuleFile; -import org.openspg.idea.grammar.psi.ConceptRuleTypes; -import org.openspg.idea.lang.parser.ConceptRuleParser; public final class ConceptRuleParserDefinition implements ParserDefinition { @@ -31,14 +31,13 @@ public Lexer createLexer(Project project) { @NotNull @Override public TokenSet getCommentTokens() { - return TokenSet.create(ConceptRuleTypes.COMMENT); + return TokenSet.create(ConceptRuleTypes.LINE_COMMENT, ConceptRuleTypes.BLOCK_COMMENT); } @NotNull @Override public TokenSet getWhitespaceTokens() { - //return TokenSet.WHITE_SPACE; - return TokenSet.create(TokenType.WHITE_SPACE, TokenType.BAD_CHARACTER); + return TokenSet.create(TokenType.WHITE_SPACE, TokenType.NEW_LINE_INDENT, TokenType.BAD_CHARACTER); } @NotNull diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/highlighter/ConceptRuleColorSettingsPage.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/highlighter/ConceptRuleColorSettingsPage.java index 4c8dac9..507e60b 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/highlighter/ConceptRuleColorSettingsPage.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/highlighter/ConceptRuleColorSettingsPage.java @@ -7,37 +7,58 @@ import com.intellij.openapi.options.colors.ColorSettingsPage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.openspg.idea.conceptRule.ConceptRuleBundle; import org.openspg.idea.conceptRule.demo.ConceptRuleDemo; import org.openspg.idea.schema.SchemaIcons; import javax.swing.*; import java.util.Map; +import static org.openspg.idea.conceptRule.highlighter.ConceptRuleHighlightingColors.*; + final class ConceptRuleColorSettingsPage implements ColorSettingsPage { private static final AttributesDescriptor[] DESCRIPTORS = new AttributesDescriptor[]{ - new AttributesDescriptor("Keywords", ConceptRuleHighlightingColors.KEYWORD), - new AttributesDescriptor("Comments//Block comment", ConceptRuleHighlightingColors.BLOCK_COMMENT), - new AttributesDescriptor("Comments//Line comment", ConceptRuleHighlightingColors.LINE_COMMENT), - new AttributesDescriptor("Error", ConceptRuleHighlightingColors.ERROR), - - new AttributesDescriptor("Namespace//Key", ConceptRuleHighlightingColors.NAMESPACE_KEY), - new AttributesDescriptor("Namespace//Value", ConceptRuleHighlightingColors.NAMESPACE_VALUE), - - new AttributesDescriptor("Concept rule//Pattern", ConceptRuleHighlightingColors.WRAPPER_PATTERN), - new AttributesDescriptor("Concept rule//Category", ConceptRuleHighlightingColors.WRAPPER_FIELD), - - new AttributesDescriptor("Number", ConceptRuleHighlightingColors.NUMBER), - new AttributesDescriptor("String", ConceptRuleHighlightingColors.STRING), - new AttributesDescriptor("Variables", ConceptRuleHighlightingColors.VARIABLES), - - new AttributesDescriptor("Braces and Operators//Braces", ConceptRuleHighlightingColors.BRACES), - new AttributesDescriptor("Braces and Operators//Brackets", ConceptRuleHighlightingColors.BRACKETS), - new AttributesDescriptor("Braces and Operators//Comma", ConceptRuleHighlightingColors.COMMA), - new AttributesDescriptor("Braces and Operators//Dot", ConceptRuleHighlightingColors.DOT), - new AttributesDescriptor("Braces and Operators//Operator sign", ConceptRuleHighlightingColors.OPERATION_SIGN), - new AttributesDescriptor("Braces and Operators//Parentheses", ConceptRuleHighlightingColors.PARENTHESES), - new AttributesDescriptor("Braces and Operators//Semicolon", ConceptRuleHighlightingColors.SEMICOLON), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.keywords"), KEYWORD), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.comments.block.comment"), BLOCK_COMMENT), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.comments.line.comment"), LINE_COMMENT), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.error"), ERROR), + + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.namespace.key"), NAMESPACE_KEY), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.namespace.value"), NAMESPACE_VALUE), + + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.conceptRule.pattern"), WRAPPER_PATTERN), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.conceptRule.category"), WRAPPER_FIELD), + + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.number"), NUMBER), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.string"), STRING), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.variables"), VARIABLES), + + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.bracesAndOperators.braces"), BRACES), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.bracesAndOperators.brackets"), BRACKETS), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.bracesAndOperators.comma"), COMMA), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.bracesAndOperators.dot"), DOT), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.bracesAndOperators.operator.sign"), OPERATION_SIGN), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.bracesAndOperators.parentheses"), PARENTHESES), + new AttributesDescriptor( + ConceptRuleBundle.message("ConceptRuleColorSettings.bracesAndOperators.semicolon"), SEMICOLON), }; @Override diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/highlighter/ConceptRuleSyntaxHighlighter.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/highlighter/ConceptRuleSyntaxHighlighter.java index 6238041..bdd75dd 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/highlighter/ConceptRuleSyntaxHighlighter.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/highlighter/ConceptRuleSyntaxHighlighter.java @@ -8,8 +8,8 @@ import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; +import org.openspg.idea.conceptRule.grammar.psi.ConceptRuleTypes; import org.openspg.idea.conceptRule.lexer.ConceptRuleLexerAdapter; -import org.openspg.idea.grammar.psi.ConceptRuleTypes; import java.util.HashMap; import java.util.Map; @@ -51,9 +51,11 @@ public ConceptRuleSyntaxHighlighter() { ourMap.put(ConceptRuleTypes.NAMESPACE_KEYWORD, ConceptRuleHighlightingColors.NAMESPACE_KEY); ourMap.put(ConceptRuleTypes.NAMESPACE_VALUE, ConceptRuleHighlightingColors.NAMESPACE_VALUE); - ourMap.put(ConceptRuleTypes.RULE_WRAPPER_TEXT, ConceptRuleHighlightingColors.WRAPPER_PATTERN); ourMap.put(ConceptRuleTypes.WRAPPER_RULE_KEYWORD, ConceptRuleHighlightingColors.WRAPPER_FIELD); + ourMap.put(ConceptRuleTypes.LINE_COMMENT, ConceptRuleHighlightingColors.LINE_COMMENT); + ourMap.put(ConceptRuleTypes.BLOCK_COMMENT, ConceptRuleHighlightingColors.BLOCK_COMMENT); + ourMap.put(TokenType.BAD_CHARACTER, HighlighterColors.BAD_CHARACTER); } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/lexer/ConceptRuleLexerAdapter.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/lexer/ConceptRuleLexerAdapter.java index 7eba8a5..a99faed 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/lexer/ConceptRuleLexerAdapter.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/lexer/ConceptRuleLexerAdapter.java @@ -1,7 +1,7 @@ package org.openspg.idea.conceptRule.lexer; import com.intellij.lexer.FlexAdapter; -import org.openspg.idea.lang.lexer.ConceptRuleLexer; +import org.openspg.idea.conceptRule.lang.lexer.ConceptRuleLexer; public class ConceptRuleLexerAdapter extends FlexAdapter { diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/ConceptRuleFile.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/ConceptRuleFile.java index 398fe06..e372b85 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/ConceptRuleFile.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/ConceptRuleFile.java @@ -22,7 +22,7 @@ public FileType getFileType() { @Override public String toString() { - return "OpenSPG Schema Rule File"; + return "OpenSPG Concept Rule File"; } } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/impl/BasicElementTypes.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/impl/BasicElementTypes.java index ab85a63..d4f97ba 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/impl/BasicElementTypes.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/impl/BasicElementTypes.java @@ -1,7 +1,7 @@ package org.openspg.idea.conceptRule.psi.impl; import com.intellij.psi.tree.TokenSet; -import org.openspg.idea.grammar.psi.ConceptRuleTypes; +import org.openspg.idea.conceptRule.grammar.psi.ConceptRuleTypes; public interface BasicElementTypes extends ConceptRuleTypes { @@ -30,6 +30,5 @@ public interface BasicElementTypes extends ConceptRuleTypes { TokenSet BASIC_INTEGER_LITERALS = TokenSet.create(INTEGER_LITERAL); TokenSet BASIC_REAL_LITERALS = TokenSet.create(FLOAT_LITERAL); TokenSet BASIC_STRING_LITERALS = TokenSet.create(STRING_LITERAL); - TokenSet BASIC_TEXT_LITERALS = TokenSet.create(STRING_LITERAL); } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/impl/ConceptRulePsiImplUtil.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/impl/ConceptRulePsiImplUtil.java index 48fa7ca..1b799cd 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/impl/ConceptRulePsiImplUtil.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/psi/impl/ConceptRulePsiImplUtil.java @@ -1,10 +1,7 @@ package org.openspg.idea.conceptRule.psi.impl; import org.apache.commons.lang3.StringUtils; -import org.openspg.idea.lang.psi.ConceptRuleNamespace; -import org.openspg.idea.lang.psi.ConceptRuleNodePattern; -import org.openspg.idea.lang.psi.ConceptRulePredicatedDefine; -import org.openspg.idea.lang.psi.ConceptRuleRuleWrapper; +import org.openspg.idea.conceptRule.lang.psi.*; import java.util.List; @@ -17,13 +14,6 @@ public static String getValue(ConceptRuleNamespace element) { return element.getNamespaceValue().getText(); } - // ============================================ - // ConceptRuleRuleWrapper methods - // - public static String getLabel(ConceptRuleRuleWrapper element) { - return element.getRuleWrapperHead().getRuleWrapperTitle().getText(); - } - // ============================================ // ConceptRulePredicatedDefine methods // @@ -43,4 +33,26 @@ public static String getMinorLabel(ConceptRulePredicatedDefine element) { return element.getFullEdgePointingRight().getText().trim() + nodePatterns.get(1).getText(); } + // ============================================ + // ConceptRuleIdentifier methods + // + public static String getLabel(ConceptRuleIdentifier element) { + String label = element.getText(); + label = StringUtils.unwrap(label, "`"); + label = StringUtils.unwrap(label, "'"); + label = StringUtils.unwrap(label, "\""); + return label; + } + + // ============================================ + // ConceptRuleIdentifier methods + // + public static String getLabel(ConceptRuleConceptInstanceId element) { + String label = element.getText(); + label = StringUtils.unwrap(label, "`"); + label = StringUtils.unwrap(label, "'"); + label = StringUtils.unwrap(label, "\""); + return label; + } + } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/ConceptRuleStructureAwareNavbar.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/ConceptRuleStructureAwareNavbar.java index 554fd3d..31d6780 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/ConceptRuleStructureAwareNavbar.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/ConceptRuleStructureAwareNavbar.java @@ -5,9 +5,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.openspg.idea.conceptRule.ConceptRuleLanguage; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleNamespace; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleRuleWrapper; import org.openspg.idea.conceptRule.psi.ConceptRuleFile; -import org.openspg.idea.lang.psi.ConceptRuleNamespace; -import org.openspg.idea.lang.psi.ConceptRuleRuleWrapper; import org.openspg.idea.schema.SchemaIcons; import javax.swing.*; @@ -22,20 +22,21 @@ protected Language getLanguage() { @Override public @Nullable String getPresentableText(Object object) { - if (object instanceof ConceptRuleFile) { - return ((ConceptRuleFile) object).getName(); + if (object instanceof ConceptRuleFile file) { + return file.getName(); } - if (object instanceof ConceptRuleNamespace) { - return ((ConceptRuleNamespace) object) + if (object instanceof ConceptRuleNamespace namespace) { + return namespace .getNamespaceValue() .getText(); } - if (object instanceof ConceptRuleRuleWrapper) { - return ((ConceptRuleRuleWrapper) object) + if (object instanceof ConceptRuleRuleWrapper ruleWrapper) { + //TODO + return ruleWrapper .getRuleWrapperHead() - .getRuleWrapperTitle() + .getRuleWrapperPattern() .getText(); } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/ConceptRuleStructureViewModel.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/ConceptRuleStructureViewModel.java index 1ce03ea..c05d5cd 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/ConceptRuleStructureViewModel.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/ConceptRuleStructureViewModel.java @@ -8,8 +8,8 @@ import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleRuleWrapper; import org.openspg.idea.conceptRule.structureView.viewElement.ConceptRuleFileStructureViewElement; -import org.openspg.idea.lang.psi.SchemaEntityInfo; public class ConceptRuleStructureViewModel extends StructureViewModelBase implements StructureViewModel.ElementInfoProvider { @@ -37,7 +37,7 @@ public boolean isAlwaysLeaf(StructureViewTreeElement element) { @Override protected Class @NotNull [] getSuitableClasses() { return new Class[]{ - SchemaEntityInfo.class, + ConceptRuleRuleWrapper.class, }; } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleCreateActionStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleCreateActionStructureViewElement.java index 5854705..32ae55f 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleCreateActionStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleCreateActionStructureViewElement.java @@ -3,7 +3,7 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.util.treeView.smartTree.TreeElement; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.ConceptRuleCreateAction; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleCreateAction; import org.openspg.idea.schema.SchemaIcons; diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleFileStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleFileStructureViewElement.java index 048a962..801122d 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleFileStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleFileStructureViewElement.java @@ -4,7 +4,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.ConceptRuleRuleWrapper; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleRuleWrapper; import java.util.ArrayList; import java.util.List; diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleRuleWrapperStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleRuleWrapperStructureViewElement.java index bad6b04..838bb25 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleRuleWrapperStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleRuleWrapperStructureViewElement.java @@ -3,15 +3,13 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.util.treeView.smartTree.TreeElement; import com.intellij.psi.util.PsiTreeUtil; -import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.ConceptRuleRuleWrapper; -import org.openspg.idea.lang.psi.ConceptRuleRuleWrapperBody; -import org.openspg.idea.lang.psi.ConceptRuleTheDefineStructure; +import org.openspg.idea.conceptRule.lang.psi.*; import org.openspg.idea.schema.SchemaIcons; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import java.util.stream.Stream; public class ConceptRuleRuleWrapperStructureViewElement extends AbstractConceptRuleStructureViewElement { @@ -22,7 +20,7 @@ public ConceptRuleRuleWrapperStructureViewElement(ConceptRuleRuleWrapper element @Override public String getNullableAlphaSortKey() { - return myElement.getLabel(); + return myElement.getRuleWrapperHead().getRuleWrapperPattern().getText(); } @Override @@ -30,25 +28,48 @@ protected PresentationData createPresentation(ConceptRuleRuleWrapper element) { List labels = new ArrayList<>(); List locations = new ArrayList<>(); - Stream.of(element.getLabel().split(":")) - .map(label -> Stream.of(label.split("/")) - .map(String::trim) - .map(x -> StringUtils.unwrap(x, "`")) - .map(x -> StringUtils.unwrap(x, "'")) - .map(x -> StringUtils.unwrap(x, "\"")) - .toList()) - .forEach(texts -> { - if (!texts.isEmpty()) { - labels.add(texts.get(0)); + myElement.getRuleWrapperHead() + .getRuleWrapperPattern() + .getLabelExpressionList() + .stream() + .flatMap(x -> x.getLabelNameList().stream()) + .flatMap(labelNameElement -> { + if (labelNameElement.getEntityType() != null) { + return Stream.of(labelNameElement.getEntityType()); } - if (texts.size() > 1) { - locations.add(texts.get(1)); + return labelNameElement.getConceptNameList().stream(); + }) + .forEach(psiElement -> { + if (psiElement instanceof ConceptRuleEntityType entityType) { + String label = entityType.getIdentifierList() + .stream() + .map(ConceptRuleIdentifier::getLabel) + .collect(Collectors.joining(".")); + if (labels.isEmpty()) { + labels.add(label); + } else { + locations.add(label); + } + + } else if (psiElement instanceof ConceptRuleConceptName conceptName) { + String label = conceptName.getMetaConceptType() + .getIdentifierList() + .stream() + .map(ConceptRuleIdentifier::getLabel) + .collect(Collectors.joining(".")); + String instanceId = conceptName.getConceptInstanceId().getLabel(); + if (labels.isEmpty()) { + labels.add(label); + locations.add(instanceId); + } else { + locations.add("(" + label + " / " + instanceId + ")"); + } } }); return new PresentationData( - String.join("/", labels), - String.join("/", locations), + String.join(" ", labels), + String.join(" ", locations), SchemaIcons.Nodes.Entity, null ); diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheDefineStructureStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheDefineStructureStructureViewElement.java index 5c59460..df629da 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheDefineStructureStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheDefineStructureStructureViewElement.java @@ -5,10 +5,10 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.ConceptRuleCreateAction; -import org.openspg.idea.lang.psi.ConceptRuleTheDefineStructure; -import org.openspg.idea.lang.psi.ConceptRuleTheGraphStructure; -import org.openspg.idea.lang.psi.ConceptRuleTheRule; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleCreateAction; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleTheDefineStructure; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleTheGraphStructure; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleTheRule; import org.openspg.idea.schema.SchemaIcons; import java.util.ArrayList; diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheGraphStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheGraphStructureViewElement.java index 3380064..1f9393d 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheGraphStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheGraphStructureViewElement.java @@ -3,7 +3,7 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.util.treeView.smartTree.TreeElement; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.ConceptRuleTheGraphStructure; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleTheGraphStructure; import org.openspg.idea.schema.SchemaIcons; diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheRuleStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheRuleStructureViewElement.java index d17e70f..b51366a 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheRuleStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/conceptRule/structureView/viewElement/ConceptRuleTheRuleStructureViewElement.java @@ -3,7 +3,7 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.util.treeView.smartTree.TreeElement; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.ConceptRuleTheRule; +import org.openspg.idea.conceptRule.lang.psi.ConceptRuleTheRule; import org.openspg.idea.schema.SchemaIcons; diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaFindUsagesProvider.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaFindUsagesProvider.java index afb3b53..b0905f5 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaFindUsagesProvider.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaFindUsagesProvider.java @@ -8,8 +8,8 @@ import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.psi.SchemaEntityInfo; +import org.openspg.idea.schema.grammar.psi.SchemaTypes; +import org.openspg.idea.schema.lang.psi.SchemaEntityHead; import org.openspg.idea.schema.lexer.SchemaLexerAdapter; public class SchemaFindUsagesProvider implements FindUsagesProvider { @@ -19,7 +19,7 @@ public class SchemaFindUsagesProvider implements FindUsagesProvider { ); TokenSet identifiers = TokenSet.create( - SchemaTypes.ENTITY_NAME, SchemaTypes.ENTITY_CLASS, SchemaTypes.PROPERTY_CLASS + SchemaTypes.STRUCTURE_NAME ); @Override @@ -41,7 +41,7 @@ public String getHelpId(@NotNull PsiElement psiElement) { @NotNull @Override public String getType(@NotNull PsiElement element) { - if (element instanceof SchemaEntityInfo) { + if (element instanceof SchemaEntityHead) { return "Schema Entity"; } return ""; @@ -50,8 +50,8 @@ public String getType(@NotNull PsiElement element) { @NotNull @Override public String getDescriptiveName(@NotNull PsiElement element) { - if (element instanceof SchemaEntityInfo info) { - return info.getEntityName(); + if (element instanceof SchemaEntityHead head) { + return head.getBasicStructureDeclaration().getStructureNameDeclaration().getText(); } return ""; } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaFoldingBuilder.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaFoldingBuilder.java new file mode 100644 index 0000000..0f5d3a1 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaFoldingBuilder.java @@ -0,0 +1,149 @@ +package org.openspg.idea.schema; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.folding.FoldingBuilderEx; +import com.intellij.lang.folding.FoldingDescriptor; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.project.DumbAware; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.openspg.idea.schema.lang.psi.*; + +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Set; + +public class SchemaFoldingBuilder extends FoldingBuilderEx implements DumbAware { + + private final Set> adapters = Set.of( + new SchemaCommentFoldingAdapter(), + new SchemaEntityFoldingAdapter(), + new SchemaEntityMetaFoldingAdapter(), + new SchemaPropertyFoldingAdapter(), + new SchemaPropertyMetaFoldingAdapter(), + new SchemaSubPropertyFoldingAdapter(), + new SchemaPlainTextContentFoldingAdapter() + ); + + @Override + @SuppressWarnings("unchecked") + public FoldingDescriptor @NotNull [] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) { + Class[] classes = adapters + .stream() + .map(FoldingAdapter::getType) + .toArray(Class[]::new); + + return PsiTreeUtil.findChildrenOfAnyType(root, classes) + .stream() + .map(element -> new FoldingDescriptor(element, element.getTextRange())) + .toArray(FoldingDescriptor[]::new); + } + + @Override + public @Nullable String getPlaceholderText(@NotNull ASTNode node) { + PsiElement element = node.getPsi(); + for (FoldingAdapter adapter : adapters) { + if (adapter.getType().isInstance(element)) { + return adapter.getPlaceholderText(node, element); + } + } + throw new IllegalArgumentException("Unknown PsiElement type: " + element.getClass()); + } + + @Override + public boolean isCollapsedByDefault(@NotNull ASTNode node) { + return node.getPsi() instanceof PsiComment; + } + + public abstract static class FoldingAdapter { + + @SuppressWarnings("unchecked") + public Class getType() { + Type superClass = getClass().getGenericSuperclass(); + Type[] params = ((ParameterizedType) superClass).getActualTypeArguments(); + return (Class) params[0]; + } + + @SuppressWarnings("unchecked") + public String getPlaceholderText(@NotNull ASTNode node, @NotNull PsiElement element) { + assert getType().isInstance(element); + return getPlaceholderText((T) element); + } + + protected abstract String getPlaceholderText(T element); + } + + public static class SchemaCommentFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull PsiComment element) { + return "#..."; + } + } + + public static class SchemaEntityFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull SchemaEntity element) { + String placeHolder = element.getEntityHead().getText(); + if (!element.isBodyEmpty()) { + placeHolder += " {...}"; + } + return placeHolder; + } + } + + public static class SchemaEntityMetaFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull SchemaEntityMeta element) { + String placeHolder = element.getEntityMetaHead().getText(); + if (!element.isBodyEmpty()) { + placeHolder += " {...}"; + } + return placeHolder; + } + } + + public static class SchemaPropertyFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull SchemaProperty element) { + String placeHolder = element.getPropertyHead().getText(); + if (!element.isBodyEmpty()) { + placeHolder += " {...}"; + } + return placeHolder; + } + } + + public static class SchemaPropertyMetaFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull SchemaPropertyMeta element) { + String placeHolder = element.getPropertyMetaHead().getText(); + if (element.getPropertyMetaBody() != null && !element.getPropertyMetaBody().getSubPropertyList().isEmpty()) { + placeHolder += " {...}"; + } + return placeHolder; + } + } + + public static class SchemaSubPropertyFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull SchemaSubProperty element) { + String placeHolder = element.getSubPropertyHead().getText(); + if (element.getSubPropertyBody() != null && !element.getSubPropertyBody().getSubPropertyMetaList().isEmpty()) { + placeHolder += " {...}"; + } + return placeHolder; + } + } + + public static class SchemaPlainTextContentFoldingAdapter extends FoldingAdapter { + @Override + protected String getPlaceholderText(@NotNull SchemaPlainTextContent element) { + return "..."; + } + } + +} + diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaLineMarkerProvider.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaLineMarkerProvider.java index fbfe516..f213e11 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaLineMarkerProvider.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/SchemaLineMarkerProvider.java @@ -5,9 +5,10 @@ import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder; import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.psi.SchemaEntityInfo; +import org.openspg.idea.schema.lang.psi.SchemaEntityHead; +import org.openspg.idea.schema.lang.psi.SchemaVariableStructureType; import java.util.Collection; @@ -16,29 +17,34 @@ public final class SchemaLineMarkerProvider extends RelatedItemLineMarkerProvide @Override protected void collectNavigationMarkers(@NotNull PsiElement element, @NotNull Collection> result) { - if (element.getNode().getElementType() == SchemaTypes.ENTITY_CLASS) { - handleEntityType(element, result); + if (element instanceof SchemaEntityHead entityHead) { + handleEntityHead(entityHead, result); } } - private void handleEntityType(@NotNull PsiElement element, + private void handleEntityHead(@NotNull SchemaEntityHead entityHead, @NotNull Collection> result) { - String entityType = element.getText(); - if (entityType == null || entityType.isEmpty()) { - return; - } + String entityName = entityHead.getBasicStructureDeclaration().getName(); - Collection infos = PsiTreeUtil.findChildrenOfType(element.getContainingFile(), SchemaEntityInfo.class); - infos = infos.stream() - .filter(info -> entityType.equals(info.getEntityName())) - .toList(); - if (!infos.isEmpty()) { - NavigationGutterIconBuilder builder = - NavigationGutterIconBuilder.create(SchemaIcons.FILE) - .setTargets(infos) - .setTooltipText("Navigate to Schema entity"); - result.add(builder.createLineMarkerInfo(element)); - } + PsiElement[] targetElements = PsiTreeUtil.findChildrenOfType(entityHead.getContainingFile(), SchemaVariableStructureType.class) + .stream() + .filter(variableStructureType -> StringUtils.equals(entityName, variableStructureType.getText())) + .toArray(PsiElement[]::new); + + NavigationGutterIconBuilder builder = NavigationGutterIconBuilder + .create(SchemaIcons.FILE) + .setTargets(targetElements) + .setTooltipText(SchemaBundle.message("SchemaLineMarkerProvider.navigate.to.usages")); + + result.add( + builder.createLineMarkerInfo( + + entityHead.getBasicStructureDeclaration() + .getStructureNameDeclaration() + .getStructureName() + .getFirstChild() + ) + ); } } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/annotator/SchemaAnnotator.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/annotator/SchemaAnnotator.java index d83ed5e..67af27c 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/annotator/SchemaAnnotator.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/annotator/SchemaAnnotator.java @@ -1,52 +1,39 @@ package org.openspg.idea.schema.annotator; -import com.intellij.codeInspection.ProblemHighlightType; import com.intellij.lang.annotation.AnnotationHolder; import com.intellij.lang.annotation.Annotator; import com.intellij.lang.annotation.HighlightSeverity; import com.intellij.psi.PsiElement; -import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.psi.SchemaEntityInfo; -import org.openspg.idea.schema.highlighter.SchemaHighlightingColors; +import org.openspg.idea.schema.highlighter.annotator.SchemaEntityAliasNameHighlighting; +import org.openspg.idea.schema.highlighter.annotator.SchemaEntityNameHighlighting; +import org.openspg.idea.schema.highlighter.annotator.SchemaEntityTypeHighlighting; +import org.openspg.idea.schema.highlighter.annotator.SchemaHighlightAnnotator; -import java.util.Collection; +import java.util.HashSet; +import java.util.Set; final class SchemaAnnotator implements Annotator { - @Override - public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) { - if (element.getNode().getElementType() == SchemaTypes.ENTITY_CLASS - || element.getNode().getElementType() == SchemaTypes.PROPERTY_CLASS) { - this.handleEntityClass(element, holder); - } - } + private final Set myHighlightAnnotators; - private void handleEntityClass(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) { - String entityClass = element.getText(); + public SchemaAnnotator() { + myHighlightAnnotators = new HashSet<>(); + myHighlightAnnotators.add(new SchemaEntityNameHighlighting()); + myHighlightAnnotators.add(new SchemaEntityAliasNameHighlighting()); + myHighlightAnnotators.add(new SchemaEntityTypeHighlighting()); + } - SchemaEntityInfo target = null; - Collection infos = PsiTreeUtil.findChildrenOfType(element.getContainingFile(), SchemaEntityInfo.class); - for (SchemaEntityInfo info : infos) { - if (entityClass.equals(info.getEntityName())) { - target = info; - break; + @Override + public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) { + for (SchemaHighlightAnnotator highlightAnnotator : myHighlightAnnotators) { + if (highlightAnnotator.test(element)) { + holder.newAnnotation(HighlightSeverity.TEXT_ATTRIBUTES, element.getText()) + .range(element.getTextRange()) + .textAttributes(highlightAnnotator.getTextAttributesKey()) + .create(); } } - - if (target == null) { - holder.newAnnotation(HighlightSeverity.ERROR, "Unresolved schema") - .range(element.getTextRange()) - .highlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL) - //.withFix(new SchemaCreatePropertyQuickFix(entityType)) - .create(); - } else { - holder.newSilentAnnotation(HighlightSeverity.INFORMATION) - .range(element.getTextRange()) - .textAttributes(SchemaHighlightingColors.ENTITY_REFERENCE) - .create(); - } } } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/codeStyle/SchemaLanguageCodeStyleSettingsProvider.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/codeStyle/SchemaLanguageCodeStyleSettingsProvider.java index d92bc39..09fff70 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/codeStyle/SchemaLanguageCodeStyleSettingsProvider.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/codeStyle/SchemaLanguageCodeStyleSettingsProvider.java @@ -5,6 +5,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettingsCustomizable; import com.intellij.psi.codeStyle.LanguageCodeStyleSettingsProvider; import org.jetbrains.annotations.NotNull; +import org.openspg.idea.schema.SchemaBundle; import org.openspg.idea.schema.SchemaLanguage; import org.openspg.idea.schema.demo.SchemaDemo; @@ -20,9 +21,12 @@ public Language getLanguage() { public void customizeSettings(@NotNull CodeStyleSettingsCustomizable consumer, @NotNull SettingsType settingsType) { if (settingsType == SettingsType.BLANK_LINES_SETTINGS) { consumer.showStandardOptions("BLANK_LINES_AFTER_PACKAGE"); - consumer.renameStandardOption("BLANK_LINES_AFTER_PACKAGE", "After namespace"); consumer.showStandardOptions("BLANK_LINES_AFTER_IMPORTS"); - consumer.renameStandardOption("BLANK_LINES_AFTER_IMPORTS", "After schema type"); + + consumer.renameStandardOption("BLANK_LINES_AFTER_PACKAGE", + SchemaBundle.message("SchemaCodeStyleSettings.blankLines.after.namespace")); + consumer.renameStandardOption("BLANK_LINES_AFTER_IMPORTS", + SchemaBundle.message("SchemaCodeStyleSettings.blankLines.after.schema")); } else if (settingsType == SettingsType.SPACING_SETTINGS) { consumer.showStandardOptions("SPACE_AFTER_COMMA"); diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/completion/SchemaCompletionContributor.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/completion/SchemaCompletionContributor.java index a8e6100..a73520a 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/completion/SchemaCompletionContributor.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/completion/SchemaCompletionContributor.java @@ -3,26 +3,21 @@ import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.patterns.PlatformPatterns; -import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.psi.SchemaEntityInfo; - -import java.util.Collection; +import org.openspg.idea.schema.lang.psi.SchemaEntity; +import org.openspg.idea.schema.lang.psi.SchemaEntityHead; +import org.openspg.idea.schema.lang.psi.SchemaVariableStructureType; final class SchemaCompletionContributor extends CompletionContributor { SchemaCompletionContributor() { - this.extendCompletionForEntityClass(); - this.extendCompletionForPropertyClass(); - this.extendCompletionForBuiltinType(); + this.extendCompletionForEntityType(); } - private void extendCompletionForEntityClass() { - extend(CompletionType.BASIC, PlatformPatterns.psiElement(SchemaTypes.ENTITY_CLASS), - new CompletionProvider<>() { + private void extendCompletionForEntityType() { + extend(CompletionType.BASIC, PlatformPatterns.psiElement(SchemaVariableStructureType.class), new CompletionProvider<>() { public void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet resultSet) { @@ -32,46 +27,21 @@ public void addCompletions(@NotNull CompletionParameters parameters, resultSet.addElement(LookupElementBuilder.create("StandardType")); resultSet.addElement(LookupElementBuilder.create("BasicType")); - PsiElement inheritedElement = PsiTreeUtil.findSiblingBackward(parameters.getPosition(), SchemaTypes.INHERITED, null); - if (inheritedElement != null) { - SchemaEntityInfo currentInfo = (SchemaEntityInfo) PsiTreeUtil.findFirstParent(parameters.getPosition(), SchemaEntityInfo.class::isInstance); - String currentEntityName = currentInfo == null ? null : currentInfo.getEntityName(); - Collection infos = PsiTreeUtil.findChildrenOfType(parameters.getOriginalFile(), SchemaEntityInfo.class); - for (SchemaEntityInfo info : infos) { - if (info.getEntityName() != null && !info.getEntityName().equals(currentEntityName)) { - resultSet.addElement(LookupElementBuilder.create(info.getEntityName())); + // for inherited-structure + SchemaEntityHead currentHead = (SchemaEntityHead) PsiTreeUtil.findFirstParent(parameters.getPosition(), SchemaEntityHead.class::isInstance); + if (currentHead != null + && currentHead.getBasicStructureDeclaration().getStructureTypeDeclaration().getInheritedStructureTypeDeclaration() != null) { + String currentName = currentHead.getName(); + PsiTreeUtil.findChildrenOfType(parameters.getOriginalFile(), SchemaEntity.class).forEach(entity -> { + if (!entity.getName().equals(currentName)) { + resultSet.addElement(LookupElementBuilder.create(entity.getName())); } - } + }); } + } } ); } - private void extendCompletionForPropertyClass() { - extend(CompletionType.BASIC, PlatformPatterns.psiElement(SchemaTypes.PROPERTY_CLASS), new CompletionProvider<>() { - public void addCompletions(@NotNull CompletionParameters parameters, - @NotNull ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - resultSet.addElement(LookupElementBuilder.create("Text")); - resultSet.addElement(LookupElementBuilder.create("Float")); - resultSet.addElement(LookupElementBuilder.create("Integer")); - } - }); - } - - private void extendCompletionForBuiltinType() { - extend(CompletionType.SMART, PlatformPatterns.psiElement(SchemaTypes.BUILTIN_TYPE), new CompletionProvider<>() { - public void addCompletions(@NotNull CompletionParameters parameters, - @NotNull ProcessingContext context, - @NotNull CompletionResultSet resultSet) { - //PsiElement parentElement = parameters.getPosition().getParent(); - - //resultSet.addElement(LookupElementBuilder.create("Text")); - //resultSet.addElement(LookupElementBuilder.create("Float")); - //resultSet.addElement(LookupElementBuilder.create("Integer")); - } - }); - } - } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/formatter/SchemaBlock.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/formatter/SchemaBlock.java index 599561a..1106495 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/formatter/SchemaBlock.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/formatter/SchemaBlock.java @@ -3,67 +3,123 @@ import com.intellij.formatting.*; import com.intellij.lang.ASTNode; import com.intellij.psi.TokenType; +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.formatter.common.AbstractBlock; +import com.intellij.psi.formatter.common.SettingsAwareBlock; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.openspg.idea.lang.psi.SchemaPlainText; -import java.util.*; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; -import static org.openspg.idea.grammar.psi.SchemaTypes.EOL; +import static org.openspg.idea.schema.grammar.psi.SchemaTypes.*; -public class SchemaBlock extends AbstractBlock { +public class SchemaBlock extends AbstractBlock implements SettingsAwareBlock { - private static final Set NONBLOCK_ELEMENT_TYPES = new HashSet<>(Arrays.asList( - TokenType.WHITE_SPACE, EOL - )); + private static final Set NONBLOCK_ELEMENT_TYPES = Set.of( + TokenType.WHITE_SPACE, TokenType.NEW_LINE_INDENT, TokenType.BAD_CHARACTER + ); - private final SpacingBuilder spacingBuilder; + private static final Set INJECTED_ELEMENT_TYPES = Set.of( + PLAIN_TEXT_CONTENT + ); - protected SchemaBlock(@NotNull ASTNode node, @Nullable Wrap wrap, @Nullable Alignment alignment, SpacingBuilder spacingBuilder) { + private static final Set NORMAL_INDENT_BLOCK_ELEMENT_TYPES = Set.of( + ENTITY_META, PROPERTY, PROPERTY_META, SUB_PROPERTY, SUB_PROPERTY_META, PLAIN_TEXT_CONTENT + ); + + private final Indent myIndent; + private final SpacingBuilder mySpacingBuilder; + private final boolean myInjection; + + protected SchemaBlock( + @NotNull ASTNode node, + @Nullable Wrap wrap, + @Nullable Alignment alignment, + @Nullable SpacingBuilder spacingBuilder + ) { + this(node, wrap, alignment, spacingBuilder, null); + } + + protected SchemaBlock( + @NotNull ASTNode node, + @Nullable Wrap wrap, + @Nullable Alignment alignment, + @Nullable SpacingBuilder spacingBuilder, + @Nullable Indent indent + ) { super(node, wrap, alignment); - this.spacingBuilder = spacingBuilder; + mySpacingBuilder = spacingBuilder; + myIndent = indent; + + if (INJECTED_ELEMENT_TYPES.contains(node.getElementType())) { + this.myInjection = true; + this.setBuildIndentsOnly(false); + } else { + this.myInjection = false; + this.setBuildIndentsOnly(true); + } } @Override protected List buildChildren() { List blocks = new ArrayList<>(); - if (myNode.getPsi() instanceof SchemaPlainText) { + if (this.myInjection) { return blocks; } - ASTNode child = myNode.getFirstChildNode(); - while (child != null) { - IElementType type = child.getElementType(); - if (!NONBLOCK_ELEMENT_TYPES.contains(type)) { - blocks.add(new SchemaBlock( - child, - Wrap.createWrap(WrapType.NONE, false), - Alignment.createAlignment(), - spacingBuilder - )); + ASTNode[] children = myNode.getChildren(null); + for (ASTNode child : children) { + Block childBlock = buildBlock(child); + if (childBlock != null) { + blocks.add(childBlock); } - child = child.getTreeNext(); } return blocks; } + private Block buildBlock(ASTNode node) { + IElementType type = node.getElementType(); + if (NONBLOCK_ELEMENT_TYPES.contains(type)) { + return null; + } + + Indent indent = null; + if (NORMAL_INDENT_BLOCK_ELEMENT_TYPES.contains(type)) { + indent = Indent.getNormalIndent(); + } + + return new SchemaBlock( + node, + Wrap.createWrap(WrapType.NONE, true), + Alignment.createAlignment(), + mySpacingBuilder, + indent + ); + } + @Override public Indent getIndent() { - return Indent.getNoneIndent(); + return myIndent == null ? Indent.getNoneIndent() : myIndent; } @Nullable @Override public Spacing getSpacing(@Nullable Block firstChild, @NotNull Block secondChild) { - return spacingBuilder.getSpacing(this, firstChild, secondChild); + return mySpacingBuilder == null ? null : mySpacingBuilder.getSpacing(this, firstChild, secondChild); } @Override public boolean isLeaf() { - return myNode.getPsi() instanceof SchemaPlainText || myNode.getFirstChildNode() == null; + return myNode.getFirstChildNode() == null; } + @Override + public @NotNull CodeStyleSettings getSettings() { + return CodeStyleSettingsManager.getInstance().createSettings(); + } } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/formatter/SchemaFormattingModelBuilder.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/formatter/SchemaFormattingModelBuilder.java index 98bcc07..09698a0 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/formatter/SchemaFormattingModelBuilder.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/formatter/SchemaFormattingModelBuilder.java @@ -5,9 +5,10 @@ import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.grammar.psi.SchemaTypes; import org.openspg.idea.schema.SchemaLanguage; +import static org.openspg.idea.schema.grammar.psi.SchemaTypes.*; + public final class SchemaFormattingModelBuilder implements FormattingModelBuilder { @Override @@ -29,60 +30,35 @@ private static SpacingBuilder createSpaceBuilder(CodeStyleSettings settings) { CommonCodeStyleSettings commonSetting = settings.getCommonSettings(SchemaLanguage.INSTANCE.getID()); SpacingBuilder builder = new SpacingBuilder(settings, SchemaLanguage.INSTANCE); - builder = builder.after(SchemaTypes.NAMESPACE_MARKER).spaces(1); + builder = builder.after(NAMESPACE_KEYWORD).spaces(1); int blankLinesAfterNamespace = Math.max(0, commonSetting.BLANK_LINES_AFTER_PACKAGE) + 1; - builder = builder.after(TokenSet.create(SchemaTypes.NAMESPACE)) + builder = builder.after(TokenSet.create(NAMESPACE)) .spacing(0, 0, blankLinesAfterNamespace, false, 0); int blankLinesAfterEntity = Math.max(0, commonSetting.BLANK_LINES_AFTER_IMPORTS) + 1; - builder = builder.after(TokenSet.create(SchemaTypes.ENTITY)) + builder = builder.after(TokenSet.create(ENTITY)) .spacing(0, 0, blankLinesAfterEntity, false, 0); - builder = initSpaceBuilderByIndent(builder, commonSetting); + builder = builder + .before(TokenSet.create(DOUBLE_LBRACKET)) + .spacing(1, 1, 0, false, 0) + .after(TokenSet.create(DOUBLE_LBRACKET)) + .spacing(0, 0, 1, false, 0) + .around(TokenSet.create(DOUBLE_RBRACKET)) + .spacing(0, 0, 1, false, 0); + builder = initSpaceBuilderByComma(builder, commonSetting); builder = initSpaceBuilderByColon(builder, commonSetting); - boolean spaceAroundBrackets = commonSetting.SPACE_WITHIN_BRACKETS; - if (spaceAroundBrackets) { - builder = builder - .before(SchemaTypes.OPEN_BRACKET).spaces(1) - .after(SchemaTypes.CLOSE_BRACKET).spaces(1); - } else { - builder = builder - .around(SchemaTypes.OPEN_BRACKET).spaces(0) - .around(SchemaTypes.CLOSE_BRACKET).spaces(0); - } - - //.after(TokenSet.create( - // SchemaTypes.ENTITY_INFO, SchemaTypes.ENTITY_META, SchemaTypes.ENTITY_META_INFO, - // SchemaTypes.PROPERTY_INFO, SchemaTypes.PROPERTY_META_INFO, - // SchemaTypes.SUB_PROPERTY_INFO, SchemaTypes.SUB_PROPERTY_META, - // SchemaTypes.LINE_COMMENT - //)) - //.spacing(0, 0, 1, false, 0) - - return builder; - } - - private static SpacingBuilder initSpaceBuilderByIndent(SpacingBuilder builder, CommonCodeStyleSettings settings) { - CommonCodeStyleSettings.IndentOptions indentOptions = settings.getIndentOptions(); - int indentSize = indentOptions == null ? 4 : Math.max(1, indentOptions.INDENT_SIZE); - - builder = builder.after(SchemaTypes.INDENT_META) - .spaces(indentSize - 1) - - .after(SchemaTypes.INDENT_PROP) - .spaces(indentSize * 2 - 1) - - .after(SchemaTypes.INDENT_PROPMETA) - .spaces(indentSize * 3 - 1) - - .after(SchemaTypes.INDENT_SUBPROP) - .spaces(indentSize * 4 - 1) + // non-blank tokens + TokenSet nonBlankLineTokens = TokenSet.create( + ENTITY_HEAD, ENTITY_META, ENTITY_META_HEAD, PROPERTY, PROPERTY_HEAD, PROPERTY_META, PROPERTY_META_HEAD, SUB_PROPERTY + ); + builder = builder + .after(nonBlankLineTokens) + .spacing(0, 0, 1, false, 0); - .after(SchemaTypes.INDENT_SUBPROPMETA) - .spaces(indentSize * 5 - 1); return builder; } @@ -91,13 +67,13 @@ private static SpacingBuilder initSpaceBuilderByComma(SpacingBuilder builder, Co boolean spaceBeforeComma = settings.SPACE_BEFORE_COMMA; if (spaceBeforeComma && !spaceAfterComma) { - builder = builder.before(SchemaTypes.COMMA).spaces(1); + builder = builder.before(COMMA).spaces(1); } else if (spaceBeforeComma) { - builder = builder.around(SchemaTypes.COMMA).spaces(1); + builder = builder.around(COMMA).spaces(1); } else if (spaceAfterComma) { - builder = builder.after(SchemaTypes.COMMA).spaces(1); + builder = builder.after(COMMA).spaces(1); } else { - builder = builder.before(SchemaTypes.COMMA).spaces(0); + builder = builder.before(COMMA).spaces(0); } return builder; } @@ -106,7 +82,7 @@ private static SpacingBuilder initSpaceBuilderByColon(SpacingBuilder builder, Co boolean spaceAfterColon = settings.SPACE_AFTER_COLON; boolean spaceBeforeColon = settings.SPACE_BEFORE_COLON; - TokenSet tokenSet = TokenSet.create(SchemaTypes.COLON, SchemaTypes.INHERITED); + TokenSet tokenSet = TokenSet.create(COLON, RIGHT_ARROW); if (spaceBeforeColon && !spaceAfterColon) { builder = builder.before(tokenSet).spaces(1); } else if (spaceBeforeColon) { diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/grammar/SchemaParserDefinition.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/grammar/SchemaParserDefinition.java index 0f9616d..f31b458 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/grammar/SchemaParserDefinition.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/grammar/SchemaParserDefinition.java @@ -12,9 +12,9 @@ import com.intellij.psi.tree.IFileElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.parser.SchemaParser; import org.openspg.idea.schema.SchemaLanguage; +import org.openspg.idea.schema.grammar.psi.SchemaTypes; +import org.openspg.idea.schema.lang.parser.SchemaParser; import org.openspg.idea.schema.lexer.SchemaLexerAdapter; import org.openspg.idea.schema.psi.SchemaFile; @@ -37,8 +37,7 @@ public TokenSet getCommentTokens() { @NotNull @Override public TokenSet getWhitespaceTokens() { - //return TokenSet.WHITE_SPACE; - return TokenSet.create(TokenType.WHITE_SPACE, TokenType.BAD_CHARACTER); + return TokenSet.create(TokenType.WHITE_SPACE, TokenType.NEW_LINE_INDENT, TokenType.BAD_CHARACTER); } @NotNull diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaColorSettingsPage.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaColorSettingsPage.java index 85d3156..241cdee 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaColorSettingsPage.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaColorSettingsPage.java @@ -7,22 +7,32 @@ import com.intellij.openapi.options.colors.ColorSettingsPage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.openspg.idea.schema.SchemaBundle; import org.openspg.idea.schema.SchemaIcons; import org.openspg.idea.schema.demo.SchemaDemo; import javax.swing.*; import java.util.Map; +import static org.openspg.idea.schema.highlighter.SchemaHighlightingColors.*; + final class SchemaColorSettingsPage implements ColorSettingsPage { private static final AttributesDescriptor[] DESCRIPTORS = new AttributesDescriptor[]{ - new AttributesDescriptor("Base//Keywords", SchemaHighlightingColors.KEYWORD), - new AttributesDescriptor("Base//Operation", SchemaHighlightingColors.OPERATION_SIGN), - new AttributesDescriptor("Schema//Name", SchemaHighlightingColors.ENTITY_NAME), - new AttributesDescriptor("Schema//Alias name", SchemaHighlightingColors.ENTITY_ALIAS), - new AttributesDescriptor("Schema//Type", SchemaHighlightingColors.ENTITY_REFERENCE), - new AttributesDescriptor("Others//Comment", SchemaHighlightingColors.COMMENT), - new AttributesDescriptor("Others//Error", SchemaHighlightingColors.ERROR), + new AttributesDescriptor( + SchemaBundle.message("SchemaColorSettings.keywords"), KEYWORD), + new AttributesDescriptor( + SchemaBundle.message("SchemaColorSettings.operator.sign"), OPERATION_SIGN), + new AttributesDescriptor( + SchemaBundle.message("SchemaColorSettings.schema.name"), ENTITY_NAME), + new AttributesDescriptor( + SchemaBundle.message("SchemaColorSettings.schema.alias.name"), ENTITY_ALIAS), + new AttributesDescriptor( + SchemaBundle.message("SchemaColorSettings.schema.type"), ENTITY_REFERENCE), + new AttributesDescriptor( + SchemaBundle.message("SchemaColorSettings.comment"), COMMENT), + new AttributesDescriptor( + SchemaBundle.message("SchemaColorSettings.error"), ERROR), }; @Override diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaHighlightingColors.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaHighlightingColors.java index c7fda3e..8f44d80 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaHighlightingColors.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaHighlightingColors.java @@ -22,7 +22,7 @@ public class SchemaHighlightingColors { public static final TextAttributesKey ENTITY_NAME = TextAttributesKey.createTextAttributesKey("OpenSGP_SCHEMA_ENTITY_NAME", DefaultLanguageHighlighterColors.CLASS_NAME); public static final TextAttributesKey ENTITY_ALIAS = - TextAttributesKey.createTextAttributesKey("OpenSGP_SCHEMA_ENTITY_ALIAS_NAME", DefaultLanguageHighlighterColors.STRING); + TextAttributesKey.createTextAttributesKey("OpenSGP_SCHEMA_ENTITY_ALIAS", DefaultLanguageHighlighterColors.STRING); public static final TextAttributesKey ENTITY_REFERENCE = TextAttributesKey.createTextAttributesKey("OpenSGP_SCHEMA_ENTITY_REFERENCE", DefaultLanguageHighlighterColors.CLASS_REFERENCE); diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaSyntaxHighlighter.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaSyntaxHighlighter.java index 379bdf4..b280127 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaSyntaxHighlighter.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/SchemaSyntaxHighlighter.java @@ -2,17 +2,37 @@ import com.intellij.lexer.Lexer; +import com.intellij.openapi.editor.HighlighterColors; import com.intellij.openapi.editor.colors.TextAttributesKey; import com.intellij.openapi.fileTypes.SyntaxHighlighterBase; import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.grammar.psi.SchemaTypes; +import org.openspg.idea.conceptRule.grammar.psi.ConceptRuleTypes; import org.openspg.idea.schema.lexer.SchemaLexerAdapter; +import java.util.HashMap; +import java.util.Map; + +import static org.openspg.idea.schema.psi.impl.BasicElementTypes.BASIC_KEYWORD_BIT_SET; +import static org.openspg.idea.schema.psi.impl.BasicElementTypes.BASIC_OPERATION_BIT_SET; + public class SchemaSyntaxHighlighter extends SyntaxHighlighterBase { + private final Map ourMap; + + public SchemaSyntaxHighlighter() { + ourMap = new HashMap<>(); + + fillMap(ourMap, BASIC_KEYWORD_BIT_SET, SchemaHighlightingColors.KEYWORD); + fillMap(ourMap, BASIC_OPERATION_BIT_SET, SchemaHighlightingColors.OPERATION_SIGN); + + ourMap.put(ConceptRuleTypes.LINE_COMMENT, SchemaHighlightingColors.COMMENT); + + ourMap.put(TokenType.BAD_CHARACTER, HighlighterColors.BAD_CHARACTER); + } + @NotNull @Override public Lexer getHighlightingLexer() { @@ -21,58 +41,7 @@ public Lexer getHighlightingLexer() { @Override public TextAttributesKey @NotNull [] getTokenHighlights(IElementType tokenType) { -// IElementType iteratorType = tokenType; -// while (iteratorType instanceof ParentProviderElementType parentProviderElementType) { -// if (parentProviderElementType.getParents().size() == 1) { -// iteratorType = parentProviderElementType.getParents().iterator().next(); -// } -// } -// System.out.println(iteratorType.getDebugName()); - - if (tokenType.equals(SchemaTypes.NAMESPACE_MARKER) - || tokenType.equals(SchemaTypes.ENTITY_BUILTIN_CLASS) - || tokenType.equals(SchemaTypes.BUILTIN_TYPE) - || tokenType.equals(SchemaTypes.META_TYPE) - ) { - return pack(SchemaHighlightingColors.KEYWORD); - } - - if (tokenType.equals(SchemaTypes.COMMENT) || tokenType.equals(SchemaTypes.LINE_COMMENT)) { - return pack(SchemaHighlightingColors.COMMENT); - } - - if (tokenType.equals(SchemaTypes.COLON) - || tokenType.equals(SchemaTypes.INHERITED) - || tokenType.equals(SchemaTypes.COMMA) - || tokenType.equals(SchemaTypes.OPEN_BRACKET) - || tokenType.equals(SchemaTypes.CLOSE_BRACKET) - || tokenType.equals(SchemaTypes.OPEN_PLAIN_BLOCK) - || tokenType.equals(SchemaTypes.CLOSE_PLAIN_BLOCK) - ) { - return pack(SchemaHighlightingColors.OPERATION_SIGN); - } - - if (tokenType.equals(TokenType.BAD_CHARACTER)) { - return pack(SchemaHighlightingColors.ERROR); - } - - if (tokenType.equals(SchemaTypes.ENTITY_NAME)) { - return pack(SchemaHighlightingColors.ENTITY_NAME); - } - - if (tokenType.equals(SchemaTypes.ENTITY_ALIAS_NAME) - || tokenType.equals(SchemaTypes.PROPERTY_ALIAS_NAME) - ) { - return pack(SchemaHighlightingColors.ENTITY_ALIAS); - } - - if (tokenType.equals(SchemaTypes.PROPERTY_CLASS) - || tokenType.equals(SchemaTypes.ENTITY_CLASS) - ) { - return pack(SchemaHighlightingColors.ENTITY_REFERENCE); - } - - return pack(null); + return pack(ourMap.get(tokenType)); } } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaEntityAliasNameHighlighting.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaEntityAliasNameHighlighting.java new file mode 100644 index 0000000..4ec99ec --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaEntityAliasNameHighlighting.java @@ -0,0 +1,19 @@ +package org.openspg.idea.schema.highlighter.annotator; + +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.psi.PsiElement; +import org.openspg.idea.schema.highlighter.SchemaHighlightingColors; +import org.openspg.idea.schema.lang.psi.SchemaStructureAliasDeclaration; + +public class SchemaEntityAliasNameHighlighting implements SchemaHighlightAnnotator { + + @Override + public boolean test(PsiElement element) { + return element instanceof SchemaStructureAliasDeclaration; + } + + @Override + public TextAttributesKey getTextAttributesKey() { + return SchemaHighlightingColors.ENTITY_ALIAS; + } +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaEntityNameHighlighting.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaEntityNameHighlighting.java new file mode 100644 index 0000000..2b2824c --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaEntityNameHighlighting.java @@ -0,0 +1,19 @@ +package org.openspg.idea.schema.highlighter.annotator; + +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.psi.PsiElement; +import org.openspg.idea.schema.highlighter.SchemaHighlightingColors; +import org.openspg.idea.schema.lang.psi.SchemaStructureNameDeclaration; + +public class SchemaEntityNameHighlighting implements SchemaHighlightAnnotator { + + @Override + public boolean test(PsiElement element) { + return element instanceof SchemaStructureNameDeclaration; + } + + @Override + public TextAttributesKey getTextAttributesKey() { + return SchemaHighlightingColors.ENTITY_NAME; + } +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaEntityTypeHighlighting.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaEntityTypeHighlighting.java new file mode 100644 index 0000000..9220900 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaEntityTypeHighlighting.java @@ -0,0 +1,22 @@ +package org.openspg.idea.schema.highlighter.annotator; + +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import org.openspg.idea.schema.highlighter.SchemaHighlightingColors; +import org.openspg.idea.schema.lang.psi.SchemaStructureName; +import org.openspg.idea.schema.lang.psi.SchemaStructureTypeDeclaration; + +public class SchemaEntityTypeHighlighting implements SchemaHighlightAnnotator { + + @Override + public boolean test(PsiElement element) { + return element instanceof SchemaStructureName + && PsiTreeUtil.getParentOfType(element, SchemaStructureTypeDeclaration.class) != null; + } + + @Override + public TextAttributesKey getTextAttributesKey() { + return SchemaHighlightingColors.ENTITY_REFERENCE; + } +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaHighlightAnnotator.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaHighlightAnnotator.java new file mode 100644 index 0000000..398d792 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/highlighter/annotator/SchemaHighlightAnnotator.java @@ -0,0 +1,12 @@ +package org.openspg.idea.schema.highlighter.annotator; + +import com.intellij.openapi.editor.colors.TextAttributesKey; +import com.intellij.psi.PsiElement; + +public interface SchemaHighlightAnnotator { + + boolean test(PsiElement element); + + TextAttributesKey getTextAttributesKey(); + +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/injection/SchemaMultiHostInjector.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/injection/SchemaMultiHostInjector.java new file mode 100644 index 0000000..df3e0c4 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/injection/SchemaMultiHostInjector.java @@ -0,0 +1,33 @@ +package org.openspg.idea.schema.injection; + +import com.intellij.lang.injection.MultiHostInjector; +import com.intellij.lang.injection.MultiHostRegistrar; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.openspg.idea.conceptRule.ConceptRuleLanguage; +import org.openspg.idea.schema.lang.psi.SchemaPlainTextContent; + +import java.util.List; + +public final class SchemaMultiHostInjector implements MultiHostInjector { + + @Override + public void getLanguagesToInject(@NotNull MultiHostRegistrar registrar, @NotNull PsiElement context) { + if (context instanceof SchemaPlainTextContent content) { + registrar.startInjecting(ConceptRuleLanguage.INSTANCE) + .addPlace( + "", + "", + content, + TextRange.from(0, content.getTextLength()) + ) + .doneInjecting(); + } + } + + @Override + public @NotNull List> elementsToInjectIn() { + return List.of(SchemaPlainTextContent.class); + } +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/lexer/SchemaLexerAdapter.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/lexer/SchemaLexerAdapter.java index 3630250..ca82167 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/lexer/SchemaLexerAdapter.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/lexer/SchemaLexerAdapter.java @@ -1,7 +1,7 @@ package org.openspg.idea.schema.lexer; import com.intellij.lexer.FlexAdapter; -import org.openspg.idea.lang.lexer.SchemaLexer; +import org.openspg.idea.schema.lang.lexer.SchemaLexer; public class SchemaLexerAdapter extends FlexAdapter { diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/SchemaLanguageInjector.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/SchemaLanguageInjector.java new file mode 100644 index 0000000..5419c35 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/SchemaLanguageInjector.java @@ -0,0 +1,24 @@ +package org.openspg.idea.schema.psi; + +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.InjectedLanguagePlaces; +import com.intellij.psi.LanguageInjector; +import com.intellij.psi.PsiLanguageInjectionHost; +import org.jetbrains.annotations.NotNull; +import org.openspg.idea.conceptRule.ConceptRuleLanguage; +import org.openspg.idea.schema.lang.psi.SchemaPlainTextContent; + +public final class SchemaLanguageInjector implements LanguageInjector { + + @Override + public void getLanguagesToInject(@NotNull PsiLanguageInjectionHost host, @NotNull InjectedLanguagePlaces injectionPlacesRegistrar) { + if (host instanceof SchemaPlainTextContent content) { + injectionPlacesRegistrar.addPlace( + ConceptRuleLanguage.INSTANCE, + TextRange.from(0, content.getTextLength()), + "", + "" + ); + } + } +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/BasicElementTypes.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/BasicElementTypes.java new file mode 100644 index 0000000..76ae3c7 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/BasicElementTypes.java @@ -0,0 +1,23 @@ +package org.openspg.idea.schema.psi.impl; + +import com.intellij.psi.tree.TokenSet; +import org.openspg.idea.schema.grammar.psi.SchemaTypes; + + +public interface BasicElementTypes extends SchemaTypes { + + TokenSet BASIC_KEYWORD_BIT_SET = TokenSet.create( + AUTORELATE_KEYWORD, BASIC_TYPE_KEYWORD, CONCEPT_TYPE_KEYWORD, CONSTRAINT_KEYWORD, DESC_KEYWORD, ENTITY_TYPE_KEYWORD, + EVENT_TYPE_KEYWORD, FLOAT_KEYWORD, HYPERNYMP_PREDICATE_KEYWORD, INDEX_KEYWORD, INTEGER_KEYWORD, IS_A_KEYWORD, + LOCATE_AT_KEYWORD, MANNER_OF_KEYWORD, MULTI_VALUE_KEYWORD, NAMESPACE_KEYWORD, NOT_NULL_KEYWORD, PROPERTIES_KEYWORD, + REGULAR_KEYWORD, RELATIONS_KEYWORD, RULE_KEYWORD, SPREADABLE_KEYWORD, STANDARD_TYPE_KEYWORD, TEXT_AND_VECTOR_KEYWORD, + TEXT_KEYWORD, VECTOR_KEYWORD + ); + + TokenSet BASIC_OPERATION_BIT_SET = TokenSet.create( + RIGHT_ARROW, LPARENTH, RPARENTH, COMMA, COLON, DOT, DOUBLE_LBRACKET, DOUBLE_RBRACKET + ); + + TokenSet BASIC_STRING_LITERALS = TokenSet.create(STRING_LITERAL); + +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/SchemaPlainTextContentBase.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/SchemaPlainTextContentBase.java new file mode 100644 index 0000000..8bd3745 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/SchemaPlainTextContentBase.java @@ -0,0 +1,30 @@ +package org.openspg.idea.schema.psi.impl; + +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.intellij.lang.ASTNode; +import com.intellij.psi.ElementManipulators; +import com.intellij.psi.LiteralTextEscaper; +import com.intellij.psi.PsiLanguageInjectionHost; +import org.jetbrains.annotations.NotNull; + +public abstract class SchemaPlainTextContentBase extends ASTWrapperPsiElement implements PsiLanguageInjectionHost { + + public SchemaPlainTextContentBase(@NotNull ASTNode node) { + super(node); + } + + @Override + public boolean isValidHost() { + return true; + } + + @Override + public PsiLanguageInjectionHost updateText(@NotNull String text) { + return ElementManipulators.handleContentChange(this, text); + } + + @Override + public @NotNull LiteralTextEscaper createLiteralTextEscaper() { + return LiteralTextEscaper.createSimple(this); + } +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/SchemaPsiImplUtil.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/SchemaPsiImplUtil.java index fedbec5..8792103 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/SchemaPsiImplUtil.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/psi/impl/SchemaPsiImplUtil.java @@ -3,277 +3,252 @@ import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; -import com.intellij.psi.tree.IElementType; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.psi.*; -import org.openspg.idea.schema.resolve.SchemaEntityClassReference; -import org.openspg.idea.schema.resolve.SchemaEntityNameReference; -import org.openspg.idea.schema.resolve.SchemaPropertyClassReference; -import org.openspg.idea.schema.util.PsiUtils; +import org.openspg.idea.schema.grammar.psi.SchemaTypes; +import org.openspg.idea.schema.lang.psi.*; +import org.openspg.idea.schema.reference.SchemaVariableStructureTypeReference; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; public class SchemaPsiImplUtil { // ============================================ // SchemaNamespace methods // - public static String getValue(SchemaNamespace element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.TEXT); + public static String getNamespace(SchemaNamespace element) { + ASTNode node = element.getNode().findChildByType(SchemaTypes.IDENTIFIER); if (node != null) { return node.getText(); - } else { - return null; } + return null; } public static Map toJson(SchemaNamespace element) { Map result = new LinkedHashMap<>(); - result.put("value", getValue(element)); + result.put("value", getNamespace(element)); return result; } // ============================================ - // SchemaEntity methods + // SchemaBasicStructureDeclaration methods // - public static String getName(SchemaEntity element) { - return element.getEntityInfo().getEntityName(); + public static String getName(SchemaBasicStructureDeclaration element) { + return element.getStructureNameDeclaration().getText(); } - public static Map toJson(SchemaEntity element) { + public static Map toJson(SchemaBasicStructureDeclaration element) { Map result = new LinkedHashMap<>(); - SchemaEntityInfo info = element.getEntityInfo(); - result.put("name", getEntityName(info)); - result.put("aliasName", getEntityAliasName(info)); - result.put("types", getEntityClassList(info)); + result.put("name", getName(element)); + result.put("aliasName", unwrapText(element.getStructureAliasDeclaration().getText())); + result.put("types", element.getStructureTypeDeclaration().getTypes()); - result.put("properties", element.getEntityMetaList().stream() - .map(SchemaPsiImplUtil::toJson).collect(Collectors.toList())); return result; } // ============================================ - // SchemaEntityInfo methods + // SchemaBasicStructureDeclaration methods // - public static String getEntityName(SchemaEntityInfo element) { - ASTNode node = element.getReferencableEntityName().getNode().findChildByType(SchemaTypes.ENTITY_NAME); - if (node != null) { - return unwrapText(node.getText()); - } else { - return null; - } - } + public static List getTypes(SchemaStructureTypeDeclaration element) { + List types = new ArrayList<>(); - public static String getEntityAliasName(SchemaEntityInfo element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.ENTITY_ALIAS_NAME); - if (node != null) { - return unwrapText(node.getText()); - } else { - return null; + SchemaBasicStructureTypeDeclaration basicType = element.getBasicStructureTypeDeclaration(); + if (basicType != null) { + SchemaBasicStructureTypeVariable variable = basicType.getBasicStructureTypeVariable(); + types.add(variable.getText()); } - } - public static List getEntityClassList(SchemaEntityInfo element) { - List elements = PsiUtils.searchChildrenOfAnyType(element, true, SchemaTypes.ENTITY_CLASS, SchemaTypes.ENTITY_BUILTIN_CLASS); - return elements.stream().map(e -> unwrapText(e.getText())).collect(Collectors.toList()); - } - - public static String getName(SchemaEntityInfo element) { - return getEntityName(element); - } - - public static PsiElement setName(SchemaEntityInfo element, String newName) { - throw new IllegalArgumentException("unsupported operation. setName(SchemaEntityInfo element, String newName)"); - //System.out.println("TODO: SchemaPsiImplUtil.setName()"); - //ASTNode node = element.getNode().findChildByType(SchemaTypes.ENTITY_NAME); - //if (node != null) { - // System.out.println("TODO: SchemaPsiImplUtil.setName(SchemaEntityInfo element, String newName)"); - // //element.getNode().replaceChild(node, newKeyNode); - //} - //return element; - } + SchemaInheritedStructureTypeDeclaration inheritedType = element.getInheritedStructureTypeDeclaration(); + if (inheritedType != null) { + for (SchemaInheritedStructureTypeVariable variable : inheritedType.getInheritedStructureTypeVariableList()) { + types.add(variable.getText()); + } + } - public static PsiElement getNameIdentifier(SchemaEntityInfo element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.ENTITY_NAME); - return node != null ? node.getPsi(): null; + return types; } // ============================================ - // SchemaEntityNameReference methods + // SchemaVariableStructureType methods // - public static PsiReference getReference(SchemaReferencableEntityName element) { - return new SchemaEntityNameReference(element); + public static PsiReference getReference(SchemaVariableStructureType element) { + return new SchemaVariableStructureTypeReference(element); } // ============================================ - // SchemaReferencableEntityClass methods + // SchemaBasicPropertyDeclaration methods // - public static PsiReference getReference(SchemaReferencableEntityClass element) { - return new SchemaEntityClassReference(element); + public static String getName(SchemaBasicPropertyDeclaration element) { + return element.getPropertyNameDeclaration().getPropertyNameVariable().getText(); } - // ============================================ - // SchemaEntityMeta methods - // - public static Map toJson(SchemaEntityMeta element) { - Map result = new LinkedHashMap<>(); + public static String getValue(SchemaBasicPropertyDeclaration element) { + PsiElement sibling = element.getPropertyNameDeclaration().getNextSibling(); - SchemaEntityMetaInfo info = element.getEntityMetaInfo(); - result.put("name", getName(info)); - result.put("value", getValue(info)); + while (sibling != null && sibling.getNode().getElementType() != SchemaTypes.COLON) { + sibling = sibling.getNextSibling(); + } - result.put("children", element.getPropertyList().stream() - .map(SchemaPsiImplUtil::toJson).collect(Collectors.toList())); - return result; - } + if (sibling == null) { + return null; + } - // ============================================ - // SchemaEntityMetaInfo methods - // - public static String getName(SchemaEntityMetaInfo element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.META_TYPE); - return node != null ? node.getText(): null; - } + StringBuilder value = new StringBuilder(); + + sibling = sibling.getNextSibling(); + while (sibling != null) { + value.append(sibling.getText()); + sibling = sibling.getNextSibling(); + } - public static String getValue(SchemaEntityMetaInfo element) { - return unwrapText(PsiUtils.readPlainTextAfterNode(element, SchemaTypes.COLON)); + return value.toString().trim(); } - // ============================================ - // SchemaProperty methods - // - public static Map toJson(SchemaProperty element) { + public static Map toJson(SchemaBasicPropertyDeclaration element) { Map result = new LinkedHashMap<>(); - SchemaPropertyInfo info = element.getPropertyInfo(); - result.put("name", getPropertyName(info)); - result.put("aliasName", getPropertyAliasName(info)); - result.put("types", getPropertyClassList(info)); + result.put("name", getName(element)); + result.put("value", unwrapText(getValue(element))); - result.put("properties", element.getPropertyMetaList().stream() - .map(SchemaPsiImplUtil::toJson).collect(Collectors.toList())); return result; } // ============================================ - // SchemaPropertyInfo methods + // SchemaEntity methods // - public static String getPropertyName(SchemaPropertyInfo element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.PROPERTY_NAME); - return node != null ? node.getText(): null; + public static String getName(SchemaEntity element) { + return element.getEntityHead().getName(); } - public static String getPropertyAliasName(SchemaPropertyInfo element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.PROPERTY_ALIAS_NAME); - return node != null ? node.getText(): null; + public static boolean isBodyEmpty(SchemaEntity element) { + return element.getEntityBody() == null || element.getEntityBody().getEntityMetaList().isEmpty(); } - public static List getPropertyClassList(SchemaPropertyInfo element) { - List elements = PsiUtils.searchChildrenOfAnyType(element, true, SchemaTypes.PROPERTY_CLASS, SchemaTypes.BUILTIN_TYPE); - return elements.stream().map(e -> unwrapText(e.getText())).collect(Collectors.toList()); + public static Map toJson(SchemaEntity element) { + Map result = element.getEntityHead().getBasicStructureDeclaration().toJson(); + if (element.getEntityBody() != null) { + result.put("properties", element.getEntityBody() + .getEntityMetaList() + .stream() + .map(SchemaPsiImplUtil::toJson) + .toList() + ); + } + return result; } // ============================================ - // SchemaReferencablePropertyClass methods + // SchemaEntityHead methods // - public static PsiReference getReference(SchemaReferencablePropertyClass element) { - return new SchemaPropertyClassReference(element); + public static String getName(SchemaEntityHead element) { + return element.getBasicStructureDeclaration().getStructureNameDeclaration().getText(); } - // ============================================ - // SchemaPropertyMeta methods - // - public static Map toJson(SchemaPropertyMeta element) { - Map result = new LinkedHashMap<>(); - - SchemaPropertyMetaInfo info = element.getPropertyMetaInfo(); - result.put("name", getName(info)); - result.put("value", getValue(info)); + public static PsiElement setName(SchemaEntityHead element, String newName) { + throw new IllegalArgumentException("unsupported operation. setName(SchemaEntityHead element, String newName)"); + } - result.put("children", element.getSubPropertyList().stream() - .map(SchemaPsiImplUtil::toJson).collect(Collectors.toList())); - return result; + public static PsiElement getNameIdentifier(SchemaEntityHead element) { + return element.getBasicStructureDeclaration().getStructureNameDeclaration(); } + // ============================================ - // SchemaPropertyInfoMeta methods + // SchemaEntityMeta methods // - public static String getName(SchemaPropertyMetaInfo element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.META_TYPE); - return node != null ? node.getText(): null; + public static boolean isBodyEmpty(SchemaEntityMeta element) { + return element.getEntityMetaBody() == null || element.getEntityMetaBody().getPropertyList().isEmpty(); } - public static String getValue(SchemaPropertyMetaInfo element) { - return unwrapText(PsiUtils.readPlainTextAfterNode(element, SchemaTypes.COLON)); + public static Map toJson(SchemaEntityMeta element) { + Map result = element.getEntityMetaHead().getBasicPropertyDeclaration().toJson(); + if (element.getEntityMetaBody() != null) { + result.put("children", element.getEntityMetaBody() + .getPropertyList() + .stream() + .map(SchemaPsiImplUtil::toJson) + .toList() + ); + } + return result; } // ============================================ - // SchemaSubProperty methods + // SchemaProperty methods // - public static Map toJson(SchemaSubProperty element) { - Map result = new LinkedHashMap<>(); - - SchemaSubPropertyInfo info = element.getSubPropertyInfo(); - result.put("name", getPropertyName(info)); - result.put("alaisName", getPropertyAliasName(info)); - result.put("types", getPropertyClassList(info)); + public static boolean isBodyEmpty(SchemaProperty element) { + return element.getPropertyBody() == null || element.getPropertyBody().getPropertyMetaList().isEmpty(); + } - result.put("properties", element.getSubPropertyMetaList().stream() - .map(SchemaPsiImplUtil::toJson).collect(Collectors.toList())); + public static Map toJson(SchemaProperty element) { + Map result = element.getPropertyHead().getBasicStructureDeclaration().toJson(); + if (element.getPropertyBody() != null) { + result.put("properties", element.getPropertyBody() + .getPropertyMetaList() + .stream() + .map(SchemaPsiImplUtil::toJson) + .toList() + ); + } return result; } // ============================================ - // SchemaSubPropertyInfo methods + // SchemaPropertyMeta methods // - public static String getPropertyName(SchemaSubPropertyInfo element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.PROPERTY_NAME); - return node != null ? node.getText(): null; - } - - public static String getPropertyAliasName(SchemaSubPropertyInfo element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.PROPERTY_ALIAS_NAME); - return node != null ? node.getText(): null; + public static Map toJson(SchemaPropertyMeta element) { + Map result = element.getPropertyMetaHead().getBasicPropertyDeclaration().toJson(); + if (element.getPropertyMetaBody() != null) { + result.put("children", element.getPropertyMetaBody() + .getSubPropertyList() + .stream() + .map(SchemaPsiImplUtil::toJson) + .toList() + ); + } + return result; } - public static List getPropertyClassList(SchemaSubPropertyInfo element) { - List classList = new ArrayList<>(); - for (PsiElement child : element.getChildren()) { - IElementType type = child.getNode().getElementType(); - if (type == SchemaTypes.BUILTIN_TYPE || type == SchemaTypes.PROPERTY_CLASS) { - classList.add(unwrapText(child.getText())); - } + // ============================================ + // SchemaSubProperty methods + // + public static Map toJson(SchemaSubProperty element) { + Map result = element.getSubPropertyHead().getBasicStructureDeclaration().toJson(); + if (element.getSubPropertyBody() != null) { + result.put("properties", element.getSubPropertyBody() + .getSubPropertyMetaList() + .stream() + .map(SchemaPsiImplUtil::toJson) + .toList() + ); } - return classList; + return result; } // ============================================ // SchemaSubPropertyMeta methods // - public static String getName(SchemaSubPropertyMeta element) { - ASTNode node = element.getNode().findChildByType(SchemaTypes.META_TYPE); - return node != null ? node.getText(): null; - } - - public static String getValue(SchemaSubPropertyMeta element) { - return unwrapText(PsiUtils.readPlainTextAfterNode(element, SchemaTypes.COLON)); - } - public static Map toJson(SchemaSubPropertyMeta element) { - Map result = new LinkedHashMap<>(); - result.put("name", getName(element)); - result.put("value", getValue(element)); - return result; + return element.getBasicPropertyDeclaration().toJson(); } + + // ============================================ + // SchemaPlainTextBlock methods + // +// public static TextRange getInjectTextRange(SchemaPlainTextBlock element) { +// System.out.println(element.getFirstChild().getText()); +// System.out.println(element.getLastChild().getText()); +// int start = element.getFirstChild().getTextLength(); +// int end = element.getTextLength() - element.getLastChild().getTextLength(); +// System.out.println(element.getTextLength()); +// return TextRange.create(start, end); +// } // ============================================ public static String unwrapText(String text) { - if (text == null) { + if (text == null || text.length() < 2) { return null; } @@ -286,6 +261,10 @@ public static String unwrapText(String text) { return text.substring(1, text.length() - 1); } - return text.isEmpty() ? null: text; + if (text.startsWith("`") && text.endsWith("`")) { + return text.substring(1, text.length() - 1); + } + + return text.isEmpty() ? null : text; } } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/reference/SchemaVariableStructureTypeReference.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/reference/SchemaVariableStructureTypeReference.java new file mode 100644 index 0000000..da0ef02 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/reference/SchemaVariableStructureTypeReference.java @@ -0,0 +1,49 @@ +package org.openspg.idea.schema.reference; + +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElementResolveResult; +import com.intellij.psi.PsiPolyVariantReferenceBase; +import com.intellij.psi.ResolveResult; +import com.intellij.psi.util.PsiTreeUtil; +import org.apache.commons.lang3.StringUtils; +import org.jetbrains.annotations.NotNull; +import org.openspg.idea.schema.SchemaIcons; +import org.openspg.idea.schema.lang.psi.*; + +public class SchemaVariableStructureTypeReference extends PsiPolyVariantReferenceBase { + + private final String myEntityName; + + public SchemaVariableStructureTypeReference(@NotNull SchemaVariableStructureType element) { + super(element, new TextRange(0, element.getTextLength())); + this.myEntityName = element.getText(); + } + + @Override + public ResolveResult @NotNull [] multiResolve(boolean incompleteCode) { + return PsiTreeUtil.findChildrenOfType(myElement.getContainingFile(), SchemaEntity.class) + .stream() + .map(SchemaEntity::getEntityHead) + .map(SchemaEntityHead::getBasicStructureDeclaration) + .map(SchemaBasicStructureDeclaration::getStructureNameDeclaration) + .map(SchemaStructureNameDeclaration::getStructureName) + .filter(x -> StringUtils.equals(x.getText(), this.myEntityName)) + .map(PsiElementResolveResult::new) + .toArray(ResolveResult[]::new); + } + + @Override + public Object @NotNull [] getVariants() { + return PsiTreeUtil.getChildrenOfTypeAsList(myElement.getContainingFile(), SchemaEntity.class) + .stream() + .map(x -> LookupElementBuilder + .create(x) + .withIcon(SchemaIcons.FILE) + .withTypeText(x.getContainingFile().getName()) + ) + .toArray(LookupElement[]::new); + } + +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/resolve/SchemaEntityClassReference.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/resolve/SchemaEntityClassReference.java deleted file mode 100644 index 05f4dbc..0000000 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/resolve/SchemaEntityClassReference.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.openspg.idea.schema.resolve; - -import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReferenceBase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.psi.SchemaEntity; -import org.openspg.idea.lang.psi.SchemaReferencableEntityClass; -import org.openspg.idea.schema.util.PsiUtils; - -public class SchemaEntityClassReference extends PsiReferenceBase { - - private final String entityName; - - public SchemaEntityClassReference(@NotNull SchemaReferencableEntityClass element) { - super(element, new TextRange(0, element.getTextLength())); - this.entityName = element.getText(); - } - - @Override - public @Nullable PsiElement resolve() { - final SchemaEntity entity = PsiUtils.findEntityByName(myElement.getContainingFile(), entityName); - if (entity != null) { - ASTNode node = entity.getEntityInfo().getReferencableEntityName().getNode().findChildByType(SchemaTypes.ENTITY_NAME); - assert node != null; - return node.getPsi(); - } - return null; - } - -} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/resolve/SchemaEntityNameReference.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/resolve/SchemaEntityNameReference.java deleted file mode 100644 index 46d5bc0..0000000 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/resolve/SchemaEntityNameReference.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.openspg.idea.schema.resolve; - -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupElementBuilder; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiElementResolveResult; -import com.intellij.psi.PsiPolyVariantReferenceBase; -import com.intellij.psi.ResolveResult; -import com.intellij.psi.util.PsiTreeUtil; -import org.jetbrains.annotations.NotNull; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.psi.SchemaEntity; -import org.openspg.idea.lang.psi.SchemaReferencableEntityName; -import org.openspg.idea.schema.SchemaIcons; -import org.openspg.idea.schema.util.PsiUtils; - -import java.util.ArrayList; -import java.util.List; - -public class SchemaEntityNameReference extends PsiPolyVariantReferenceBase { - - private final String entityName; - - public SchemaEntityNameReference(@NotNull SchemaReferencableEntityName element) { - super(element, new TextRange(0, element.getTextLength())); - this.entityName = element.getText(); - } - - @Override - public ResolveResult @NotNull [] multiResolve(boolean incompleteCode) { - List results = new ArrayList<>(); - - List elements = PsiUtils.searchChildrenOfAnyType( - myElement.getContainingFile(), - true, - SchemaTypes.ENTITY_CLASS, - SchemaTypes.PROPERTY_CLASS - ); - for (PsiElement element : elements) { - if (entityName.equals(element.getText())) { - results.add(new PsiElementResolveResult(element)); - } - } - - return results.toArray(new ResolveResult[0]); - } - - @Override - public Object @NotNull [] getVariants() { - List variants = new ArrayList<>(); - - List entities = PsiTreeUtil.getChildrenOfTypeAsList(myElement.getContainingFile(), SchemaEntity.class); - for (SchemaEntity entity : entities) { - variants.add(LookupElementBuilder - .create(entity) - .withIcon(SchemaIcons.FILE) - .withTypeText(entity.getContainingFile().getName()) - ); - } - return variants.toArray(); - } - -} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/resolve/SchemaPropertyClassReference.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/resolve/SchemaPropertyClassReference.java deleted file mode 100644 index d09a774..0000000 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/resolve/SchemaPropertyClassReference.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.openspg.idea.schema.resolve; - -import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiReferenceBase; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.psi.SchemaEntity; -import org.openspg.idea.lang.psi.SchemaReferencablePropertyClass; -import org.openspg.idea.schema.util.PsiUtils; - -public class SchemaPropertyClassReference extends PsiReferenceBase { - - private final String entityName; - - public SchemaPropertyClassReference(@NotNull SchemaReferencablePropertyClass element) { - super(element, new TextRange(0, element.getTextLength())); - this.entityName = element.getText(); - } - - @Override - public @Nullable PsiElement resolve() { - final SchemaEntity entity = PsiUtils.findEntityByName(myElement.getContainingFile(), entityName); - if (entity != null) { - ASTNode node = entity.getEntityInfo().getReferencableEntityName().getNode().findChildByType(SchemaTypes.ENTITY_NAME); - assert node != null; - return node.getPsi(); - } - return null; - } - -} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/spellchecker/SchemaSpellcheckingStrategy.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/spellchecker/SchemaSpellcheckingStrategy.java new file mode 100644 index 0000000..f32733b --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/spellchecker/SchemaSpellcheckingStrategy.java @@ -0,0 +1,29 @@ +package org.openspg.idea.schema.spellchecker; + +import com.intellij.lang.ASTNode; +import com.intellij.openapi.project.DumbAware; +import com.intellij.psi.PsiElement; +import com.intellij.psi.impl.source.tree.TreeUtil; +import com.intellij.psi.tree.TokenSet; +import com.intellij.spellchecker.tokenizer.SpellcheckingStrategy; +import com.intellij.spellchecker.tokenizer.Tokenizer; +import org.jetbrains.annotations.NotNull; +import org.openspg.idea.schema.grammar.psi.SchemaTypes; + +public class SchemaSpellcheckingStrategy extends SpellcheckingStrategy implements DumbAware { + + public static final TokenSet NO_SPELLCHECKING_TYPES = TokenSet.create( + SchemaTypes.PLAIN_TEXT_CONTENT + ); + + @Override + public @NotNull Tokenizer getTokenizer(PsiElement element) { + final ASTNode node = element.getNode(); + + if (TreeUtil.findParent(node, NO_SPELLCHECKING_TYPES) != null) { + return SpellcheckingStrategy.EMPTY_TOKENIZER; + } + + return SpellcheckingStrategy.TEXT_TOKENIZER; + } +} diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/SchemaStructureAwareNavbar.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/SchemaStructureAwareNavbar.java index 323e663..0ca6bfb 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/SchemaStructureAwareNavbar.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/SchemaStructureAwareNavbar.java @@ -4,8 +4,6 @@ import com.intellij.lang.Language; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.openspg.idea.lang.psi.SchemaEntityInfo; -import org.openspg.idea.schema.SchemaIcons; import org.openspg.idea.schema.SchemaLanguage; import org.openspg.idea.schema.psi.SchemaFile; @@ -25,9 +23,9 @@ protected Language getLanguage() { return ((SchemaFile) object).getName(); } - if (object instanceof SchemaEntityInfo) { - return ((SchemaEntityInfo) object).getEntityName(); - } +// if (object instanceof SchemaEntityInfo) { +// return ((SchemaEntityInfo) object).getEntityName(); +// } return null; } @@ -35,9 +33,9 @@ protected Language getLanguage() { @Override @Nullable public Icon getIcon(Object object) { - if (object instanceof SchemaEntityInfo) { - return SchemaIcons.Nodes.Entity; - } +// if (object instanceof SchemaEntityInfo) { +// return SchemaIcons.Nodes.Entity; +// } return null; } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/SchemaStructureViewModel.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/SchemaStructureViewModel.java index 67042fa..ac46168 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/SchemaStructureViewModel.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/SchemaStructureViewModel.java @@ -8,7 +8,7 @@ import com.intellij.psi.PsiFile; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.openspg.idea.lang.psi.SchemaEntityInfo; +import org.openspg.idea.schema.lang.psi.SchemaEntityHead; import org.openspg.idea.schema.structureView.viewElement.SchemaFileStructureViewElement; public class SchemaStructureViewModel extends StructureViewModelBase implements @@ -37,7 +37,7 @@ public boolean isAlwaysLeaf(StructureViewTreeElement element) { @Override protected Class @NotNull [] getSuitableClasses() { return new Class[]{ - SchemaEntityInfo.class, + SchemaEntityHead.class, }; } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaEntityMetaStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaEntityMetaStructureViewElement.java index cf3f416..e94961a 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaEntityMetaStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaEntityMetaStructureViewElement.java @@ -4,9 +4,9 @@ import com.intellij.ide.util.treeView.smartTree.TreeElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.SchemaEntityMeta; -import org.openspg.idea.lang.psi.SchemaProperty; import org.openspg.idea.schema.SchemaIcons; +import org.openspg.idea.schema.lang.psi.SchemaEntityMeta; +import org.openspg.idea.schema.lang.psi.SchemaProperty; import java.util.ArrayList; import java.util.List; @@ -19,15 +19,15 @@ public SchemaEntityMetaStructureViewElement(SchemaEntityMeta element) { @Override public String getNullableAlphaSortKey() { - return myElement.getEntityMetaInfo().getName(); + return myElement.getEntityMetaHead().getBasicPropertyDeclaration().getName(); } @Override protected PresentationData createPresentation(SchemaEntityMeta element) { return new PresentationData( - myElement.getEntityMetaInfo().getName(), - myElement.getEntityMetaInfo().getValue(), - element.getPropertyList().isEmpty() ? SchemaIcons.Nodes.EmptyMeta : SchemaIcons.Nodes.EntityMeta, + element.getEntityMetaHead().getBasicPropertyDeclaration().getName(), + element.getEntityMetaHead().getBasicPropertyDeclaration().getValue(), + element.getEntityMetaBody().getPropertyList().isEmpty() ? SchemaIcons.Nodes.EmptyMeta : SchemaIcons.Nodes.EntityMeta, null ); } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaEntityStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaEntityStructureViewElement.java index 54c9818..3f3ea29 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaEntityStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaEntityStructureViewElement.java @@ -4,10 +4,10 @@ import com.intellij.ide.util.treeView.smartTree.TreeElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.SchemaEntity; -import org.openspg.idea.lang.psi.SchemaEntityInfo; -import org.openspg.idea.lang.psi.SchemaEntityMeta; import org.openspg.idea.schema.SchemaIcons; +import org.openspg.idea.schema.lang.psi.SchemaEntity; +import org.openspg.idea.schema.lang.psi.SchemaEntityHead; +import org.openspg.idea.schema.lang.psi.SchemaEntityMeta; import java.util.ArrayList; import java.util.List; @@ -20,15 +20,15 @@ public SchemaEntityStructureViewElement(SchemaEntity element) { @Override public String getNullableAlphaSortKey() { - return myElement.getName(); + return myElement.getEntityHead().getBasicStructureDeclaration().getStructureNameDeclaration().getText(); } @Override protected PresentationData createPresentation(SchemaEntity element) { - SchemaEntityInfo info = element.getEntityInfo(); + SchemaEntityHead head = element.getEntityHead(); return new PresentationData( - info.getEntityName(), - info.getEntityAliasName(), + head.getBasicStructureDeclaration().getStructureNameDeclaration().getText(), + head.getBasicStructureDeclaration().getStructureAliasDeclaration().getText(), SchemaIcons.Nodes.Entity, null ); diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaFileStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaFileStructureViewElement.java index 184579d..6aa1798 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaFileStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaFileStructureViewElement.java @@ -4,7 +4,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.SchemaEntity; +import org.openspg.idea.schema.lang.psi.SchemaEntity; import java.util.ArrayList; import java.util.List; diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaPropertyMetaStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaPropertyMetaStructureViewElement.java index 82d125c..76a0b7a 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaPropertyMetaStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaPropertyMetaStructureViewElement.java @@ -4,9 +4,9 @@ import com.intellij.ide.util.treeView.smartTree.TreeElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.SchemaPropertyMeta; -import org.openspg.idea.lang.psi.SchemaSubProperty; import org.openspg.idea.schema.SchemaIcons; +import org.openspg.idea.schema.lang.psi.SchemaPropertyMeta; +import org.openspg.idea.schema.lang.psi.SchemaSubProperty; import java.util.ArrayList; import java.util.List; @@ -19,15 +19,15 @@ public SchemaPropertyMetaStructureViewElement(SchemaPropertyMeta element) { @Override public String getNullableAlphaSortKey() { - return myElement.getPropertyMetaInfo().getName(); + return myElement.getPropertyMetaHead().getBasicPropertyDeclaration().getName(); } @Override protected PresentationData createPresentation(SchemaPropertyMeta element) { return new PresentationData( - element.getPropertyMetaInfo().getName(), - element.getPropertyMetaInfo().getValue(), - element.getSubPropertyList().isEmpty() ? SchemaIcons.Nodes.EmptyMeta: SchemaIcons.Nodes.PropertyMeta, + element.getPropertyMetaHead().getBasicPropertyDeclaration().getName(), + element.getPropertyMetaHead().getBasicPropertyDeclaration().getValue(), + element.getPropertyMetaBody().getSubPropertyList().isEmpty() ? SchemaIcons.Nodes.EmptyMeta : SchemaIcons.Nodes.PropertyMeta, null ); } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaPropertyStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaPropertyStructureViewElement.java index 84c1b8d..5dfe2f3 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaPropertyStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaPropertyStructureViewElement.java @@ -4,9 +4,9 @@ import com.intellij.ide.util.treeView.smartTree.TreeElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.SchemaProperty; -import org.openspg.idea.lang.psi.SchemaPropertyMeta; import org.openspg.idea.schema.SchemaIcons; +import org.openspg.idea.schema.lang.psi.SchemaProperty; +import org.openspg.idea.schema.lang.psi.SchemaPropertyMeta; import java.util.ArrayList; import java.util.List; @@ -19,14 +19,14 @@ public SchemaPropertyStructureViewElement(SchemaProperty element) { @Override public String getNullableAlphaSortKey() { - return myElement.getPropertyInfo().getPropertyName(); + return myElement.getPropertyHead().getBasicStructureDeclaration().getStructureNameDeclaration().getText(); } @Override protected PresentationData createPresentation(SchemaProperty element) { return new PresentationData( - myElement.getPropertyInfo().getPropertyName(), - myElement.getPropertyInfo().getPropertyAliasName(), + element.getPropertyHead().getBasicStructureDeclaration().getStructureNameDeclaration().getText(), + element.getPropertyHead().getBasicStructureDeclaration().getStructureAliasDeclaration().getText(), SchemaIcons.Nodes.Property, null ); diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaSubPropertyMetaStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaSubPropertyMetaStructureViewElement.java index 7c289dc..9970bb4 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaSubPropertyMetaStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaSubPropertyMetaStructureViewElement.java @@ -3,8 +3,8 @@ import com.intellij.ide.projectView.PresentationData; import com.intellij.ide.util.treeView.smartTree.TreeElement; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.SchemaSubPropertyMeta; import org.openspg.idea.schema.SchemaIcons; +import org.openspg.idea.schema.lang.psi.SchemaSubPropertyMeta; public class SchemaSubPropertyMetaStructureViewElement extends AbstractSchemaStructureViewElement { @@ -14,14 +14,14 @@ public SchemaSubPropertyMetaStructureViewElement(SchemaSubPropertyMeta element) @Override public String getNullableAlphaSortKey() { - return myElement.getName(); + return myElement.getBasicPropertyDeclaration().getName(); } @Override protected PresentationData createPresentation(SchemaSubPropertyMeta element) { return new PresentationData( - myElement.getName(), - myElement.getValue(), + element.getBasicPropertyDeclaration().getName(), + element.getBasicPropertyDeclaration().getValue(), SchemaIcons.Nodes.SubPropertyMeta, null); } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaSubPropertyStructureViewElement.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaSubPropertyStructureViewElement.java index 466b0b3..1ad7443 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaSubPropertyStructureViewElement.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/structureView/viewElement/SchemaSubPropertyStructureViewElement.java @@ -4,9 +4,9 @@ import com.intellij.ide.util.treeView.smartTree.TreeElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.SchemaSubProperty; -import org.openspg.idea.lang.psi.SchemaSubPropertyMeta; import org.openspg.idea.schema.SchemaIcons; +import org.openspg.idea.schema.lang.psi.SchemaSubProperty; +import org.openspg.idea.schema.lang.psi.SchemaSubPropertyMeta; import java.util.ArrayList; import java.util.List; @@ -19,14 +19,14 @@ public SchemaSubPropertyStructureViewElement(SchemaSubProperty element) { @Override public String getNullableAlphaSortKey() { - return myElement.getSubPropertyInfo().getPropertyName(); + return myElement.getSubPropertyHead().getBasicStructureDeclaration().getStructureNameDeclaration().getText(); } @Override protected PresentationData createPresentation(SchemaSubProperty element) { return new PresentationData( - myElement.getSubPropertyInfo().getPropertyName(), - myElement.getSubPropertyInfo().getPropertyAliasName(), + myElement.getSubPropertyHead().getBasicStructureDeclaration().getStructureNameDeclaration().getText(), + myElement.getSubPropertyHead().getBasicStructureDeclaration().getStructureAliasDeclaration().getText(), SchemaIcons.Nodes.SubProperty, null ); diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/SchemaHtmlPanel.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/SchemaHtmlPanel.java index cb992aa..eadd127 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/SchemaHtmlPanel.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/SchemaHtmlPanel.java @@ -15,7 +15,7 @@ import org.cef.misc.BoolRef; import org.cef.network.CefRequest; import org.jetbrains.ide.BuiltInServerManager; -import org.openspg.idea.lang.psi.SchemaEntity; +import org.openspg.idea.schema.lang.psi.SchemaEntity; import org.openspg.idea.schema.ui.editor.jcef.FetchSchemaApiSupplier; import org.openspg.idea.schema.ui.editor.jcef.FetchThemeCssSupplier; import org.openspg.idea.schema.ui.editor.jcef.FocusEntityApiSupplier; @@ -126,7 +126,7 @@ public void activateEntity(String name) { private Boolean handleEntityActivated(List entities) { for (SchemaEntity entity : entities) { - System.out.println(entity.getName()); + System.out.println(entity.getEntityHead().getBasicStructureDeclaration().getStructureNameDeclaration().getText()); } return true; } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/SchemaSplitEditorProvider.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/SchemaSplitEditorProvider.java index b2e3ffa..5ff9754 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/SchemaSplitEditorProvider.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/SchemaSplitEditorProvider.java @@ -17,8 +17,8 @@ import com.intellij.psi.PsiManager; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.SchemaEntity; import org.openspg.idea.schema.SchemaFileType; +import org.openspg.idea.schema.lang.psi.SchemaEntity; import java.util.Objects; @@ -35,8 +35,7 @@ public boolean accept(@NotNull Project project, @NotNull VirtualFile file) { return isSchemaFileType(project, file); } - - @Override + // @Override public boolean acceptRequiresReadAction() { return false; } @@ -64,7 +63,7 @@ public void caretPositionChanged(@NotNull CaretEvent event) { return; } - String entityName = entity.getEntityInfo().getEntityName(); + String entityName = entity.getEntityHead().getBasicStructureDeclaration().getStructureNameDeclaration().getText(); if (entityName != null && !entityName.isBlank()) { previewEditor.activateEntity(entityName); } diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/jcef/FocusEntityApiSupplier.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/jcef/FocusEntityApiSupplier.java index e17546b..b09e6d8 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/jcef/FocusEntityApiSupplier.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/ui/editor/jcef/FocusEntityApiSupplier.java @@ -4,7 +4,7 @@ import com.alibaba.fastjson.TypeReference; import org.cef.network.CefRequest; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.lang.psi.SchemaEntity; +import org.openspg.idea.schema.lang.psi.SchemaEntity; import java.nio.charset.StandardCharsets; import java.util.HashMap; diff --git a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/util/PsiUtils.java b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/util/PsiUtils.java index 26a6e0b..8b2db9c 100644 --- a/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/util/PsiUtils.java +++ b/idea/spg-schema-idea-plugin/src/main/java/org/openspg/idea/schema/util/PsiUtils.java @@ -1,82 +1,24 @@ package org.openspg.idea.schema.util; -import com.intellij.lang.ASTNode; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; -import org.openspg.idea.grammar.psi.SchemaTypes; -import org.openspg.idea.lang.psi.SchemaEntity; -import org.openspg.idea.lang.psi.SchemaEntityInfo; -import org.openspg.idea.lang.psi.SchemaNamespace; -import org.openspg.idea.lang.psi.SchemaPlainText; +import org.openspg.idea.schema.lang.psi.SchemaEntity; +import org.openspg.idea.schema.lang.psi.SchemaEntityHead; +import org.openspg.idea.schema.lang.psi.SchemaNamespace; -import java.util.*; +import java.util.Collection; +import java.util.LinkedHashMap; +import java.util.Map; import java.util.stream.Collectors; public class PsiUtils { - public static @NotNull List searchChildrenOfAnyType( - @NotNull PsiElement psiRoot, - boolean recursion, - IElementType @NotNull ... types - ) { - List results = new ArrayList<>(); - searchChildrenOfAnyType(results, psiRoot, recursion, types); - return results; - } - - private static void searchChildrenOfAnyType( - @NotNull List result, - @NotNull PsiElement psiRoot, - boolean recursion, - IElementType @NotNull ... types - ) { - PsiElement psiChild = psiRoot.getFirstChild(); - while (psiChild != null) { - IElementType childType = psiChild.getNode().getElementType(); - for (IElementType type : types) { - if (childType.equals(type)) { - result.add(psiChild); - break; - } - } - - if (recursion) { - searchChildrenOfAnyType(result, psiChild, recursion, types); - } - psiChild = psiChild.getNextSibling(); - } - } - - public static String readPlainTextAfterNode( - @NotNull PsiElement element, - @NotNull IElementType nodeType - ) { - ASTNode node = element.getNode().findChildByType(nodeType); - if (node == null) { - return null; - } - - StringBuilder result = new StringBuilder(); - - PsiElement psiElement = node.getPsi().getNextSibling(); - while (psiElement != null) { - if (psiElement instanceof SchemaPlainText - || psiElement.getNode().getElementType() != SchemaTypes.COMMENT) { - result.append(psiElement.getText()); - } - psiElement = psiElement.getNextSibling(); - } - return result.toString(); - } - public static SchemaEntity findEntityByName(@NotNull PsiFile file, @NotNull String entityName) { Collection entities = PsiTreeUtil.findChildrenOfType(file, SchemaEntity.class); for (SchemaEntity entity : entities) { - SchemaEntityInfo info = entity.getEntityInfo(); - if (entityName.equals(info.getEntityName())) { + SchemaEntityHead head = entity.getEntityHead(); + if (entityName.equals(head.getBasicStructureDeclaration().getStructureNameDeclaration().getText())) { return entity; } } diff --git a/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/conceptRule/grammar/ConceptRule.bnf b/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/conceptRule/grammar/ConceptRule.bnf index 7e130a1..0280d07 100644 --- a/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/conceptRule/grammar/ConceptRule.bnf +++ b/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/conceptRule/grammar/ConceptRule.bnf @@ -1,15 +1,15 @@ { - parserClass="org.openspg.idea.lang.parser.ConceptRuleParser" + parserClass="org.openspg.idea.conceptRule.lang.parser.ConceptRuleParser" parserUtilClass="org.openspg.idea.conceptRule.grammar.ConceptRuleParserUtil" extends="com.intellij.extapi.psi.ASTWrapperPsiElement" psiClassPrefix="ConceptRule" psiImplClassSuffix="Impl" - psiPackage="org.openspg.idea.lang.psi" - psiImplPackage="org.openspg.idea.lang.psi.impl" + psiPackage="org.openspg.idea.conceptRule.lang.psi" + psiImplPackage="org.openspg.idea.conceptRule.lang.psi.impl" - elementTypeHolderClass="org.openspg.idea.grammar.psi.ConceptRuleTypes" + elementTypeHolderClass="org.openspg.idea.conceptRule.grammar.psi.ConceptRuleTypes" elementTypeClass="org.openspg.idea.conceptRule.ConceptRuleElementType" tokenTypeClass="org.openspg.idea.conceptRule.psi.ConceptRuleTokenType" @@ -18,19 +18,17 @@ ruleFile ::= item_* -private item_ ::= rule_wrapper | namespace | EOL | reserved_keywords | debug_items_ +private item_ ::= namespace | rule_wrapper | base_predicated_define | LINE_COMMENT | BLOCK_COMMENT | EOL | reserved_keywords | debug_items_ namespace ::= NAMESPACE_KEYWORD namespace_value { methods=[getValue] } -namespace_value ::= TEXT +namespace_value ::= UNESCAPED_SYMBOLIC_NAME | STRING_LITERAL | ESCAPED_SYMBOLIC_NAME -rule_wrapper ::= rule_wrapper_head (EOL WRAPPER_RULE_KEYWORD COLON EOL* OPEN_RULE_BLOCK rule_wrapper_body CLOSE_RULE_BLOCK)? { - methods=[getLabel] -} -rule_wrapper_head ::= rule_wrapper_title -rule_wrapper_title ::= (RULE_WRAPPER_TEXT|COLON)+ -rule_wrapper_body ::= base_predicated_define* +rule_wrapper ::= rule_wrapper_head (rule_wrapper_body)? +rule_wrapper_head ::= rule_wrapper_pattern +rule_wrapper_pattern ::= (label_expression (COLON label_expression)+) | (label_expression COLON) +rule_wrapper_body ::= WRAPPER_RULE_KEYWORD COLON OPEN_RULE_BLOCK base_predicated_define* CLOSE_RULE_BLOCK // all logic copy from file "openspg/KGDSL.g4" @@ -151,8 +149,8 @@ element_lookup ::= COLON ( label_expression | linked_edge )? element_pattern_declaration_and_filler ::= element_variable_declaration? element_lookup? element_pattern_where_clause? element_variable_declaration ::= element_variable element_variable ::= identifier -label_expression_lookup ::= VBAR label_name label_expression ::= label_name label_expression_lookup* +private label_expression_lookup ::= VBAR label_name // label_name ^_^ // `TaxOfRiskApp` @@ -163,8 +161,10 @@ label_name ::= combination_concept | concept_name | entity_type entity_type ::= identifier (DOT identifier)? concept_name ::= meta_concept_type DIV concept_instance_id meta_concept_type ::= identifier (DOT identifier)? -concept_instance_id ::= ESCAPED_SYMBOLIC_NAME -combination_concept ::= concept_name PLUS concept_name (PLUS concept_name)* +concept_instance_id ::= ESCAPED_SYMBOLIC_NAME { + methods=[getLabel] +} +private combination_concept ::= concept_name PLUS concept_name (PLUS concept_name)* linked_edge ::= function_expr @@ -286,9 +286,8 @@ graph_alias_element_list ::= graph_alias_with_property ( COMMA graph_alias_with_ // graph structure 定义部分 //############################################################################# -create_action_symbol::= ACTION_KEYWORD create_action ::= create_action_symbol LBRACE create_action_body* RBRACE - +create_action_symbol::= ACTION_KEYWORD create_action_body ::= add_node | add_edge add_edge ::= ADD_EDGE_KEYWORD LPARENTH add_edge_param COMMA add_edge_param COMMA add_type COMMA add_props RPARENTH @@ -373,10 +372,7 @@ absolute_value_expression ::= ABS_KEYWORD LPARENTH project_value_expression RPAR floor_function ::= FLOOR_KEYWORD LPARENTH project_value_expression RPARENTH ceiling_function ::= CEIL_KEYWORD LPARENTH project_value_expression RPARENTH - -separator ::= ( comment|whitespace )+ -whitespace ::= WHITESPACE -comment ::= Comment +separator ::= ( WHITESPACE )+ // 完整字符串定义 unbroken_character_string_literal ::= STRING_LITERAL @@ -385,11 +381,11 @@ unbroken_character_string_literal ::= STRING_LITERAL numeric_literal ::= FLOAT_LITERAL | INTEGER_LITERAL // 符号变量定义 -identifier ::= UNESCAPED_SYMBOLIC_NAME | ESCAPED_SYMBOLIC_NAME - -WHITESPACE ::= SPACE | TAB | LF | VT | FF | CR | FS | GS | RS | US | '\u1680' | '\u180e' | '\u2000' | '\u2001' | '\u2002' | '\u2003' | '\u2004' | '\u2005' | '\u2006' | '\u2008' | '\u2009' | '\u200a' | '\u2028' | '\u2029' | '\u205f' | '\u3000' | '\u00a0' | '\u2007' | '\u202f' | Comment +identifier ::= UNESCAPED_SYMBOLIC_NAME | ESCAPED_SYMBOLIC_NAME { + methods=[getLabel] +} -Comment ::= BLOCK_COMMENT | LINE_COMMENT +WHITESPACE ::= SPACE | TAB | LF | VT | FF | CR | FS | GS | RS | US | '\u1680' | '\u180e' | '\u2000' | '\u2001' | '\u2002' | '\u2003' | '\u2004' | '\u2005' | '\u2006' | '\u2008' | '\u2009' | '\u200a' | '\u2028' | '\u2029' | '\u205f' | '\u3000' | '\u00a0' | '\u2007' | '\u202f' // ################################################ Simplify DSL ################################################ diff --git a/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/conceptRule/lexer/ConceptRule.flex b/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/conceptRule/lexer/ConceptRule.flex index 95e278f..911f4b0 100644 --- a/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/conceptRule/lexer/ConceptRule.flex +++ b/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/conceptRule/lexer/ConceptRule.flex @@ -1,14 +1,13 @@ -package org.openspg.idea.lang.lexer; +package org.openspg.idea.conceptRule.lang.lexer; -import com.intellij.openapi.vfs.newvfs.persistent.log.VfsOperation;import com.intellij.psi.TokenType; -import com.intellij.psi.tree.IElementType;import com.intellij.ui.dsl.builder.AlignX; -import java.security.cert.CertificateRevokedException; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; /* Auto generated File */ %% %class ConceptRuleLexer -%implements com.intellij.lexer.FlexLexer, org.openspg.idea.grammar.psi.ConceptRuleTypes +%implements com.intellij.lexer.FlexLexer, org.openspg.idea.conceptRule.grammar.psi.ConceptRuleTypes %unicode %public %column @@ -39,7 +38,7 @@ import java.security.cert.CertificateRevokedException; // NB !(!a|b) is "a - b" // From the spec -IDENTIFIER = [:jletter:] [:jletterdigit:]* +IDENTIFIER = [:jletter:] [:jletterdigit:]* DIGIT = [0-9] DIGIT_OR_UNDERSCORE = [_0-9] @@ -60,7 +59,8 @@ HEX_FP_LITERAL = {HEX_SIGNIFICAND} {HEX_EXPONENT} HEX_SIGNIFICAND = 0 [Xx] ({HEX_DIGIT_OR_UNDERSCORE}+ "."? | {HEX_DIGIT_OR_UNDERSCORE}* "." {HEX_DIGIT_OR_UNDERSCORE}+) HEX_EXPONENT = [Pp] [+-]? {DIGIT_OR_UNDERSCORE}* -LINE_COMMENT = "//"[^\n]* +LINE = [^\n]* +LINE_COMMENT = "//"{LINE} BLOCK_COMMENT = "/"\*([^*]|\*+[^*/])*(\*+"/")? DOUBLE_QUOTED_STRING = \"([^\\\"\r\n]|\\[^\r\n])*\"? SINGLE_QUOTED_STRING = '([^\\'\r\n]|\\[^\r\n])*'? @@ -69,14 +69,6 @@ EOL = "\n" WHITE_SPACE_CHAR = [ \t\f] WHITE_SPACE = {WHITE_SPACE_CHAR}+ -LINE = [^\n]* - -// Schema spec: when a comment follows another syntax element, -// it must be separated from it by space characters. -// See http://www.yaml.org/spec/1.2/spec.html#comment - -COMMENT = "#"{LINE} - ESCAPED_SYMBOLIC_NAME = \`[^`]*\` //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -84,10 +76,7 @@ ESCAPED_SYMBOLIC_NAME = \`[^`]*\` //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Main states -%xstate RULE_STATE - -// Small technical one-token states -%xstate NAMESPACE_STATE, LINE_COMMENT_STATE, ERROR_STATE +%xstate TODO_STATE %% //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -99,75 +88,19 @@ ESCAPED_SYMBOLIC_NAME = \`[^`]*\` //------------------------------------------------------------------------------------------------------------------- // common: white-space, eol, comment - { + { {LINE_COMMENT} { return LINE_COMMENT; } {BLOCK_COMMENT} { return BLOCK_COMMENT; } {WHITE_SPACE} { return TokenType.WHITE_SPACE; } } - { - {EOL} { return EOL; } - ":" { return COLON; } - [Rr][Uu][Ll][Ee] { return WRAPPER_RULE_KEYWORD; } - - "namespace" { - goToState(NAMESPACE_STATE); - } - - "[[" { - yybegin(RULE_STATE); - return OPEN_RULE_BLOCK; - } - - {DOUBLE_QUOTED_STRING} { return RULE_WRAPPER_TEXT; } - {SINGLE_QUOTED_STRING} { return RULE_WRAPPER_TEXT; } - {ESCAPED_SYMBOLIC_NAME} { return RULE_WRAPPER_TEXT; } - [^\s\n\[\`\'\":]+ { return RULE_WRAPPER_TEXT; } - - [^] { - return TokenType.BAD_CHARACTER; - } -} -//------------------------------------------------------------------------------------------------------------------- - - -//------------------------------------------------------------------------------------------------------------------- -// namespace - { - "namespace" { - return NAMESPACE_KEYWORD; - } - - {DOUBLE_QUOTED_STRING} { return TEXT; } - {SINGLE_QUOTED_STRING} { return TEXT; } - {ESCAPED_SYMBOLIC_NAME} { return TEXT; } - [\w]+ { return TEXT; } - - {WHITE_SPACE} { - return TokenType.WHITE_SPACE; - } - - {EOL} { - yybegin(YYINITIAL); - return TokenType.WHITE_SPACE; - } - - [^] { - return TokenType.BAD_CHARACTER; - } -} -//------------------------------------------------------------------------------------------------------------------- - - //------------------------------------------------------------------------------------------------------------------- // rulue block - { - {EOL} { return TokenType.WHITE_SPACE; } + { + {EOL} { return TokenType.NEW_LINE_INDENT; } - "]]" { - yybegin(YYINITIAL); - return CLOSE_RULE_BLOCK; - } + "[[" { return OPEN_RULE_BLOCK; } + "]]" { return CLOSE_RULE_BLOCK; } {INTEGER_LITERAL} { return INTEGER_LITERAL; } {LONG_LITERAL} { return INTEGER_LITERAL; } @@ -178,15 +111,18 @@ ESCAPED_SYMBOLIC_NAME = \`[^`]*\` {ESCAPED_SYMBOLIC_NAME} { return ESCAPED_SYMBOLIC_NAME; } - "Action" { return ACTION_KEYWORD; } - "Define" { return DEFINE_KEYWORD; } - "DefinePriority" { return DEFINE_PRIORITY_KEYWORD; } - "Description" { return DESCRIPTION_KEYWORD; } - "GraphStructure" { return GRAPH_STRUCTURE_KEYWORD; } - "Rule" { return RULE_KEYWORD; } - "createEdgeInstance" { return ADD_EDGE_KEYWORD; } - "createNodeInstance" { return ADD_NODE_KEYWORD; } - "str_join" { return STR_JOIN_KEYWORD; } + "namespace" { return NAMESPACE_KEYWORD; } + "rule" { return WRAPPER_RULE_KEYWORD; } + + "Action" { return ACTION_KEYWORD; } + "Define" { return DEFINE_KEYWORD; } + "DefinePriority" { return DEFINE_PRIORITY_KEYWORD; } + "Description" { return DESCRIPTION_KEYWORD; } + "GraphStructure" { return GRAPH_STRUCTURE_KEYWORD; } + "Rule" { return RULE_KEYWORD; } + "createEdgeInstance" { return ADD_EDGE_KEYWORD; } + "createNodeInstance" { return ADD_NODE_KEYWORD; } + "str_join" { return STR_JOIN_KEYWORD; } [C][Oo][Nn][Ss][Tt][Rr][Aa][Ii][Nn][Tt] { diff --git a/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/schema/grammar/Schema.bnf b/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/schema/grammar/Schema.bnf index 21bb8b0..f944368 100644 --- a/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/schema/grammar/Schema.bnf +++ b/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/schema/grammar/Schema.bnf @@ -1,15 +1,15 @@ { - parserClass="org.openspg.idea.lang.parser.SchemaParser" + parserClass="org.openspg.idea.schema.lang.parser.SchemaParser" parserUtilClass="org.openspg.idea.schema.grammar.SchemaParserUtil" extends="com.intellij.extapi.psi.ASTWrapperPsiElement" psiClassPrefix="Schema" psiImplClassSuffix="Impl" - psiPackage="org.openspg.idea.lang.psi" - psiImplPackage="org.openspg.idea.lang.psi.impl" + psiPackage="org.openspg.idea.schema.lang.psi" + psiImplPackage="org.openspg.idea.schema.lang.psi.impl" - elementTypeHolderClass="org.openspg.idea.grammar.psi.SchemaTypes" + elementTypeHolderClass="org.openspg.idea.schema.grammar.psi.SchemaTypes" elementTypeClass="org.openspg.idea.schema.SchemaElementType" tokenTypeClass="org.openspg.idea.schema.psi.SchemaTokenType" @@ -18,70 +18,162 @@ schemaFile ::= item_* -private item_ ::= namespace|entity|COMMENT|LINE_COMMENT|indent_|EOL|TEXT +private item_ ::= namespace|entity|COMMENT|LINE_COMMENT|indents_ -private indent_ ::= INDENT|INDENT_META|INDENT_PROP|INDENT_PROPMETA|INDENT_SUBPROP|INDENT_SUBPROPMETA +private indents_ ::= INDENT|INDENT_META|INDENT_PROP|INDENT_PROPMETA|INDENT_SUBPROP|INDENT_SUBPROPMETA | DOUBLE_LBRACKET | DOUBLE_RBRACKET -plain_text ::= (OPEN_PLAIN_BLOCK (TEXT|EOL)* CLOSE_PLAIN_BLOCK) -private text_value ::= TEXT|plain_text -private EOL_ ::= (indent_)* EOL - -namespace ::= NAMESPACE_MARKER TEXT EOL_ { - methods=[getValue toJson] +namespace ::= NAMESPACE_KEYWORD IDENTIFIER { + methods=[getNamespace toJson] } -entity ::= entity_info EOL_* entity_meta* { +/** + * Basic Element declaration + * Example: + */ +// Example: +// Chunk(文本块): EntityType +// BigChunk("大文本块"): StandardType.Text +// MultiChunk("多个文本块") -> Chunk, BigChunk +basic_structure_declaration ::= structure_name_declaration LPARENTH structure_alias_declaration RPARENTH structure_type_declaration { methods=[getName toJson] } -entity_info ::= referencable_entity_name OPEN_BRACKET ENTITY_ALIAS_NAME CLOSE_BRACKET (basedEntityClass_|inheritedEntityClass_) { - mixin="org.openspg.idea.schema.psi.impl.SchemaNamedElementImpl" - implements="org.openspg.idea.schema.psi.SchemaNamedElement" - methods=[getEntityName getEntityAliasName getEntityClassList getName setName getNameIdentifier] -} -private basedEntityClass_ ::= COLON ENTITY_BUILTIN_CLASS -private inheritedEntityClass_ ::= INHERITED (referencable_entity_class COMMA)* (referencable_entity_class) COLON +structure_name_declaration ::= structure_name +structure_name ::= IDENTIFIER -referencable_entity_name ::= ENTITY_NAME { - methods=[getReference] -} +structure_alias_declaration ::= structure_alias +structure_alias ::= (IDENTIFIER | STRING_LITERAL | TEXT)+ -referencable_entity_class ::= ENTITY_BUILTIN_CLASS|ENTITY_CLASS { - methods=[getReference] +// : EntityType +// -> EntityType, ConceptType, MyType: +structure_type_declaration ::= basic_structure_type_declaration | inherited_structure_type_declaration { + methods=[getTypes] } -entity_meta ::= entity_meta_info EOL_* property* { - methods=[toJson] -} +basic_structure_type_declaration ::= COLON basic_structure_type_variable +basic_structure_type_variable ::= knowledge_structure_type | basic_structure_type | standard_structure_type | variable_structure_type + +inherited_structure_type_declaration ::= RIGHT_ARROW (inherited_structure_type_variable COMMA)* inherited_structure_type_variable COLON +inherited_structure_type_variable ::= knowledge_structure_type | standard_structure_type | variable_structure_type -entity_meta_info ::= INDENT_META META_TYPE COLON (BUILTIN_TYPE|text_value*)? { - methods=[getName getValue] +knowledge_structure_type ::= ENTITY_TYPE_KEYWORD | CONCEPT_TYPE_KEYWORD | EVENT_TYPE_KEYWORD | INDEX_TYPE_KEYWORD +basic_structure_type ::= (BASIC_TYPE_KEYWORD DOT)? (INTEGER_KEYWORD | FLOAT_KEYWORD | TEXT_KEYWORD) +standard_structure_type ::= STANDARD_TYPE_KEYWORD DOT IDENTIFIER +variable_structure_type ::= structure_name { + methods=[getReference] } -property ::= property_info EOL_* (property_meta EOL_*)* { - methods=[toJson] +/** + * Basic Key-Value Property declaration + * Example: + * desc: + * desc: 文本块 + * desc: [[ plain text... ]] + */ +basic_property_declaration ::= property_name_declaration COLON property_value_declaration? { + methods=[getName getValue toJson] } -property_info ::= (INDENT_PROP PROPERTY_NAME OPEN_BRACKET PROPERTY_ALIAS_NAME CLOSE_BRACKET COLON multiPropertyClass_) { - methods=[getPropertyName getPropertyAliasName getPropertyClassList] + +property_name_declaration ::= property_name_variable +property_name_variable ::= builtin_property_name | IDENTIFIER +builtin_property_name ::= DESC_KEYWORD | PROPERTIES_KEYWORD | RELATIONS_KEYWORD | HYPERNYMP_PREDICATE_KEYWORD | REGULAR_KEYWORD | SPREADABLE_KEYWORD | AUTORELATE_KEYWORD | CONSTRAINT_KEYWORD | RULE_KEYWORD | INDEX_KEYWORD + +private property_value_declaration ::= property_value_variable +private property_value_variable ::= builtin_property_value | plain_text_block | TEXT+ +private builtin_property_value ::= IS_A_KEYWORD | LOCATE_AT_KEYWORD | MANNER_OF_KEYWORD | TEXT_KEYWORD | VECTOR_KEYWORD | TEXT_AND_VECTOR_KEYWORD | SPARSE_VECTOR_KEYWORD | TEXT_AND_SPARSE_VECTOR_KEYWORD | NOT_NULL_KEYWORD | MULTI_VALUE_KEYWORD + +private plain_text_block ::= DOUBLE_LBRACKET plain_text_content? DOUBLE_RBRACKET +plain_text_content ::= PLAIN_TEXT+ { + mixin="org.openspg.idea.schema.psi.impl.SchemaPlainTextContentBase" + implements="com.intellij.psi.PsiLanguageInjectionHost" + methods=[getInjectTextRange] } -referencable_property_class ::= (BUILTIN_TYPE | PROPERTY_CLASS) { - methods=[getReference] + +/** + * Entity + * Example: + * Chunk(文本块): EntityType + * Chunk(文本块)->EntityType, ConceptType: + */ +entity ::= entity_head entity_body? { + methods=[getName isBodyEmpty toJson] } -private multiPropertyClass_ ::= (referencable_property_class COMMA)* referencable_property_class -property_meta ::= property_meta_info EOL_* (sub_property)* { +entity_head ::= basic_structure_declaration { + mixin="org.openspg.idea.schema.psi.impl.SchemaNamedElementImpl" + implements="org.openspg.idea.schema.psi.SchemaNamedElement" + methods=[getName setName getNameIdentifier] +} + +entity_body ::= entity_meta+ + +/** + * EntityMeta + * Example: + * Chunk(文本块): EntityType + * desc: 文本块 + */ +entity_meta ::= entity_meta_head entity_meta_body? { + methods=[isBodyEmpty toJson] +} +entity_meta_head ::= INDENT_META basic_property_declaration +entity_meta_body ::= property+ + +/** + * Property + * Example: + * Chunk(文本块): EntityType + * properties : + * belongTo(属于) : Story + */ +property ::= property_head property_body? { + methods=[isBodyEmpty toJson] +} +property_head ::= INDENT_PROP basic_structure_declaration +property_body ::= property_meta+ + +/** + * PropertyMeta + * Example: + * Chunk(文本块): EntityType + * properties : + * belongTo(属于) : Story + * desc: 属于 + */ +property_meta ::= property_meta_head property_meta_body? { methods=[toJson] } -property_meta_info ::= INDENT_PROPMETA META_TYPE COLON (BUILTIN_TYPE | text_value)* { - methods=[getName getValue] -} - -sub_property ::= sub_property_info EOL_* (sub_property_meta EOL_*)* { +property_meta_head ::= INDENT_PROPMETA basic_property_declaration +property_meta_body ::= sub_property+ + +/** + * SubProperty + * Example: + * Disease(疾病): EntityType + * properties: + * commonSymptom(常见症状): Symptom + * properties: + * desc(描述): Text + */ +sub_property ::= sub_property_head sub_property_body? { methods=[toJson] } -sub_property_info ::= (INDENT_SUBPROP PROPERTY_NAME OPEN_BRACKET PROPERTY_ALIAS_NAME CLOSE_BRACKET COLON multiPropertyClass_) { +sub_property_head ::= (INDENT_SUBPROP basic_structure_declaration) { methods=[getPropertyName getPropertyAliasName getPropertyClassList] } -sub_property_meta ::= (INDENT_SUBPROPMETA META_TYPE COLON (text_value | BUILTIN_TYPE)*) { +sub_property_body ::= sub_property_meta+ + +/** + * SubPropertyMeta + * Example: + * Disease(疾病): EntityType + * properties: + * commonSymptom(常见症状): Symptom + * properties: + * desc(描述): Text + * index: Text + */ +sub_property_meta ::= (INDENT_SUBPROPMETA basic_property_declaration) { methods=[getName getValue toJson] } + diff --git a/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/schema/lexer/Schema.flex b/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/schema/lexer/Schema.flex index 851e938..295d6ef 100644 --- a/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/schema/lexer/Schema.flex +++ b/idea/spg-schema-idea-plugin/src/main/lexer/org/openspg/idea/schema/lexer/Schema.flex @@ -1,4 +1,4 @@ -package org.openspg.idea.lang.lexer; +package org.openspg.idea.schema.lang.lexer; import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; @@ -7,7 +7,7 @@ import com.intellij.psi.tree.IElementType; %% %class SchemaLexer -%implements com.intellij.lexer.FlexLexer, org.openspg.idea.grammar.psi.SchemaTypes +%implements com.intellij.lexer.FlexLexer, org.openspg.idea.schema.grammar.psi.SchemaTypes %unicode %public %column @@ -27,10 +27,11 @@ import com.intellij.psi.tree.IElementType; private int myBraceCount = 0; private final int[] indentPos = {0, 0, 0, 0, 0, 0}; - private final int[] indentState = {ENTITY_STATE, ENTITYMETA_STATE, PROPERTY_STATE, PROPERTYMETA_STATE, PROPERTY_STATE, PROPERTYMETA_STATE}; + private final int[] indentState = {DEFINITION_STATE, KV_STATE, DEFINITION_STATE, KV_STATE, DEFINITION_STATE, KV_STATE}; private final IElementType[] indentToken = {INDENT, INDENT_META, INDENT_PROP, INDENT_PROPMETA, INDENT_SUBPROP, INDENT_SUBPROPMETA}; private final int maxIndentLevel = 6; private int currentIndentLevel = 0; + private int lastIndentLevel = 0; //------------------------------------------------------------------------------------------------------------------- @@ -75,23 +76,6 @@ import com.intellij.psi.tree.IElementType; return this.currentIndentLevel; } - //------------------------------------------------------------------------------------------------------------------- - private void openBrace() { - myBraceCount++; - if (myBraceCount != 0) { - yybegin(PLAIN_BLOCK_STATE); - } - } - - private void closeBrace() { - if (myBraceCount > 0) { - myBraceCount--; - } - if (myBraceCount == 0){ - yybegin(this.indentState[this.currentIndentLevel]); - } - } - private void goToState(int state) { yybegin(state); yypushback(yylength()); @@ -112,46 +96,36 @@ import com.intellij.psi.tree.IElementType; // From the spec ANY_CHAR = [^] -NS_CHAR = [^\n\t\r\ ] -NS_INDICATOR = [-?:,\(\)\[\]\{\}#&*!|>'\"%@`] - -EOL = "\n" -WHITE_SPACE_CHAR = [ \t] -WHITE_SPACE = {WHITE_SPACE_CHAR}+ +COMMENT = "#"{LINE} -NAME = [\w]+ +IDENTIFIER = [:jletter:] [:jletterdigit:]* +LETTERDIGIT = [:jletterdigit:]+ -LINE = [^\n]* +DOUBLE_QUOTED_STRING = \"([^\\\"\r\n]|\\[^\r\n])*\"? +SINGLE_QUOTED_STRING = '([^\\'\r\n]|\\[^\r\n])*'? +GRAVE_QUOTED_STRING = \`([^\\`\r\n]|\\[^\r\n])*\`? -// Schema spec: when a comment follows another syntax element, -// it must be separated from it by space characters. -// See http://www.yaml.org/spec/1.2/spec.html#comment -COMMENT = "#"{LINE} +PLAIN_TEXT_BLOCK = "[[" {ANY_CHAR}* "]]" -ESCAPE_SEQUENCE= \\[^\n] -DSTRING = \"([^\\\"]|{ESCAPE_SEQUENCE}|\\\n)*\" -STRING = '([^']|'')*' +WHITE_SPACE_CHAR = [ \t] +WHITE_SPACE = {WHITE_SPACE_CHAR}+ +EOL = "\n" -TEXT = {DSTRING}|{STRING}|{NAME} +BLANK_LINE = {WHITE_SPACE_CHAR}*{EOL} +LINE = [^\n]* +COMMENT = "#"{LINE} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////// STATES DECLARATIONS ////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Main states -%xstate LINE_START_STATE, BLOCK_STATE, PLAIN_BLOCK_STATE +%xstate LINE_START_STATE, INDENT_STATE // Small technical one-token states %xstate NAMESPACE_STATE, LINE_COMMENT_STATE, ERROR_STATE -%xstate ENTITY_STATE, WAITING_ENTITY_ALIAS_NAME_STATE, WAITING_ENTITY_CLASS_STATE -%xstate ENTITYMETA_STATE - -%xstate PROPERTY_STATE, WAITING_PROPERTY_ALIAS_NAME_STATE, WAITING_PROPERTY_CLASS_STATE -%xstate PROPERTYMETA_STATE - -%xstate WAITING_META_VALUE_STATE, WAITING_META_BUILTIN_VALUE_STATE, WAITING_META_TEXT_VALUE_STATE - +%xstate DEFINITION_STATE, KV_STATE, WAITING_VALUE_STATE, WAITING_BLOCK_VALUE_STATE %% //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////// RULES declarations //////////////////////////////////////////////////////////////////////////////////////////// @@ -166,12 +140,12 @@ TEXT = {DSTRING}|{STRING}|{NAME} goToState(NAMESPACE_STATE); } - {WHITE_SPACE}* {COMMENT} { - goToState(LINE_COMMENT_STATE); + {BLANK_LINE} { + return TokenType.NEW_LINE_INDENT; } - {EOL} { - return EOL; + {WHITE_SPACE}* {COMMENT} { + return LINE_COMMENT; } {WHITE_SPACE} { @@ -179,15 +153,28 @@ TEXT = {DSTRING}|{STRING}|{NAME} if (indentLevel < 0) { goToState(ERROR_STATE); } else { - yybegin(this.indentState[indentLevel]); - yypushback(yylength() - 1); - return this.indentToken[indentLevel]; +// yybegin(this.indentState[indentLevel]); +// yypushback(yylength()); +// return this.indentToken[indentLevel]; + yybegin(INDENT_STATE); + return TokenType.WHITE_SPACE; } } {ANY_CHAR} { this.currentIndentLevel = 0; - goToState(ENTITY_STATE); + goToState(DEFINITION_STATE); + } +} +//------------------------------------------------------------------------------------------------------------------- + +//------------------------------------------------------------------------------------------------------------------- +// indent: after whitespac + { + {ANY_CHAR} { + yybegin(this.indentState[this.currentIndentLevel]); + yypushback(yylength()); + return this.indentToken[this.currentIndentLevel]; } } //------------------------------------------------------------------------------------------------------------------- @@ -195,10 +182,10 @@ TEXT = {DSTRING}|{STRING}|{NAME} //------------------------------------------------------------------------------------------------------------------- // common: white-space, eol, comment - { + { {EOL} { yybegin(LINE_START_STATE); - return EOL; + return TokenType.NEW_LINE_INDENT; } {COMMENT} { @@ -213,16 +200,16 @@ TEXT = {DSTRING}|{STRING}|{NAME} { {EOL} { yybegin(LINE_START_STATE); - return EOL; - } - - {COMMENT} { - return LINE_COMMENT; + return TokenType.NEW_LINE_INDENT; } {WHITE_SPACE} { return TokenType.WHITE_SPACE; } + + {COMMENT} { + return LINE_COMMENT; + } } //------------------------------------------------------------------------------------------------------------------- @@ -230,12 +217,12 @@ TEXT = {DSTRING}|{STRING}|{NAME} //------------------------------------------------------------------------------------------------------------------- // namespace { - ("namespace") { - return NAMESPACE_MARKER; + "namespace" { + return NAMESPACE_KEYWORD; } - {TEXT} { - return TEXT; + {IDENTIFIER} { + return IDENTIFIER; } } //------------------------------------------------------------------------------------------------------------------- @@ -250,78 +237,35 @@ TEXT = {DSTRING}|{STRING}|{NAME} } //------------------------------------------------------------------------------------------------------------------- - -// common waiting state - { - {WHITE_SPACE}*{EOL} { - yybegin(LINE_START_STATE); - return EOL; - } - - {COMMENT} { - return COMMENT; - } - - {WHITE_SPACE} { - return TokenType.WHITE_SPACE; - } -} //------------------------------------------------------------------------------------------------------------------- +// definition-state +// name (alias-name) : type + { + {DOUBLE_QUOTED_STRING} { return STRING_LITERAL; } + {SINGLE_QUOTED_STRING} { return STRING_LITERAL; } + {GRAVE_QUOTED_STRING} { return STRING_LITERAL; } + + [Ee][Nn][Tt][Ii][Tt][Yy][Tt][Yy][Pp][Ee] { return ENTITY_TYPE_KEYWORD; } + [Cc][Oo][Nn][Cc][Ee][Pp][Tt][Tt][Yy][Pp][Ee] { return CONCEPT_TYPE_KEYWORD; } + [Ee][Vv][Ee][Nn][Tt][Tt][Yy][Pp][Ee] { return EVENT_TYPE_KEYWORD; } + [Ii][Nn][Dd][Ee][Xx][Tt][Yy][Pp][Ee] { return INDEX_TYPE_KEYWORD; } + [Ss][Tt][Aa][Nn][Dd][Aa][Rr][Dd][Tt][Yy][Pp][Ee] { return STANDARD_TYPE_KEYWORD; } + [Bb][Aa][Ss][Ii][Cc][Tt][Yy][Pp][Ee] { return BASIC_TYPE_KEYWORD; } + [Ii][Nn][Tt][Ee][Gg][Ee][Rr] { return INTEGER_KEYWORD; } + [Ff][Ll][Oo][Aa][Tt] { return FLOAT_KEYWORD; } + [Tt][Ee][Xx][Tt] { return TEXT_KEYWORD; } + + {IDENTIFIER} { return IDENTIFIER; } + {LETTERDIGIT} { return TEXT; } + + "->" { return RIGHT_ARROW; } + "(" { return LPARENTH; } + ")" { return RPARENTH; } + "," { return COMMA; } + ":" { return COLON; } + "." { return DOT; } - -//------------------------------------------------------------------------------------------------------------------- -// level-1 entity - { - [a-zA-Z0-9\.]+ { - return ENTITY_NAME; - } - - "(" {TEXT} ")" { - goToState(WAITING_ENTITY_ALIAS_NAME_STATE); - } - - [^\n] { - return TokenType.BAD_CHARACTER; - } -} - - { - "(" { - return OPEN_BRACKET; - } - - ")" { - yybegin(WAITING_ENTITY_CLASS_STATE); - return CLOSE_BRACKET; - } - - {TEXT} { - return ENTITY_ALIAS_NAME; - } -} - - { - "EntityType" | "ConceptType" | "EventType" | "StandardType" | "BasicType" { - return ENTITY_BUILTIN_CLASS; - } - - "," { - return COMMA; - } - - ":" { - return COLON; - } - - "->" { - return INHERITED; - } - - [a-zA-Z0-9]+ { - return ENTITY_CLASS; - } - - [^\n] { + {ANY_CHAR} { return TokenType.BAD_CHARACTER; } } @@ -329,166 +273,106 @@ TEXT = {DSTRING}|{STRING}|{NAME} //------------------------------------------------------------------------------------------------------------------- -// level-2 entity meta - { - "desc" | "properties" | "relations" | "hypernymPredicate" | "regular" | "spreadable" | "autoRelate" { - return META_TYPE; - } +// key-value-state + { + [Dd][Ee][Ss][Cc] { return DESC_KEYWORD; } + [Pp][Rr][Oo][Pp][Ee][Rr][Tt][Ii][Ee][Ss] { return PROPERTIES_KEYWORD; } + [Rr][Ee][Ll][Aa][Tt][Ii][Oo][Nn][Ss] { return RELATIONS_KEYWORD; } + [Hh][Yy][Pp][Ee][Rr][Nn][Yy][Mm][Pp][Rr][Ee][Dd][Ii][Cc][Aa][Tt][Ee] { return HYPERNYMP_PREDICATE_KEYWORD; } + [Rr][Ee][Gg][Uu][Ll][Aa][Rr] { return REGULAR_KEYWORD; } + [Ss][Pp][Rr][Ee][Aa][Dd][Aa][Bb][Ll][Ee] { return SPREADABLE_KEYWORD; } + [Aa][Uu][Tt][Oo][Rr][Ee][Ll][Aa][Tt][Ee] { return AUTORELATE_KEYWORD; } + [Cc][Oo][Nn][Ss][Tt][Rr][Aa][Ii][Nn][Tt] { return CONSTRAINT_KEYWORD; } + [Rr][Uu][Ll][Ee] { return RULE_KEYWORD; } + [Ii][Nn][Dd][Ee][Xx] { return INDEX_KEYWORD; } + + {IDENTIFIER} { return IDENTIFIER; } ":" { - yybegin(WAITING_META_VALUE_STATE); + yybegin(WAITING_VALUE_STATE); return COLON; } - [^\n] { + {ANY_CHAR} { return TokenType.BAD_CHARACTER; } } //------------------------------------------------------------------------------------------------------------------- - //------------------------------------------------------------------------------------------------------------------- -// level-3/5 property/subproperty - { - [a-zA-Z0-9#]+ { - return PROPERTY_NAME; - } - - "(" {TEXT} ")" { - goToState(WAITING_PROPERTY_ALIAS_NAME_STATE); +// waiting value + { + {PLAIN_TEXT_BLOCK} { + goToState(WAITING_BLOCK_VALUE_STATE); } - [^\n] { - return TokenType.BAD_CHARACTER; + [Ii][Ss][Aa] { + return IS_A_KEYWORD; } -} - - { - "(" { - return OPEN_BRACKET; + [Ll][Oo][Cc][Aa][Tt][Ee][Aa][Tt] { + return LOCATE_AT_KEYWORD; } - - ")" { - yybegin(WAITING_PROPERTY_CLASS_STATE); - return CLOSE_BRACKET; + [Mm][Aa][Nn][Nn][Ee][Rr][Oo][ff] { + return MANNER_OF_KEYWORD; } - - {TEXT} { - return PROPERTY_ALIAS_NAME; - } -} - - { - "EntityType" | "ConceptType" | "EventType" | "StandardType" | "Integer" | "Text" | "Float" { - return BUILTIN_TYPE; + [Tt][Ee][Xx][Tt] { + return TEXT_KEYWORD; } - - "," { - return COMMA; + [Vv][Ee][Cc][Tt][Oo][Rr] { + return VECTOR_KEYWORD; } - - ":" { - return COLON; + [Ss][Pp][Aa][Rr][Ss][Ee][Vv][Ee][Cc][Tt][Oo][Rr] { + return SPARSE_VECTOR_KEYWORD; } - - [a-zA-Z0-9\.]+ { - return PROPERTY_CLASS; + [Tt][Ee][Xx][Tt][Aa][Nn][Dd][Vv][Ee][Cc][Tt][Oo][Rr] { + return TEXT_AND_VECTOR_KEYWORD; } - - [^\n] { - return TokenType.BAD_CHARACTER; + [Tt][Ee][Xx][Tt][Aa][Nn][Dd][Ss][Pp][Aa][Rr][Ss][Ee][Vv][Ee][Cc][Tt][Oo][Rr] { + return TEXT_AND_SPARSE_VECTOR_KEYWORD; } -} -//------------------------------------------------------------------------------------------------------------------- - - -//------------------------------------------------------------------------------------------------------------------- -// level-4/6 property meta/subproperty meta - { - "desc" | "properties" | "constraint" | "rule" | "index" { - return META_TYPE; + [Nn][Oo][Tt][Nn][Uu][Ll][Ll] { + return NOT_NULL_KEYWORD; } - - ":" { - yybegin(WAITING_META_VALUE_STATE); - return COLON; + [Mm][Uu][Ll][Tt][Ii][Vv][Aa][Ll][Uu][Ee] { + return MULTI_VALUE_KEYWORD; } - [^\n] { - return TokenType.BAD_CHARACTER; + [^ \n]+ { + return TEXT; } } //------------------------------------------------------------------------------------------------------------------- - //------------------------------------------------------------------------------------------------------------------- -// common meta value - { - {EOL} { - yybegin(LINE_START_STATE); - return EOL; - } - - {WHITE_SPACE} { - return TokenType.WHITE_SPACE; - } - - {COMMENT} { - return COMMENT; - } -} - { +// plain-text-block-state + { "[[" { - yybegin(PLAIN_BLOCK_STATE); - return OPEN_PLAIN_BLOCK; - } - - ("isA"|"locateAt"|"mannerOf"|"Text"|"Vector"|"TextAndVector"|"NotNull"|"MultiValue") {WHITE_SPACE}* {EOL} { - goToState(WAITING_META_BUILTIN_VALUE_STATE); + return DOUBLE_LBRACKET; } - [^#\n] { - goToState(WAITING_META_TEXT_VALUE_STATE); + "]]" { + yybegin(WAITING_VALUE_STATE); + return DOUBLE_RBRACKET; } -} - { - {TEXT} { - return BUILTIN_TYPE; + "[" { + return PLAIN_TEXT; } -} - { - [^#\n]+ { - //return TokenType.BAD_CHARACTER; - return TEXT; + "]" { + return PLAIN_TEXT; } -} - -//------------------------------------------------------------------------------------------------------------------- - -//------------------------------------------------------------------------------------------------------------------- -// plain block. [[plain text]] - { - {WHITE_SPACE}*{EOL} { - return EOL; + {EOL} { + return TokenType.NEW_LINE_INDENT; } {WHITE_SPACE} { - return TokenType.WHITE_SPACE; + return isAfterEol() ? TokenType.WHITE_SPACE : PLAIN_TEXT; } - "]]" { - closeBrace(); - return CLOSE_PLAIN_BLOCK; - } - - "]" { - return TEXT; - } - - [^\n\]]+ { - return TEXT; + [^ \n\[\]]+ { + return PLAIN_TEXT; } } +//------------------------------------------------------------------------------------------------------------------- diff --git a/idea/spg-schema-idea-plugin/src/main/resources/META-INF/plugin.xml b/idea/spg-schema-idea-plugin/src/main/resources/META-INF/plugin.xml index d58dbde..553c7a6 100644 --- a/idea/spg-schema-idea-plugin/src/main/resources/META-INF/plugin.xml +++ b/idea/spg-schema-idea-plugin/src/main/resources/META-INF/plugin.xml @@ -17,6 +17,8 @@ +
  • version 0.0.11 SchemaML: add RuleML injection
  • +
  • version 0.0.10 RuleML: add formatter and commenter
  • version 0.0.9 RuleML: add structure view
  • version 0.0.8 RuleML: support Concept-Rule mark language
  • version 0.0.7 SchemaML: support PyCharm IDE
  • @@ -34,10 +36,6 @@ - - - + - + + + + + + + + - - + - - - - - - - - - - - - - - - diff --git a/idea/spg-schema-idea-plugin/src/main/resources/messages/ConceptRuleBundle.properties b/idea/spg-schema-idea-plugin/src/main/resources/messages/ConceptRuleBundle.properties new file mode 100644 index 0000000..17431b8 --- /dev/null +++ b/idea/spg-schema-idea-plugin/src/main/resources/messages/ConceptRuleBundle.properties @@ -0,0 +1,24 @@ + +ConceptRuleColorSettings.keywords=Keywords +ConceptRuleColorSettings.comments.block.comment=Comments//Block comment +ConceptRuleColorSettings.comments.line.comment=Comments//Line comment +ConceptRuleColorSettings.error=Error +ConceptRuleColorSettings.namespace.key=Namespace//Key +ConceptRuleColorSettings.namespace.value=Namespace//Value +ConceptRuleColorSettings.conceptRule.pattern=Concept rule//Pattern +ConceptRuleColorSettings.conceptRule.category=Concept rule//Category +ConceptRuleColorSettings.number=Number +ConceptRuleColorSettings.string=String +ConceptRuleColorSettings.variables=Variables +ConceptRuleColorSettings.bracesAndOperators.braces=Braces and Operators//Braces +ConceptRuleColorSettings.bracesAndOperators.brackets=Braces and Operators//Brackets +ConceptRuleColorSettings.bracesAndOperators.comma=Braces and Operators//Comma +ConceptRuleColorSettings.bracesAndOperators.dot=Braces and Operators//Dot +ConceptRuleColorSettings.bracesAndOperators.operator.sign=Braces and Operators//Operator sign +ConceptRuleColorSettings.bracesAndOperators.parentheses=Braces and Operators//Parentheses +ConceptRuleColorSettings.bracesAndOperators.semicolon=Braces and Operators//Semicolon + +ConceptRuleCodeStyleSettings.blankLines.after.namespace=After namespace +ConceptRuleCodeStyleSettings.blankLines.after.schema=After schema + + diff --git a/idea/spg-schema-idea-plugin/src/main/resources/messages/SchemaBundle.properties b/idea/spg-schema-idea-plugin/src/main/resources/messages/SchemaBundle.properties index e3b52b5..2944e5a 100644 --- a/idea/spg-schema-idea-plugin/src/main/resources/messages/SchemaBundle.properties +++ b/idea/spg-schema-idea-plugin/src/main/resources/messages/SchemaBundle.properties @@ -1,122 +1,13 @@ -filetype.schema.description=YAML -color.settings.schema.name=YAML -color.settings.schema.key=Key -color.settings.schema.string=String -color.settings.schema.dstring=Double quoted string -color.settings.schema.scalar.list='|' block -color.settings.schema.scalar.text='>' block -color.settings.schema.text=Text -color.settings.schema.sign=Sign: brace, comma, etc -color.settings.schema.comment=Comment -color.settings.schema.anchor=Anchor/Alias +SchemaColorSettings.keywords=Keywords +SchemaColorSettings.operator.sign=Operator sign +SchemaColorSettings.schema.name=Schema//Name +SchemaColorSettings.schema.alias.name=Schema//Alias name +SchemaColorSettings.schema.type=Schema//Type +SchemaColorSettings.comment=Comment +SchemaColorSettings.error=Error -settings.comment.label=Comments +SchemaCodeStyleSettings.blankLines.after.namespace=After namespace +SchemaCodeStyleSettings.blankLines.after.schema=After schema -new.name.conflicts.with=Key conflicts with existing one: ''{0}'' -rename.same.name=Same name -rename.invalid.name=''{0}'' is not a valid key name -schema.smartkeys.option.paste=Auto expand key sequences upon paste - -SchemaUnknownKeysInspectionBase.unknown.key=Key ''{0}'' is not expected here - -SchemaMissingKeysInspectionBase.missing.keys=Missing required key(s): ''{0}'' -SchemaMissingKeysInspectionBase.add.missing.keys.quickfix.name=Add missing keys -SchemaNonEditableKeysInspectionBase.noneditable.key=Key ''{0}'' is not modifiable by user - -SchemaDeprecatedKeysInspectionBase.deprecated.key=Key ''{0}'' is deprecated -YAMLDuplicatedKeysInspection.duplicated.key=Key ''{0}'' is duplicated -YAMLDuplicatedKeysInspection.remove.key.quickfix.name=Remove key -YAMLDuplicatedKeysInspection.merge.quickfix.name=Merge duplicated sections -SchemaNonEditableKeyInspectionBase.strip.noneditable.keys.quickfix.name=Remove all non-editable keys from the file - -SchemaUnknownValuesInspectionBase.error.value.is.required=Value is required -SchemaUnknownValuesInspectionBase.error.array.is.required=Array is required -SchemaUnknownValuesInspectionBase.error.array.not.allowed=Single value is expected - -SchemaEnumType.validation.error.value.unknown=Value ''{0}'' is not expected here -SchemaEnumType.validation.warning.value.deprecated=Value ''{0}'' is deprecated - -SchemaBooleanType.validation.error.quoted.value=Boolean value expected -SchemaMetaClass.error.scalar.value=Scalar value is not allowed here -SchemaScalarType.error.scalar.value=Scalar value expected -SchemaIntegerType.error.integer.value=Integer value expected -SchemaNumberType.error.numeric.value=Numeric value expected - -parsing.error.sequence.item.expected=Sequence item expected - -YAMLStructureViewDocument.element.name=YAML document -YAMLStructureViewSequenceItem.element.name=Sequence Item - -YAMLParser.invalid.header.symbols=Invalid block scalar header -YAMLParser.multiple.anchors=Multiple anchors are not permitted -YAMLParser.multiple.tags=Multiple tags are not permitted - -YAMLLanguageCodeStyleSettingsProvider.label.before=Before ':' -YAMLLanguageCodeStyleSettingsProvider.align.options.no=Do not align -YAMLLanguageCodeStyleSettingsProvider.align.options.colon=On colon -YAMLLanguageCodeStyleSettingsProvider.align.options.value=On value -YAMLLanguageCodeStyleSettingsProvider.align.values=Align values in maps -YAMLLanguageCodeStyleSettingsProvider.group.sequence.value=Sequence value -YAMLLanguageCodeStyleSettingsProvider.sequence.on.new.line=Sequence on new line -YAMLLanguageCodeStyleSettingsProvider.block.mapping.on.new.line=Block mapping on new line -YAMLLanguageCodeStyleSettingsProvider.indent.sequence.value=Indent sequence value -YAMLLanguageCodeStyleSettingsProvider.autoinsert.sequence.marker=Automatically insert hyphen on enter - -YAMLBreadcrumbsInfoProvider.copy.key.to.clipboard=Copy key to clipboard - -YAMLElementDescriptionProvider.type.anchor=Anchor - -YAMLAnchorRenameProcessor.lost.alias=Alias will refer to another anchor -YAMLAnchorRenameProcessor.reuse=Anchor already has the same name - -YAMLAliasResolveNodeProvider.action.name=Aliased sub-trees -YAMLAliasResolveNodeProvider.action.description=Resolve aliases and show referenced values in the structure - -YAMLKeysSearchEverywhereContributor.group.name=Config keys - -SchemaKeyCompletionInsertHandler.insert.value=Insert Value -SchemaKeyCompletionInsertHandler.remove.key=Remove Key - -inspections.group.name=YAML -inspections.unresolved.alias.name=Unresolved alias -inspections.unresolved.alias.message=Can''t resolve alias {0} -inspections.recursive.alias.name=Recursive alias -inspections.recursive.alias.message=Alias can't be recursive -inspections.schema.validation.name=Validation by JSON Schema -inspections.schema.deprecation.name=Deprecated YAML key -inspections.schema.deprecation.text=Key ''{0}'' is deprecated: {1} -inspections.schema.validation.prefix=Schema validation: -inspections.duplicated.keys.name=Duplicated YAML keys -inspections.unused.anchor.name=Unused anchor -inspections.types.mismatch.name=Suspicious type mismatch -inspections.incompatible.types.message=The type of value is ''{0}'' while other values use type ''{1}'' -inspections.incompatible.types.quickfix.wrap.quotes.message=Wrap with quotes -inspections.incompatible.types.quickfix.wrap.all.quotes.message=Wrap all scalars in sequence with quotes -inspections.unused.anchor.message=Anchor {0} is never used -inspections.unused.anchor.quickfix.name=Remove anchor -inspections.invalid.child.in.block.mapping=Invalid child element in a block mapping -inspections.invalid.child.in.block.sequence=Invalid child element in a block sequence -inspections.invalid.list.item.indent=Invalid list item indent -inspections.invalid.key.indent=Invalid block mapping key indent - -annotator.same.line.composed.value.message=It is forbidden to specify block composed value at the same line as key -schema.smartkeys.option.title=YAML - -find.usages.scalar=scalar -find.usages.sequence=sequence -find.usages.mapping=mapping -find.usages.key.value=key-value -find.usages.document=document -find.usages.unnamed= - -element.presentation.document.type=YAML Document -suppress.inspection.key=Suppress ''{0}'' for key ''{1}'' -suppress.inspection.file=Suppress ''{0}'' for file ''{1}'' - -schema.intention.category.name=YAML -schema.intention.name.inline.collection=Inline collection -schema.intention.name.expand.collection=Expand collection -schema.intention.name.expand.all.collections.inside=Expand all collections inside -schema.progress.title.inlining.collection=Inlining collection\u2026 -schema.progress.title.expanding.schema.collection=Expanding the schema collection\u2026 +SchemaLineMarkerProvider.navigate.to.usages=Navigate.to.usages