Lines 93-100
Link Here
|
93 |
import org.netbeans.api.java.source.CompilationInfo; |
93 |
import org.netbeans.api.java.source.CompilationInfo; |
94 |
import org.netbeans.api.java.source.JavaSource; |
94 |
import org.netbeans.api.java.source.JavaSource; |
95 |
import org.netbeans.api.java.source.JavaSource.Phase; |
95 |
import org.netbeans.api.java.source.JavaSource.Phase; |
|
|
96 |
import org.netbeans.api.java.source.ModificationResult; |
97 |
import org.netbeans.api.java.source.ModificationResult.Difference; |
96 |
import org.netbeans.api.java.source.Task; |
98 |
import org.netbeans.api.java.source.Task; |
|
|
99 |
import org.netbeans.api.java.source.WorkingCopy; |
97 |
import org.netbeans.api.lexer.Language; |
100 |
import org.netbeans.api.lexer.Language; |
|
|
101 |
import org.netbeans.api.project.Project; |
98 |
import org.netbeans.core.startup.Main; |
102 |
import org.netbeans.core.startup.Main; |
99 |
import org.netbeans.junit.NbTestCase; |
103 |
import org.netbeans.junit.NbTestCase; |
100 |
import org.netbeans.modules.java.JavaDataLoader; |
104 |
import org.netbeans.modules.java.JavaDataLoader; |
Lines 102-121
Link Here
|
102 |
import org.netbeans.modules.java.hints.providers.code.FSWrapper; |
106 |
import org.netbeans.modules.java.hints.providers.code.FSWrapper; |
103 |
import org.netbeans.modules.java.hints.providers.code.FSWrapper.ClassWrapper; |
107 |
import org.netbeans.modules.java.hints.providers.code.FSWrapper.ClassWrapper; |
104 |
import org.netbeans.modules.java.hints.providers.spi.HintDescription; |
108 |
import org.netbeans.modules.java.hints.providers.spi.HintDescription; |
|
|
109 |
import org.netbeans.modules.java.hints.providers.spi.HintDescription.Worker; |
110 |
import org.netbeans.modules.java.hints.providers.spi.HintDescriptionFactory; |
105 |
import org.netbeans.modules.java.hints.providers.spi.HintMetadata; |
111 |
import org.netbeans.modules.java.hints.providers.spi.HintMetadata; |
|
|
112 |
import org.netbeans.modules.java.hints.providers.spi.HintMetadata.Options; |
113 |
import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl; |
114 |
import org.netbeans.modules.java.hints.spiimpl.JavaFixImpl.Accessor; |
106 |
import org.netbeans.modules.java.hints.spiimpl.MessageImpl; |
115 |
import org.netbeans.modules.java.hints.spiimpl.MessageImpl; |
107 |
import org.netbeans.modules.java.hints.spiimpl.SyntheticFix; |
116 |
import org.netbeans.modules.java.hints.spiimpl.SyntheticFix; |
|
|
117 |
import org.netbeans.modules.java.hints.spiimpl.batch.BatchUtilities; |
108 |
import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker; |
118 |
import org.netbeans.modules.java.hints.spiimpl.hints.HintsInvoker; |
109 |
import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings; |
119 |
import org.netbeans.modules.java.hints.spiimpl.options.HintsSettings; |
110 |
import org.netbeans.modules.java.hints.test.Utilities.TestLookup; |
120 |
import org.netbeans.modules.java.hints.test.Utilities.TestLookup; |
|
|
121 |
import org.netbeans.modules.java.source.JavaSourceAccessor; |
111 |
import org.netbeans.modules.java.source.TreeLoader; |
122 |
import org.netbeans.modules.java.source.TreeLoader; |
112 |
import org.netbeans.modules.parsing.impl.indexing.CacheFolder; |
123 |
import org.netbeans.modules.parsing.impl.indexing.CacheFolder; |
113 |
import org.netbeans.modules.parsing.impl.indexing.MimeTypes; |
124 |
import org.netbeans.modules.parsing.impl.indexing.MimeTypes; |
|
|
125 |
import org.netbeans.modules.refactoring.spi.RefactoringElementImplementation; |
114 |
import org.netbeans.spi.editor.hints.ErrorDescription; |
126 |
import org.netbeans.spi.editor.hints.ErrorDescription; |
115 |
import org.netbeans.spi.editor.hints.Fix; |
127 |
import org.netbeans.spi.editor.hints.Fix; |
116 |
import org.netbeans.spi.editor.hints.Severity; |
128 |
import org.netbeans.spi.editor.hints.Severity; |
117 |
import org.netbeans.spi.java.classpath.ClassPathProvider; |
129 |
import org.netbeans.spi.java.classpath.ClassPathProvider; |
118 |
import org.netbeans.spi.java.classpath.support.ClassPathSupport; |
130 |
import org.netbeans.spi.java.classpath.support.ClassPathSupport; |
|
|
131 |
import org.netbeans.spi.java.hints.Hint.Kind; |
132 |
import org.netbeans.spi.java.hints.HintContext; |
133 |
import org.netbeans.spi.java.hints.JavaFix; |
119 |
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation; |
134 |
import org.netbeans.spi.java.queries.SourceForBinaryQueryImplementation; |
120 |
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation; |
135 |
import org.netbeans.spi.java.queries.SourceLevelQueryImplementation; |
121 |
import org.openide.LifecycleManager; |
136 |
import org.openide.LifecycleManager; |
Lines 448-456
Link Here
|
448 |
} |
463 |
} |
449 |
|
464 |
|
450 |
List<HintDescription> total = new LinkedList<HintDescription>(); |
465 |
List<HintDescription> total = new LinkedList<HintDescription>(); |
|
|
466 |
final Set<ErrorDescription> requiresJavaFix = Collections.newSetFromMap(new IdentityHashMap<ErrorDescription, Boolean>()); |
451 |
|
467 |
|
452 |
for (Collection<? extends HintDescription> l : hints.values()) { |
468 |
for (final Entry<HintMetadata, Collection<HintDescription>> e : hints.entrySet()) { |
453 |
total.addAll(l); |
469 |
if ( e.getKey().options.contains(Options.NO_BATCH) |
|
|
470 |
|| e.getKey().options.contains(Options.QUERY) |
471 |
|| e.getKey().kind == Kind.ACTION) { |
472 |
total.addAll(e.getValue()); |
473 |
continue; |
474 |
} |
475 |
for (final HintDescription hd : e.getValue()) { |
476 |
total.add(HintDescriptionFactory.create() |
477 |
.setTrigger(hd.getTrigger()) |
478 |
.setMetadata(e.getKey()) |
479 |
.setAdditionalConstraints(hd.getAdditionalConstraints()) |
480 |
.addOptions(hd.getOptions().toArray(new Options[0])) |
481 |
.setWorker(new Worker() { |
482 |
@Override public Collection<? extends ErrorDescription> createErrors(HintContext ctx) { |
483 |
Collection<? extends ErrorDescription> errors = hd.getWorker().createErrors(ctx); |
484 |
|
485 |
if (errors != null) { |
486 |
for (ErrorDescription ed : errors) { |
487 |
requiresJavaFix.add(ed); |
488 |
} |
489 |
} |
490 |
|
491 |
return errors; |
492 |
} |
493 |
}) |
494 |
.produce()); |
495 |
} |
454 |
} |
496 |
} |
455 |
|
497 |
|
456 |
CompilationInfo info = parse(testFile); |
498 |
CompilationInfo info = parse(testFile); |
Lines 489-495
Link Here
|
489 |
NbTestCase.assertGC("noone holds javac", cut); |
531 |
NbTestCase.assertGC("noone holds javac", cut); |
490 |
DEBUGGING_HELPER.remove(result); |
532 |
DEBUGGING_HELPER.remove(result); |
491 |
|
533 |
|
492 |
return new HintOutput(result); |
534 |
return new HintOutput(result, requiresJavaFix); |
493 |
} |
535 |
} |
494 |
|
536 |
|
495 |
//must keep the error descriptions (and their Fixes through them) in a field |
537 |
//must keep the error descriptions (and their Fixes through them) in a field |
Lines 721-729
Link Here
|
721 |
public final class HintOutput { |
763 |
public final class HintOutput { |
722 |
|
764 |
|
723 |
private final List<ErrorDescription> errors; |
765 |
private final List<ErrorDescription> errors; |
|
|
766 |
private final Set<ErrorDescription> requiresJavaFix; |
724 |
|
767 |
|
725 |
private HintOutput(List<ErrorDescription> errors) { |
768 |
private HintOutput(List<ErrorDescription> errors, Set<ErrorDescription> requiresJavaFix) { |
726 |
this.errors = errors; |
769 |
this.errors = errors; |
|
|
770 |
this.requiresJavaFix = requiresJavaFix; |
727 |
|
771 |
|
728 |
} |
772 |
} |
729 |
|
773 |
|
Lines 809-815
Link Here
|
809 |
|
853 |
|
810 |
assertNotNull("Warning: \"" + warning + "\" not found. All ErrorDescriptions: " + errors.toString(), toFix); |
854 |
assertNotNull("Warning: \"" + warning + "\" not found. All ErrorDescriptions: " + errors.toString(), toFix); |
811 |
|
855 |
|
812 |
return new HintWarning(toFix); |
856 |
return new HintWarning(toFix, requiresJavaFix.contains(toFix)); |
813 |
} |
857 |
} |
814 |
} |
858 |
} |
815 |
|
859 |
|
Lines 817-824
Link Here
|
817 |
*/ |
861 |
*/ |
818 |
public final class HintWarning { |
862 |
public final class HintWarning { |
819 |
private final ErrorDescription warning; |
863 |
private final ErrorDescription warning; |
820 |
HintWarning(ErrorDescription warning) { |
864 |
private final boolean requiresJavaFix; |
|
|
865 |
HintWarning(ErrorDescription warning, boolean requiresJavaFix) { |
821 |
this.warning = warning; |
866 |
this.warning = warning; |
|
|
867 |
this.requiresJavaFix = requiresJavaFix; |
822 |
} |
868 |
} |
823 |
/**Applies the only fix of the current warning. Fails if the given warning |
869 |
/**Applies the only fix of the current warning. Fails if the given warning |
824 |
* does not have exactly one fix. |
870 |
* does not have exactly one fix. |
Lines 840-852
Link Here
|
840 |
|
886 |
|
841 |
assertEquals(1, fixes.size()); |
887 |
assertEquals(1, fixes.size()); |
842 |
|
888 |
|
843 |
Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class); |
889 |
doApplyFix(fixes.get(0)); |
844 |
preferences.putBoolean("importInnerClasses", true); |
|
|
845 |
try { |
846 |
fixes.get(0).implement(); |
847 |
} finally { |
848 |
preferences.remove("importInnerClasses"); |
849 |
} |
850 |
|
890 |
|
851 |
if (saveAll) |
891 |
if (saveAll) |
852 |
LifecycleManager.getDefault().saveAll(); |
892 |
LifecycleManager.getDefault().saveAll(); |
Lines 879-889
Link Here
|
879 |
|
919 |
|
880 |
assertNotNull("Cannot find fix to invoke: " + fixNames.toString(), toApply); |
920 |
assertNotNull("Cannot find fix to invoke: " + fixNames.toString(), toApply); |
881 |
|
921 |
|
882 |
toApply.implement(); |
922 |
doApplyFix(toApply); |
|
|
923 |
|
883 |
LifecycleManager.getDefault().saveAll(); |
924 |
LifecycleManager.getDefault().saveAll(); |
884 |
|
925 |
|
885 |
return new AppliedFix(); |
926 |
return new AppliedFix(); |
886 |
} |
927 |
} |
|
|
928 |
private void doApplyFix(Fix f) throws Exception { |
929 |
Preferences preferences = MimeLookup.getLookup(JavaTokenId.language().mimeType()).lookup(Preferences.class); |
930 |
preferences.putBoolean("importInnerClasses", true); |
931 |
try { |
932 |
if (requiresJavaFix) { |
933 |
assertTrue("The fix must be a JavaFix", f instanceof JavaFixImpl); |
934 |
|
935 |
ModificationResult result1 = runJavaFix(((JavaFixImpl) f).jf); |
936 |
ModificationResult result2 = runJavaFix(((JavaFixImpl) f).jf); |
937 |
|
938 |
//ensure the results are the same: |
939 |
assertEquals("The fix must be repeatable", result1.getModifiedFileObjects(), result2.getModifiedFileObjects()); |
940 |
|
941 |
for (FileObject file : result1.getModifiedFileObjects()) { |
942 |
assertEquals("The fix must be repeatable", result1.getResultingSource(file), result2.getResultingSource(file)); |
943 |
} |
944 |
|
945 |
result1.commit(); |
946 |
} else { |
947 |
f.implement(); |
948 |
} |
949 |
} finally { |
950 |
preferences.remove("importInnerClasses"); |
951 |
} |
952 |
} |
953 |
private ModificationResult runJavaFix(final JavaFix jf) throws IOException { |
954 |
FileObject file = Accessor.INSTANCE.getFile(jf); |
955 |
JavaSource js = JavaSource.forFileObject(file); |
956 |
final Map<FileObject, List<Difference>> changes = new HashMap<FileObject, List<Difference>>(); |
957 |
|
958 |
ModificationResult mr = js.runModificationTask(new Task<WorkingCopy>() { |
959 |
public void run(WorkingCopy wc) throws Exception { |
960 |
if (wc.toPhase(Phase.RESOLVED).compareTo(Phase.RESOLVED) < 0) { |
961 |
return; |
962 |
} |
963 |
|
964 |
Map<FileObject, byte[]> resourceContentChanges = new HashMap<FileObject, byte[]>(); |
965 |
Accessor.INSTANCE.process(jf, wc, true, resourceContentChanges, /*Ignored for now:*/new ArrayList<RefactoringElementImplementation>()); |
966 |
BatchUtilities.addResourceContentChanges(resourceContentChanges, changes); |
967 |
|
968 |
} |
969 |
}); |
970 |
|
971 |
changes.putAll(JavaSourceAccessor.getINSTANCE().getDiffsFromModificationResult(mr)); |
972 |
|
973 |
return JavaSourceAccessor.getINSTANCE().createModificationResult(changes, Collections.<Object, int[]>emptyMap()); |
974 |
} |
887 |
/**Verifies that the current warning provides the given fixes. |
975 |
/**Verifies that the current warning provides the given fixes. |
888 |
* |
976 |
* |
889 |
* @param fixes the {@link Fix#getText() } of the expected fixes |
977 |
* @param fixes the {@link Fix#getText() } of the expected fixes |