public static boolean filterEquals(ClassFilter[] filters1, ClassFilter[] filters2) { if (filters1.length != filters2.length) { return false; } final Set<ClassFilter> f1 = new HashSet<ClassFilter>(Math.max((int) (filters1.length / .75f) + 1, 16)); final Set<ClassFilter> f2 = new HashSet<ClassFilter>(Math.max((int) (filters2.length / .75f) + 1, 16)); Collections.addAll(f1, filters1); Collections.addAll(f2, filters2); return f2.equals(f1); }
@Override public void visitReferenceExpression(final PsiReferenceExpression reference) { if (myLineRange.intersects(reference.getTextRange())) { final PsiElement psiElement = reference.resolve(); if (psiElement instanceof PsiVariable) { final PsiVariable var = (PsiVariable) psiElement; if (var instanceof PsiField) { if (myCollectExpressions && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars( reference, myVisibleLocals)) { /* if (var instanceof PsiEnumConstant && reference.getQualifier() == null) { final PsiClass enumClass = ((PsiEnumConstant)var).getContainingClass(); if (enumClass != null) { final PsiExpression expression = JavaPsiFacade.getInstance(var.getProject()).getParserFacade().createExpressionFromText(enumClass.getName() + "." + var.getName(), var); final PsiReference ref = expression.getReference(); if (ref != null) { ref.bindToElement(var); myExpressions.add(new TextWithImportsImpl(expression)); } } } else { myExpressions.add(new TextWithImportsImpl(reference)); } */ final PsiModifierList modifierList = var.getModifierList(); boolean isConstant = (var instanceof PsiEnumConstant) || (modifierList != null && modifierList.hasModifierProperty(PsiModifier.STATIC) && modifierList.hasModifierProperty(PsiModifier.FINAL)); if (!isConstant) { myExpressions.add(new TextWithImportsImpl(reference)); } } } else { if (myVisibleLocals.contains(var.getName())) { myVars.add(var.getName()); } else { // fix for variables used in inner classes if (!Comparing.equal( PsiTreeUtil.getParentOfType(reference, PsiClass.class), PsiTreeUtil.getParentOfType(var, PsiClass.class))) { myExpressions.add(new TextWithImportsImpl(reference)); } } } } } super.visitReferenceExpression(reference); }
public static boolean filterEquals(ClassFilter[] filters1, ClassFilter[] filters2) { if (filters1.length != filters2.length) { return false; } final Set<ClassFilter> f1 = new HashSet<ClassFilter>(Math.max((int) (filters1.length / .75f) + 1, 16)); final Set<ClassFilter> f2 = new HashSet<ClassFilter>(Math.max((int) (filters2.length / .75f) + 1, 16)); for (ClassFilter filter : filters1) { f1.add(filter); } for (ClassFilter aFilters2 : filters2) { f2.add(aFilters2); } return f2.equals(f1); }
@Override public void visitArrayAccessExpression(final PsiArrayAccessExpression expression) { if (myCollectExpressions && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars(expression, myVisibleLocals)) { myExpressions.add(new TextWithImportsImpl(expression)); } super.visitArrayAccessExpression(expression); }
private static Set<TextWithImports> computeExtraVars( Pair<Set<String>, Set<TextWithImports>> usedVars, SourcePosition sourcePosition, EvaluationContextImpl evalContext) { Set<String> alreadyCollected = new HashSet<String>(usedVars.first); for (TextWithImports text : usedVars.second) { alreadyCollected.add(text.getText()); } Set<TextWithImports> extra = new HashSet<TextWithImports>(); for (FrameExtraVariablesProvider provider : FrameExtraVariablesProvider.EP_NAME.getExtensions()) { if (provider.isAvailable(sourcePosition, evalContext)) { extra.addAll(provider.collectVariables(sourcePosition, evalContext, alreadyCollected)); } } return extra; }
@SuppressWarnings({"HardCodedStringLiteral"}) public static boolean isCharOrIntegerArray(Value value) { if (value == null) return false; if (myCharOrIntegers == null) { myCharOrIntegers = new HashSet<String>(); myCharOrIntegers.add("C"); myCharOrIntegers.add("B"); myCharOrIntegers.add("S"); myCharOrIntegers.add("I"); myCharOrIntegers.add("J"); } String signature = value.type().signature(); int i; for (i = 0; signature.charAt(i) == '['; i++) ; if (i == 0) return false; signature = signature.substring(i, signature.length()); return myCharOrIntegers.contains(signature); }
@Override public void visitMethodCallExpression(final PsiMethodCallExpression expression) { if (myCollectExpressions) { final PsiMethod psiMethod = expression.resolveMethod(); if (psiMethod != null && !DebuggerUtils.hasSideEffectsOrReferencesMissingVars(expression, myVisibleLocals)) { myExpressions.add(new TextWithImportsImpl(expression)); } } super.visitMethodCallExpression(expression); }
public List<ReferenceType> nestedTypes(ReferenceType refType) { List<ReferenceType> nestedTypes = myNestedClassesCache.get(refType); if (nestedTypes == null) { List<ReferenceType> list = Collections.emptyList(); try { list = refType.nestedTypes(); } catch (Throwable e) { // sometimes some strange errors are thrown from JDI. Do not crash debugger because of this. // Example: // java.lang.StringIndexOutOfBoundsException: String index out of range: 487700285 // at java.lang.String.checkBounds(String.java:375) // at java.lang.String.<init>(String.java:415) // at com.sun.tools.jdi.PacketStream.readString(PacketStream.java:392) // at // com.sun.tools.jdi.JDWP$VirtualMachine$AllClassesWithGeneric$ClassInfo.<init>(JDWP.java:1644) LOG.info(e); } if (!list.isEmpty()) { final Set<ReferenceType> candidates = new HashSet<>(); final ClassLoaderReference outerLoader = refType.classLoader(); for (ReferenceType nested : list) { try { if (outerLoader == null ? nested.classLoader() == null : outerLoader.equals(nested.classLoader())) { candidates.add(nested); } } catch (ObjectCollectedException ignored) { } } if (!candidates.isEmpty()) { // keep only direct nested types final Set<ReferenceType> nested2 = new HashSet<>(); for (final ReferenceType candidate : candidates) { nested2.addAll(nestedTypes(candidate)); } candidates.removeAll(nested2); } nestedTypes = candidates.isEmpty() ? Collections.emptyList() : new ArrayList<>(candidates); } else { nestedTypes = Collections.emptyList(); } myNestedClassesCache.put(refType, nestedTypes); } return nestedTypes; }
private void processVariable(final PsiVariable variable) { if (myLineRange.intersects(variable.getTextRange()) && myVisibleLocals.contains(variable.getName())) { myVars.add(variable.getName()); } }
// copied from FrameVariablesTree private void buildVariables( DebuggerContextImpl debuggerContext, final EvaluationContextImpl evaluationContext, @NotNull DebugProcessImpl debugProcess, XValueChildrenList children, ObjectReference thisObjectReference, Location location) throws EvaluateException { final Set<String> visibleLocals = new HashSet<String>(); if (NodeRendererSettings.getInstance().getClassRenderer().SHOW_VAL_FIELDS_AS_LOCAL_VARIABLES) { if (thisObjectReference != null && debugProcess.getVirtualMachineProxy().canGetSyntheticAttribute()) { final ReferenceType thisRefType = thisObjectReference.referenceType(); if (thisRefType instanceof ClassType && location != null && thisRefType.equals(location.declaringType()) && thisRefType.name().contains("$")) { // makes sense for nested classes only for (Field field : thisRefType.fields()) { if (DebuggerUtils.isSynthetic(field) && StringUtil.startsWith( field.name(), FieldDescriptorImpl.OUTER_LOCAL_VAR_FIELD_PREFIX)) { final FieldDescriptorImpl fieldDescriptor = myNodeManager.getFieldDescriptor(myDescriptor, thisObjectReference, field); children.add(JavaValue.create(fieldDescriptor, evaluationContext, myNodeManager)); visibleLocals.add(fieldDescriptor.calcValueName()); } } } } } boolean myAutoWatchMode = DebuggerSettings.getInstance().AUTO_VARIABLES_MODE; if (evaluationContext == null) { return; } final SourcePosition sourcePosition = debuggerContext.getSourcePosition(); if (sourcePosition == null) { return; } try { if (!XDebuggerSettingsManager.getInstance().getDataViewSettings().isAutoExpressions() && !myAutoWatchMode) { // optimization superBuildVariables(evaluationContext, children); } else { final Map<String, LocalVariableProxyImpl> visibleVariables = getVisibleVariables(getStackFrameProxy()); final Pair<Set<String>, Set<TextWithImports>> usedVars = ApplicationManager.getApplication() .runReadAction( new Computable<Pair<Set<String>, Set<TextWithImports>>>() { @Override public Pair<Set<String>, Set<TextWithImports>> compute() { return findReferencedVars( ContainerUtil.union(visibleVariables.keySet(), visibleLocals), sourcePosition); } }); // add locals if (myAutoWatchMode) { for (String var : usedVars.first) { LocalVariableProxyImpl local = visibleVariables.get(var); if (local != null) { children.add( JavaValue.create( myNodeManager.getLocalVariableDescriptor(null, local), evaluationContext, myNodeManager)); } } } else { superBuildVariables(evaluationContext, children); } final EvaluationContextImpl evalContextCopy = evaluationContext.createEvaluationContext(evaluationContext.getThisObject()); evalContextCopy.setAutoLoadClasses(false); final Set<TextWithImports> extraVars = computeExtraVars(usedVars, sourcePosition, evaluationContext); // add extra vars addToChildrenFrom(extraVars, children, evaluationContext); // add expressions addToChildrenFrom(usedVars.second, children, evalContextCopy); } } catch (EvaluateException e) { if (e.getCause() instanceof AbsentInformationException) { children.add( new DummyMessageValueNode( MessageDescriptor.LOCAL_VARIABLES_INFO_UNAVAILABLE.getLabel(), XDebuggerUIConstants.INFORMATION_MESSAGE_ICON)); // trying to collect values from variable slots try { for (Map.Entry<DecompiledLocalVariable, Value> entry : LocalVariablesUtil.fetchValues(getStackFrameProxy(), debugProcess).entrySet()) { children.add( JavaValue.create( myNodeManager.getArgumentValueDescriptor( null, entry.getKey(), entry.getValue()), evaluationContext, myNodeManager)); } } catch (Exception ex) { LOG.info(ex); } } else { throw e; } } }