Search in sources :

Example 1 with CodeGenerationSettings

use of org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings in project eclipse.jdt.ls by eclipse.

the class AnonymousTypeCompletionProposal method createNewBody.

private String createNewBody(ImportRewrite importRewrite) throws CoreException {
    if (importRewrite == null) {
        return null;
    }
    ICompilationUnit workingCopy = null;
    try {
        // $NON-NLS-1$
        String name = "Type" + System.currentTimeMillis();
        workingCopy = fCompilationUnit.getPrimary().getWorkingCopy(null);
        ISourceRange range = fSuperType.getSourceRange();
        boolean sameUnit = range != null && fCompilationUnit.equals(fSuperType.getCompilationUnit());
        String dummyClassContent = createDummyType(name);
        StringBuffer workingCopyContents = new StringBuffer(fCompilationUnit.getSource());
        int insertPosition;
        if (sameUnit) {
            insertPosition = range.getOffset() + range.getLength();
        } else {
            ISourceRange firstTypeRange = fCompilationUnit.getTypes()[0].getSourceRange();
            insertPosition = firstTypeRange.getOffset();
        }
        if (fSuperType.isLocal()) {
            workingCopyContents.insert(insertPosition, '{' + dummyClassContent + '}');
            insertPosition++;
        } else {
            // $NON-NLS-1$
            workingCopyContents.insert(insertPosition, dummyClassContent + "\n\n");
        }
        workingCopy.getBuffer().setContents(workingCopyContents.toString());
        ASTParser parser = ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
        parser.setResolveBindings(true);
        parser.setStatementsRecovery(true);
        parser.setSource(workingCopy);
        CompilationUnit astRoot = (CompilationUnit) parser.createAST(new NullProgressMonitor());
        ASTNode newType = NodeFinder.perform(astRoot, insertPosition, dummyClassContent.length());
        if (!(newType instanceof AbstractTypeDeclaration)) {
            return null;
        }
        AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) newType;
        ITypeBinding dummyTypeBinding = declaration.resolveBinding();
        if (dummyTypeBinding == null) {
            return null;
        }
        IMethodBinding[] bindings = StubUtility2.getOverridableMethods(astRoot.getAST(), dummyTypeBinding, true);
        if (fSuperType.isInterface()) {
            ITypeBinding[] dummySuperInterfaces = dummyTypeBinding.getInterfaces();
            if (dummySuperInterfaces.length == 0 || dummySuperInterfaces.length == 1 && dummySuperInterfaces[0].isRawType()) {
                bindings = new IMethodBinding[0];
            }
        } else {
            ITypeBinding dummySuperclass = dummyTypeBinding.getSuperclass();
            if (dummySuperclass == null || dummySuperclass.isRawType()) {
                bindings = new IMethodBinding[0];
            }
        }
        CodeGenerationSettings settings = PreferenceManager.getCodeGenerationSettings(fJavaProject.getProject());
        IMethodBinding[] methodsToOverride = null;
        settings.createComments = false;
        List<IMethodBinding> result = new ArrayList<>();
        for (int i = 0; i < bindings.length; i++) {
            IMethodBinding curr = bindings[i];
            if (Modifier.isAbstract(curr.getModifiers())) {
                result.add(curr);
            }
        }
        methodsToOverride = result.toArray(new IMethodBinding[result.size()]);
        // used to find @NonNullByDefault effective at that current context
        IBinding contextBinding = null;
        if (fCompilationUnit.getJavaProject().getOption(JavaCore.COMPILER_ANNOTATION_NULL_ANALYSIS, true).equals(JavaCore.ENABLED)) {
            ASTNode focusNode = NodeFinder.perform(astRoot, fReplacementOffset + dummyClassContent.length(), 0);
            contextBinding = getEnclosingDeclaration(focusNode);
        }
        ASTRewrite rewrite = ASTRewrite.create(astRoot.getAST());
        ITrackedNodePosition trackedDeclaration = rewrite.track(declaration);
        ListRewrite rewriter = rewrite.getListRewrite(declaration, declaration.getBodyDeclarationsProperty());
        for (int i = 0; i < methodsToOverride.length; i++) {
            boolean snippetSupport = i == methodsToOverride.length - 1 ? fSnippetSupport : false;
            IMethodBinding curr = methodsToOverride[i];
            MethodDeclaration stub = StubUtility2.createImplementationStub(workingCopy, rewrite, importRewrite, null, curr, dummyTypeBinding, settings, dummyTypeBinding.isInterface(), contextBinding, snippetSupport);
            rewriter.insertFirst(stub, null);
        }
        IDocument document = new Document(workingCopy.getSource());
        try {
            rewrite.rewriteAST().apply(document);
            int bodyStart = trackedDeclaration.getStartPosition() + dummyClassContent.indexOf('{');
            int bodyEnd = trackedDeclaration.getStartPosition() + trackedDeclaration.getLength();
            return document.get(bodyStart, bodyEnd - bodyStart);
        } catch (MalformedTreeException exception) {
            JavaLanguageServerPlugin.logException(exception.getMessage(), exception);
        } catch (BadLocationException exception) {
            JavaLanguageServerPlugin.logException(exception.getMessage(), exception);
        }
        return null;
    } finally {
        if (workingCopy != null) {
            workingCopy.discardWorkingCopy();
        }
    }
}
Also used : IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) NullProgressMonitor(org.eclipse.core.runtime.NullProgressMonitor) CodeGenerationSettings(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings) IBinding(org.eclipse.jdt.core.dom.IBinding) ArrayList(java.util.ArrayList) ListRewrite(org.eclipse.jdt.core.dom.rewrite.ListRewrite) Document(org.eclipse.jface.text.Document) IDocument(org.eclipse.jface.text.IDocument) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ASTNode(org.eclipse.jdt.core.dom.ASTNode) ASTRewrite(org.eclipse.jdt.core.dom.rewrite.ASTRewrite) ITrackedNodePosition(org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition) ASTParser(org.eclipse.jdt.core.dom.ASTParser) ISourceRange(org.eclipse.jdt.core.ISourceRange) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) MethodDeclaration(org.eclipse.jdt.core.dom.MethodDeclaration) MalformedTreeException(org.eclipse.text.edits.MalformedTreeException) IDocument(org.eclipse.jface.text.IDocument) BadLocationException(org.eclipse.jface.text.BadLocationException) AbstractTypeDeclaration(org.eclipse.jdt.core.dom.AbstractTypeDeclaration)

Example 2 with CodeGenerationSettings

use of org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings in project eclipse.jdt.ls by eclipse.

the class AbstractMethodCorrectionProposal method getStub.

private MethodDeclaration getStub(ASTRewrite rewrite, ASTNode targetTypeDecl) throws CoreException {
    ImportRewriteContext context = new ContextSensitiveImportRewriteContext(targetTypeDecl, getImportRewrite());
    AST ast = targetTypeDecl.getAST();
    MethodDeclaration decl = ast.newMethodDeclaration();
    SimpleName newNameNode = getNewName(rewrite);
    decl.setConstructor(isConstructor());
    addNewModifiers(rewrite, targetTypeDecl, decl.modifiers());
    ArrayList<String> takenNames = new ArrayList<>();
    addNewTypeParameters(rewrite, takenNames, decl.typeParameters(), context);
    decl.setName(newNameNode);
    IVariableBinding[] declaredFields = fSenderBinding.getDeclaredFields();
    for (int i = 0; i < declaredFields.length; i++) {
        // avoid to take parameter names that are equal to field names
        takenNames.add(declaredFields[i].getName());
    }
    // $NON-NLS-1$
    String bodyStatement = "";
    boolean isAbstractMethod = Modifier.isAbstract(decl.getModifiers()) || (fSenderBinding.isInterface() && !Modifier.isStatic(decl.getModifiers()) && !Modifier.isDefault(decl.getModifiers()));
    if (!isConstructor()) {
        Type returnType = getNewMethodType(rewrite, context);
        decl.setReturnType2(returnType);
        boolean isVoid = returnType instanceof PrimitiveType && PrimitiveType.VOID.equals(((PrimitiveType) returnType).getPrimitiveTypeCode());
        if (!isAbstractMethod && !isVoid) {
            ReturnStatement returnStatement = ast.newReturnStatement();
            returnStatement.setExpression(ASTNodeFactory.newDefaultExpression(ast, returnType, 0));
            bodyStatement = ASTNodes.asFormattedString(returnStatement, 0, String.valueOf('\n'), getCompilationUnit().getJavaProject().getOptions(true));
        }
    }
    addNewParameters(rewrite, takenNames, decl.parameters(), context);
    addNewExceptions(rewrite, decl.thrownExceptionTypes(), context);
    Block body = null;
    if (!isAbstractMethod && !Flags.isAbstract(decl.getModifiers())) {
        body = ast.newBlock();
        if (bodyStatement.length() > 0) {
            ReturnStatement todoNode = (ReturnStatement) rewrite.createStringPlaceholder(bodyStatement, ASTNode.RETURN_STATEMENT);
            body.statements().add(todoNode);
        }
    }
    decl.setBody(body);
    CodeGenerationSettings settings = PreferenceManager.getCodeGenerationSettings(getCompilationUnit().getResource());
    if (settings.createComments && !fSenderBinding.isAnonymous()) {
        String string = CodeGeneration.getMethodComment(getCompilationUnit(), fSenderBinding.getName(), decl, null, String.valueOf('\n'));
        if (string != null) {
            Javadoc javadoc = (Javadoc) rewrite.createStringPlaceholder(string, ASTNode.JAVADOC);
            decl.setJavadoc(javadoc);
        }
    }
    return decl;
}
Also used : AST(org.eclipse.jdt.core.dom.AST) CodeGenerationSettings(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings) MethodDeclaration(org.eclipse.jdt.core.dom.MethodDeclaration) SimpleName(org.eclipse.jdt.core.dom.SimpleName) ArrayList(java.util.ArrayList) Javadoc(org.eclipse.jdt.core.dom.Javadoc) IVariableBinding(org.eclipse.jdt.core.dom.IVariableBinding) ContextSensitiveImportRewriteContext(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext) Type(org.eclipse.jdt.core.dom.Type) PrimitiveType(org.eclipse.jdt.core.dom.PrimitiveType) ImportRewriteContext(org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext) ContextSensitiveImportRewriteContext(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext) ReturnStatement(org.eclipse.jdt.core.dom.ReturnStatement) Block(org.eclipse.jdt.core.dom.Block) PrimitiveType(org.eclipse.jdt.core.dom.PrimitiveType)

Example 3 with CodeGenerationSettings

use of org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings in project eclipse.jdt.ls by eclipse.

the class PreferenceManager method getCodeGenerationSettings.

public static CodeGenerationSettings getCodeGenerationSettings(IResource resource) {
    IJavaProject project = JavaCore.create(resource.getProject());
    CodeGenerationSettings res = new CodeGenerationSettings();
    // TODO indentation settings should be retrieved from client/external
    // settings?
    res.tabWidth = CodeFormatterUtil.getTabWidth(project);
    res.indentWidth = CodeFormatterUtil.getIndentWidth(project);
    return res;
}
Also used : IJavaProject(org.eclipse.jdt.core.IJavaProject) CodeGenerationSettings(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings)

Example 4 with CodeGenerationSettings

use of org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings in project eclipse.jdt.ls by eclipse.

the class AddUnimplementedMethodsOperation method rewriteAST.

@Override
public void rewriteAST(CompilationUnitRewrite cuRewrite, LinkedProposalModel model) throws CoreException {
    IMethodBinding[] unimplementedMethods = getUnimplementedMethods(fTypeNode);
    if (unimplementedMethods.length == 0) {
        return;
    }
    ImportRewriteContext context = new ContextSensitiveImportRewriteContext((CompilationUnit) fTypeNode.getRoot(), fTypeNode.getStartPosition(), cuRewrite.getImportRewrite());
    ASTRewrite rewrite = cuRewrite.getASTRewrite();
    ICompilationUnit unit = cuRewrite.getCu();
    CodeGenerationSettings settings = PreferenceManager.getCodeGenerationSettings(unit.getJavaProject().getProject());
    ListRewrite listRewrite;
    ITypeBinding currentType = null;
    if (fTypeNode instanceof AnonymousClassDeclaration) {
        AnonymousClassDeclaration decl = (AnonymousClassDeclaration) fTypeNode;
        listRewrite = rewrite.getListRewrite(decl, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY);
        settings.createComments = false;
        currentType = decl.resolveBinding();
    } else if (fTypeNode instanceof AbstractTypeDeclaration) {
        AbstractTypeDeclaration decl = (AbstractTypeDeclaration) fTypeNode;
        listRewrite = rewrite.getListRewrite(decl, decl.getBodyDeclarationsProperty());
        currentType = decl.resolveBinding();
    } else if (fTypeNode instanceof EnumConstantDeclaration) {
        EnumConstantDeclaration enumConstantDeclaration = (EnumConstantDeclaration) fTypeNode;
        AnonymousClassDeclaration anonymousClassDeclaration = enumConstantDeclaration.getAnonymousClassDeclaration();
        if (anonymousClassDeclaration == null) {
            anonymousClassDeclaration = rewrite.getAST().newAnonymousClassDeclaration();
            rewrite.set(enumConstantDeclaration, EnumConstantDeclaration.ANONYMOUS_CLASS_DECLARATION_PROPERTY, anonymousClassDeclaration, createTextEditGroup(CorrectionMessages.AddUnimplementedMethodsOperation_AddMissingMethod_group, cuRewrite));
        }
        listRewrite = rewrite.getListRewrite(anonymousClassDeclaration, AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY);
        settings.createComments = false;
    } else {
        // $NON-NLS-1$
        Assert.isTrue(false, "Unknown type node");
        return;
    }
    ImportRewrite imports = cuRewrite.getImportRewrite();
    for (int i = 0; i < unimplementedMethods.length; i++) {
        IMethodBinding curr = unimplementedMethods[i];
        MethodDeclaration newMethodDecl = StubUtility2.createImplementationStub(unit, rewrite, imports, context, curr, curr.getDeclaringClass(), settings, false, currentType, false);
        listRewrite.insertLast(newMethodDecl, createTextEditGroup(CorrectionMessages.AddUnimplementedMethodsOperation_AddMissingMethod_group, cuRewrite));
    }
}
Also used : IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) ImportRewrite(org.eclipse.jdt.core.dom.rewrite.ImportRewrite) CodeGenerationSettings(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings) MethodDeclaration(org.eclipse.jdt.core.dom.MethodDeclaration) AnonymousClassDeclaration(org.eclipse.jdt.core.dom.AnonymousClassDeclaration) ListRewrite(org.eclipse.jdt.core.dom.rewrite.ListRewrite) EnumConstantDeclaration(org.eclipse.jdt.core.dom.EnumConstantDeclaration) ContextSensitiveImportRewriteContext(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext) ImportRewriteContext(org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext) ContextSensitiveImportRewriteContext(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ASTRewrite(org.eclipse.jdt.core.dom.rewrite.ASTRewrite) AbstractTypeDeclaration(org.eclipse.jdt.core.dom.AbstractTypeDeclaration)

Example 5 with CodeGenerationSettings

use of org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings in project eclipse.jdt.ls by eclipse.

the class OverrideCompletionProposal method updateReplacementString.

/*
	 * @see JavaTypeCompletionProposal#updateReplacementString(IDocument,char,int,ImportRewrite)
	 */
public String updateReplacementString(IDocument document, int offset, ImportRewrite importRewrite, boolean snippetStringSupport) throws CoreException, BadLocationException {
    Document recoveredDocument = new Document();
    CompilationUnit unit = getRecoveredAST(document, offset, recoveredDocument);
    ImportRewriteContext context = new ContextSensitiveImportRewriteContext(unit, offset, importRewrite);
    ITypeBinding declaringType = null;
    ChildListPropertyDescriptor descriptor = null;
    ASTNode node = NodeFinder.perform(unit, offset, 1);
    node = ASTResolving.findParentType(node);
    String result = null;
    if (node instanceof AnonymousClassDeclaration) {
        declaringType = ((AnonymousClassDeclaration) node).resolveBinding();
        descriptor = AnonymousClassDeclaration.BODY_DECLARATIONS_PROPERTY;
    } else if (node instanceof AbstractTypeDeclaration) {
        AbstractTypeDeclaration declaration = (AbstractTypeDeclaration) node;
        descriptor = declaration.getBodyDeclarationsProperty();
        declaringType = declaration.resolveBinding();
    }
    if (declaringType != null) {
        ASTRewrite rewrite = ASTRewrite.create(unit.getAST());
        IMethodBinding methodToOverride = Bindings.findMethodInHierarchy(declaringType, fMethodName, fParamTypes);
        if (methodToOverride == null && declaringType.isInterface()) {
            // $NON-NLS-1$
            methodToOverride = Bindings.findMethodInType(node.getAST().resolveWellKnownType("java.lang.Object"), fMethodName, fParamTypes);
        }
        if (methodToOverride != null) {
            CodeGenerationSettings settings = PreferenceManager.getCodeGenerationSettings(fJavaProject.getProject());
            MethodDeclaration stub = StubUtility2.createImplementationStub(fCompilationUnit, rewrite, importRewrite, context, methodToOverride, declaringType, settings, declaringType.isInterface(), declaringType, snippetStringSupport);
            ListRewrite rewriter = rewrite.getListRewrite(node, descriptor);
            rewriter.insertFirst(stub, null);
            ITrackedNodePosition position = rewrite.track(stub);
            try {
                Map<String, String> options = fJavaProject.getOptions(true);
                rewrite.rewriteAST(recoveredDocument, options).apply(recoveredDocument);
                String generatedCode = recoveredDocument.get(position.getStartPosition(), position.getLength());
                String indentAt = getIndentAt(recoveredDocument, position.getStartPosition(), settings);
                int generatedIndent = IndentManipulation.measureIndentUnits(indentAt, settings.tabWidth, settings.indentWidth);
                // Kinda fishy but empirical data shows Override needs to change indent by at
                // least 1
                generatedIndent = Math.max(1, generatedIndent);
                // Cancel generated code indent
                String delimiter = TextUtilities.getDefaultLineDelimiter(document);
                result = IndentManipulation.changeIndent(generatedCode, generatedIndent, settings.tabWidth, settings.indentWidth, "", delimiter);
            } catch (MalformedTreeException | BadLocationException exception) {
                JavaLanguageServerPlugin.logException("Unable to compute override proposal", exception);
            }
        }
    }
    return result;
}
Also used : ICompilationUnit(org.eclipse.jdt.core.ICompilationUnit) CompilationUnit(org.eclipse.jdt.core.dom.CompilationUnit) IMethodBinding(org.eclipse.jdt.core.dom.IMethodBinding) CodeGenerationSettings(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings) MethodDeclaration(org.eclipse.jdt.core.dom.MethodDeclaration) AnonymousClassDeclaration(org.eclipse.jdt.core.dom.AnonymousClassDeclaration) MalformedTreeException(org.eclipse.text.edits.MalformedTreeException) ListRewrite(org.eclipse.jdt.core.dom.rewrite.ListRewrite) Document(org.eclipse.jface.text.Document) IDocument(org.eclipse.jface.text.IDocument) ChildListPropertyDescriptor(org.eclipse.jdt.core.dom.ChildListPropertyDescriptor) ContextSensitiveImportRewriteContext(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext) ImportRewriteContext(org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext) ContextSensitiveImportRewriteContext(org.eclipse.jdt.ls.core.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext) ITypeBinding(org.eclipse.jdt.core.dom.ITypeBinding) ASTNode(org.eclipse.jdt.core.dom.ASTNode) ASTRewrite(org.eclipse.jdt.core.dom.rewrite.ASTRewrite) ITrackedNodePosition(org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition) BadLocationException(org.eclipse.jface.text.BadLocationException) AbstractTypeDeclaration(org.eclipse.jdt.core.dom.AbstractTypeDeclaration)

Aggregations

CodeGenerationSettings (org.eclipse.jdt.ls.core.internal.corext.codemanipulation.CodeGenerationSettings)5 MethodDeclaration (org.eclipse.jdt.core.dom.MethodDeclaration)4 ICompilationUnit (org.eclipse.jdt.core.ICompilationUnit)3 AbstractTypeDeclaration (org.eclipse.jdt.core.dom.AbstractTypeDeclaration)3 IMethodBinding (org.eclipse.jdt.core.dom.IMethodBinding)3 ITypeBinding (org.eclipse.jdt.core.dom.ITypeBinding)3 ASTRewrite (org.eclipse.jdt.core.dom.rewrite.ASTRewrite)3 ImportRewriteContext (org.eclipse.jdt.core.dom.rewrite.ImportRewrite.ImportRewriteContext)3 ListRewrite (org.eclipse.jdt.core.dom.rewrite.ListRewrite)3 ContextSensitiveImportRewriteContext (org.eclipse.jdt.ls.core.internal.corext.codemanipulation.ContextSensitiveImportRewriteContext)3 ArrayList (java.util.ArrayList)2 ASTNode (org.eclipse.jdt.core.dom.ASTNode)2 AnonymousClassDeclaration (org.eclipse.jdt.core.dom.AnonymousClassDeclaration)2 CompilationUnit (org.eclipse.jdt.core.dom.CompilationUnit)2 ITrackedNodePosition (org.eclipse.jdt.core.dom.rewrite.ITrackedNodePosition)2 BadLocationException (org.eclipse.jface.text.BadLocationException)2 Document (org.eclipse.jface.text.Document)2 IDocument (org.eclipse.jface.text.IDocument)2 MalformedTreeException (org.eclipse.text.edits.MalformedTreeException)2 NullProgressMonitor (org.eclipse.core.runtime.NullProgressMonitor)1