public static void checkFieldConflicts( @Nullable PsiClass aClass, String newName, final Map<PsiElement, String> conflicts) { PsiField existingField = aClass != null ? aClass.findFieldByName(newName, true) : null; if (existingField != null) { if (aClass.equals(existingField.getContainingClass())) { String className = aClass instanceof PsiAnonymousClass ? RefactoringBundle.message("current.class") : RefactoringUIUtil.getDescription(aClass, false); final String conflict = RefactoringBundle.message( "field.0.is.already.defined.in.the.1", existingField.getName(), className); conflicts.put(existingField, conflict); } else { // method somewhere in base class if (!existingField.hasModifierProperty(PsiModifier.PRIVATE)) { String fieldInfo = PsiFormatUtil.formatVariable( existingField, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE | PsiFormatUtil.TYPE_AFTER, PsiSubstitutor.EMPTY); String className = RefactoringUIUtil.getDescription(existingField.getContainingClass(), false); final String descr = RefactoringBundle.message( "field.0.will.hide.field.1.of.the.base.class", newName, fieldInfo, className); conflicts.put(existingField, descr); } } } }
@Override public void visitReferenceExpression(@NotNull PsiReferenceExpression expression) { if (FileTypeUtils.isInServerPageFile(expression)) { // disable for jsp files IDEADEV-12957 return; } super.visitReferenceExpression(expression); if (expression.getQualifierExpression() == null) { return; } final PsiElement referenceNameElement = expression.getReferenceNameElement(); if (referenceNameElement == null) { return; } final PsiElement containingClass = getContainingContextClass(expression); if (containingClass == null) { return; } final PsiElement element = expression.resolve(); if (!(element instanceof PsiMethod || element instanceof PsiField)) { return; } final PsiMember member = (PsiMember) element; if (!member.hasModifierProperty(PsiModifier.PRIVATE)) { return; } final PsiClass memberClass = ClassUtils.getContainingClass(member); if (memberClass == null) { return; } if (memberClass.equals(containingClass)) { return; } registerError(referenceNameElement, memberClass, member); }
private void doMoveClass(PsiSubstitutor substitutor, MemberInfo info) { PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject); PsiClass aClass = (PsiClass) info.getMember(); if (Boolean.FALSE.equals(info.getOverrides())) { final PsiReferenceList sourceReferenceList = info.getSourceReferenceList(); LOG.assertTrue(sourceReferenceList != null); PsiJavaCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ? RefactoringUtil.removeFromReferenceList(sourceReferenceList, aClass) : RefactoringUtil.findReferenceToClass(sourceReferenceList, aClass); if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) { RefactoringUtil.replaceMovedMemberTypeParameters( ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final PsiReferenceList referenceList = myIsTargetInterface ? myTargetSuperClass.getExtendsList() : myTargetSuperClass.getImplementsList(); assert referenceList != null; referenceList.add(ref); } } else { RefactoringUtil.replaceMovedMemberTypeParameters( aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); fixReferencesToStatic(aClass); final PsiMember movedElement = (PsiMember) myTargetSuperClass.add( convertClassToLanguage(aClass, myTargetSuperClass.getLanguage())); myMembersAfterMove.add(movedElement); aClass.delete(); } }
@Override public void visitMethodCallExpression(@NotNull PsiMethodCallExpression call) { super.visitMethodCallExpression(call); final PsiReferenceExpression methodExpression = call.getMethodExpression(); final PsiElement qualifier = methodExpression.getQualifier(); if (!(qualifier instanceof PsiReferenceExpression)) { return; } final PsiMethod method = call.resolveMethod(); if (method == null) { return; } if (!method.hasModifierProperty(PsiModifier.STATIC)) { return; } final PsiElement referent = ((PsiReference) qualifier).resolve(); if (!(referent instanceof PsiClass)) { return; } final PsiClass referencedClass = (PsiClass) referent; final PsiClass declaringClass = method.getContainingClass(); if (declaringClass == null) { return; } if (declaringClass.equals(referencedClass)) { return; } final PsiClass containingClass = ClassUtils.getContainingClass(call); if (!ClassUtils.isClassVisibleFromClass(containingClass, declaringClass)) { return; } registerMethodCallError(call, declaringClass, referencedClass); }
@NotNull private static List<PsiMethod> findMethodsBySignature( @NotNull PsiClass aClass, @NotNull PsiMethod patternMethod, boolean checkBases, boolean stopOnFirst) { final PsiMethod[] methodsByName = aClass.findMethodsByName(patternMethod.getName(), checkBases); if (methodsByName.length == 0) return Collections.emptyList(); final List<PsiMethod> methods = new SmartList<PsiMethod>(); final MethodSignature patternSignature = patternMethod.getSignature(PsiSubstitutor.EMPTY); for (final PsiMethod method : methodsByName) { final PsiClass superClass = method.getContainingClass(); final PsiSubstitutor substitutor; if (checkBases && !aClass.equals(superClass)) { substitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, aClass, PsiSubstitutor.EMPTY); } else { substitutor = PsiSubstitutor.EMPTY; } final MethodSignature signature = method.getSignature(substitutor); if (signature.equals(patternSignature)) { methods.add(method); if (stopOnFirst) { break; } } } return methods; }
private Binding unify(final PsiType x, final PsiType y, final Unifier unifier) { final int indicator = (x instanceof PsiTypeVariable ? 1 : 0) + (y instanceof PsiTypeVariable ? 2 : 0); switch (indicator) { case 0: if (x instanceof PsiWildcardType || y instanceof PsiWildcardType) { return unifier.unify(x, y); } else if (x instanceof PsiArrayType || y instanceof PsiArrayType) { final PsiType xType = x instanceof PsiArrayType ? ((PsiArrayType) x).getComponentType() : x; final PsiType yType = y instanceof PsiArrayType ? ((PsiArrayType) y).getComponentType() : y; return unify(xType, yType, unifier); } else if (x instanceof PsiClassType && y instanceof PsiClassType) { final PsiClassType.ClassResolveResult resultX = Util.resolveType(x); final PsiClassType.ClassResolveResult resultY = Util.resolveType(y); final PsiClass xClass = resultX.getElement(); final PsiClass yClass = resultY.getElement(); if (xClass != null && yClass != null) { final PsiSubstitutor ySubst = resultY.getSubstitutor(); final PsiSubstitutor xSubst = resultX.getSubstitutor(); if (!xClass.equals(yClass)) { return null; } Binding b = create(); for (final PsiTypeParameter aParm : xSubst.getSubstitutionMap().keySet()) { final PsiType xType = xSubst.substitute(aParm); final PsiType yType = ySubst.substitute(aParm); final Binding b1 = unify(xType, yType, unifier); if (b1 == null) { return null; } b = b.compose(b1); } return b; } } else if (y instanceof Bottom) { return create(); } else { return null; } default: return unifier.unify(x, y); } }
@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof ClassIconRequest)) return false; ClassIconRequest that = (ClassIconRequest) o; return flags == that.flags && psiClass.equals(that.psiClass); }
public static void checkMethodConflicts( @Nullable PsiClass aClass, PsiMethod refactoredMethod, PsiMethod prototype, final MultiMap<PsiElement, String> conflicts) { if (prototype == null) return; PsiMethod method = aClass != null ? aClass.findMethodBySignature(prototype, true) : null; if (method != null && method != refactoredMethod) { if (aClass.equals(method.getContainingClass())) { final String classDescr = aClass instanceof PsiAnonymousClass ? RefactoringBundle.message("current.class") : RefactoringUIUtil.getDescription(aClass, false); conflicts.putValue( method, RefactoringBundle.message( "method.0.is.already.defined.in.the.1", getMethodPrototypeString(prototype), classDescr)); } else { // method somewhere in base class if (JavaPsiFacade.getInstance(method.getProject()) .getResolveHelper() .isAccessible(method, aClass, null)) { String protoMethodInfo = getMethodPrototypeString(prototype); String className = CommonRefactoringUtil.htmlEmphasize( UsageViewUtil.getDescriptiveName(method.getContainingClass())); if (PsiUtil.getAccessLevel(prototype.getModifierList()) >= PsiUtil.getAccessLevel(method.getModifierList())) { boolean isMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT); boolean isMyMethodAbstract = refactoredMethod != null && refactoredMethod.hasModifierProperty(PsiModifier.ABSTRACT); final String conflict = isMethodAbstract != isMyMethodAbstract ? RefactoringBundle.message( "method.0.will.implement.method.of.the.base.class", protoMethodInfo, className) : RefactoringBundle.message( "method.0.will.override.a.method.of.the.base.class", protoMethodInfo, className); conflicts.putValue(method, conflict); } else { // prototype is private, will be compile-error conflicts.putValue( method, RefactoringBundle.message( "method.0.will.hide.method.of.the.base.class", protoMethodInfo, className)); } } } } }
private void doMoveClass(PsiSubstitutor substitutor, GrMemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrTypeDefinition aClass = (GrTypeDefinition) info.getMember(); if (Boolean.FALSE.equals(info.getOverrides())) { final GrReferenceList sourceReferenceList = info.getSourceReferenceList(); LOG.assertTrue(sourceReferenceList != null); GrCodeReferenceElement ref = mySourceClass.equals(sourceReferenceList.getParent()) ? removeFromReferenceList(sourceReferenceList, aClass) : findReferenceToClass(sourceReferenceList, aClass); if (ref != null && !myTargetSuperClass.isInheritor(aClass, false)) { replaceMovedMemberTypeParameters( ref, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); GrReferenceList referenceList; if (myTargetSuperClass.isInterface()) { referenceList = myTargetSuperClass.getExtendsClause(); if (referenceList == null) { GrExtendsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createExtendsClause(); PsiElement anchor = myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList() : myTargetSuperClass.getNameIdentifierGroovy(); referenceList = (GrReferenceList) myTargetSuperClass.addAfter(newClause, anchor); addSpacesAround(referenceList); } } else { referenceList = myTargetSuperClass.getImplementsClause(); if (referenceList == null) { GrImplementsClause newClause = GroovyPsiElementFactory.getInstance(myProject).createImplementsClause(); PsiElement anchor = myTargetSuperClass.getExtendsClause() != null ? myTargetSuperClass.getExtendsClause() : myTargetSuperClass.getTypeParameterList() != null ? myTargetSuperClass.getTypeParameterList() : myTargetSuperClass.getNameIdentifierGroovy(); referenceList = (GrReferenceList) myTargetSuperClass.addAfter(newClause, anchor); addSpacesAround(referenceList); } } assert referenceList != null; referenceList.add(ref); } } else { replaceMovedMemberTypeParameters( aClass, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); // fixReferencesToStatic(aClass, movedMembers); PsiMember movedElement = (PsiMember) myTargetSuperClass.addAfter(aClass, null); // movedElement = (PsiMember)CodeStyleManager.getInstance(myProject).reformat(movedElement); myMembersAfterMove.add(movedElement); deleteMemberWithDocComment(aClass); } }
@Override public void visitNewExpression(PsiNewExpression expression) { if (FileTypeUtils.isInServerPageFile(expression)) { return; } super.visitNewExpression(expression); final PsiClass containingClass = getContainingContextClass(expression); if (containingClass == null) { return; } final PsiMethod constructor = expression.resolveConstructor(); if (constructor == null) { final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference(); if (classReference == null) { return; } final PsiElement target = classReference.resolve(); if (!(target instanceof PsiClass)) { return; } final PsiClass aClass = (PsiClass) target; if (!aClass.hasModifierProperty(PsiModifier.PRIVATE)) { return; } if (aClass.equals(containingClass)) { return; } registerNewExpressionError(expression, aClass); } else { if (!constructor.hasModifierProperty(PsiModifier.PRIVATE)) { return; } final PsiClass aClass = constructor.getContainingClass(); if (containingClass.equals(aClass)) { return; } registerNewExpressionError(expression, aClass); } }
@Nullable private PsiType extractListTypeFromContainingClass( PsiElement element) { PsiClass listClass = PsiTreeUtil.getParentOfType(element, PsiClass.class); if (listClass == null) { return null; } final PsiMethod[] getMethods = listClass.findMethodsByName("get", true); if (getMethods.length == 0) { return null; } final PsiType type = getMethods[0].getReturnType(); if (!(type instanceof PsiClassType)) { return null; } final PsiClassType classType = (PsiClassType)type; final PsiClass parameterClass = classType.resolve(); if (parameterClass == null) { return null; } PsiClass subClass = null; while (listClass != null && !listClass.hasTypeParameters()) { subClass = listClass; listClass = listClass.getSuperClass(); } if (listClass == null || subClass == null) { return TypeUtils.getObjectType(element); } final PsiTypeParameter[] typeParameters = listClass.getTypeParameters(); if (!parameterClass.equals(typeParameters[0])) { return TypeUtils.getObjectType(element); } final PsiReferenceList extendsList = subClass.getExtendsList(); if (extendsList == null) { return null; } final PsiJavaCodeReferenceElement[] referenceElements = extendsList.getReferenceElements(); if (referenceElements.length == 0) { return null; } final PsiType[] types = referenceElements[0].getTypeParameters(); if (types.length == 0) { return TypeUtils.getObjectType(element); } return types[0]; }
public void visitClass(PsiClass aClass) { super.visitClass(aClass); if (isConcreteClass(aClass)) { final PsiField[] allFields = aClass.getAllFields(); int numInheritedFields = 0; for (final PsiField field : allFields) { final PsiClass containingClass = field.getContainingClass(); if (containingClass != null && !containingClass.equals(aClass) && !field.hasModifierProperty(PsiModifier.STATIC)) { numInheritedFields++; } } postMetric(aClass, numInheritedFields); } }
public void checkMemberPlacementInTargetClassConflict( final PsiClass targetClass, final PsiMember movedMember) { if (movedMember instanceof PsiField) { String name = movedMember.getName(); final PsiField field = targetClass.findFieldByName(name, false); if (field != null) { String message = RefactoringBundle.message( "0.already.contains.field.1", RefactoringUIUtil.getDescription(targetClass, false), CommonRefactoringUtil.htmlEmphasize(name)); myConflicts.putValue(field, CommonRefactoringUtil.capitalize(message)); } } else if (movedMember instanceof PsiMethod) { /* final PsiModifierList modifierList = movedMember.getModifierList(); assert modifierList != null; if (!modifierList.hasModifierProperty(PsiModifier.ABSTRACT)) { PsiMethod method = (PsiMethod)movedMember; final PsiMethod overrider = targetClass.findMethodBySignature(method, false); if (overrider != null) { String message = RefactoringBundle.message("0.is.already.overridden.in.1", RefactoringUIUtil.getDescription(method, true), RefactoringUIUtil.getDescription(targetClass, false)); myConflicts.putValue(overrider, CommonRefactoringUtil.capitalize(message)); } } */ } else if (movedMember instanceof PsiClass) { PsiClass aClass = (PsiClass) movedMember; final String name = aClass.getName(); final PsiClass[] allInnerClasses = targetClass.getAllInnerClasses(); for (PsiClass innerClass : allInnerClasses) { if (innerClass.equals(movedMember)) continue; if (name.equals(innerClass.getName())) { String message = RefactoringBundle.message( "0.already.contains.inner.class.named.1", RefactoringUIUtil.getDescription(targetClass, false), CommonRefactoringUtil.htmlEmphasize(name)); myConflicts.putValue(innerClass, message); } } } }
public static boolean containsMember(@Nullable PsiType qualifierType, @NotNull Object object) { if (qualifierType instanceof PsiArrayType && object instanceof PsiMember) { // length and clone() PsiFile file = ((PsiMember) object).getContainingFile(); if (file == null || file.getVirtualFile() == null) { // yes, they're a bit dummy return true; } } else if (qualifierType instanceof PsiClassType) { PsiClass qualifierClass = ((PsiClassType) qualifierType).resolve(); if (qualifierClass == null) return false; if (object instanceof PsiMethod && qualifierClass.findMethodBySignature((PsiMethod) object, false) != null) { return true; } if (object instanceof PsiMember) { return qualifierClass.equals(((PsiMember) object).getContainingClass()); } } return false; }
private static boolean isSuperMethod( PsiClass aClass, HierarchicalMethodSignature hierarchicalMethodSignature, HierarchicalMethodSignature superSignatureHierarchical) { PsiMethod superMethod = superSignatureHierarchical.getMethod(); PsiClass superClass = superMethod.getContainingClass(); PsiClass containingClass = hierarchicalMethodSignature.getMethod().getContainingClass(); if (!superMethod.isConstructor()) { if (!aClass.equals(superClass)) { if (PsiUtil.isAccessible(aClass.getProject(), superMethod, aClass, aClass)) { if (MethodSignatureUtil.isSubsignature( superSignatureHierarchical, hierarchicalMethodSignature)) { if (superClass != null) { if (superClass.isInterface() || CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) { if (superMethod.hasModifierProperty(PsiModifier.DEFAULT) || hierarchicalMethodSignature .getMethod() .hasModifierProperty(PsiModifier.DEFAULT)) { return !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true); } return true; } if (containingClass != null) { if (containingClass.isInterface()) { return false; } if (!aClass.isInterface() && !InheritanceUtil.isInheritorOrSelf(superClass, containingClass, true)) { return true; } } } } } } } return false; }
@Nullable @Override public EditorNotificationPanel createNotificationPanel( @NotNull VirtualFile file, @NotNull FileEditor fileEditor) { XDebugSession session = XDebuggerManager.getInstance(myProject).getCurrentSession(); if (session == null) { FILE_PROCESSED_KEY.set(file, null); return null; } XSourcePosition position = session.getCurrentPosition(); if (position == null || !file.equals(position.getFile())) { FILE_PROCESSED_KEY.set(file, null); return null; } if (file.getFileType() == JavaClassFileType.INSTANCE) return null; final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file); if (psiFile == null) return null; if (!(psiFile instanceof PsiJavaFile)) return null; PsiClass[] classes = ((PsiJavaFile) psiFile).getClasses(); if (classes.length == 0) return null; PsiClass baseClass = classes[0]; String name = baseClass.getQualifiedName(); if (name == null) return null; if (DumbService.getInstance(myProject).isDumb()) return null; ArrayList<PsiClass> alts = ContainerUtil.newArrayList( JavaPsiFacade.getInstance(myProject) .findClasses(name, GlobalSearchScope.allScope(myProject))); ContainerUtil.removeDuplicates(alts); FILE_PROCESSED_KEY.set(file, true); if (alts.size() > 1) { for (PsiClass cls : alts) { if (cls.equals(baseClass) || cls.getNavigationElement().equals(baseClass)) { alts.remove(cls); break; } } alts.add(0, baseClass); ComboBoxClassElement[] elems = ContainerUtil.map2Array( alts, ComboBoxClassElement.class, new Function<PsiClass, ComboBoxClassElement>() { @Override public ComboBoxClassElement fun(PsiClass psiClass) { return new ComboBoxClassElement(psiClass); } }); return new AlternativeSourceNotificationPanel(elems, baseClass, myProject, file); } return null; }
@Override public void visitClassObjectAccessExpression(PsiClassObjectAccessExpression expression) { super.visitClassObjectAccessExpression(expression); PsiElement parent = expression.getParent(); if (parent instanceof PsiReferenceExpression) { final PsiReferenceExpression referenceExpression = (PsiReferenceExpression) parent; if (!expression.equals(referenceExpression.getQualifierExpression())) { return; } @NonNls final String name = referenceExpression.getReferenceName(); if (!"getName".equals(name)) { return; } final PsiElement grandParent = referenceExpression.getParent(); if (!(grandParent instanceof PsiMethodCallExpression)) { return; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent; final PsiExpressionList list = methodCallExpression.getArgumentList(); if (list.getExpressions().length != 0) { return; } parent = methodCallExpression.getParent(); } if (!(parent instanceof PsiExpressionList)) { return; } final PsiElement grandParent = parent.getParent(); if (!(grandParent instanceof PsiMethodCallExpression)) { return; } final PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression) grandParent; final PsiExpressionList argumentList = methodCallExpression.getArgumentList(); final PsiExpression[] expressions = argumentList.getExpressions(); if (expressions.length != 1) { return; } final PsiClass containingClass = PsiTreeUtil.getParentOfType(expression, PsiClass.class); if (containingClass == null) { return; } final String containingClassName = containingClass.getName(); if (containingClassName == null) { return; } final PsiMethod method = methodCallExpression.resolveMethod(); if (method == null) { return; } final PsiClass aClass = method.getContainingClass(); if (aClass == null) { return; } final String className = aClass.getQualifiedName(); final int index = loggerFactoryClassNames.indexOf(className); if (index < 0) { return; } final PsiReferenceExpression methodExpression = methodCallExpression.getMethodExpression(); final String referenceName = methodExpression.getReferenceName(); final String loggerFactoryMethodName = loggerFactoryMethodNames.get(index); if (!loggerFactoryMethodName.equals(referenceName)) { return; } final PsiTypeElement operand = expression.getOperand(); final PsiType type = operand.getType(); if (!(type instanceof PsiClassType)) { return; } final PsiClassType classType = (PsiClassType) type; final PsiClass initializerClass = classType.resolve(); if (initializerClass == null) { return; } if (containingClass.equals(initializerClass)) { return; } registerError(expression, containingClassName); }
private Domination dominates( PsiClass aClass, boolean accessible, String fqName, ClassCandidateInfo info) { final PsiClass otherClass = info.getElement(); assert otherClass != null; String otherQName = otherClass.getQualifiedName(); if (fqName.equals(otherQName)) { return Domination.DOMINATED_BY; } final PsiClass containingClass1 = aClass.getContainingClass(); final PsiClass containingClass2 = otherClass.getContainingClass(); if (myAccessClass != null && !Comparing.equal(containingClass1, containingClass2)) { if (myAccessClass.equals(containingClass1)) return Domination.DOMINATES; if (myAccessClass.equals(containingClass2)) return Domination.DOMINATED_BY; } // JLS 8.5: // A class may inherit two or more type declarations with the same name, either from two // interfaces or from its superclass and an interface. // It is a compile-time error to attempt to refer to any ambiguously inherited class or // interface by its simple name. if (containingClass1 != null && containingClass2 != null && containingClass2.isInheritor(containingClass1, true) && !isImported(myCurrentFileContext)) { if (!isAmbiguousInherited(containingClass1)) { // shadowing return Domination.DOMINATED_BY; } } boolean infoAccessible = info.isAccessible() && isAccessible(otherClass); if (infoAccessible && !accessible) { return Domination.DOMINATED_BY; } if (!infoAccessible && accessible) { return Domination.DOMINATES; } // everything wins over class from default package boolean isDefault = StringUtil.getPackageName(fqName).length() == 0; boolean otherDefault = otherQName != null && StringUtil.getPackageName(otherQName).length() == 0; if (isDefault && !otherDefault) { return Domination.DOMINATED_BY; } if (!isDefault && otherDefault) { return Domination.DOMINATES; } // single import wins over on-demand boolean myOnDemand = isOnDemand(myCurrentFileContext, aClass); boolean otherOnDemand = isOnDemand(info.getCurrentFileResolveScope(), otherClass); if (myOnDemand && !otherOnDemand) { return Domination.DOMINATED_BY; } if (!myOnDemand && otherOnDemand) { return Domination.DOMINATES; } return Domination.EQUAL; }
@Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof LanguageDefinition)) return false; return clazz.equals(((LanguageDefinition) o).clazz); }