private static TailType getReturnTail(PsiElement position) { PsiElement scope = position; while (true) { if (scope instanceof PsiFile || scope instanceof PsiClassInitializer) { return TailType.NONE; } if (scope instanceof PsiMethod) { final PsiMethod method = (PsiMethod) scope; if (method.isConstructor() || PsiType.VOID.equals(method.getReturnType())) { return TailType.SEMICOLON; } return TailType.HUMBLE_SPACE_BEFORE_WORD; } if (scope instanceof PsiLambdaExpression) { final PsiType returnType = LambdaUtil.getFunctionalInterfaceReturnType(((PsiLambdaExpression) scope)); if (PsiType.VOID.equals(returnType)) { return TailType.SEMICOLON; } return TailType.HUMBLE_SPACE_BEFORE_WORD; } scope = scope.getParent(); } }
@NotNull @Override public MyResult weigh(@NotNull LookupElement item) { final Object object = item.getObject(); if (object instanceof PsiClass) { if (object instanceof PsiTypeParameter) return MyResult.typeParameter; if (myTypeParameter != null && object.equals( PsiUtil.resolveClassInType( TypeConversionUtil.typeParameterErasure(myTypeParameter)))) { return MyResult.exactlyExpected; } } if (myExpectedTypes == null) return MyResult.normal; PsiType itemType = JavaCompletionUtil.getLookupElementType(item); if (itemType == null || !itemType.isValid()) return MyResult.normal; if (object instanceof PsiClass) { for (final ExpectedTypeInfo info : myExpectedTypes) { if (TypeConversionUtil.erasure(info.getType().getDeepComponentType()) .equals(TypeConversionUtil.erasure(itemType))) { return AbstractExpectedTypeSkipper.skips(item, myLocation) ? MyResult.expectedNoSelect : MyResult.exactlyExpected; } } } for (final ExpectedTypeInfo expectedInfo : myExpectedTypes) { final PsiType defaultType = expectedInfo.getDefaultType(); final PsiType expectedType = expectedInfo.getType(); if (!expectedType.isValid()) { return MyResult.normal; } if (defaultType != expectedType) { if (defaultType.equals(itemType)) { return MyResult.exactlyDefault; } if (defaultType.isAssignableFrom(itemType)) { return MyResult.ofDefaultType; } } if (PsiType.VOID.equals(itemType) && PsiType.VOID.equals(expectedType)) { return MyResult.exactlyExpected; } } return MyResult.normal; }
private static void suggestChainedCalls( CompletionParameters parameters, CompletionResultSet result, PsiElement position) { PsiElement parent = position.getParent(); if (!(parent instanceof PsiJavaCodeReferenceElement)) { return; } PsiElement qualifier = ((PsiJavaCodeReferenceElement) parent).getQualifier(); if (!(qualifier instanceof PsiJavaCodeReferenceElement) || ((PsiJavaCodeReferenceElement) qualifier).isQualified() || ((PsiJavaCodeReferenceElement) qualifier).resolve() != null) { return; } String fullPrefix = position .getContainingFile() .getText() .substring(parent.getTextRange().getStartOffset(), parameters.getOffset()); CompletionResultSet qualifiedCollector = result.withPrefixMatcher(fullPrefix); ElementFilter filter = JavaCompletionContributor.getReferenceFilter(position); for (LookupElement base : suggestQualifierItems(parameters, (PsiJavaCodeReferenceElement) qualifier, filter)) { PsiType type = JavaCompletionUtil.getLookupElementType(base); if (type != null && !PsiType.VOID.equals(type)) { PsiReferenceExpression ref = ReferenceExpressionCompletionContributor.createMockReference(position, type, base); for (final LookupElement item : JavaSmartCompletionContributor.completeReference( position, ref, filter, true, true, parameters, result.getPrefixMatcher())) { qualifiedCollector.addElement(new JavaChainLookupElement(base, item)); } } } }
@Nullable public static HighlightInfo checkMissingReturnStatement(PsiCodeBlock body, PsiType returnType) { if (body == null || returnType == null || PsiType.VOID.equals(returnType.getDeepComponentType())) { return null; } // do not compute constant expressions for if() statement condition // see JLS 14.20 Unreachable Statements try { ControlFlow controlFlow = getControlFlowNoConstantEvaluate(body); if (!ControlFlowUtil.returnPresent(controlFlow)) { PsiJavaToken rBrace = body.getRBrace(); PsiElement context = rBrace == null ? body.getLastChild() : rBrace; String message = JavaErrorMessages.message("missing.return.statement"); HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR) .range(context) .descriptionAndTooltip(message) .create(); PsiElement parent = body.getParent(); if (parent instanceof PsiMethod) { PsiMethod method = (PsiMethod) parent; QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createAddReturnFix(method)); QuickFixAction.registerQuickFixAction( info, QUICK_FIX_FACTORY.createMethodReturnFix(method, PsiType.VOID, true)); } return info; } } catch (AnalysisCanceledException ignored) { } return null; }
public static PsiType getType(@NotNull PsiClassObjectAccessExpression classAccessExpression) { GlobalSearchScope resolveScope = classAccessExpression.getResolveScope(); PsiManager manager = classAccessExpression.getManager(); final PsiClass classClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.lang.Class", resolveScope); if (classClass == null) { return new PsiClassReferenceType( new LightClassReference(manager, "Class", "java.lang.Class", resolveScope), null); } if (!PsiUtil.isLanguageLevel5OrHigher(classAccessExpression)) { // Raw java.lang.Class return JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createType(classClass); } PsiSubstitutor substitutor = PsiSubstitutor.EMPTY; PsiType operandType = classAccessExpression.getOperand().getType(); if (operandType instanceof PsiPrimitiveType && !PsiType.NULL.equals(operandType)) { if (PsiType.VOID.equals(operandType)) { operandType = JavaPsiFacade.getInstance(manager.getProject()) .getElementFactory() .createTypeByFQClassName("java.lang.Void", classAccessExpression.getResolveScope()); } else { operandType = ((PsiPrimitiveType) operandType).getBoxedType(classAccessExpression); } } final PsiTypeParameter[] typeParameters = classClass.getTypeParameters(); if (typeParameters.length == 1) { substitutor = substitutor.put(typeParameters[0], operandType); } return new PsiImmediateClassType(classClass, substitutor); }
private static boolean generateDelegate(GrChangeInfoImpl grInfo) { final GrMethod method = grInfo.getMethod(); final PsiClass psiClass = method.getContainingClass(); GrMethod newMethod = (GrMethod) method.copy(); newMethod = (GrMethod) psiClass.addAfter(newMethod, method); StringBuilder buffer = new StringBuilder(); buffer.append("\n"); if (method.isConstructor()) { buffer.append("this"); } else { if (!PsiType.VOID.equals(method.getReturnType())) { buffer.append("return "); } buffer.append( GrChangeSignatureUtil.getNameWithQuotesIfNeeded( grInfo.getNewName(), method.getProject())); } generateParametersForDelegateCall(grInfo, method, buffer); final GrCodeBlock codeBlock = GroovyPsiElementFactory.getInstance(method.getProject()) .createMethodBodyFromText(buffer.toString()); newMethod.setBlock(codeBlock); newMethod.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, false); CodeStyleManager.getInstance(method.getProject()).reformat(newMethod); return processPrimaryMethodInner(grInfo, method, null); }
@Override public boolean isApplicable( @NotNull PsiElement context, @NotNull Document copyDocument, int newOffset) { PsiExpression expr = getTopmostExpression(context); if (expr == null || !(expr.getParent() instanceof PsiExpressionStatement)) return false; PsiType type = expr.getType(); return type != null && !PsiType.VOID.equals(type); }
private static boolean hasNonVoid(ExpectedTypeInfo[] expectedInfos) { boolean hasNonVoid = false; for (ExpectedTypeInfo info : expectedInfos) { if (!PsiType.VOID.equals(info.getType())) { hasNonVoid = true; } } return hasNonVoid; }
/** * Sets the basic element information from the given type. * * @param element the element to set information from the type * @param factory * @param type the type * @param modifiers modifier list * @since 2.15 */ private static void setElementInfo( AbstractElement element, PsiElementFactory factory, PsiType type, PsiModifierList modifiers) { // type names element.setTypeName(PsiAdapter.getTypeClassName(type)); element.setTypeQualifiedName(PsiAdapter.getTypeQualifiedClassName(type)); element.setType(type.getCanonicalText()); // arrays, collections and maps types if (PsiAdapter.isObjectArrayType(type)) { element.setObjectArray(true); element.setArray(true); // additional specify if the element is a string array if (PsiAdapter.isStringArrayType(type)) element.setStringArray(true); } else if (PsiAdapter.isPrimitiveArrayType(type)) { element.setPrimitiveArray(true); element.setArray(true); } if (PsiAdapter.isCollectionType(factory, type)) element.setCollection(true); if (PsiAdapter.isListType(factory, type)) element.setList(true); if (PsiAdapter.isSetType(factory, type)) element.setSet(true); if (PsiAdapter.isMapType(factory, type)) element.setMap(true); // other types if (PsiAdapter.isPrimitiveType(type)) element.setPrimitive(true); if (PsiAdapter.isObjectType(factory, type)) element.setObject(true); if (PsiAdapter.isStringType(factory, type)) element.setString(true); if (PsiAdapter.isNumericType(factory, type)) element.setNumeric(true); if (PsiAdapter.isDateType(factory, type)) element.setDate(true); if (PsiAdapter.isCalendarType(factory, type)) element.setCalendar(true); if (PsiAdapter.isBooleanType(factory, type)) element.setBoolean(true); if (PsiType.VOID.equals(type)) element.setVoid(true); if (PsiType.LONG.equals(type)) element.setLong(true); if (PsiType.FLOAT.equals(type)) element.setFloat(true); if (PsiType.DOUBLE.equals(type)) element.setDouble(true); if (PsiType.BYTE.equals(type)) element.setByte(true); if (PsiType.CHAR.equals(type)) element.setChar(true); if (PsiType.SHORT.equals(type)) element.setShort(true); element.setNestedArray(PsiAdapter.isNestedArray(type)); // modifiers if (modifiers != null) { if (modifiers.hasModifierProperty(PsiModifier.STATIC)) element.setModifierStatic(true); if (modifiers.hasModifierProperty(PsiModifier.FINAL)) element.setModifierFinal(true); if (modifiers.hasModifierProperty(PsiModifier.PUBLIC)) { element.setModifierPublic(true); } else if (modifiers.hasModifierProperty(PsiModifier.PROTECTED)) { element.setModifierProtected(true); } else if (modifiers.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { element.setModifierPackageLocal(true); } else if (modifiers.hasModifierProperty(PsiModifier.PRIVATE)) element.setModifierPrivate(true); } }
@Override protected void initialize() { final PsiMethod method = (PsiMethod) getElement(); LOG.assertTrue(method != null); setConstructor(method.isConstructor()); final PsiType returnType = method.getReturnType(); setFlag( returnType == null || PsiType.VOID.equals(returnType) || returnType.equalsToText(CommonClassNames.JAVA_LANG_VOID), IS_RETURN_VALUE_USED_MASK); if (!isReturnValueUsed()) { myReturnValueTemplate = RETURN_VALUE_UNDEFINED; } if (isConstructor()) { addReference(getOwnerClass(), getOwnerClass().getElement(), method, false, true, null); } if (getOwnerClass().isInterface()) { setAbstract(false); } else { setAbstract(method.hasModifierProperty(PsiModifier.ABSTRACT)); } setAppMain(isAppMain(method, this)); setLibraryOverride(method.hasModifierProperty(PsiModifier.NATIVE)); initializeSuperMethods(method); if (isExternalOverride()) { ((RefClassImpl) getOwnerClass()).addLibraryOverrideMethod(this); } @NonNls final String name = method.getName(); if (getOwnerClass().isTestCase() && name.startsWith("test")) { setTestMethod(true); } PsiParameter[] paramList = method.getParameterList().getParameters(); if (paramList.length > 0) { myParameters = new RefParameterImpl[paramList.length]; for (int i = 0; i < paramList.length; i++) { PsiParameter parameter = paramList[i]; myParameters[i] = getRefJavaManager().getParameterReference(parameter, i); } } if (method.hasModifierProperty(PsiModifier.NATIVE)) { updateReturnValueTemplate(null); updateThrowsList(null); } collectUncaughtExceptions(method); }
@Override public void invoke( @NotNull Project project, @NotNull PsiFile file, Editor editor, @NotNull PsiElement startElement, @NotNull PsiElement endElement) { final PsiMethod myMethod = (PsiMethod) startElement; if (!FileModificationService.getInstance().prepareFileForWrite(myMethod.getContainingFile())) return; final PsiType myReturnType = myReturnTypePointer.getType(); if (myReturnType == null) return; if (myFixWholeHierarchy) { final PsiMethod superMethod = myMethod.findDeepestSuperMethod(); final PsiType superReturnType = superMethod == null ? null : superMethod.getReturnType(); if (superReturnType != null && !Comparing.equal(myReturnType, superReturnType) && !changeClassTypeArgument( myMethod, project, superReturnType, superMethod.getContainingClass(), editor, myReturnType)) { return; } } final List<PsiMethod> affectedMethods = changeReturnType(myMethod, myReturnType); PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory(); PsiReturnStatement statementToSelect = null; if (!PsiType.VOID.equals(myReturnType)) { final ReturnStatementAdder adder = new ReturnStatementAdder(factory, myReturnType); for (PsiMethod affectedMethod : affectedMethods) { PsiReturnStatement statement = adder.addReturnForMethod(file, affectedMethod); if (statement != null && affectedMethod == myMethod) { statementToSelect = statement; } } } if (statementToSelect != null) { Editor editorForMethod = getEditorForMethod(myMethod, project, editor, statementToSelect.getContainingFile()); if (editorForMethod != null) { selectReturnValueInEditor(statementToSelect, editorForMethod); } } }
@NotNull public static PsiPrimitiveType getPrimitiveTypeByText(String typeText) { for (final PsiPrimitiveType primitive : PRIMITIVES) { if (PsiType.VOID.equals(primitive)) { return primitive; } if (primitive.getCanonicalText().equals(typeText)) { return primitive; } } assert false : "Unknown primitive type"; return null; }
public static String[] suggestVariableNames( @NotNull GrExpression expr, NameValidator validator, boolean forStaticVariable) { Set<String> possibleNames = new LinkedHashSet<String>(); PsiType type = expr.getType(); generateNameByExpr(expr, possibleNames, validator, forStaticVariable); if (type != null && !PsiType.VOID.equals(type)) { generateVariableNameByTypeInner(type, possibleNames, validator); } possibleNames.remove(""); if (possibleNames.isEmpty()) { possibleNames.add(validator.validateName("var", true)); } return ArrayUtil.toStringArray(possibleNames); }
private static boolean isAppMain(PsiMethod psiMethod, RefMethod refMethod) { if (!refMethod.isStatic()) return false; if (!PsiType.VOID.equals(psiMethod.getReturnType())) return false; PsiMethod appMainPattern = ((RefMethodImpl) refMethod).getRefJavaManager().getAppMainPattern(); if (MethodSignatureUtil.areSignaturesEqual(psiMethod, appMainPattern)) return true; PsiMethod appPremainPattern = ((RefMethodImpl) refMethod).getRefJavaManager().getAppPremainPattern(); if (MethodSignatureUtil.areSignaturesEqual(psiMethod, appPremainPattern)) return true; PsiMethod appAgentmainPattern = ((RefMethodImpl) refMethod).getRefJavaManager().getAppAgentmainPattern(); return MethodSignatureUtil.areSignaturesEqual(psiMethod, appAgentmainPattern); }
@Override public String generateDocumentationContentStub(PsiComment contextComment) { if (!(contextComment instanceof GrDocComment)) { return null; } final GrDocCommentOwner owner = GrDocCommentUtil.findDocOwner((GrDocComment) contextComment); if (owner == null) return null; Project project = contextComment.getProject(); final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter) LanguageCommenters.INSTANCE.forLanguage(owner.getLanguage()); StringBuilder builder = StringBuilderSpinAllocator.alloc(); try { if (owner instanceof GrMethod) { final GrMethod method = (GrMethod) owner; JavaDocumentationProvider.generateParametersTakingDocFromSuperMethods( project, builder, commenter, method); final PsiType returnType = method.getInferredReturnType(); if ((returnType != null || method.getModifierList().hasModifierProperty(GrModifier.DEF)) && !PsiType.VOID.equals(returnType)) { builder.append( CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter)); builder.append(LINE_SEPARATOR); } final PsiClassType[] references = method.getThrowsList().getReferencedTypes(); for (PsiClassType reference : references) { builder.append( CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter)); builder.append(reference.getClassName()); builder.append(LINE_SEPARATOR); } } else if (owner instanceof GrTypeDefinition) { final PsiTypeParameterList typeParameterList = ((PsiClass) owner).getTypeParameterList(); if (typeParameterList != null) { JavaDocumentationProvider.createTypeParamsListComment( builder, project, commenter, typeParameterList); } } return builder.length() > 0 ? builder.toString() : null; } finally { StringBuilderSpinAllocator.dispose(builder); } }
@Override public void visitExpressionStatement(@NotNull PsiExpressionStatement statement) { super.visitExpressionStatement(statement); final PsiExpression expression = statement.getExpression(); if (!(expression instanceof PsiMethodCallExpression)) { return; } final PsiMethodCallExpression call = (PsiMethodCallExpression) expression; final PsiMethod method = call.resolveMethod(); if (method == null || method.isConstructor()) { return; } final PsiType returnType = method.getReturnType(); if (PsiType.VOID.equals(returnType)) { return; } final PsiClass aClass = method.getContainingClass(); if (aClass == null) { return; } if (PsiUtilCore.hasErrorElementChild(statement)) { return; } if (m_reportAllNonLibraryCalls && !LibraryUtil.classIsInLibrary(aClass)) { registerMethodCallError(call, aClass); return; } final PsiReferenceExpression methodExpression = call.getMethodExpression(); final String methodName = methodExpression.getReferenceName(); if (methodName == null) { return; } for (int i = 0; i < methodNamePatterns.size(); i++) { final String methodNamePattern = methodNamePatterns.get(i); if (!methodNamesMatch(methodName, methodNamePattern)) { continue; } final String className = classNames.get(i); if (!InheritanceUtil.isInheritor(aClass, className)) { continue; } registerMethodCallError(call, aClass); return; } }
public static boolean isJUnitTestMethod(PsiMethod method) { //noinspection HardCodedStringLiteral if (AnnotationUtil.isAnnotated(method, "org.junit.Test", true)) { return true; } final PsiType returnType = method.getReturnType(); if (!PsiType.VOID.equals(returnType)) { return false; } if (!method.hasModifierProperty(PsiModifier.PUBLIC)) { return false; } @NonNls final String methodName = method.getName(); if (!methodName.startsWith("test")) { return false; } final PsiClass containingClass = method.getContainingClass(); return containingClass != null && isJUnitTestCase(containingClass); }
public static boolean insertTail( InsertionContext context, LookupElement item, TailType tailType, boolean hasTail) { TailType toInsert = tailType; LookupItem<?> lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY); if (lookupItem == null || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) { if (!hasTail && item.getObject() instanceof PsiMethod && PsiType.VOID.equals(((PsiMethod) item.getObject()).getReturnType())) { PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments(); if (psiElement() .beforeLeaf(psiElement().withText(".")) .accepts(context.getFile().findElementAt(context.getTailOffset() - 1))) { return false; } boolean insertAdditionalSemicolon = true; final PsiReferenceExpression referenceExpression = PsiTreeUtil.getTopmostParentOfType( context.getFile().findElementAt(context.getStartOffset()), PsiReferenceExpression.class); if (referenceExpression instanceof PsiMethodReferenceExpression && LambdaHighlightingUtil.insertSemicolon(referenceExpression.getParent())) { insertAdditionalSemicolon = false; } else if (referenceExpression != null) { PsiElement parent = referenceExpression.getParent(); if (parent instanceof PsiMethodCallExpression) { parent = parent.getParent(); } if (parent instanceof PsiLambdaExpression && !LambdaHighlightingUtil.insertSemicolonAfter((PsiLambdaExpression) parent)) { insertAdditionalSemicolon = false; } } if (insertAdditionalSemicolon) { toInsert = TailType.SEMICOLON; } } } toInsert.processTail(context.getEditor(), context.getTailOffset()); return true; }
public static boolean inferPurity(@NotNull final PsiMethod method) { if (!InferenceFromSourceUtil.shouldInferFromSource(method) || PsiType.VOID.equals(method.getReturnType()) || method.isConstructor()) { return false; } return CachedValuesManager.getCachedValue( method, () -> { MethodData data = ContractInferenceIndexKt.getIndexedData(method); PurityInferenceResult result = data == null ? null : data.getPurity(); Boolean pure = RecursionManager.doPreventingRecursion( method, true, () -> result != null && result.isPure(method, data.methodBody(method))); return CachedValueProvider.Result.create(pure == Boolean.TRUE, method); }); }
public static boolean isMainOrPremainMethod(@NotNull PsiMethod method) { if (!PsiType.VOID.equals(method.getReturnType())) return false; String name = method.getName(); if (!("main".equals(name) || "premain".equals(name))) return false; PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory(); MethodSignature signature = method.getSignature(PsiSubstitutor.EMPTY); try { MethodSignature main = createSignatureFromText(factory, "void main(String[] args);"); if (MethodSignatureUtil.areSignaturesEqual(signature, main)) return true; MethodSignature premain = createSignatureFromText( factory, "void premain(String args, java.lang.instrument.Instrumentation i);"); if (MethodSignatureUtil.areSignaturesEqual(signature, premain)) return true; } catch (IncorrectOperationException e) { LOG.error(e); } return false; }
@Nullable public static PsiField findPropertyFieldByMember(final PsiMember psiMember) { if (psiMember instanceof PsiField) { return (PsiField) psiMember; } else if (psiMember instanceof PsiMethod) { final PsiMethod psiMethod = (PsiMethod) psiMember; final PsiType returnType = psiMethod.getReturnType(); if (returnType == null) return null; final PsiCodeBlock body = psiMethod.getBody(); final PsiStatement[] statements = body == null ? null : body.getStatements(); final PsiStatement statement = statements == null || statements.length != 1 ? null : statements[0]; final PsiElement target; if (PsiType.VOID.equals(returnType)) { final PsiExpression expression = statement instanceof PsiExpressionStatement ? ((PsiExpressionStatement) statement).getExpression() : null; target = expression instanceof PsiAssignmentExpression ? ((PsiAssignmentExpression) expression).getLExpression() : null; } else { target = statement instanceof PsiReturnStatement ? ((PsiReturnStatement) statement).getReturnValue() : null; } final PsiElement resolved = target instanceof PsiReferenceExpression ? ((PsiReferenceExpression) target).resolve() : null; if (resolved instanceof PsiField) { final PsiField field = (PsiField) resolved; if (psiMember.getContainingClass() == field.getContainingClass() || psiMember.getContainingClass().isInheritor(field.getContainingClass(), true)) return field; } } return null; }
@SuppressWarnings({"HardCodedStringLiteral"}) public static boolean hasGetterName(final PsiMethod method) { if (method == null) return false; if (method.isConstructor()) return false; String methodName = method.getName(); PsiType returnType = method.getReturnType(); if (methodName.startsWith("get") && methodName.length() > "get".length()) { if (Character.isLowerCase(methodName.charAt("get".length())) && (methodName.length() == "get".length() + 1 || Character.isLowerCase(methodName.charAt("get".length() + 1)))) { return false; } if (returnType != null && PsiType.VOID.equals(returnType)) return false; } else if (methodName.startsWith("is")) { return isBoolean(returnType); } else { return false; } return true; }
private boolean hasOnlyMain(PsiClass aClass) { final PsiMethod[] methods = aClass.getMethods(); if (methods.length == 0) { return false; } for (PsiMethod method : methods) { if (method.isConstructor()) { continue; } if (!method.hasModifierProperty(PsiModifier.STATIC)) { return false; } if (method.hasModifierProperty(PsiModifier.PRIVATE)) { continue; } if (!method.hasModifierProperty(PsiModifier.PUBLIC)) { return false; } final String name = method.getName(); if (!name.equals(HardcodedMethodConstants.MAIN)) { return false; } final PsiType returnType = method.getReturnType(); if (!PsiType.VOID.equals(returnType)) { return false; } final PsiParameterList parameterList = method.getParameterList(); if (parameterList.getParametersCount() != 1) { return false; } final PsiParameter[] parameters = parameterList.getParameters(); final PsiParameter parameter = parameters[0]; final PsiType type = parameter.getType(); if (!type.equalsToText("java.lang.String[]")) { return false; } } return true; }
private static ExpectedTypeMatching getExpectedTypeMatching( LookupElement item, ExpectedTypeInfo[] expectedInfos) { PsiType itemType = JavaCompletionUtil.getLookupElementType(item); if (itemType != null) { for (final ExpectedTypeInfo expectedInfo : expectedInfos) { final PsiType defaultType = expectedInfo.getDefaultType(); final PsiType expectedType = expectedInfo.getType(); if (defaultType != expectedType && defaultType.isAssignableFrom(itemType)) { return ExpectedTypeMatching.ofDefaultType; } if (expectedType.isAssignableFrom(itemType)) { return ExpectedTypeMatching.expected; } } } boolean hasNonVoid = false; for (ExpectedTypeInfo info : expectedInfos) { if (!PsiType.VOID.equals(info.getType())) { hasNonVoid = true; } } if (hasNonVoid) { if (item.getObject() instanceof PsiKeyword) { String keyword = ((PsiKeyword) item.getObject()).getText(); if (PsiKeyword.NEW.equals(keyword) || PsiKeyword.NULL.equals(keyword)) { return ExpectedTypeMatching.maybeExpected; } } } else if (expectedInfos.length > 0) { return ExpectedTypeMatching.unexpected; } return ExpectedTypeMatching.normal; }
@NotNull private static GrStatement[] createResultStatement(ExtractInfoHelper helper) { VariableInfo[] outputVars = helper.getOutputVariableInfos(); PsiType type = helper.getOutputType(); GrStatement[] statements = helper.getStatements(); GrMethodCallExpression callExpression = createMethodCall(helper); if ((outputVars.length == 0 || PsiType.VOID.equals(type)) && !helper.hasReturnValue()) return new GrStatement[] {callExpression}; GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(helper.getProject()); if (helper.hasReturnValue()) { return new GrStatement[] { factory.createStatementFromText("return " + callExpression.getText()) }; } LOG.assertTrue(outputVars.length > 0); final List<VariableInfo> mustAdd = mustAddVariableDeclaration(statements, outputVars); if (mustAdd.size() == 0) { return new GrStatement[] {createAssignment(outputVars, callExpression, helper.getProject())}; } else if (mustAdd.size() == outputVars.length && outputVars.length == 1) { return new GrVariableDeclaration[] { factory.createVariableDeclaration( ArrayUtil.EMPTY_STRING_ARRAY, callExpression, outputVars[0].getType(), outputVars[0].getName()) }; } else if (varsAreEqual(mustAdd, outputVars)) { return createTupleDeclaration(outputVars, callExpression, helper.getProject()); } else { final List<GrStatement> result = generateVarDeclarations(mustAdd, helper.getProject(), null); result.add(createAssignment(outputVars, callExpression, helper.getProject())); return result.toArray(new GrStatement[result.size()]); } }
@SuppressWarnings({"HardCodedStringLiteral"}) public static String getPrimitiveSignature(String typeName) { if (PsiType.BOOLEAN.getCanonicalText().equals(typeName)) { return "Z"; } else if (PsiType.BYTE.getCanonicalText().equals(typeName)) { return "B"; } else if (PsiType.CHAR.getCanonicalText().equals(typeName)) { return "C"; } else if (PsiType.SHORT.getCanonicalText().equals(typeName)) { return "S"; } else if (PsiType.INT.getCanonicalText().equals(typeName)) { return "I"; } else if (PsiType.LONG.getCanonicalText().equals(typeName)) { return "J"; } else if (PsiType.FLOAT.getCanonicalText().equals(typeName)) { return "F"; } else if (PsiType.DOUBLE.getCanonicalText().equals(typeName)) { return "D"; } else if (PsiType.VOID.getCanonicalText().equals(typeName)) { return "V"; } return null; }
@SuppressWarnings("HardCodedStringLiteral") public static boolean isSimplePropertySetter(PsiMethod method) { if (method == null) return false; if (method.isConstructor()) return false; String methodName = method.getName(); if (!(methodName.startsWith("set") && methodName.length() > "set".length())) return false; if (Character.isLowerCase(methodName.charAt("set".length()))) return false; if (method.getParameterList().getParametersCount() != 1) { return false; } final PsiType returnType = method.getReturnType(); if (returnType == null || PsiType.VOID.equals(returnType)) { return true; } return Comparing.equal(PsiUtil.resolveClassInType(returnType), method.getContainingClass()); }
@Override public boolean reduce(InferenceSession session, List<ConstraintFormula> constraints) { if (!LambdaUtil.isFunctionalType(myT)) { return false; } final PsiType groundTargetType = FunctionalInterfaceParameterizationUtil.getGroundTargetType(myT); final PsiClassType.ClassResolveResult classResolveResult = PsiUtil.resolveGenericsClassInType(groundTargetType); final PsiMethod interfaceMethod = LambdaUtil.getFunctionalInterfaceMethod(classResolveResult); if (interfaceMethod == null) { return false; } final PsiSubstitutor substitutor = LambdaUtil.getSubstitutor(interfaceMethod, classResolveResult); final PsiParameter[] targetParameters = interfaceMethod.getParameterList().getParameters(); final PsiType interfaceMethodReturnType = interfaceMethod.getReturnType(); final PsiType returnType = substitutor.substitute(interfaceMethodReturnType); final PsiType[] typeParameters = myExpression.getTypeParameters(); final PsiMethodReferenceUtil.QualifierResolveResult qualifierResolveResult = PsiMethodReferenceUtil.getQualifierResolveResult(myExpression); if (!myExpression.isExact()) { for (PsiParameter parameter : targetParameters) { if (!session.isProperType(substitutor.substitute(parameter.getType()))) { return false; } } } else { final PsiMember applicableMember = myExpression.getPotentiallyApplicableMember(); LOG.assertTrue(applicableMember != null); final PsiClass applicableMemberContainingClass = applicableMember.getContainingClass(); final PsiClass containingClass = qualifierResolveResult.getContainingClass(); PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor(); psiSubstitutor = applicableMemberContainingClass == null || containingClass == null || myExpression.isConstructor() ? psiSubstitutor : TypeConversionUtil.getSuperClassSubstitutor( applicableMemberContainingClass, containingClass, psiSubstitutor); PsiType applicableMethodReturnType = applicableMember instanceof PsiMethod ? ((PsiMethod) applicableMember).getReturnType() : null; int idx = 0; for (PsiTypeParameter param : ((PsiTypeParameterListOwner) applicableMember).getTypeParameters()) { if (idx < typeParameters.length) { psiSubstitutor = psiSubstitutor.put(param, typeParameters[idx++]); } } final PsiParameter[] parameters = applicableMember instanceof PsiMethod ? ((PsiMethod) applicableMember).getParameterList().getParameters() : PsiParameter.EMPTY_ARRAY; if (targetParameters.length == parameters.length + 1) { specialCase(session, constraints, substitutor, targetParameters, true); for (int i = 1; i < targetParameters.length; i++) { constraints.add( new TypeCompatibilityConstraint( session.substituteWithInferenceVariables( psiSubstitutor.substitute(parameters[i - 1].getType())), substitutor.substitute(targetParameters[i].getType()))); } } else if (targetParameters.length == parameters.length) { for (int i = 0; i < targetParameters.length; i++) { constraints.add( new TypeCompatibilityConstraint( session.substituteWithInferenceVariables( psiSubstitutor.substitute(parameters[i].getType())), substitutor.substitute(targetParameters[i].getType()))); } } else { return false; } if (returnType != PsiType.VOID && returnType != null) { if (applicableMethodReturnType == PsiType.VOID) { return false; } if (applicableMethodReturnType != null) { constraints.add( new TypeCompatibilityConstraint( returnType, session.substituteWithInferenceVariables( psiSubstitutor.substitute(applicableMethodReturnType)))); } else if (applicableMember instanceof PsiClass || applicableMember instanceof PsiMethod && ((PsiMethod) applicableMember).isConstructor()) { final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(applicableMember.getProject()); if (containingClass != null) { final PsiType classType = session.substituteWithInferenceVariables( elementFactory.createType(containingClass, psiSubstitutor)); constraints.add(new TypeCompatibilityConstraint(returnType, classType)); } } } return true; } final Map<PsiElement, PsiType> map = LambdaUtil.getFunctionalTypeMap(); final PsiType added = map.put(myExpression, session.startWithFreshVars(groundTargetType)); final JavaResolveResult resolve; try { resolve = myExpression.advancedResolve(true); } finally { if (added == null) { map.remove(myExpression); } } final PsiElement element = resolve.getElement(); if (element == null) { return false; } if (PsiType.VOID.equals(returnType) || returnType == null) { return true; } if (element instanceof PsiMethod) { final PsiMethod method = (PsiMethod) element; final PsiType referencedMethodReturnType; final PsiClass containingClass = method.getContainingClass(); LOG.assertTrue(containingClass != null, method); PsiClass qContainingClass = qualifierResolveResult.getContainingClass(); PsiSubstitutor psiSubstitutor = qualifierResolveResult.getSubstitutor(); if (qContainingClass != null) { if (PsiUtil.isRawSubstitutor(qContainingClass, psiSubstitutor)) { psiSubstitutor = PsiSubstitutor.EMPTY; } if (qContainingClass.isInheritor(containingClass, true)) { psiSubstitutor = TypeConversionUtil.getClassSubstitutor( containingClass, qContainingClass, PsiSubstitutor.EMPTY); LOG.assertTrue(psiSubstitutor != null); } } if (method.isConstructor()) { referencedMethodReturnType = JavaPsiFacade.getElementFactory(method.getProject()) .createType(containingClass, PsiSubstitutor.EMPTY); } else { referencedMethodReturnType = method.getReturnType(); } LOG.assertTrue(referencedMethodReturnType != null, method); if (!PsiTreeUtil.isContextAncestor(containingClass, myExpression, false) || PsiUtil.getEnclosingStaticElement(myExpression, containingClass) != null) { session.initBounds(myExpression, containingClass.getTypeParameters()); } session.initBounds(myExpression, method.getTypeParameters()); // if i) the method reference elides NonWildTypeArguments, // ii) the compile-time declaration is a generic method, and // iii) the return type of the compile-time declaration mentions at least one of the method's // type parameters; if (typeParameters.length == 0 && method.getTypeParameters().length > 0) { final PsiClass interfaceClass = classResolveResult.getElement(); LOG.assertTrue(interfaceClass != null); if (PsiPolyExpressionUtil.mentionsTypeParameters( referencedMethodReturnType, ContainerUtil.newHashSet(method.getTypeParameters()))) { // the constraint reduces to the bound set B3 which would be used to determine the method // reference's invocation type // when targeting the return type of the function type, as defined in 18.5.2. session.collectApplicabilityConstraints( myExpression, ((MethodCandidateInfo) resolve), groundTargetType); session.registerReturnTypeConstraints(referencedMethodReturnType, returnType); return true; } } if (PsiType.VOID.equals(referencedMethodReturnType)) { return false; } int idx = 0; for (PsiTypeParameter param : method.getTypeParameters()) { if (idx < typeParameters.length) { psiSubstitutor = psiSubstitutor.put(param, typeParameters[idx++]); } } final PsiParameter[] parameters = method.getParameterList().getParameters(); if (targetParameters.length == parameters.length + 1 && !method.isVarArgs() && PsiPolyExpressionUtil.mentionsTypeParameters( referencedMethodReturnType, ContainerUtil.newHashSet( containingClass.getTypeParameters()))) { // todo specification bug? specialCase(session, constraints, substitutor, targetParameters, false); } constraints.add( new TypeCompatibilityConstraint( returnType, session.substituteWithInferenceVariables( psiSubstitutor.substitute(referencedMethodReturnType)))); } return true; }
@Override protected void init() { super.init(); JavaRefactoringSettings settings = JavaRefactoringSettings.getInstance(); initReplaceFieldsWithGetters(settings); myDeclareFinalCheckBox.setSelected(hasFinalModifier()); myDelegateViaOverloadingMethodCheckBox.setVisible(myInfo.getToSearchFor() != null); setTitle(RefactoringBundle.message("introduce.parameter.title")); myTable.init(myInfo); final GrParameter[] parameters = myInfo.getToReplaceIn().getParameters(); toRemoveCBs.forEachEntry( new TObjectIntProcedure<JCheckBox>() { @Override public boolean execute(JCheckBox checkbox, int index) { checkbox.setSelected(true); final GrParameter param = parameters[index]; final ParameterInfo pinfo = findParamByOldName(param.getName()); if (pinfo != null) { pinfo.setPassAsParameter(false); } return true; } }); updateSignature(); if (myCanIntroduceSimpleParameter) { mySignaturePanel.setVisible(false); // action to hide signature panel if we have variants to introduce simple parameter myTypeComboBox.addItemListener( new ItemListener() { @Override public void itemStateChanged(ItemEvent e) { mySignaturePanel.setVisible(myTypeComboBox.isClosureSelected()); pack(); } }); } final PsiType closureReturnType = inferClosureReturnType(); if (PsiType.VOID.equals(closureReturnType)) { myForceReturnCheckBox.setEnabled(false); myForceReturnCheckBox.setSelected(false); } else { myForceReturnCheckBox.setSelected(isForceReturn()); } if (myInfo.getToReplaceIn() instanceof GrClosableBlock) { myDelegateViaOverloadingMethodCheckBox.setEnabled(false); myDelegateViaOverloadingMethodCheckBox.setToolTipText( "Delegating is not allowed in closure context"); } pack(); }
@Override public Boolean visitPrimitiveType(PsiPrimitiveType primitiveType) { return PsiType.VOID.equals(primitiveType) || PsiType.NULL.equals(primitiveType) ? Boolean.FALSE : Boolean.TRUE; }