blob: be60bffa6c09aebdad64a96206ff4ab86277f607 [file] [log] [blame]
/*
* Copyright 2001-2013 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.generate.tostring.element;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.*;
import org.jetbrains.generate.tostring.psi.PsiAdapter;
/**
* Factory for creating {@link FieldElement} or {@link ClassElement} objects.
*/
public class ElementFactory {
private static final Logger log = Logger.getInstance("#org.jetbrains.generate.tostring.element.ElementFactory");
private ElementFactory() {
}
/**
* Creates a new {@link ClassElement} object.
*
* @param clazz class information.
* @return a new {@link ClassElement} object.
*/
public static ClassElement newClassElement(PsiClass clazz) {
ClassElement ce = new ClassElement();
// name
ce.setName(clazz.getName());
ce.setQualifiedName(clazz.getQualifiedName());
// super
PsiClass superClass = clazz.getSuperClass();
if (superClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(superClass.getQualifiedName())) {
ce.setSuperName(superClass.getName());
}
// interfaces
ce.setImplementNames(PsiAdapter.getImplementsClassnames(clazz));
// other
ce.setEnum(clazz.isEnum());
ce.setDeprecated(clazz.isDeprecated());
ce.setException(PsiAdapter.isExceptionClass(clazz));
ce.setAbstract(clazz.hasModifierProperty(PsiModifier.ABSTRACT));
return ce;
}
/**
* Create a new {@link FieldElement} object.
*
* @param field the {@link com.intellij.psi.PsiField} to get the information from.
* @return a new {@link FieldElement} object.
*/
public static FieldElement newFieldElement(PsiField field) {
FieldElement fe = new FieldElement();
fe.setName(field.getName());
if (PsiAdapter.isConstantField(field)) fe.setConstant(true);
if (PsiAdapter.isEnumField(field)) fe.setEnum(true);
PsiModifierList modifiers = field.getModifierList();
if (modifiers != null) {
if (modifiers.hasModifierProperty(PsiModifier.TRANSIENT)) fe.setModifierTransient(true);
if (modifiers.hasModifierProperty(PsiModifier.VOLATILE)) fe.setModifierVolatile(true);
}
PsiElementFactory factory = JavaPsiFacade.getInstance(field.getProject()).getElementFactory();
PsiType type = field.getType();
setElementInfo(fe, factory, type, modifiers);
return fe;
}
/**
* Creates a new {@link MethodElement} object.
*
* @param method the PSI method object.
* @return a new {@link MethodElement} object.
* @since 2.15
*/
public static MethodElement newMethodElement(PsiMethod method) {
MethodElement me = new MethodElement();
PsiType type = method.getReturnType();
PsiModifierList modifiers = method.getModifierList();
// if something is wrong:
// http://www.intellij.net/forums/thread.jsp?nav=false&forum=18&thread=88676&start=0&msRange=15
if (type == null) {
log.warn("This method does not have a valid return type: " + method.getName() + ", returnType=" + type);
return me;
}
PsiElementFactory factory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
setElementInfo(me, factory, type, modifiers);
// names
String fieldName = PsiAdapter.getGetterFieldName(method);
me.setName(fieldName == null ? method.getName() : fieldName);
me.setFieldName(fieldName);
me.setMethodName(method.getName());
// getter
me.setGetter(PsiAdapter.isGetterMethod(method));
// misc
me.setDeprecated(method.isDeprecated());
me.setReturnTypeVoid(PsiAdapter.isTypeOfVoid(method.getReturnType()));
// modifiers
if (modifiers.hasModifierProperty(PsiModifier.ABSTRACT)) me.setModifierAbstract(true);
if (modifiers.hasModifierProperty(PsiModifier.SYNCHRONIZED)) me.setModifierSynchronized(true);
return me;
}
/**
* 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));
// 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);
// 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);
}
}
}