public static void clearCaches(
     @NotNull PsiFile injected, @NotNull DocumentWindowImpl documentWindow) {
   VirtualFileWindowImpl virtualFile = (VirtualFileWindowImpl) injected.getVirtualFile();
   PsiManagerEx psiManagerEx = (PsiManagerEx) injected.getManager();
   if (psiManagerEx.getProject().isDisposed()) return;
   psiManagerEx.getFileManager().setViewProvider(virtualFile, null);
   PsiElement context =
       InjectedLanguageManager.getInstance(injected.getProject()).getInjectionHost(injected);
   PsiFile hostFile;
   if (context != null) {
     hostFile = context.getContainingFile();
   } else {
     VirtualFile delegate = virtualFile.getDelegate();
     hostFile = delegate.isValid() ? psiManagerEx.findFile(delegate) : null;
   }
   if (hostFile != null) {
     // modification of cachedInjectedDocuments must be under PsiLock
     synchronized (PsiLock.LOCK) {
       List<DocumentWindow> cachedInjectedDocuments = getCachedInjectedDocuments(hostFile);
       for (int i = cachedInjectedDocuments.size() - 1; i >= 0; i--) {
         DocumentWindow cachedInjectedDocument = cachedInjectedDocuments.get(i);
         if (cachedInjectedDocument == documentWindow) {
           cachedInjectedDocuments.remove(i);
         }
       }
     }
   }
 }
  public static boolean isValidName(
      final Project project, final PsiElement psiElement, final String newName) {
    if (newName == null || newName.length() == 0) {
      return false;
    }
    final Condition<String> inputValidator =
        RenameInputValidatorRegistry.getInputValidator(psiElement);
    if (inputValidator != null) {
      return inputValidator.value(newName);
    }
    if (psiElement instanceof PsiFile || psiElement instanceof PsiDirectory) {
      return newName.indexOf('\\') < 0 && newName.indexOf('/') < 0;
    }
    if (psiElement instanceof PomTargetPsiElement) {
      return !StringUtil.isEmptyOrSpaces(newName);
    }

    final PsiFile file = psiElement.getContainingFile();
    final Language elementLanguage = psiElement.getLanguage();

    final Language fileLanguage = file == null ? null : file.getLanguage();
    Language language =
        fileLanguage == null
            ? elementLanguage
            : fileLanguage.isKindOf(elementLanguage) ? fileLanguage : elementLanguage;

    return LanguageNamesValidation.INSTANCE
        .forLanguage(language)
        .isIdentifier(newName.trim(), project);
  }
예제 #3
0
  public String getAttributeValue(String _name, String namespace) {
    if (namespace == null) {
      return getAttributeValue(_name);
    }

    XmlTagImpl current = this;
    PsiElement parent = getParent();

    while (current != null) {
      BidirectionalMap<String, String> map = current.initNamespaceMaps(parent);
      if (map != null) {
        List<String> keysByValue = map.getKeysByValue(namespace);
        if (keysByValue != null && !keysByValue.isEmpty()) {

          for (String prefix : keysByValue) {
            if (prefix != null && prefix.length() > 0) {
              final String value = getAttributeValue(prefix + ":" + _name);
              if (value != null) return value;
            }
          }
        }
      }

      current = parent instanceof XmlTag ? (XmlTagImpl) parent : null;
      parent = parent.getParent();
    }

    if (namespace.length() == 0 || getNamespace().equals(namespace)) {
      return getAttributeValue(_name);
    }
    return null;
  }
  public static void enumerate(
      @NotNull PsiElement host,
      @NotNull PsiFile containingFile,
      boolean probeUp,
      @NotNull PsiLanguageInjectionHost.InjectedPsiVisitor visitor) {
    // do not inject into nonphysical files except during completion
    if (!containingFile.isPhysical() && containingFile.getOriginalFile() == containingFile) {
      final PsiElement context =
          InjectedLanguageManager.getInstance(containingFile.getProject())
              .getInjectionHost(containingFile);
      if (context == null) return;

      final PsiFile file = context.getContainingFile();
      if (file == null || !file.isPhysical() && file.getOriginalFile() == file) return;
    }

    if (containingFile.getViewProvider() instanceof InjectedFileViewProvider)
      return; // no injection inside injection

    PsiElement inTree = loadTree(host, containingFile);
    if (inTree != host) {
      host = inTree;
      containingFile = host.getContainingFile();
    }

    MultiHostRegistrarImpl registrar = probeElementsUp(host, containingFile, probeUp);
    if (registrar == null) {
      return;
    }
    List<Pair<Place, PsiFile>> places = registrar.getResult();
    for (Pair<Place, PsiFile> pair : places) {
      PsiFile injectedPsi = pair.second;
      visitor.visit(injectedPsi, pair.first);
    }
  }
  // returns (injected psi, leaf element at the offset, language of the leaf element)
  // since findElementAt() is expensive, we trying to reuse its result
  @NotNull
  private static Trinity<PsiElement, PsiElement, Language> tryOffset(
      @NotNull PsiFile hostFile, final int offset, @NotNull PsiDocumentManager documentManager) {
    FileViewProvider provider = hostFile.getViewProvider();
    Language leafLanguage = null;
    PsiElement leafElement = null;
    for (Language language : provider.getLanguages()) {
      PsiElement element = provider.findElementAt(offset, language);
      if (element != null) {
        if (leafLanguage == null) {
          leafLanguage = language;
          leafElement = element;
        }
        PsiElement injected = findInside(element, hostFile, offset, documentManager);
        if (injected != null) return Trinity.create(injected, element, language);
      }
      // maybe we are at the border between two psi elements, then try to find injection at the end
      // of the left element
      if (offset != 0 && (element == null || element.getTextRange().getStartOffset() == offset)) {
        PsiElement leftElement = provider.findElementAt(offset - 1, language);
        if (leftElement != null && leftElement.getTextRange().getEndOffset() == offset) {
          PsiElement injected = findInside(leftElement, hostFile, offset, documentManager);
          if (injected != null) return Trinity.create(injected, element, language);
        }
      }
    }

    return Trinity.create(null, leafElement, leafLanguage);
  }
  void loadFromEditor(@NotNull Editor editor) {
    assertDispatchThread();
    LOG.assertTrue(!editor.isDisposed());
    clear();

    PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
    documentManager.commitDocument(editor.getDocument());
    PsiFile file = documentManager.getPsiFile(editor.getDocument());

    SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
    EditorFoldingInfo info = EditorFoldingInfo.get(editor);
    FoldRegion[] foldRegions = editor.getFoldingModel().getAllFoldRegions();
    for (FoldRegion region : foldRegions) {
      if (!region.isValid()) continue;
      PsiElement element = info.getPsiElement(region);
      boolean expanded = region.isExpanded();
      boolean collapseByDefault =
          element != null
              && FoldingPolicy.isCollapseByDefault(element)
              && !FoldingUtil.caretInsideRange(editor, TextRange.create(region));
      if (collapseByDefault == expanded || element == null) {
        FoldingInfo fi = new FoldingInfo(region.getPlaceholderText(), expanded);
        if (element != null) {
          myPsiElements.add(smartPointerManager.createSmartPsiElementPointer(element, file));
          element.putUserData(FOLDING_INFO_KEY, fi);
        } else if (region.isValid()) {
          myRangeMarkers.add(region);
          region.putUserData(FOLDING_INFO_KEY, fi);
        }
      }
    }
  }
  public static void initOffsets(final PsiFile file, final OffsetMap offsetMap) {
    int offset =
        Math.max(
            offsetMap.getOffset(CompletionInitializationContext.SELECTION_END_OFFSET),
            offsetMap.getOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET));

    PsiElement element = file.findElementAt(offset);
    if (element instanceof PsiWhiteSpace
        && (!element.textContains('\n')
            || CodeStyleSettingsManager.getSettings(file.getProject())
                .getCommonSettings(JavaLanguage.INSTANCE)
                .METHOD_PARAMETERS_LPAREN_ON_NEXT_LINE)) {
      element = file.findElementAt(element.getTextRange().getEndOffset());
    }
    if (element == null) return;

    if (LEFT_PAREN.accepts(element)) {
      offsetMap.addOffset(LPAREN_OFFSET, element.getTextRange().getStartOffset());
      PsiElement list = element.getParent();
      PsiElement last = list.getLastChild();
      if (last instanceof PsiJavaToken
          && ((PsiJavaToken) last).getTokenType() == JavaTokenType.RPARENTH) {
        offsetMap.addOffset(RPAREN_OFFSET, last.getTextRange().getStartOffset());
      }

      offsetMap.addOffset(ARG_LIST_END_OFFSET, list.getTextRange().getEndOffset());
    }
  }
  public static String getUnescapedText(
      PsiFile file,
      @Nullable final PsiElement startElement,
      @Nullable final PsiElement endElement) {
    final InjectedLanguageManager manager = InjectedLanguageManager.getInstance(file.getProject());
    if (manager.getInjectionHost(file) == null) {
      return file.getText()
          .substring(
              startElement == null ? 0 : startElement.getTextRange().getStartOffset(),
              endElement == null
                  ? file.getTextLength()
                  : endElement.getTextRange().getStartOffset());
    }
    final StringBuilder sb = new StringBuilder();
    file.accept(
        new PsiRecursiveElementWalkingVisitor() {

          Boolean myState = startElement == null ? Boolean.TRUE : null;

          @Override
          public void visitElement(PsiElement element) {
            if (element == startElement) myState = Boolean.TRUE;
            if (element == endElement) myState = Boolean.FALSE;
            if (Boolean.FALSE == myState) return;
            if (Boolean.TRUE == myState && element.getFirstChild() == null) {
              sb.append(getUnescapedLeafText(element, false));
            } else {
              super.visitElement(element);
            }
          }
        });
    return sb.toString();
  }
예제 #9
0
  public static TextWithImports getEditorText(final Editor editor) {
    if (editor == null) {
      return null;
    }
    final Project project = editor.getProject();
    if (project == null) return null;

    String defaultExpression = editor.getSelectionModel().getSelectedText();
    if (defaultExpression == null) {
      int offset = editor.getCaretModel().getOffset();
      PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument());
      if (psiFile != null) {
        PsiElement elementAtCursor = psiFile.findElementAt(offset);
        if (elementAtCursor != null) {
          final EditorTextProvider textProvider =
              EditorTextProvider.EP.forLanguage(elementAtCursor.getLanguage());
          if (textProvider != null) {
            final TextWithImports editorText = textProvider.getEditorText(elementAtCursor);
            if (editorText != null) return editorText;
          }
        }
      }
    } else {
      return new TextWithImportsImpl(CodeFragmentKind.EXPRESSION, defaultExpression);
    }
    return null;
  }
예제 #10
0
 private static PsiElement getNextElement(PsiElement element) {
   PsiElement sibling = element.getNextSibling();
   if (sibling != null) return sibling;
   element = element.getParent();
   if (element != null) return getNextElement(element);
   return null;
 }
 @NotNull
 public UsageViewPresentation createPresentation(
     @NotNull FindUsagesHandler handler, @NotNull FindUsagesOptions findUsagesOptions) {
   PsiElement element = handler.getPsiElement();
   LOG.assertTrue(element.isValid());
   return createPresentation(element, findUsagesOptions, myToOpenInNewTab);
 }
 public PsiDirectory[] getSelectedDirectories() {
   final PsiElement[] elements = getSelectedPSIElements();
   if (elements.length == 1) {
     final PsiElement element = elements[0];
     if (element instanceof PsiDirectory) {
       return new PsiDirectory[] {(PsiDirectory) element};
     } else if (element instanceof PsiDirectoryContainer) {
       return ((PsiDirectoryContainer) element).getDirectories();
     } else {
       final PsiFile containingFile = element.getContainingFile();
       if (containingFile != null) {
         final PsiDirectory psiDirectory = containingFile.getContainingDirectory();
         if (psiDirectory != null) {
           return new PsiDirectory[] {psiDirectory};
         }
         final VirtualFile file = containingFile.getVirtualFile();
         if (file instanceof VirtualFileWindow) {
           final VirtualFile delegate = ((VirtualFileWindow) file).getDelegate();
           final PsiFile delegatePsiFile = containingFile.getManager().findFile(delegate);
           if (delegatePsiFile != null && delegatePsiFile.getContainingDirectory() != null) {
             return new PsiDirectory[] {delegatePsiFile.getContainingDirectory()};
           }
         }
         return PsiDirectory.EMPTY_ARRAY;
       }
     }
   } else {
     final DefaultMutableTreeNode selectedNode = getSelectedNode();
     if (selectedNode != null) {
       return getSelectedDirectoriesInAmbiguousCase(selectedNode);
     }
   }
   return PsiDirectory.EMPTY_ARRAY;
 }
  public static boolean isClassEquivalentTo(@NotNull PsiClass aClass, PsiElement another) {
    if (aClass == another) return true;
    if (!(another instanceof PsiClass)) return false;
    String name1 = aClass.getName();
    if (name1 == null) return false;
    if (!another.isValid()) return false;
    String name2 = ((PsiClass) another).getName();
    if (name2 == null) return false;
    if (name1.hashCode() != name2.hashCode()) return false;
    if (!name1.equals(name2)) return false;
    String qName1 = aClass.getQualifiedName();
    String qName2 = ((PsiClass) another).getQualifiedName();
    if (qName1 == null || qName2 == null) {
      //noinspection StringEquality
      if (qName1 != qName2) return false;

      if (aClass instanceof PsiTypeParameter && another instanceof PsiTypeParameter) {
        PsiTypeParameter p1 = (PsiTypeParameter) aClass;
        PsiTypeParameter p2 = (PsiTypeParameter) another;

        return p1.getIndex() == p2.getIndex()
            && aClass.getManager().areElementsEquivalent(p1.getOwner(), p2.getOwner());
      } else {
        return false;
      }
    }
    if (qName1.hashCode() != qName2.hashCode() || !qName1.equals(qName2)) {
      return false;
    }

    if (originalElement(aClass).equals(originalElement((PsiClass) another))) {
      return true;
    }

    final PsiFile file1 = aClass.getContainingFile().getOriginalFile();
    final PsiFile file2 = another.getContainingFile().getOriginalFile();

    // see com.intellij.openapi.vcs.changes.PsiChangeTracker
    // see com.intellij.psi.impl.PsiFileFactoryImpl#createFileFromText(CharSequence,PsiFile)
    final PsiFile original1 = file1.getUserData(PsiFileFactory.ORIGINAL_FILE);
    final PsiFile original2 = file2.getUserData(PsiFileFactory.ORIGINAL_FILE);
    if (original1 == original2 && original1 != null
        || original1 == file2
        || original2 == file1
        || file1 == file2) {
      return compareClassSeqNumber(aClass, (PsiClass) another);
    }

    final FileIndexFacade fileIndex =
        ServiceManager.getService(file1.getProject(), FileIndexFacade.class);
    final VirtualFile vfile1 = file1.getViewProvider().getVirtualFile();
    final VirtualFile vfile2 = file2.getViewProvider().getVirtualFile();
    boolean lib1 = fileIndex.isInLibraryClasses(vfile1);
    boolean lib2 = fileIndex.isInLibraryClasses(vfile2);

    return (fileIndex.isInSource(vfile1) || lib1) && (fileIndex.isInSource(vfile2) || lib2);
  }
  @Override
  public void replaceDotToken(PsiElement newDot) {
    if (newDot == null) return;
    if (!TokenSets.DOTS.contains(newDot.getNode().getElementType())) return;
    final PsiElement oldDot = getDotToken();
    if (oldDot == null) return;

    getNode().replaceChild(oldDot.getNode(), newDot.getNode());
  }
 @Nullable
 protected PsiElement getPSIElement(@Nullable final Object element) {
   if (element instanceof PsiElement) {
     PsiElement psiElement = (PsiElement) element;
     if (psiElement.isValid()) {
       return psiElement;
     }
   }
   return null;
 }
    private static PsiType doFun(GrReferenceExpression refExpr) {
      if (ResolveUtil.isClassReference(refExpr)) {
        GrExpression qualifier = refExpr.getQualifier();
        LOG.assertTrue(qualifier != null);
        return TypesUtil.createJavaLangClassType(
            qualifier.getType(), refExpr.getProject(), refExpr.getResolveScope());
      }

      if (PsiUtil.isCompileStatic(refExpr)) {
        final GroovyResolveResult resolveResult = refExpr.advancedResolve();
        final PsiElement resolvedF = resolveResult.getElement();
        final PsiType type;
        if (resolvedF instanceof GrField) {
          type = ((GrField) resolvedF).getType();
        } else if (resolvedF instanceof GrAccessorMethod) {
          type = ((GrAccessorMethod) resolvedF).getProperty().getType();
        } else {
          type = null;
        }
        if (type != null) {
          return resolveResult.getSubstitutor().substitute(type);
        }
      }

      final PsiElement resolved = refExpr.resolve();
      final PsiType nominal = refExpr.getNominalType();

      Boolean reassigned = GrReassignedLocalVarsChecker.isReassignedVar(refExpr);
      if (reassigned != null && reassigned.booleanValue()) {
        return GrReassignedLocalVarsChecker.getReassignedVarType(refExpr, true);
      }

      final PsiType inferred = getInferredTypes(refExpr, resolved);
      if (inferred == null) {
        if (nominal == null) {
          // inside nested closure we could still try to infer from variable initializer. Not sound,
          // but makes sense
          if (resolved instanceof GrVariable) {
            LOG.assertTrue(resolved.isValid());
            return ((GrVariable) resolved).getTypeGroovy();
          }
        }

        return nominal;
      }

      if (nominal == null) return inferred;
      if (!TypeConversionUtil.isAssignable(TypeConversionUtil.erasure(nominal), inferred, false)) {
        if (resolved instanceof GrVariable
            && ((GrVariable) resolved).getTypeElementGroovy() != null) {
          return nominal;
        }
      }
      return inferred;
    }
  private void getInjectedPsiFiles(
      @NotNull final List<PsiElement> elements1,
      @NotNull final List<PsiElement> elements2,
      @NotNull final ProgressIndicator progress,
      @NotNull final Set<PsiFile> outInjected) {
    List<DocumentWindow> injected = InjectedLanguageUtil.getCachedInjectedDocuments(myFile);
    Collection<PsiElement> hosts =
        new THashSet<PsiElement>(elements1.size() + elements2.size() + injected.size());

    // rehighlight all injected PSI regardless the range,
    // since change in one place can lead to invalidation of injected PSI in (completely) other
    // place.
    for (DocumentWindow documentRange : injected) {
      progress.checkCanceled();
      if (!documentRange.isValid()) continue;
      PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(documentRange);
      if (file == null) continue;
      PsiElement context =
          InjectedLanguageManager.getInstance(file.getProject()).getInjectionHost(file);
      if (context != null
          && context.isValid()
          && !file.getProject().isDisposed()
          && (myUpdateAll
              || new ProperTextRange(myStartOffset, myEndOffset)
                  .intersects(context.getTextRange()))) {
        hosts.add(context);
      }
    }
    hosts.addAll(elements1);
    hosts.addAll(elements2);

    final PsiLanguageInjectionHost.InjectedPsiVisitor visitor =
        new PsiLanguageInjectionHost.InjectedPsiVisitor() {
          @Override
          public void visit(
              @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
            synchronized (outInjected) {
              outInjected.add(injectedPsi);
            }
          }
        };
    if (!JobUtil.invokeConcurrentlyUnderProgress(
        new ArrayList<PsiElement>(hosts),
        progress,
        false,
        new Processor<PsiElement>() {
          @Override
          public boolean process(PsiElement element) {
            progress.checkCanceled();
            InjectedLanguageUtil.enumerate(element, myFile, false, visitor);
            return true;
          }
        })) throw new ProcessCanceledException();
  }
 @Nullable
 public static String getUnescapedLeafText(PsiElement element, boolean strict) {
   String unescaped = element.getCopyableUserData(LeafPatcher.UNESCAPED_TEXT);
   if (unescaped != null) {
     return unescaped;
   }
   if (!strict && element.getFirstChild() == null) {
     return element.getText();
   }
   return null;
 }
예제 #19
0
 public PomModelEvent runInner() throws IncorrectOperationException {
   final ASTNode anchor = expandTag();
   if (myChild.getElementType() == XmlElementType.XML_TAG) {
     // compute where to insert tag according to DTD or XSD
     final XmlElementDescriptor parentDescriptor = getDescriptor();
     final XmlTag[] subTags = getSubTags();
     final PsiElement declaration =
         parentDescriptor != null ? parentDescriptor.getDeclaration() : null;
     // filtring out generated dtds
     if (declaration != null
         && declaration.getContainingFile() != null
         && declaration.getContainingFile().isPhysical()
         && subTags.length > 0) {
       final XmlElementDescriptor[] childElementDescriptors =
           parentDescriptor.getElementsDescriptors(XmlTagImpl.this);
       int subTagNum = -1;
       for (final XmlElementDescriptor childElementDescriptor : childElementDescriptors) {
         final String childElementName = childElementDescriptor.getName();
         while (subTagNum < subTags.length - 1
             && subTags[subTagNum + 1].getName().equals(childElementName)) {
           subTagNum++;
         }
         if (childElementName.equals(
             XmlChildRole.START_TAG_NAME_FINDER.findChild(myChild).getText())) {
           // insert child just after anchor
           // insert into the position specified by index
           if (subTagNum >= 0) {
             final ASTNode subTag = (ASTNode) subTags[subTagNum];
             if (subTag.getTreeParent() != XmlTagImpl.this) {
               // in entity
               final XmlEntityRef entityRef =
                   PsiTreeUtil.getParentOfType(subTags[subTagNum], XmlEntityRef.class);
               throw new IncorrectOperationException(
                   "Can't insert subtag to the entity. Entity reference text: "
                       + (entityRef == null ? "" : entityRef.getText()));
             }
             myNewElement =
                 XmlTagImpl.super.addInternal(myChild, myChild, subTag, Boolean.FALSE);
           } else {
             final ASTNode child = XmlChildRole.START_TAG_END_FINDER.findChild(XmlTagImpl.this);
             myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, child, Boolean.FALSE);
           }
           return null;
         }
       }
     } else {
       final ASTNode child = XmlChildRole.CLOSING_TAG_START_FINDER.findChild(XmlTagImpl.this);
       myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, child, Boolean.TRUE);
       return null;
     }
   }
   myNewElement = XmlTagImpl.super.addInternal(myChild, myChild, anchor, Boolean.TRUE);
   return null;
 }
 @NotNull
 private static PsiElement originalElement(@NotNull PsiClass aClass) {
   final PsiElement originalElement = aClass.getOriginalElement();
   ASTNode node = originalElement.getNode();
   if (node != null) {
     final PsiCompiledElement compiled = node.getUserData(ClsElementImpl.COMPILED_ELEMENT);
     if (compiled != null) {
       return compiled;
     }
   }
   return originalElement;
 }
 public static PsiFile getTopLevelFile(@NotNull PsiElement element) {
   PsiFile containingFile = element.getContainingFile();
   if (containingFile == null) return null;
   Document document =
       PsiDocumentManager.getInstance(element.getProject()).getCachedDocument(containingFile);
   if (document instanceof DocumentWindow) {
     PsiElement host =
         InjectedLanguageManager.getInstance(containingFile.getProject())
             .getInjectionHost(containingFile);
     if (host != null) containingFile = host.getContainingFile();
   }
   return containingFile;
 }
 @NotNull
 public static GlobalSearchScope getMaximalScope(@NotNull FindUsagesHandler handler) {
   PsiElement element = handler.getPsiElement();
   Project project = element.getProject();
   PsiFile file = element.getContainingFile();
   if (file != null
       && ProjectFileIndex.SERVICE
           .getInstance(project)
           .isInContent(file.getViewProvider().getVirtualFile())) {
     return GlobalSearchScope.projectScope(project);
   }
   return GlobalSearchScope.allScope(project);
 }
 private static int getSeqNumber(@NotNull PsiClass aClass) {
   // sequence number of this class among its parent' child classes named the same
   PsiElement parent = aClass.getParent();
   if (parent == null) return -1;
   int seqNo = 0;
   for (PsiElement child : parent.getChildren()) {
     if (child == aClass) return seqNo;
     if (child instanceof PsiClass
         && Comparing.strEqual(aClass.getName(), ((PsiClass) child).getName())) {
       seqNo++;
     }
   }
   return -1;
 }
  public static PsiMethod findPsiMethod(PsiFile file, int offset) {
    PsiElement element = null;

    while (offset >= 0) {
      element = file.findElementAt(offset);
      if (element != null) break;
      offset--;
    }

    for (; element != null; element = element.getParent()) {
      if (element instanceof PsiClass) return null;
      if (element instanceof PsiMethod) return (PsiMethod) element;
    }
    return null;
  }
예제 #25
0
  @NotNull
  public String getNamespaceByPrefix(String prefix) {
    final PsiElement parent = getParent();
    LOG.assertTrue(parent.isValid());
    BidirectionalMap<String, String> map = initNamespaceMaps(parent);
    if (map != null) {
      final String ns = map.get(prefix);
      if (ns != null) return ns;
    }
    if (parent instanceof XmlTag) return ((XmlTag) parent).getNamespaceByPrefix(prefix);
    // The prefix 'xml' is by definition bound to the namespace name
    // http://www.w3.org/XML/1998/namespace. It MAY, but need not, be declared
    if (XML_NS_PREFIX.equals(prefix)) return XmlUtil.XML_NAMESPACE_URI;

    if (prefix.length() > 0 && !hasNamespaceDeclarations() && getNamespacePrefix().equals(prefix)) {
      // When there is no namespace declarations then qualified names should be just used in dtds
      // this implies that we may have "" namespace prefix ! (see last paragraph in Namespaces in
      // Xml, Section 5)

      String result =
          ourGuard.doPreventingRecursion(
              "getNsByPrefix",
              true,
              new Computable<String>() {
                @Override
                public String compute() {
                  final String nsFromEmptyPrefix = getNamespaceByPrefix("");
                  final XmlNSDescriptor nsDescriptor = getNSDescriptor(nsFromEmptyPrefix, false);
                  final XmlElementDescriptor descriptor =
                      nsDescriptor != null
                          ? nsDescriptor.getElementDescriptor(XmlTagImpl.this)
                          : null;
                  final String nameFromRealDescriptor =
                      descriptor != null
                              && descriptor.getDeclaration() != null
                              && descriptor.getDeclaration().isPhysical()
                          ? descriptor.getName()
                          : "";
                  if (nameFromRealDescriptor.equals(getName())) return nsFromEmptyPrefix;
                  return XmlUtil.EMPTY_URI;
                }
              });
      if (result != null) {
        return result;
      }
    }
    return XmlUtil.EMPTY_URI;
  }
  @Override
  public PsiElement handleElementRenameSimple(String newElementName)
      throws IncorrectOperationException {
    if (!PsiUtil.isValidReferenceName(newElementName)) {
      final PsiElement old = getReferenceNameElement();
      if (old == null) throw new IncorrectOperationException("ref has no name element");

      PsiElement element =
          GroovyPsiElementFactory.getInstance(getProject())
              .createStringLiteralForReference(newElementName);
      old.replace(element);
      return this;
    }

    return super.handleElementRenameSimple(newElementName);
  }
 @Override
 @Nullable
 public List<Pair<PsiElement, TextRange>> getInjectedPsiFiles(@NotNull final PsiElement host) {
   if (!(host instanceof PsiLanguageInjectionHost)
       || !((PsiLanguageInjectionHost) host).isValidHost()) {
     return null;
   }
   final PsiElement inTree = InjectedLanguageUtil.loadTree(host, host.getContainingFile());
   final List<Pair<PsiElement, TextRange>> result = new SmartList<Pair<PsiElement, TextRange>>();
   InjectedLanguageUtil.enumerate(
       inTree,
       new PsiLanguageInjectionHost.InjectedPsiVisitor() {
         @Override
         public void visit(
             @NotNull PsiFile injectedPsi, @NotNull List<PsiLanguageInjectionHost.Shred> places) {
           for (PsiLanguageInjectionHost.Shred place : places) {
             if (place.getHost() == inTree) {
               result.add(
                   new Pair<PsiElement, TextRange>(injectedPsi, place.getRangeInsideHost()));
             }
           }
         }
       });
   return result.isEmpty() ? null : result;
 }
  public static boolean isInInjectedLanguagePrefixSuffix(@NotNull final PsiElement element) {
    PsiFile injectedFile = element.getContainingFile();
    if (injectedFile == null) return false;
    Project project = injectedFile.getProject();
    InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(project);
    if (!languageManager.isInjectedFragment(injectedFile)) return false;
    TextRange elementRange = element.getTextRange();
    List<TextRange> editables =
        languageManager.intersectWithAllEditableFragments(injectedFile, elementRange);
    int combinedEdiablesLength = 0;
    for (TextRange editable : editables) {
      combinedEdiablesLength += editable.getLength();
    }

    return combinedEdiablesLength != elementRange.getLength();
  }
  @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;
  }
  public static void renameNonCodeUsages(
      @NotNull Project project, @NotNull NonCodeUsageInfo[] usages) {
    PsiDocumentManager.getInstance(project).commitAllDocuments();
    Map<Document, List<UsageOffset>> docsToOffsetsMap = new HashMap<Document, List<UsageOffset>>();
    final PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
    for (NonCodeUsageInfo usage : usages) {
      PsiElement element = usage.getElement();

      if (element == null) continue;
      element = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element, true);
      if (element == null) continue;

      final ProperTextRange rangeInElement = usage.getRangeInElement();
      if (rangeInElement == null) continue;

      final PsiFile containingFile = element.getContainingFile();
      final Document document = psiDocumentManager.getDocument(containingFile);

      final Segment segment = usage.getSegment();
      LOG.assertTrue(segment != null);
      int fileOffset = segment.getStartOffset();

      List<UsageOffset> list = docsToOffsetsMap.get(document);
      if (list == null) {
        list = new ArrayList<UsageOffset>();
        docsToOffsetsMap.put(document, list);
      }

      list.add(new UsageOffset(fileOffset, fileOffset + rangeInElement.getLength(), usage.newText));
    }

    for (Document document : docsToOffsetsMap.keySet()) {
      List<UsageOffset> list = docsToOffsetsMap.get(document);
      LOG.assertTrue(list != null, document);
      UsageOffset[] offsets = list.toArray(new UsageOffset[list.size()]);
      Arrays.sort(offsets);

      for (int i = offsets.length - 1; i >= 0; i--) {
        UsageOffset usageOffset = offsets[i];
        document.replaceString(usageOffset.startOffset, usageOffset.endOffset, usageOffset.newText);
      }
      PsiDocumentManager.getInstance(project).commitDocument(document);
    }
    PsiDocumentManager.getInstance(project).commitAllDocuments();
  }