Merge branch 'IJSDK-479B'

This commit is contained in:
JohnHake 2020-02-13 10:21:02 -08:00
commit 59a4610efe
118 changed files with 930 additions and 1028 deletions

View File

@ -1,11 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="simple_language_plugin" type="#org.jetbrains.idea.devkit.run.PluginConfigurationType">
<module name="simple_language_plugin" />
<option name="VM_PARAMETERS" value="-Xmx512m -Xms256m -XX:MaxMetaspaceSize=250m -ea" />
<option name="PROGRAM_PARAMETERS" value="" />
<predefined_log_file enabled="true" id="idea.log" />
<method v="2">
<option name="Make" enabled="true" />
</method>
</configuration>
</component>

View File

@ -1,24 +0,0 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="simple_language_plugin_tests" type="JUnit" factoryName="JUnit">
<extension name="coverage" enabled="false" merge="false" sample_coverage="true" runner="idea" />
<module name="simple_language_plugin" />
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="false" />
<option name="ALTERNATIVE_JRE_PATH" />
<option name="PACKAGE_NAME" />
<option name="MAIN_CLASS_NAME" value="" />
<option name="METHOD_NAME" value="" />
<option name="TEST_OBJECT" value="directory" />
<option name="VM_PARAMETERS" value="-ea -Xbootclasspath/p:../out/classes/production/boot -XX:+HeapDumpOnOutOfMemoryError -Xmx512m -XX:MaxPermSize=320m -Didea.system.path=../test-system -Didea.home.path=. -Didea.config.path=../test-config -Didea.test.group=ALL_EXCLUDE_DEFINED" />
<option name="PARAMETERS" value="" />
<option name="WORKING_DIRECTORY" value="" />
<option name="ENV_VARIABLES" />
<option name="PASS_PARENT_ENVS" value="true" />
<option name="TEST_SEARCH_SCOPE">
<value defaultName="singleModule" />
</option>
<envs />
<dir value="$PROJECT_DIR$/code_samples/simple_language_plugin/tests" />
<patterns />
<method />
</configuration>
</component>

View File

@ -1,10 +1,10 @@
/* The following code was generated by JFlex 1.7.0 tweaked for IntelliJ platform */
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import com.intellij.sdk.language.psi.SimpleTypes;
import org.intellij.sdk.language.psi.SimpleTypes;
import com.intellij.psi.TokenType;

View File

@ -1,9 +1,9 @@
// This is a generated file. Not intended for manual editing.
package com.intellij.sdk.language.parser;
package org.intellij.sdk.language.parser;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiBuilder.Marker;
import static com.intellij.sdk.language.psi.SimpleTypes.*;
import static org.intellij.sdk.language.psi.SimpleTypes.*;
import static com.intellij.lang.parser.GeneratedParserUtilBase.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.lang.ASTNode;

View File

@ -1,5 +1,5 @@
// This is a generated file. Not intended for manual editing.
package com.intellij.sdk.language.psi;
package org.intellij.sdk.language.psi;
import java.util.List;
import org.jetbrains.annotations.*;

View File

@ -1,10 +1,10 @@
// This is a generated file. Not intended for manual editing.
package com.intellij.sdk.language.psi;
package org.intellij.sdk.language.psi;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.PsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.sdk.language.psi.impl.*;
import org.intellij.sdk.language.psi.impl.*;
public interface SimpleTypes {

View File

@ -1,5 +1,5 @@
// This is a generated file. Not intended for manual editing.
package com.intellij.sdk.language.psi;
package org.intellij.sdk.language.psi;
import org.jetbrains.annotations.*;
import com.intellij.psi.PsiElementVisitor;

View File

@ -1,5 +1,5 @@
// This is a generated file. Not intended for manual editing.
package com.intellij.sdk.language.psi.impl;
package org.intellij.sdk.language.psi.impl;
import java.util.List;
import org.jetbrains.annotations.*;
@ -7,8 +7,8 @@ import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.util.PsiTreeUtil;
import static com.intellij.sdk.language.psi.SimpleTypes.*;
import com.intellij.sdk.language.psi.*;
import static org.intellij.sdk.language.psi.SimpleTypes.*;
import org.intellij.sdk.language.psi.*;
import com.intellij.navigation.ItemPresentation;
public class SimplePropertyImpl extends SimpleNamedElementImpl implements SimpleProperty {

View File

@ -1,30 +0,0 @@
{
parserClass="com.intellij.sdk.language.parser.SimpleParser"
extends="com.intellij.extapi.psi.ASTWrapperPsiElement"
psiClassPrefix="Simple"
psiImplClassSuffix="Impl"
psiPackage="com.intellij.sdk.language.psi"
psiImplPackage="com.intellij.sdk.language.psi.impl"
elementTypeHolderClass="com.intellij.sdk.language.psi.SimpleTypes"
elementTypeClass="com.intellij.sdk.language.psi.SimpleElementType"
tokenTypeClass="com.intellij.sdk.language.psi.SimpleTokenType"
psiImplUtilClass="com.intellij.sdk.language.psi.impl.SimplePsiImplUtil"
}
simpleFile ::= item_*
private item_ ::= (property|COMMENT|CRLF)
property ::= (KEY? SEPARATOR VALUE?) | KEY {
pin=3
recoverWhile="recover_property"
mixin="com.intellij.sdk.language.psi.impl.SimpleNamedElementImpl"
implements="com.intellij.sdk.language.psi.SimpleNamedElement"
methods=[getKey getValue getName setName getNameIdentifier getPresentation]
}
private recover_property ::= !(KEY|SEPARATOR|COMMENT)

View File

@ -1,8 +0,0 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language.psi;
import com.intellij.psi.PsiNameIdentifierOwner;
public interface SimpleNamedElement extends PsiNameIdentifierOwner {
}

View File

@ -0,0 +1,30 @@
{
parserClass="org.intellij.sdk.language.parser.SimpleParser"
extends="com.intellij.extapi.psi.ASTWrapperPsiElement"
psiClassPrefix="Simple"
psiImplClassSuffix="Impl"
psiPackage="org.intellij.sdk.language.psi"
psiImplPackage="org.intellij.sdk.language.psi.impl"
elementTypeHolderClass="org.intellij.sdk.language.psi.SimpleTypes"
elementTypeClass="org.intellij.sdk.language.psi.SimpleElementType"
tokenTypeClass="org.intellij.sdk.language.psi.SimpleTokenType"
psiImplUtilClass="org.intellij.sdk.language.psi.impl.SimplePsiImplUtil"
}
simpleFile ::= item_*
private item_ ::= (property|COMMENT|CRLF)
property ::= (KEY? SEPARATOR VALUE?) | KEY {
pin=3
recoverWhile="recover_property"
mixin="org.intellij.sdk.language.psi.impl.SimpleNamedElementImpl"
implements="org.intellij.sdk.language.psi.SimpleNamedElement"
methods=[getKey getValue getName setName getNameIdentifier getPresentation]
}
private recover_property ::= !(KEY|SEPARATOR|COMMENT)

View File

@ -1,8 +1,8 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import com.intellij.sdk.language.psi.SimpleTypes;
import org.intellij.sdk.language.psi.SimpleTypes;
import com.intellij.psi.TokenType;
%%

View File

@ -1,10 +1,10 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lang.annotation.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;

View File

@ -1,6 +1,6 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.formatting.*;
import com.intellij.lang.ASTNode;

View File

@ -1,10 +1,8 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.navigation.*;
import com.intellij.openapi.project.Project;
import com.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.jetbrains.annotations.NotNull;
import java.util.*;

View File

@ -1,6 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.psi.codeStyle.*;

View File

@ -1,6 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.application.options.*;
import com.intellij.psi.codeStyle.*;

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
@ -8,8 +8,6 @@ import org.jetbrains.annotations.*;
import javax.swing.*;
import java.util.Map;
import static com.intellij.sdk.language.SimpleLanguage.*;
public class SimpleColorSettingsPage implements ColorSettingsPage {
private static final AttributesDescriptor[] DESCRIPTORS = new AttributesDescriptor[]{
new AttributesDescriptor("Key", SimpleSyntaxHighlighter.KEY),

View File

@ -1,6 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lang.Commenter;
import org.jetbrains.annotations.Nullable;

View File

@ -1,12 +1,10 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.util.ProcessingContext;
import com.intellij.sdk.language.psi.SimpleTypes;
import org.intellij.sdk.language.psi.SimpleTypes;
import org.jetbrains.annotations.NotNull;
public class SimpleCompletionContributor extends CompletionContributor {

View File

@ -1,6 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.lang.ASTNode;
@ -20,9 +18,9 @@ import com.intellij.psi.PsiManager;
import com.intellij.psi.search.FileTypeIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.util.IncorrectOperationException;
import com.intellij.sdk.language.psi.SimpleElementFactory;
import com.intellij.sdk.language.psi.SimpleFile;
import com.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.SimpleElementFactory;
import org.intellij.sdk.language.psi.SimpleFile;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.openapi.fileTypes.LanguageFileType;
import org.jetbrains.annotations.NotNull;

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.openapi.fileTypes.FileTypeConsumer;
import com.intellij.openapi.fileTypes.FileTypeFactory;

View File

@ -1,14 +1,12 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lang.cacheBuilder.*;
import com.intellij.lang.findUsages.FindUsagesProvider;
import com.intellij.psi.*;
import com.intellij.psi.tree.TokenSet;
import com.intellij.sdk.language.psi.*;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.SimpleTypes;
import org.jetbrains.annotations.*;
import static com.intellij.sdk.language.SimpleAnnotator.*;
public class SimpleFindUsagesProvider implements FindUsagesProvider {
@Nullable
@ -55,7 +53,7 @@ public class SimpleFindUsagesProvider implements FindUsagesProvider {
@Override
public String getNodeText(@NotNull PsiElement element, boolean useFullName) {
if (element instanceof SimpleProperty) {
return ((SimpleProperty) element).getKey() + SIMPLE_SEPARATOR_STR + ((SimpleProperty) element).getValue();
return ((SimpleProperty) element).getKey() + SimpleAnnotator.SIMPLE_SEPARATOR_STR + ((SimpleProperty) element).getValue();
} else {
return "";
}

View File

@ -1,6 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lang.ASTNode;
import com.intellij.lang.folding.*;
@ -9,11 +7,9 @@ import com.intellij.openapi.project.*;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.jetbrains.annotations.*;
import static com.intellij.sdk.language.SimpleAnnotator.*;
import java.util.*;
public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware {
@ -21,7 +17,7 @@ public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware
@Override
public FoldingDescriptor[] buildFoldRegions(@NotNull PsiElement root, @NotNull Document document, boolean quick) {
// Initialize the group of folding regions that will expand/collapse together.
FoldingGroup group = FoldingGroup.newGroup(SIMPLE_PREFIX_STR);
FoldingGroup group = FoldingGroup.newGroup(SimpleAnnotator.SIMPLE_PREFIX_STR);
// Initialize the list of folding regions
List< FoldingDescriptor > descriptors = new ArrayList< FoldingDescriptor >();
// Get a collection of the literal expressions in the document below root
@ -30,11 +26,11 @@ public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware
// Evaluate the collection
for ( final PsiLiteralExpression literalExpression : literalExpressions ) {
String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null;
if ( value != null && value.startsWith(SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR) ) {
if ( value != null && value.startsWith(SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR) ) {
Project project = literalExpression.getProject();
String key = value.substring(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length());
String key = value.substring(SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length());
// Get a list of all properties for a given key in the project
final List< SimpleProperty > properties = SimpleUtil.findProperties(project, key);
final List<SimpleProperty> properties = SimpleUtil.findProperties(project, key);
if ( properties.size() == 1 ) {
// Add a folding descriptor for the literal expression at this node.
descriptors.add(new FoldingDescriptor(literalExpression.getNode(),
@ -59,7 +55,7 @@ public class SimpleFoldingBuilder extends FoldingBuilderEx implements DumbAware
String retTxt = "...";
if ( node.getPsi() instanceof PsiLiteralExpression ) {
PsiLiteralExpression nodeElement = (PsiLiteralExpression) node.getPsi();
String key = ((String) nodeElement.getValue()).substring(SIMPLE_PREFIX_STR.length() + SIMPLE_SEPARATOR_STR.length());
String key = ((String) nodeElement.getValue()).substring(SimpleAnnotator.SIMPLE_PREFIX_STR.length() + SimpleAnnotator.SIMPLE_SEPARATOR_STR.length());
final List< SimpleProperty > properties = SimpleUtil.findProperties(nodeElement.getProject(), key);
String place = properties.get(0).getValue();
// IMPORTANT: keys can come with no values, so a test for null is needed

View File

@ -1,13 +1,11 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.formatting.*;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.sdk.language.psi.SimpleTypes;
import org.intellij.sdk.language.psi.SimpleTypes;
import org.jetbrains.annotations.*;
public class SimpleFormattingModelBuilder implements FormattingModelBuilder {

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.openapi.util.IconLoader;

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lang.Language;

View File

@ -1,6 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lang.Language;
import com.intellij.psi.codeStyle.*;

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lexer.FlexAdapter;

View File

@ -1,13 +1,12 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.codeInsight.daemon.*;
import com.intellij.codeInsight.navigation.NavigationGutterIconBuilder;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.java.PsiJavaTokenImpl;
import com.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.jetbrains.annotations.NotNull;
import static com.intellij.sdk.language.SimpleAnnotator.*;
import java.util.*;
@ -21,12 +20,12 @@ public class SimpleLineMarkerProvider extends RelatedItemLineMarkerProvider {
// The literal expression must start with the Simple language literal expression
PsiLiteralExpression literalExpression = (PsiLiteralExpression) element.getParent();
String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null;
if ( ( value == null ) || !value.startsWith( SIMPLE_PREFIX_STR + SIMPLE_SEPARATOR_STR ) ) return;
if ( ( value == null ) || !value.startsWith( SimpleAnnotator.SIMPLE_PREFIX_STR + SimpleAnnotator.SIMPLE_SEPARATOR_STR ) ) return;
// Get the Simple language property usage
Project project = element.getProject();
String possibleProperties = value.substring( SIMPLE_PREFIX_STR.length()+SIMPLE_SEPARATOR_STR.length() );
final List< SimpleProperty > properties = SimpleUtil.findProperties( project, possibleProperties );
String possibleProperties = value.substring( SimpleAnnotator.SIMPLE_PREFIX_STR.length()+ SimpleAnnotator.SIMPLE_SEPARATOR_STR.length() );
final List<SimpleProperty> properties = SimpleUtil.findProperties( project, possibleProperties );
if ( properties.size() > 0 ) {
// Add the property to a collection of line marker info
NavigationGutterIconBuilder< PsiElement > builder =

View File

@ -1,12 +1,12 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lang.*;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.tree.*;
import com.intellij.sdk.language.parser.SimpleParser;
import com.intellij.sdk.language.psi.*;
import org.intellij.sdk.language.parser.SimpleParser;
import org.intellij.sdk.language.psi.*;
import org.jetbrains.annotations.NotNull;
public class SimpleParserDefinition implements ParserDefinition {

View File

@ -1,10 +1,8 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lang.refactoring.RefactoringSupportProvider;
import com.intellij.psi.PsiElement;
import com.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.jetbrains.annotations.*;
public class SimpleRefactoringSupportProvider extends RefactoringSupportProvider {

View File

@ -1,12 +1,10 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.codeInsight.lookup.*;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.jetbrains.annotations.*;
import java.util.*;

View File

@ -1,6 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.openapi.util.TextRange;
import com.intellij.patterns.PlatformPatterns;
@ -8,7 +6,7 @@ import com.intellij.psi.*;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import static com.intellij.sdk.language.SimpleAnnotator.*;
import static org.intellij.sdk.language.SimpleAnnotator.*;
public class SimpleReferenceContributor extends PsiReferenceContributor {
@Override

View File

@ -1,6 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.structureView.StructureViewTreeElement;
@ -9,9 +7,9 @@ import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.sdk.language.psi.SimpleFile;
import com.intellij.sdk.language.psi.SimpleProperty;
import com.intellij.sdk.language.psi.impl.SimplePropertyImpl;
import org.intellij.sdk.language.psi.*;
import org.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.impl.SimplePropertyImpl;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;

View File

@ -1,6 +1,4 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.ide.structureView.*;
import com.intellij.lang.PsiStructureViewFactory;

View File

@ -1,11 +1,9 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.ide.structureView.*;
import com.intellij.ide.util.treeView.smartTree.Sorter;
import com.intellij.psi.PsiFile;
import com.intellij.sdk.language.psi.SimpleFile;
import org.intellij.sdk.language.psi.SimpleFile;
import org.jetbrains.annotations.NotNull;
public class SimpleStructureViewModel extends StructureViewModelBase implements

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.*;
@ -6,7 +6,7 @@ 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 com.intellij.sdk.language.psi.SimpleTypes;
import org.intellij.sdk.language.psi.SimpleTypes;
import org.jetbrains.annotations.NotNull;
import static com.intellij.openapi.editor.colors.TextAttributesKey.createTextAttributesKey;

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.project.Project;

View File

@ -1,12 +1,12 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.search.*;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.sdk.language.psi.*;
import org.intellij.sdk.language.psi.SimpleFile;
import org.intellij.sdk.language.psi.SimpleProperty;
import java.util.*;
@ -14,7 +14,7 @@ public class SimpleUtil {
// Searches the entire project for Simple language files with instances of the Simple property with the given key
public static List<SimpleProperty> findProperties(Project project, String key) {
List<SimpleProperty> result = null;
List<SimpleProperty> result = new ArrayList<>();
Collection<VirtualFile> virtualFiles =
FileTypeIndex.getFiles(SimpleFileType.INSTANCE, GlobalSearchScope.allScope(project));
for (VirtualFile virtualFile : virtualFiles) {
@ -24,16 +24,13 @@ public class SimpleUtil {
if (properties != null) {
for (SimpleProperty property : properties) {
if (key.equals(property.getKey())) {
if (result == null) {
result = new ArrayList<SimpleProperty>();
}
result.add(property);
result.add(property);
}
}
}
}
}
return result != null ? result : Collections.<SimpleProperty>emptyList();
return result;
}
public static List<SimpleProperty> findProperties(Project project) {

View File

@ -1,29 +1,28 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language.psi;
package org.intellij.sdk.language.psi;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.sdk.language.SimpleFileType;
import org.intellij.sdk.language.SimpleFileType;
public class SimpleElementFactory {
public static SimpleProperty createProperty(Project project, String name) {
final SimpleFile file = createFile(project, name);
return (SimpleProperty) file.getFirstChild();
}
public static SimpleProperty createProperty(Project project, String name, String value) {
final SimpleFile file = createFile(project, name + " = " + value);
return (SimpleProperty) file.getFirstChild();
}
public static PsiElement createCRLF(Project project) {
final SimpleFile file = createFile(project, "\n");
return file.getFirstChild();
}
public static SimpleFile createFile(Project project, String text) {
String name = "dummy.simple";
return (SimpleFile) PsiFileFactory.getInstance( project).createFileFromText(name, SimpleFileType.INSTANCE, text);
}
public static SimpleProperty createProperty(Project project, String name, String value) {
final SimpleFile file = createFile(project, name + " = " + value);
return (SimpleProperty) file.getFirstChild();
}
public static PsiElement createCRLF(Project project) {
final SimpleFile file = createFile(project, "\n");
return file.getFirstChild();
}
}

View File

@ -1,7 +1,7 @@
package com.intellij.sdk.language.psi;
package org.intellij.sdk.language.psi;
import com.intellij.psi.tree.IElementType;
import com.intellij.sdk.language.SimpleLanguage;
import org.intellij.sdk.language.SimpleLanguage;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

View File

@ -1,13 +1,11 @@
package com.intellij.sdk.language.psi;
package org.intellij.sdk.language.psi;
import com.intellij.extapi.psi.PsiFileBase;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.psi.FileViewProvider;
import com.intellij.sdk.language.*;
import org.intellij.sdk.language.*;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
public class SimpleFile extends PsiFileBase {
public SimpleFile(@NotNull FileViewProvider viewProvider) {
super(viewProvider, SimpleLanguage.INSTANCE);

View File

@ -0,0 +1,6 @@
package org.intellij.sdk.language.psi;
import com.intellij.psi.PsiNameIdentifierOwner;
public interface SimpleNamedElement extends PsiNameIdentifierOwner {
}

View File

@ -1,7 +1,7 @@
package com.intellij.sdk.language.psi;
package org.intellij.sdk.language.psi;
import com.intellij.psi.tree.IElementType;
import com.intellij.sdk.language.SimpleLanguage;
import org.intellij.sdk.language.SimpleLanguage;
import org.jetbrains.annotations.*;
public class SimpleTokenType extends IElementType {

View File

@ -1,10 +1,10 @@
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.sdk.language.psi.impl;
package org.intellij.sdk.language.psi.impl;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.sdk.language.psi.SimpleNamedElement;
import org.intellij.sdk.language.psi.SimpleNamedElement;
import org.jetbrains.annotations.NotNull;
public abstract class SimpleNamedElementImpl extends ASTWrapperPsiElement implements SimpleNamedElement {

View File

@ -1,11 +1,11 @@
package com.intellij.sdk.language.psi.impl;
package org.intellij.sdk.language.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.sdk.language.SimpleIcons;
import com.intellij.sdk.language.psi.*;
import org.intellij.sdk.language.SimpleIcons;
import org.intellij.sdk.language.psi.*;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;

View File

@ -3,7 +3,7 @@
<idea-plugin>
<!-- Unique id for this plugin. Must stay constant for the life of the plugin. -->
<id>com.intellij.sdk.simple_language</id>
<id>org.intellij.sdk.simple_language</id>
<!-- Text to display as name on Preferences/Settings | Plugin page -->
<name>SDK: Simple Language Sample Project</name>
@ -40,28 +40,28 @@
<vendor url="https://plugins.jetbrains.com">IntelliJ Platform SDK</vendor>
<extensions defaultExtensionNs="com.intellij">
<fileType name="Simple file" implementationClass="com.intellij.sdk.language.SimpleFileType" fieldName="INSTANCE"
language="Simple" extensions="simple"/>
<fileType name="Simple file" implementationClass="org.intellij.sdk.language.SimpleFileType" fieldName="INSTANCE"
language="Simple" extensions="simple"/>
<!-- Only required for versions of the IntelliJ Platform prior to v2019.2.
Use fileTypeFactory extension point INSTEAD of fileType.
<fileTypeFactory implementation="com.intellij.sdk.language.SimpleFileTypeFactory"/>
<fileTypeFactory implementation="org.intellij.sdk.language.SimpleFileTypeFactory"/>
-->
<lang.parserDefinition language="Simple" implementationClass="com.intellij.sdk.language.SimpleParserDefinition"/>
<lang.syntaxHighlighterFactory language="Simple" implementationClass="com.intellij.sdk.language.SimpleSyntaxHighlighterFactory"/>
<colorSettingsPage implementation="com.intellij.sdk.language.SimpleColorSettingsPage"/>
<annotator language="JAVA" implementationClass="com.intellij.sdk.language.SimpleAnnotator"/>
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.intellij.sdk.language.SimpleLineMarkerProvider"/>
<completion.contributor language="Simple" implementationClass="com.intellij.sdk.language.SimpleCompletionContributor"/>
<psi.referenceContributor implementation="com.intellij.sdk.language.SimpleReferenceContributor"/>
<lang.refactoringSupport language="Simple" implementationClass="com.intellij.sdk.language.SimpleRefactoringSupportProvider"/>
<lang.findUsagesProvider language="Simple" implementationClass="com.intellij.sdk.language.SimpleFindUsagesProvider"/>
<lang.foldingBuilder language="JAVA" implementationClass="com.intellij.sdk.language.SimpleFoldingBuilder"/>
<gotoSymbolContributor implementation="com.intellij.sdk.language.SimpleChooseByNameContributor"/>
<lang.psiStructureViewFactory language="Simple" implementationClass="com.intellij.sdk.language.SimpleStructureViewFactory"/>
<lang.formatter language="Simple" implementationClass="com.intellij.sdk.language.SimpleFormattingModelBuilder"/>
<codeStyleSettingsProvider implementation="com.intellij.sdk.language.SimpleCodeStyleSettingsProvider"/>
<langCodeStyleSettingsProvider implementation="com.intellij.sdk.language.SimpleLanguageCodeStyleSettingsProvider"/>
<lang.commenter language="Simple" implementationClass="com.intellij.sdk.language.SimpleCommenter"/>
<lang.parserDefinition language="Simple" implementationClass="org.intellij.sdk.language.SimpleParserDefinition"/>
<lang.syntaxHighlighterFactory language="Simple" implementationClass="org.intellij.sdk.language.SimpleSyntaxHighlighterFactory"/>
<colorSettingsPage implementation="org.intellij.sdk.language.SimpleColorSettingsPage"/>
<annotator language="JAVA" implementationClass="org.intellij.sdk.language.SimpleAnnotator"/>
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="org.intellij.sdk.language.SimpleLineMarkerProvider"/>
<completion.contributor language="Simple" implementationClass="org.intellij.sdk.language.SimpleCompletionContributor"/>
<psi.referenceContributor implementation="org.intellij.sdk.language.SimpleReferenceContributor"/>
<lang.refactoringSupport language="Simple" implementationClass="org.intellij.sdk.language.SimpleRefactoringSupportProvider"/>
<lang.findUsagesProvider language="Simple" implementationClass="org.intellij.sdk.language.SimpleFindUsagesProvider"/>
<lang.foldingBuilder language="JAVA" implementationClass="org.intellij.sdk.language.SimpleFoldingBuilder"/>
<gotoSymbolContributor implementation="org.intellij.sdk.language.SimpleChooseByNameContributor"/>
<lang.psiStructureViewFactory language="Simple" implementationClass="org.intellij.sdk.language.SimpleStructureViewFactory"/>
<lang.formatter language="Simple" implementationClass="org.intellij.sdk.language.SimpleFormattingModelBuilder"/>
<codeStyleSettingsProvider implementation="org.intellij.sdk.language.SimpleCodeStyleSettingsProvider"/>
<langCodeStyleSettingsProvider implementation="org.intellij.sdk.language.SimpleLanguageCodeStyleSettingsProvider"/>
<lang.commenter language="Simple" implementationClass="org.intellij.sdk.language.SimpleCommenter"/>
</extensions>
</idea-plugin>

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.application.options.CodeStyle;
import com.intellij.codeInsight.completion.CompletionType;
@ -9,7 +9,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.sdk.language.psi.SimpleProperty;
import org.intellij.sdk.language.psi.SimpleProperty;
import java.util.Arrays;
import java.util.Collection;
@ -23,7 +23,7 @@ public class SimpleCodeInsightTest extends LightJavaCodeInsightFixtureTestCase {
*/
@Override
protected String getTestDataPath() {
return "src/test/resources";
return "src/test/testData";
}
public void testCompletion() {
@ -40,7 +40,7 @@ public class SimpleCodeInsightTest extends LightJavaCodeInsightFixtureTestCase {
}
public void testFormatter() {
myFixture.configureByFiles("FormatterTestData.simple");
myFixture.configureByFile("FormatterTestData.simple");
CodeStyle.getLanguageSettings(myFixture.getFile()).SPACE_AROUND_ASSIGNMENT_OPERATORS = true;
CodeStyle.getLanguageSettings(myFixture.getFile()).KEEP_BLANK_LINES_IN_CODE = 2;
WriteCommandAction.writeCommandAction(getProject()).run(() -> {
@ -57,7 +57,7 @@ public class SimpleCodeInsightTest extends LightJavaCodeInsightFixtureTestCase {
}
public void testFolding() {
myFixture.configureByFiles("DefaultTestData.simple");
myFixture.configureByFile("DefaultTestData.simple");
myFixture.testFolding(getTestDataPath() + "/FoldingTestData.java");
}

View File

@ -1,4 +1,4 @@
package com.intellij.sdk.language;
package org.intellij.sdk.language;
import com.intellij.testFramework.ParsingTestCase;
@ -17,7 +17,7 @@ public class SimpleParsingTest extends ParsingTestCase {
*/
@Override
protected String getTestDataPath() {
return "src/test/resources";
return "src/test/testData";
}
@Override

View File

@ -2,63 +2,31 @@
title: 7. Annotator
---
Annotator helps highlight and annotate any code based on specific rules.
An [Annotator](/reference_guide/custom_language_support/syntax_highlighting_and_error_highlighting.md#annotator) helps highlight and annotate any code based on specific rules.
This section adds annotation functionality to support the Simple Language in the context of Java code.
### 7.1. Define an annotator
In this tutorial we will annotate usages of our properties within Java code.
Let's consider a literal which starts with *"simple:"* as a usage of our property.
* bullet list
{:toc}
## 7.1. Define an Annotator
The `SimpleAnnotator` subclasses [`Annotator`](upsource:///platform/analysis-api/src/com/intellij/lang/annotation/Annotator.java).
Consider a literal string that starts with "simple:" as a prefix of a Simple Language key.
It isn't part of the Simple Language, but it is a useful convention for detecting Simple Language keys embedded as string literals in other languages, like Java.
Annotate the `simple:key` literal expression, and differentiate between a well-formed vs. an unresolved property:
```java
package com.simpleplugin;
import com.intellij.lang.annotation.*;
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.simpleplugin.psi.SimpleProperty;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public class SimpleAnnotator implements Annotator {
@Override
public void annotate(@NotNull final PsiElement element, @NotNull AnnotationHolder holder) {
if (element instanceof PsiLiteralExpression) {
PsiLiteralExpression literalExpression = (PsiLiteralExpression) element;
String value = literalExpression.getValue() instanceof String ? (String) literalExpression.getValue() : null;
if (value != null && value.startsWith("simple" + ":")) {
Project project = element.getProject();
String key = value.substring(7);
List<SimpleProperty> properties = SimpleUtil.findProperties(project, key);
if (properties.size() == 1) {
TextRange range = new TextRange(element.getTextRange().getStartOffset() + 8,
element.getTextRange().getEndOffset() - 1);
Annotation annotation = holder.createInfoAnnotation(range, null);
annotation.setTextAttributes(DefaultLanguageHighlighterColors.LINE_COMMENT);
} else if (properties.size() == 0) {
TextRange range = new TextRange(element.getTextRange().getStartOffset() + 8,
element.getTextRange().getEndOffset() - 1);
holder.createErrorAnnotation(range, "Unresolved property");
}
}
}
}
}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleAnnotator.java %}
```
### 7.2. Register the annotator
## 7.2. Register the Annotator
Using an extension point, register the Simple Language annotator class with the IntelliJ Platform:
```xml
<annotator language="JAVA" implementationClass="com.simpleplugin.SimpleAnnotator"/>
<extensions defaultExtensionNs="com.intellij">
<annotator language="JAVA" implementationClass="org.intellij.sdk.language.SimpleAnnotator"/>
</extensions>
```
### 7.3. Run the project
Let's define the following Java file and check if the IDE resolves a property.
## 7.3. Run the Project
As a test, define the following Java file containing a Simple Language `prefix:value` pair:
```java
public class Test {
public static void main(String[] args) {
@ -67,9 +35,12 @@ public class Test {
}
```
![Annotator](img/annotator.png)
Open this Java file in an IDE Development Instance running the `simple_language_plugin` to check if the IDE resolves a property:
If we type an undefined property name, it will annotate the code with a error.
![Annotator](img/annotator.png){:width="800px"}
![Unresolved property](img/unresolved_property.png)
If the property is an undefined name, the annotator flags the code with an error.
![Unresolved property](img/unresolved_property.png){:width="800px"}
Try changing the Simple Language [color settings](/tutorials/custom_language_support/syntax_highlighter_and_color_settings_page.md#run-the-project-1) to differentiate the annotation from the default language color settings.

View File

@ -2,38 +2,50 @@
title: 16. Code Style Setting
---
Code style settings allow defining formatting options. A code style settings provider will create an instance of the settings, and also create an options page in order to edit them. In this example, we'll create a page that uses the default language code style settings, customised by a language code style settings provider.
[Code style settings](/reference_guide/custom_language_support/code_formatting.md#code-style-settings) enable defining formatting options.
A code style settings provider creates an instance of the settings and also creates an options page in settings/preferences.
This example creates a settings/preferences page that uses the default language code style settings, customized by a language code style settings provider.
### 16.1. Define code style settings
* bullet list
{:toc}
## 16.1. Define Code Style Settings
Define a code style settings for Simple Language by subclassing [`CustomCodeStyleSettings`](upsource:///platform/lang-api/src/com/intellij/psi/codeStyle/CustomCodeStyleSettings.java).
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettings.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettings.java %}
```
### 16.2. Define code style settings provider
## 16.2. Define Code Style Settings Provider
The code style settings provider gives the IntelliJ Platform a standard way to instantiate `CustomCodeStyleSettings` for the Simple Language.
Define a code style settings provider for Simple Language by subclassing [`CodeStyleSettingsProvider`](upsource:///platform/lang-api/src/com/intellij/psi/codeStyle/CodeStyleSettingsProvider.java).
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCodeStyleSettingsProvider.java %}
```
### 16.3. Register the code style settings provider
## 16.3. Register the Code Style Settings Provider
The `SimpleCodeStyleSettingsProvider` implementation is registered with the IntelliJ Platform in the plugin configuration file using the `codeStyleSettingsProvider` extension point.
```xml
<codeStyleSettingsProvider implementation="com.simpleplugin.SimpleCodeStyleSettingsProvider"/>
<extensions defaultExtensionNs="com.intellij">
<codeStyleSettingsProvider implementation="org.intellij.sdk.language.SimpleCodeStyleSettingsProvider"/>
</extensions>
```
### 16.4. Define language code style settings provider
## 16.4. Define the Language Code Style Settings Provider
Define a code style settings provider for Simple Language by subclassing [`LanguageCodeStyleSettingsProvider`](upsource:///platform/lang-api/src/com/intellij/psi/codeStyle/LanguageCodeStyleSettingsProvider.java), which provides common code style settings for a specific language.
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguageCodeStyleSettingsProvider.java %}
```
### 16.5. Register the language code style settings provider
## 16.5. Register the Language Code Style Settings Provider
The `SimpleLanguageCodeStyleSettingsProvider` implementation is registered with the IntelliJ Platform in the plugin configuration file using the `langCodeStyleSettingsProvider` extension point.
```xml
<langCodeStyleSettingsProvider implementation="com.simpleplugin.SimpleLanguageCodeStyleSettingsProvider"/>
<extensions defaultExtensionNs="com.intellij">
<langCodeStyleSettingsProvider
implementation="org.intellij.sdk.language.SimpleLanguageCodeStyleSettingsProvider"/>
</extensions>
```
### 16.6. Run the project
## 16.6. Run the project
In the IDE Development Instance, open the Simple Language code formatting page: **Preferences/Settings \| Editor \| Code Style \| Simple**.
![Code Style Settings](img/code_style_settings.png)

View File

@ -2,20 +2,32 @@
title: 17. Commenter
---
A commenter allows user to comment the code at the cursor or selected code automatically via corresponding actions.
A commenter enables the user to comment-out a line of code at the cursor or selected code automatically.
The [`Commenter`](upsource:///platform/core-api/src/com/intellij/lang/Commenter.java) defines support for "Comment with Line Comment" and "Comment with Block Comment" actions.
### 17.1. Define a commenter
* bullet list
{:toc}
## 17.1. Define a Commenter
The Simple Language commenter subclasses `Commenter`.
This commenter defines the line comment prefix as "#".
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleCommenter.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCommenter.java %}
```
### 17.2. Register the commenter
## 17.2. Register the Commenter
The `SimpleCommenter` implementation is registered with the IntelliJ Platform in the plugin configuration file using the `lang.commenter` extension point.
```xml
<lang.commenter language="Simple" implementationClass="com.simpleplugin.SimpleCommenter"/>
<extensions defaultExtensionNs="com.intellij">
<lang.commenter language="Simple" implementationClass="org.intellij.sdk.language.SimpleCommenter"/>
</extensions>
```
### 17.3. Run the project
## 17.3. Run the Project
Open the example Simple Language [properties file ](/tutorials/custom_language_support/lexer_and_parser_definition.md#47-run-the-project) in the IDE Development Instance.
Place the cursor at the `website` line.
Select **Code \| Comment with Line Comment**.
The line is converted to a comment.
Select **Code \| Comment with Line Comment** again, and the comment is converted back to active code.
![Commenter](img/commenter.png)
![Commenter](img/commenter.png){:width="800px"}

View File

@ -2,23 +2,32 @@
title: 9. Completion Contributor
---
Custom languages provide code completion using one of [two approaches](/reference_guide/custom_language_support/code_completion.md).
The Simple Language plugin implements the less complex of the two methods, reference completion.
The easiest way to provide completion is to use a completion contributor.
### 9.1. Define a completion contributor
Let's provide custom completion for values in property files.
* bullet list
{:toc}
## 9.1. Define a Completion Contributor
For this tutorial, the `simple_language_plugin` provides custom completion for values in Simple Language property files.
Create a completion contributor by subclassing [`CompletionContributor`](upsource:///platform/analysis-api/src/com/intellij/codeInsight/completion/CompletionContributor.java).
This rudimentary completion contributor always adds "Hello" to the results set, regardless of context:
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleCompletionContributor.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleCompletionContributor.java %}
```
### 9.2. Register the completion contributor
## 9.2. Register the Completion Contributor
The `SimpleCompletionContributor` implementation is registered in the plugin configuration file with the IntelliJ Platform using the `completion.contributor` extension point.
```xml
<completion.contributor language="Simple" implementationClass="com.simpleplugin.SimpleCompletionContributor"/>
<extensions defaultExtensionNs="com.intellij">
<completion.contributor language="Simple"
implementationClass="org.intellij.sdk.language.SimpleCompletionContributor"/>
</extensions>
```
### 9.3. Run the project
## 9.3. Run the Project
Run the `simple_language_plugin` in a Development Instance and open the [`test.simple`](/tutorials/custom_language_support/lexer_and_parser_definition.md#run-the-project) file.
Erase the property "English" and invoke [Basic Code Completion](https://www.jetbrains.com/help/idea/auto-completing-code.html#invoke-basic-completion).
The choice "Hello" is shown:
![Completion](img/completion.png)
![Completion](img/completion.png){:width="800px"}

View File

@ -2,23 +2,31 @@
title: 11. Find Usages Provider
---
A find usage provider uses a word scanner to build an index of words present in every file.
A scanner breaks the text into words, defines the context for each word and passes it to the find usage provider.
A [find usage provider](/reference_guide/custom_language_support/find_usages.md) uses a word scanner to build an index of words in every file.
A scanner breaks the text into words and defines the context for each word.
### 11.1. Define a find usages provider
* bullet list
{:toc}
## 11.1. Define a Find Usages Provider
The `SimpleFindUsagesProvider` implements [`FindUsagesProvider`](upsource:///platform/indexing-api/src/com/intellij/lang/findUsages/FindUsagesProvider.java).
Using the [`DefaultWordsScanner`](upsource:///platform/indexing-api/src/com/intellij/lang/cacheBuilder/DefaultWordsScanner.java) ensures the scanner implementation is thread-safe.
See the comments in `FindUsagesProvider` for more information.
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleFindUsagesProvider.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFindUsagesProvider.java %}
```
### 11.2. Register the find usages provider
## 11.2. Register the Find Usages Provider
The `SimpleFindUsagesProvider` implementation is registered with the IntelliJ Platform in the plugin configuration file using the `lang.findUsagesProvider` extension point.
```xml
<lang.findUsagesProvider language="Simple" implementationClass="com.simpleplugin.SimpleFindUsagesProvider"/>
<extensions defaultExtensionNs="com.intellij">
<lang.findUsagesProvider language="Simple"
implementationClass="org.intellij.sdk.language.SimpleFindUsagesProvider"/>
</extensions>
```
### 11.3. Run the project
## 11.3. Run the Project
Rebuild the project, and run `simple_language_plugin` in a Development Instance.
The IDE now supports [Find Usages](https://www.jetbrains.com/help/idea/find-highlight-usages.html) for any property with a reference:
Now we can call *Find Usages* for any property with a reference.
![Find Usages](img/find_usages.png)
![Find Usages](img/find_usages.png){:width="800px"}

View File

@ -2,24 +2,44 @@
title: 12. Folding Builder
---
A folding builder helps you to fold the code regions and replace it with specific text.
A folding builder identifies the folding regions in the code.
In this step of the tutorial, the folding builder is used to identify folding regions and replace the regions with specific text.
Rather than the usual practice of using a folding builder to collapse a class, method, or comments to fewer lines, the folding builder replaces Simple Language keys with their corresponding values.
### 12.1. Define a folding builder
* bullet list
{:toc}
Let's replace usages of properties with its values by default.
## 12.1. Define a Folding Builder
The `SimpleFoldingBuilder` replaces usages of properties with their values by default.
Start by subclassing [`FoldingBuilderEx`](upsource:///community/platform/core-api/src/com/intellij/lang/folding/FoldingBuilderEx.java)
Note that `SimpleFoldingBuilder` also implements [`DumbAware`](upsource:///platform/core-api/src/com/intellij/openapi/project/DumbAware.java), which means the class is allowed to run in dumb mode, when indices are in background update.
> **NOTE** A folding builder must implement [`DumbAware`](upsource:///platform/core-api/src/com/intellij/openapi/project/DumbAware.java) to function in this tutorial and pass tests.
The `buildFoldRegions()` method searches down a PSI tree from `root` to find all literal expressions containing the [simple prefix](/tutorials/custom_language_support/annotator.md#define-an-annotator) `simple:`.
The remainder of such a string is expected to contain a Simple Language key, and so the text range is stored as a [`FoldingDescriptor`](upsource:///platform/core-api/src/com/intellij/lang/folding/FoldingDescriptor.java).
The `getPlaceholderText()` method retrieves the Simple Language value corresponding to the key associated with the (ASTNode) provided.
The IntelliJ Platform uses the value to substitute for the key when the code gets folded.
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleFoldingBuilder.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFoldingBuilder.java %}
```
### 12.2. Register the folding builder
## 12.2. Register the Folding Builder
The `SimpleFoldingBuilder` implementation is registered with the IntelliJ Platform in the plugin configuration file using the `lang.foldingBuilder` extension point.
```xml
<lang.foldingBuilder language="JAVA" implementationClass="com.simpleplugin.SimpleFoldingBuilder"/>
<extensions defaultExtensionNs="com.intellij">
<lang.foldingBuilder language="JAVA"
implementationClass="org.intellij.sdk.language.SimpleFoldingBuilder"/>
</extensions>
```
### 12.3. Run the project
## 12.3. Run the Project
Rebuild the project, and run `simple_language_plugin` in a Development Instance.
Now when a Java file is opened in the Editor, it shows the property's value instead of the key.
This is because `SimpleFoldingBuilder.isCollapsedByDefault()` always returns `true`.
Try using **Code \| Folding \| Expand All** to show the key rather than the value.
Now when we open a Java file, it shows the property's value instead of the key.
![Folding](img/folding.png)
![Folding](img/folding.png){:width="800px"}

View File

@ -2,33 +2,41 @@
title: 15. Formatter
---
*A formatter allows to reformat the code automatically based on code style settings.*
The IntelliJ Platform includes a powerful framework for implementing formatting for custom languages.
A [formatter](/reference_guide/custom_language_support/code_formatting.md) enables reformatting code automatically based on code style settings.
The formatter controls spaces, indents, wrap, and alignment.
### 15.1. Define a block
The formatter uses the blocks to receive formatting rules for each PSI element.
Our goal is to cover each PSI element with such block. Since each block builds own children blocks we can generate extra blocks or skip any PSI elements.
* bullet list
{:toc}
## 15.1. Define a Block
The formatting model represents the formatting structure of a file as a tree of [`Block`](upsource:///platform/lang-api/src/com/intellij/formatting/Block.java) objects, with associated indent, wrap, alignment and spacing settings.
The goal is to cover each PSI element with such a block.
Since each block builds its children's blocks, it can generate extra blocks or skip any PSI elements.
Define `SimpleBlock` based on [`AbstractBlock`](upsource:///platform/lang-impl/src/com/intellij/psi/formatter/common/AbstractBlock.java)
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleBlock.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleBlock.java %}
```
### 15.2. Define a formatting model builder
Let's define a formatter which removes extra spaces except the single ones around the property separator.
## 15.2. Define a Formatting Model Builder
Define a formatter that removes extra spaces except for the single spaces around the property separator.
For example, reformat "foo = &nbsp;&nbsp;&nbsp;&nbsp;bar" to `foo = bar`.
Create `SimpleFormattingModelBuilder` by subclassing [`FormattingModelBuilder`](upsource:///platform/lang-api/src/com/intellij/formatting/FormattingModelBuilder.java).
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleFormattingModelBuilder.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFormattingModelBuilder.java %}
```
### 15.3. Register the formatter
## 15.3. Register the Formatter
The `SimpleFormattingModelBuilder` implementation is registered with the IntelliJ Platform in the plugin configuration file using the `lang.formatter` extension point.
```xml
<lang.formatter language="Simple" implementationClass="com.simpleplugin.SimpleFormattingModelBuilder"/>
<extensions defaultExtensionNs="com.intellij">
<lang.formatter language="Simple"
implementationClass="org.intellij.sdk.language.SimpleFormattingModelBuilder"/>
</extensions>
```
### 15.4. Run the project
## 15.4. Run the Project
Add some extra spaces around the `=` separator between `language` and `English`.
Reformat the code by selecting **Code \| Show Reformat File Dialog** and choose **Run**.
Now add some extra spaces and reformat the code via **Code \| Reformat Code**.
![Formatter](img/formatter.png)
![Formatter](img/formatter.png){:width="800px"}

View File

@ -2,14 +2,15 @@
title: 13. Go To Symbol Contributor
---
*A go to symbol contributor helps user to navigate to any PSI element by its name.*
A _Go to Symbol Contributor_ helps the user to navigate to any PSI element by its name.
### 13.1. Define helper method for generated PSI elements
To specify how a PSI element looks like in the *Go To Symbol* popup window, *Structure* tool window or another components, it should implement *getPresentation* method.
This means we need to define this method in our utility *com.simpleplugin.psi.impl.SimplePsiImplUtil* and regenerate the parser and PSI classes.
* bullet list
{:toc}
## 13.1. Define a Helper Method for Generated PSI Elements
To specify how a PSI element looks like in the **Go To Symbol** popup window, **Structure** tool window, or other components, it should implement `getPresentation()`.
This method gets defined in the utility class `SimplePsiImplUtil`, and the parser and PSI classes must be regenerated.
Add the following method to `SimplePsiImplUtil`:
```java
public static ItemPresentation getPresentation(final SimpleProperty element) {
return new ItemPresentation() {
@ -34,29 +35,35 @@ public static ItemPresentation getPresentation(final SimpleProperty element) {
}
```
### 13.2. Update grammar and regenerate the parser
## 13.2. Update Grammar and Regenerate the Parser
Now add the `SimplePsiImplUtil.getPresentation()` to the `property` methods definition in the `Simple.bnf` grammar file by replacing the `property` definition with the lines below.
Don't forget to regenerate the parser after updating the file!
Right-click on the `Simple.bnf` file and select **Generate Parser Code**.
```java
property ::= (KEY? SEPARATOR VALUE?) | KEY {mixin="com.simpleplugin.psi.impl.SimpleNamedElementImpl"
implements="com.simpleplugin.psi.SimpleNamedElement" methods=[getKey getValue getName setName getNameIdentifier getPresentation]}
property ::= (KEY? SEPARATOR VALUE?) | KEY {
mixin="org.intellij.sdk.language.psi.impl.SimpleNamedElementImpl"
implements="org.intellij.sdk.language.psi.SimpleNamedElement"
methods=[getKey getValue getName setName getNameIdentifier getPresentation]
}
```
Regenerate the parser by right clicking on the `Simple.bnf` file and selecting _Generate Parser Code_.
### 13.3. Define a go to symbol contributor
## 13.3. Define a Go to Symbol Contributor
To enable the `simple_language_plugin` to contribute items to **Navigate \| Class..., File..., Symbol...** lists, subclass [`ChooseByNameContributor`](upsource:///platform/lang-api/src/com/intellij/navigation/ChooseByNameContributor.java) to create `SimpleChooseByNameContributor`:
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleChooseByNameContributor.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleChooseByNameContributor.java %}
```
### 13.4. Register the go to symbol contributor
## 13.4. Register the Go To Symbol Contributor
The `SimpleChooseByNameContributor` implementation is registered with the IntelliJ Platform in the plugin configuration file using the `gotoSymbolContributor` extension point.
```xml
<gotoSymbolContributor implementation="com.simpleplugin.SimpleChooseByNameContributor"/>
<extensions defaultExtensionNs="com.intellij">
<gotoSymbolContributor
implementation="org.intellij.sdk.language.SimpleChooseByNameContributor"/>
</extensions>
```
### 13.5. Run the project
## 13.5. Run the Project
Rebuild the project, and run `simple_language_plugin` in a Development Instance.
The IDE now supports navigating to a property definition by name pattern via **Navigate \| Symbol** action.
Now we can navigate to a property definition by name pattern via **Navigate \| Symbol** action.
![Go To Symbol](img/go_to_symbol.png)
![Go To Symbol](img/go_to_symbol.png){:width="800px"}

View File

@ -2,40 +2,42 @@
title: 3. Grammar and Parser
---
### 3.1. Define a token type
Create a file in the `com.simpleplugin.psi` package.
In order for the IntelliJ Platform to parse a Simple Language file, [tokens and elements](/reference_guide/custom_language_support/implementing_parser_and_psi.md) must be defined based on [`IElementType`](upsource:///platform/core-api/src/com/intellij/psi/tree/IElementType.java).
The Simple Language grammar must also be defined to generate a parser.
* bullet item
{:toc}
## 3.1. Define a Token Type
Create `SimpleTokenType` in the `org.intellij.sdk.language.psi` package (see the `simple_language_plugin` code sample) by subclassing `IElementType`.
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/psi/SimpleTokenType.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleTokenType.java %}
```
### 3.2. Define an element type
Create a file in the `com.simpleplugin.psi` package.
## 3.2. Define an Element Type
Create the `SimpleElementType` in the `org.intellij.sdk.language.psi` package by subclassing `IElementType`.
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/psi/SimpleElementType.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleElementType.java %}
```
### 3.3. Define grammar
Define a grammar for the properties language with */com/simpleplugin/Simple.bnf* file.
## 3.3. Define the Grammar
Define a grammar for the Simple Language in the `com/intellij/sdk/language/Simple.bnf` file.
```java
{
parserClass="com.simpleplugin.parser.SimpleParser"
parserClass="org.intellij.sdk.language.parser.SimpleParser"
extends="com.intellij.extapi.psi.ASTWrapperPsiElement"
psiClassPrefix="Simple"
psiImplClassSuffix="Impl"
psiPackage="com.simpleplugin.psi"
psiImplPackage="com.simpleplugin.psi.impl"
psiPackage="org.intellij.sdk.language.psi"
psiImplPackage="org.intellij.sdk.language.psi.impl"
elementTypeHolderClass="com.simpleplugin.psi.SimpleTypes"
elementTypeClass="com.simpleplugin.psi.SimpleElementType"
tokenTypeClass="com.simpleplugin.psi.SimpleTokenType"
elementTypeHolderClass="org.intellij.sdk.language.psi.SimpleTypes"
elementTypeClass="org.intellij.sdk.language.psi.SimpleElementType"
tokenTypeClass="org.intellij.sdk.language.psi.SimpleTokenType"
psiImplUtilClass="org.intellij.sdk.language.psi.impl.SimplePsiImplUtil"
}
simpleFile ::= item_*
@ -45,18 +47,17 @@ private item_ ::= (property|COMMENT|CRLF)
property ::= (KEY? SEPARATOR VALUE?) | KEY
```
As you see a properties file can contain properties, comments and line breaks.
As shown, a properties file can contain properties, comments, and line breaks.
The grammar defines how flexible the support for a language can be.
We specified that a property may have or may not have key and value.
This lets the IDE still recognise incorrectly defined properties and provide corresponding code analysis and quick-fixes.
The grammar defines the flexibility of the support for a language.
The above grammar specifies that a property may have or may not have key and value.
This flexibility allows the IntelliJ Platform to recognize incorrectly defined properties and provide corresponding code analysis and quick-fixes.
Note that the `SimpleTypes` class in the `elementTypeHolderClass` field above specifies the name of a class that gets generated from the grammar, it doesn't exist at this point.
Note that the `SimpleTypes` class in the `elementTypeHolderClass` field above specifies the name of a class that gets generated from the grammar; it doesn't exist at this point.
### 3.4. Generate a parser
## 3.4. Generate a Parser
Now that the grammar is defined generate a parser with PSI classes via **Generate Parser Code** from the context menu on the *Simple.bnf* file.
This step generates a parser and PSI elements in the `/src/main/gen` folder of the project.
Mark this folder as *Generated Sources Root* and make sure everything compiles without errors.
Now when the grammar is defined we can generate a parser with PSI classes via *Generate Parser Code* from the context menu on *Simple.bnf* file.
This will generate a parser and PSI elements in *gen* folder.
Mark this folder as *Generated Sources Root* and make sure everything is compiled without errors.
![Parser](img/generated_parser.png)
![Parser](img/generated_parser.png){:width="800px"}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 226 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 70 KiB

After

Width:  |  Height:  |  Size: 423 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 318 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 42 KiB

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 150 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 86 KiB

After

Width:  |  Height:  |  Size: 242 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 264 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

After

Width:  |  Height:  |  Size: 153 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 50 KiB

After

Width:  |  Height:  |  Size: 135 KiB

View File

@ -2,63 +2,66 @@
title: 2. Language and File Type
---
The IntelliJ Platform [determines file type](/reference_guide/custom_language_support/registering_file_type.md) by examining the name of a file.
Each language has [Language](upsource:///platform/core-api/src/com/intellij/lang/Language.java) and [LanguageFileType](upsource:///platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java) objects defining the language.
Register the `LanguageFileType` with the IntelliJ Platform in the plugin configuration file.
### 2.1. Define a language
Note the case of the name of the language - `Simple`.
* bullet item
{:toc}
## 2.1. Define the Language
The language implemented in this tutorial is named "Simple" - note the case of the name.
The `SimpleLanguage` class is defined in the `org.intellij.sdk.language` package of the `simple_language_plugin` code sample:
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleLanguage.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLanguage.java %}
```
### 2.2. Define an icon
Copy the
[icon](https://raw.githubusercontent.com/JetBrains/intellij-sdk-docs/master/code_samples/simple_language_plugin/src/main/resources/icons/jar-gray.png)
to **com.simpleplugin.icons** package.
## 2.2. Define an Icon
The [icon](https://raw.githubusercontent.com/JetBrains/intellij-sdk-docs/master/code_samples/simple_language_plugin/src/com/simpleplugin/icons/jar-gray.png) for the Simple Language is defined by the `SimpleIcons` class.
There is nothing uniquely Simple Language-specific about [defining the icon](/reference_guide/work_with_icons_and_images.md) itself.
The definition follows a pattern similar to defining, e.g., `SdkIcons`.
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleIcons.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleIcons.java %}
```
### 2.3. Define a file type
## 2.3. Define a FileType
The Simple Language file type is defined by subclassing [`LanguageFileType`](upsource:///platform/core-api/src/com/intellij/openapi/fileTypes/LanguageFileType.java):
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleFileType.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileType.java %}
```
### 2.4. Define a file type factory
> **NOTE** When targeting 2019.2 or later only, please see [2.5.B](#b-register-file-type-20192-or-later)
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleFileTypeFactory.java %}
```
### 2.5. Register the file type factory
In plugin.xml add:
## 2.4. Register the FileType Directly
Direct registration is necessary when targeting version 2019.2 (and later) of the IntelliJ Platform.
No `FileTypeFactory` is required.
Instead, the file type is registered of file type is done via the `com.intellij.fileType` extension point in `plugin.xml`:
```xml
<extensions defaultExtensionNs="com.intellij">
<fileTypeFactory implementation="com.simpleplugin.SimpleFileTypeFactory"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<fileType name="Simple file" implementationClass="org.intellij.sdk.language.SimpleFileType"
fieldName="INSTANCE" language="Simple" extensions="simple"/>
</extensions>
```
### 2.5.B. Register file type (2019.2 or later)
Skip to [section 2.6](#run-the-project).
When matching via file extension, pattern or exact file name, registration of file type should be done via `com.intellij.fileType` extension point instead of implementing dedicated `FileTypeFactory`.
## 2.5. Register the FileType Using a Factory
This pattern is necessary when targeting versions of the IntelliJ Platform prior to 2019.2
### 2.5.1 Define a FileType Factory
First, define `SimpleFileTypeFactory` as a subclass of [`FileTypeFactory`](upsource:///platform/platform-api/src/com/intellij/openapi/fileTypes/FileTypeFactory.java).
```java
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleFileTypeFactory.java %}
```
### 2.5.2 Register the FileType Factory
The `SimpleFileTypeFactory` is registered with the IntelliJ Platform using the `com.intellij.openapi.fileTypes.FileTypeFactory` extension point in `plugin.xml`.
```xml
<extensions defaultExtensionNs="com.intellij">
<fileType name="Simple file" implementationClass="com.simpleplugin.SimpleFileType" fieldName="INSTANCE"
language="Simple" extensions="simple"/>
</extensions>
<extensions defaultExtensionNs="com.intellij">
<fileTypeFactory implementation="org.intellij.sdk.language.SimpleFileTypeFactory"/>
</extensions>
```
### 2.6. Run the project
## 2.6. Run the Project
Create an empty file with the extension `\*.simple`, and IntelliJ IDEA automatically associates it with our language.
Note the appearance of the Simple Language file icon next to the `test.simple` file in the **Project Tool Window**, and the editor tab for the file.
Create a file with extension *.simple*
and IntelliJ IDEA will automatically associate it with our language.
![File Type Factory](img/file_type_factory.png)
![File Type Factory](img/file_type_factory.png){:width="800px"}

View File

@ -2,57 +2,62 @@
title: 4. Lexer and Parser Definition
---
The lexer defines how the contents of a file is broken into tokens.
The lexical analyzer defines how the [contents of a file are broken into tokens](/reference_guide/custom_language_support/implementing_lexer.md), which is the basis for supporting custom language features.
The easiest way to create a lexer is to use [JFlex](https://jflex.de/)
### 4.1. Define a lexer
Define */com/simpleplugin/Simple.flex* file with rules for our lexer.
* bullet item
{:toc}
## 4.1. Define a Lexer
Define a `Simple.flex` file with rules for the Simple Language lexer, as demonstrated in `org.intellij.sdk.language.Simple.flex`.
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/Simple.flex %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/Simple.flex %}
```
### 4.2. Generate a lexer class
## 4.2. Generate a Lexer Class
Now generate a lexer class via **JFlex Generator** from the context menu on `Simple.flex` file.
Now we can generate a lexer class via *JFlex Generator* from the context menu on `Simple.flex` file.
The Grammar-Kit plugin uses JFlex lexer generation.
If you run it for the first time, it offers you to choose a folder to download the JFlex library and skeleton to.
Choose the project root directory.
The Grammar-Kit plugin uses the JFlex lexer generation.
When running for the first time, JFlex prompts for a destination folder to download the JFlex library and skeleton.
Choose the project root directory, for example `code_samples/simple_language_plugin`.
After that, the IDE generates the lexer: *com.simpleplugin.SimpleLexer*.
After that, the IDE generates the lexer under the `gen` directory, for example in `simple_language_plugin/src/main/gen/org/intellij/sdk/language/SimpleLexer`.
### 4.3. Define an adapter
See [Implementing Lexer](/reference_guide/custom_language_support/implementing_lexer.md) for more information about using _JFlex_ with the IntelliJ Platform.
## 4.3. Define a Lexer Adapter
The JFlex lexer needs to be adapted to the IntelliJ Platform Lexer API.
This is done by subclassing [`FlexAdapter`](upsource:///platform/core-api/src/com/intellij/lexer/FlexAdapter.java).
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleLexerAdapter.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLexerAdapter.java %}
```
### 4.4. Define a root file
Create the class in the `com.simpleplugin.psi` namespace.
## 4.4. Define a Root File
The `SimpleFile` implementation is the top-level node of the [tree of `PsiElements`](/reference_guide/custom_language_support/implementing_parser_and_psi.md) for a Simple Language file.
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/psi/SimpleFile.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/psi/SimpleFile.java %}
```
### 4.5. Define a parser definition
## 4.5. Define a Parser
The Simple Language parser is defined by subclassing [`ParserDefinition`](upsource:///platform/core-api/src/com/intellij/lang/ParserDefinition.java).
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleParserDefinition.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleParserDefinition.java %}
```
### 4.6. Register the parser definition
## 4.6. Register the Parser Definition
Registering the parser definition in the `plugin.xml` file makes it available to the IntelliJ Platform.
Use the `lang.parserDefinition` extension point for registration.
For example, see `simple_language_plugin/src/main/resources/META-INF/plugin.xml`.
```xml
<lang.parserDefinition language="Simple" implementationClass="com.simpleplugin.SimpleParserDefinition"/>
<extensions defaultExtensionNs="com.intellij">
<lang.parserDefinition language="Simple"
implementationClass="org.intellij.sdk.language.SimpleParserDefinition"/>
</extensions>
```
### 4.7. Run the project
Create a properties file with the following content:
```
## 4.7. Run the Project
With the `simple_language_plugin` loaded in a Development Instance, create a `test.simple` properties file with the following content:
```text
# You are reading the ".properties" entry.
! The exclamation mark can also mark text as comments.
website = http://en.wikipedia.org/
@ -69,4 +74,4 @@ tab : \u0009
Now open the *PsiViewer* tool window and check how the lexer breaks the content of the file into tokens, and the parser parsed the tokens into PSI elements.
![PSI Elements](img/psi_elements.png)
![PSI Elements](img/psi_elements.png){:width="900px"}

View File

@ -2,31 +2,37 @@
title: 8. Line Marker Provider
---
Line markers help to annotate any code with icons on the gutter.
These icons may provide navigation to related code.
Line markers help annotate code with icons on the gutter.
These markers can provide navigation targets to related code.
### 8.1. Define a line marker provider
* bullet list
{:toc}
Let's annotate usages of our properties within Java code and provide navigation to the definition of these properties.
## 8.1. Define a Line Marker Provider
A line marker provider annotates usages of Simple Language properties within Java code and provides navigation to the definition of these properties.
The visual marker is a Simple Language icon in the gutter of the Editor window.
The Simple Language marker provider subclasses [`RelatedItemLineMarkerProvider`](upsource:///platform/lang-api/src/com/intellij/codeInsight/daemon/RelatedItemLineMarkerProvider.java).
For this example, override the `collectNavigationMarkers()` method to collect usage of a Simple Language [key and separators](/tutorials/custom_language_support/language_and_filetype.md#define-the-language):
```java
{% include /code_samples/simple_language_plugin/src/main/java/com/intellij/sdk/language/SimpleLineMarkerProvider.java %}
{% include /code_samples/simple_language_plugin/src/main/java/org/intellij/sdk/language/SimpleLineMarkerProvider.java %}
```
## More technical details for implementers
* Please return line marker info for exact element you were asked for.
For example, do not return class marker info if `getLineMarkerInfo()` was called for a method.
* Please return relevant line marker info for as small element as possible.
For example, do not return method marker for [`PsiMethod`](upsource:///java/java-psi-api/src/com/intellij/psi/PsiMethod.java). Instead, return it for the [`PsiIdentifier`](upsource:///java/java-psi-api/src/com/intellij/psi/PsiIdentifier.java) which is a name of this method.
### Even more technical details:
What happens when `LineMarkerProvider` returns something for too big PsiElement?
## 8.2. Best Practices for Implementing Line Marker Providers
This section addresses important details about implementing a marker provider.
The `collectNavigationMarkers()` method should:
* Only return line marker information consistent with the element passed into the method.
For example, do not return a _class_ marker if `getLineMarkerInfo()` was called with an element that corresponds to a _method_.
* Return line marker information for the appropriate element at the correct scope of the PSI tree.
For example, do not return method marker for [`PsiMethod`](upsource:///java/java-psi-api/src/com/intellij/psi/PsiMethod.java).
Instead, return it for the [`PsiIdentifier`](upsource:///java/java-psi-api/src/com/intellij/psi/PsiIdentifier.java) which contains the name of the method.
![Line Marker Location](img/line_marker_location.png){:width="900px"}
What happens when a `LineMarkerProvider` returns marker information for a `PsiElement` that is a higher node in the PSI tree?
For example, if `MyWrongLineMarkerProvider()` erroneously returns a `PsiMethod` instead of a `PsiIdentifier` element:
```java
public class MyLineMarkerProvider implements LineMarkerProvider {
public class MyWrongLineMarkerProvider implements LineMarkerProvider {
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
if (element instanceof PsiMethod) return new LineMarkerInfo(element, ...);
return null;
@ -34,25 +40,20 @@ public class MyLineMarkerProvider implements LineMarkerProvider {
}
```
Inspection (specifically, [`LineMarkersPass`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java)) for performance reasons queries all [`LineMarkerProviders`](upsource:///platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerProviders.java) in two passes:
The consequences of the `MyWrongLineMarkerProvider()` implementation have to do with how the IntelliJ Platform performs inspections.
For performance reasons, inspection, and specifically the [`LineMarkersPass`](upsource:///platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LineMarkersPass.java) queries all [`LineMarkerProviders`](upsource:///platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerProviders.java) in two phases:
* The first pass is for all elements visible in the Editor window,
* The second pass is for the rest of the elements in the file.
* first pass for all elements in visible area
* second pass for all the rest elements
If providers return nothing for either area, its line markers are cleared.
So if e.g. a method is half-visible (its name is visible but part of its body isn't) and
some poorly written [`LineMarkerProvider`](upsource:///platform/lang-api/src/com/intellij/codeInsight/daemon/LineMarkerProvider.java) returned info for the `PsiMethod` instead of `PsiIdentifier` then:
* the first pass removes line marker info because whole `PsiMethod` is not visible.
* the second pass tries to add line marker info back because `LineMarkerProvider` is called for the `PsiMethod` at last.
As a result, line marker icon would blink annoyingly.
To fix this, rewrite `LineMarkerProvider` to return info for `PsiIdentifier` instead of `PsiMethod`:
If providers return nothing for either area, the line markers get cleared.
However, if a method like `actionPerformed()` is not completely visible in the Editor window (as shown in the image above,) and `MyWrongLineMarkerProvider()` returns marker info for the `PsiMethod` instead of `PsiIdentifier`, then:
* The first pass removes line marker info because whole `PsiMethod` isn't visible.
* The second pass tries to add a line marker because `MyWrongLineMarkerProvider()` is called for the `PsiMethod`.
As a result, _the line marker icon would blink annoyingly_.
To fix this problem, rewrite `MyWrongLineMarkerProvider` to return info for `PsiIdentifier` instead of `PsiMethod` as shown below:
```java
public class MyLineMarkerProvider implements LineMarkerProvider {
public class MyCorrectLineMarkerProvider implements LineMarkerProvider {
public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
if (element instanceof PsiIdentifier && element.getParent() instanceof PsiMethod) return new LineMarkerInfo(element, ...);
return null;
@ -60,14 +61,18 @@ public class MyLineMarkerProvider implements LineMarkerProvider {
}
```
### 8.2. Register the line marker provider
## 8.3. Register the Line Marker Provider
The `SimpleLineMarkerProvider` implementation is registered with the IntelliJ Platform in the plugin configuration file using the `codeInsight.lineMarkerProvider` extension point.
```xml
<codeInsight.lineMarkerProvider language="JAVA" implementationClass="com.simpleplugin.SimpleLineMarkerProvider"/>
<extensions defaultExtensionNs="com.intellij">
<codeInsight.lineMarkerProvider language="JAVA"
implementationClass="org.intellij.sdk.language.SimpleLineMarkerProvider"/>
</extensions>
```
### 8.3. Run the project
Now you see the icon on the gutter and can navigate to the property definition.
## 8.4. Run the Project
Run the `simple_language_plugin` in a Development Instance and open the [Test file](/tutorials/custom_language_support/annotator.md#run-the-project).
Now the icon appears next to line 3 on the gutter.
A user can click on the icon to navigate to the property definition.
![Line Marker](img/line_marker.png)

View File

@ -2,32 +2,16 @@
title: 1. Prerequisites
---
### 1.1. Download and Install IntelliJ IDEA
Download and install either IntelliJ IDEA Ultimate or IntelliJ IDEA Community Edition as described on the
[Creating Your First Plugin](/basics/getting_started.md) page.
Download and install either IntelliJ IDEA Ultimate or IntelliJ IDEA Community Edition as described on the [Creating Your First Plugin](/basics/getting_started.md) page.
### 1.2. Check out Community Edition Source Files
Download the IntelliJ IDEA Community Edition source files as described in the IntelliJ IDEA Community Edition
[README](upsource:///README.md) file.
Download the IntelliJ IDEA Community Edition source files as described in the IntelliJ IDEA Community Edition [README](upsource:///README.md) file.
### 1.3. Install Required Plugins
Make sure that the bundled *Plugin DevKit* plugin is enabled.
Install and enable
[Grammar-Kit](https://plugins.jetbrains.com/plugin/6606-grammar-kit)
and
[PsiViewer](https://plugins.jetbrains.com/plugin/227-psiviewer)
plugins.
Install and enable [Grammar-Kit](https://plugins.jetbrains.com/plugin/6606-grammar-kit) and [PsiViewer](https://plugins.jetbrains.com/plugin/227-psiviewer) plugins.
### 1.4. Configure the SDK and Source Files
Configure a common [JDK](upsource:///README.md)
and an [IntelliJ Platform SDK](/basics/getting_started/setting_up_environment.md).
### 1.5. Create a Project
Create an [IntelliJ Platform Plugin project](/basics/getting_started/creating_plugin_project.md).
### 1.4. Create a Project
Create an [IntelliJ Platform Plugin project](/tutorials/build_system/prerequisites.md).

Some files were not shown because too many files have changed in this diff Show More