use of com.perl5.lang.perl.psi.properties.PerlLexicalScope in project Perl5-IDEA by Camelcade.
the class PerlResolveUtil method processChildren.
public static boolean processChildren(@NotNull PsiElement element, @NotNull PsiScopeProcessor processor, @NotNull ResolveState resolveState, @Nullable PsiElement lastParent, @NotNull PsiElement place) {
PsiElement run = lastParent == null ? element.getLastChild() : lastParent.getPrevSibling();
while (run != null) {
ProgressManager.checkCanceled();
if (run instanceof PerlCompositeElement && // fixme this should be in composite
!(run instanceof PerlLexicalScope) && !run.processDeclarations(processor, resolveState, null, place)) {
return false;
}
run = run.getPrevSibling();
}
// checking implicit variables fixme: decide, move processchildren to here or move this one to processDeclarations?
if (element instanceof PerlImplicitVariablesProvider) {
for (PerlVariableDeclarationElement wrapper : ((PerlImplicitVariablesProvider) element).getImplicitVariables()) {
ProgressManager.checkCanceled();
if (!processor.execute(wrapper, resolveState)) {
return false;
}
}
}
return true;
}
use of com.perl5.lang.perl.psi.properties.PerlLexicalScope 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.properties.PerlLexicalScope 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;
}
Aggregations