private static boolean isFieldUnreferenced(final PsiField field) { try { return ReferencesSearch.search(field).forEach(new Processor<PsiReference>() { public boolean process(final PsiReference t) { PsiFile f = t.getElement().getContainingFile(); if (f != null && f.getFileType().equals(StdFileTypes.GUI_DESIGNER_FORM)) { return true; } PsiMethod method = PsiTreeUtil.getParentOfType(t.getElement(), PsiMethod.class); if (method != null && method.getName().equals(AsmCodeGenerator.SETUP_METHOD_NAME)) { return true; } return false; } }); } catch (IndexNotReadyException e) { return false; } }
private static Collection<PsiReference> findPropertyReferences(final Property pproperty, final Module module) { final Collection<PsiReference> references = Collections.synchronizedList(new ArrayList<PsiReference>()); ProgressManager.getInstance().runProcessWithProgressSynchronously( new Runnable() { public void run() { ReferencesSearch.search(pproperty).forEach(new Processor<PsiReference>() { public boolean process(final PsiReference psiReference) { PsiMethod method = PsiTreeUtil.getParentOfType(psiReference.getElement(), PsiMethod.class); if (method == null || !AsmCodeGenerator.SETUP_METHOD_NAME.equals(method.getName())) { references.add(psiReference); } return true; } }); } }, UIDesignerBundle.message("edit.text.searching.references"), false, module.getProject() ); return references; }
private static boolean isFieldUnreferenced(final PsiField field) { try { return ReferencesSearch.search(field).forEach(new Processor<PsiReference>() { public boolean process(final PsiReference t) { PsiFile f = t.getElement().getContainingFile(); if (f != null && f.getFileType().equals(GuiFormFileType.INSTANCE)) { return true; } PsiMethod method = PsiTreeUtil.getParentOfType(t.getElement(), PsiMethod.class); if (method != null && method.getName().equals(AsmCodeGenerator.SETUP_METHOD_NAME)) { return true; } return false; } }); } catch (IndexNotReadyException e) { return false; } }
public static void cleanup(final PsiClass aClass) throws IncorrectOperationException { final PsiMethod[] methods = aClass.findMethodsByName(AsmCodeGenerator.SETUP_METHOD_NAME, false); for(final PsiMethod method : methods) { final PsiClassInitializer[] initializers = aClass.getInitializers(); for(final PsiClassInitializer initializer : initializers) { if(containsMethodIdentifier(initializer, method)) { initializer.delete(); } } method.delete(); } deleteMethods(aClass, AsmCodeGenerator.GET_ROOT_COMPONENT_METHOD_NAME); deleteMethods(aClass, AsmCodeGenerator.LOAD_BUTTON_TEXT_METHOD); deleteMethods(aClass, AsmCodeGenerator.LOAD_LABEL_TEXT_METHOD); }
public static PsiMethod findCreateComponentsMethod(final PsiClass aClass) { PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory(); PsiMethod method; try { method = factory.createMethodFromText("void " + AsmCodeGenerator.CREATE_COMPONENTS_METHOD_NAME + "() {}", aClass); } catch (IncorrectOperationException e) { throw new RuntimeException(e); } return aClass.findMethodBySignature(method, true); }
public boolean isImplicitUsage(PsiElement element) { if (element instanceof PsiMethod) { PsiMethod method = (PsiMethod) element; if ((AsmCodeGenerator.CREATE_COMPONENTS_METHOD_NAME.equals(method.getName()) || AsmCodeGenerator.GET_ROOT_COMPONENT_METHOD_NAME.equals(method.getName()) || AsmCodeGenerator.SETUP_METHOD_NAME.equals(method.getName())) && method.getParameterList().getParametersCount() == 0) { return true; } } return false; }
private static boolean isGeneratedUIInitializer(PsiClassInitializer initializer) { PsiCodeBlock body = initializer.getBody(); if (body.getStatements().length != 1) return false; PsiStatement statement = body.getStatements()[0]; if (!(statement instanceof PsiExpressionStatement) || !(((PsiExpressionStatement)statement).getExpression() instanceof PsiMethodCallExpression)) { return false; } PsiMethodCallExpression call = (PsiMethodCallExpression)((PsiExpressionStatement)statement).getExpression(); return AsmCodeGenerator.SETUP_METHOD_NAME.equals(call.getMethodExpression().getReferenceName()); }
@Override public void visitMethod(PsiMethod method) { if (AsmCodeGenerator.SETUP_METHOD_NAME.equals(method.getName()) || AsmCodeGenerator.GET_ROOT_COMPONENT_METHOD_NAME.equals(method.getName()) || AsmCodeGenerator.LOAD_BUTTON_TEXT_METHOD.equals(method.getName()) || AsmCodeGenerator.LOAD_LABEL_TEXT_METHOD.equals(method.getName())) { addFoldingData(method); } }
@NotNull public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) { PsiExpression lExpression = expression.getLExpression(); if (lExpression instanceof PsiReferenceExpression) { PsiReferenceExpression lExpr = (PsiReferenceExpression)lExpression; PsiElement lElement = lExpr.resolve(); if (!(lElement instanceof PsiField)) { return; } PsiField field = (PsiField) lElement; PsiReference formReference = FormReferenceProvider.getFormReference(field); if (!(formReference instanceof FieldFormReference)) { return; } FieldFormReference ref = (FieldFormReference) formReference; if (ref.isCustomCreate()) { return; } PsiMethod method = PsiTreeUtil.getParentOfType(expression, PsiMethod.class); if (method != null && AsmCodeGenerator.SETUP_METHOD_NAME.equals(method.getName())) { return; } holder.registerProblem(expression, UIDesignerBundle.message("inspection.bound.field.message")); } } }; }
private void generateStubClass(final LwRootContainer rootContainer, final String generatedClassName) throws IOException, CodeGenerationException { @NonNls ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, generatedClassName, null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY); cw.visitField(Opcodes.ACC_PUBLIC, PreviewFormAction.PREVIEW_BINDING_FIELD, "Ljavax/swing/JComponent;", null, null); @NonNls MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); cw.visitEnd(); ByteArrayInputStream bais = new ByteArrayInputStream(cw.toByteArray()); AsmCodeGenerator acg = new AsmCodeGenerator(rootContainer, myFinder, this, true, new PsiClassWriter(myModule)); byte[] data = acg.patchClass(bais); FormErrorInfo[] errors = acg.getErrors(); if (errors.length > 0) { throw new CodeGenerationException(errors [0].getComponentId(), errors [0].getErrorMessage()); } FileOutputStream fos = new FileOutputStream(new File(myTempPath, generatedClassName + ".class")); try { fos.write(data); } finally { fos.close(); } }
/** * Removes all generated sources */ private void vanishGeneratedSources() { final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myProject); final PsiMethod[] methods = cache.getMethodsByName(AsmCodeGenerator.SETUP_METHOD_NAME, GlobalSearchScope.projectScope(myProject)); CodeInsightUtil.preparePsiElementsForWrite(methods); for (int i = 0; i < methods.length; i++) { final PsiMethod method = methods[i]; final PsiClass aClass = method.getContainingClass(); if (aClass != null) { try { final PsiFile psiFile = aClass.getContainingFile(); LOG.assertTrue(psiFile != null); final VirtualFile vFile = psiFile.getVirtualFile(); LOG.assertTrue(vFile != null); myProgressWindow.setText(UIDesignerBundle.message("progress.converting", vFile.getPresentableUrl())); myProgressWindow.setFraction(((double)i) / ((double)methods.length)); if (vFile.isWritable()) { FormSourceCodeGenerator.cleanup(aClass); } } catch (IncorrectOperationException e) { LOG.error(e); } } } }
private AsmCodeGenerator initCodeGenerator(final String formFileName, final String className, final String testDataPath) throws Exception { String tmpPath = FileUtil.getTempDirectory(); String formPath = testDataPath + formFileName; String javaPath = testDataPath + className + ".java"; final int rc = Main.compile(new String[]{"-d", tmpPath, javaPath}); assertEquals(0, rc); final String classPath = tmpPath + "/" + className + ".class"; final File classFile = new File(classPath); assertTrue(classFile.exists()); final LwRootContainer rootContainer = loadFormData(formPath); final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, myClassFinder, myNestedFormLoader, false, new ClassWriter(ClassWriter.COMPUTE_FRAMES)); final FileInputStream classStream = new FileInputStream(classFile); try { codeGenerator.patchClass(classStream); } finally { classStream.close(); FileUtil.delete(classFile); final File[] inners = new File(tmpPath).listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.startsWith(className + "$") && name.endsWith(".class"); } }); if (inners != null) { for (File file : inners) FileUtil.delete(file); } } return codeGenerator; }
private Class loadAndPatchClass(final String formFileName, final String className) throws Exception { final AsmCodeGenerator codeGenerator = initCodeGenerator(formFileName, className); byte[] patchedData = getVerifiedPatchedData(codeGenerator); /* FileOutputStream fos = new FileOutputStream("C:\\yole\\FormPreview27447\\MainPatched.class"); fos.write(patchedData); fos.close(); */ myClassFinder.addClassDefinition(className, patchedData); return myClassFinder.getLoader().loadClass(className); }
private static byte[] getVerifiedPatchedData(final AsmCodeGenerator codeGenerator) { byte[] patchedData = codeGenerator.getPatchedData(); FormErrorInfo[] errors = codeGenerator.getErrors(); FormErrorInfo[] warnings = codeGenerator.getWarnings(); if (errors.length == 0 && warnings.length == 0) { assertNotNull("Class patching failed but no errors or warnings were returned", patchedData); } else if (errors.length > 0) { assertTrue(errors[0].getErrorMessage(), false); } else { assertTrue(warnings[0].getErrorMessage(), false); } return patchedData; }
@NotNull public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) { return new JavaElementVisitor() { @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) { if (expression.getLExpression() instanceof PsiReferenceExpression) { PsiMethod method = PsiTreeUtil.getParentOfType(expression, PsiMethod.class); if (method != null && AsmCodeGenerator.SETUP_METHOD_NAME.equals(method.getName())) { return; } PsiReferenceExpression lExpr = (PsiReferenceExpression) expression.getLExpression(); PsiElement lElement = lExpr.resolve(); if (lElement instanceof PsiField) { PsiField field = (PsiField) lElement; PsiReference formReference = FormReferenceProvider.getFormReference(field); if (formReference instanceof FieldFormReference) { FieldFormReference ref = (FieldFormReference) formReference; if (!ref.isCustomCreate()) { holder.registerProblem(expression, UIDesignerBundle.message("inspection.bound.field.message"), new LocalQuickFix[0]); } } } } } }; }
private void generateStubClass(final LwRootContainer rootContainer, final String generatedClassName) throws IOException, CodeGenerationException { @NonNls ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); cw.visit(Opcodes.V1_1, Opcodes.ACC_PUBLIC, generatedClassName, null, "java/lang/Object", ArrayUtil.EMPTY_STRING_ARRAY); cw.visitField(Opcodes.ACC_PUBLIC, PreviewFormAction.PREVIEW_BINDING_FIELD, "Ljavax/swing/JComponent;", null, null); @NonNls MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null); mv.visitCode(); mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V"); mv.visitInsn(Opcodes.RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); cw.visitEnd(); ByteArrayInputStream bais = new ByteArrayInputStream(cw.toByteArray()); AsmCodeGenerator acg = new AsmCodeGenerator(rootContainer, myFinder, this, true, new PsiClassWriter(myModule)); byte[] data = acg.patchClass(bais); FormErrorInfo[] errors = acg.getErrors(); if (errors.length > 0) { throw new CodeGenerationException(errors [0].getComponentId(), errors [0].getErrorMessage()); } FileOutputStream fos = new FileOutputStream(new File(myTempPath, generatedClassName + ".class")); try { fos.write(data); } finally { fos.close(); } }
private AsmCodeGenerator initCodeGenerator(final String formFileName, final String className, final String testDataPath) throws Exception { String tmpPath = FileUtil.getTempDirectory(); String formPath = testDataPath + formFileName; String javaPath = testDataPath + className + ".java"; com.sun.tools.javac.Main.compile(new String[] { "-d", tmpPath, javaPath } ); String classPath = tmpPath + "/" + className + ".class"; final LwRootContainer rootContainer = loadFormData(formPath); final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, myClassFinder, myNestedFormLoader, false, new ClassWriter(ClassWriter.COMPUTE_FRAMES)); final FileInputStream classStream = new FileInputStream(classPath); try { codeGenerator.patchClass(classStream); } finally { classStream.close(); FileUtil.delete(new File(classPath)); final File[] inners = new File(tmpPath).listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return name.startsWith(className + "$") && name.endsWith(".class"); } }); if (inners != null) { for (File file : inners) FileUtil.delete(file); } } return codeGenerator; }
public static PsiMethod findCreateComponentsMethod(final PsiClass aClass) { PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory(); PsiMethod method; try { method = factory.createMethodFromText("void " + AsmCodeGenerator.CREATE_COMPONENTS_METHOD_NAME + "() {}", aClass); } catch(IncorrectOperationException e) { throw new RuntimeException(e); } return aClass.findMethodBySignature(method, true); }
/** * Removes all generated sources */ private void vanishGeneratedSources() { final PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myProject); final PsiMethod[] methods = cache.getMethodsByName(AsmCodeGenerator.SETUP_METHOD_NAME, GlobalSearchScope.projectScope(myProject)); CodeInsightUtil.preparePsiElementsForWrite(methods); for(int i = 0; i < methods.length; i++) { final PsiMethod method = methods[i]; final PsiClass aClass = method.getContainingClass(); if(aClass != null) { try { final PsiFile psiFile = aClass.getContainingFile(); LOG.assertTrue(psiFile != null); final VirtualFile vFile = psiFile.getVirtualFile(); LOG.assertTrue(vFile != null); myProgressWindow.setText(UIDesignerBundle.message("progress.converting", vFile.getPresentableUrl())); myProgressWindow.setFraction(((double) i) / ((double) methods.length)); if(vFile.isWritable()) { FormSourceCodeGenerator.cleanup(aClass); } } catch(IncorrectOperationException e) { LOG.error(e); } } } }
private AsmCodeGenerator initCodeGenerator(final String formFileName, final String className) throws Exception { final String testDataPath = PluginPathManager.getPluginHomePath("ui-designer") + "/testData/"; return initCodeGenerator(formFileName, className, testDataPath); }
public void testNoSuchField() throws Exception { AsmCodeGenerator generator = initCodeGenerator("TestNoSuchField.form", "BindingTest"); assertEquals("Cannot bind: field does not exist: BindingTest.myNoSuchField", generator.getErrors() [0].getErrorMessage()); }
public void testStaticField() throws Exception { AsmCodeGenerator generator = initCodeGenerator("TestStaticField.form", "BindingTest"); assertEquals("Cannot bind: field is static: BindingTest.myStaticField", generator.getErrors() [0].getErrorMessage()); }