]>
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.corext.refactoring.structure; | |
12 | ||
13 | import java.util.ArrayList; | |
14 | import java.util.Arrays; | |
15 | import java.util.List; | |
16 | ||
17 | import org.eclipse.ltk.core.refactoring.RefactoringStatus; | |
18 | import org.eclipse.ltk.core.refactoring.RefactoringStatusContext; | |
19 | ||
20 | import org.eclipse.jdt.core.IField; | |
21 | import org.eclipse.jdt.core.IJavaElement; | |
22 | import org.eclipse.jdt.core.IMember; | |
23 | import org.eclipse.jdt.core.IMethod; | |
24 | import org.eclipse.jdt.core.IType; | |
25 | import org.eclipse.jdt.core.JavaModelException; | |
26 | ||
27 | import org.eclipse.jdt.internal.corext.refactoring.Checks; | |
28 | import org.eclipse.jdt.internal.corext.refactoring.RefactoringCoreMessages; | |
29 | import org.eclipse.jdt.internal.corext.refactoring.base.JavaStatusContext; | |
30 | import org.eclipse.jdt.internal.corext.util.JavaModelUtil; | |
31 | import org.eclipse.jdt.internal.corext.util.Messages; | |
32 | ||
33 | import org.eclipse.jdt.internal.ui.viewsupport.BasicElementLabels; | |
34 | ||
35 | class MemberCheckUtil { | |
36 | ||
37 | private MemberCheckUtil(){ | |
38 | //static only | |
39 | } | |
40 | ||
41 | public static RefactoringStatus checkMembersInDestinationType(IMember[] members, IType destinationType) throws JavaModelException { | |
42 | RefactoringStatus result= new RefactoringStatus(); | |
43 | for (int i= 0; i < members.length; i++) { | |
44 | if (members[i].getElementType() == IJavaElement.METHOD) | |
45 | checkMethodInType(destinationType, result, (IMethod)members[i]); | |
46 | else if (members[i].getElementType() == IJavaElement.FIELD) | |
47 | checkFieldInType(destinationType, result, (IField)members[i]); | |
48 | else if (members[i].getElementType() == IJavaElement.TYPE) | |
49 | checkTypeInType(destinationType, result, (IType)members[i]); | |
50 | } | |
51 | return result; | |
52 | } | |
53 | ||
54 | private static void checkMethodInType(IType destinationType, RefactoringStatus result, IMethod method) throws JavaModelException { | |
55 | IMethod[] destinationTypeMethods= destinationType.getMethods(); | |
56 | IMethod found= findMethod(method, destinationTypeMethods); | |
57 | if (found != null){ | |
58 | RefactoringStatusContext context= JavaStatusContext.create(destinationType.getCompilationUnit(), found.getSourceRange()); | |
59 | String message= Messages.format(RefactoringCoreMessages.MemberCheckUtil_signature_exists, | |
60 | new String[]{ BasicElementLabels.getJavaElementName(method.getElementName()), getQualifiedLabel(destinationType)}); | |
61 | result.addError(message, context); | |
62 | } else { | |
63 | IMethod similar= Checks.findMethod(method, destinationType); | |
64 | if (similar != null){ | |
65 | String message= Messages.format(RefactoringCoreMessages.MemberCheckUtil_same_param_count, | |
66 | new String[]{ BasicElementLabels.getJavaElementName(method.getElementName()), getQualifiedLabel(destinationType)}); | |
67 | RefactoringStatusContext context= JavaStatusContext.create(destinationType.getCompilationUnit(), similar.getSourceRange()); | |
68 | result.addWarning(message, context); | |
69 | } | |
70 | } | |
71 | } | |
72 | ||
73 | private static void checkFieldInType(IType destinationType, RefactoringStatus result, IField field) throws JavaModelException { | |
74 | IField destinationTypeField= destinationType.getField(field.getElementName()); | |
75 | if (! destinationTypeField.exists()) | |
76 | return; | |
77 | String message= Messages.format(RefactoringCoreMessages.MemberCheckUtil_field_exists, | |
78 | new String[]{ BasicElementLabels.getJavaElementName(field.getElementName()), getQualifiedLabel(destinationType)}); | |
79 | RefactoringStatusContext context= JavaStatusContext.create(destinationType.getCompilationUnit(), destinationTypeField.getSourceRange()); | |
80 | result.addError(message, context); | |
81 | } | |
82 | ||
83 | private static void checkTypeInType(IType destinationType, RefactoringStatus result, IType type) throws JavaModelException { | |
84 | String typeName= type.getElementName(); | |
85 | IType destinationTypeType= destinationType.getType(typeName); | |
86 | if (destinationTypeType.exists()){ | |
87 | String message= Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict0, | |
88 | new String[]{ BasicElementLabels.getJavaElementName(typeName), getQualifiedLabel(destinationType)}); | |
89 | RefactoringStatusContext context= JavaStatusContext.create(destinationType.getCompilationUnit(), destinationTypeType.getNameRange()); | |
90 | result.addError(message, context); | |
91 | } else { | |
92 | //need to check the hierarchy of enclosing and enclosed types | |
93 | if (destinationType.getElementName().equals(typeName)){ | |
94 | String message= Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict1, getQualifiedLabel(type)); | |
95 | RefactoringStatusContext context= JavaStatusContext.create(destinationType.getCompilationUnit(), destinationType.getNameRange()); | |
96 | result.addError(message, context); | |
97 | } | |
98 | if (typeNameExistsInEnclosingTypeChain(destinationType, typeName)){ | |
99 | String message= Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict2, getQualifiedLabel(type)); | |
100 | RefactoringStatusContext context= JavaStatusContext.create(destinationType.getCompilationUnit(), destinationType.getNameRange()); | |
101 | result.addError(message, context); | |
102 | } | |
103 | checkHierarchyOfEnclosedTypes(destinationType, result, type); | |
104 | } | |
105 | } | |
106 | ||
107 | private static void checkHierarchyOfEnclosedTypes(IType destinationType, RefactoringStatus result, IType type) throws JavaModelException { | |
108 | IType[] enclosedTypes= getAllEnclosedTypes(type); | |
109 | for (int i= 0; i < enclosedTypes.length; i++) { | |
110 | IType enclosedType= enclosedTypes[i]; | |
111 | if (destinationType.getElementName().equals(enclosedType.getElementName())){ | |
112 | String message= Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict3, | |
113 | new String[] { getQualifiedLabel(enclosedType), getQualifiedLabel(type)}); | |
114 | RefactoringStatusContext context= JavaStatusContext.create(destinationType.getCompilationUnit(), destinationType.getNameRange()); | |
115 | result.addError(message, context); | |
116 | } | |
117 | if (typeNameExistsInEnclosingTypeChain(destinationType, enclosedType.getElementName())){ | |
118 | String message= Messages.format(RefactoringCoreMessages.MemberCheckUtil_type_name_conflict4, | |
119 | new String[] { getQualifiedLabel(enclosedType), getQualifiedLabel(type)}); | |
120 | RefactoringStatusContext context= JavaStatusContext.create(destinationType.getCompilationUnit(), destinationType.getNameRange()); | |
121 | result.addError(message, context); | |
122 | } | |
123 | } | |
124 | } | |
125 | ||
126 | private static String getQualifiedLabel(IType enclosedType) { | |
127 | return BasicElementLabels.getJavaElementName(enclosedType.getFullyQualifiedName('.')); | |
128 | } | |
129 | ||
130 | private static IType[] getAllEnclosedTypes(IType type) throws JavaModelException { | |
131 | List<IType> result= new ArrayList<IType>(2); | |
132 | IType[] directlyEnclosed= type.getTypes(); | |
133 | result.addAll(Arrays.asList(directlyEnclosed)); | |
134 | for (int i= 0; i < directlyEnclosed.length; i++) { | |
135 | IType enclosedType= directlyEnclosed[i]; | |
136 | result.addAll(Arrays.asList(getAllEnclosedTypes(enclosedType))); | |
137 | } | |
138 | return result.toArray(new IType[result.size()]); | |
139 | } | |
140 | ||
141 | private static boolean typeNameExistsInEnclosingTypeChain(IType type, String typeName){ | |
142 | IType enclosing= type.getDeclaringType(); | |
143 | while (enclosing != null){ | |
144 | if (enclosing.getElementName().equals(typeName)) | |
145 | return true; | |
146 | enclosing= enclosing.getDeclaringType(); | |
147 | } | |
148 | return false; | |
149 | } | |
150 | ||
151 | /** | |
152 | * Finds a method in a list of methods. Compares methods by signature | |
153 | * (only SimpleNames of types), and not by the declaring type. | |
154 | * @param method the method to find | |
155 | * @param allMethods the methods to look at | |
156 | * @return The found method or <code>null</code>, if nothing found | |
157 | * @throws JavaModelException | |
158 | */ | |
159 | public static IMethod findMethod(IMethod method, IMethod[] allMethods) throws JavaModelException { | |
160 | String name= method.getElementName(); | |
161 | String[] paramTypes= method.getParameterTypes(); | |
162 | boolean isConstructor= method.isConstructor(); | |
163 | ||
164 | for (int i= 0; i < allMethods.length; i++) { | |
165 | if (JavaModelUtil.isSameMethodSignature(name, paramTypes, isConstructor, allMethods[i])) | |
166 | return allMethods[i]; | |
167 | } | |
168 | return null; | |
169 | } | |
170 | } |