OSDN Git Service

original
[gb-231r1-is01/GB_2.3_IS01.git] / cts / tools / annotation-helper / src / spechelper / MethodSelector.java
diff --git a/cts/tools/annotation-helper/src/spechelper/MethodSelector.java b/cts/tools/annotation-helper/src/spechelper/MethodSelector.java
new file mode 100644 (file)
index 0000000..a0b4bba
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * 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 spechelper;
+
+import org.eclipse.jdt.core.Flags;
+import org.eclipse.jdt.core.ICompilationUnit;
+import org.eclipse.jdt.core.IJavaProject;
+import org.eclipse.jdt.core.IMethod;
+import org.eclipse.jdt.core.IType;
+import org.eclipse.jdt.core.ITypeParameter;
+import org.eclipse.jdt.core.JavaModelException;
+import org.eclipse.jdt.core.Signature;
+import org.eclipse.jdt.core.dom.AST;
+import org.eclipse.jdt.core.dom.ASTParser;
+import org.eclipse.jdt.core.dom.ASTVisitor;
+import org.eclipse.jdt.core.dom.CompilationUnit;
+import org.eclipse.jdt.core.dom.Expression;
+import org.eclipse.jdt.core.dom.ITypeBinding;
+import org.eclipse.jdt.core.dom.SingleMemberAnnotation;
+import org.eclipse.jdt.internal.ui.JavaPlugin;
+import org.eclipse.jdt.ui.JavaElementLabelProvider;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.IEditorInput;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.dialogs.ElementListSelectionDialog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 
+ */
+public class MethodSelector {
+
+    public String obtainReplacement(String buffer) {
+        IMethod method = selectMethod();
+        // if user did cancel the selection
+        if (method == null) {
+            return null;
+        }
+
+        // see if we are already in a annotation:
+        // if yes -> only dump the testtarget annotation, not the complete
+        // TestInfo
+        // (could not easily find this out with CompilationUnit, since inserting
+        // a :
+        // broke the AST - maybe use WorkingCopy and so on,
+        // but for now: do it with simple String analysis
+        boolean shortOnly = false;
+        int annotPos = buffer.lastIndexOf("@TestInfo");
+        // the latest annotation - count "(" ")" pairs - if not the same count
+        // we assume to be in the annotation (H: code compiles fine)
+        if (annotPos != -1) {
+            String sub = buffer.substring(annotPos);
+            // only consider the latest 6 lines for the annotation to occur
+            // (6 = range within which the annotation @TestTarget
+            // must occur, but out of range to reach the annotation from the
+            // previous method - ah i'd prefer working with compilationUnit...
+            String[] lines = sub.split("\n");
+            for (int i = lines.length - 6; i < lines.length; i++) {
+                String line = lines[i];
+                if (line.contains("@TestTarget")) {
+                    shortOnly = true;
+                }
+            }
+        }
+
+        return generateAnnotation(shortOnly, method);
+    }
+
+
+    private String generateAnnotation(boolean shortOnly, IMethod method) {
+        String[] ptypes = method.getParameterTypes();
+        String param = "";
+        for (int i = 0; i < ptypes.length; i++) {
+            String ptype = ptypes[i];
+            String sig = Signature.toString(ptype);
+            // kind of a hack: convert all Generic Type args to Object, or to
+            // its bound Type
+            if (sig.length() == 1) {
+                ITypeParameter tps = method.getTypeParameter(sig);
+                sig = "Object";
+
+                if (tps != null && tps.exists()) {
+                    try {
+                        String[] bounds = tps.getBounds();
+                        if (bounds.length > 0) {
+                            sig = bounds[0];
+                        }
+                    } catch (JavaModelException e) {
+                        e.printStackTrace();
+                    }
+
+                }
+            }
+            // omit type signature
+            sig = sig.replaceAll("<.*>", "");
+            param += (i > 0 ? ", " : "") + sig + ".class";
+        }
+        String IND = "    ";
+
+        String targ = "@TestTarget(\n" + IND + "      methodName = \""
+                + method.getElementName() + "\",\n" + IND
+                + "      methodArgs = {" + param + "}\n" + IND + "    )\n";
+
+        String s;
+        if (shortOnly) {
+            s = targ;
+        } else {
+
+            s = "@TestInfo(\n" + IND + "  status = TestStatus.TBR,\n" + IND
+                    + "  notes = \"\",\n" + IND + "  targets = {\n" + IND
+                    + "    " + targ + IND + "})";
+        }
+        return s;
+    }
+
+    private IMethod selectMethod() {
+        IEditorPart part = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+                .getActivePage().getActiveEditor();
+        Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
+                .getShell();
+        IEditorInput ei = part.getEditorInput();
+        final ICompilationUnit cu = JavaPlugin.getDefault()
+                .getWorkingCopyManager().getWorkingCopy(ei);
+        // cu != null since we register only for java/javadoc completion
+        // proposals
+        ASTParser parser = ASTParser.newParser(AST.JLS3);
+        parser.setSource(cu);
+        parser.setResolveBindings(true);
+        CompilationUnit unit = (CompilationUnit) parser.createAST(null);
+
+        class MHolder {
+            IMethod method;
+        }
+        final MHolder mholder = new MHolder();
+
+        class FHolder {
+            boolean foundClassAnnotation;
+        }
+        final FHolder fholder = new FHolder();
+
+        unit.accept(new ASTVisitor() {
+            public boolean visit(SingleMemberAnnotation node) {
+                String name = node.getTypeName().getFullyQualifiedName();
+                if (!name.equals("TestTargetClass")) {
+                    return false;
+                }
+                fholder.foundClassAnnotation = true;
+                Expression targetClassE = node.getValue();
+                ITypeBinding ty = targetClassE.resolveTypeBinding();
+                if (ty == null) {
+                    return false;
+                }
+                ITypeBinding[] classTypes = ty.getTypeArguments();
+                if (classTypes.length > 0) {
+                    ITypeBinding tp = classTypes[0];
+                    String qname = tp.getQualifiedName();
+                    System.out.println("qname:" + qname);
+                    IJavaProject myProject = cu.getJavaProject();
+                    try {
+                        IType myType = myProject.findType(qname);
+                        if (myType != null) {
+                            Shell parent = PlatformUI.getWorkbench()
+                                    .getActiveWorkbenchWindow().getShell();
+                            ElementListSelectionDialog dialog = new ElementListSelectionDialog(
+                                    parent,
+                                    new JavaElementLabelProvider(
+                                            JavaElementLabelProvider.SHOW_PARAMETERS
+                                                    | JavaElementLabelProvider.SHOW_OVERLAY_ICONS
+                                                    | JavaElementLabelProvider.SHOW_RETURN_TYPE));
+                            // restrict to public/protected methods only
+                            IMethod[] allMeth = myType.getMethods();
+                            List<IMethod> pubproMethods = new ArrayList<IMethod>();
+                            for (int i = 0; i < allMeth.length; i++) {
+                                IMethod method = allMeth[i];
+                                if ((method.getFlags() & (Flags.AccPublic | Flags.AccProtected)) != 0) {
+                                    pubproMethods.add(method);
+                                }
+                            }
+                            IMethod[] res = pubproMethods
+                                    .toArray(new IMethod[pubproMethods.size()]);
+                            dialog.setIgnoreCase(true);
+                            dialog.setBlockOnOpen(true);
+                            dialog.setElements(res);//
+                            dialog.setFilter("");
+                            dialog.setTitle(qname);
+                            if (dialog.open() != IDialogConstants.CANCEL_ID) {
+                                Object[] types = dialog.getResult();
+                                System.out.println("selected:" + types[0]);
+                                IMethod method = (IMethod) types[0];
+                                mholder.method = method;
+
+                            } else {
+                                // System.out.println("cancelled!!");
+                            }
+                        }
+                    } catch (JavaModelException e) {
+                        e.printStackTrace();
+                    }
+                }
+                return true;
+            }
+        });
+        if (!fholder.foundClassAnnotation) {
+            MessageDialog.openInformation(shell, "Class Annotation missing",
+                    "@TestTargetClass(...) is missing");
+            return null;
+        }
+        return mholder.method;
+    }
+}