EditorOptions editorOptions = options.getEditorOptions();
ZoomOptions zoomOptions = editorOptions.getZoomOptions();
if (zoomOptions.isWheelZooming() && e.isControlDown()) {
- if (e.getWheelRotation() < 0) {
+ int rotation = e.getWheelRotation();
+ if (rotation < 0) {
zoomModel.zoomOut();
- } else {
+ }
+ else if (rotation > 0) {
zoomModel.zoomIn();
}
e.consume();
import org.jetbrains.org.objectweb.asm.Opcodes;
import java.util.Collections;
+import java.util.Deque;
+import java.util.LinkedList;
import java.util.List;
-import java.util.Stack;
/**
* User: Alexander Podkhalyuzin
final Ref<TextRange> textRange = new Ref<>(lineRange);
final PsiElementVisitor methodCollector = new JavaRecursiveElementVisitor() {
- final Stack<PsiMethod> myContextStack = new Stack<>();
- final Stack<String> myParamNameStack = new Stack<>();
+ final Deque<PsiMethod> myContextStack = new LinkedList<>();
+ final Deque<String> myParamNameStack = new LinkedList<>();
private int myNextLambdaExpressionOrdinal = 0;
private boolean myInsideLambda = false;
@Nullable
private String getCurrentParamName() {
- return myParamNameStack.isEmpty() ? null : myParamNameStack.peek();
+ return myParamNameStack.peekFirst();
}
@Override
}
public void visitExpressionList(PsiExpressionList expressionList) {
- final PsiMethod psiMethod = myContextStack.isEmpty()? null : myContextStack.peek();
+ PsiMethod psiMethod = myContextStack.peekFirst();
if (psiMethod != null) {
final String methodName = psiMethod.getName();
final PsiExpression[] expressions = expressionList.getExpressions();
private final MultiMap<Integer, String> myNames;
private int myCurrentSlotIndex;
private final PsiElement myElement;
- private final Stack<Integer> myIndexStack;
+ private final Deque<Integer> myIndexStack = new LinkedList<>();
private boolean myReached = false;
public LocalVariableNameFinder(int startSlot, MultiMap<Integer, String> names, PsiElement element) {
myNames = names;
myCurrentSlotIndex = startSlot;
myElement = element;
- myIndexStack = new Stack<>();
-
}
private boolean shouldVisit(PsiElement scope) {
}
else {
final Editor editor = CommonDataKeys.EDITOR.getData(dataContext);
+ PsiElement element = null;
if (editor != null) {
+ final PsiFile editorFile = CommonDataKeys.PSI_FILE.getData(dataContext);
final List<Caret> allCarets = editor.getCaretModel().getAllCarets();
- if (allCarets.size() > 1) {
- final PsiFile editorFile = CommonDataKeys.PSI_FILE.getData(dataContext);
- if (editorFile != null) {
+ if (editorFile != null) {
+ if (allCarets.size() > 1) {
final Set<PsiMethod> methods = new LinkedHashSet<>();
for (Caret caret : allCarets) {
ContainerUtil.addIfNotNull(methods, PsiTreeUtil.getParentOfType(editorFile.findElementAt(caret.getOffset()), PsiMethod.class));
return collectTestMembers(methods.toArray(PsiElement.EMPTY_ARRAY), checkAbstract, checkIsTest, processor, classes);
}
}
+ else {
+ element = editorFile.findElementAt(editor.getCaretModel().getOffset());
+ }
}
}
- final PsiElement element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
+
+ if (element == null) {
+ element = CommonDataKeys.PSI_ELEMENT.getData(dataContext);
+ }
+
final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext);
if (files != null) {
Project project = CommonDataKeys.PROJECT.getData(dataContext);
private JavaSdkVersion myJavaSdkVersion;
@SuppressWarnings("StatefulEp") private PsiFile myFile;
+ @SuppressWarnings("StatefulEp") private PsiJavaModule myJavaModule;
// map codeBlock->List of PsiReferenceExpression of uninitialized final variables
private final Map<PsiElement, Collection<PsiReferenceExpression>> myUninitializedVarProblems = new THashMap<>();
@Override
public boolean analyze(@NotNull PsiFile file, boolean updateWholeFile, @NotNull HighlightInfoHolder holder, @NotNull Runnable highlight) {
- myFile = file;
- myHolder = Holder.CHECK_ELEMENT_LEVEL ? new CheckLevelHighlightInfoHolder(file, holder) : holder;
-
boolean success = true;
try {
- myLanguageLevel = PsiUtil.getLanguageLevel(file);
- myJavaSdkVersion = notNull(JavaVersionService.getInstance().getJavaSdkVersion(file), JavaSdkVersion.fromLanguageLevel(myLanguageLevel));
+ prepare(Holder.CHECK_ELEMENT_LEVEL ? new CheckLevelHighlightInfoHolder(file, holder) : holder, file);
if (updateWholeFile) {
ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
if (progress == null) throw new IllegalStateException("Must be run under progress");
myReassignedParameters.clear();
myRefCountHolder = null;
+ myJavaModule = null;
myFile = null;
myHolder = null;
myDuplicateMethods.clear();
return success;
}
+ protected void prepareToRunAsInspection(@NotNull HighlightInfoHolder holder) {
+ prepare(holder, holder.getContextFile());
+ }
+
+ private void prepare(HighlightInfoHolder holder, PsiFile file) {
+ myHolder = holder;
+ myFile = file;
+ myLanguageLevel = PsiUtil.getLanguageLevel(file);
+ myJavaSdkVersion = notNull(JavaVersionService.getInstance().getJavaSdkVersion(file), JavaSdkVersion.fromLanguageLevel(myLanguageLevel));
+ myJavaModule = myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_9) ? ModuleHighlightUtil.getModuleDescriptor(file) : null;
+ }
+
@Override
public void visitElement(PsiElement element) {
if (myRefCountHolder != null && myFile instanceof ServerPageFile) {
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement ref) {
- JavaResolveResult resolveResult = doVisitReferenceElement(ref);
- if (resolveResult != null && !myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkRawOnParameterizedType(ref, resolveResult.getElement()));
+ JavaResolveResult result = doVisitReferenceElement(ref);
+ if (result != null) {
+ PsiElement resolved = result.getElement();
+ if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkRawOnParameterizedType(ref, resolved));
+ if (!myHolder.hasErrorResults() && resolved != null && myJavaModule != null) {
+ myHolder.add(ModuleHighlightUtil.checkPackageAccessibility(ref, resolved, myJavaModule));
+ }
+ }
}
private JavaResolveResult doVisitReferenceElement(@NotNull PsiJavaCodeReferenceElement ref) {
private HighlightInfo checkFeature(@NotNull PsiElement element, @NotNull Feature feature) {
return HighlightUtil.checkFeature(element, feature, myLanguageLevel, myFile);
}
-
- protected void prepareToRunAsInspection(@NotNull HighlightInfoHolder holder) {
- PsiFile file = holder.getContextFile();
- JavaSdkVersion sdkVersion = JavaVersionService.getInstance().getJavaSdkVersion(file);
-
- myHolder = holder;
- myFile = file;
- myLanguageLevel = PsiUtil.getLanguageLevel(file);
- myJavaSdkVersion = sdkVersion != null ? sdkVersion : JavaSdkVersion.fromLanguageLevel(myLanguageLevel);
- }
}
\ No newline at end of file
+++ /dev/null
-/*
- * Copyright 2000-2016 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInsight.daemon.impl.analysis;
-
-import com.intellij.openapi.application.ReadAction;
-import com.intellij.openapi.module.Module;
-import com.intellij.openapi.module.ModuleManager;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
-import com.intellij.psi.search.FilenameIndex;
-import com.intellij.psi.util.CachedValueProvider.Result;
-import com.intellij.psi.util.CachedValuesManager;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.MultiMap;
-import com.intellij.util.graph.DFSTBuilder;
-import com.intellij.util.graph.Graph;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-import static com.intellij.psi.PsiJavaModule.MODULE_INFO_FILE;
-import static com.intellij.psi.SyntaxTraverser.psiTraverser;
-import static com.intellij.psi.util.PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT;
-
-public class JavaModuleGraphBuilder {
- private JavaModuleGraphBuilder() { }
-
- @Nullable
- public static Graph<PsiJavaModule> getOrBuild(@NotNull Project project) {
- return CachedValuesManager.getManager(project).getCachedValue(project, () -> {
- Graph<PsiJavaModule> graph = ReadAction.compute(() -> build(project));
- return Result.create(graph, OUT_OF_CODE_BLOCK_MODIFICATION_COUNT);
- });
- }
-
- @Nullable
- public static Collection<PsiJavaModule> findCycle(@NotNull Graph<PsiJavaModule> graph, @NotNull PsiJavaModule module) {
- return ((JavaModuleGraph)graph).myCycles.stream().filter(set -> set.contains(module)).findFirst().orElse(null);
- }
-
- // Discovers relationships between Java modules in the project.
- // Library/JDK modules are excluded - in assumption there can't be any lib -> src dependencies.
- private static Graph<PsiJavaModule> build(Project project) {
- Set<PsiJavaModule> projectModules = ContainerUtil.newHashSet();
- for (Module module : ModuleManager.getInstance(project).getModules()) {
- Collection<VirtualFile> files = FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, module.getModuleScope(false));
- if (files.size() > 1) return null; // aborts the process when there are incorrect modules in the project
- VirtualFile vFile = ContainerUtil.getFirstItem(files);
- if (vFile != null) {
- PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile);
- if (psiFile instanceof PsiJavaFile) {
- PsiJavaModule moduleDeclaration = ((PsiJavaFile)psiFile).getModuleDeclaration();
- if (moduleDeclaration != null) {
- projectModules.add(moduleDeclaration);
- }
- }
- }
- }
-
- MultiMap<PsiJavaModule, PsiJavaModule> relations = MultiMap.create();
- for (PsiJavaModule moduleDeclaration : projectModules) {
- for (PsiRequiresStatement statement : psiTraverser().children(moduleDeclaration).filter(PsiRequiresStatement.class)) {
- PsiJavaModule dependency = resolveDependency(statement);
- if (dependency != null && projectModules.contains(dependency)) {
- relations.putValue(moduleDeclaration, dependency);
- }
- }
- }
- return new JavaModuleGraph(relations);
- }
-
- private static PsiJavaModule resolveDependency(PsiRequiresStatement statement) {
- PsiJavaModuleReferenceElement refElement = statement.getReferenceElement();
- if (refElement != null) {
- PsiPolyVariantReference ref = refElement.getReference();
- if (ref != null) {
- ResolveResult[] results = ref.multiResolve(true);
- if (results.length == 1) {
- PsiElement target = results[0].getElement();
- if (target instanceof PsiJavaModule) {
- return (PsiJavaModule)target;
- }
- }
- }
- }
-
- return null;
- }
-
- private static class JavaModuleGraph implements Graph<PsiJavaModule> {
- private final MultiMap<PsiJavaModule, PsiJavaModule> myMap;
- private final List<Set<PsiJavaModule>> myCycles;
-
- public JavaModuleGraph(MultiMap<PsiJavaModule, PsiJavaModule> map) {
- myMap = map;
-
- DFSTBuilder<PsiJavaModule> builder = new DFSTBuilder<>(this);
- myCycles = builder.getComponents().stream()
- .map(ContainerUtil::newLinkedHashSet)
- .collect(Collectors.toList());
- }
-
- @Override
- public Collection<PsiJavaModule> getNodes() {
- return myMap.keySet();
- }
-
- @Override
- public Iterator<PsiJavaModule> getIn(PsiJavaModule n) {
- return ContainerUtil.emptyIterator();
- }
-
- @Override
- public Iterator<PsiJavaModule> getOut(PsiJavaModule n) {
- return myMap.get(n).iterator();
- }
- }
-}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright 2000-2016 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.daemon.impl.analysis;
+
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.search.FilenameIndex;
+import com.intellij.psi.util.CachedValueProvider.Result;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.graph.DFSTBuilder;
+import com.intellij.util.graph.Graph;
+import com.intellij.util.graph.GraphGenerator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.intellij.psi.PsiJavaModule.MODULE_INFO_FILE;
+import static com.intellij.psi.SyntaxTraverser.psiTraverser;
+import static com.intellij.psi.util.PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT;
+
+public class JavaModuleGraphUtil {
+ private JavaModuleGraphUtil() { }
+
+ @Nullable
+ public static Collection<PsiJavaModule> findCycle(@NotNull PsiJavaModule module) {
+ Project project = module.getProject();
+ List<Set<PsiJavaModule>> cycles = CachedValuesManager.getManager(project).getCachedValue(project, () ->
+ Result.create(ReadAction.compute(() -> findCycles(project)), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT));
+ return ContainerUtil.find(cycles, set -> set.contains(module));
+ }
+
+ public static boolean reads(@NotNull PsiJavaModule source, @NotNull PsiJavaModule destination) {
+ Project project = source.getProject();
+ RequiresGraph graph = CachedValuesManager.getManager(project).getCachedValue(project, () ->
+ Result.create(ReadAction.compute(() -> buildRequiresGraph(project)), OUT_OF_CODE_BLOCK_MODIFICATION_COUNT));
+ return graph.reads(source, destination);
+ }
+
+ // Looks for cycles between Java modules in the project sources.
+ // Library/JDK modules are excluded - in assumption there can't be any lib -> src dependencies.
+ // Module references are resolved "globally" (i.e., without taking project dependencies into account).
+ private static List<Set<PsiJavaModule>> findCycles(Project project) {
+ Set<PsiJavaModule> projectModules = ContainerUtil.newHashSet();
+ for (Module module : ModuleManager.getInstance(project).getModules()) {
+ Collection<VirtualFile> files = FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, module.getModuleScope(false));
+ if (files.size() > 1) return Collections.emptyList(); // aborts the process when there are incorrect modules in the project
+ Optional.ofNullable(ContainerUtil.getFirstItem(files))
+ .map(PsiManager.getInstance(project)::findFile)
+ .map(f -> f instanceof PsiJavaFile ? ((PsiJavaFile)f).getModuleDeclaration() : null)
+ .ifPresent(projectModules::add);
+ }
+
+ if (!projectModules.isEmpty()) {
+ MultiMap<PsiJavaModule, PsiJavaModule> relations = MultiMap.create();
+ for (PsiJavaModule module : projectModules) {
+ for (PsiRequiresStatement statement : psiTraverser().children(module).filter(PsiRequiresStatement.class)) {
+ Optional.ofNullable(statement.getReferenceElement())
+ .map(PsiJavaModuleReferenceElement::getReference)
+ .map(ref -> ref.multiResolve(true))
+ .map(a -> a.length == 1 ? a[0].getElement() : null)
+ .map(e -> e instanceof PsiJavaModule ? (PsiJavaModule)e : null)
+ .filter(projectModules::contains)
+ .ifPresent(dependency -> relations.putValue(module, dependency));
+ }
+ }
+
+ if (!relations.isEmpty()) {
+ Graph<PsiJavaModule> graph = new SourceSemiGraph(relations);
+ DFSTBuilder<PsiJavaModule> builder = new DFSTBuilder<>(graph);
+ Collection<Collection<PsiJavaModule>> components = builder.getComponents();
+ if (!components.isEmpty()) {
+ return components.stream().map(ContainerUtil::newLinkedHashSet).collect(Collectors.toList());
+ }
+ }
+ }
+
+ return Collections.emptyList();
+ }
+
+ // Starting from source modules, collects all module dependencies in the project.
+ // The resulting graph is used for tracing readability.
+ private static RequiresGraph buildRequiresGraph(Project project) {
+ MultiMap<PsiJavaModule, PsiJavaModule> relations = MultiMap.create();
+ Set<String> publicEdges = ContainerUtil.newTroveSet();
+ for (Module module : ModuleManager.getInstance(project).getModules()) {
+ Collection<VirtualFile> files = FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, module.getModuleScope(false));
+ Optional.ofNullable(ContainerUtil.getFirstItem(files))
+ .map(PsiManager.getInstance(project)::findFile)
+ .map(f -> f instanceof PsiJavaFile ? ((PsiJavaFile)f).getModuleDeclaration() : null)
+ .ifPresent(m -> visit(m, relations, publicEdges));
+ }
+
+ GraphGenerator<PsiJavaModule> graph = GraphGenerator.create(new RequiresSemiGraph(relations));
+ return new RequiresGraph(graph, publicEdges);
+ }
+
+ private static void visit(PsiJavaModule module, MultiMap<PsiJavaModule, PsiJavaModule> relations, Set<String> publicEdges) {
+ if (!relations.containsKey(module)) {
+ relations.putValues(module, Collections.emptyList());
+ for (PsiRequiresStatement statement : psiTraverser().children(module).filter(PsiRequiresStatement.class)) {
+ Optional.ofNullable(statement.getReferenceElement())
+ .map(PsiJavaModuleReferenceElement::getReference)
+ .map(PsiReference::resolve)
+ .map(e -> e instanceof PsiJavaModule ? (PsiJavaModule)e : null)
+ .ifPresent(dependency -> {
+ relations.putValue(module, dependency);
+ if (isPublic(statement)) publicEdges.add(RequiresGraph.key(dependency, module));
+ visit(dependency, relations, publicEdges);
+ });
+ }
+ }
+ }
+
+ private static boolean isPublic(PsiRequiresStatement statement) {
+ for (PsiElement child = statement.getFirstChild(); child != null; child = child.getNextSibling()) {
+ if (PsiUtil.isJavaToken(child, JavaTokenType.PUBLIC_KEYWORD)) return true;
+ if (child instanceof PsiJavaModuleReferenceElement) break;
+ }
+ return false;
+ }
+
+ private static class RequiresGraph {
+ private final Graph<PsiJavaModule> myGraph;
+ private final Set<String> myPublicEdges;
+
+ public RequiresGraph(Graph<PsiJavaModule> graph, Set<String> publicEdges) {
+ myGraph = graph;
+ myPublicEdges = publicEdges;
+ }
+
+ public boolean reads(PsiJavaModule source, PsiJavaModule destination) {
+ Iterator<PsiJavaModule> directReaders = myGraph.getOut(destination);
+ while (directReaders.hasNext()) {
+ PsiJavaModule next = directReaders.next();
+ if (source.equals(next) || myPublicEdges.contains(key(destination, next)) && reads(source, next)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static String key(PsiJavaModule module, PsiJavaModule exporter) {
+ return module.getModuleName() + '/' + exporter.getModuleName();
+ }
+ }
+
+ //<editor-fold desc="Helpers.">
+ private static class SourceSemiGraph implements Graph<PsiJavaModule> {
+ private final MultiMap<PsiJavaModule, PsiJavaModule> myMap;
+
+ public SourceSemiGraph(MultiMap<PsiJavaModule, PsiJavaModule> map) {
+ myMap = map;
+ }
+
+ @Override
+ public Collection<PsiJavaModule> getNodes() {
+ return myMap.keySet();
+ }
+
+ @Override
+ public Iterator<PsiJavaModule> getIn(PsiJavaModule n) {
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public Iterator<PsiJavaModule> getOut(PsiJavaModule n) {
+ return myMap.get(n).iterator();
+ }
+ }
+
+ private static class RequiresSemiGraph implements GraphGenerator.SemiGraph<PsiJavaModule> {
+ private final MultiMap<PsiJavaModule, PsiJavaModule> myMap;
+
+ public RequiresSemiGraph(MultiMap<PsiJavaModule, PsiJavaModule> map) {
+ myMap = map;
+ }
+
+ @Override
+ public Collection<PsiJavaModule> getNodes() {
+ return myMap.keySet();
+ }
+
+ @Override
+ public Iterator<PsiJavaModule> getIn(PsiJavaModule n) {
+ return myMap.get(n).iterator();
+ }
+ }
+ //</editor-fold>
+}
\ No newline at end of file
final PsiClass aClass = resolveResult.getElement();
if (aClass != null) {
if (aClass instanceof PsiTypeParameter) return null; //should be logged as cyclic inference
- final List<HierarchicalMethodSignature> signatures = LambdaUtil.findFunctionCandidates(aClass);
- if (signatures != null && signatures.size() == 1) {
- final MethodSignature functionalMethod = signatures.get(0);
- if (functionalMethod.getTypeParameters().length > 0) return "Target method is generic";
- }
+ MethodSignature functionalMethod = LambdaUtil.getFunction(aClass);
+ if (functionalMethod != null && functionalMethod.getTypeParameters().length > 0) return "Target method is generic";
if (checkReturnTypeApplicable(resolveResult, aClass)) {
return "No instance of type " + functionalInterfaceType.getPresentableText() + " exists so that lambda expression can be type-checked";
}
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.JBIterable;
-import com.intellij.util.graph.Graph;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.PropertyKey;
import static com.intellij.psi.SyntaxTraverser.psiTraverser;
public class ModuleHighlightUtil {
+ @Nullable
+ static PsiJavaModule getModuleDescriptor(@NotNull PsiElement element) {
+ VirtualFile file = Optional.of(element)
+ .map(e -> e instanceof PsiFileSystemItem ? (PsiFileSystemItem)e : e.getContainingFile())
+ .map(PsiFileSystemItem::getVirtualFile)
+ .orElse(null);
+ if (file == null) return null;
+
+ Project project = element.getProject();
+ ProjectFileIndex index = ProjectFileIndex.SERVICE.getInstance(project);
+ if (element instanceof PsiCompiledElement) {
+ return Optional.ofNullable(index.getClassRootForFile(file))
+ .map(r -> r.findChild(PsiJavaModule.MODULE_INFO_CLS_FILE))
+ .map(PsiManager.getInstance(project)::findFile)
+ .map(f -> f instanceof PsiJavaFile ? ((PsiJavaFile)f).getModuleDeclaration() : null)
+ .orElse(null);
+ }
+ else {
+ Module module = index.getModuleForFile(file);
+ return Optional.ofNullable(module)
+ .map(m -> FilenameIndex.getVirtualFilesByName(project, MODULE_INFO_FILE, m.getModuleScope(false)))
+ .map(c -> c.size () == 1 ? c.iterator().next() : null)
+ .map(PsiManager.getInstance(project)::findFile)
+ .map(f -> f instanceof PsiJavaFile ? ((PsiJavaFile)f).getModuleDeclaration() : null)
+ .orElse(null);
+ }
+ }
+
@Nullable
static HighlightInfo checkFileName(@NotNull PsiJavaModule element, @NotNull PsiFile file) {
if (!MODULE_INFO_FILE.equals(file.getName())) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).description(message).create();
}
else {
- Graph<PsiJavaModule> graph = JavaModuleGraphBuilder.getOrBuild(target.getProject());
- if (graph != null) {
- Collection<PsiJavaModule> cycle = JavaModuleGraphBuilder.findCycle(graph, (PsiJavaModule)target);
- if (cycle != null && cycle.contains(container)) {
- Stream<String> stream = cycle.stream().map(PsiJavaModule::getModuleName);
- if (ApplicationManager.getApplication().isUnitTestMode()) stream = stream.sorted();
- String message = JavaErrorMessages.message("module.cyclic.dependence", stream.collect(Collectors.joining(", ")));
- return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).description(message).create();
- }
+ Collection<PsiJavaModule> cycle = JavaModuleGraphUtil.findCycle((PsiJavaModule)target);
+ if (cycle != null && cycle.contains(container)) {
+ Stream<String> stream = cycle.stream().map(PsiJavaModule::getModuleName);
+ if (ApplicationManager.getApplication().isUnitTestMode()) stream = stream.sorted();
+ String message = JavaErrorMessages.message("module.cyclic.dependence", stream.collect(Collectors.joining(", ")));
+ return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(refElement).description(message).create();
}
}
}
return null;
}
+ @Nullable
+ static HighlightInfo checkPackageAccessibility(@NotNull PsiJavaCodeReferenceElement ref,
+ @NotNull PsiElement target,
+ @NotNull PsiJavaModule refModule) {
+ Module module = ModuleUtilCore.findModuleForPsiElement(ref);
+ if (module != null) {
+ if (target instanceof PsiClass && !(target instanceof PsiCompiledElement) && module != ModuleUtilCore.findModuleForPsiElement(target)) {
+ PsiElement targetFile = target.getParent();
+ if (targetFile instanceof PsiClassOwner) {
+ PsiJavaModule targetModule = getModuleDescriptor(target);
+ String packageName = ((PsiClassOwner)targetFile).getPackageName();
+ return checkPackageAccessibility(ref, refModule, targetModule, packageName);
+ }
+ }
+ else if (target instanceof PsiPackage) {
+ PsiElement refImport = ref.getParent();
+ if (refImport instanceof PsiImportStatementBase && ((PsiImportStatementBase)refImport).isOnDemand()) {
+ PsiDirectory[] dirs = ((PsiPackage)target).getDirectories(module.getModuleWithDependenciesAndLibrariesScope(false));
+ if (dirs.length == 1 && ModuleUtilCore.findModuleForPsiElement(dirs[0]) != module) {
+ PsiJavaModule targetModule = getModuleDescriptor(dirs[0]);
+ String packageName = ((PsiPackage)target).getQualifiedName();
+ return checkPackageAccessibility(ref, refModule, targetModule, packageName);
+ }
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private static HighlightInfo checkPackageAccessibility(PsiJavaCodeReferenceElement ref,
+ PsiJavaModule refModule,
+ PsiJavaModule targetModule,
+ String packageName) {
+ if (targetModule == null) {
+ String message = JavaErrorMessages.message("module.package.on.classpath");
+ return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).description(message).create();
+ }
+
+ String refModuleName = refModule.getModuleName();
+ String requiredName = targetModule.getModuleName();
+ if (!(targetModule instanceof PsiCompiledElement) && !isExported(targetModule, packageName)) {
+ String message = JavaErrorMessages.message("module.package.not.exported", requiredName, packageName, refModuleName);
+ return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).description(message).create();
+ }
+
+ if (!(PsiJavaModule.JAVA_BASE.equals(requiredName) || JavaModuleGraphUtil.reads(refModule, targetModule))) {
+ String message = JavaErrorMessages.message("module.not.in.requirements", refModuleName, requiredName);
+ return HighlightInfo.newHighlightInfo(HighlightInfoType.WRONG_REF).range(ref).description(message).create();
+ }
+
+ return null;
+ }
+
+ private static boolean isExported(PsiJavaModule module, String packageName) {
+ for (PsiExportsStatement statement : psiTraverser().children(module).filter(PsiExportsStatement.class)) {
+ String exportedName = Optional.ofNullable(statement.getPackageReference()).map(ModuleHighlightUtil::refText).orElse("");
+ if (packageName.equals(exportedName)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
private static HighlightInfo moduleResolveError(PsiJavaModuleReferenceElement refElement, PsiPolyVariantReference ref) {
boolean missing = ref.multiResolve(true).length == 0;
String message = JavaErrorMessages.message(missing ? "module.not.found" : "module.not.on.path", refElement.getReferenceText());
}
private static class ReplaceWithLambdaFix implements LocalQuickFix, HighPriorityAction {
- @NotNull
- @Override
- public String getName() {
- return "Replace with lambda";
- }
-
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Replace with lambda";
}
@Override
}
private static class ReplaceWithMethodRefFix implements LocalQuickFix {
- @NotNull
- @Override
- public String getName() {
- return "Replace with method reference";
- }
-
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Replace with method reference";
}
- @Override
+ @Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final PsiElement element = descriptor.getPsiElement();
if (element instanceof PsiNewExpression) {
}
if (MARKER_PATTERN.accepts(element)) {
holder.registerProblem(element, "Redundant block marker", new LocalQuickFix() {
- @NotNull
- @Override
- public String getName() {
- return getFamilyName();
- }
-
@NotNull
@Override
public String getFamilyName() {
}
private static class ReplaceWithDiamondFix implements LocalQuickFix, HighPriorityAction {
- @NotNull
- @Override
- public String getName() {
- return "Replace with <>";
- }
-
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Replace with <>";
}
@Override
}
private static class ReplaceWithMethodRefFix implements LocalQuickFix {
- @NotNull
- @Override
- public String getName() {
- return "Replace lambda with method reference";
- }
-
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Replace lambda with method reference";
}
@Override
}
private static class AnnotateAsSafeVarargsQuickFix implements LocalQuickFix {
- @NotNull
- @Override
- public String getName() {
- return "Annotate as @SafeVarargs";
- }
-
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Annotate as @SafeVarargs";
}
@Override
}
private static class MakeFinalAndAnnotateQuickFix implements LocalQuickFix {
- @NotNull
- @Override
- public String getName() {
- return "Make final and annotate as @SafeVarargs";
- }
-
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Make final and annotate as @SafeVarargs";
}
@Override
}
private static class ReplaceWithExprFix implements LocalQuickFix, HighPriorityAction {
- @NotNull
- @Override
- public String getName() {
- return "Replace with expression lambda";
- }
-
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Replace with expression lambda";
}
@Override
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return CodeInsightBundle.message("remove.annotation");
}
ExternalAnnotationsManager.getInstance(project).deannotate(myListOwner, myAnnotation.getQualifiedName());
}
}
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
}
\ No newline at end of file
}
private static class ReplaceMethodRefWithQualifierFix implements LocalQuickFix {
- @Nls
- @NotNull
- @Override
- public String getName() {
- return getFamilyName();
- }
-
@Nls
@NotNull
@Override
myManager = manager;
}
- @Override
- @NotNull
- public String getName() {
- return QUICK_FIX_NAME;
- }
-
@Override
@NotNull
public String getFamilyName() {
- return getName();
+ return QUICK_FIX_NAME;
}
@Override
myName = name;
}
- @NotNull
- @Override
- public String getName() {
- return myName;
- }
-
@NotNull
@Override
public String getFamilyName() {
private static class RedundantInstanceofFix implements LocalQuickFix {
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return InspectionsBundle.message("inspection.data.flow.redundant.instanceof.quickfix");
}
}
}
}
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
}
}
Collection<PsiCall> getAlwaysFailingCalls() {
- return StreamEx.of(myFailingCalls.keySet()).filter(this::isAlwaysFailing).map(MethodCallInstruction::getCallExpression).toList();
+ return StreamEx.ofKeys(myFailingCalls, v -> v).map(MethodCallInstruction::getCallExpression).toList();
}
@Override
DfaInstructionState[] states = super.visitMethodCall(instruction, runner, memState);
if (hasNonTrivialFailingContracts(instruction)) {
boolean allFail = Arrays.stream(states).allMatch(s -> s.getMemoryState().peek() == runner.getFactory().getConstFactory().getContractFail());
- myFailingCalls.put(instruction, allFail && isAlwaysFailing(instruction));
+ myFailingCalls.merge(instruction, allFail, Boolean::logicalAnd);
}
return states;
}
Arrays.stream(contract.arguments).anyMatch(v -> v != MethodContract.ValueConstraint.ANY_VALUE);
}
- private boolean isAlwaysFailing(MethodCallInstruction instruction) {
- return !Boolean.FALSE.equals(myFailingCalls.get(instruction));
- }
-
@Override
protected boolean checkNotNullable(DfaMemoryState state, DfaValue value, NullabilityProblem problem, PsiElement anchor) {
boolean ok = super.checkNotNullable(state, value, problem, anchor);
myClearArguments = clearArguments;
}
- @Nls
- @NotNull
- @Override
- public String getName() {
- return getFamilyName();
- }
-
@NotNull
@Override
public String getFamilyName() {
}
private static class ReplaceWithListSortFix implements LocalQuickFix {
- @Nls
- @NotNull
- @Override
- public String getName() {
- return getFamilyName();
- }
-
@Nls
@NotNull
@Override
}
private static class ReplaceWithRemoveIfQuickFix implements LocalQuickFix {
- @Nls
- @NotNull
- @Override
- public String getName() {
- return getFamilyName();
- }
-
@Nls
@NotNull
@Override
private static class AcceptSuggested implements LocalQuickFix {
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return InspectionsBundle.message("inspection.can.be.final.accept.quickfix");
}
LOG.error(e);
}
}
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
}
@Override
private static class MyQuickFixAction implements LocalQuickFix {
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return InspectionsBundle.message("inspection.redundant.type.remove.quickfix");
}
LOG.error(e);
}
}
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
}
//separate quickfix is needed to invalidate initial method reference
private static class MyMethodReferenceFixAction implements LocalQuickFix {
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return InspectionsBundle.message("inspection.redundant.type.remove.quickfix");
}
expression.replace(createMethodReference(expression, typeElement));
}
}
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
}
}
myNullableName = nullable;
}
- @NotNull
- @Override
- public String getName() {
- return "Make \"" + (myNotNullName != null ? myNotNullName : myNullableName) + "\" default annotation";
- }
-
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Make \"" + (myNotNullName != null ? myNotNullName : myNullableName) + "\" default annotation";
}
@Override
private static class AcceptSuggested implements LocalQuickFix {
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return InspectionsBundle.message("inspection.redundant.cast.remove.quickfix");
}
RedundantCastUtil.removeCast(cast);
}
}
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
}
@Override
import com.intellij.codeInspection.LambdaCanBeMethodReferenceInspection;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
PsiType expressionType) {
PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
restoreComments(foreachStatement, foreachStatement.getBody());
- if (StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) {
+ InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, foreachStatement);
+ if (status != InitializerUsageStatus.UNKNOWN) {
PsiExpression initializer = var.getInitializer();
if (ExpressionUtils.isZero(initializer)) {
PsiType type = var.getType();
String replacement = (type.equals(expressionType) ? "" : "(" + type.getCanonicalText() + ") ") + builder;
- initializer.replace(elementFactory.createExpressionFromText(replacement, foreachStatement));
- removeLoop(foreachStatement);
- simplifyAndFormat(project, var);
+ replaceInitializer(foreachStatement, var, initializer, replacement, status);
return;
}
}
simplifyAndFormat(project, result);
}
+ static void replaceInitializer(PsiForeachStatement foreachStatement,
+ PsiVariable var,
+ PsiExpression initializer,
+ String replacement,
+ InitializerUsageStatus status) {
+ Project project = foreachStatement.getProject();
+ PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
+ if(status == InitializerUsageStatus.DECLARED_JUST_BEFORE) {
+ initializer.replace(elementFactory.createExpressionFromText(replacement, foreachStatement));
+ removeLoop(foreachStatement);
+ simplifyAndFormat(project, var);
+ } else {
+ if(status == InitializerUsageStatus.AT_WANTED_PLACE_ONLY) {
+ initializer.delete();
+ }
+ PsiElement result =
+ foreachStatement.replace(elementFactory.createStatementFromText(var.getName() + " = " + replacement + ";", foreachStatement));
+ simplifyAndFormat(project, result);
+ }
+ }
+
static void simplifyAndFormat(@NotNull Project project, PsiElement result) {
if (result == null) return;
LambdaCanBeMethodReferenceInspection.replaceAllLambdasWithMethodReferences(result);
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
+import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
* @author Tagir Valeev
*/
class ReplaceWithCollectFix extends MigrateToStreamFix {
+ private static final Logger LOG = Logger.getInstance(ReplaceWithCollectFix.class);
+
final String myMethodName;
protected ReplaceWithCollectFix(String methodName) {
final StringBuilder builder = generateStream(iteratedValue, operations);
final PsiExpression qualifierExpression = methodCallExpression.getMethodExpression().getQualifierExpression();
- final PsiExpression initializer = StreamApiMigrationInspection
- .extractReplaceableCollectionInitializer(qualifierExpression, foreachStatement);
- if (initializer != null) {
- String callText = builder.append(".collect(java.util.stream.Collectors.")
- .append(createInitializerReplacementText(qualifierExpression.getType(), initializer))
- .append(")").toString();
- PsiElement result = initializer.replace(elementFactory.createExpressionFromText(callText, null));
- simplifyAndFormat(project, result);
- removeLoop(foreachStatement);
- return;
+ final PsiLocalVariable variable = StreamApiMigrationInspection.extractCollectionVariable(qualifierExpression);
+ if (variable != null) {
+ InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(variable, foreachStatement);
+ if(status != InitializerUsageStatus.UNKNOWN) {
+ PsiExpression initializer = variable.getInitializer();
+ LOG.assertTrue(initializer != null);
+ String callText = builder.append(".collect(java.util.stream.Collectors.")
+ .append(createInitializerReplacementText(qualifierExpression.getType(), initializer))
+ .append(")").toString();
+ replaceInitializer(foreachStatement, variable, initializer, callText, status);
+ return;
+ }
}
final String qualifierText = qualifierExpression != null ? qualifierExpression.getText() + "." : "";
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
PsiExpression value = assignment.getRExpression();
if (value == null) return;
restoreComments(foreachStatement, body);
- if (StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) {
+ InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, foreachStatement);
+ if (status != InitializerUsageStatus.UNKNOWN) {
PsiExpression initializer = var.getInitializer();
if (initializer != null) {
- PsiElement result =
- initializer.replace(elementFactory.createExpressionFromText(generateOptionalUnwrap(stream, tb, value, initializer), initializer));
- removeLoop(foreachStatement);
- simplifyAndFormat(project, result);
+ String replacementText = generateOptionalUnwrap(stream, tb, value, initializer);
+ replaceInitializer(foreachStatement, var, initializer, replacementText, status);
return;
}
}
package com.intellij.codeInspection.streamMigration;
import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus;
import com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.Operation;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
// for(....) if(...) {flag = true; break;}
PsiVariable var = (PsiVariable)maybeVar;
PsiExpression initializer = var.getInitializer();
- if(initializer != null && StreamApiMigrationInspection.isDeclarationJustBefore(var, foreachStatement)) {
+ InitializerUsageStatus status = StreamApiMigrationInspection.getInitializerUsageStatus(var, foreachStatement);
+ if(initializer != null && status != InitializerUsageStatus.UNKNOWN) {
String replacement;
if(ExpressionUtils.isLiteral(initializer, Boolean.FALSE) &&
ExpressionUtils.isLiteral(rValue, Boolean.TRUE)) {
} else {
replacement = streamText + "?" + rValue.getText() + ":" + initializer.getText();
}
- PsiElement result = initializer.replace(elementFactory.createExpressionFromText(replacement, initializer));
- removeLoop(foreachStatement);
- simplifyAndFormat(project, result);
+ replaceInitializer(foreachStatement, var, initializer, replacement, status);
return;
}
}
import javax.swing.*;
import java.util.*;
+import static com.intellij.codeInspection.streamMigration.StreamApiMigrationInspection.InitializerUsageStatus.*;
+
/**
* User: anna
*/
return consumerClass != null ? psiFacade.getElementFactory().createType(consumerClass, variable.getType()) : null;
}
- @Contract("null, _ -> null")
- static PsiExpression extractReplaceableCollectionInitializer(PsiExpression qualifierExpression, PsiStatement foreachStatement) {
+ @Contract("null -> null")
+ static PsiLocalVariable extractCollectionVariable(PsiExpression qualifierExpression) {
if (qualifierExpression instanceof PsiReferenceExpression) {
final PsiElement resolve = ((PsiReferenceExpression)qualifierExpression).resolve();
if (resolve instanceof PsiLocalVariable) {
PsiLocalVariable var = (PsiLocalVariable)resolve;
- if (isDeclarationJustBefore(var, foreachStatement)) {
- final PsiExpression initializer = var.getInitializer();
- if (initializer instanceof PsiNewExpression) {
- final PsiExpressionList argumentList = ((PsiNewExpression)initializer).getArgumentList();
- if (argumentList != null && argumentList.getExpressions().length == 0) {
- return initializer;
- }
+ final PsiExpression initializer = var.getInitializer();
+ if (initializer instanceof PsiNewExpression) {
+ final PsiExpressionList argumentList = ((PsiNewExpression)initializer).getArgumentList();
+ if (argumentList != null && argumentList.getExpressions().length == 0) {
+ return var;
}
}
}
return null;
}
+ enum InitializerUsageStatus {
+ // Variable is declared just before the wanted place
+ DECLARED_JUST_BEFORE,
+ // All initial value usages go through wanted place and at wanted place the variable value is guaranteed to be the initial value
+ AT_WANTED_PLACE_ONLY,
+ // At wanted place the variable value is guaranteed to be the initial value, but this initial value might be used somewhere else
+ AT_WANTED_PLACE,
+ // It's not guaranteed that the variable value at wanted place is initial value
+ UNKNOWN
+ }
+
+ static InitializerUsageStatus getInitializerUsageStatus(PsiVariable var, PsiStatement nextStatement) {
+ if(var.getInitializer() == null) return UNKNOWN;
+ if(isDeclarationJustBefore(var, nextStatement)) return DECLARED_JUST_BEFORE;
+ PsiElement declaration = var.getParent();
+ // Check if variable is not referenced in the same declaration like "int a = 0, b = a;"
+ if(!PsiTreeUtil.processElements(declaration, e -> !(e instanceof PsiReferenceExpression) ||
+ ((PsiReferenceExpression)e).resolve() != var)) return UNKNOWN;
+ PsiElement block = PsiUtil.getVariableCodeBlock(var, null);
+ if(block == null) return UNKNOWN;
+ final ControlFlow controlFlow;
+ try {
+ controlFlow = ControlFlowFactory.getInstance(nextStatement.getProject())
+ .getControlFlow(block, LocalsOrMyInstanceFieldsControlFlowPolicy.getInstance());
+ }
+ catch (AnalysisCanceledException ignored) {
+ return UNKNOWN;
+ }
+ int start = controlFlow.getEndOffset(declaration);
+ int stop = controlFlow.getStartOffset(nextStatement);
+ if(ControlFlowUtil.isVariableReferencedBetween(controlFlow, start, stop, var)) return UNKNOWN;
+ return ControlFlowUtil.isValueUsedWithoutVisitingStop(controlFlow, start, stop, var) ? AT_WANTED_PLACE : AT_WANTED_PLACE_ONLY;
+ }
+
static boolean isDeclarationJustBefore(PsiVariable var, PsiStatement nextStatement) {
PsiElement declaration = var.getParent();
PsiElement nextStatementParent = nextStatement.getParent();
methodName = "addAll";
} else {
PsiMethodCallExpression methodCallExpression = tb.getSingleMethodCall();
- if(methodCallExpression != null && extractReplaceableCollectionInitializer(
- methodCallExpression.getMethodExpression().getQualifierExpression(), statement) != null) {
+ if(canCollect(statement, methodCallExpression)) {
methodName = "collect";
} else {
if (!SUGGEST_FOREACH) return;
}
}
- void handleSingleReturn(PsiForeachStatement statement,
- TerminalBlock tb,
- List<Operation> operations) {
+ boolean canCollect(PsiForeachStatement statement, PsiMethodCallExpression methodCallExpression) {
+ if(methodCallExpression == null) return false;
+ PsiLocalVariable variable = extractCollectionVariable(methodCallExpression.getMethodExpression().getQualifierExpression());
+ if(variable == null) return false;
+ return getInitializerUsageStatus(variable, statement) != UNKNOWN;
+ }
+
+ void handleSingleReturn(PsiForeachStatement statement, TerminalBlock tb, List<Operation> operations) {
PsiReturnStatement returnStatement = (PsiReturnStatement)tb.getSingleStatement();
PsiExpression value = returnStatement.getReturnValue();
PsiReturnStatement nextReturnStatement = getNextReturnStatement(statement);
- if(nextReturnStatement != null && (ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE))) {
+ if (nextReturnStatement != null &&
+ (ExpressionUtils.isLiteral(value, Boolean.TRUE) || ExpressionUtils.isLiteral(value, Boolean.FALSE))) {
boolean foundResult = (boolean)((PsiLiteralExpression)value).getValue();
if(ExpressionUtils.isLiteral(nextReturnStatement.getReturnValue(), !foundResult)) {
String methodName;
myDependency = dependency;
}
- @Override
- @NotNull
- public String getName() {
- return "Remove dependency";
- }
-
@Override
@NotNull
public String getFamilyName() {
- return getName();
+ return "Remove dependency";
}
@Override
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return InspectionsBundle.message("inspection.redundant.throws.remove.quickfix");
}
}
}
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
-
private void removeExcessiveThrows(@Nullable RefMethod refMethod, @Nullable final PsiModifierListOwner element, final CommonProblemDescriptor[] problems) {
try {
@Nullable final PsiMethod psiMethod;
myFiles = files;
}
- @Override
- @NotNull
- public String getName() {
- return myFiles == null ? InspectionsBundle.message("detach.library.quickfix.name") : InspectionsBundle.message("detach.library.roots.quickfix.name");
- }
-
@Override
@NotNull
public String getFamilyName() {
- return getName();
+ return myFiles == null ? InspectionsBundle.message("detach.library.quickfix.name") : InspectionsBundle.message("detach.library.roots.quickfix.name");
}
@Override
import java.util.regex.Pattern;
class ExcludeTable extends ListTableWithButtons<ExcludeTable.Item> {
- private static final Pattern ourPackagePattern = Pattern.compile("(\\w+\\.)*\\w+");
+ private static final Pattern ourPackagePattern = Pattern.compile("([\\w*]+\\.)*[\\w*]+");
private static final ColumnInfo<Item, String> NAME_COLUMN = new ColumnInfo<Item, String>("Class/package/member qualified name mask") {
@Nullable
@Override
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.impl.TemplateState;
import com.intellij.featureStatistics.FeatureUsageTracker;
+import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.event.DocumentAdapter;
TextRange endRange = templateState.getVariableRange(template.getVariableNameAt(template.getVariableCount() - 1));
if (startRange == null || endRange == null) return;
- editor.getDocument().deleteString(startRange.getStartOffset(), endRange.getEndOffset());
+ WriteCommandAction.runWriteCommandAction(editor.getProject(), () ->
+ editor.getDocument().deleteString(startRange.getStartOffset(), endRange.getEndOffset()));
}
});
}
}
- @NotNull
- @Override
- public String getName() {
- return QuickFixBundle.message("create.method.from.usage.family");
- }
-
@NotNull
@Override
public String getFamilyName() {
return QuickFixBundle.message(myMemberType == PropertyMemberType.FIELD ? "create.field.text":"create.property.text", myName);
}
- @Override
- @NotNull
- public String getName() {
- return getText();
- }
-
@Override
@NotNull
public String getFamilyName() {
myAssignmentExpression = smartPointerManager.createSmartPsiElementPointer(assignmentExpression);
}
- @Nls
- @NotNull
- @Override
- public String getName() {
- return getFamilyName();
- }
-
@NotNull
@Override
public String getFamilyName() {
if (defaultValue == null) return;
if (areEqual(value, defaultValue)) {
holder.registerProblem(value, "Redundant default parameter value assignment", ProblemHighlightType.LIKE_UNUSED_SYMBOL, new LocalQuickFix() {
- @Nls
- @NotNull
- @Override
- public String getName() {
- return "Remove redundant parameter";
- }
-
@Nls
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Remove redundant parameter";
}
@Override
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return InspectionsBundle.message("inspection.unused.assignment.remove.quickfix");
}
LOG.error(e);
}
}
-
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
}
return myHint;
}
- @Override
- @NotNull
- public String getName() {
- return InspectionsBundle.message("inspection.unused.parameter.delete.quickfix");
- }
-
@Override
@NotNull
public String getFamilyName() {
- return getName();
+ return InspectionsBundle.message("inspection.unused.parameter.delete.quickfix");
}
@Override
myReplaceTemplateFix = replaceTemplateFix;
}
- @Override
- @NotNull
- public String getName() {
- return InspectionsBundle.message("default.file.template.edit.template");
- }
-
@Override
@NotNull
public String getFamilyName() {
- return getName();
+ return InspectionsBundle.message("default.file.template.edit.template");
}
@Override
* @author cdr
*/
public abstract class ReplaceWithFileTemplateFix implements LocalQuickFix {
- @Override
- @NotNull
- public String getName() {
- return InspectionsBundle.message("default.file.template.replace.with.actual.file.template");
- }
-
@Override
@NotNull
public String getFamilyName() {
- return getName();
+ return InspectionsBundle.message("default.file.template.replace.with.actual.file.template");
}
}
myHint = hint;
}
- @Override
- @NotNull
- public String getName() {
- return QUICK_FIX_NAME;
- }
-
@Override
@NotNull
public String getFamilyName() {
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return QUICK_FIX_NAME;
}
applyFix(project, new ProblemDescriptor[]{descriptor}, new ArrayList<>(), null);
}
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
-
private void deleteHierarchy(RefMethod refMethod, List<PsiElement> result) {
Collection<RefMethod> derivedMethods = refMethod.getDerivedMethods();
RefMethod[] refMethods = derivedMethods.toArray(new RefMethod[derivedMethods.size()]);
@NotNull
@Override
- public String getName() {
+ public String getFamilyName() {
return myHasEquals
? InspectionsBundle.message("inspection.equals.hashcode.generate.hashcode.quickfix")
: InspectionsBundle.message("inspection.equals.hashcode.generate.equals.quickfix");
}
- @NotNull
- @Override
- public String getFamilyName() {
- return getName();
- }
-
@Override
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
final Editor editor = FileEditorManager.getInstance(project).getSelectedTextEditor();
myHandler = handler;
}
- @Nls
- @NotNull
- @Override
- public String getName() {
- return getFamilyName();
- }
-
@NotNull
@Override
public String getFamilyName() {
myUnboundParams = unboundParams;
}
- @Override
- @NotNull
- public String getName() {
- return "Change to ...";
- }
-
@Override
@NotNull
public String getFamilyName() {
- return getName();
+ return "Change to ...";
}
@Override
this.originalClasses = originalClasses;
}
- @Override
- @NotNull
- public String getName() {
- return QuickFixBundle.message("add.qualifier");
- }
-
@Override
@NotNull
public String getFamilyName() {
}
private static class LambdaParametersFix implements LocalQuickFix {
- @Nls
- @NotNull
- @Override
- public String getName() {
- return getFamilyName();
- }
-
@Nls
@NotNull
@Override
String text = "No IDEA annotations attached to the JDK " + finalJdk.getName() + (path == null ? "" : " (" + FileUtil.toSystemDependentName(path) + ")")
+", some issues will not be found";
holder.registerProblem(file, text, ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new LocalQuickFix() {
- @NotNull
- @Override
- public String getName() {
- return "Attach annotations";
- }
-
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return "Attach annotations";
}
@Override
@Override
@NotNull
public String getFamilyName() {
- return getName();
- }
-
- @Override
- @NotNull
- public String getName() {
return InspectionsBundle.message("inspection.redundant.array.creation.quickfix");
}
}
private static class RemoveSillyAssignmentFix implements LocalQuickFix {
- @Nls
- @NotNull
- @Override
- public String getName() {
- return InspectionsBundle.message("assignment.to.itself.quickfix.name");
- }
-
@Nls
@NotNull
@Override
public String getFamilyName() {
- return getName();
+ return InspectionsBundle.message("assignment.to.itself.quickfix.name");
}
@Override
@Override
@NotNull
- public String getName() {
+ public String getFamilyName() {
return InspectionsBundle.message("inspection.unused.return.value.make.void.quickfix");
}
return false;
}
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
-
private static void makeMethodHierarchyVoid(Project project, @NotNull PsiMethod psiMethod) {
replaceReturnStatements(psiMethod);
for (final PsiMethod oMethod : OverridingMethodsSearch.search(psiMethod)) {
@Override
@NotNull
- public final String getName() {
+ public final String getFamilyName() {
return InspectionsBundle.message("inspection.convert.to.local.quickfix");
}
}
}
- @Override
- @NotNull
- public String getFamilyName() {
- return getName();
- }
-
@Nullable
private static PsiElement getAnchorElement(PsiCodeBlock anchorBlock, @NotNull PsiElement firstElement) {
PsiElement element = firstElement;
@Nullable
public static String generateExternalJavadoc(@NotNull final PsiElement element) {
+ List<String> docURLs = getExternalJavaDocUrl(element);
+ return generateExternalJavadoc(element, docURLs);
+ }
+
+ @Nullable
+ public static String generateExternalJavadoc(@NotNull final PsiElement element, @Nullable List<String> docURLs) {
final JavaDocInfoGenerator javaDocInfoGenerator = JavaDocInfoGeneratorFactory.create(element.getProject(), element);
- return generateExternalJavadoc(element, javaDocInfoGenerator);
+ return generateExternalJavadoc(javaDocInfoGenerator, docURLs);
}
@Nullable
public static String generateExternalJavadoc(@NotNull final PsiElement element, @NotNull JavaDocInfoGenerator generator) {
final List<String> docURLs = getExternalJavaDocUrl(element);
+ return generateExternalJavadoc(generator, docURLs);
+ }
+
+ @Nullable
+ private static String generateExternalJavadoc(@NotNull JavaDocInfoGenerator generator, @Nullable List<String> docURLs) {
return JavaDocExternalFilter.filterInternalDocInfo(generator.generateDocInfo(docURLs));
}
PsiPackage pkg = JavaPsiFacade.getInstance(project).findPackage(referenceName);
if (pkg != null && pkg.getDirectories(scope).length > 0) return null;
- if (!cache.processFieldsWithName(referenceName, processor, scope, null) ||
- !cache.processClassesWithName(referenceName, processor, scope, null)) {
+ if (!cache.processFieldsWithName(referenceName, processor, scope, null)) {
markExpensive(project);
return null;
}
}
+
+ if (!cache.processClassesWithName(referenceName, processor, scope, null)) {
+ markExpensive(project);
+ return null;
+ }
+
return candidates;
}
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.util.*;
-import com.intellij.util.Consumer;
-import com.intellij.util.Function;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.Producer;
+import com.intellij.util.*;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.Contract;
public static boolean isFunctionalClass(PsiClass aClass) {
if (aClass != null) {
if (aClass instanceof PsiTypeParameter) return false;
- final List<HierarchicalMethodSignature> signatures = findFunctionCandidates(aClass);
- return signatures != null && signatures.size() == 1;
+ return getFunction(aClass) != null;
}
return false;
}
@Contract("null -> null")
@Nullable
- public static MethodSignature getFunction(PsiClass psiClass) {
- if (psiClass == null) return null;
- final List<HierarchicalMethodSignature> functions = findFunctionCandidates(psiClass);
- if (functions != null && functions.size() == 1) {
- return functions.get(0);
+ public static MethodSignature getFunction(final PsiClass psiClass) {
+ if (isPlainInterface(psiClass)) {
+ return CachedValuesManager.getCachedValue(psiClass, new CachedValueProvider<MethodSignature>() {
+ @Nullable
+ @Override
+ public Result<MethodSignature> compute() {
+ return Result.create(calcFunction(psiClass), PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
+ }
+ });
}
return null;
}
+ private static boolean isPlainInterface(PsiClass psiClass) {
+ return psiClass != null && psiClass.isInterface() && !psiClass.isAnnotationType();
+ }
+
+ @Nullable
+ private static MethodSignature calcFunction(@NotNull PsiClass psiClass) {
+ if (hasManyOwnAbstractMethods(psiClass) || hasManyInheritedAbstractMethods(psiClass)) return null;
+
+ final List<HierarchicalMethodSignature> functions = findFunctionCandidates(psiClass);
+ return functions != null && functions.size() == 1 ? functions.get(0) : null;
+ }
+
+ private static boolean hasManyOwnAbstractMethods(@NotNull PsiClass psiClass) {
+ int abstractCount = 0;
+ for (PsiMethod method : psiClass.getMethods()) {
+ if (isDefinitelyAbstractInterfaceMethod(method) && ++abstractCount > 1) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static boolean isDefinitelyAbstractInterfaceMethod(PsiMethod method) {
+ return method.hasModifierProperty(PsiModifier.ABSTRACT) && !isPublicObjectMethod(method.getName());
+ }
+
+ private static boolean isPublicObjectMethod(String methodName) {
+ return "equals".equals(methodName) || "hashCode".equals(methodName) || "toString".equals(methodName);
+ }
+
+ private static boolean hasManyInheritedAbstractMethods(@NotNull PsiClass psiClass) {
+ final Set<String> abstractNames = ContainerUtil.newHashSet();
+ final Set<String> defaultNames = ContainerUtil.newHashSet();
+ InheritanceUtil.processSupers(psiClass, true, new Processor<PsiClass>() {
+ @Override
+ public boolean process(PsiClass psiClass) {
+ for (PsiMethod method : psiClass.getMethods()) {
+ if (isDefinitelyAbstractInterfaceMethod(method)) {
+ abstractNames.add(method.getName());
+ }
+ else if (method.hasModifierProperty(PsiModifier.DEFAULT)) {
+ defaultNames.add(method.getName());
+ }
+ }
+ return true;
+ }
+ });
+ abstractNames.removeAll(defaultNames);
+ return abstractNames.size() > 1;
+ }
private static boolean overridesPublicObjectMethod(HierarchicalMethodSignature psiMethod) {
final List<HierarchicalMethodSignature> signatures = psiMethod.getSuperSignatures();
@Contract("null -> null")
@Nullable
- public static List<HierarchicalMethodSignature> findFunctionCandidates(final PsiClass psiClass) {
- if (psiClass != null && psiClass.isInterface() && !psiClass.isAnnotationType()) {
- return CachedValuesManager.getCachedValue(psiClass, new CachedValueProvider<List<HierarchicalMethodSignature>>() {
- @Nullable
- @Override
- public Result<List<HierarchicalMethodSignature>> compute() {
- return Result.create(calcFunctionCandidates(psiClass), PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT);
- }
- });
- }
- return null;
- }
+ public static List<HierarchicalMethodSignature> findFunctionCandidates(@Nullable final PsiClass psiClass) {
+ if (!isPlainInterface(psiClass)) return null;
- private static List<HierarchicalMethodSignature> calcFunctionCandidates(PsiClass psiClass) {
final List<HierarchicalMethodSignature> methods = new ArrayList<HierarchicalMethodSignature>();
final Map<MethodSignature, Set<PsiMethod>> overrideEquivalents = PsiSuperMethodUtil.collectOverrideEquivalents(psiClass);
final Collection<HierarchicalMethodSignature> visibleSignatures = psiClass.getVisibleSignatures();
String MODULE_INFO_CLASS = "module-info";
String MODULE_INFO_FILE = MODULE_INFO_CLASS + ".java";
String MODULE_INFO_CLS_FILE = MODULE_INFO_CLASS + ".class";
+ String JAVA_BASE = "java.base";
@NotNull PsiJavaModuleReferenceElement getNameElement();
@NotNull String getModuleName();
/*
- * Copyright 2000-2014 JetBrains s.r.o.
+ * Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
import com.intellij.util.containers.IntStack;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
+import gnu.trove.TIntArrayList;
import gnu.trove.TIntHashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
return visitor.getResult().booleanValue();
}
+ /**
+ * Returns true if the value the variable has at start is later referenced without going through stop instruction
+ *
+ * @param flow ControlFlow to analyze
+ * @param start the point at which variable value is created
+ * @param stop the stop-point
+ * @param variable the variable to examine
+ * @return true if the value the variable has at start is later referenced without going through stop instruction
+ */
+ public static boolean isValueUsedWithoutVisitingStop(final ControlFlow flow, final int start, final int stop, final PsiVariable variable) {
+ if(start == stop) return false;
+
+ class MyVisitor extends InstructionClientVisitor<Boolean> {
+ // true if value the variable has at given offset maybe referenced without going through stop instruction
+ final boolean[] maybeReferenced = new boolean[flow.getSize() + 1];
+
+ @Override
+ public void visitInstruction(Instruction instruction, int offset, int nextOffset) {
+ if (offset == stop) {
+ maybeReferenced[offset] = false;
+ return;
+ }
+ if(instruction instanceof WriteVariableInstruction && ((WriteVariableInstruction)instruction).variable == variable) {
+ maybeReferenced[offset] = false;
+ return;
+ }
+ if (maybeReferenced[offset]) return;
+ if (nextOffset > flow.getSize()) nextOffset = flow.getSize();
+
+ boolean nextState = maybeReferenced[nextOffset];
+ maybeReferenced[offset] =
+ nextState || (instruction instanceof ReadVariableInstruction && ((ReadVariableInstruction)instruction).variable == variable);
+ }
+
+ @Override
+ public Boolean getResult() {
+ return maybeReferenced[start];
+ }
+ }
+ MyVisitor visitor = new MyVisitor();
+ depthFirstSearch(flow, visitor, start, flow.getSize());
+ return visitor.getResult().booleanValue();
+ }
+
+ /**
+ * Checks whether variable can be referenced between start and stop points. Back-edges are also considered, so the actual place
+ * where it referenced might be outside of (start, stop) interval.
+ *
+ * @param flow ControlFlow to analyze
+ * @param start start point
+ * @param stop stop point
+ * @param variable variable to analyze
+ * @return true if variable can be referenced between start and stop points
+ */
+ public static boolean isVariableReferencedBetween(final ControlFlow flow,
+ final int start,
+ final int stop,
+ final PsiVariable variable) {
+ if(start == stop) return false;
+
+ // DFS visits instructions mainly in backward direction while here visiting in forward direction
+ // greatly reduces number of iterations. So first we just collect edges, then reverse their order.
+ // contains (from, to) pairs representing control flow arcs
+ final TIntArrayList list = new TIntArrayList();
+ depthFirstSearch(flow, new InstructionClientVisitor<Void>() {
+ @Override
+ public void visitInstruction(Instruction instruction, int offset, int nextOffset) {
+ list.add(offset);
+ list.add(nextOffset);
+ }
+
+ @Override
+ public Void getResult() {
+ return null;
+ }
+ }, start, flow.getSize());
+ BitSet violated = new BitSet();
+ List<Instruction> instructions = flow.getInstructions();
+ boolean changed = true;
+ while(changed) {
+ changed = false;
+ for(int i=list.size()-2; i>=0; i-=2) {
+ int from = list.get(i);
+ int to = list.get(i+1);
+ if(from == stop) continue;
+ if(violated.get(from)) {
+ if(!violated.get(to)) {
+ if(to == stop) return true;
+ violated.set(to);
+ changed = true;
+ }
+ continue;
+ }
+ Instruction instruction = instructions.get(from);
+ if((instruction instanceof ReadVariableInstruction && ((ReadVariableInstruction)instruction).variable == variable) ||
+ (instruction instanceof WriteVariableInstruction && ((WriteVariableInstruction)instruction).variable == variable)) {
+ violated.set(from);
+ violated.set(to);
+ if(to == stop) return true;
+ changed = true;
+ }
+ }
+ }
+ return false;
+ }
+
/**
* @return min offset after sourceOffset which is definitely reachable from all references
*/
module.service.no.ctor=The service implementation does not have a default constructor: {0}
module.service.hidden.ctor=The default constructor of the service implementation is not public: {0}
module.service.unused=Service interface provided but not exported or used
+module.package.not.exported=The module ''{0}'' does not export the package ''{1}'' to the module ''{2}''
+module.package.on.classpath=A named module cannot access packages of an unnamed one
+module.not.in.requirements=The module ''{0}'' does not have the module ''{1}'' in requirements
feature.generics=Generics
feature.annotations=Annotations
--- /dev/null
+class A {
+
+ void foo() {
+ new IterHelper<>().loopMap((k, val) -> {
+ //do something
+ });
+ }
+}
+
+final class IterHelper<K, V> {
+ public void loopMap(final MapIterCallback<K, V> callback) {
+ //do something
+ }
+ public static interface MapIterCallback<K, V> {
+ abstract void eval(K k, V v);
+ }
+}
\ No newline at end of file
public class Main {
public void testAssignment(List<String> data) {
- String found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()) ? "yes" : "no";
+ String found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty()) ? "yes" : "no";
}
}
\ No newline at end of file
public class Main {
public void testAssignment(List<String> data) {
- boolean found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
+ boolean found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
}
}
\ No newline at end of file
public class Main {
public void testAssignment(List<String> data) {
- boolean found = !data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
+ boolean found = !data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
}
}
\ No newline at end of file
--- /dev/null
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+ public void testAssignment(List<String> data) {
+ boolean found;
+ if (data.size() > 10) {
+ System.out.println("Big data");
+ }
+ found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
+ System.out.println(found);
+ }
+}
\ No newline at end of file
public class Main {
public void testAssignment(List<String> data) {
- boolean found = false;
+ boolean found;
if(Math.random() > 0.5) {
found = true;
} else {
- if (data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty())) {
- found = true;
- }
+ found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
}
+ System.out.println(found);
}
}
\ No newline at end of file
--- /dev/null
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+ public void testAssignment(List<String> data) {
+ boolean found = false;
+ if(Math.random() > 0.5) {
+ System.out.println("oops");
+ } else {
+ found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
+ }
+ System.out.println(found);
+ }
+}
\ No newline at end of file
--- /dev/null
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+ public void testAssignment(List<String> data) {
+ boolean found;
+ try {
+ found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
+ System.out.println(found);
+ }
+ catch(Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+// "Replace with anyMatch()" "true"
+
+import java.util.List;
+
+public class Main {
+ public void testAssignment(List<String> data) {
+ boolean found = false;
+ try {
+ found = data.stream().map(String::trim).anyMatch(trimmed -> !trimmed.isEmpty());
+ }
+ catch(Exception ex) {
+ ex.printStackTrace();
+ }
+ System.out.println(found);
+ }
+}
\ No newline at end of file
public class Main {
public void test(Integer[] arr) {
- List<Integer> result = Arrays.stream(arr).filter(x -> x > 5).collect(Collectors.toList());
+ List<Integer> result = Arrays.stream(arr).filter(x -> x > 5).collect(Collectors.toList());
}
}
\ No newline at end of file
class A {
public static void main(List<String> args) {
- ArrayList<String> uniqNames = args.stream().map(name -> name.substring(1)).collect(Collectors.toCollection(ArrayList::new));
+ ArrayList<String> uniqNames = args.stream().map(name -> name.substring(1)).collect(Collectors.toCollection(ArrayList::new));
uniqNames.forEach(System.out::println);
}
class Test {
public static <T> List<TokenFilter<T>> fromString(final T src, Function<T, List<String>> extractor) {
- final List<TokenFilter<T>> result = extractor.apply(src).stream().map((Function<String, TokenFilter<T>>) TokenFilter::new).collect(Collectors.toList());
+ final List<TokenFilter<T>> result = extractor.apply(src).stream().map((Function<String, TokenFilter<T>>) TokenFilter::new).collect(Collectors.toList());
return result;
}
}
void collectNames(List<Person> persons){
- List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
+ List<String> names = persons.stream().map(Person::getName).collect(Collectors.toList());
}
}