use of com.intellij.psi.PsiElementVisitor in project phpinspectionsea by kalessil.
the class UselessReturnInspector method buildVisitor.
@Override
@NotNull
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new BasePhpElementVisitor() {
@Override
public void visitPhpReturn(@NotNull PhpReturn expression) {
final PhpExpression returnValue = ExpressionSemanticUtil.getReturnValue(expression);
if (returnValue instanceof AssignmentExpression) {
final AssignmentExpression assignment = (AssignmentExpression) returnValue;
final PsiElement assignmentVariable = assignment.getVariable();
final PsiElement assignmentValue = assignment.getValue();
if (assignmentValue != null && assignmentVariable instanceof Variable) {
final Function scope = ExpressionSemanticUtil.getScope(expression);
if (scope != null) {
final Variable variable = (Variable) assignmentVariable;
final boolean isTarget = !this.isArgumentReference(variable, scope) && !this.isBoundReference(variable, scope) && !this.isStaticVariable(variable, scope) && !this.isUsedInFinally(variable, scope);
if (isTarget) {
final String replacement = String.format("return %s;", assignmentValue.getText());
holder.registerProblem(expression, MessagesPresentationUtil.prefixWithEa(messageConfusing), new SimplifyFix(replacement));
}
}
}
}
}
@Override
public void visitPhpMethod(@NotNull Method method) {
if (!method.isAbstract()) {
this.inspectForSenselessReturn(method);
}
}
@Override
public void visitPhpFunction(@NotNull Function function) {
this.inspectForSenselessReturn(function);
}
private void inspectForSenselessReturn(@NotNull Function callable) {
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(callable);
final PsiElement lastStatement = body == null ? null : ExpressionSemanticUtil.getLastStatement(body);
if (lastStatement instanceof PhpReturn) {
final PhpExpression returnValue = ExpressionSemanticUtil.getReturnValue((PhpReturn) lastStatement);
if (returnValue == null) {
holder.registerProblem(lastStatement, MessagesPresentationUtil.prefixWithEa(messageSenseless), ProblemHighlightType.LIKE_UNUSED_SYMBOL);
}
}
}
private boolean isArgumentReference(@NotNull Variable variable, @NotNull Function function) {
boolean result = false;
final String variableName = variable.getName();
for (final Parameter parameter : function.getParameters()) {
if (parameter.getName().equals(variableName) && parameter.isPassByRef()) {
result = true;
break;
}
}
return result;
}
private boolean isBoundReference(@NotNull Variable variable, @NotNull Function function) {
boolean result = false;
final String variableName = variable.getName();
if (!variableName.isEmpty() && !(result = this.isReferenceBoundTo(variableName, function))) {
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(function);
if (body != null) {
result = PsiTreeUtil.findChildrenOfType(body, Function.class).stream().anyMatch(l -> this.isReferenceBoundTo(variableName, l));
}
}
return result;
}
private boolean isReferenceBoundTo(@NotNull String variableName, @NotNull Function function) {
boolean result = false;
if (OpenapiTypesUtil.isLambda(function)) {
final List<Variable> used = ExpressionSemanticUtil.getUseListVariables(function);
if (used != null) {
final Optional<Variable> match = used.stream().filter(v -> v.getName().equals(variableName)).findFirst();
if (match.isPresent()) {
final PsiElement previous = match.get().getPrevSibling();
final PsiElement candidate = previous instanceof PsiWhiteSpace ? previous.getPrevSibling() : previous;
result = OpenapiTypesUtil.is(candidate, PhpTokenTypes.opBIT_AND);
}
used.clear();
}
}
return result;
}
private boolean isUsedInFinally(@NotNull Variable variable, @NotNull Function function) {
boolean result = false;
final Try tryScope = PsiTreeUtil.getParentOfType(variable, Try.class, false, Function.class);
if (tryScope != null) {
final Finally finallyScope = tryScope.getFinallyBlock();
final GroupStatement body = finallyScope == null ? null : ExpressionSemanticUtil.getGroupStatement(finallyScope);
if (body != null) {
final String variableName = variable.getName();
result = PsiTreeUtil.findChildrenOfType(body, Variable.class).stream().anyMatch(v -> variableName.equals(v.getName()));
}
}
return result;
}
private boolean isStaticVariable(@NotNull Variable variable, @NotNull Function function) {
boolean result = false;
final GroupStatement body = ExpressionSemanticUtil.getGroupStatement(function);
if (body != null) {
final String variableName = variable.getName();
for (final PhpStaticStatement candidate : PsiTreeUtil.findChildrenOfType(body, PhpStaticStatement.class)) {
result = candidate.getDeclarations().stream().anyMatch(declaration -> {
final PhpPsiElement declared = declaration.getVariable();
return declared instanceof Variable && variableName.equals(declared.getName());
});
if (result) {
break;
}
}
}
return result;
}
};
}
use of com.intellij.psi.PsiElementVisitor in project intellij-plugins by JetBrains.
the class JstdConfigFileUtils method buildSequenceTextFragment.
@Nullable
public static PsiElementFragment<YAMLSequenceItem> buildSequenceTextFragment(@NotNull YAMLSequenceItem sequence) {
final Ref<Integer> startOffsetRef = Ref.create(null);
final Ref<Integer> endOffsetRef = Ref.create(null);
sequence.acceptChildren(new PsiElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (JsPsiUtils.isElementOfType(element, YAMLTokenTypes.TEXT, YAMLTokenTypes.SCALAR_DSTRING, YAMLTokenTypes.SCALAR_STRING)) {
UnquotedText unquotedText = new UnquotedText(element);
TextRange usefulTextRange = unquotedText.getUnquotedDocumentTextRange();
if (startOffsetRef.isNull()) {
startOffsetRef.set(usefulTextRange.getStartOffset());
}
endOffsetRef.set(usefulTextRange.getEndOffset());
}
}
});
Integer startOffset = startOffsetRef.get();
Integer endOffset = endOffsetRef.get();
if (startOffset == null || endOffset == null) {
return null;
}
int sequenceStartOffset = sequence.getTextRange().getStartOffset();
TextRange textRangeInSequence = TextRange.create(startOffset - sequenceStartOffset, endOffset - sequenceStartOffset);
return PsiElementFragment.create(sequence, textRangeInSequence);
}
use of com.intellij.psi.PsiElementVisitor in project intellij-community by JetBrains.
the class InjectedReferencesInspection method buildVisitor.
@NotNull
@Override
public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
return new PsiElementVisitor() {
@Override
public void visitElement(PsiElement element) {
PsiReference[] injected = InjectedReferencesContributor.getInjectedReferences(element);
if (injected != null) {
for (PsiReference reference : injected) {
if (reference.resolve() == null) {
TextRange range = reference.getRangeInElement();
if (range.isEmpty() && range.getStartOffset() == 1 && "\"\"".equals(element.getText())) {
String message = ProblemsHolder.unresolvedReferenceMessage(reference);
holder.registerProblem(element, message, ProblemHighlightType.LIKE_UNKNOWN_SYMBOL, TextRange.create(0, 2));
} else {
holder.registerProblem(reference);
}
}
}
}
super.visitElement(element);
}
};
}
use of com.intellij.psi.PsiElementVisitor in project intellij-community by JetBrains.
the class XmlLanguageInjector method getInjectedLanguage.
void getInjectedLanguage(final PsiElement place, final Ref<Boolean> unparsableRef, final PairProcessor<Language, List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>>> processor) {
if (place instanceof XmlTag) {
final XmlTag xmlTag = (XmlTag) place;
List<BaseInjection> injections = myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID);
//noinspection ForLoopReplaceableByForEach
for (int i = 0, injectionsSize = injections.size(); i < injectionsSize; i++) {
final BaseInjection injection = injections.get(i);
if (injection.acceptsPsiElement(xmlTag)) {
final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId());
if (language == null)
continue;
final boolean separateFiles = !injection.isSingleFile() && StringUtil.isNotEmpty(injection.getValuePattern());
final List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> result = ContainerUtil.newArrayList();
xmlTag.acceptChildren(new PsiElementVisitor() {
@Override
public void visitElement(final PsiElement element) {
if (element instanceof XmlText) {
if (!(element instanceof PsiLanguageInjectionHost) || element.getTextLength() == 0)
return;
final List<TextRange> list = injection.getInjectedArea(element);
final InjectedLanguage l = InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false);
for (TextRange textRange : list) {
result.add(Trinity.create((PsiLanguageInjectionHost) element, l, textRange));
}
} else if (element instanceof XmlTag) {
if (!separateFiles)
unparsableRef.set(Boolean.TRUE);
if (injection instanceof AbstractTagInjection && ((AbstractTagInjection) injection).isApplyToSubTags()) {
element.acceptChildren(this);
}
}
}
});
if (!result.isEmpty()) {
if (separateFiles) {
for (Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange> trinity : result) {
processor.process(language, Collections.singletonList(trinity));
}
} else {
processor.process(language, result);
}
}
if (injection.isTerminal()) {
break;
}
}
}
} else if (place instanceof XmlAttributeValue && place.getParent() instanceof XmlAttribute) {
final XmlAttribute attribute = (XmlAttribute) place.getParent();
final XmlAttributeValue value = (XmlAttributeValue) place;
//if (value == null) return;
// Check that we don't inject anything into embedded (e.g. JavaScript) content:
// XmlToken: "
// JSEmbeddedContent
// XmlToken "
// Actually IDEA shouldn't ask for injected languages at all in this case.
final PsiElement[] children = value.getChildren();
if (children.length < 3 || !(children[1] instanceof XmlToken) || ((XmlToken) children[1]).getTokenType() != XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN) {
return;
}
List<BaseInjection> injections = myConfiguration.getInjections(XmlLanguageInjectionSupport.XML_SUPPORT_ID);
//noinspection ForLoopReplaceableByForEach
for (int i = 0, size = injections.size(); i < size; i++) {
BaseInjection injection = injections.get(i);
if (injection.acceptsPsiElement(attribute)) {
final Language language = InjectedLanguage.findLanguageById(injection.getInjectedLanguageId());
if (language == null)
continue;
final boolean separateFiles = !injection.isSingleFile() && StringUtil.isNotEmpty(injection.getValuePattern());
final List<TextRange> ranges = injection.getInjectedArea(value);
if (ranges.isEmpty())
continue;
final List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> result = new ArrayList<>();
final InjectedLanguage l = InjectedLanguage.create(injection.getInjectedLanguageId(), injection.getPrefix(), injection.getSuffix(), false);
for (TextRange textRange : ranges) {
result.add(Trinity.create((PsiLanguageInjectionHost) value, l, textRange));
}
if (separateFiles) {
for (Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange> trinity : result) {
processor.process(language, Collections.singletonList(trinity));
}
} else {
processor.process(language, result);
}
if (injection.isTerminal()) {
break;
}
}
}
}
}
use of com.intellij.psi.PsiElementVisitor in project intellij-community by JetBrains.
the class InconsistentLanguageLevelInspection method runInspection.
@Override
public void runInspection(@NotNull AnalysisScope scope, @NotNull InspectionManager manager, @NotNull GlobalInspectionContext globalContext, @NotNull ProblemDescriptionsProcessor problemProcessor) {
final Set<Module> modules = new THashSet<>();
scope.accept(new PsiElementVisitor() {
@Override
public void visitElement(PsiElement element) {
final Module module = ModuleUtilCore.findModuleForPsiElement(element);
if (module != null) {
modules.add(module);
}
}
});
LanguageLevel projectLanguageLevel = LanguageLevelProjectExtension.getInstance(manager.getProject()).getLanguageLevel();
for (Module module : modules) {
LanguageLevel languageLevel = LanguageLevelModuleExtensionImpl.getInstance(module).getLanguageLevel();
if (languageLevel == null) {
languageLevel = projectLanguageLevel;
}
RefManager refManager = globalContext.getRefManager();
final RefModule refModule = refManager.getRefModule(module);
for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
if (!(entry instanceof ModuleOrderEntry))
continue;
final Module dependantModule = ((ModuleOrderEntry) entry).getModule();
if (dependantModule == null)
continue;
LanguageLevel dependantLanguageLevel = LanguageLevelModuleExtensionImpl.getInstance(dependantModule).getLanguageLevel();
if (dependantLanguageLevel == null) {
dependantLanguageLevel = projectLanguageLevel;
}
if (languageLevel.compareTo(dependantLanguageLevel) < 0) {
final CommonProblemDescriptor problemDescriptor = manager.createProblemDescriptor("Inconsistent language level settings: module " + module.getName() + " with language level " + languageLevel + " depends on module " + dependantModule.getName() + " with language level " + dependantLanguageLevel, new UnnecessaryModuleDependencyInspection.RemoveModuleDependencyFix(module, dependantModule), (QuickFix) QuickFixFactory.getInstance().createShowModulePropertiesFix(module));
problemProcessor.addProblemElement(refModule, problemDescriptor);
}
}
}
}
Aggregations