Source Code Cross Referenced for StaticAnalysis.java in  » IDE » tIDE » tide » staticanalysis » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE » tIDE » tide.staticanalysis 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package tide.staticanalysis;
002:
003:        import tide.project.ProjectSettings;
004:        import tide.bytecode.asm.RecurseChecker;
005:        import tide.classsyntax.RefClassUtils;
006:        import javax.swing.JOptionPane;
007:        import tide.project.ClassFilesManager;
008:        import tide.editor.linemessages.MessagesTable;
009:        import tide.bytecode.asm.ASMethod;
010:        import tide.bytecode.asm.OverrideMustInvokeChecker;
011:        import java.lang.annotation.Annotation;
012:        import snow.utils.StringUtils;
013:        import tide.editor.linemessages.LineMessagesManager;
014:        import javaparser.TreeUtils;
015:        import tide.utils.SyntaxUtils;
016:        import javaparser.Parameter;
017:        import tide.classsyntax.ClassUtils;
018:        import tide.utils.BytecodeUtils;
019:        import snow.utils.gui.ProgressModalDialog;
020:        import tide.editor.MainEditorFrame;
021:        import javaparser.ParserTreeNode;
022:        import javaparser.MethodNode;
023:        import javaparser.ClassNode;
024:        import javaparser.TypeNode;
025:        import tide.syntaxtree.SimplifiedSyntaxTree2;
026:        import javaparser.RAWSyntaxTree;
027:        import javaparser.javacc_gen.JavaParser;
028:        import java.io.StringReader;
029:        import java.lang.reflect.*;
030:        import tide.classsyntax.SingleClassLoader;
031:        import tide.sources.SourceFile;
032:        import java.util.*;
033:
034:        /**
035:         *  [Oct2007]: first motivation: enforce Override declarations !
036:         *    => after JLint Lint4J and Xlint:  Tlint is born !
037:         *   no other tool find them. They must use source (cause of annotation retention that limit existence to source)
038:         *  TODO: also look in anonymous classes, typically adapters (or search for new XXAdapter(){
039:         TODO2: check @edu.umd.cs.findbugs.annotations.OverrideMustInvoke
040:         TODO3: make HTMLEditorKit.ParserCallback override correctly handled
041:         */
042:        public final class StaticAnalysis {
043:
044:            static private final boolean debug = false;
045:
046:            // Set in StaticAnalysisSettingsDialog, saved here, in the project settings
047:
048:            static boolean autoApplyOnChangedClasses = false;
049:
050:            static boolean detectMissingOverrides = true; // or overloads
051:            static boolean detectStaticOverloads = true;
052:            static boolean detectNearOverrides = true; // = overload
053:            static boolean detectPrivateOverloads = true;
054:
055:            static boolean detectOverrideMustInvoke = true;
056:
057:            static boolean detectRecurseAnn = true;
058:            static boolean detectMissingRecurseAnn = true;
059:
060:            static boolean detectImplementsAnn = true; // attempt
061:
062:            // Settings Persistance
063:
064:            /** Should be called at project changes. (load)
065:             */
066:            public static void readSettings(final ProjectSettings proj) {
067:                autoApplyOnChangedClasses = proj.getBooleanProperty(
068:                        "SA_autoApplyOnChangedClasses", false);
069:
070:                detectMissingOverrides = proj.getBooleanProperty(
071:                        "SA_detectMissingOverrides", true);
072:                detectStaticOverloads = proj.getBooleanProperty(
073:                        "SA_detectStaticOverloads", true);
074:                detectNearOverrides = proj.getBooleanProperty(
075:                        "SA_detectNearOverrides", true);
076:                detectPrivateOverloads = proj.getBooleanProperty(
077:                        "SA_detectPrivateOverloads", true);
078:
079:                detectOverrideMustInvoke = proj.getBooleanProperty(
080:                        "SA_detectOverrideMustInvoke", true);
081:
082:                detectRecurseAnn = proj.getBooleanProperty(
083:                        "SA_detectRecurseAnn", true);
084:                detectMissingRecurseAnn = proj.getBooleanProperty(
085:                        "SA_detectMissingRecurseAnn", true);
086:
087:                detectImplementsAnn = proj.getBooleanProperty(
088:                        "SA_detectImplementsAnn", true);
089:            }
090:
091:            /** Should be called on changes only => from the dialog.
092:             */
093:            public static void saveSettings(final ProjectSettings proj) {
094:                proj.setBooleanProperty("SA_autoApplyOnChangedClasses",
095:                        autoApplyOnChangedClasses);
096:
097:                proj.setBooleanProperty("SA_detectMissingOverrides",
098:                        detectMissingOverrides);
099:                proj.setBooleanProperty("SA_detectStaticOverloads",
100:                        detectStaticOverloads);
101:                proj.setBooleanProperty("SA_detectNearOverrides",
102:                        detectNearOverrides);
103:                proj.setBooleanProperty("SA_detectPrivateOverloads",
104:                        detectPrivateOverloads);
105:
106:                proj.setBooleanProperty("SA_detectOverrideMustInvoke",
107:                        detectOverrideMustInvoke);
108:
109:                proj
110:                        .setBooleanProperty("SA_detectRecurseAnn",
111:                                detectRecurseAnn);
112:                proj.setBooleanProperty("SA_detectMissingRecurseAnn",
113:                        detectMissingRecurseAnn);
114:
115:                proj.setBooleanProperty("SA_detectImplementsAnn",
116:                        detectImplementsAnn);
117:            }
118:
119:            private StaticAnalysis() {
120:            }
121:
122:            @edu.umd.cs.findbugs.annotations.OverrideMustInvoke
123:            public static void analyse(final List<SourceFile> srcs) {
124:
125:                if (MainEditorFrame.instance.getActualProject()
126:                        .getClassFilesManager() == null) {
127:                    // some info for the impatients:
128:                    JOptionPane
129:                            .showMessageDialog(
130:                                    null,
131:                                    "The project classes are not already loaded, try again later..."
132:                                            + "\n\nNote:\n  The JDK and project classes are loaded lazily in background"
133:                                            + "\n  to make tIDE immediately responsive for editing at startup."
134:                                            + "\n  Advanced features such as the static analysis however requires full loading.",
135:                                    "Warning", JOptionPane.ERROR_MESSAGE);
136:                    return;
137:                }
138:
139:                MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
140:                        .clearDocument();
141:                MainEditorFrame.instance.outputPanels.selectToolsTab(false);
142:                String title = "TLint analysis of " + srcs.size() + " source"
143:                        + (srcs.size() == 1 ? "" : "s");
144:                MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
145:                        .appendLine(title);
146:
147:                final ProgressModalDialog pmd = new ProgressModalDialog(
148:                        MainEditorFrame.instance, title, false);
149:                pmd.setProgressBounds(srcs.size());
150:                pmd.start();
151:
152:                Thread t = new Thread() {
153:                    public void run() {
154:                        int w = 0;
155:                        try {
156:                            for (SourceFile sfi : srcs) {
157:                                if (pmd.getWasCancelled()) {
158:                                    MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
159:                                            .appendErrorLine("\nAnalysis cancelled.");
160:                                    return;
161:                                }
162:                                pmd.incrementProgress(1);
163:
164:                                if (w > 0)
165:                                    pmd.setProgressComment("" + w + " issue"
166:                                            + (w == 1 ? "" : "s")
167:                                            + " so far...");
168:
169:                                try {
170:                                    w += analyse(sfi);
171:                                } catch (Exception e) {
172:                                    e.printStackTrace();
173:                                } catch (Error e) {
174:                                    e.printStackTrace();
175:                                }
176:                            }
177:                        } finally {
178:                            pmd.closeDialog();
179:                            LineMessagesManager.getInstance().refreshView();
180:                        }
181:
182:                        MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
183:                                .appendLine("\n\n"
184:                                        + w
185:                                        + " warning"
186:                                        + (w == 1 ? "" : "s")
187:                                        + " produced"
188:                                        + (w > 0 ? " (see messages tab)." : "."));
189:                        if (w > 0) {
190:                            MessagesTable.getInstance().setShowLatest();
191:                            MainEditorFrame.instance.outputPanels
192:                                    .select_LineMessages();
193:                        }
194:                    }
195:                };
196:                t.start();
197:            }
198:
199:            public static int analyse(final SourceFile si) throws Exception {
200:                int w = 0;
201:                StringReader sr = new StringReader(si.getContent());
202:                JavaParser pa = new JavaParser(sr);
203:                pa.disable_tracing();
204:                RAWSyntaxTree st = new RAWSyntaxTree(si.getJavaName());
205:                pa.parserOutputProcessor = st;
206:                pa.CompilationUnit();
207:
208:                final SimplifiedSyntaxTree2 sst = new SimplifiedSyntaxTree2(
209:                        st.root, si.getJavaName());
210:
211:                LineMessagesManager.getInstance().removeMessagesFor(
212:                        si.getJavaName(), TintLineMessage.class);
213:
214:                for (TypeNode it : sst.getAllTypes()) {
215:                    if (it instanceof  ClassNode) {
216:                        w += analyse(si, (ClassNode) it, si.javaFile.getName());
217:                    }
218:                    /*else
219:                    {
220:                       //System.out.println("Not a class: "+it.getClass());  ==> "Not a class: class javaparser.EnumNode"
221:
222:                    }*/
223:                }
224:                return w;
225:            }
226:
227:            public static int getNumberOfArgsFromSimplified1Sign(String s) {
228:                try {
229:                    int pos = s.lastIndexOf('%');
230:                    if (pos < 0)
231:                        return 0;
232:                    return Integer.parseInt(s.substring(pos + 1));
233:                } catch (NumberFormatException nfe) {
234:                    nfe.printStackTrace();
235:                    return 0;
236:                }
237:            }
238:
239:            /** Just use name + "%" + number of args.
240:             *   Useful to detect collisions, that may give hints on bad design.
241:             */
242:            public static String getSignatureSimplified1(Method mh) {
243:                return mh.getName() + "%" + mh.getParameterTypes().length;
244:            }
245:
246:            /** Name +"("+ list of arg types simple names) (String,double[],..) no spaces, no generics.
247:             */
248:            public static String getSignatureSimplified2(Method mh) {
249:                if (mh.getParameterTypes().length == 0)
250:                    return mh.getName() + "()";
251:
252:                StringBuilder sb = new StringBuilder(mh.getName() + "(");
253:                for (Class pari : mh.getParameterTypes()) {
254:                    sb.append(pari.getSimpleName());
255:                    sb.append(",");
256:                }
257:                sb.setLength(sb.length() - 1); // remove last ","
258:                sb.append(")");
259:
260:                return sb.toString();
261:            }
262:
263:            /** Name +"("+ list of arg types simple names) (String,double[],..) no spaces, no generics.
264:             */
265:            public static String getSignatureSimplified2Gen(Method mh,
266:                    Map<String, String> claParamTypesForName) {
267:                //System.out.println(""+Arrays.asList(cla.getTypeParameters())); // [T]
268:                //System.out.println(""+mh.toGenericString()); // "public abstract int java.lang.Comparable.compareTo(T)"
269:
270:                if (mh.getParameterTypes().length == 0)
271:                    return mh.getName() + "()";
272:
273:                StringBuilder sb = new StringBuilder(mh.getName() + "(");
274:                for (Type pari : mh.getGenericParameterTypes()) {
275:                    if (pari instanceof  Class) {
276:                        Class ci = (Class) pari;
277:                        sb.append(ci.getSimpleName());
278:                    } else {
279:                        String parN = "" + pari; // ex: T
280:                        sb.append(claParamTypesForName.get(parN));
281:                    }
282:
283:                    sb.append(",");
284:                }
285:                sb.setLength(sb.length() - 1); // remove last ","
286:                sb.append(")");
287:
288:                return sb.toString();
289:            }
290:
291:            /** Search for missing Overrides (also static !). (EASY simplif: only count args instead full sign.)
292:             *   Not possible in bytecode! java.lang.Override.class has source retention => never present in class !
293:             */
294:            public static int analyse(SourceFile si, ClassNode tn,
295:                    String simpleFileName) throws Exception {
296:                int w = 0;
297:                final List<MethodNode> methods = new ArrayList<MethodNode>();
298:
299:                //ASM:
300:                if (detectOverrideMustInvoke) {
301:                    List<ASMethod> miss = OverrideMustInvokeChecker
302:                            .searchMissingSuperCalls(tn.getJavaFullName());
303:                    if (miss != null && !miss.isEmpty()) {
304:                        for (final ASMethod asi : miss) {
305:                            //String mess =
306:                            TintLineMessage tm = new TintLineMessage(si
307:                                    .getJavaName(), asi.getFailureMessage(),
308:                                    asi.getFailureCategory(), asi.begLine,
309:                                    System.currentTimeMillis(),
310:                                    asi.issuePriority);
311:                            LineMessagesManager.add(tm);
312:                            w++;
313:                        }
314:                    }
315:                }
316:
317:                //ASM:
318:                if (detectRecurseAnn) {
319:                    List<ASMethod> miss = RecurseChecker
320:                            .searchMissingRecurseCalls(tn.getJavaFullName(),
321:                                    detectMissingRecurseAnn);
322:                    if (miss != null && !miss.isEmpty()) {
323:                        for (final ASMethod asi : miss) {
324:                            TintLineMessage tm = new TintLineMessage(si
325:                                    .getJavaName(), asi.getFailureMessage(),
326:                                    asi.getFailureCategory(), asi.begLine,
327:                                    System.currentTimeMillis(),
328:                                    asi.issuePriority);
329:                            LineMessagesManager.add(tm);
330:                            w++;
331:                        }
332:                    }
333:                }
334:
335:                Set<String> methodsDeclOverr = new HashSet<String>(); // name+"%"+nargs,  used to detect more possible issues
336:                Set<String> methodsDeclOverr2 = new HashSet<String>(); // name+"("+ simple javanames list)
337:                Map<String, MethodNode> methodsDeclImpl2 = new HashMap<String, MethodNode>(); // name+"("+ simple javanames list)
338:
339:                List<ParserTreeNode> methAndFields = TreeUtils
340:                        .getAllMethodsAndFieldsForType(tn);
341:
342:                for (ParserTreeNode ti : methAndFields) {
343:                    if (ti instanceof  MethodNode) {
344:                        MethodNode mi = (MethodNode) ti;
345:                        methods.add(mi);
346:                        if (mi.override_) {
347:                            methodsDeclOverr.add(mi.getSignatureSimplified1());
348:                            //System.out.println("T>"+getSignatureSimplified2(mi));
349:                            methodsDeclOverr2.add(mi.getSignatureSimplified2());
350:                        }
351:
352:                        if (mi.implements _) {
353:                            methodsDeclImpl2.put(mi.getSignatureSimplified2(),
354:                                    mi);
355:                            //System.out.println("declare @Implements: "+mi.getSignatureSimplified2());
356:                        }
357:                    }
358:                }
359:
360:                String jn = tn.getJavaFullName();
361:
362:                SingleClassLoader scl = SingleClassLoader
363:                        .createSingleClassLoader();
364:                Class cl = scl.loadClass(jn);
365:                if (cl == null)
366:                    throw new Exception("no class found for " + jn);
367:
368:                List<Method> declared = new ArrayList<Method>();
369:                for (Method mi : cl.getDeclaredMethods()) // also private
370:                {
371:                    declared.add(mi);
372:                }
373:
374:                List<Method> herited = new ArrayList<Method>();
375:
376:                Class par = cl.getSuperclass();
377:                while (par != null) {
378:                    for (Method mi : par.getDeclaredMethods()) // also privates !
379:                    {
380:                        herited.add(mi);
381:                    }
382:                    par = par.getSuperclass();
383:                }
384:
385:                if (detectImplementsAnn && !methodsDeclImpl2.isEmpty()) {
386:                    // collect the interfaces
387:                    List<Type> allints = new ArrayList<Type>();
388:                    allints.addAll(Arrays.asList(cl.getGenericInterfaces()));
389:                    par = cl.getSuperclass();
390:                    while (par != null) {
391:                        allints.addAll(Arrays
392:                                .asList(par.getGenericInterfaces()));
393:                        par = par.getSuperclass();
394:                    }
395:
396:                    //System.out.println("All interfaces (incl parent): "+allints);
397:                    ft: for (Type t : allints) {
398:                        Class cla = null;
399:                        Map<String, String> claParamTypesForName = new HashMap<String, String>(); // {T,String}
400:
401:                        if (t instanceof  ParameterizedType) {
402:                            ParameterizedType pt = (ParameterizedType) t;
403:                            // toString:  "java.lang.Comparable<java.lang.String>"
404:                            /*System.out.println("PT "+t);
405:                            System.out.println("Targ: "+Arrays.asList(pt.getActualTypeArguments()));  // [class java.lang.String]
406:                            System.out.println("rt="+pt.getRawType());  // interface java.lang.Comparable
407:                            System.out.println("ownt="+pt.getOwnerType());  // null
408:                             */
409:                            cla = (Class) pt.getRawType();
410:
411:                            List l1 = Arrays.asList(cla.getTypeParameters()); // [T]
412:                            List<Type> l2 = Arrays.asList(pt
413:                                    .getActualTypeArguments()); // [class java.lang.String]
414:                            for (int i = 0; i < l1.size(); i++) {
415:                                claParamTypesForName.put("" + l1.get(i),
416:                                        RefClassUtils.simpleName(l2.get(i)));
417:                            }
418:
419:                        } else if (t instanceof  Class) {
420:                            cla = (Class) t;
421:                            System.out.println("\nClass " + cla);
422:                        } else {
423:                            System.out.println("?? " + t);
424:                        }
425:
426:                        if (cla != null) {
427:
428:                            for (Method dmi : cla.getDeclaredMethods()) // maybe empty, like SwingConstants
429:                            {
430:                                // Tostring => "public abstract void java.awt.event.MouseListener.mouseClicked(java.awt.event.MouseEvent)"
431:                                // simpl: "mouseClicked(MouseEvent)"
432:
433:                                String dmis2 = getSignatureSimplified2(dmi);
434:                                System.out.println("  decl " + dmis2);
435:                                if (methodsDeclImpl2.containsKey(dmis2)) {
436:                                    System.out.println("Found!");
437:                                    methodsDeclImpl2.remove(dmis2);
438:                                    if (methodsDeclImpl2.isEmpty())
439:                                        break ft;
440:                                }
441:
442:                                String dmis2g = getSignatureSimplified2Gen(dmi,
443:                                        claParamTypesForName);
444:                                System.out.println("  declg " + dmis2g);
445:                                if (methodsDeclImpl2.containsKey(dmis2g)) {
446:                                    System.out.println("Found!");
447:                                    methodsDeclImpl2.remove(dmis2g);
448:                                    if (methodsDeclImpl2.isEmpty())
449:                                        break ft;
450:                                }
451:                            }
452:
453:                        }
454:
455:                    }
456:
457:                    if (!methodsDeclImpl2.isEmpty()) {
458:                        System.out.println("NOT FOUND for @Implements: "
459:                                + methodsDeclImpl2.keySet());
460:                        for (MethodNode mi : methodsDeclImpl2.values()) {
461:                            w++;
462:                            String mess = "@Implements '"
463:                                    + mi.name
464:                                    + "' seems not to implement some interface.";
465:                            if (debug) {
466:                                MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
467:                                        .append("\r\n\tat " + jn + "("
468:                                                + simpleFileName + ":"
469:                                                + mi.getStartLinCol()[0] + ")"
470:                                                + mess);
471:                            }
472:
473:                            TintLineMessage tm = new TintLineMessage(jn, mess,
474:                                    "Unresolved @Implements", mi
475:                                            .getStartLinCol()[0], System
476:                                            .currentTimeMillis(), 1);
477:                            LineMessagesManager.add(tm);
478:                        }
479:                    }
480:                }
481:
482:                // also "warnings"
483:                Set<String> miss1 = new HashSet<String>(); // name+"%"+nargs
484:                // very likely to be a real miss, signature with simple names is identical.
485:                Set<String> miss2 = new HashSet<String>(); // name + (simple arg names)
486:
487:                for (Method mh : herited) {
488:                    //System.out.println("heri: "+mh.toString());
489:                    String mhn1 = getSignatureSimplified1(mh);
490:
491:                    //look for collisions
492:
493:                    for (Method md : declared) {
494:                        String mdn1 = getSignatureSimplified1(md);
495:
496:                        if (mhn1.equals(mdn1)) {
497:                            if (!methodsDeclOverr.contains(mhn1)) {
498:                                miss1.add(mhn1);
499:
500:                                // deeper look:
501:                                String mhn2 = getSignatureSimplified2(mh);
502:                                String mdn2 = getSignatureSimplified2(md);
503:                                if (mhn2.equals(mdn2)) {
504:                                    if (!methodsDeclOverr2.contains(mhn2)) {
505:                                        miss2.add(mhn2);
506:                                    }
507:                                }
508:                            }
509:                            //               System.out.println("\tat "+jn+": overrides: "+mh);
510:                        }
511:                    }
512:                }
513:
514:                if (miss1.size() > 0) {
515:                    for (final MethodNode mi : methods) {
516:                        String mn = mi.getSignatureSimplified1();
517:                        if (miss1.contains(mn)) {
518:                            String mn2 = mi.getSignatureSimplified2();
519:                            //System.out.println("DBG: "+mn2+" in "+miss2);
520:
521:                            if (mi.isStatic()) {
522:                                // todo: ignore "public static main(String[])"
523:                                if (detectStaticOverloads) {
524:                                    w++;
525:                                    String mess = "Parent class defines a similar static method '"
526:                                            + mi.name + "'.";
527:                                    if (debug) {
528:                                        MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
529:                                                .append("\r\n\tat "
530:                                                        + jn
531:                                                        + "("
532:                                                        + simpleFileName
533:                                                        + ":"
534:                                                        + mi.getStartLinCol()[0]
535:                                                        + ")" + mess);
536:                                    }
537:
538:                                    TintLineMessage tm = new TintLineMessage(
539:                                            jn, mess,
540:                                            "Static method shadowing", mi
541:                                                    .getStartLinCol()[0],
542:                                            System.currentTimeMillis(), 2);
543:                                    LineMessagesManager.add(tm);
544:                                }
545:                            } else if (mi.isPrivate()) {
546:                                if (detectPrivateOverloads) {
547:                                    w++;
548:                                    String mess = "Parent class defines a similar private method '"
549:                                            + mi.name + "'.";
550:
551:                                    if (debug) {
552:                                        MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
553:                                                .append("\r\n\tat "
554:                                                        + jn
555:                                                        + "("
556:                                                        + simpleFileName
557:                                                        + ":"
558:                                                        + mi.getStartLinCol()[0]
559:                                                        + ")" + mess);
560:                                    }
561:
562:                                    TintLineMessage tm = new TintLineMessage(
563:                                            jn, mess,
564:                                            "Private method shadowing", mi
565:                                                    .getStartLinCol()[0],
566:                                            System.currentTimeMillis(), 2);
567:                                    LineMessagesManager.add(tm);
568:                                }
569:                            }
570:                            // TODO: protected that are not in the same package
571:                            // TODO: detect static/non stat collisions
572:                            else {
573:                                if (miss2.contains(mn2)) {
574:                                    // find the herited method
575:                                    Method md = null;
576:                                    for (Method mdi : herited) {
577:                                        if (getSignatureSimplified2(mdi)
578:                                                .equals(mn2)) {
579:                                            md = mdi;
580:                                            System.out.println("" + md);
581:                                            break;
582:                                        }
583:                                    }
584:
585:                                    if (md != null) {
586:                                        // todo: also detect package scope "violations"
587:
588:                                        if (detectPrivateOverloads
589:                                                && Modifier.isPrivate(md
590:                                                        .getModifiers())) {
591:
592:                                            w++;
593:                                            String mess = "A same private method '"
594:                                                    + mi.name
595:                                                    + "' exists in parent. This is NOT an override.";
596:
597:                                            if (debug) {
598:                                                MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
599:                                                        .append("\r\n\tat "
600:                                                                + jn
601:                                                                + "("
602:                                                                + simpleFileName
603:                                                                + ":"
604:                                                                + mi
605:                                                                        .getStartLinCol()[0]
606:                                                                + ")" + mess);
607:                                            }
608:
609:                                            TintLineMessage tm = new TintLineMessage(
610:                                                    jn, mess, "False override",
611:                                                    mi.getStartLinCol()[0],
612:                                                    System.currentTimeMillis(),
613:                                                    2);
614:                                            LineMessagesManager.add(tm);
615:                                            continue;
616:                                        }
617:                                    }
618:
619:                                    if (detectMissingOverrides) {
620:                                        w++;
621:                                        String mess = "Probably missing @Override for method '"
622:                                                + mi.name + "' or overload.";
623:
624:                                        if (debug) {
625:                                            MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
626:                                                    .append("\r\n\tat "
627:                                                            + jn
628:                                                            + "("
629:                                                            + simpleFileName
630:                                                            + ":"
631:                                                            + mi
632:                                                                    .getStartLinCol()[0]
633:                                                            + ")" + mess);
634:                                        }
635:
636:                                        TintLineMessage tm = new TintLineMessage(
637:                                                jn, mess, "Missing @Override",
638:                                                mi.getStartLinCol()[0], System
639:                                                        .currentTimeMillis(), 2);
640:                                        LineMessagesManager.add(tm);
641:                                    }
642:                                } else {
643:                                    if (detectNearOverrides) {
644:                                        w++;
645:                                        int na = getNumberOfArgsFromSimplified1Sign(mn);
646:                                        String mess = "A similar method '"
647:                                                + mi.name
648:                                                + "' also with "
649:                                                + na
650:                                                + " argument"
651:                                                + (na == 1 ? "" : "s")
652:                                                + " but different type"
653:                                                + (na == 1 ? "" : "s")
654:                                                + " exists in parent."
655:                                                + " It would be safer to use another name or ensure there's not a broken override.";
656:
657:                                        if (debug) {
658:                                            MainEditorFrame.instance.outputPanels.toolsOutputPanel.doc
659:                                                    .append("\r\n\tat "
660:                                                            + jn
661:                                                            + "("
662:                                                            + simpleFileName
663:                                                            + ":"
664:                                                            + mi
665:                                                                    .getStartLinCol()[0]
666:                                                            + ")" + mess);
667:                                        }
668:
669:                                        TintLineMessage tm = new TintLineMessage(
670:                                                jn, mess,
671:                                                "Possible overloading", mi
672:                                                        .getStartLinCol()[0],
673:                                                System.currentTimeMillis(), 2);
674:                                        LineMessagesManager.add(tm);
675:                                    }
676:
677:                                }
678:                            }
679:
680:                            //System.out.println("\tat "+jn+": Missing @Override: "+mi);
681:                        }
682:                    } // for MethodNode mi
683:                }
684:
685:                return w;
686:            }
687:
688:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.