use of com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration in project Perl5-IDEA by Camelcade.
the class PerlVariableShadowingInspection method checkDeclaration.
@Override
public void checkDeclaration(ProblemsHolder holder, PerlVariableDeclarationElement variableDeclarationWrapper) {
PerlVariable variable = variableDeclarationWrapper.getVariable();
PsiElement declarationContainer = variableDeclarationWrapper.getParent();
if (variable != null && !(declarationContainer instanceof PsiPerlVariableDeclarationLocal)) {
PerlVariableDeclarationElement lexicalDeclaration = PerlResolveUtil.getLexicalDeclaration(variable);
if (lexicalDeclaration instanceof PerlBuiltInVariable) {
registerProblem(holder, variable, PerlBundle.message("perl.inspection.shadows.builtin", lexicalDeclaration.getVariable().getLineNumber()));
} else if (lexicalDeclaration instanceof PerlImplicitVariableDeclaration) {
registerProblem(holder, variable, PerlBundle.message("perl.inspection.shadows.implicit", lexicalDeclaration.getVariable().getLineNumber()));
} else if (lexicalDeclaration != null) {
registerProblem(holder, variable, PerlBundle.message("perl.inspection.shadows.other", lexicalDeclaration.getVariable().getLineNumber()));
}
}
}
use of com.perl5.lang.perl.psi.impl.PerlImplicitVariableDeclaration 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.impl.PerlImplicitVariableDeclaration in project Perl5-IDEA by Camelcade.
the class PerlVariableReference method resolveInner.
@NotNull
@Override
protected ResolveResult[] resolveInner(boolean incompleteCode) {
PsiElement elementParent = myElement.getParent();
assert elementParent instanceof PerlVariable;
PerlVariable perlVariable = (PerlVariable) elementParent;
List<ResolveResult> result = new ArrayList<>();
PerlVariableDeclarationElement lexicalDeclaration = PerlResolveUtil.getLexicalDeclaration(perlVariable);
if (lexicalDeclaration == null || lexicalDeclaration.isGlobalDeclaration() && !(lexicalDeclaration instanceof PerlImplicitVariableDeclaration)) {
// not found explicit lexically visible declarations
// imports
PerlVariableType actualType = perlVariable.getActualType();
Project project = perlVariable.getProject();
PerlNamespaceDefinitionElement namespaceContainer = PerlPackageUtil.getNamespaceContainerForElement(perlVariable);
if (// not true if LPE in TemplateToolkit
namespaceContainer != null) {
String variableName = perlVariable.getName();
if (actualType == PerlVariableType.SCALAR) {
for (PerlExportDescriptor importEntry : namespaceContainer.getImportedScalarDescriptors()) {
if (importEntry.getImportedName().equals(variableName)) {
for (PerlVariableDeclarationElement targetVariable : PerlScalarUtil.getGlobalScalarDefinitions(project, importEntry.getTargetCanonicalName())) {
result.add(new PsiElementResolveResult(targetVariable));
}
}
}
} else if (actualType == PerlVariableType.ARRAY) {
for (PerlExportDescriptor importEntry : namespaceContainer.getImportedArrayDescriptors()) {
if (importEntry.getImportedName().equals(variableName)) {
for (PerlVariableDeclarationElement targetVariable : PerlArrayUtil.getGlobalArrayDefinitions(project, importEntry.getTargetCanonicalName())) {
result.add(new PsiElementResolveResult(targetVariable));
}
}
}
} else if (actualType == PerlVariableType.HASH) {
for (PerlExportDescriptor importEntry : namespaceContainer.getImportedHashDescriptors()) {
if (importEntry.getImportedName().equals(variableName)) {
for (PerlVariableDeclarationElement targetVariable : PerlHashUtil.getGlobalHashDefinitions(project, importEntry.getTargetCanonicalName())) {
result.add(new PsiElementResolveResult(targetVariable));
}
}
}
}
}
// our variable declaration
for (PerlGlobVariable glob : perlVariable.getRelatedGlobs()) {
result.add(new PsiElementResolveResult(glob));
}
// globs
for (PerlVariableDeclarationElement globalDeclaration : perlVariable.getGlobalDeclarations()) {
result.add(new PsiElementResolveResult(globalDeclaration));
}
} else {
result.add(new PsiElementResolveResult(lexicalDeclaration));
}
return result.toArray(new ResolveResult[result.size()]);
}
Aggregations