use of com.perl5.lang.perl.psi.PerlVariableNameElement in project Perl5-IDEA by Camelcade.
the class PerlVariableCompletionUtil method fillWithUnresolvedVars.
public static void fillWithUnresolvedVars(@NotNull PerlVariableNameElement variableNameElement, @NotNull CompletionResultSet resultSet) {
final PerlLexicalScope lexicalScope = PsiTreeUtil.getParentOfType(variableNameElement, PerlLexicalScope.class);
PsiElement perlVariable = variableNameElement.getParent();
final Set<String> collectedNames = new THashSet<>();
if (lexicalScope != null && perlVariable instanceof PerlVariable) {
final int minOffset = variableNameElement.getTextOffset();
final PerlVariableType actualType = ((PerlVariable) perlVariable).getActualType();
lexicalScope.accept(new PerlRecursiveVisitor() {
@Override
public void visitPerlVariable(@NotNull PerlVariable perlVariable) {
if (perlVariable.isValid() && !(perlVariable.getParent() instanceof PerlVariableDeclarationElement) && perlVariable.getTextOffset() > minOffset && actualType == perlVariable.getActualType()) {
String variableName = perlVariable.getName();
if (StringUtil.isNotEmpty(variableName) && !collectedNames.contains(variableName) && perlVariable.getLexicalDeclaration() == null) {
collectedNames.add(variableName);
resultSet.addElement(LookupElementBuilder.create(variableName));
}
}
super.visitPerlVariable(perlVariable);
}
});
}
}
use of com.perl5.lang.perl.psi.PerlVariableNameElement 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.PerlVariableNameElement in project Perl5-IDEA by Camelcade.
the class PerlUnresolvedVariableInspection method buildVisitor.
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new PerlVisitor() {
@Override
public void visitPerlVariable(@NotNull final PerlVariable variable) {
PsiElement parent = variable.getParent();
if (parent instanceof PerlVariableDeclarationElement || variable.isBuiltIn()) {
return;
}
PerlVariableNameElement variableNameElement = variable.getVariableNameElement();
if (variableNameElement != null) {
for (PsiReference reference : variableNameElement.getReferences()) {
if (reference instanceof PsiPolyVariantReference && ((PsiPolyVariantReference) reference).multiResolve(false).length > 0 || reference.resolve() != null) {
return;
}
}
registerProblem(holder, variableNameElement, "Unable to find variable declaration.");
}
}
};
}
use of com.perl5.lang.perl.psi.PerlVariableNameElement in project Perl5-IDEA by Camelcade.
the class PerlGlobVariableMixin method getExplicitPackageName.
@Nullable
@Override
public String getExplicitPackageName() {
PerlVariableNameElement variableNameElement = getVariableNameElement();
if (variableNameElement == null) {
return null;
}
String variableNameText = variableNameElement.getText();
int delimiterIndex = variableNameText.lastIndexOf(':');
return delimiterIndex == -1 ? null : PerlPackageUtil.getCanonicalPackageName(variableNameText.substring(0, delimiterIndex + 1));
}
use of com.perl5.lang.perl.psi.PerlVariableNameElement in project Perl5-IDEA by Camelcade.
the class PerlGlobVariableMixin method getName.
@Override
public String getName() {
PerlGlobStub stub = getStub();
if (stub != null) {
return stub.getName();
}
PerlVariableNameElement variableNameElement = getVariableNameElement();
if (variableNameElement == null) {
return null;
}
String variableNameText = variableNameElement.getText();
int delimiterIndex = variableNameText.lastIndexOf(':');
return delimiterIndex == -1 ? variableNameText : variableNameText.substring(delimiterIndex + 1);
}
Aggregations