Skip to content

Commit

Permalink
Wrapped signature elements into psi element signature_element
Browse files Browse the repository at this point in the history
  • Loading branch information
hurricup committed Apr 25, 2020
1 parent 17e0870 commit c3c5bf6
Show file tree
Hide file tree
Showing 187 changed files with 3,561 additions and 2,968 deletions.
27 changes: 15 additions & 12 deletions mason2/testData/parser/template/testComponent.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1029,15 +1029,17 @@ Mason2 template file
PerlSubNameElementImpl(Perl5: subname)('greet1')
PsiElement(Perl5: ()('(')
PsiPerlSignatureContentImpl(Perl5: SIGNATURE_CONTENT)
PsiPerlVariableDeclarationElementImpl(VARIABLE_DECLARATION_ELEMENT)
PsiPerlScalarVariableImpl(Perl5: SCALAR_VARIABLE)
PsiElement(Perl5: $$)('$')
PerlVariableNameElementImpl(Perl5: SCALAR_NAME)('name')
PsiPerlSignatureElementImpl(Perl5: SIGNATURE_ELEMENT)
PsiPerlVariableDeclarationElementImpl(VARIABLE_DECLARATION_ELEMENT)
PsiPerlScalarVariableImpl(Perl5: SCALAR_VARIABLE)
PsiElement(Perl5: $$)('$')
PerlVariableNameElementImpl(Perl5: SCALAR_NAME)('name')
PsiElement(Perl5: ,)(',')
PsiPerlVariableDeclarationElementImpl(VARIABLE_DECLARATION_ELEMENT)
PsiPerlScalarVariableImpl(Perl5: SCALAR_VARIABLE)
PsiElement(Perl5: $$)('$')
PerlVariableNameElementImpl(Perl5: SCALAR_NAME)('color')
PsiPerlSignatureElementImpl(Perl5: SIGNATURE_ELEMENT)
PsiPerlVariableDeclarationElementImpl(VARIABLE_DECLARATION_ELEMENT)
PsiPerlScalarVariableImpl(Perl5: SCALAR_VARIABLE)
PsiElement(Perl5: $$)('$')
PerlVariableNameElementImpl(Perl5: SCALAR_NAME)('color')
PsiElement(Perl5: ))(')')
PsiElement(Mason2: >)('>')
PsiPerlBlockImpl(Perl5: BLOCK)
Expand Down Expand Up @@ -1098,10 +1100,11 @@ Mason2 template file
PerlSubNameElementImpl(Perl5: subname)('Row1')
PsiElement(Perl5: ()('(')
PsiPerlSignatureContentImpl(Perl5: SIGNATURE_CONTENT)
PsiPerlVariableDeclarationElementImpl(VARIABLE_DECLARATION_ELEMENT)
PsiPerlScalarVariableImpl(Perl5: SCALAR_VARIABLE)
PsiElement(Perl5: $$)('$')
PerlVariableNameElementImpl(Perl5: SCALAR_NAME)('class')
PsiPerlSignatureElementImpl(Perl5: SIGNATURE_ELEMENT)
PsiPerlVariableDeclarationElementImpl(VARIABLE_DECLARATION_ELEMENT)
PsiPerlScalarVariableImpl(Perl5: SCALAR_VARIABLE)
PsiElement(Perl5: $$)('$')
PerlVariableNameElementImpl(Perl5: SCALAR_NAME)('class')
PsiElement(Perl5: ))(')')
PsiElement(Mason2: >)('>')
PsiPerlBlockImpl(Perl5: BLOCK)
Expand Down
10 changes: 7 additions & 3 deletions plugin/core/grammar/Perl5.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -409,7 +409,8 @@
extends(".*statement_modifier")=statement_modifier
implements("statement_modifier")="com.perl5.lang.perl.psi.PerlStatementModifier"

implements("signature_content|variable_declaration_lexical")="com.perl5.lang.perl.psi.PerlLexicalVariableDeclarationMarker"
implements("variable_declaration_lexical")="com.perl5.lang.perl.psi.PerlLexicalVariableDeclarationMarker"
implements("signature_element")="com.perl5.lang.perl.psi.PerlSignatureElement"

extends("heredoc_opener|anon_array|anon_hash")=expr
// extends("glob_slot")=expr
Expand Down Expand Up @@ -699,7 +700,8 @@ private sub_prototype ::= SUB_PROTOTYPE_TOKEN*
/************************************* Sub signatures *****************************************************************/
private sub_signature ::= <<signature_content parse_sub_signature>>
private parse_sub_signature ::= sub_signature_element (',' sub_signature_element) *
private sub_signature_element ::= signature_left_side ['=' [parse_scalar_expr]]
private sub_signature_element ::= <<signature_element parse_sub_signature_element>>
private parse_sub_signature_element ::= signature_left_side ['=' [parse_scalar_expr]]
private signature_left_side ::= variable_declaration_element | sub_signature_element_ignore
sub_signature_element_ignore ::= '$$' | '$@' | '$%'

Expand Down Expand Up @@ -1244,6 +1246,7 @@ before_modifier ::= 'fp_before' fp_modifier_named_body

private meta parse_signature_content ::= '(' <<signature_content <<x1>>>> ')' {pin=1}
meta signature_content ::= <<x1>>
meta signature_element ::= <<x1>>

// not sure that we need a wrapper for signatures
private method_signature ::= <<parse_signature_content parse_method_signature_content>>
Expand All @@ -1252,7 +1255,8 @@ method_signature_invocant ::= <<scalarDeclarationWrapper>> ':'
private func_signature ::= <<parse_signature_content parse_func_signature_content>>
private parse_func_signature_content ::= [func_signature_elements] {recoverWhile=recover_signature_content}
private func_signature_elements ::= func_signature_element (comma + func_signature_element ) * comma*
private func_signature_element ::= [type_specifier]':' ? strict_variable_declaration_wrapper [parse_func_initializer] | undef_expr | sub_signature_element_ignore
private func_signature_element ::= <<signature_element parse_func_signature_element>>
private parse_func_signature_element ::= [type_specifier]':' ? strict_variable_declaration_wrapper [parse_func_initializer] | undef_expr | sub_signature_element_ignore
private parse_func_initializer ::= '=' [parse_list_element]

private recover_signature_content ::= !(')'|'{')
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,12 @@ private PsiElement computeFunctionParametersDoc(@NotNull PsiElement contextEleme
else if (parentElementType == AROUND_SIGNATURE_INVOCANTS) {
return PerlDocUtil.resolveDescriptor(PodLinkDescriptor.create(FUNCTION_PARAMETERS, KEYWORD_AROUND), contextElement, false);
}
else if (parentElementType == SIGNATURE_CONTENT) {
else if (parentElementType == SIGNATURE_ELEMENT) {
return PerlDocUtil.resolveDescriptor(PodLinkDescriptor.create(FUNCTION_PARAMETERS, "Named parameters"), contextElement, false);
}
}
if (elementType == OPERATOR_ASSIGN && parentElementType == SIGNATURE_CONTENT) {
// fixme these may occur in regular sub signature
if (elementType == OPERATOR_ASSIGN && parentElementType == SIGNATURE_ELEMENT) {
return PerlDocUtil.resolveDescriptor(PodLinkDescriptor.create(FUNCTION_PARAMETERS, "Default arguments"), contextElement, false);
}
if (PerlTokenSets.SIGILS.contains(elementType) && parentElementType == SUB_SIGNATURE_ELEMENT_IGNORE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public class PerlControlFlowBuilder extends ControlFlowBuilder {
TokenSet.create(
NAMESPACE_CONTENT, NAMESPACE_DEFINITION,
DO_BLOCK_EXPR,
SIGNATURE_CONTENT,
SIGNATURE_CONTENT, SIGNATURE_ELEMENT,
BLOCK, CONTINUE_BLOCK, CONDITION_EXPR,
CALL_ARGUMENTS, PARENTHESISED_CALL_ARGUMENTS,
WHILE_COMPOUND, UNTIL_COMPOUND,
Expand Down Expand Up @@ -366,29 +366,31 @@ public void visitVariableDeclarationElement(@NotNull PsiPerlVariableDeclarationE
if (declarationContainer instanceof PsiPerlMethodSignatureInvocant) {
declarationContainer = declarationContainer.getParent();
}
else if (declarationContainer instanceof PerlSignatureElement) {
declarationContainer = declarationContainer.getParent();
}
if (!(declarationContainer instanceof PsiPerlSignatureContent)) {
super.visitVariableDeclarationElement(o);
return;
}
PsiElement[] signatureElements = declarationContainer.getChildren();
int argumentIndex = computeBaseArgumentIndex(declarationContainer.getParent(), signatureElements);
int childIndex = 0;

PsiElement currentSignatureElement = null;
for (PsiElement signatureElement : signatureElements) {
if (signatureElement instanceof PsiPerlMethodSignatureInvocant) {
signatureElement = signatureElement.getFirstChild();
}
if (signatureElement.equals(o)) {
if (PsiTreeUtil.isAncestor(signatureElement, o, true)) {
currentSignatureElement = signatureElement;
break;
}
if (isDeclarationElement(signatureElement)) {
argumentIndex++;
}
childIndex++;
argumentIndex++;
}

int nextChildIndex = childIndex + 1;
PsiElement nextChild = signatureElements.length > nextChildIndex ? signatureElements[nextChildIndex] : null;
PsiElement defaultValue = isDeclarationElement(nextChild) ? null : nextChild;
if (currentSignatureElement == null) {
LOG.error("Could not find: " + o.getText() + " in " + declarationContainer.getText());
}

PsiElement defaultValue = currentSignatureElement instanceof PerlSignatureElement ?
((PerlSignatureElement)currentSignatureElement).getDefaultValueElement() : null;
PerlVariable variable = o.getVariable();
addNodeAndCheckPending(new PerlSubSignatureElementInstruction(PerlControlFlowBuilder.this, variable, argumentIndex, defaultValue));
}
Expand All @@ -403,12 +405,6 @@ private int computeBaseArgumentIndex(@Nullable PsiElement subDeclarationElement,
return signatureElements.length > 0 && signatureElements[0] instanceof PsiPerlMethodSignatureInvocant ? 0 : 1;
}

private boolean isDeclarationElement(PsiElement signatureElement) {
return signatureElement instanceof PsiPerlVariableDeclarationElement ||
signatureElement instanceof PsiPerlSubSignatureElementIgnore ||
signatureElement instanceof PsiPerlMethodSignatureInvocant;
}

@Override
public void visitTrycatchExpr(@NotNull PsiPerlTrycatchExpr o) {
acceptSafe(o.getTryExpression());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,8 @@
import com.perl5.lang.perl.idea.formatter.settings.PerlCodeStyleSettings;
import com.perl5.lang.perl.lexer.PerlElementTypes;
import com.perl5.lang.perl.lexer.PerlTokenSets;
import com.perl5.lang.perl.psi.PerlVariableDeclarationElement;
import com.perl5.lang.perl.psi.PsiPerlStatementModifier;
import com.perl5.lang.perl.psi.utils.PerlPsiUtil;
import com.perl5.lang.perl.psi.utils.PerlSubArgument;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
Expand Down Expand Up @@ -442,13 +440,8 @@ else if (childNodeType != COLON && childNodeType != QUESTION) {
return getWrapBySettings(parentNode, mySettings.TERNARY_OPERATION_WRAP, false);
}
}
// fixme assign operator should probably use assignment wrapping settings
else if (parentNodeType == SIGNATURE_CONTENT &&
childNodeType != COMMA && childNodeType != FAT_COMMA && childNodeType != OPERATOR_ASSIGN) {
PsiElement psiElement = childNode.getPsi();
if (!PerlVariableDeclarationElement.isNamedParameter(psiElement) && !PerlSubArgument.isDefaultValue(childNode.getPsi())) {
return getWrapBySettings(parentNode, mySettings.METHOD_PARAMETERS_WRAP, false);
}
else if (parentNodeType == SIGNATURE_CONTENT && childNodeType != COMMA && childNodeType != FAT_COMMA) {
return getWrapBySettings(parentNode, mySettings.METHOD_PARAMETERS_WRAP, false);
}
else if (parentNodeType == COMMA_SEQUENCE_EXPR && childNodeType != COMMA && childNodeType != FAT_COMMA) {
IElementType grandParentNodeType = PsiUtilCore.getElementType(parentNode.getTreeParent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ public interface PerlFormattingTokenSets extends PerlElementTypes {

LP_STRING_QW
));

TokenSet UNINDENTABLE_TOKENS = TokenSet.create(
LP_STRING_QW,
COMMA_SEQUENCE_EXPR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.RIGHT_BRACKET;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.RIGHT_PAREN;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.SEMICOLON;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.SIGNATURE_CONTENT;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.SIGNATURE_ELEMENT;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.SORT_EXPR;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.STATEMENT;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.STRING_BARE;
Expand All @@ -104,7 +104,6 @@
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.SUB_DEFINITION;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.SUB_EXPR;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.SUB_NAME;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.SUB_SIGNATURE_ELEMENT_IGNORE;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.TERNARY_EXPR;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.UNCONDITIONAL_BLOCK;
import static com.perl5.lang.perl.idea.formatter.PerlFormattingTokenSets.UNLESS_STATEMENT_MODIFIER;
Expand Down Expand Up @@ -174,9 +173,8 @@ static SpacingBuilder createSpacingBuilder(CommonCodeStyleSettings settings, Per

.before(ATTRIBUTES).spaceIf(perlSettings.SPACE_BEFORE_ATTRIBUTE)
.between(INVOCANTS_TOKENSET, COLON).spaces(1)
.between(INVOCANTS_TOKENSET, VARIABLE_DECLARATION_ELEMENT).spaces(1)
.between(INVOCANTS_TOKENSET, SUB_SIGNATURE_ELEMENT_IGNORE).spaces(1)
.betweenInside(COLON, VARIABLE_DECLARATION_ELEMENT, SIGNATURE_CONTENT).spaces(0)
.between(INVOCANTS_TOKENSET, SIGNATURE_ELEMENT).spaces(1)
.betweenInside(COLON, VARIABLE_DECLARATION_ELEMENT, SIGNATURE_ELEMENT).spaces(0)
.beforeInside(COLON, INVOCANTS_TOKENSET).spaces(0)
.beforeInside(COLON, ATTRIBUTES).spaceIf(perlSettings.SPACE_BEFORE_ATTRIBUTE)
.between(COLON, ATTRIBUTE).spaces(0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,8 @@ public PsiElement getPsiElement(@NotNull ASTNode node) {
return new PerlElementTypeEx(name, PsiPerlContinueExprImpl.class);
case "SIGNATURE_CONTENT":
return new PerlElementTypeEx(name, PsiPerlSignatureContentImpl.class);
case "SIGNATURE_ELEMENT":
return new PerlElementTypeEx(name, PsiPerlSignatureElementImpl.class);
case "SUB_SIGNATURE_ELEMENT_IGNORE":
return new PerlElementTypeEx(name, PsiPerlSubSignatureElementIgnoreImpl.class);
case "SUFF_PP_EXPR":
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2018 Alexandr Evstigneev
* Copyright 2015-2020 Alexandr Evstigneev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,8 +16,10 @@

package com.perl5.lang.perl.psi;

import com.intellij.psi.PsiElement;

/**
* Marker interface for declarations wrappers, which wraps lexical variables: signatures, locals and so on
*/
public interface PerlLexicalVariableDeclarationMarker {
public interface PerlLexicalVariableDeclarationMarker extends PsiElement {
}
66 changes: 66 additions & 0 deletions plugin/core/src/com/perl5/lang/perl/psi/PerlSignatureElement.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2015-2020 Alexandr Evstigneev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.perl5.lang.perl.psi;

import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public interface PerlSignatureElement extends PerlLexicalVariableDeclarationMarker {
@Nullable
default PsiElement getTypeConstraintElement() {
PsiElement[] children = getChildren();
if (children.length == 3) {
return children[0];
}
if (children.length < 2) {
return null;
}
return isDeclarationElement(children[1]) ? children[0] : null;
}

@Nullable
default PsiElement getDeclarationElement() {
PsiElement[] children = getChildren();
if (children.length == 3) {
return children[1];
}
if (children.length == 1) {
return children[0];
}
return isDeclarationElement(children[0]) ? children[0] : children[1];
}

/**
* @return true iff {@code psiElement} is variable declaration or ignore element
*/
static boolean isDeclarationElement(@NotNull PsiElement psiElement) {
return psiElement instanceof PerlVariableDeclaration || psiElement instanceof PsiPerlSubSignatureElementIgnore;
}

@Nullable
default PsiElement getDefaultValueElement() {
PsiElement[] children = getChildren();
if (children.length == 3) {
return children[2];
}
if (children.length < 2) {
return null;
}
return isDeclarationElement(children[1]) ? null : children[1];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
import javax.swing.*;

import static com.perl5.lang.perl.lexer.PerlElementTypesGenerated.COLON;
import static com.perl5.lang.perl.lexer.PerlElementTypesGenerated.SIGNATURE_CONTENT;
import static com.perl5.lang.perl.lexer.PerlElementTypesGenerated.SIGNATURE_ELEMENT;


public interface PerlVariableDeclarationElement
Expand Down Expand Up @@ -119,7 +119,7 @@ default boolean isSelf() {
@Contract("null -> false")
static boolean isNamedParameter(@Nullable PsiElement psiElement) {
return psiElement instanceof PerlVariableDeclarationElement &&
PsiUtilCore.getElementType(psiElement.getParent()) == SIGNATURE_CONTENT &&
PsiUtilCore.getElementType(psiElement.getParent()) == SIGNATURE_ELEMENT &&
PsiUtilCore.getElementType(PerlPsiUtil.getPrevSignificantSibling(psiElement)) == COLON;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,14 @@ protected PsiElement getSignatureContainer() {

@Override
protected boolean processSignatureElement(PsiElement signatureElement, List<PerlSubArgument> arguments) {
if (signatureElement instanceof PsiPerlMethodSignatureInvocant) // explicit invocant
{
if (signatureElement instanceof PsiPerlMethodSignatureInvocant) {
PerlVariable variable = PsiTreeUtil.findChildOfType(signatureElement, PerlVariable.class);
if (variable != null) {
arguments.add(PerlSubArgument.mandatory(variable.getActualType(), variable.getName()));
}
}
else if (signatureElement instanceof PerlVariableDeclarationElement) {
if (arguments.isEmpty()) // implicit invocant
{
if (arguments.isEmpty()) {
arguments.add(PerlSubArgument.mandatoryScalar(getDefaultInvocantName().substring(1)));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2015-2019 Alexandr Evstigneev
* Copyright 2015-2020 Alexandr Evstigneev
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -111,7 +111,12 @@ private List<PerlSubArgument> getPerlSubArgumentsFromSignature() {
PsiElement signatureElement = signatureContainer.getFirstChild();

while (signatureElement != null) {
processSignatureElement(signatureElement, arguments);
if (signatureElement instanceof PerlSignatureElement) {
processSignatureElement(((PerlSignatureElement)signatureElement).getDeclarationElement(), arguments);
}
else {
processSignatureElement(signatureElement, arguments);
}
signatureElement = signatureElement.getNextSibling();
}
}
Expand All @@ -122,7 +127,9 @@ private List<PerlSubArgument> getPerlSubArgumentsFromSignature() {
protected boolean processSignatureElement(PsiElement signatureElement, List<PerlSubArgument> arguments) {
if (signatureElement instanceof PerlVariableDeclarationElement) {
PerlVariable variable = ((PerlVariableDeclarationElement)signatureElement).getVariable();
arguments.add(PerlSubArgument.mandatory(variable.getActualType(), variable.getName()));
PerlSubArgument newArgument = PerlSubArgument.mandatory(variable.getActualType(), variable.getName());
newArgument.setOptional(signatureElement.getNextSibling() != null);
arguments.add(newArgument);
return true;
}
return false;
Expand Down
Loading

0 comments on commit c3c5bf6

Please sign in to comment.