This is an automated email from the ASF dual-hosted git repository.

jlahoda pushed a commit to branch jdk-javac
in repository https://gitbox.apache.org/repos/asf/incubator-netbeans.git

commit 755ed65a5c6a8835f40301e95022d7d368f53ce1
Author: Jan Lahoda <jlah...@netbeans.org>
AuthorDate: Sun Dec 10 22:31:17 2017 +0100

    Improving indexing: producing sig files also for erroneous source files, 
stripping code of methods.
---
 java.source.base/nbproject/project.xml             |   4 +
 .../java/source/indexing/VanillaCompileWorker.java | 170 ++++++++++++++++++++-
 .../source/indexing/VanillaCompileWorkerTest.java  | 123 ++++++++++++++-
 3 files changed, 284 insertions(+), 13 deletions(-)

diff --git a/java.source.base/nbproject/project.xml 
b/java.source.base/nbproject/project.xml
index dcc344b..fa276ea 100644
--- a/java.source.base/nbproject/project.xml
+++ b/java.source.base/nbproject/project.xml
@@ -336,6 +336,10 @@
                         <compile-dependency/>
                     </test-dependency>
                     <test-dependency>
+                        
<code-name-base>org.netbeans.modules.java.j2seplatform</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                    <test-dependency>
                         
<code-name-base>org.netbeans.modules.java.lexer</code-name-base>
                         <compile-dependency/>
                     </test-dependency>
diff --git 
a/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java
 
b/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java
index 1ec005d..73d5570 100644
--- 
a/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java
+++ 
b/java.source.base/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorker.java
@@ -19,14 +19,27 @@
 
 package org.netbeans.modules.java.source.indexing;
 
+import com.sun.source.tree.ClassTree;
 import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
 import com.sun.source.tree.PackageTree;
 import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
 import com.sun.source.util.TreePath;
+import com.sun.source.util.TreePathScanner;
 import com.sun.source.util.Trees;
 import com.sun.tools.javac.api.JavacTaskImpl;
-import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Attribute;
+import com.sun.tools.javac.code.Flags;
+import com.sun.tools.javac.code.Symbol;
 import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.code.SymbolMetadata;
+import com.sun.tools.javac.code.Symtab;
+import com.sun.tools.javac.code.Type;
+import com.sun.tools.javac.code.Type.ClassType;
+import com.sun.tools.javac.code.Type.ForAll;
+import com.sun.tools.javac.code.Type.TypeVar;
+import com.sun.tools.javac.code.TypeTag;
 import com.sun.tools.javac.comp.AttrContext;
 import com.sun.tools.javac.comp.CompileStates.CompileState;
 import com.sun.tools.javac.comp.Enter;
@@ -37,9 +50,11 @@ import com.sun.tools.javac.tree.JCTree;
 import com.sun.tools.javac.tree.JCTree.JCClassDecl;
 import com.sun.tools.javac.tree.JCTree.JCModuleDecl;
 import com.sun.tools.javac.tree.JCTree.JCPackageDecl;
+import com.sun.tools.javac.tree.TreeMaker;
 import org.netbeans.lib.nbjavac.services.CancelAbort;
 import org.netbeans.lib.nbjavac.services.CancelService;
 import com.sun.tools.javac.util.FatalError;
+import com.sun.tools.javac.util.ListBuffer;
 import com.sun.tools.javac.util.Log;
 import java.io.File;
 import java.io.IOException;
@@ -50,9 +65,11 @@ import java.util.logging.Level;
 import java.util.stream.Collectors;
 import javax.lang.model.element.Element;
 import javax.lang.model.element.ElementKind;
+import javax.lang.model.element.Modifier;
 import javax.lang.model.element.ModuleElement;
 import javax.lang.model.element.TypeElement;
-import javax.tools.Diagnostic.Kind;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeMirror;
 import javax.tools.JavaFileManager;
 import javax.tools.JavaFileObject;
 import org.netbeans.api.java.classpath.ClassPath;
@@ -189,7 +206,6 @@ final class VanillaCompileWorker extends CompileWorker {
         boolean aptEnabled = true;
         Log log = Log.instance(jt.getContext());
         JavaCompiler compiler = JavaCompiler.instance(jt.getContext());
-        Set<JavaFileObject> haveErrors = new HashSet<>();
         JavaFileManager fm = jt.getContext().get(JavaFileManager.class);
         fm.handleOption(OutputFileManager.OPTION_SET_CURRENT_ROOT, 
Collections.singleton(context.getRootURI().toString()).iterator());
         try {
@@ -265,9 +281,7 @@ final class VanillaCompileWorker extends CompileWorker {
                     modifiedTypes.addAll(aTypes);
                 }
                 
ExecutableFilesIndex.DEFAULT.setMainClass(context.getRoot().toURL(), 
active.indexable.getURL(), main[0]);
-                if (dc.peekDiagnostics(active.jfo).stream().anyMatch(d -> 
d.getKind() == Kind.ERROR)) {
-                    haveErrors.add(active.jfo);
-                }
+                dropMethodsAndErrors(jt.getContext(), unit.getKey());
                 JavaCustomIndexer.setErrors(context, active, dc);
             }
             if (context.isCancelled()) {
@@ -285,7 +299,7 @@ final class VanillaCompileWorker extends CompileWorker {
                     for (Element type : types) {
                         TreePath tp = Trees.instance(jtFin).getPath(type);
                         assert tp != null;
-                        log.nerrors = 
haveErrors.contains(tp.getCompilationUnit().getSourceFile()) ? 1 : 0;
+                        log.nerrors = 0;
                         Iterable<? extends JavaFileObject> generatedFiles = 
jtFin.generate(Collections.singletonList(type));
                         CompileTuple unit = clazz2Tuple.get(type);
                         if (unit == null || !unit.virtual) {
@@ -360,4 +374,146 @@ final class VanillaCompileWorker extends CompileWorker {
         }
         return ParsingOutput.failure(moduleName.name, file2FQNs, addedTypes, 
addedModules, createdFiles, finished, modifiedTypes, aptGenerated);
     }
+
+    private void dropMethodsAndErrors(com.sun.tools.javac.util.Context ctx, 
CompilationUnitTree cut) {
+        Symtab syms = Symtab.instance(ctx);
+        TreeMaker make = TreeMaker.instance(ctx);
+        //TODO: should preserve error types!!!
+        new TreePathScanner<Void, Void>() {
+            @Override
+            public Void visitVariable(VariableTree node, Void p) {
+                JCTree.JCVariableDecl decl = (JCTree.JCVariableDecl) node;
+                if ((decl.mods.flags & Flags.ENUM) == 0) {
+                    decl.init = null;
+                }
+                if (decl.type.getKind() == TypeKind.ERROR) {
+                    decl.sym.type = decl.type = syms.objectType;
+                }
+                clearAnnotations(decl.sym.getMetadata());
+                return super.visitVariable(node, p);
+            }
+
+            @Override
+            public Void visitMethod(MethodTree node, Void p) {
+                JCTree.JCMethodDecl decl = (JCTree.JCMethodDecl) node;
+                Symbol.MethodSymbol msym = decl.sym;
+                if (Collections.disjoint(msym.getModifiers(), 
EnumSet.of(Modifier.NATIVE, Modifier.ABSTRACT))) {
+                    JCTree.JCNewClass nct =
+                            make.NewClass(null,
+                                          com.sun.tools.javac.util.List.nil(),
+                                          
make.QualIdent(syms.runtimeExceptionType.tsym),
+                                          
com.sun.tools.javac.util.List.of(make.Literal("")),
+                                          null);
+                    nct.type = syms.runtimeExceptionType;
+                    nct.constructor = 
syms.runtimeExceptionType.tsym.members().getSymbols(
+                            s -> s.getKind() == ElementKind.CONSTRUCTOR && 
s.type.getParameterTypes().size() == 1 && s.type.getParameterTypes().head.tsym 
== syms.stringType.tsym
+                    ).iterator().next();
+                    decl.body = make.Block(0, 
com.sun.tools.javac.util.List.of(make.Throw(nct)));
+                }
+                Type.MethodType mt;
+                if (msym.type.hasTag(TypeTag.FORALL)) {
+                    ForAll fa = (ForAll) msym.type;
+                    fa.tvars = error2Object(fa.tvars);
+                    mt = fa.asMethodType();
+                } else {
+                    mt = (Type.MethodType) msym.type;
+                }
+                mt.restype = error2Object(mt.restype);
+                mt.argtypes = error2Object(mt.argtypes);
+                mt.thrown = error2Object(mt.thrown);
+                clearAnnotations(decl.sym.getMetadata());
+                return super.visitMethod(node, p);
+            }
+
+            @Override
+            public Void visitClass(ClassTree node, Void p) {
+                Symbol.ClassSymbol csym = ((JCTree.JCClassDecl) node).sym;
+                Type.ClassType ct = (Type.ClassType) csym.type;
+                ct.all_interfaces_field = 
error2Object(ct.all_interfaces_field);
+                ct.allparams_field = error2Object(ct.allparams_field);
+                ct.interfaces_field = error2Object(ct.interfaces_field);
+                ct.typarams_field = error2Object(ct.typarams_field);
+                ct.supertype_field = error2Object(ct.supertype_field);
+                return super.visitClass(node, p);
+            }
+
+            private void clearAnnotations(SymbolMetadata metadata) {
+                if (metadata == null)
+                    return;
+
+                //TODO: type annotations, etc.
+                com.sun.tools.javac.util.List<Attribute.Compound> annotations 
= metadata.getDeclarationAttributes();
+                com.sun.tools.javac.util.List<Attribute.Compound> prev = null;
+                while (annotations.nonEmpty()) {
+                    if (isErroneous(annotations.head.type)) {
+                        if (prev == null) {
+                            metadata.reset();
+                            
metadata.setDeclarationAttributes(annotations.tail);
+                        } else {
+                            prev.tail = annotations.tail;
+                        }
+                    }
+                    prev = annotations;
+                    annotations = annotations.tail;
+                }
+            }
+
+            private boolean isErroneous(TypeMirror type) {
+                return type == null || type.getKind() == TypeKind.ERROR || 
type.getKind() == TypeKind.NONE || type.getKind() == TypeKind.OTHER;
+            }
+
+            private Set<Type> seen = Collections.newSetFromMap(new 
IdentityHashMap<>());
+
+            private Type error2Object(Type t) {
+                if (t == null)
+                    return null;
+
+                if (isErroneous(t)) {
+                    return syms.objectType;
+                }
+
+                if (!seen.add(t))
+                    return t;
+
+                switch (t.getKind()) {
+                    case DECLARED: {
+                        resolveErrors((ClassType) t);
+                        break;
+                    }
+                    case WILDCARD: {
+                        Type.WildcardType wt = ((Type.WildcardType) t);
+                        wt.type = error2Object(wt.type);
+                        TypeVar tv = wt.bound;
+                        tv.bound = error2Object(tv.bound);
+                        tv.lower = error2Object(tv.lower);
+                        break;
+                    }
+                }
+                return t;
+            }
+
+            private com.sun.tools.javac.util.List<Type> 
error2Object(com.sun.tools.javac.util.List<Type> types) {
+                if (types == null)
+                    return null;
+
+                ListBuffer<Type> lb = new ListBuffer<>();
+                boolean changed = false;
+                for (Type t : types) {
+                    Type nue = error2Object(t);
+                    changed |= nue != t;
+                    lb.append(nue);
+                }
+                return changed ? lb.toList() : types;
+            }
+
+            private void resolveErrors(ClassType ct) {
+                if (ct.tsym == syms.objectType.tsym) return ;
+                ct.all_interfaces_field = 
error2Object(ct.all_interfaces_field);
+                ct.allparams_field = error2Object(ct.allparams_field); //TODO: 
should replace with bounds
+                ct.interfaces_field = error2Object(ct.interfaces_field);
+                ct.typarams_field = error2Object(ct.typarams_field);
+                ct.supertype_field = error2Object(ct.supertype_field);
+            }
+        }.scan(cut, null);
+    }
 }
diff --git 
a/java.source.base/test/unit/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorkerTest.java
 
b/java.source.base/test/unit/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorkerTest.java
index c2f5ee0..91bb77e 100644
--- 
a/java.source.base/test/unit/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorkerTest.java
+++ 
b/java.source.base/test/unit/src/org/netbeans/modules/java/source/indexing/VanillaCompileWorkerTest.java
@@ -50,22 +50,133 @@ public class VanillaCompileWorkerTest extends 
CompileWorkerTestBase {
                                                          
compileTuple("test/Test4.java", "package test; public class Test4 { Undef 
undef; }")),
                                            
Arrays.asList(virtualCompileTuple("test/Test1.virtual", "package test; public 
class Test1 {}"),
                                                          
virtualCompileTuple("test/Test2.virtual", "package test; public class Test2 
{}")));
-        
+
         assertFalse(result.lowMemory);
         assertTrue(result.success);
-        
+
         Set<String> createdFiles = new HashSet<String>();
-        
+
         for (File created : result.createdFiles) {
             
createdFiles.add(getWorkDir().toURI().relativize(created.toURI()).getPath());
         }
-        
+
         //TODO:
-//        assertEquals(new 
HashSet<String>(Arrays.asList("cache/s1/java/15/classes/test/Test3.sig")), 
createdFiles);
+        assertEquals(new 
HashSet<String>(Arrays.asList("cache/s1/java/15/classes/test/Test3.sig",
+                                                       
"cache/s1/java/15/classes/test/Test4.sig")), createdFiles);
         result = runIndexing(Arrays.asList(compileTuple("test/Test4.java", 
"package test; public class Test4 { void t() { Undef undef; } }")),
                              Collections.emptyList());
-        
+
+        assertFalse(result.lowMemory);
+        assertTrue(result.success);
+    }
+
+    public void testRepair1() throws Exception {
+        ParsingOutput result = 
runIndexing(Arrays.asList(compileTuple("test/Test4.java", "package test; public 
class Test4 { public void test() { Undef undef; } }")),
+                                           Arrays.asList());
+
+        assertFalse(result.lowMemory);
+        assertTrue(result.success);
+
+        Set<String> createdFiles = new HashSet<String>();
+
+        for (File created : result.createdFiles) {
+            
createdFiles.add(getWorkDir().toURI().relativize(created.toURI()).getPath());
+        }
+
+        //TODO:
+        assertEquals(new 
HashSet<String>(Arrays.asList("cache/s1/java/15/classes/test/Test4.sig")), 
createdFiles);
+    }
+
+    public void testRepair2() throws Exception {
+        ParsingOutput result = 
runIndexing(Arrays.asList(compileTuple("test/Test4.java", "package test; public 
class Test4 { @Undef public void test1() { } @Deprecated @Undef public void 
test2() { } }")),
+                                           Arrays.asList());
+
         assertFalse(result.lowMemory);
         assertTrue(result.success);
+
+        Set<String> createdFiles = new HashSet<String>();
+
+        for (File created : result.createdFiles) {
+            
createdFiles.add(getWorkDir().toURI().relativize(created.toURI()).getPath());
+        }
+
+        //TODO:
+        assertEquals(new 
HashSet<String>(Arrays.asList("cache/s1/java/15/classes/test/Test4.sig")), 
createdFiles);
+        //TODO: check file content!!!
+    }
+
+    public void testRepair3() throws Exception {
+        ParsingOutput result = 
runIndexing(Arrays.asList(compileTuple("test/Test4.java", "package test; public 
class Test4 { public <T> void test1(T t) { } }")),
+                                           Arrays.asList());
+
+        assertFalse(result.lowMemory);
+        assertTrue(result.success);
+
+        Set<String> createdFiles = new HashSet<String>();
+
+        for (File created : result.createdFiles) {
+            
createdFiles.add(getWorkDir().toURI().relativize(created.toURI()).getPath());
+        }
+
+        //TODO:
+        assertEquals(new 
HashSet<String>(Arrays.asList("cache/s1/java/15/classes/test/Test4.sig")), 
createdFiles);
+        //TODO: check file content!!!
+    }
+
+    public void testRepair4() throws Exception {
+        ParsingOutput result = 
runIndexing(Arrays.asList(compileTuple("test/Test4.java", "package test; import 
java.util.List; public class Test4 { public List<Undef> test() { } }")),
+                                           Arrays.asList());
+
+        assertFalse(result.lowMemory);
+        assertTrue(result.success);
+
+        Set<String> createdFiles = new HashSet<String>();
+
+        for (File created : result.createdFiles) {
+            
createdFiles.add(getWorkDir().toURI().relativize(created.toURI()).getPath());
+        }
+
+        //TODO:
+        assertEquals(new 
HashSet<String>(Arrays.asList("cache/s1/java/15/classes/test/Test4.sig")), 
createdFiles);
+        //TODO: check file content!!!
+    }
+
+    public void testRepairEnum() throws Exception {
+        ParsingOutput result = 
runIndexing(Arrays.asList(compileTuple("test/Test4.java", "package test; public 
enum Test4 { A {} }")),
+                                           Arrays.asList());
+
+        assertFalse(result.lowMemory);
+        assertTrue(result.success);
+
+        Set<String> createdFiles = new HashSet<String>();
+
+        for (File created : result.createdFiles) {
+            
createdFiles.add(getWorkDir().toURI().relativize(created.toURI()).getPath());
+        }
+
+        //TODO:
+        assertEquals(new 
HashSet<String>(Arrays.asList("cache/s1/java/15/classes/test/Test4.sig",
+                                                       
"cache/s1/java/15/classes/test/Test4$1.sig")),
+                     createdFiles);
+        //TODO: check file content!!!
+    }
+
+    public void testRepairWildcard() throws Exception {
+        ParsingOutput result = 
runIndexing(Arrays.asList(compileTuple("test/Test4.java", "package test; import 
java.util.*; public class Test4 { void test(List<? extends Undef> l1, List<? 
super Undef> l2) { } }")),
+                                           Arrays.asList());
+
+        assertFalse(result.lowMemory);
+        assertTrue(result.success);
+
+        Set<String> createdFiles = new HashSet<String>();
+
+        for (File created : result.createdFiles) {
+            
createdFiles.add(getWorkDir().toURI().relativize(created.toURI()).getPath());
+        }
+
+        //TODO:
+        assertEquals(new 
HashSet<String>(Arrays.asList("cache/s1/java/15/classes/test/Test4.sig")),
+                     createdFiles);
+        //TODO: check file content!!!
     }
 }

-- 
To stop receiving notification emails like this one, please contact
"comm...@netbeans.apache.org" <comm...@netbeans.apache.org>.

Reply via email to