Skip to content

Commit

Permalink
restructured the code & made it keeps the old declarations
Browse files Browse the repository at this point in the history
  • Loading branch information
nekocode committed Feb 19, 2016
1 parent eaecd37 commit 6ebff14
Show file tree
Hide file tree
Showing 6 changed files with 242 additions and 200 deletions.
2 changes: 1 addition & 1 deletion META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<idea-plugin version="2">
<id>cn.nekocode.plugin.parcelablegenerator</id>
<name>Parcelable Code Generator(for kotlin's data class)</name>
<version>0.4.0</version>
<version>0.4.2</version>
<vendor email="[email protected]" url="https://github.com/nekocode/android-parcelable-intellij-plugin-kotlin">nekocode</vendor>

<description><![CDATA[
Expand Down
142 changes: 33 additions & 109 deletions src/cn/nekocode/plugin/parcelablegenerator/CodeGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.ImportPath;
import org.jetbrains.kotlin.types.KotlinType;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static cn.nekocode.plugin.parcelablegenerator.typeserializers.TypeSerializerFactory.createTypeSerializers;


/**
* Created by nekocode on 2015/12/1.
Expand Down Expand Up @@ -116,9 +116,31 @@ public void generate() {
}


// Clean Class Body
// Save old declarations and clean Class Body
List<KtDeclaration> oldDeclarations = new ArrayList<>();
KtClassBody body = mClass.getBody();

if(body != null) {
List<KtDeclaration> declarations = body.getDeclarations();

if(declarations.size() != 0) {
for(KtDeclaration declaration: declarations) {
if(declaration instanceof KtSecondaryConstructor) {

} else if(declaration instanceof KtObjectDeclaration) {

} else if(declaration instanceof KtNamedFunction) {
String name = declaration.getName();
if(name != null && !name.equals("describeContents") && !name.equals("writeToParcel")) {
oldDeclarations.add(declaration);
}

} else {
oldDeclarations.add(declaration);
}
}
}

body.delete();
}

Expand Down Expand Up @@ -147,117 +169,19 @@ public void generate() {
mClass.addAfter(elementFactory.createWhiteSpace(), mClass.getLastChild());
}

// Add old declarations
String oldDeclarationsStr = "";
for(KtDeclaration declaration: oldDeclarations) {
oldDeclarationsStr += declaration.getText() + "\n\n";
}

List<TypeSerializer> typeSerializers = getTypeSerializers(mFields);
String block = generateConstructor(typeSerializers) + "\n\n" +
List<TypeSerializer> typeSerializers = createTypeSerializers(mFields);
String block = oldDeclarationsStr +
generateConstructor(typeSerializers) + "\n\n" +
generateDescribeContents() + "\n\n" +
generateWriteToParcel(typeSerializers) + "\n\n" +
generateStaticCreator(mClass);

mClass.addAfter(elementFactory.createBlock(block), mClass.getLastChild());

}

private List<TypeSerializer> getTypeSerializers(List<ValueParameterDescriptor> fields) {
List<TypeSerializer> typeSerializers = new ArrayList<>();
for(ValueParameterDescriptor field : fields) {
KotlinType type = field.getType();
String typeName = type.toString();

switch (typeName) {
case "String":
case "Byte":
case "Double":
case "Float":
case "Int":
case "Long":
typeSerializers.add(new NormalSerializer(field));
break;

case "Boolean":
typeSerializers.add(new BooleanSerializer(field));
break;

case "Char":
typeSerializers.add(new CharSerializer(field));
break;

case "List<String>":
typeSerializers.add(new StringListSerializer(field));
break;

case "Array<String>":
case "ByteArray":
case "DoubleArray":
case "FloatArray":
case "IntArray":
case "LongArray":
case "CharArray":
case "BooleanArray":
typeSerializers.add(new NormalArraySerializer(field));
break;

default:
Collection<KotlinType> supertypes = null;

// Check if type is List or Array
if(typeName.startsWith("List")) {
KotlinType typeProjectionType = type.getArguments().get(0).getType();

Boolean isParcelable = false;
supertypes = typeProjectionType.getConstructor().getSupertypes();
for(KotlinType supertype : supertypes) {
String supertypeName = supertype.toString();
if(supertypeName.equals("Parcelable")) {
typeSerializers.add(new ParcelableListSerializer(field));
isParcelable = true;
break;
}
}

if(!isParcelable) {
typeSerializers.add(new NormalListSerializer(field));
}


} else if(typeName.startsWith("Array")) {
KotlinType typeProjectionType = type.getArguments().get(0).getType();

supertypes = typeProjectionType.getConstructor().getSupertypes();
for(KotlinType supertype : supertypes) {
String supertypeName = supertype.toString();
if(supertypeName.equals("Parcelable")) {
typeSerializers.add(new ParcelableArraySerializer(field));
break;
}
}


} else {
// Check if supertype is Parcelable or Serializable
boolean found = false;
supertypes = type.getConstructor().getSupertypes();
for(KotlinType supertype : supertypes) {
String supertypeName = supertype.toString();
if(supertypeName.equals("Parcelable")) {
typeSerializers.add(new ParcelableObjectSerializer(field));
found = true;
break;

} else if(supertypeName.equals("Serializable")) {
typeSerializers.add(new SerializableObjectSerializer(field));
found = true;
break;
}
}

// Not found
if(!found) {
typeSerializers.add(new NormalSerializer(field));
}
}
}
}
return typeSerializers;
}
}
38 changes: 4 additions & 34 deletions src/cn/nekocode/plugin/parcelablegenerator/GenerateDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,18 @@
*/
package cn.nekocode.plugin.parcelablegenerator;

import com.intellij.openapi.project.Project;
import cn.nekocode.plugin.parcelablegenerator.utils.KtClassHelper;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.psi.PsiElement;
import com.intellij.ui.CollectionListModel;
import com.intellij.ui.ToolbarDecorator;
import com.intellij.ui.components.JBList;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.psi.KtClass;
import org.jetbrains.kotlin.psi.KtElement;
import org.jetbrains.kotlin.resolve.lazy.ResolveSession;

import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;

/**
Expand All @@ -45,11 +37,11 @@ public class GenerateDialog extends DialogWrapper {
private final LabeledComponent<JPanel> myComponent;
private CollectionListModel<ValueParameterDescriptor> myFileds;

protected GenerateDialog(Project project, KtClass ktClass) {
super(project);
protected GenerateDialog(KtClass ktClass) {
super(ktClass.getProject());
setTitle("Select Fields for Parcelable Generation");

myFileds = new CollectionListModel<ValueParameterDescriptor>(findParams(ktClass));
myFileds = new CollectionListModel<>(KtClassHelper.findParams(ktClass));

JBList fieldList = new JBList(myFileds);
fieldList.setCellRenderer(new DefaultListCellRenderer() {
Expand All @@ -71,28 +63,6 @@ public Component getListCellRendererComponent(JList list, Object value, int inde
init();
}

private List<ValueParameterDescriptor> findParams(PsiElement element) {
List<KtElement> list = new ArrayList<>();
list.add((KtElement) element);

ResolveSession resolveSession = KotlinCacheService.Companion.getInstance(element.getProject()).
getResolutionFacade(list).getFrontendService(ResolveSession.class);
ClassDescriptor classDescriptor = resolveSession.getClassDescriptor((KtClass) element, NoLookupLocation.FROM_IDE);

List<ValueParameterDescriptor> valueParameters = new ArrayList<>();
if (classDescriptor.isData()) {
ConstructorDescriptor constructorDescriptor = classDescriptor.getUnsubstitutedPrimaryConstructor();

if (constructorDescriptor != null) {
List<ValueParameterDescriptor> allParameters = constructorDescriptor.getValueParameters();

allParameters.stream().forEach(valueParameters::add);
}
}

return valueParameters;
}

@Nullable
@Override
protected JComponent createCenterPanel() {
Expand Down
60 changes: 4 additions & 56 deletions src/cn/nekocode/plugin/parcelablegenerator/ParcelableAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package cn.nekocode.plugin.parcelablegenerator;

import cn.nekocode.plugin.parcelablegenerator.utils.KtClassHelper;
import com.intellij.ide.projectView.impl.ProjectRootsUtil;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.command.WriteCommandAction;
Expand All @@ -23,19 +24,11 @@
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.*;

import java.util.ArrayList;
import java.util.List;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.asJava.KtLightElement;
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor;
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor;
import org.jetbrains.kotlin.idea.internal.Location;
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.lazy.ResolveSession;

/**
* Created by nekocode on 2015/12/1.
Expand All @@ -54,32 +47,12 @@ public void actionPerformed(AnActionEvent e) {
// GenerateDialog dlg = new GenerateDialog(ktClass);
// dlg.show();
// if (dlg.isOK()) {
generateParcelable(ktClass, findParams(ktClass));
// generateParcelable(ktClass, dlg.getSelectedFields());
// }
}
}
}

private List<ValueParameterDescriptor> findParams(PsiElement element) {
List<KtElement> list = new ArrayList<>();
list.add((KtElement) element);

ResolveSession resolveSession = KotlinCacheService.Companion.getInstance(element.getProject()).
getResolutionFacade(list).getFrontendService(ResolveSession.class);
ClassDescriptor classDescriptor = resolveSession.getClassDescriptor((KtClassOrObject) element, NoLookupLocation.FROM_IDE);

List<ValueParameterDescriptor> valueParameters = new ArrayList<>();
if (classDescriptor.isData()) {
ConstructorDescriptor constructorDescriptor = classDescriptor.getUnsubstitutedPrimaryConstructor();

if (constructorDescriptor != null) {
List<ValueParameterDescriptor> allParameters = constructorDescriptor.getValueParameters();

allParameters.stream().forEach(valueParameters::add);
generateParcelable(ktClass, KtClassHelper.findParams(ktClass));
}
}

return valueParameters;
}

private void generateParcelable(final KtClass ktClass, final List<ValueParameterDescriptor> fields) {
Expand Down Expand Up @@ -113,31 +86,6 @@ private KtClass getPsiClassFromEvent(AnActionEvent e) {
PsiElement psiElement = psiFile.findElementAt(location.getStartOffset());
if (psiElement == null) return null;

return getKtClass(psiElement);
}

private KtClass getKtClass(@NotNull PsiElement psiElement) {
if (psiElement instanceof KtLightElement) {
PsiElement origin = ((KtLightElement) psiElement).getOrigin();
if (origin != null) {
return getKtClass(origin);
} else {
return null;
}

} else if (psiElement instanceof KtClass && !((KtClass) psiElement).isEnum() &&
!((KtClass) psiElement).isInterface() &&
!((KtClass) psiElement).isAnnotation() &&
!((KtClass) psiElement).isSealed()) {
return (KtClass) psiElement;

} else {
PsiElement parent = psiElement.getParent();
if (parent == null) {
return null;
} else {
return getKtClass(parent);
}
}
return KtClassHelper.getKtClassForElement(psiElement);
}
}
Loading

0 comments on commit 6ebff14

Please sign in to comment.