use of com.intellij.psi.javadoc.PsiDocComment in project intellij-community by JetBrains.
the class AppEngineForbiddenCodeInspection method checkFile.
@Override
public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull final InspectionManager manager, final boolean isOnTheFly) {
final Project project = manager.getProject();
Module module = ModuleUtilCore.findModuleForPsiElement(file);
final AppEngineFacet appEngineFacet = AppEngineFacet.getAppEngineFacetByModule(module);
if (appEngineFacet == null) {
return null;
}
final AppEngineSdk appEngineSdk = appEngineFacet.getSdk();
if (!appEngineSdk.isValid()) {
return null;
}
final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
final List<ProblemDescriptor> problems = new ArrayList<>();
file.accept(new JavaRecursiveElementWalkingVisitor() {
@Override
public void visitDocComment(PsiDocComment comment) {
}
@Override
public void visitMethod(PsiMethod method) {
final PsiModifierList modifierList = method.getModifierList();
if (modifierList.hasModifierProperty(PsiModifier.NATIVE)) {
if (!isNativeMethodAllowed(method)) {
problems.add(manager.createProblemDescriptor(modifierList, "Native methods aren't allowed in App Engine application", isOnTheFly, LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING));
}
}
super.visitMethod(method);
}
@Override
public void visitNewExpression(PsiNewExpression expression) {
final PsiJavaCodeReferenceElement classReference = expression.getClassReference();
if (classReference != null) {
final PsiElement resolved = classReference.resolve();
if (resolved instanceof PsiClass) {
final String qualifiedName = ((PsiClass) resolved).getQualifiedName();
if (qualifiedName != null && appEngineSdk.isMethodInBlacklist(qualifiedName, "new")) {
final String message = "App Engine application should not create new instances of '" + qualifiedName + "' class";
problems.add(manager.createProblemDescriptor(classReference, message, isOnTheFly, LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING));
}
}
}
super.visitNewExpression(expression);
}
@Override
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
final PsiElement element = methodExpression.resolve();
if (element instanceof PsiMethod) {
final PsiMethod method = (PsiMethod) element;
final PsiClass psiClass = method.getContainingClass();
if (psiClass != null) {
final String qualifiedName = psiClass.getQualifiedName();
final String methodName = method.getName();
if (qualifiedName != null && appEngineSdk.isMethodInBlacklist(qualifiedName, methodName)) {
final String message = "AppEngine application should not call '" + StringUtil.getShortName(qualifiedName) + "." + methodName + "' method";
problems.add(manager.createProblemDescriptor(methodExpression, message, isOnTheFly, LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING));
}
}
}
super.visitMethodCallExpression(expression);
}
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement reference) {
final PsiElement resolved = reference.resolve();
if (resolved instanceof PsiClass) {
final PsiFile psiFile = resolved.getContainingFile();
if (psiFile != null) {
final VirtualFile virtualFile = psiFile.getVirtualFile();
if (virtualFile != null && !fileIndex.isInSource(virtualFile)) {
final List<OrderEntry> list = fileIndex.getOrderEntriesForFile(virtualFile);
for (OrderEntry entry : list) {
if (entry instanceof JdkOrderEntry) {
final String className = ClassUtil.getJVMClassName((PsiClass) resolved);
if (className != null && !appEngineSdk.isClassInWhiteList(className)) {
problems.add(manager.createProblemDescriptor(reference, "Class '" + className + "' is not included in App Engine JRE White List", isOnTheFly, LocalQuickFix.EMPTY_ARRAY, ProblemHighlightType.GENERIC_ERROR_OR_WARNING));
}
}
}
}
}
}
super.visitReferenceElement(reference);
}
});
return problems.toArray(new ProblemDescriptor[problems.size()]);
}
use of com.intellij.psi.javadoc.PsiDocComment in project intellij-community by JetBrains.
the class SourceCodeChecker method check.
private static ThreeState check(Location location, SourcePosition position, Project project) {
Method method = DebuggerUtilsEx.getMethod(location);
// for now skip constructors, bridges, lambdas etc.
if (method == null || method.isConstructor() || method.isSynthetic() || method.isBridge() || method.isStaticInitializer() || (method.declaringType() instanceof ClassType && ((ClassType) method.declaringType()).isEnum()) || DebuggerUtilsEx.isLambda(method)) {
return ThreeState.UNSURE;
}
List<Location> locations = DebuggerUtilsEx.allLineLocations(method);
if (ContainerUtil.isEmpty(locations)) {
return ThreeState.UNSURE;
}
if (position != null) {
return ReadAction.compute(() -> {
PsiFile psiFile = position.getFile();
if (!psiFile.getLanguage().isKindOf(JavaLanguage.INSTANCE)) {
// only for java for now
return ThreeState.UNSURE;
}
Document document = PsiDocumentManager.getInstance(project).getDocument(psiFile);
if (document == null) {
return ThreeState.UNSURE;
}
boolean res = false;
PsiElement psiMethod = DebuggerUtilsEx.getContainingMethod(position);
if (psiMethod != null) {
TextRange range = psiMethod.getTextRange();
if (psiMethod instanceof PsiDocCommentOwner) {
PsiDocComment comment = ((PsiDocCommentOwner) psiMethod).getDocComment();
if (comment != null) {
range = new TextRange(comment.getTextRange().getEndOffset() + 1, range.getEndOffset());
}
}
int startLine = document.getLineNumber(range.getStartOffset()) + 1;
int endLine = document.getLineNumber(range.getEndOffset()) + 1;
res = getLinesStream(locations, psiFile).allMatch(line -> startLine <= line && line <= endLine);
if (!res) {
LOG.debug("Source check failed: Method " + method.name() + ", source: " + ((NavigationItem) psiMethod).getName() + "\nLines: " + getLinesStream(locations, psiFile).joining(", ") + "\nExpected range: " + startLine + "-" + endLine);
}
} else {
LOG.debug("Source check failed: method " + method.name() + " not found in sources");
}
if (!res) {
FileEditor editor = FileEditorManager.getInstance(project).getSelectedEditor(position.getFile().getVirtualFile());
if (editor instanceof TextEditor) {
AppUIUtil.invokeOnEdt(() -> HintManager.getInstance().showErrorHint(((TextEditor) editor).getEditor(), DebuggerBundle.message("warning.source.code.not.match")));
} else {
XDebugSessionImpl.NOTIFICATION_GROUP.createNotification(DebuggerBundle.message("warning.source.code.not.match"), NotificationType.WARNING).notify(project);
}
return ThreeState.NO;
}
return ThreeState.YES;
});
}
return ThreeState.YES;
}
use of com.intellij.psi.javadoc.PsiDocComment in project intellij-community by JetBrains.
the class EncapsulateFieldsProcessor method generateAccessors.
private void generateAccessors() {
// generate accessors
myNameToGetter = new HashMap<>();
myNameToSetter = new HashMap<>();
for (FieldDescriptor fieldDescriptor : myFieldDescriptors) {
final DocCommentPolicy<PsiDocComment> commentPolicy = new DocCommentPolicy<>(myDescriptor.getJavadocPolicy());
PsiField field = fieldDescriptor.getField();
final PsiDocComment docComment = field.getDocComment();
if (myDescriptor.isToEncapsulateGet()) {
final PsiMethod prototype = fieldDescriptor.getGetterPrototype();
assert prototype != null;
final PsiMethod getter = addOrChangeAccessor(prototype, myNameToGetter);
if (docComment != null) {
final PsiDocComment getterJavadoc = (PsiDocComment) getter.addBefore(docComment, getter.getFirstChild());
commentPolicy.processNewJavaDoc(getterJavadoc);
}
}
if (myDescriptor.isToEncapsulateSet() && !field.hasModifierProperty(PsiModifier.FINAL)) {
PsiMethod prototype = fieldDescriptor.getSetterPrototype();
assert prototype != null;
addOrChangeAccessor(prototype, myNameToSetter);
}
if (docComment != null) {
commentPolicy.processOldJavaDoc(docComment);
}
}
}
use of com.intellij.psi.javadoc.PsiDocComment in project intellij-community by JetBrains.
the class PsiDocParamRef method getReference.
@Override
public PsiReference getReference() {
final PsiDocComment comment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class);
if (comment == null)
return null;
final PsiJavaDocumentedElement owner = comment.getOwner();
if (!(owner instanceof PsiMethod) && !(owner instanceof PsiClass))
return null;
final ASTNode valueToken = findChildByType(JavaDocTokenType.DOC_TAG_VALUE_TOKEN);
if (valueToken == null)
return null;
final String name = valueToken.getText();
PsiElement reference = null;
final PsiElement firstChild = getFirstChild();
if (firstChild instanceof PsiDocToken && ((PsiDocToken) firstChild).getTokenType().equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) {
final PsiTypeParameter[] typeParameters = ((PsiTypeParameterListOwner) owner).getTypeParameters();
for (PsiTypeParameter typeParameter : typeParameters) {
if (typeParameter.getName().equals(name)) {
reference = typeParameter;
}
}
} else if (owner instanceof PsiMethod) {
final PsiParameter[] parameters = ((PsiMethod) owner).getParameterList().getParameters();
for (PsiParameter parameter : parameters) {
if (parameter.getName().equals(name)) {
reference = parameter;
}
}
}
final PsiElement resultReference = reference;
return new PsiJavaReference() {
@Override
public PsiElement resolve() {
return resultReference;
}
@Override
@NotNull
public String getCanonicalText() {
return valueToken.getText();
}
@Override
public PsiElement handleElementRename(String newElementName) {
final CharTable charTableByTree = SharedImplUtil.findCharTableByTree(getNode());
LeafElement newElement = Factory.createSingleLeafElement(JavaDocTokenType.DOC_TAG_VALUE_TOKEN, newElementName, charTableByTree, getManager());
replaceChild(valueToken, newElement);
return PsiDocParamRef.this;
}
@Override
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
if (isReferenceTo(element))
return PsiDocParamRef.this;
if (!(element instanceof PsiParameter)) {
throw new IncorrectOperationException("Unsupported operation");
}
return handleElementRename(((PsiParameter) element).getName());
}
@Override
public boolean isReferenceTo(PsiElement element) {
if (!(element instanceof PsiNamedElement))
return false;
PsiNamedElement namedElement = (PsiNamedElement) element;
if (!getCanonicalText().equals(namedElement.getName()))
return false;
return getManager().areElementsEquivalent(resolve(), element);
}
@Override
@NotNull
public PsiElement[] getVariants() {
final PsiElement firstChild = getFirstChild();
Set<String> usedNames = new HashSet<>();
for (PsiDocTag tag : comment.getTags()) {
if (tag.getName().equals("param")) {
PsiDocTagValue valueElement = tag.getValueElement();
if (valueElement != null) {
usedNames.add(valueElement.getText());
}
}
}
PsiNamedElement[] result = PsiNamedElement.EMPTY_ARRAY;
if (firstChild instanceof PsiDocToken && ((PsiDocToken) firstChild).getTokenType().equals(JavaDocTokenType.DOC_TAG_VALUE_LT)) {
result = ((PsiTypeParameterListOwner) owner).getTypeParameters();
} else if (owner instanceof PsiMethod) {
result = ((PsiMethod) owner).getParameterList().getParameters();
}
List<PsiElement> filtered = new ArrayList<>();
for (PsiNamedElement namedElement : result) {
if (!usedNames.contains(namedElement.getName())) {
filtered.add(namedElement);
}
}
return filtered.toArray(new PsiElement[filtered.size()]);
}
@Override
public boolean isSoft() {
return false;
}
@Override
public TextRange getRangeInElement() {
final int startOffsetInParent = valueToken.getPsi().getStartOffsetInParent();
return new TextRange(startOffsetInParent, startOffsetInParent + valueToken.getTextLength());
}
@Override
public PsiElement getElement() {
return PsiDocParamRef.this;
}
@Override
public void processVariants(@NotNull PsiScopeProcessor processor) {
for (final PsiElement element : getVariants()) {
if (!processor.execute(element, ResolveState.initial())) {
return;
}
}
}
@Override
@NotNull
public JavaResolveResult advancedResolve(boolean incompleteCode) {
return resultReference == null ? JavaResolveResult.EMPTY : new CandidateInfo(resultReference, PsiSubstitutor.EMPTY);
}
@Override
@NotNull
public JavaResolveResult[] multiResolve(boolean incompleteCode) {
return resultReference == null ? JavaResolveResult.EMPTY_ARRAY : new JavaResolveResult[] { new CandidateInfo(resultReference, PsiSubstitutor.EMPTY) };
}
};
}
use of com.intellij.psi.javadoc.PsiDocComment in project intellij-community by JetBrains.
the class PsiJavaCodeReferenceElementImpl method getKind.
public int getKind(@NotNull PsiFile containingFile) {
if (!containingFile.isValid()) {
// optimization to avoid relatively expensive this.isValid check
// but still provide diagnostics for this element and not its containing DummyHolder file
PsiUtilCore.ensureValid(this);
}
CompositeElement treeParent = getTreeParent();
IElementType i = treeParent.getElementType();
if (isDummy(i)) {
return myKindWhenDummy;
}
if (i == JavaElementType.TYPE) {
return treeParent.getTreeParent().getPsi() instanceof PsiTypeCodeFragment ? CLASS_OR_PACKAGE_NAME_KIND : CLASS_NAME_KIND;
}
if (i == JavaElementType.EXTENDS_LIST || i == JavaElementType.IMPLEMENTS_LIST || i == JavaElementType.EXTENDS_BOUND_LIST || i == JavaElementType.THROWS_LIST || i == JavaElementType.THIS_EXPRESSION || i == JavaElementType.SUPER_EXPRESSION || i == JavaDocElementType.DOC_METHOD_OR_FIELD_REF || i == JavaDocElementType.DOC_TAG_VALUE_ELEMENT || i == JavaElementType.REFERENCE_PARAMETER_LIST || i == JavaElementType.ANNOTATION) {
if (isQualified()) {
return CLASS_OR_PACKAGE_NAME_KIND;
}
return CLASS_NAME_KIND;
}
if (i == JavaElementType.NEW_EXPRESSION) {
final ASTNode qualifier = treeParent.findChildByRole(ChildRole.QUALIFIER);
return qualifier != null ? CLASS_IN_QUALIFIED_NEW_KIND : CLASS_NAME_KIND;
}
if (i == JavaElementType.ANONYMOUS_CLASS) {
if (treeParent.getChildRole(this) == ChildRole.BASE_CLASS_REFERENCE) {
LOG.assertTrue(treeParent.getTreeParent().getElementType() == JavaElementType.NEW_EXPRESSION);
final ASTNode qualifier = treeParent.getTreeParent().findChildByRole(ChildRole.QUALIFIER);
return qualifier != null ? CLASS_IN_QUALIFIED_NEW_KIND : CLASS_NAME_KIND;
} else {
// incomplete code
return CLASS_OR_PACKAGE_NAME_KIND;
}
}
if (i == JavaElementType.PACKAGE_STATEMENT || i == JavaElementType.EXPORTS_STATEMENT || i == JavaElementType.OPENS_STATEMENT) {
return PACKAGE_NAME_KIND;
}
if (i == JavaElementType.IMPORT_STATEMENT) {
boolean isOnDemand = SourceTreeToPsiMap.<PsiImportStatement>treeToPsiNotNull(treeParent).isOnDemand();
return isOnDemand ? CLASS_FQ_OR_PACKAGE_NAME_KIND : CLASS_FQ_NAME_KIND;
}
if (i == JavaElementType.IMPORT_STATIC_STATEMENT) {
return CLASS_FQ_OR_PACKAGE_NAME_KIND;
}
if (i == JavaElementType.JAVA_CODE_REFERENCE) {
int parentKind = ((PsiJavaCodeReferenceElementImpl) treeParent).getKind(containingFile);
if (parentKind == CLASS_NAME_KIND) {
return CLASS_OR_PACKAGE_NAME_KIND;
}
if (parentKind == CLASS_FQ_NAME_KIND) {
return CLASS_FQ_OR_PACKAGE_NAME_KIND;
}
return parentKind;
}
if (i == JavaElementType.CLASS || i == JavaElementType.PARAMETER_LIST || i == TokenType.ERROR_ELEMENT) {
return CLASS_OR_PACKAGE_NAME_KIND;
}
if (i == JavaElementType.IMPORT_STATIC_REFERENCE) {
return CLASS_FQ_OR_PACKAGE_NAME_KIND;
}
if (i == JavaDocElementType.DOC_TAG || i == JavaDocElementType.DOC_INLINE_TAG || i == JavaDocElementType.DOC_REFERENCE_HOLDER || i == JavaDocElementType.DOC_TYPE_HOLDER) {
PsiDocComment docComment = PsiTreeUtil.getParentOfType(this, PsiDocComment.class);
if (JavaDocUtil.isInsidePackageInfo(docComment)) {
return CLASS_FQ_OR_PACKAGE_NAME_KIND;
}
return CLASS_OR_PACKAGE_NAME_KIND;
}
if (isCodeFragmentType(i)) {
PsiJavaCodeReferenceCodeFragment fragment = (PsiJavaCodeReferenceCodeFragment) treeParent.getPsi();
return fragment.isClassesAccepted() ? CLASS_FQ_OR_PACKAGE_NAME_KIND : PACKAGE_NAME_KIND;
}
if (i == JavaElementType.USES_STATEMENT || i == JavaElementType.PROVIDES_STATEMENT || i == JavaElementType.PROVIDES_WITH_LIST) {
return CLASS_NAME_KIND;
}
diagnoseUnknownParent();
return CLASS_NAME_KIND;
}
Aggregations