use of com.perl5.lang.perl.psi.PsiPerlExpr in project Perl5-IDEA by Camelcade.
the class PerlFormattingStatementModifierUnwrap method apply.
@Override
public int apply() {
int delta = 0;
if (getMyModifier().isValid()) {
PsiPerlExpr expression = PsiTreeUtil.getChildOfType(getMyModifier(), PsiPerlExpr.class);
if (expression != null && expression instanceof PsiPerlParenthesisedExpr) {
PsiPerlExpr nestedExpression = ((PsiPerlParenthesisedExpr) expression).getExpr();
if (nestedExpression != null) {
delta = nestedExpression.getNode().getTextLength() - expression.getNode().getTextLength();
expression.replace(nestedExpression.copy());
}
}
}
return delta;
}
use of com.perl5.lang.perl.psi.PsiPerlExpr in project Perl5-IDEA by Camelcade.
the class PerlFormattingStatementModifierWrap method apply.
@Override
public int apply() {
int delta = 0;
if (getMyModifier().isValid()) {
PsiPerlExpr expression = PsiTreeUtil.getChildOfType(getMyModifier(), PsiPerlExpr.class);
if (expression != null && !(expression instanceof PsiPerlParenthesisedExpr)) {
PsiPerlParenthesisedExpr parenthesisedExpression = PerlElementFactory.createParenthesisedExpression(getMyModifier().getProject());
parenthesisedExpression.addAfter(expression.copy(), parenthesisedExpression.getFirstChild());
delta = expression.getNode().getTextLength() - parenthesisedExpression.getNode().getTextLength();
expression.replace(parenthesisedExpression);
}
}
return delta;
}
use of com.perl5.lang.perl.psi.PsiPerlExpr in project Perl5-IDEA by Camelcade.
the class CompoundToStatementIntention method replaceWithStatement.
/**
* Generating new code, extracting declarations from control expression and replacing compound statement if possible.
*
* @param compound compound statement
* @param statementText statement text
* @param controlExpr control expression (condition or iterable)
*/
private static void replaceWithStatement(@NotNull PerlConvertableCompound compound, @NotNull String statementText, @NotNull PsiPerlExpr controlExpr) {
List<PsiElement> declarations = new ArrayList<>();
controlExpr.accept(new PerlRecursiveVisitor() {
@Override
public void visitPerlVariableDeclarationExpr(@NotNull PerlVariableDeclarationExpr o) {
declarations.add(o);
super.visitPerlVariableDeclarationExpr(o);
}
});
String controlExprText = controlExpr.getText();
StringBuilder sb = new StringBuilder();
if (!declarations.isEmpty()) {
// extracting declarations from control statement
TextRange controlExprTextRange = controlExpr.getTextRange();
for (int i = declarations.size() - 1; i >= 0; i--) {
PsiElement declaration = declarations.get(i);
sb.append(declaration.getText()).append(";\n");
PsiElement keywordElement = declaration.getFirstChild();
if (keywordElement instanceof LeafPsiElement) {
// removing keyword from control expression my $var => $var, my ($var1, $var2) => ($var1, $var2)
controlExprText = keywordElement.getTextRange().shiftRight(-controlExprTextRange.getStartOffset()).replace(controlExprText, "");
}
}
}
sb.append(statementText).append(" ").append(compound.getFirstChild().getText()).append(" ").append(controlExprText).append(";");
PerlFileImpl perlFile = PerlElementFactory.createFile(compound.getProject(), sb.toString());
PsiPerlStatementImpl[] statements = PsiTreeUtil.getChildrenOfType(perlFile, PsiPerlStatementImpl.class);
if (statements == null || statements.length == 0) {
return;
}
PsiElement container = compound.getParent();
if (container == null) {
return;
}
container.addRangeBefore(statements[0], statements[statements.length - 1], compound);
compound.delete();
}
use of com.perl5.lang.perl.psi.PsiPerlExpr in project Perl5-IDEA by Camelcade.
the class PerlVariableMixin method getVariableTypeHeavy.
@Nullable
private String getVariableTypeHeavy() {
if (this instanceof PsiPerlScalarVariable) {
// System.err.println("Guessing type for " + getText() + " at " + getTextOffset());
PerlVariableNameElement variableNameElement = getVariableNameElement();
if (variableNameElement != null) {
// find lexicaly visible declaration and check type
final PerlVariableDeclarationElement declarationWrapper = getLexicalDeclaration();
if (declarationWrapper != null) {
if (declarationWrapper instanceof PerlImplicitVariableDeclaration) {
return ((PerlImplicitVariableDeclaration) declarationWrapper).getVariableClass();
}
if (declarationWrapper.isInvocantDeclaration() || declarationWrapper.isSelf()) {
PerlSelfHinter selfHinter = PsiTreeUtil.getParentOfType(declarationWrapper, PerlSelfHinter.class);
if (selfHinter != null) {
return selfHinter.getSelfNamespace();
}
return PerlPackageUtil.getContextPackageName(declarationWrapper);
}
// check explicit type in declaration
String declarationPackageName = declarationWrapper.getDeclaredType();
if (declarationPackageName != null) {
assert !declarationPackageName.equals("");
return declarationPackageName;
}
// check assignment around declaration
PerlVariableDeclarationExpr declaration = PsiTreeUtil.getParentOfType(declarationWrapper, PerlVariableDeclarationExpr.class);
if (declaration != null) {
if (declaration.getParent() instanceof PsiPerlAssignExpr) {
PsiPerlAssignExpr assignmentExpression = (PsiPerlAssignExpr) declaration.getParent();
List<PsiPerlExpr> assignmentElements = assignmentExpression.getExprList();
if (!assignmentElements.isEmpty()) {
PsiPerlExpr lastExpression = assignmentElements.get(assignmentElements.size() - 1);
if (lastExpression != declaration) {
// source element is on the left side
if (lastExpression instanceof PerlMethodContainer) {
return PerlSubUtil.getMethodReturnValue((PerlMethodContainer) lastExpression);
}
if (lastExpression instanceof PerlDerefExpression) {
return ((PerlDerefExpression) lastExpression).guessType();
}
}
}
}
}
// fixme this is bad, because my $var1 && print $var1 will be valid, but it's not
PerlLexicalScope perlLexicalScope = PsiTreeUtil.getParentOfType(declarationWrapper, PerlLexicalScope.class);
assert perlLexicalScope != null : "Unable to find lexical scope for:" + declarationWrapper.getClass() + " at " + declarationWrapper.getTextOffset() + " in " + declarationWrapper.getContainingFile();
final String[] guessResult = new String[] { null };
int startOffset = declarationWrapper.getTextRange().getEndOffset();
int endOffset = getTextRange().getStartOffset();
if (startOffset < endOffset) {
PerlPsiUtil.processElementsInRange(perlLexicalScope, new TextRange(startOffset, endOffset), element -> {
if (element != PerlVariableMixin.this && element instanceof PsiPerlScalarVariable && element.getParent() instanceof PsiPerlAssignExpr) {
PsiElement variableNameElement1 = ((PsiPerlScalarVariable) element).getVariableNameElement();
if (variableNameElement1 != null && variableNameElement1.getReference() != null && variableNameElement1.getReference().isReferenceTo(declarationWrapper)) {
// found variable assignment
PsiPerlAssignExpr assignmentExpression = (PsiPerlAssignExpr) element.getParent();
List<PsiPerlExpr> assignmentElements = assignmentExpression.getExprList();
if (!assignmentElements.isEmpty()) {
PsiPerlExpr lastExpression = assignmentElements.get(assignmentElements.size() - 1);
if (lastExpression != element && lastExpression.getTextOffset() < getTextOffset()) {
// source element is on the left side
// fixme implement variables assignment support. Need to build kinda visitor with recursion control
String returnValue = null;
if (lastExpression instanceof PerlMethodContainer) {
returnValue = PerlSubUtil.getMethodReturnValue((PerlMethodContainer) lastExpression);
}
if (lastExpression instanceof PerlDerefExpression) {
returnValue = ((PerlDerefExpression) lastExpression).guessType();
}
if (StringUtil.isNotEmpty(returnValue)) {
guessResult[0] = returnValue;
return false;
}
}
}
}
}
return true;
});
}
if (guessResult[0] != null) {
return guessResult[0];
}
}
// checking global declarations with explicit types
for (PerlVariableDeclarationElement declaration : getGlobalDeclarations()) {
if (declaration.getDeclaredType() != null) {
return declaration.getDeclaredType();
}
}
}
}
return null;
}
use of com.perl5.lang.perl.psi.PsiPerlExpr in project Perl5-IDEA by Camelcade.
the class StatementToCompoundIntention method invoke.
@Override
public void invoke(@NotNull Project project, Editor editor, @NotNull PsiElement element) throws IncorrectOperationException {
PsiPerlStatementImpl statement = getStatement(element);
if (statement == null) {
return;
}
PsiPerlStatementModifier modifier = statement.getModifier();
if (modifier == null) {
return;
}
PsiElement keyword = modifier.getFirstChild();
if (keyword == null) {
return;
}
PsiPerlExpr modifierExpression = PsiTreeUtil.getChildOfType(modifier, PsiPerlExpr.class);
PsiPerlExpr valueExpression = modifierExpression instanceof PsiPerlParenthesisedExpr ? ((PsiPerlParenthesisedExpr) modifierExpression).getExpr() : modifierExpression;
String conditionText = valueExpression == null ? "" : valueExpression.getText();
TextRange modifierRangeInStatement = TextRange.from(modifier.getStartOffsetInParent(), modifier.getTextLength());
String statementText = modifierRangeInStatement.replace(statement.getText(), "");
StringBuilder newCode = new StringBuilder();
newCode.append(keyword.getText()).append("(").append(conditionText).append("){\n").append(statementText).append("\n}");
PerlFileImpl fakeFile = PerlElementFactory.createFile(project, newCode.toString());
PsiElement[] children = fakeFile.getChildren();
assert children.length == 1;
statement.replace(children[0]);
}
Aggregations