@Nullable public static String getReferencePrefix(@NotNull PsiElement insertedElement, int offsetInFile) { final PsiReference ref = insertedElement.getContainingFile().findReferenceAt(offsetInFile); if (ref != null) { final PsiElement element = ref.getElement(); final int endIndex = offsetInFile - element.getTextRange().getStartOffset(); final int beginIndex = ref.getRangeInElement().getStartOffset(); if (beginIndex > endIndex) { LOG.error( "Inconsistent reference (found at offset not included in its range): ref=" + ref + " element=" + element + " text=" + element.getText()); } if (beginIndex < 0) { LOG.error( "Inconsistent reference (begin < 0): ref=" + ref + " element=" + element + "; begin=" + beginIndex + " text=" + element.getText()); } LOG.assertTrue(endIndex >= 0); return element.getText().substring(beginIndex, endIndex); } return null; }
public static FileReferenceSet createSet( PsiElement element, final boolean soft, boolean endingSlashNotAllowed, final boolean urlEncoded) { String text; int offset; final ElementManipulator<PsiElement> manipulator = ElementManipulators.getManipulator(element); assert manipulator != null; final TextRange range = manipulator.getRangeInElement(element); offset = range.getStartOffset(); text = range.substring(element.getText()); for (final FileReferenceHelper helper : FileReferenceHelperRegistrar.getHelpers()) { text = helper.trimUrl(text); } return new FileReferenceSet(text, element, offset, null, true, endingSlashNotAllowed) { @Override protected boolean isUrlEncoded() { return urlEncoded; } @Override protected boolean isSoft() { return soft; } }; }
@Override protected void previewRefactoring(@NotNull final UsageInfo[] usages) { MigrationPanel panel = new MigrationPanel(myRoot, myLabeler, myProject, isPreviewUsages()); String name; if (myRoot.length == 1) { String fromType = assertNotNull(TypeMigrationLabeler.getElementType(myRoot[0])).getPresentableText(); String toType = myRootTypes.fun(myRoot[0]).getPresentableText(); String text; text = getPresentation(myRoot[0]); name = "Migrate Type of " + text + " from \'" + fromType + "\' to \'" + toType + "\'"; } else { final int rootsInPresentationCount = myRoot.length > MAX_ROOT_IN_PREVIEW_PRESENTATION ? MAX_ROOT_IN_PREVIEW_PRESENTATION : myRoot.length; String[] rootsPresentation = new String[rootsInPresentationCount]; for (int i = 0; i < rootsInPresentationCount; i++) { final PsiElement root = myRoot[i]; rootsPresentation[i] = root instanceof PsiNamedElement ? ((PsiNamedElement) root).getName() : root.getText(); } rootsPresentation = StringUtil.surround(rootsPresentation, "\'", "\'"); name = "Migrate Type of " + StringUtil.join(rootsPresentation, ", "); if (myRoot.length > MAX_ROOT_IN_PREVIEW_PRESENTATION) { name += "..."; } } Content content = UsageViewManager.getInstance(myProject).addContent(name, false, panel, true, true); panel.setContent(content); ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.FIND).activate(null); }
public static boolean isStringPsiLiteral(PsiElement element) { if (element instanceof PsiLiteralExpression) { final String text = element.getText(); return StringUtil.isQuotedString(text); } return false; }
@NotNull public static String getElementTextWithContext(@NotNull JetElement element) { if (element instanceof JetFile) { return element.getContainingFile().getText(); } // Find parent for element among file children PsiElement inFileParent = PsiTreeUtil.findFirstParent( element, new Condition<PsiElement>() { @Override public boolean value(PsiElement parentCandidate) { return parentCandidate != null && parentCandidate.getParent() instanceof JetFile; } }); assert inFileParent != null : "For non-file element we should always be able to find parent in file children"; int startContextOffset = inFileParent.getTextRange().getStartOffset(); int elementContextOffset = element.getTextRange().getStartOffset(); int inFileParentOffset = elementContextOffset - startContextOffset; return new StringBuilder(inFileParent.getText()) .insert(inFileParentOffset, "<caret>") .toString(); }
protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) { final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); checkExistingMethods(conflicts, true); checkExistingMethods(conflicts, false); final Collection<PsiClass> classes = ClassInheritorsSearch.search(myClass).findAll(); for (FieldDescriptor fieldDescriptor : myFieldDescriptors) { final Set<PsiMethod> setters = new HashSet<PsiMethod>(); final Set<PsiMethod> getters = new HashSet<PsiMethod>(); for (PsiClass aClass : classes) { final PsiMethod getterOverrider = myDescriptor.isToEncapsulateGet() ? aClass.findMethodBySignature(fieldDescriptor.getGetterPrototype(), false) : null; if (getterOverrider != null) { getters.add(getterOverrider); } final PsiMethod setterOverrider = myDescriptor.isToEncapsulateSet() ? aClass.findMethodBySignature(fieldDescriptor.getSetterPrototype(), false) : null; if (setterOverrider != null) { setters.add(setterOverrider); } } if (!getters.isEmpty() || !setters.isEmpty()) { final PsiField field = fieldDescriptor.getField(); for (PsiReference reference : ReferencesSearch.search(field)) { final PsiElement place = reference.getElement(); if (place instanceof PsiReferenceExpression) { final PsiExpression qualifierExpression = ((PsiReferenceExpression) place).getQualifierExpression(); final PsiClass ancestor; if (qualifierExpression == null) { ancestor = PsiTreeUtil.getParentOfType(place, PsiClass.class, false); } else { ancestor = PsiUtil.resolveClassInType(qualifierExpression.getType()); } final boolean isGetter = !PsiUtil.isAccessedForWriting((PsiExpression) place); for (PsiMethod overridden : isGetter ? getters : setters) { if (InheritanceUtil.isInheritorOrSelf(myClass, ancestor, true)) { conflicts.putValue( overridden, "There is already a " + RefactoringUIUtil.getDescription(overridden, true) + " which would hide generated " + (isGetter ? "getter" : "setter") + " for " + place.getText()); break; } } } } } } return showConflicts(conflicts, refUsages.get()); }
public static String getPrevSiblingAsTextUntil( PsiElement psiElement, ElementPattern pattern, boolean includeMatching) { String prevText = ""; for (PsiElement child = psiElement.getPrevSibling(); child != null; child = child.getPrevSibling()) { if (pattern.accepts(child)) { if (includeMatching) { return child.getText() + prevText; } return prevText; } else { prevText = child.getText() + prevText; } } return prevText; }
public PyType getType(@NotNull TypeEvalContext context, @NotNull TypeEvalContext.Key key) { if (!TypeEvalStack.mayEvaluate(this)) { return null; } try { final boolean qualified = isQualified(); if (!qualified) { String name = getReferencedName(); if (PyNames.NONE.equals(name)) { return PyNoneType.INSTANCE; } } PyType type = getTypeFromProviders(context); if (type != null) { return type; } if (qualified) { PyType maybe_type = PyUtil.getSpecialAttributeType(this, context); if (maybe_type != null) return maybe_type; Ref<PyType> typeOfProperty = getTypeOfProperty(context); if (typeOfProperty != null) { return typeOfProperty.get(); } } final PsiPolyVariantReference reference = getReference(PyResolveContext.noImplicits().withTypeEvalContext(context)); final List<PsiElement> targets = PyUtil.multiResolveTopPriority(reference); if (targets.isEmpty()) { return getQualifiedReferenceTypeByControlFlow(context); } final List<PyType> members = new ArrayList<PyType>(); for (PsiElement target : targets) { if (target == this || target == null) { continue; } if (!target.isValid()) { LOG.error( "Reference " + this + " resolved to invalid element " + target + " (text=" + target.getText() + ")"); continue; } members.add(getTypeFromTarget(target, context, this)); } return PyUnionType.union(members); } finally { TypeEvalStack.evaluated(this); } }
private static void processParameterUsage( PsiReferenceExpression ref, String oldName, String newName) throws IncorrectOperationException { PsiElement last = ref.getReferenceNameElement(); if (last instanceof PsiIdentifier && last.getText().equals(oldName)) { PsiElementFactory factory = JavaPsiFacade.getInstance(ref.getProject()).getElementFactory(); PsiIdentifier newNameIdentifier = factory.createIdentifier(newName); last.replace(newNameIdentifier); } }
/** * Try to visit possible class name for PsiElements with text like "Foo\|Bar", "Foo|\Bar", * "\Foo|\Bar" Cursor must have position in PsiElement * * @param psiElement the element context, cursor should be in it * @param cursorOffset current cursor editor eg from completion context * @param visitor callback on matching class */ public static void visitNamespaceClassForCompletion( PsiElement psiElement, int cursorOffset, ClassForCompletionVisitor visitor) { int cursorOffsetClean = cursorOffset - psiElement.getTextOffset(); if (cursorOffsetClean < 1) { return; } String content = psiElement.getText(); int length = content.length(); if (!(length >= cursorOffsetClean)) { return; } String beforeCursor = content.substring(0, cursorOffsetClean); boolean isValid; // espend\|Container, espend\Cont|ainer <- fallback to last full namespace // espend|\Container <- only on known namespace "espend" String namespace = beforeCursor; // if no backslash or its equal in first position, fallback on namespace completion int lastSlash = beforeCursor.lastIndexOf("\\"); if (lastSlash <= 0) { isValid = PhpIndexUtil.hasNamespace(psiElement.getProject(), beforeCursor); } else { isValid = true; namespace = beforeCursor.substring(0, lastSlash); } if (!isValid) { return; } // format namespaces and add prefix for fluent completion String prefix = ""; if (namespace.startsWith("\\")) { prefix = "\\"; } else { namespace = "\\" + namespace; } // search classes in current namespace and child namespaces for (PhpClass phpClass : PhpIndexUtil.getPhpClassInsideNamespace(psiElement.getProject(), namespace)) { String presentableFQN = phpClass.getPresentableFQN(); if (presentableFQN != null && fr.adrienbrault.idea.symfony2plugin.util.StringUtils.startWithEqualClassname( presentableFQN, beforeCursor)) { visitor.visit(phpClass, presentableFQN, prefix); } } }
public FileReferenceSet(final @NotNull PsiElement element) { myElement = element; TextRange range = ElementManipulators.getValueTextRange(element); myStartInElement = range.getStartOffset(); myPathStringNonTrimmed = range.substring(element.getText()); myPathString = myPathStringNonTrimmed.trim(); myEndingSlashNotAllowed = true; myCaseSensitive = false; reparse(); }
private static void processMethodUsage( PsiElement ref, JavaChangeInfo changeInfo, boolean toChangeArguments, boolean toCatchExceptions, PsiMethod callee, PsiSubstitutor subsitutor, final UsageInfo[] usages) throws IncorrectOperationException { if (changeInfo.isNameChanged()) { if (ref instanceof PsiJavaCodeReferenceElement) { PsiElement last = ((PsiJavaCodeReferenceElement) ref).getReferenceNameElement(); if (last instanceof PsiIdentifier && last.getText().equals(changeInfo.getOldName())) { last.replace(changeInfo.getNewNameIdentifier()); } } } final PsiMethod caller = RefactoringUtil.getEnclosingMethod(ref); if (toChangeArguments) { final PsiExpressionList list = RefactoringUtil.getArgumentListByMethodReference(ref); LOG.assertTrue(list != null); boolean toInsertDefaultValue = needDefaultValue(changeInfo, caller); if (toInsertDefaultValue && ref instanceof PsiReferenceExpression) { final PsiExpression qualifierExpression = ((PsiReferenceExpression) ref).getQualifierExpression(); if (qualifierExpression instanceof PsiSuperExpression && callerSignatureIsAboutToChangeToo(caller, usages)) { toInsertDefaultValue = false; } } fixActualArgumentsList(list, changeInfo, toInsertDefaultValue, subsitutor); } if (toCatchExceptions) { if (!(ref instanceof PsiReferenceExpression && ((PsiReferenceExpression) ref).getQualifierExpression() instanceof PsiSuperExpression)) { if (needToCatchExceptions(changeInfo, caller)) { PsiClassType[] newExceptions = callee != null ? getCalleeChangedExceptionInfo(callee) : getPrimaryChangedExceptionInfo(changeInfo); fixExceptions(ref, newExceptions); } } } }
protected static String findPrefixDefault( final PsiElement insertedElement, final int offset, @NotNull final ElementPattern trimStart) { String substr = insertedElement .getText() .substring(0, offset - insertedElement.getTextRange().getStartOffset()); if (substr.length() == 0 || Character.isWhitespace(substr.charAt(substr.length() - 1))) return ""; substr = substr.trim(); int i = 0; while (substr.length() > i && trimStart.accepts(substr.charAt(i))) i++; return substr.substring(i).trim(); }
public static String getPresentation(PsiElement element) { String text; if (element instanceof PsiField) { text = "field \'" + ((PsiField) element).getName() + "\'"; } else if (element instanceof PsiParameter) { text = "parameter \'" + ((PsiParameter) element).getName() + "\'"; } else if (element instanceof PsiLocalVariable) { text = "variable \'" + ((PsiLocalVariable) element).getName() + "\'"; } else if (element instanceof PsiMethod) { text = "method \'" + ((PsiMethod) element).getName() + "\' return"; } else { text = element.getText(); } return text; }
@Override @Nullable public String getReferenceName() { PsiElement nameElement = getReferenceNameElement(); if (nameElement != null) { IElementType nodeType = nameElement.getNode().getElementType(); if (TokenSets.STRING_LITERAL_SET.contains(nodeType)) { final Object value = GrLiteralImpl.getLiteralValue(nameElement); if (value instanceof String) { return (String) value; } } return nameElement.getText(); } return null; }
@Nullable private static PsiMethod getOverridingConstructorOfSuperCall(final PsiElement element) { if (element instanceof PsiReferenceExpression && "super".equals(element.getText())) { PsiElement parent = element.getParent(); if (parent instanceof PsiMethodCallExpression) { parent = parent.getParent(); if (parent instanceof PsiExpressionStatement) { parent = parent.getParent(); if (parent instanceof PsiCodeBlock) { parent = parent.getParent(); if (parent instanceof PsiMethod && ((PsiMethod) parent).isConstructor()) { return (PsiMethod) parent; } } } } } return null; }
private JavaResolveResult doAdvancedResolve() { final PsiElement psiElement = getElement(); if (!psiElement.isValid()) return JavaResolveResult.EMPTY; final String elementText = psiElement.getText(); final PsiElement context = getContext(); if (context instanceof PsiClass) { if (isStaticClassReference(elementText, false)) { final PsiClass psiClass = ((PsiClass) context).findInnerClassByName(getCanonicalText(), false); if (psiClass != null) return new ClassCandidateInfo(psiClass, PsiSubstitutor.EMPTY, false, psiElement); PsiElement member = doResolveMember((PsiClass) context, myText); return member == null ? JavaResolveResult.EMPTY : new CandidateInfo(member, PsiSubstitutor.EMPTY, false, false, psiElement); } else if (!myInStaticImport && myJavaClassReferenceSet.isAllowDollarInNames()) { return JavaResolveResult.EMPTY; } } final int endOffset = getRangeInElement().getEndOffset(); LOG.assertTrue(endOffset <= elementText.length(), elementText); final int startOffset = myJavaClassReferenceSet.getReference(0).getRangeInElement().getStartOffset(); final String qName = elementText.substring(startOffset, endOffset); if (!qName.contains(".")) { final String defaultPackage = JavaClassReferenceProvider.DEFAULT_PACKAGE.getValue(getOptions()); if (StringUtil.isNotEmpty(defaultPackage)) { final JavaResolveResult resolveResult = advancedResolveInner(psiElement, defaultPackage + "." + qName); if (resolveResult != JavaResolveResult.EMPTY) { return resolveResult; } } } return advancedResolveInner(psiElement, qName); }
public void testGroupByValuesCorrectLeaves() throws Exception { SliceTreeStructure treeStructure = configureTree("DuplicateLeaves"); SliceRootNode root = (SliceRootNode) treeStructure.getRootElement(); Map<SliceNode, Collection<PsiElement>> map = SliceLeafAnalyzer.createMap(); Collection<PsiElement> leaves = SliceLeafAnalyzer.calcLeafExpressions(root, treeStructure, map); assertNotNull(leaves); assertEquals(1, leaves.size()); PsiElement leaf = leaves.iterator().next(); assertTrue(leaf instanceof PsiLiteralExpression); assertEquals("\"oo\"", leaf.getText()); SliceRootNode newRoot = SliceLeafAnalyzer.createTreeGroupedByValues(leaves, root, map); Collection<? extends AbstractTreeNode> children = newRoot.getChildren(); assertEquals(1, children.size()); SliceNode child = (SliceNode) children.iterator().next(); assertTrue(child instanceof SliceLeafValueRootNode); children = child.getChildren(); assertEquals(1, children.size()); child = (SliceNode) children.iterator().next(); assertTrue(child.getValue().getElement() instanceof PsiField); children = child.getChildren(); assertEquals(1, children.size()); child = (SliceNode) children.iterator().next(); assertTrue(child.getValue().getElement() instanceof PsiReferenceExpression); children = child.getChildren(); assertEquals(1, children.size()); child = (SliceNode) children.iterator().next(); assertTrue(child.getValue().getElement() instanceof PsiReferenceExpression); children = child.getChildren(); assertEquals(1, children.size()); child = (SliceNode) children.iterator().next(); assertTrue(child.getValue().getElement() instanceof PsiLiteralExpression); assertEquals(child.getValue().getElement(), leaf); }
/** "DateTime", DateTime::class */ @Nullable public static PhpClass resolvePhpClassOnPsiElement(@NotNull PsiElement psiElement) { String dataClass = null; if (psiElement instanceof ClassConstantReference) { PsiElement lastChild = psiElement.getLastChild(); // @TODO: FOO::class find PhpElementTyp: toString provides "class" if ("class".equals(lastChild.getText())) { PhpExpression classReference = ((ClassConstantReference) psiElement).getClassReference(); if (classReference instanceof PhpReference) { dataClass = ((PhpReference) classReference).getFQN(); } } } else { dataClass = getStringValue(psiElement); } if (dataClass == null) { return null; } return getClassInterface(psiElement.getProject(), dataClass); }
private HashMap<PsiMethod, HashSet<PsiMethod>> buildConstructorsToSubConstructorsMap( final PsiMethod[] constructors) { final HashMap<PsiMethod, HashSet<PsiMethod>> constructorsToSubConstructors = new HashMap<PsiMethod, HashSet<PsiMethod>>(); for (PsiMethod constructor : constructors) { final HashSet<PsiMethod> referencingSubConstructors = new HashSet<PsiMethod>(); constructorsToSubConstructors.put(constructor, referencingSubConstructors); if (constructor != null) { // find references for (PsiReference reference : ReferencesSearch.search(constructor, new LocalSearchScope(mySourceClass), false)) { final PsiElement element = reference.getElement(); if (element != null && "super".equals(element.getText())) { PsiMethod parentMethod = PsiTreeUtil.getParentOfType(element, PsiMethod.class); if (parentMethod != null && parentMethod.isConstructor()) { referencingSubConstructors.add(parentMethod); } } } } // check default constructor if (constructor == null || constructor.getParameterList().getParametersCount() == 0) { RefactoringUtil.visitImplicitSuperConstructorUsages( mySourceClass, new RefactoringUtil.ImplicitConstructorUsageVisitor() { public void visitConstructor(PsiMethod constructor, PsiMethod baseConstructor) { referencingSubConstructors.add(constructor); } public void visitClassWithoutConstructors(PsiClass aClass) {} }, myTargetSuperClass); } } return constructorsToSubConstructors; }
private static boolean hasExactImportStaticConflict( String qualifierClass, String memberName, PsiElement context) { final PsiFile file = context.getContainingFile(); if (!(file instanceof PsiJavaFile)) { return false; } final PsiJavaFile javaFile = (PsiJavaFile) file; final PsiImportList importList = javaFile.getImportList(); if (importList == null) { return false; } final PsiImportStaticStatement[] importStaticStatements = importList.getImportStaticStatements(); for (PsiImportStaticStatement importStaticStatement : importStaticStatements) { if (importStaticStatement.isOnDemand()) { continue; } final String name = importStaticStatement.getReferenceName(); if (!memberName.equals(name)) { continue; } final PsiJavaCodeReferenceElement importReference = importStaticStatement.getImportReference(); if (importReference == null) { continue; } final PsiElement qualifier = importReference.getQualifier(); if (qualifier == null) { continue; } final String qualifierText = qualifier.getText(); if (!qualifierClass.equals(qualifierText)) { return true; } } return false; }
public final RunnerResult analyzeMethod( @NotNull PsiElement psiBlock, InstructionVisitor visitor, boolean ignoreAssertions, @NotNull Collection<DfaMemoryState> initialStates) { try { prepareAnalysis(psiBlock, initialStates); final ControlFlow flow = createControlFlowAnalyzer().buildControlFlow(psiBlock, ignoreAssertions); if (flow == null) return RunnerResult.NOT_APPLICABLE; int endOffset = flow.getInstructionCount(); myInstructions = flow.getInstructions(); myFields = flow.getFields(); myNestedClosures.clear(); if (LOG.isDebugEnabled()) { LOG.debug("Analyzing code block: " + psiBlock.getText()); for (int i = 0; i < myInstructions.length; i++) { Instruction instruction = myInstructions[i]; LOG.debug(i + ": " + instruction.toString()); } } Integer tooExpensiveHash = psiBlock.getUserData(TOO_EXPENSIVE_HASH); if (tooExpensiveHash != null && tooExpensiveHash == psiBlock.getText().hashCode()) { LOG.debug("Too complex because hasn't changed since being too complex already"); return RunnerResult.TOO_COMPLEX; } final ArrayList<DfaInstructionState> queue = new ArrayList<DfaInstructionState>(); for (final DfaMemoryState initialState : initialStates) { queue.add(new DfaInstructionState(myInstructions[0], initialState)); } long timeLimit = ourTimeLimit; final boolean unitTestMode = ApplicationManager.getApplication().isUnitTestMode(); WorkingTimeMeasurer measurer = new WorkingTimeMeasurer(timeLimit); int count = 0; while (!queue.isEmpty()) { if (count % 50 == 0 && !unitTestMode && measurer.isTimeOver()) { LOG.debug("Too complex because the analysis took too long"); psiBlock.putUserData(TOO_EXPENSIVE_HASH, psiBlock.getText().hashCode()); return RunnerResult.TOO_COMPLEX; } ProgressManager.checkCanceled(); DfaInstructionState instructionState = queue.remove(0); if (LOG.isDebugEnabled()) { LOG.debug(instructionState.toString()); } // System.out.println(instructionState.toString()); Instruction instruction = instructionState.getInstruction(); long distance = instructionState.getDistanceFromStart(); if (instruction instanceof BranchingInstruction) { if (!instruction.setMemoryStateProcessed( instructionState.getMemoryState().createCopy())) { LOG.debug("Too complex because too many different possible states"); return RunnerResult.TOO_COMPLEX; // Too complex :( } } DfaInstructionState[] after = acceptInstruction(visitor, instructionState); for (DfaInstructionState state : after) { Instruction nextInstruction = state.getInstruction(); if ((!(nextInstruction instanceof BranchingInstruction) || !nextInstruction.isMemoryStateProcessed(state.getMemoryState())) && instruction.getIndex() < endOffset) { state.setDistanceFromStart(distance + 1); queue.add(state); } } count++; } psiBlock.putUserData(TOO_EXPENSIVE_HASH, null); LOG.debug("Analysis ok"); return RunnerResult.OK; } catch (ArrayIndexOutOfBoundsException e) { LOG.error(psiBlock.getText(), e); // TODO fix in better times return RunnerResult.ABORTED; } catch (EmptyStackException e) { if (LOG.isDebugEnabled()) { LOG.error(e); // TODO fix in better times } return RunnerResult.ABORTED; } }
public static boolean areParenthesesNecessary( @NotNull JetExpression innerExpression, @NotNull JetExpression currentInner, @NotNull JetExpression parentExpression) { if (parentExpression instanceof JetParenthesizedExpression || innerExpression instanceof JetParenthesizedExpression) { return false; } if (parentExpression instanceof JetWhenExpression || innerExpression instanceof JetWhenExpression) { return false; } if (innerExpression instanceof JetIfExpression) { PsiElement current = parentExpression; while (!(current instanceof JetBlockExpression || current instanceof JetDeclaration || current instanceof JetStatementExpression)) { if (current.getTextRange().getEndOffset() != currentInner.getTextRange().getEndOffset()) { return current.getText().charAt(current.getTextLength() - 1) != ')'; // if current expression is "guarded" by parenthesis, no extra parenthesis is // necessary } current = current.getParent(); } } IElementType innerOperation = getOperation(innerExpression); IElementType parentOperation = getOperation(parentExpression); // 'return (@label{...})' case if (parentExpression instanceof JetReturnExpression && innerOperation == JetTokens.LABEL_IDENTIFIER) { return true; } // '(x: Int) < y' case if (innerExpression instanceof JetBinaryExpressionWithTypeRHS && parentOperation == JetTokens.LT) { return true; } int innerPriority = getPriority(innerExpression); int parentPriority = getPriority(parentExpression); if (innerPriority == parentPriority) { if (parentExpression instanceof JetBinaryExpression) { if (innerOperation == JetTokens.ANDAND || innerOperation == JetTokens.OROR) { return false; } return ((JetBinaryExpression) parentExpression).getRight() == currentInner; } // '-(-x)' case if (parentExpression instanceof JetPrefixExpression && innerExpression instanceof JetPrefixExpression) { return innerOperation == parentOperation && (innerOperation == JetTokens.PLUS || innerOperation == JetTokens.MINUS); } return false; } return innerPriority < parentPriority; }
@NotNull public static String getText(@Nullable PsiElement element) { return element != null ? element.getText() : ""; }
@Nullable public static String getNullableText(@Nullable PsiElement element) { return element != null ? element.getText() : null; }
@Override public void writeExternal(Element element) throws WriteExternalException { PsiDocumentManager.getInstance(myProject).commitAllDocuments(); if (myPsiElements.isEmpty() && myRangeMarkers.isEmpty() && mySerializedElements.isEmpty()) { throw new WriteExternalException(); } if (mySerializedElements.isEmpty()) { for (SmartPsiElementPointer<PsiElement> ptr : myPsiElements) { PsiElement psiElement = ptr.getElement(); if (psiElement == null || !psiElement.isValid()) { continue; } FoldingInfo fi = psiElement.getUserData(FOLDING_INFO_KEY); boolean state = fi != null && fi.expanded; String signature = FoldingPolicy.getSignature(psiElement); if (signature == null) { continue; } PsiFile containingFile = psiElement.getContainingFile(); PsiElement restoredElement = FoldingPolicy.restoreBySignature(containingFile, signature); if (!psiElement.equals(restoredElement)) { StringBuilder trace = new StringBuilder(); PsiElement restoredAgain = FoldingPolicy.restoreBySignature(containingFile, signature, trace); LOG.error( "element: " + psiElement + "(" + psiElement.getText() + "); restoredElement: " + restoredElement + "; signature: '" + signature + "'; file: " + containingFile + "; injected: " + InjectedLanguageManager.getInstance(myProject) .isInjectedFragment(containingFile) + "; languages: " + containingFile.getViewProvider().getLanguages() + "; restored again: " + restoredAgain + "; restore produces same results: " + (restoredAgain == restoredElement) + "; trace:\n" + trace); } Element e = new Element(ELEMENT_TAG); e.setAttribute(SIGNATURE_ATT, signature); e.setAttribute(EXPANDED_ATT, Boolean.toString(state)); element.addContent(e); } } else { // get back postponed state (before folding initialization) for (SerializedPsiElement entry : mySerializedElements) { Element e = new Element(ELEMENT_TAG); e.setAttribute(SIGNATURE_ATT, entry.mySerializedElement); e.setAttribute(EXPANDED_ATT, Boolean.toString(entry.myFoldingInfo.getExpanded())); element.addContent(e); } } String date = null; for (RangeMarker marker : myRangeMarkers) { FoldingInfo fi = marker.getUserData(FOLDING_INFO_KEY); boolean state = fi != null && fi.expanded; Element e = new Element(MARKER_TAG); if (date == null) { date = getTimeStamp(); } if (date.isEmpty()) { continue; } e.setAttribute(DATE_ATT, date); e.setAttribute(EXPANDED_ATT, Boolean.toString(state)); String signature = Integer.valueOf(marker.getStartOffset()) + ":" + Integer.valueOf(marker.getEndOffset()); e.setAttribute(SIGNATURE_ATT, signature); String placeHolderText = fi == null ? DEFAULT_PLACEHOLDER : fi.placeHolder; e.setAttribute(PLACEHOLDER_ATT, placeHolderText); element.addContent(e); } }
public static boolean checkConsistency(PsiFile psiFile, Document document) { // todo hack if (psiFile.getVirtualFile() == null) return true; CharSequence editorText = document.getCharsSequence(); int documentLength = document.getTextLength(); if (psiFile.textMatches(editorText)) { LOG.assertTrue(psiFile.getTextLength() == documentLength); return true; } char[] fileText = psiFile.textToCharArray(); @SuppressWarnings({"NonConstantStringShouldBeStringBuffer"}) @NonNls String error = "File '" + psiFile.getName() + "' text mismatch after reparse. " + "File length=" + fileText.length + "; Doc length=" + documentLength + "\n"; int i = 0; for (; i < documentLength; i++) { if (i >= fileText.length) { error += "editorText.length > psiText.length i=" + i + "\n"; break; } if (i >= editorText.length()) { error += "editorText.length > psiText.length i=" + i + "\n"; break; } if (editorText.charAt(i) != fileText[i]) { error += "first unequal char i=" + i + "\n"; break; } } // error += "*********************************************" + "\n"; // if (i <= 500){ // error += "Equal part:" + editorText.subSequence(0, i) + "\n"; // } // else{ // error += "Equal part start:\n" + editorText.subSequence(0, 200) + "\n"; // error += "................................................" + "\n"; // error += "................................................" + "\n"; // error += "................................................" + "\n"; // error += "Equal part end:\n" + editorText.subSequence(i - 200, i) + "\n"; // } error += "*********************************************" + "\n"; error += "Editor Text tail:(" + (documentLength - i) + ")\n"; // + editorText.subSequence(i, Math.min(i + 300, documentLength)) + "\n"; error += "*********************************************" + "\n"; error += "Psi Text tail:(" + (fileText.length - i) + ")\n"; error += "*********************************************" + "\n"; if (document instanceof DocumentWindow) { error += "doc: '" + document.getText() + "'\n"; error += "psi: '" + psiFile.getText() + "'\n"; error += "ast: '" + psiFile.getNode().getText() + "'\n"; error += psiFile.getLanguage() + "\n"; PsiElement context = InjectedLanguageManager.getInstance(psiFile.getProject()).getInjectionHost(psiFile); if (context != null) { error += "context: " + context + "; text: '" + context.getText() + "'\n"; error += "context file: " + context.getContainingFile() + "\n"; } error += "document window ranges: " + Arrays.asList(((DocumentWindow) document).getHostRanges()) + "\n"; } LOG.error(error); // document.replaceString(0, documentLength, psiFile.getText()); return false; }
@NotNull final RunnerResult analyzeMethod( @NotNull PsiElement psiBlock, @NotNull InstructionVisitor visitor, boolean ignoreAssertions, @NotNull Collection<DfaMemoryState> initialStates) { if (PsiTreeUtil.findChildOfType(psiBlock, OuterLanguageElement.class) != null) return RunnerResult.NOT_APPLICABLE; try { final ControlFlow flow = new ControlFlowAnalyzer(myValueFactory, psiBlock, ignoreAssertions).buildControlFlow(); if (flow == null) return RunnerResult.NOT_APPLICABLE; int[] loopNumber = LoopAnalyzer.calcInLoop(flow); int endOffset = flow.getInstructionCount(); myInstructions = flow.getInstructions(); myNestedClosures.clear(); Set<Instruction> joinInstructions = ContainerUtil.newHashSet(); for (int index = 0; index < myInstructions.length; index++) { Instruction instruction = myInstructions[index]; if (instruction instanceof GotoInstruction) { joinInstructions.add(myInstructions[((GotoInstruction) instruction).getOffset()]); } else if (instruction instanceof ConditionalGotoInstruction) { joinInstructions.add( myInstructions[((ConditionalGotoInstruction) instruction).getOffset()]); } else if (instruction instanceof MethodCallInstruction && !((MethodCallInstruction) instruction).getContracts().isEmpty()) { joinInstructions.add(myInstructions[index + 1]); } } if (LOG.isDebugEnabled()) { LOG.debug("Analyzing code block: " + psiBlock.getText()); for (int i = 0; i < myInstructions.length; i++) { LOG.debug(i + ": " + myInstructions[i]); } } // for (int i = 0; i < myInstructions.length; i++) System.out.println(i + ": " + // myInstructions[i].toString()); Integer tooExpensiveHash = psiBlock.getUserData(TOO_EXPENSIVE_HASH); if (tooExpensiveHash != null && tooExpensiveHash == psiBlock.getText().hashCode()) { LOG.debug("Too complex because hasn't changed since being too complex already"); return RunnerResult.TOO_COMPLEX; } final StateQueue queue = new StateQueue(); for (final DfaMemoryState initialState : initialStates) { queue.offer(new DfaInstructionState(myInstructions[0], initialState)); } MultiMap<BranchingInstruction, DfaMemoryState> processedStates = MultiMap.createSet(); MultiMap<BranchingInstruction, DfaMemoryState> incomingStates = MultiMap.createSet(); long msLimit = shouldCheckTimeLimit() ? Registry.intValue("ide.dfa.time.limit.online") : Registry.intValue("ide.dfa.time.limit.offline"); WorkingTimeMeasurer measurer = new WorkingTimeMeasurer(msLimit * 1000 * 1000); int count = 0; while (!queue.isEmpty()) { List<DfaInstructionState> states = queue.getNextInstructionStates(joinInstructions); for (DfaInstructionState instructionState : states) { if (count++ % 1024 == 0 && measurer.isTimeOver()) { LOG.debug("Too complex because the analysis took too long"); psiBlock.putUserData(TOO_EXPENSIVE_HASH, psiBlock.getText().hashCode()); return RunnerResult.TOO_COMPLEX; } ProgressManager.checkCanceled(); if (LOG.isDebugEnabled()) { LOG.debug(instructionState.toString()); } // System.out.println(instructionState.toString()); Instruction instruction = instructionState.getInstruction(); if (instruction instanceof BranchingInstruction) { BranchingInstruction branching = (BranchingInstruction) instruction; Collection<DfaMemoryState> processed = processedStates.get(branching); if (processed.contains(instructionState.getMemoryState())) { continue; } if (processed.size() > MAX_STATES_PER_BRANCH) { LOG.debug("Too complex because too many different possible states"); return RunnerResult.TOO_COMPLEX; // Too complex :( } if (loopNumber[branching.getIndex()] != 0) { processedStates.putValue(branching, instructionState.getMemoryState().createCopy()); } } DfaInstructionState[] after = acceptInstruction(visitor, instructionState); for (DfaInstructionState state : after) { Instruction nextInstruction = state.getInstruction(); if (nextInstruction.getIndex() >= endOffset) { continue; } handleStepOutOfLoop( instruction, nextInstruction, loopNumber, processedStates, incomingStates, states, after, queue); if (nextInstruction instanceof BranchingInstruction) { BranchingInstruction branching = (BranchingInstruction) nextInstruction; if (processedStates.get(branching).contains(state.getMemoryState()) || incomingStates.get(branching).contains(state.getMemoryState())) { continue; } if (loopNumber[branching.getIndex()] != 0) { incomingStates.putValue(branching, state.getMemoryState().createCopy()); } } queue.offer(state); } } } psiBlock.putUserData(TOO_EXPENSIVE_HASH, null); LOG.debug("Analysis ok"); return RunnerResult.OK; } catch (ArrayIndexOutOfBoundsException e) { LOG.error(psiBlock.getText(), e); return RunnerResult.ABORTED; } catch (EmptyStackException e) { LOG.error(psiBlock.getText(), e); return RunnerResult.ABORTED; } }