Skip to content
Snippets Groups Projects
Commit 9448d05a authored by Johannes Mey's avatar Johannes Mey
Browse files

Merge branch 'feature/structure-view-support' into 'develop'

Resolve "Structure View Support"

Closes #3

See merge request !5
parents a944a191 927d293e
No related branches found
No related tags found
1 merge request!5Resolve "Structure View Support"
Pipeline #12053 passed
Showing
with 828 additions and 85 deletions
......@@ -34,7 +34,11 @@ modifiers ::= (PUBLIC | STATIC | PROTECTED | PRIVATE | FINAL | ABSTRACT | SYNCH
type_declaration ::= SEMICOLON | (modifiers ( class_declaration | interface_declaration | unmodified_enum_declaration | annotation_type_declaration | aspect_declaration ) )
aspect_declaration ::= ASPECT IDENTIFIER aspect_body
aspect_declaration ::= ASPECT aspect_name aspect_body
{
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectAspectDeclarationImplExtension"
implements="org.jastadd.tooling.common.psi.NamedElement"
}
aspect_body ::= LBRACE aspect_body_declaration* RBRACE
......@@ -70,7 +74,7 @@ aspect_class_declaration ::= modifiers class_declaration
// aspect_class_body unused
aspect_interface_declaration ::= modifiers INTERFACE IDENTIFIER type_parameters? (EXTENDS type_name_list)? LBRACE aspect_interface_member_declaration* RBRACE
aspect_interface_declaration ::= modifiers INTERFACE simple_type_name type_parameters? (EXTENDS type_name_list)? LBRACE aspect_interface_member_declaration* RBRACE
aspect_interface_member_declaration ::= ( aspect_nested_class_declaration
| aspect_nested_interface_declaration
......@@ -79,16 +83,16 @@ aspect_interface_member_declaration ::= ( aspect_nested_class_declaration
| aspect_interface_method_declaration
| aspect_interface_field_declaration )
aspect_interface_syn_attribute_declaration ::= annotation* SYN LAZY? FINAL? aspect_type attribute_name LPAREN (type IDENTIFIER (COMMA type IDENTIFIER)* )? RPAREN (CIRCULAR LBRACKET expression RBRACKET)? SEMICOLON
aspect_interface_syn_attribute_declaration ::= annotation* SYN LAZY? FINAL? aspect_type attribute_name LPAREN (type parameter_name (COMMA type parameter_name)* )? RPAREN (CIRCULAR LBRACKET expression RBRACKET)? SEMICOLON
{
implements="org.jastadd.tooling.aspect.psi.JastAddAspectAttribute"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectSynAttributeImpl"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectAspectSynAttributeDeclarationImplExtension"
}
aspect_interface_inh_attribute_declaration ::= annotation* INH LAZY? FINAL? aspect_type attribute_name LPAREN (type IDENTIFIER (COMMA type IDENTIFIER)* )? RPAREN (CIRCULAR LBRACKET expression RBRACKET)? SEMICOLON
aspect_interface_inh_attribute_declaration ::= annotation* INH LAZY? FINAL? aspect_type attribute_name LPAREN (type parameter_name (COMMA type parameter_name)* )? RPAREN (CIRCULAR LBRACKET expression RBRACKET)? SEMICOLON
{
implements="org.jastadd.tooling.aspect.psi.JastAddAspectAttribute"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectInhAttributeImpl"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectAspectInhAttributeDeclarationImplExtension"
}
aspect_interface_method_declaration ::= (PUBLIC | PROTECTED | PRIVATE | STATIC | ABSTRACT | FINAL | NATIVE | SYNCHRONIZED )* aspect_result_type method_declarator (THROWS name_list)? SEMICOLON
......@@ -103,41 +107,41 @@ aspect_nested_class_declaration ::= modifiers class_declaration
aspect_method_declaration ::= modifiers type_parameters? aspect_result_type ast_type_name DOT method_declarator (THROWS name_list)? (block | SEMICOLON)
aspect_refine_method_declaration ::= REFINE [IDENTIFIER] modifiers type_parameters? aspect_result_type IDENTIFIER DOT method_declarator (THROWS name_list)? (block | SEMICOLON)
aspect_refine_method_declaration ::= REFINE [aspect_name] modifiers type_parameters? aspect_result_type ast_type_name DOT method_declarator (THROWS name_list)? (block | SEMICOLON)
aspect_constructor_declaration ::= modifiers ast_type_name DOT ast_type_name formal_parameters (THROWS name_list)? LBRACE explicit_constructor_invocation? block_statement* RBRACE
aspect_refine_constructor_declaration ::= REFINE IDENTIFIER (PUBLIC | PROTECTED | PRIVATE) ast_type_name DOT IDENTIFIER formal_parameters (THROWS name_list)? LBRACE block_statement* RBRACE
aspect_refine_constructor_declaration ::= REFINE aspect_name (PUBLIC | PROTECTED | PRIVATE) ast_type_name DOT method_name formal_parameters (THROWS name_list)? LBRACE block_statement* RBRACE
aspect_field_declaration ::= modifiers aspect_type ast_type_name DOT variable_declarator (COMMA variable_declarator)* SEMICOLON
aspect_syn_attribute_declaration ::= annotation* SYN NTA? LAZY? FINAL? aspect_type ast_type_name DOT attribute_name LPAREN (type IDENTIFIER (COMMA type IDENTIFIER)* )? RPAREN (CIRCULAR LBRACKET expression RBRACKET)? ( ASSIGN expression SEMICOLON | block | SEMICOLON )
aspect_syn_attribute_declaration ::= annotation* SYN NTA? LAZY? FINAL? aspect_type ast_type_name DOT attribute_name LPAREN (type parameter_name (COMMA type parameter_name)* )? RPAREN (CIRCULAR LBRACKET expression RBRACKET)? ( ASSIGN expression SEMICOLON | block | SEMICOLON )
{
implements="org.jastadd.tooling.aspect.psi.JastAddAspectAttribute"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectSynAttributeImpl"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectAspectSynAttributeDeclarationImplExtension"
}
aspect_inh_attribute_declaration ::= annotation* INH NTA? LAZY? FINAL? aspect_type ast_type_name DOT attribute_name LPAREN (type IDENTIFIER (COMMA type IDENTIFIER)* )? RPAREN (CIRCULAR LBRACKET expression RBRACKET)? SEMICOLON
aspect_inh_attribute_declaration ::= annotation* INH NTA? LAZY? FINAL? aspect_type ast_type_name DOT attribute_name LPAREN (type parameter_name (COMMA type parameter_name)* )? RPAREN (CIRCULAR LBRACKET expression RBRACKET)? SEMICOLON
{
implements="org.jastadd.tooling.aspect.psi.JastAddAspectAttribute"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectInhAttributeImpl"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectAspectInhAttributeDeclarationImplExtension"
}
// FIXME parentheses are not required around the WHEN expression?
aspect_rewrite ::= REWRITE IDENTIFIER (ast_type_name DOT IDENTIFIER LPAREN RPAREN)? LBRACE ((WHEN LPAREN expression RPAREN)? TO aspect_type ( expression SEMICOLON | block ))+ RBRACE
aspect_rewrite ::= REWRITE ast_type_name (ast_type_name DOT method_name LPAREN RPAREN)? LBRACE ((WHEN LPAREN expression RPAREN)? TO aspect_type ( expression SEMICOLON | block ))+ RBRACE
aspect_syn_equation ::= annotation* EQUATION ast_type_name DOT attribute_name LPAREN (type IDENTIFIER (COMMA type IDENTIFIER)*)? RPAREN ( ASSIGN expression SEMICOLON | block )
aspect_syn_equation ::= annotation* EQUATION ast_type_name DOT attribute_name LPAREN (type parameter_name (COMMA type parameter_name)*)? RPAREN ( ASSIGN expression SEMICOLON | block )
aspect_refine_syn_equation ::= REFINE IDENTIFIER EQUATION ast_type_name DOT attribute_name LPAREN (type IDENTIFIER (COMMA type IDENTIFIER)*)? RPAREN (ASSIGN expression SEMICOLON | block)
aspect_refine_syn_equation ::= REFINE aspect_name EQUATION ast_type_name DOT attribute_name LPAREN (type parameter_name (COMMA type parameter_name)*)? RPAREN (ASSIGN expression SEMICOLON | block)
aspect_inh_equation ::= annotation* EQUATION ast_type_name DOT IDENTIFIER LPAREN (INT IDENTIFIER)? RPAREN DOT attribute_name LPAREN (type IDENTIFIER (COMMA type IDENTIFIER)*)? RPAREN (ASSIGN expression SEMICOLON | block)
aspect_inh_equation ::= annotation* EQUATION ast_type_name DOT attribute_name LPAREN (INT parameter_name)? RPAREN DOT attribute_name LPAREN (type parameter_name (COMMA type parameter_name)*)? RPAREN (ASSIGN expression SEMICOLON | block)
aspect_refine_inh_equation ::= REFINE IDENTIFIER EQUATION ast_type_name DOT IDENTIFIER LPAREN (INT IDENTIFIER)? RPAREN DOT attribute_name LPAREN (type IDENTIFIER (COMMA type IDENTIFIER)*)? RPAREN (ASSIGN expression SEMICOLON | block)
aspect_refine_inh_equation ::= REFINE aspect_name EQUATION ast_type_name DOT attribute_name LPAREN (INT parameter_name)? RPAREN DOT attribute_name LPAREN (type parameter_name (COMMA type parameter_name)*)? RPAREN (ASSIGN expression SEMICOLON | block)
collection_attribute ::= annotation* COLL aspect_type ast_type_name DOT attribute_name LPAREN RPAREN CIRCULAR? (LBRACKET expression RBRACKET)? (WITH IDENTIFIER)? (ROOT IDENTIFIER)? SEMICOLON
collection_attribute ::= annotation* COLL aspect_type ast_type_name DOT attribute_name LPAREN RPAREN CIRCULAR? (LBRACKET expression RBRACKET)? (WITH method_name)? (ROOT ast_type_name)? SEMICOLON
{
implements="org.jastadd.tooling.aspect.psi.JastAddAspectAttribute"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectCollAttributeImpl"
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectCollectionAttributeImplExtension"
}
collection_contribution ::= annotation* ast_type_name CONTRIBUTES ( NTA expression TO ast_type_name DOT attribute_name LPAREN RPAREN | EACH? expression (WHEN expression)? TO ast_type_name DOT attribute_name LPAREN RPAREN (FOR EACH? expression)? | block TO ast_type_name DOT attribute_name LPAREN RPAREN ) SEMICOLON
......@@ -146,14 +150,14 @@ aspect_add_interface ::= ast_type_name IMPLEMENTS type_name_list SEMICOLON
aspect_extend_interface ::= ast_type_name EXTENDS type_name_list SEMICOLON
class_declaration ::= CLASS IDENTIFIER type_parameters? (EXTENDS class_or_interface_type)? (implements type_name_list)? class_body
class_declaration ::= CLASS simple_type_name type_parameters? (EXTENDS class_or_interface_type)? (implements type_name_list)? class_body
type_name_list ::= class_or_interface_type (COMMA class_or_interface_type)*
unmodified_class_declaration ::= CLASS IDENTIFIER type_parameters? (EXTENDS class_or_interface_type)? (IMPLEMENTS type_name_list)? class_body
unmodified_class_declaration ::= CLASS simple_type_name type_parameters? (EXTENDS class_or_interface_type)? (IMPLEMENTS type_name_list)? class_body
// TODO check simplification
aspect_enum_declaration ::= modifiers ENUM IDENTIFIER (IMPLEMENTS type_name_list)? enum_body
aspect_enum_declaration ::= modifiers ENUM simple_type_name (IMPLEMENTS type_name_list)? enum_body
unmodified_enum_declaration ::= ENUM java_identifier (IMPLEMENTS type_name_list)? enum_body
......@@ -173,7 +177,7 @@ class_body_declaration ::= initializer | modifiers ( unmodified_class_declaratio
interface_declaration ::= unmodified_interface_declaration
unmodified_interface_declaration ::= INTERFACE IDENTIFIER type_parameters? (EXTENDS type_name_list)? LBRACE interface_member_declaration* RBRACE
unmodified_interface_declaration ::= INTERFACE simple_type_name type_parameters? (EXTENDS type_name_list)? LBRACE interface_member_declaration* RBRACE
interface_member_declaration ::= modifiers (unmodified_class_declaration | unmodified_interface_declaration | field_declaration | method_declaration) | SEMICOLON
......@@ -217,7 +221,7 @@ reference_type ::= ( primitive_type (LBRACKET RBRACKET)+ ) | ( class_or_interfac
class_or_interface_type ::= java_identifier type_arguments? (DOT java_identifier type_arguments? )*
{
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectClassOrInterfaceTypeImplExtension"
implements="org.jastadd.tooling.grammar.psi.GrammarNamedElement"
implements="org.jastadd.tooling.common.psi.NamedElement"
}
type_arguments ::= LT (type_argument (COMMA type_argument)* )? GT
......@@ -384,7 +388,7 @@ annotation_type_member_declaration ::= ( modifiers (aspect_type java_identifier
default_value ::= DEFAULT member_value
aspect_cache_declaration ::= (CACHE | UNCACHE) IDENTIFIER DOT attribute_name LPAREN (type IDENTIFIER? (COMMA type IDENTIFIER?)* )? RPAREN SEMICOLON
aspect_cache_declaration ::= (CACHE | UNCACHE) aspect_name DOT attribute_name LPAREN (type parameter_name? (COMMA type parameter_name?)* )? RPAREN SEMICOLON
java_identifier ::= IDENTIFIER | INH | SYN | LAZY | REWRITE | TO | WHEN | ASPECT | EQUATION | CIRCULAR | REFINE | COLL | CONTRIBUTES | EACH | NTA | CACHE | UNCACHE
......@@ -393,8 +397,16 @@ attribute_name ::= IDENTIFIER
ast_type_name ::= IDENTIFIER
{
extends="org.jastadd.tooling.aspect.psi.impl.JastAddAspectAstTypeNameImplExtension"
implements="org.jastadd.tooling.grammar.psi.GrammarNamedElement"
implements="org.jastadd.tooling.common.psi.NamedElement"
}
aspect_name ::= IDENTIFIER
simple_type_name ::= IDENTIFIER
parameter_name ::= IDENTIFIER
method_name ::= IDENTIFIER
// unused keywords must still appear somewhere
unused_keywords ::= GOTO | CONST ELLIPSIS | PACKAGE
......@@ -22,7 +22,7 @@ comment ::= (WHITESPACE | MULTILINECOMMENT | DOCCOMMENT | SINGLELINECOMMENT)
type_decl ::= ABSTRACT? type_name (COL type_name)? (ASSIGN (component | nta_component)*)? SCOL
{
extends="org.jastadd.tooling.grammar.psi.impl.GrammarTypeDeclImplExtension"
implements="org.jastadd.tooling.grammar.psi.GrammarNamedElement"
implements="org.jastadd.tooling.common.psi.NamedElement"
}
nta_component ::= SLASH component SLASH
......@@ -47,13 +47,13 @@ navigable_role ::= type_name DOT component_name (STAR | QUESTION_MARK)?
type_name ::= ID
{
extends="org.jastadd.tooling.grammar.psi.impl.GrammarTypeNameImplExtension"
implements="org.jastadd.tooling.grammar.psi.GrammarNamedElement"
implements="org.jastadd.tooling.common.psi.NamedElement"
}
component_name ::= ID
{
extends="org.jastadd.tooling.grammar.psi.impl.GrammarComponentNameImplExtension"
implements="org.jastadd.tooling.grammar.psi.GrammarNamedElement"
implements="org.jastadd.tooling.common.psi.NamedElement"
}
......
package org.jastadd.tooling.aspect;
import com.intellij.icons.AllIcons;
import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.smartTree.SortableTreeElement;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import org.jastadd.tooling.aspect.psi.*;
import org.jastadd.tooling.aspect.psi.impl.*;
import org.jastadd.tooling.util.JastAddIcons;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.Objects;
import java.util.stream.Collectors;
public class AspectStructureViewElement implements StructureViewTreeElement, SortableTreeElement {
private final NavigatablePsiElement myElement;
public AspectStructureViewElement(NavigatablePsiElement element) {
this.myElement = element;
}
@Override
public NavigatablePsiElement getValue() {
return myElement;
}
@Override
public void navigate(boolean requestFocus) {
myElement.navigate(requestFocus);
}
@Override
public boolean canNavigate() {
return myElement.canNavigate();
}
@Override
public boolean canNavigateToSource() {
return myElement.canNavigateToSource();
}
@NotNull
@Override
public String getAlphaSortKey() {
String name = myElement.getName();
return name != null ? name : "";
}
@NotNull
@Override
public ItemPresentation getPresentation() {
ItemPresentation presentation = myElement.getPresentation();
if (presentation == null) {
if (myElement instanceof JastAddAspectAspectMethodDeclaration) {
presentation = new ItemPresentation() {
@Override
public String getPresentableText() {
return AspectStructureViewElement.getPresentableText((JastAddAspectAspectMethodDeclaration) myElement);
}
@Override
public Icon getIcon(boolean unused) {
return AllIcons.Nodes.Method;
}
};
} else if (myElement instanceof JastAddAspectAspectClassDeclaration) {
presentation = new ItemPresentation() {
@Override
public String getPresentableText() {
return AspectStructureViewElement.getPresentableText((JastAddAspectAspectClassDeclaration) myElement);
}
@Override
public Icon getIcon(boolean unused) {
return AllIcons.Nodes.Class;
}
};
} else if (myElement instanceof JastAddAspectAspectEnumDeclaration) {
presentation = new ItemPresentation() {
@Override
public String getPresentableText() {
return AspectStructureViewElement.getPresentableText((JastAddAspectAspectEnumDeclaration) myElement);
}
@Override
public Icon getIcon(boolean unused) {
return AllIcons.Nodes.Enum;
}
};
} else if (myElement instanceof JastAddAspectAspectInterfaceDeclaration) {
presentation = new ItemPresentation() {
@Override
public String getPresentableText() {
return AspectStructureViewElement.getPresentableText((JastAddAspectAspectInterfaceDeclaration) myElement);
}
@Override
public Icon getIcon(boolean unused) {
return AllIcons.Nodes.Interface;
}
};
} else if (myElement instanceof JastAddAspectAspectFieldDeclaration) {
presentation = new ItemPresentation() {
@Override
public String getPresentableText() {
return AspectStructureViewElement.getPresentableText((JastAddAspectAspectFieldDeclaration) myElement);
}
@Override
public Icon getIcon(boolean unused) {
return AllIcons.Nodes.Field;
}
};
} else if (myElement instanceof JastAddAspectAspectConstructorDeclaration) {
presentation = new ItemPresentation() {
@Override
public String getPresentableText() {
return AspectStructureViewElement.getPresentableText((JastAddAspectAspectConstructorDeclaration) myElement);
}
@Override
public Icon getIcon(boolean unused) {
return AllIcons.Nodes.Method;
}
};
} else if (myElement instanceof JastAddAspectAspectRewrite) {
presentation = new ItemPresentation() {
@Override
public String getPresentableText() {
return AspectStructureViewElement.getPresentableText((JastAddAspectAspectRewrite) myElement);
}
@Override
public Icon getIcon(boolean unused) {
return JastAddIcons.REWRITE;
}
};
}
}
return presentation != null ? presentation : new PresentationData();
}
private static String getPresentableText(JastAddAspectAspectClassDeclaration decl) {
return decl.getModifiers().getText()
+ " class " + decl.getClassDeclaration().getSimpleTypeName().getText();
}
private static String getPresentableText(JastAddAspectAspectEnumDeclaration decl) {
return decl.getModifiers().getText()
+ " class " + decl.getSimpleTypeName().getText();
}
private static String getPresentableText(JastAddAspectAspectInterfaceDeclaration decl) {
return decl.getModifiers().getText()
+ " class " + decl.getSimpleTypeName().getText();
}
private static String getPresentableText(JastAddAspectAspectFieldDeclaration decl) {
return decl.getModifiers().getText()
+ " " + decl.getAstTypeName().getText()
+ " : " + decl.getAspectType().getText();
}
private static String getPresentableText(JastAddAspectAspectRewrite rewrite) {
return "rewrite " + rewrite.getAstTypeNameList().get(0).getText()
+ " to " + rewrite.getAspectTypeList().stream().map(JastAddAspectAspectType::getText).collect(Collectors.joining("/"));
}
private static String getPresentableText(JastAddAspectAspectConstructorDeclaration decl) {
return decl.getModifiers().getText()
+ " " + decl.getAstTypeNameList().get(0).getText()
+ "." + decl.getAstTypeNameList().get(1).getText()
+ decl.getFormalParameters().getFormalParameterList().stream()
.map(JastAddAspectFormalParameter::getType)
.map(PsiElement::getText).collect(Collectors.joining(", ", "(", ")"));
}
private static String getPresentableText(JastAddAspectAspectMethodDeclaration decl) {
return decl.getModifiers().getText()
+ " " + decl.getAstTypeName().getText()
+ "." + AspectStructureViewElement.getPresentableText(decl.getMethodDeclarator()) + " : "
+ decl.getAspectResultType().getText();
}
private static String getPresentableText(JastAddAspectMethodDeclarator declarator) {
return declarator.getJavaIdentifier().getText()
+ declarator.getFormalParameters().getFormalParameterList().stream()
.map(JastAddAspectFormalParameter::getType)
.map(PsiElement::getText).collect(Collectors.joining(", ", "(", ")"));
}
@Override
public TreeElement @NotNull [] getChildren() {
if (myElement instanceof AspectFile) {
return PsiTreeUtil.getChildrenOfTypeAsList(myElement, JastAddAspectTypeDeclaration.class)
.stream()
.map(JastAddAspectTypeDeclaration::getAspectDeclaration)
.filter(Objects::nonNull)
.map(decl -> new AspectStructureViewElement((JastAddAspectAspectDeclarationImpl) decl))
.toArray(TreeElement[]::new);
} else if (myElement instanceof JastAddAspectAspectDeclaration) {
return PsiTreeUtil.getChildrenOfTypeAsList(((JastAddAspectAspectDeclaration) myElement).getAspectBody(), JastAddAspectAspectBodyDeclaration.class)
.stream()
.map(decl -> {
if (decl.getAspectSynAttributeDeclaration() != null) {
return new AspectStructureViewElement((JastAddAspectAspectSynAttributeDeclarationImpl) decl.getAspectSynAttributeDeclaration());
} else if (decl.getAspectInhAttributeDeclaration() != null) {
return new AspectStructureViewElement((JastAddAspectAspectInhAttributeDeclarationImpl) decl.getAspectInhAttributeDeclaration());
} else if (decl.getCollectionAttribute() != null) {
return new AspectStructureViewElement((JastAddAspectCollectionAttributeImpl) decl.getCollectionAttribute());
} else if (decl.getAspectMethodDeclaration() != null) {
return new AspectStructureViewElement((JastAddAspectAspectMethodDeclarationImpl) decl.getAspectMethodDeclaration());
} else if (decl.getAspectClassDeclaration() != null) {
return new AspectStructureViewElement((JastAddAspectAspectClassDeclarationImpl) decl.getAspectClassDeclaration());
} else if (decl.getAspectEnumDeclaration() != null) {
return new AspectStructureViewElement((JastAddAspectAspectEnumDeclarationImpl) decl.getAspectEnumDeclaration());
} else if (decl.getAspectInterfaceDeclaration() != null) {
return new AspectStructureViewElement((JastAddAspectAspectInterfaceDeclarationImpl) decl.getAspectInterfaceDeclaration());
} else if (decl.getAspectFieldDeclaration() != null) {
return new AspectStructureViewElement((JastAddAspectAspectFieldDeclarationImpl) decl.getAspectFieldDeclaration());
} else if (decl.getAspectConstructorDeclaration() != null) {
return new AspectStructureViewElement((JastAddAspectAspectConstructorDeclarationImpl) decl.getAspectConstructorDeclaration());
} else if (decl.getAspectRewrite() != null) {
return new AspectStructureViewElement((JastAddAspectAspectRewriteImpl) decl.getAspectRewrite());
}
// missing cases include:
// aspect_refine_method_declaration
// aspect_refine_constructor_declaration
// aspect_add_interface
// aspect_extend_interface
return null;
})
.filter(Objects::nonNull)
.toArray(TreeElement[]::new);
}
return EMPTY_ARRAY;
}
}
package org.jastadd.tooling.aspect;
import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.structureView.StructureViewModel;
import com.intellij.ide.structureView.TreeBasedStructureViewBuilder;
import com.intellij.lang.PsiStructureViewFactory;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AspectStructureViewFactory implements PsiStructureViewFactory {
@Nullable
@Override
public StructureViewBuilder getStructureViewBuilder(@NotNull final PsiFile psiFile) {
return new TreeBasedStructureViewBuilder() {
@NotNull
@Override
public StructureViewModel createStructureViewModel(@Nullable Editor editor) {
return new AspectStructureViewModel(psiFile);
}
};
}
}
package org.jastadd.tooling.aspect;
import com.intellij.ide.structureView.StructureViewModel;
import com.intellij.ide.structureView.StructureViewModelBase;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.smartTree.Filter;
import com.intellij.ide.util.treeView.smartTree.Grouper;
import com.intellij.ide.util.treeView.smartTree.Sorter;
import com.intellij.psi.PsiFile;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectDeclaration;
import org.jastadd.tooling.aspect.psi.JastAddAspectAttribute;
import org.jetbrains.annotations.NotNull;
public class AspectStructureViewModel extends StructureViewModelBase implements
StructureViewModel.ElementInfoProvider {
public AspectStructureViewModel(PsiFile psiFile) {
super(psiFile, new AspectStructureViewElement(psiFile));
}
@NotNull
public Sorter @NotNull [] getSorters() {
return new Sorter[]{Sorter.ALPHA_SORTER};
}
@Override
public boolean isAlwaysShowsPlus(StructureViewTreeElement element) {
return element.getValue() instanceof JastAddAspectAspectDeclaration;
}
@Override
public boolean isAlwaysLeaf(StructureViewTreeElement element) {
return element.getValue() instanceof JastAddAspectAttribute;
}
@Override
public Grouper @NotNull [] getGroupers() {
// TODO group by member type
return new Grouper[]{};
}
@Override
public Filter @NotNull [] getFilters() {
return new Filter[]{new JastAddAspectAttributeFilter(), new JastAddAspectIntertypeFilter(), new JastAddAspectRewriteFilter()};
}
}
package org.jastadd.tooling.aspect;
import com.intellij.ide.util.treeView.smartTree.ActionPresentation;
import com.intellij.ide.util.treeView.smartTree.ActionPresentationData;
import com.intellij.ide.util.treeView.smartTree.Filter;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectDeclaration;
import org.jastadd.tooling.aspect.psi.JastAddAspectAttribute;
import org.jastadd.tooling.util.JastAddIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class JastAddAspectAttributeFilter implements Filter {
@NonNls
public static final String ID = "HIDE_ATTRIBUTE";
@Override
public boolean isVisible(TreeElement treeNode) {
if (treeNode instanceof AspectStructureViewElement) {
return !(((AspectStructureViewElement) treeNode).getValue() instanceof JastAddAspectAttribute);
}
else {
return true;
}
}
@Override
@NotNull
public ActionPresentation getPresentation() {
// TODO use i18n and string bundle like JavaStructureViewBundle
return new ActionPresentationData("Hide Attributes", null, JastAddIcons.ATTRIBUTE);
}
@Override
@NotNull
public String getName() {
return ID;
}
@Override
public boolean isReverted() {
return false;
}
}
package org.jastadd.tooling.aspect;
import com.intellij.ide.util.treeView.smartTree.ActionPresentation;
import com.intellij.ide.util.treeView.smartTree.ActionPresentationData;
import com.intellij.ide.util.treeView.smartTree.Filter;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectEnumDeclaration;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectFieldDeclaration;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectInterfaceDeclaration;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectMethodDeclaration;
import org.jastadd.tooling.aspect.psi.impl.JastAddAspectAspectClassDeclarationImpl;
import org.jastadd.tooling.util.JastAddIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class JastAddAspectIntertypeFilter implements Filter {
@NonNls
public static final String ID = "HIDE_INTERTYPE_DECLS";
@Override
public boolean isVisible(TreeElement treeNode) {
if (treeNode instanceof AspectStructureViewElement) {
return !(
((AspectStructureViewElement) treeNode).getValue() instanceof JastAddAspectAspectMethodDeclaration
|| ((AspectStructureViewElement) treeNode).getValue() instanceof JastAddAspectAspectClassDeclarationImpl
|| ((AspectStructureViewElement) treeNode).getValue() instanceof JastAddAspectAspectEnumDeclaration
|| ((AspectStructureViewElement) treeNode).getValue() instanceof JastAddAspectAspectInterfaceDeclaration
|| ((AspectStructureViewElement) treeNode).getValue() instanceof JastAddAspectAspectFieldDeclaration
);
} else {
return true;
}
}
@Override
@NotNull
public ActionPresentation getPresentation() {
// TODO use i18n and string bundle like JavaStructureViewBundle
return new ActionPresentationData("Hide Intertype Declarations", null, JastAddIcons.INTERTYPE_DECL);
}
@Override
@NotNull
public String getName() {
return ID;
}
@Override
public boolean isReverted() {
return false;
}
}
package org.jastadd.tooling.aspect;
import com.intellij.ide.util.treeView.smartTree.ActionPresentation;
import com.intellij.ide.util.treeView.smartTree.ActionPresentationData;
import com.intellij.ide.util.treeView.smartTree.Filter;
import com.intellij.ide.util.treeView.smartTree.TreeElement;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectRewrite;
import org.jastadd.tooling.aspect.psi.JastAddAspectAttribute;
import org.jastadd.tooling.util.JastAddIcons;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
public class JastAddAspectRewriteFilter implements Filter {
@NonNls
public static final String ID = "HIDE_REWRITES";
@Override
public boolean isVisible(TreeElement treeNode) {
if (treeNode instanceof AspectStructureViewElement) {
return !(((AspectStructureViewElement) treeNode).getValue() instanceof JastAddAspectAspectRewrite);
}
else {
return true;
}
}
@Override
@NotNull
public ActionPresentation getPresentation() {
// TODO use i18n and string bundle like JavaStructureViewBundle
return new ActionPresentationData("Hide Rewrites", null, JastAddIcons.REWRITE);
}
@Override
@NotNull
public String getName() {
return ID;
}
@Override
public boolean isReverted() {
return false;
}
}
......@@ -34,4 +34,13 @@ public class AspectElementFactory {
return (AspectFile) PsiFileFactory.getInstance(project).
createFileFromText(name, AspectFileType.INSTANCE, text);
}
public static JastAddAspectAspectDeclaration createAspectDeclaration(Project project, String name) {
final AspectFile file = createFile(project, "aspect " + name + "{}");
PsiElement result = file.getFirstChild().findElementAt(20);
if (result != null) {
return (JastAddAspectAspectDeclaration) result.getParent().getParent();
}
return null;
}
}
package org.jastadd.tooling.aspect.psi;
import com.intellij.psi.PsiElement;
import org.jastadd.tooling.common.psi.NamedElement;
public interface JastAddAspectAttribute extends PsiElement, NamedElement {
String signature();
public interface JastAddAspectAttribute extends PsiElement {
}
package org.jastadd.tooling.aspect.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.PsiElement;
import org.jastadd.tooling.aspect.psi.AspectElementFactory;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectDeclaration;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectName;
import org.jastadd.tooling.common.psi.NamedElement;
import org.jastadd.tooling.common.psi.impl.NamedElementImpl;
import org.jastadd.tooling.util.JastAddIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public class JastAddAspectAspectDeclarationImplExtension extends NamedElementImpl implements NamedElement {
public JastAddAspectAspectDeclarationImplExtension(@NotNull ASTNode node) {
super(node);
}
public String getName() {
return getNameIdentifier().getText();
}
public PsiElement setName(@NotNull String newName) {
ASTNode identifierNode = getNameIdentifier().getNode().getFirstChildNode();
if (identifierNode != null) {
JastAddAspectAspectDeclaration name = AspectElementFactory.createAspectDeclaration(getProject(), newName);
assert name != null; // we know the name is not null because we always create the same one
ASTNode newNameIdentifierNode = name.getAspectName().getNode().getFirstChildNode();
getNameIdentifier().getNode().replaceChild(identifierNode, newNameIdentifierNode);
}
return this;
}
@Override
@NotNull
public JastAddAspectAspectName getNameIdentifier() {
return ((JastAddAspectAspectDeclaration) getNode().getPsi()).getAspectName();
}
@Override
public ItemPresentation getPresentation() {
return new ItemPresentation() {
@Nullable
@Override
public String getPresentableText() {
return "aspect " + getName();
}
@Override
public Icon getIcon(boolean unused) {
return JastAddIcons.ASPECT;
}
};
}
}
package org.jastadd.tooling.aspect.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jastadd.tooling.aspect.psi.AspectTypes;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectInhAttributeDeclaration;
import org.jastadd.tooling.aspect.psi.JastAddAspectAttribute;
import org.jastadd.tooling.common.psi.impl.NamedElementImpl;
import org.jastadd.tooling.util.JastAddIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.stream.Collectors;
public abstract class JastAddAspectAspectInhAttributeDeclarationImplExtension extends NamedElementImpl implements JastAddAspectAttribute {
public JastAddAspectAspectInhAttributeDeclarationImplExtension(@NotNull ASTNode node) {
super(node);
}
public String getName() {
// this finds the *first* ID, which is what we want
ASTNode nameNode = getNode().findChildByType(AspectTypes.ATTRIBUTE_NAME);
if (nameNode != null) {
return nameNode.getText();
} else {
return null;
}
}
@Override
public @Nullable PsiElement getNameIdentifier() {
return ((JastAddAspectAspectInhAttributeDeclaration) this).getAttributeName();
}
@Override
public PsiElement setName(@NlsSafe @NotNull String name) throws IncorrectOperationException {
throw new IncorrectOperationException("Renaming collection attributes is not supported.");
}
@Override
public @Nullable PsiElement getIdentifyingElement() {
return this;
}
@Override
public String signature() {
JastAddAspectAspectInhAttributeDeclaration decl = (JastAddAspectAspectInhAttributeDeclaration) this;
return "inh " + decl.getAstTypeName().getText() + "." + decl.getAttributeName().getText() + "(" + decl.getTypeList().stream().map(PsiElement::getText).collect(Collectors.joining(", ")) + ") : " + decl.getAspectType().getText();
}
@Override
public ItemPresentation getPresentation() {
return new ItemPresentation() {
@Nullable
@Override
public String getPresentableText() {
return signature();
}
@Override
public Icon getIcon(boolean unused) {
return JastAddIcons.INH_ATTRIBUTE;
}
};
}
}
package org.jastadd.tooling.aspect.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jastadd.tooling.aspect.psi.AspectTypes;
import org.jastadd.tooling.aspect.psi.JastAddAspectAspectSynAttributeDeclaration;
import org.jastadd.tooling.aspect.psi.JastAddAspectAttribute;
import org.jastadd.tooling.common.psi.impl.NamedElementImpl;
import org.jastadd.tooling.util.JastAddIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.stream.Collectors;
public abstract class JastAddAspectAspectSynAttributeDeclarationImplExtension extends NamedElementImpl implements JastAddAspectAttribute {
public JastAddAspectAspectSynAttributeDeclarationImplExtension(@NotNull ASTNode node) {
super(node);
}
public String getName() {
// this finds the *first* ID, which is what we want
ASTNode nameNode = getNode().findChildByType(AspectTypes.ATTRIBUTE_NAME);
if (nameNode != null) {
return nameNode.getText();
} else {
return null;
}
}
@Override
public @Nullable PsiElement getNameIdentifier() {
return ((JastAddAspectAspectSynAttributeDeclaration) this).getAttributeName();
}
@Override
public PsiElement setName(@NlsSafe @NotNull String name) throws IncorrectOperationException {
throw new IncorrectOperationException("Renaming collection attributes is not supported.");
}
@Override
public @Nullable PsiElement getIdentifyingElement() {
return this;
}
@Override
public String signature() {
JastAddAspectAspectSynAttributeDeclaration decl = (JastAddAspectAspectSynAttributeDeclaration) this;
return "syn " + decl.getAstTypeName().getText() + "." + decl.getAttributeName().getText() + "(" + decl.getTypeList().stream().map(PsiElement::getText).collect(Collectors.joining(", ")) + ") : " + decl.getAspectType().getText();
}
@Override
public ItemPresentation getPresentation() {
return new ItemPresentation() {
@Nullable
@Override
public String getPresentableText() {
return signature();
}
@Override
public Icon getIcon(boolean unused) {
return JastAddIcons.SYN_ATTRIBUTE;
}
};
}
}
......@@ -3,30 +3,34 @@ package org.jastadd.tooling.aspect.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jastadd.tooling.aspect.psi.AspectElementFactory;
import org.jastadd.tooling.aspect.psi.AspectTypes;
import org.jastadd.tooling.aspect.psi.JastAddAspectAstTypeName;
import org.jastadd.tooling.grammar.psi.GrammarNamedElement;
import org.jastadd.tooling.grammar.psi.impl.GrammarNamedElementImpl;
import org.jastadd.tooling.common.psi.NamedElement;
import org.jastadd.tooling.common.psi.impl.NamedElementImpl;
import org.jetbrains.annotations.NotNull;
public class JastAddAspectAstTypeNameImplExtension extends GrammarNamedElementImpl implements GrammarNamedElement {
public class JastAddAspectAstTypeNameImplExtension extends NamedElementImpl implements NamedElement {
public JastAddAspectAstTypeNameImplExtension(@NotNull ASTNode node) {
super(node);
}
public String getName() {
// this finds the *first* ID, which is what we want
return getNode().getText();
ASTNode nameNode = getNode().findChildByType(AspectTypes.AST_TYPE_NAME);
if (nameNode != null) {
return nameNode.getText();
} else {
return null;
}
}
public PsiElement setName(@NotNull String newName) {
// FIXME this can break the grammar when the type is used in an unnamed component (and in many other cases probably)
ASTNode keyNode = getNode().getFirstChildNode();
if (keyNode != null) {
ASTNode nameNode = getNode().findChildByType(AspectTypes.AST_TYPE_NAME);
if (nameNode != null) {
JastAddAspectAstTypeName name = AspectElementFactory.createAstTypeName(getProject(), newName);
assert name != null; // we know the name is not null because we always create the same one
ASTNode newKeyNode = name.getNode().getFirstChildNode();
getNode().replaceChild(keyNode, newKeyNode);
ASTNode newNameNode = name.getNode().getFirstChildNode();
getNode().replaceChild(nameNode, newNameNode);
}
return this;
}
......
......@@ -3,12 +3,13 @@ package org.jastadd.tooling.aspect.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jastadd.tooling.aspect.psi.AspectElementFactory;
import org.jastadd.tooling.aspect.psi.AspectTypes;
import org.jastadd.tooling.aspect.psi.JastAddAspectClassOrInterfaceType;
import org.jastadd.tooling.grammar.psi.GrammarNamedElement;
import org.jastadd.tooling.grammar.psi.impl.GrammarNamedElementImpl;
import org.jastadd.tooling.common.psi.NamedElement;
import org.jastadd.tooling.common.psi.impl.NamedElementImpl;
import org.jetbrains.annotations.NotNull;
public class JastAddAspectClassOrInterfaceTypeImplExtension extends GrammarNamedElementImpl implements GrammarNamedElement {
public class JastAddAspectClassOrInterfaceTypeImplExtension extends NamedElementImpl implements NamedElement {
public JastAddAspectClassOrInterfaceTypeImplExtension(@NotNull ASTNode node) {
super(node);
......@@ -16,22 +17,28 @@ public class JastAddAspectClassOrInterfaceTypeImplExtension extends GrammarNamed
public String getName() {
// this finds the *first* ID, which is what we want
return getNode().getText();
ASTNode nameNode = getNode().findChildByType(AspectTypes.JAVA_IDENTIFIER);
if (nameNode != null) {
return nameNode.getText();
} else {
return null;
}
}
public PsiElement setName(@NotNull String newName) {
// FIXME this can break the grammar when the type is used in an unnamed component (and in many other cases probably)
ASTNode keyNode = getNode().getFirstChildNode();
if (keyNode != null) {
ASTNode nameNode = getNode().findChildByType(AspectTypes.JAVA_IDENTIFIER);
if (nameNode != null) {
JastAddAspectClassOrInterfaceType name = AspectElementFactory.createClassOrInterfaceType(getProject(), newName);
assert name != null; // we know the name is not null because we always create the same one
ASTNode newKeyNode = name.getNode().getFirstChildNode();
getNode().replaceChild(keyNode, newKeyNode);
assert !name.getJavaIdentifierList().isEmpty(); // we know there is always one name - the class name
ASTNode newKeyNode = name.getJavaIdentifierList().get(0).getNode().getFirstChildNode();
getNode().replaceChild(nameNode, newKeyNode);
}
return this;
}
public PsiElement getNameIdentifier() {
// the entire thing is the identifier
return getNode().getPsi();
}
......
package org.jastadd.tooling.aspect.psi.impl;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import org.jastadd.tooling.aspect.psi.JastAddAspectAttribute;
import org.jetbrains.annotations.NotNull;
public abstract class JastAddAspectCollAttributeImpl extends ASTWrapperPsiElement implements JastAddAspectAttribute {
public JastAddAspectCollAttributeImpl(@NotNull ASTNode node) {
super(node);
}
}
package org.jastadd.tooling.aspect.psi.impl;
import com.intellij.lang.ASTNode;
import com.intellij.navigation.ItemPresentation;
import com.intellij.openapi.util.NlsSafe;
import com.intellij.psi.PsiElement;
import com.intellij.util.IncorrectOperationException;
import org.jastadd.tooling.aspect.psi.AspectTypes;
import org.jastadd.tooling.aspect.psi.JastAddAspectAttribute;
import org.jastadd.tooling.aspect.psi.JastAddAspectCollectionAttribute;
import org.jastadd.tooling.common.psi.impl.NamedElementImpl;
import org.jastadd.tooling.util.JastAddIcons;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
public abstract class JastAddAspectCollectionAttributeImplExtension extends NamedElementImpl implements JastAddAspectAttribute {
public JastAddAspectCollectionAttributeImplExtension(@NotNull ASTNode node) {
super(node);
}
public String getName() {
// this finds the *first* ID, which is what we want
ASTNode nameNode = getNode().findChildByType(AspectTypes.ATTRIBUTE_NAME);
if (nameNode != null) {
return nameNode.getText();
} else {
return null;
}
}
@Override
public @Nullable PsiElement getNameIdentifier() {
return ((JastAddAspectCollectionAttribute) this).getAttributeName();
}
@Override
public PsiElement setName(@NlsSafe @NotNull String name) throws IncorrectOperationException {
throw new IncorrectOperationException("Renaming collection attributes is not supported.");
}
@Override
public @Nullable PsiElement getIdentifyingElement() {
return this;
}
@Override
public String signature() {
JastAddAspectCollectionAttribute decl = (JastAddAspectCollectionAttribute) this;
return "coll " + decl.getAstTypeNameList().get(0).getText() + "." + decl.getAttributeName().getText() + "() : " + decl.getAspectType().getText();
}
@Override
public ItemPresentation getPresentation() {
return new ItemPresentation() {
@Nullable
@Override
public String getPresentableText() {
return signature();
}
@Override
public Icon getIcon(boolean unused) {
return JastAddIcons.COL_ATTRIBUTE;
}
};
}
}
package org.jastadd.tooling.aspect.psi.impl;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import org.jastadd.tooling.aspect.psi.JastAddAspectAttribute;
import org.jetbrains.annotations.NotNull;
public abstract class JastAddAspectInhAttributeImpl extends ASTWrapperPsiElement implements JastAddAspectAttribute {
public JastAddAspectInhAttributeImpl(@NotNull ASTNode node) {
super(node);
}
}
package org.jastadd.tooling.aspect.psi.impl;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import org.jastadd.tooling.aspect.psi.JastAddAspectAttribute;
import org.jetbrains.annotations.NotNull;
public abstract class JastAddAspectSynAttributeImpl extends ASTWrapperPsiElement implements JastAddAspectAttribute {
public JastAddAspectSynAttributeImpl(@NotNull ASTNode node) {
super(node);
}
}
package org.jastadd.tooling.grammar.psi;
package org.jastadd.tooling.common.psi;
import com.intellij.psi.PsiNameIdentifierOwner;
public interface GrammarNamedElement extends PsiNameIdentifierOwner {
public interface NamedElement extends PsiNameIdentifierOwner {
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment