]>
Commit | Line | Data |
---|---|---|
1b2798f6 EK |
1 | /******************************************************************************* |
2 | * Copyright (c) 2000, 2011 IBM Corporation and others. | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * IBM Corporation - initial API and implementation | |
10 | *******************************************************************************/ | |
11 | package org.eclipse.jdt.internal.ui.text.correction.proposals; | |
12 | ||
13 | import java.lang.reflect.Modifier; | |
14 | import java.util.List; | |
15 | ||
16 | import org.eclipse.jdt.core.ICompilationUnit; | |
17 | import org.eclipse.jdt.core.dom.AST; | |
18 | import org.eclipse.jdt.core.dom.ASTNode; | |
19 | import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; | |
20 | import org.eclipse.jdt.core.dom.CompilationUnit; | |
21 | import org.eclipse.jdt.core.dom.Expression; | |
22 | import org.eclipse.jdt.core.dom.IBinding; | |
23 | import org.eclipse.jdt.core.dom.ITypeBinding; | |
24 | import org.eclipse.jdt.core.dom.IVariableBinding; | |
25 | import org.eclipse.jdt.core.dom.StructuralPropertyDescriptor; | |
26 | import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; | |
27 | import org.eclipse.jdt.core.dom.rewrite.ListRewrite; | |
28 | ||
29 | import org.eclipse.jdt.internal.corext.dom.ASTNodeFactory; | |
30 | import org.eclipse.jdt.internal.corext.dom.ASTNodes; | |
31 | import org.eclipse.jdt.internal.corext.dom.ScopeAnalyzer; | |
32 | ||
33 | import org.eclipse.jdt.internal.ui.JavaPluginImages; | |
34 | import org.eclipse.jdt.internal.ui.text.correction.ASTResolving; | |
35 | ||
36 | public class AddArgumentCorrectionProposal extends LinkedCorrectionProposal { | |
37 | ||
38 | private int[] fInsertIndexes; | |
39 | private ITypeBinding[] fParamTypes; | |
40 | private ASTNode fCallerNode; | |
41 | ||
42 | public AddArgumentCorrectionProposal(String label, ICompilationUnit cu, ASTNode callerNode, int[] insertIdx, ITypeBinding[] expectedTypes, int relevance) { | |
43 | super(label, cu, null, relevance, JavaPluginImages.get(JavaPluginImages.IMG_CORRECTION_CHANGE)); | |
44 | fCallerNode= callerNode; | |
45 | fInsertIndexes= insertIdx; | |
46 | fParamTypes= expectedTypes; | |
47 | } | |
48 | ||
49 | /*(non-Javadoc) | |
50 | * @see org.eclipse.jdt.internal.ui.text.correction.ASTRewriteCorrectionProposal#getRewrite() | |
51 | */ | |
52 | @Override | |
53 | protected ASTRewrite getRewrite() { | |
54 | AST ast= fCallerNode.getAST(); | |
55 | ASTRewrite rewrite= ASTRewrite.create(ast); | |
56 | ChildListPropertyDescriptor property= getProperty(); | |
57 | ||
58 | for (int i= 0; i < fInsertIndexes.length; i++) { | |
59 | int idx= fInsertIndexes[i]; | |
60 | String key= "newarg_" + i; //$NON-NLS-1$ | |
61 | Expression newArg= evaluateArgumentExpressions(ast, fParamTypes[idx], key); | |
62 | ListRewrite listRewriter= rewrite.getListRewrite(fCallerNode, property); | |
63 | listRewriter.insertAt(newArg, idx, null); | |
64 | ||
65 | addLinkedPosition(rewrite.track(newArg), i == 0, key); | |
66 | } | |
67 | return rewrite; | |
68 | } | |
69 | ||
70 | private ChildListPropertyDescriptor getProperty() { | |
71 | List<StructuralPropertyDescriptor> list= fCallerNode.structuralPropertiesForType(); | |
72 | for (int i= 0; i < list.size(); i++) { | |
73 | StructuralPropertyDescriptor curr= list.get(i); | |
74 | if (curr.isChildListProperty() && "arguments".equals(curr.getId())) { //$NON-NLS-1$ | |
75 | return (ChildListPropertyDescriptor) curr; | |
76 | } | |
77 | } | |
78 | return null; | |
79 | ||
80 | } | |
81 | ||
82 | ||
83 | private Expression evaluateArgumentExpressions(AST ast, ITypeBinding requiredType, String key) { | |
84 | CompilationUnit root= (CompilationUnit) fCallerNode.getRoot(); | |
85 | ||
86 | int offset= fCallerNode.getStartPosition(); | |
87 | Expression best= null; | |
88 | ITypeBinding bestType= null; | |
89 | ||
90 | ScopeAnalyzer analyzer= new ScopeAnalyzer(root); | |
91 | IBinding[] bindings= analyzer.getDeclarationsInScope(offset, ScopeAnalyzer.VARIABLES); | |
92 | for (int i= 0; i < bindings.length; i++) { | |
93 | IVariableBinding curr= (IVariableBinding) bindings[i]; | |
94 | ITypeBinding type= curr.getType(); | |
95 | if (type != null && canAssign(type, requiredType) && testModifier(curr)) { | |
96 | if (best == null || isMoreSpecific(bestType, type)) { | |
97 | best= ast.newSimpleName(curr.getName()); | |
98 | bestType= type; | |
99 | } | |
100 | addLinkedPositionProposal(key, curr.getName(), null); | |
101 | } | |
102 | } | |
103 | Expression defaultExpression= ASTNodeFactory.newDefaultExpression(ast, requiredType); | |
104 | if (best == null) { | |
105 | best= defaultExpression; | |
106 | } | |
107 | addLinkedPositionProposal(key, ASTNodes.asString(defaultExpression), null); | |
108 | return best; | |
109 | } | |
110 | ||
111 | private boolean isMoreSpecific(ITypeBinding best, ITypeBinding curr) { | |
112 | return (canAssign(best, curr) && !canAssign(curr, best)); | |
113 | } | |
114 | ||
115 | ||
116 | private boolean canAssign(ITypeBinding curr, ITypeBinding best) { | |
117 | return curr.isAssignmentCompatible(best); | |
118 | } | |
119 | ||
120 | private boolean testModifier(IVariableBinding curr) { | |
121 | int modifiers= curr.getModifiers(); | |
122 | int staticFinal= Modifier.STATIC | Modifier.FINAL; | |
123 | if ((modifiers & staticFinal) == staticFinal) { | |
124 | return false; | |
125 | } | |
126 | if (Modifier.isStatic(modifiers) && !ASTResolving.isInStaticContext(fCallerNode)) { | |
127 | return false; | |
128 | } | |
129 | return true; | |
130 | } | |
131 | } |