diff --git a/java.source/apichanges.xml b/java.source/apichanges.xml --- a/java.source/apichanges.xml +++ b/java.source/apichanges.xml @@ -108,6 +108,20 @@ + + + Added several methods to support Java 8 features. + + + + + + Added several new methods to support Java 8 features. Namely: ElementUtilities.isEffectivelyFinal, + TreeMaker.TypeAnnotation, TreeMaker.LambdaExpression, + TreeMaker.MemberReference and TypeUtilities.getDescriptorType. + + + Added overloaded method SourceUtils.getDependentRoots. diff --git a/java.source/nbproject/project.properties b/java.source/nbproject/project.properties --- a/java.source/nbproject/project.properties +++ b/java.source/nbproject/project.properties @@ -46,7 +46,7 @@ javadoc.title=Java Source javadoc.arch=${basedir}/arch.xml javadoc.apichanges=${basedir}/apichanges.xml -spec.version.base=0.111.0 +spec.version.base=0.112 test.qa-functional.cp.extra=${refactoring.java.dir}/modules/ext/nb-javac-api.jar test.unit.run.cp.extra=${o.n.core.dir}/core/core.jar:\ ${o.n.core.dir}/lib/boot.jar:\ @@ -148,6 +148,7 @@ ${test.config.generator.includes},\ org/netbeans/api/java/source/TypeUtilitiesTest.class,\ org/netbeans/api/java/source/TreePathHandleTest.class,\ + org/netbeans/api/java/source/TreeMirrorHandleTest.class,\ org/netbeans/api/java/source/ModificationResultTest.class,\ org/netbeans/api/java/source/ScanUtilsTest.class,\ org/netbeans/modules/java/source/save/FormatingTest.class,\ diff --git a/java.source/src/org/netbeans/api/java/source/ElementUtilities.java b/java.source/src/org/netbeans/api/java/source/ElementUtilities.java --- a/java.source/src/org/netbeans/api/java/source/ElementUtilities.java +++ b/java.source/src/org/netbeans/api/java/source/ElementUtilities.java @@ -88,6 +88,7 @@ import javax.lang.model.element.Modifier; import javax.lang.model.element.TypeElement; import javax.lang.model.element.TypeParameterElement; +import javax.lang.model.element.VariableElement; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeKind; @@ -260,6 +261,7 @@ case DECLARED: case UNION: TypeElement te = (TypeElement)((DeclaredType)type).asElement(); + if (te == null) break; for (Element member : elements.getAllMembers(te)) { if (acceptor == null || acceptor.accept(member, type)) { if (!isHidden(member, members, elements, types)) @@ -534,6 +536,17 @@ } return false; } + + /** Check whether the given variable is effectively final or final. + * + * @param e variable to check for effectively final status + * @return true if the given variable is effectively final or final + * @since 0.112 + */ + public boolean isEffectivelyFinal(VariableElement e) { + return (((Symbol) e).flags() & (Flags.EFFECTIVELY_FINAL | Flags.FINAL)) != 0; + }; + // private implementation -------------------------------------------------- diff --git a/java.source/src/org/netbeans/api/java/source/TreeMaker.java b/java.source/src/org/netbeans/api/java/source/TreeMaker.java --- a/java.source/src/org/netbeans/api/java/source/TreeMaker.java +++ b/java.source/src/org/netbeans/api/java/source/TreeMaker.java @@ -46,6 +46,7 @@ import com.sun.source.tree.*; import org.netbeans.modules.java.source.parsing.FileObjects; import org.openide.filesystems.FileObject; +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import static com.sun.source.tree.Tree.*; import com.sun.source.util.SourcePositions; @@ -133,6 +134,18 @@ return delegate.Annotation(type, arguments); } + /** + * Creates a new type AnnotationTree. + * + * @param type the annotation type. + * @param arguments the arguments for this annotation, or an empty list. + * @see com.sun.source.tree.AnnotationTree + * @since 0.112 + */ + public AnnotationTree TypeAnnotation(Tree type, List arguments) { + return delegate.TypeAnnotation(type, arguments); + } + /** * Creates a new ArrayAccessTree. * @@ -620,7 +633,18 @@ public LabeledStatementTree LabeledStatement(CharSequence label, StatementTree statement) { return delegate.LabeledStatement(label, statement); } - + + /**Creates a new LambdaExpressionTree + * + * @param parameters the lambda's formal arguments + * @param body the lambda's body + * @return the LambdaExpressionTree + * @since 0.112 + */ + public LambdaExpressionTree LambdaExpression(List parameters, Tree body) { + return delegate.LambdaExpression(parameters, body); + } + /** * Creates a new LiteralTree. Only literals which are wrappers for * primitive types (Integer, Boolean, etc.) and String instances can @@ -634,6 +658,19 @@ return delegate.Literal(value); } + /**Creates a new MemberReferenceTree. + * + * @param refMode the desired {@link ReferenceMode reference mode} + * @param expression the class (or expression), from which a member is to be referenced + * @param name the name of the referenced member + * @param typeArguments the reference's type arguments + * @return the MemberReferenceTree + * @since 0.112 + */ + public MemberReferenceTree MemberReference(ReferenceMode refMode, ExpressionTree expression, CharSequence name, List typeArguments) { + return delegate.MemberReference(refMode, name, expression, typeArguments); + } + /** * Creates a new MemberSelectTree. A MemberSelectTree consists of an * expression and an identifier. Valid expressions include things like @@ -2573,7 +2610,7 @@ * aLabel argument. Throws IllegalArgumentException if * node's kind is invalid. Valid node's kinds are:
* BREAK, CLASS, CONTINUE, IDENTIFIER, LABELED_STATEMENT, - * MEMBER_SELECT, METHOD, TYPE_PARAMETER, VARIABLE.

+ * MEMBER_SELECT, METHOD, TYPE_PARAMETER, VARIABLE, MEMBER_REFERENCE (since 0.112).

* * Consider you want to change name of method fooMet to * fooMethod: @@ -2703,6 +2740,16 @@ ); return clone; } + case MEMBER_REFERENCE: { + MemberReferenceTree t = (MemberReferenceTree) node; + N clone = (N) MemberReference( + t.getMode(), + t.getQualifierExpression(), + aLabel, + t.getTypeArguments() + ); + return clone; + } case METHOD: { MethodTree t = (MethodTree) node; N clone = (N) Method( @@ -3062,4 +3109,76 @@ } } + + /** + * Appends specified element parameter + * to the end of parameters list. + * + * @param method lambda expression tree containing parameters list. + * @param parameter element to be appended to parameters list. + * @return lambda expression tree with modified parameters. + * @since 0.112 + */ + public LambdaExpressionTree addLambdaParameter(LambdaExpressionTree method, VariableTree parameter) { + return delegate.addLambdaParameter(method, parameter); + } + + /** + * Inserts the specified element parameter + * at the specified position in parameters list. + * + * @param method lambda expression tree containing parameters list. + * @param index index at which the specified elements is to be inserted. + * @param parameter element to be inserted to parameters list. + * @return lambda expression tree with modified parameters. + * + * @throws IndexOutOfBoundsException if the index is out of range + * (index < 0 || index > size()). + * @since 0.112 + */ + public LambdaExpressionTree insertLambdaParameter(LambdaExpressionTree method, int index, VariableTree parameter) { + return delegate.insertLambdaParameter(method, index, parameter); + } + + /** + * Removes the first occurrence in parameters list of the specified + * elements. If this list do not contain the element, it is + * unchanged. + * + * @param method lambda expression tree containing parameters list. + * @param parameter element to be removed from this list, if present. + * @return lambda expression tree with modified parameters and type parameters. + * @since 0.112 + */ + public LambdaExpressionTree removeLambdaParameter(LambdaExpressionTree method, VariableTree parameter) { + return delegate.removeLambdaParameter(method, parameter); + } + + /** + * Removes the element at the specified position in parameters list. + * Returns the modified lambda expression tree. + * + * @param method lambda expression tree containing parameters list. + * @param index the index of the element to be removed. + * @return method tree with modified parameters. + * + * @throws IndexOutOfBoundsException if the index is out of range (index + * < 0 || index >= size()). + * @since 0.112 + */ + public LambdaExpressionTree removeLambdaParameter(LambdaExpressionTree method, int index) { + return delegate.removeLambdaParameter(method, index); + } + + /**Creates a new lambda expression as a copy of the given lambda expression + * with the specified body. + * + * @param method the source lambda expression + * @param newBody the new body + * @return new lambda expression tree with the new body + * @since 0.112 + */ + public LambdaExpressionTree setLambdaBody(LambdaExpressionTree method, Tree newBody) { + return delegate.setLambdaBody(method, newBody); + } } diff --git a/java.source/src/org/netbeans/api/java/source/TypeMirrorHandle.java b/java.source/src/org/netbeans/api/java/source/TypeMirrorHandle.java --- a/java.source/src/org/netbeans/api/java/source/TypeMirrorHandle.java +++ b/java.source/src/org/netbeans/api/java/source/TypeMirrorHandle.java @@ -50,10 +50,11 @@ import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type.ClassType; import com.sun.tools.javac.code.Type.TypeVar; -import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.code.Types.DefaultTypeVisitor; import com.sun.tools.javac.util.Context; +import com.sun.tools.javac.util.ListBuffer; import com.sun.tools.javac.util.Names; import java.util.ArrayList; import java.util.Collections; @@ -68,6 +69,7 @@ import javax.lang.model.type.ArrayType; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.ErrorType; +import javax.lang.model.type.IntersectionType; import javax.lang.model.type.ReferenceType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; @@ -224,6 +226,12 @@ typeMirrors.add(create(alternative, map)); } break; + case INTERSECTION: + typeMirrors = new ArrayList>(); + for (TypeMirror alternative : ((IntersectionType) tm).getBounds()) { + typeMirrors.add(create(alternative, map)); + } + break; default: throw new IllegalArgumentException("Currently unsupported TypeKind: " + tm.getKind()); } @@ -378,9 +386,22 @@ t = Types.instance(info.impl.getJavacTask().getContext()); Type lub = t.lub(resolvedAlternatives); - if (lub.tag != TypeTags.CLASS) return null; + if (!lub.hasTag(TypeTag.CLASS)) return null; return (T) new Type.UnionClassType((ClassType) lub, resolvedAlternatives); + case INTERSECTION: + ListBuffer resolvedBounds = new ListBuffer(); + for (TypeMirrorHandle alternative : typeMirrors) { + TypeMirror resolvedAlternative = alternative.resolve(info, map); + if (resolvedAlternative == null) { + return null; + } + resolvedBounds = resolvedBounds.append((Type) resolvedAlternative); + } + + t = Types.instance(info.impl.getJavacTask().getContext()); + + return (T) t.makeCompoundType(resolvedBounds.toList()); default: throw new IllegalStateException("Internal error: unknown TypeHandle kind: " + kind); } @@ -405,7 +426,7 @@ private Type delegate = null; public PlaceholderType() { - super(TypeTags.UNKNOWN, null); + super(TypeTag.UNKNOWN, null); } } diff --git a/java.source/src/org/netbeans/api/java/source/TypeUtilities.java b/java.source/src/org/netbeans/api/java/source/TypeUtilities.java --- a/java.source/src/org/netbeans/api/java/source/TypeUtilities.java +++ b/java.source/src/org/netbeans/api/java/source/TypeUtilities.java @@ -55,6 +55,7 @@ import javax.lang.model.type.ArrayType; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.ErrorType; +import javax.lang.model.type.ExecutableType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; @@ -129,7 +130,25 @@ return Types.instance(info.impl.getJavacTask().getContext()).subst((Type)type, l1, l2); } - /**Get textual representation of the given type. + /** + * Find the type of the method descriptor associated to the functional interface. + * + * @param origin functional interface type + * @return associated method descriptor type or null if the origin is not a functional interface. + * @since 0.112 + */ + public ExecutableType getDescriptorType(DeclaredType origin) { + Types types = Types.instance(info.impl.getJavacTask().getContext()); + if (types.isFunctionalInterface(((Type)origin).tsym)) { + Type dt = types.findDescriptorType((Type)origin); + if (dt != null && dt.getKind() == TypeKind.EXECUTABLE) { + return (ExecutableType)dt; + } + } + return null; + } + + /**Get textual representation of the given type. * * @param type to print * @param options allows to specify various adjustments to the output text @@ -269,5 +288,11 @@ } return DEFAULT_VALUE; } + + @Override + public StringBuilder visitUnknown(TypeMirror t, Boolean p) { + return DEFAULT_VALUE.append(""); + } + } } diff --git a/java.source/src/org/netbeans/modules/java/source/JavadocEnv.java b/java.source/src/org/netbeans/modules/java/source/JavadocEnv.java --- a/java.source/src/org/netbeans/modules/java/source/JavadocEnv.java +++ b/java.source/src/org/netbeans/modules/java/source/JavadocEnv.java @@ -45,6 +45,7 @@ package org.netbeans.modules.java.source; import com.sun.javadoc.ClassDoc; +import com.sun.source.util.TreePath; import com.sun.tools.javac.code.Flags; import com.sun.tools.javac.code.Kinds; import com.sun.tools.javac.code.Symbol.ClassSymbol; @@ -53,12 +54,9 @@ import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Symbol.VarSymbol; import com.sun.tools.javac.tree.JCTree.JCClassDecl; -import com.sun.tools.javac.tree.JCTree.JCMethodDecl; -import com.sun.tools.javac.tree.JCTree.JCVariableDecl; import com.sun.tools.javac.util.Context; import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Names; -import com.sun.tools.javac.util.Position; import com.sun.tools.javadoc.AnnotationTypeDocImpl; import com.sun.tools.javadoc.AnnotationTypeElementDocImpl; import com.sun.tools.javadoc.ClassDocImpl; @@ -121,16 +119,16 @@ } @Override - protected void makeClassDoc(ClassSymbol clazz, String docComment, JCClassDecl tree, Position.LineMap lineMap) { + protected void makeClassDoc(ClassSymbol clazz, TreePath treePath) { ClassDocImpl result = classMap.get(clazz); if (result != null) { - if (docComment != null) result.setRawCommentText(docComment); + if (treePath != null) result.setTreePath(treePath); return; } - if (isAnnotationType(tree)) { // flags of clazz may not yet be set - result = new JavadocAnnotation(this, clazz, docComment); + if (isAnnotationType((JCClassDecl)treePath.getLeaf())) { // flags of clazz may not yet be set + result = new JavadocAnnotation(this, clazz, treePath); } else { - result = new JavadocClass(this, clazz, docComment); + result = new JavadocClass(this, clazz, treePath); } classMap.put(clazz, result); } @@ -145,12 +143,12 @@ } @Override - protected void makeFieldDoc(VarSymbol var, String docComment, JCVariableDecl tree, Position.LineMap lineMap) { + protected void makeFieldDoc(VarSymbol var, TreePath treePath) { FieldDocImpl result = fieldMap.get(var); if (result != null) { - if (docComment != null) result.setRawCommentText(docComment); + if (treePath != null) result.setTreePath(treePath); } else { - result = new JavadocField(this, var, docComment); + result = new JavadocField(this, var, treePath); fieldMap.put(var, result); } } @@ -168,12 +166,12 @@ } @Override - protected void makeMethodDoc(MethodSymbol meth, String docComment, JCMethodDecl tree, Position.LineMap lineMap) { + protected void makeMethodDoc(MethodSymbol meth, TreePath treePath) { MethodDocImpl result = (MethodDocImpl)methodMap.get(meth); if (result != null) { - if (docComment != null) result.setRawCommentText(docComment); + if (treePath != null) result.setTreePath(treePath); } else { - result = new JavadocMethod(this, meth, docComment); + result = new JavadocMethod(this, meth, treePath); methodMap.put(meth, result); } } @@ -191,12 +189,12 @@ } @Override - protected void makeConstructorDoc(MethodSymbol meth, String docComment, JCMethodDecl tree, Position.LineMap lineMap) { + protected void makeConstructorDoc(MethodSymbol meth, TreePath treePath) { ConstructorDocImpl result = (ConstructorDocImpl)methodMap.get(meth); if (result != null) { - if (docComment != null) result.setRawCommentText(docComment); + if (treePath != null) result.setTreePath(treePath); } else { - result = new JavadocConstructor(this, meth, docComment); + result = new JavadocConstructor(this, meth, treePath); methodMap.put(meth, result); } } @@ -214,12 +212,12 @@ } @Override - protected void makeAnnotationTypeElementDoc(MethodSymbol meth, String docComment, JCMethodDecl tree, Position.LineMap lineMap) { + protected void makeAnnotationTypeElementDoc(MethodSymbol meth, TreePath treePath) { AnnotationTypeElementDocImpl result = (AnnotationTypeElementDocImpl)methodMap.get(meth); if (result != null) { - if (docComment != null) result.setRawCommentText(docComment); + if (treePath != null) result.setTreePath(treePath); } else { - result = new JavadocAnnotationTypeElement(this, meth, docComment); + result = new JavadocAnnotationTypeElement(this, meth, treePath); methodMap.put(meth, result); } } @@ -277,11 +275,11 @@ private class JavadocClass extends ClassDocImpl implements ElementHolder { private JavadocClass(DocEnv env, ClassSymbol sym) { - super(env, sym, null, null, null); + super(env, sym); } - private JavadocClass(DocEnv env, ClassSymbol sym, String docComment) { - super(env, sym, docComment != null ? docComment : "", null, null); //NOI18N + private JavadocClass(DocEnv env, ClassSymbol sym, TreePath treePath) { + super(env, sym, treePath); } @Override @@ -300,11 +298,11 @@ private class JavadocAnnotation extends AnnotationTypeDocImpl implements ElementHolder { private JavadocAnnotation(DocEnv env, ClassSymbol sym) { - super(env, sym, null, null, null); + super(env, sym); } - private JavadocAnnotation(DocEnv env, ClassSymbol sym, String docComment) { - super(env, sym, docComment != null ? docComment : "", null, null); //NOI18N + private JavadocAnnotation(DocEnv env, ClassSymbol sym, TreePath treePath) { + super(env, sym, treePath); } @Override @@ -323,11 +321,11 @@ private class JavadocField extends FieldDocImpl implements ElementHolder { private JavadocField(DocEnv env, VarSymbol sym) { - super(env, sym, null, null, null); + super(env, sym); } - private JavadocField(DocEnv env, VarSymbol sym, String docComment) { - super(env, sym, docComment != null ? docComment : "", null, null); //NOI18N + private JavadocField(DocEnv env, VarSymbol sym, TreePath treePath) { + super(env, sym, treePath); } @Override @@ -346,11 +344,11 @@ private class JavadocMethod extends MethodDocImpl implements ElementHolder { private JavadocMethod(DocEnv env, MethodSymbol sym) { - super(env, sym, null, null, null); + super(env, sym); } - private JavadocMethod(DocEnv env, MethodSymbol sym, String docComment) { - super(env, sym, docComment != null ? docComment : "", null, null); //NOI18N + private JavadocMethod(DocEnv env, MethodSymbol sym, TreePath treePath) { + super(env, sym, treePath); } @Override @@ -369,11 +367,11 @@ private class JavadocConstructor extends ConstructorDocImpl implements ElementHolder { private JavadocConstructor(DocEnv env, MethodSymbol sym) { - super(env, sym, null, null, null); + super(env, sym); } - private JavadocConstructor(DocEnv env, MethodSymbol sym, String docComment) { - super(env, sym, docComment != null ? docComment : "", null, null); //NOI18N + private JavadocConstructor(DocEnv env, MethodSymbol sym, TreePath treePath) { + super(env, sym, treePath); } @Override @@ -392,11 +390,11 @@ private class JavadocAnnotationTypeElement extends AnnotationTypeElementDocImpl implements ElementHolder { private JavadocAnnotationTypeElement(DocEnv env, MethodSymbol sym) { - super(env, sym, null, null, null); + super(env, sym); } - private JavadocAnnotationTypeElement(DocEnv env, MethodSymbol sym, String docComment) { - super(env, sym, docComment != null ? docComment : "", null, null); //NOI18N + private JavadocAnnotationTypeElement(DocEnv env, MethodSymbol sym, TreePath treePath) { + super(env, sym, treePath); } @Override diff --git a/java.source/src/org/netbeans/modules/java/source/PostFlowAnalysis.java b/java.source/src/org/netbeans/modules/java/source/PostFlowAnalysis.java --- a/java.source/src/org/netbeans/modules/java/source/PostFlowAnalysis.java +++ b/java.source/src/org/netbeans/modules/java/source/PostFlowAnalysis.java @@ -200,7 +200,7 @@ Symbol c = meth.owner; if (c.hasOuterInstance()) { checkThis = false; - if (tree.meth.getTag() != JCTree.SELECT && ((c.owner.kind & (Kinds.MTH | Kinds.VAR)) != 0 || methName == names._this)) { + if (tree.meth.getTag() != JCTree.Tag.SELECT && ((c.owner.kind & (Kinds.MTH | Kinds.VAR)) != 0 || methName == names._this)) { checkThis(tree.meth.pos(), c.type.getEnclosingType().tsym); } } diff --git a/java.source/src/org/netbeans/modules/java/source/TreeLoader.java b/java.source/src/org/netbeans/modules/java/source/TreeLoader.java --- a/java.source/src/org/netbeans/modules/java/source/TreeLoader.java +++ b/java.source/src/org/netbeans/modules/java/source/TreeLoader.java @@ -73,6 +73,7 @@ import com.sun.tools.javac.util.CouplingAbort; import com.sun.tools.javac.util.List; import com.sun.tools.javac.util.Log; +import com.sun.tools.javac.util.Log.DiscardDiagnosticHandler; import java.awt.EventQueue; import java.io.File; import java.io.FileOutputStream; @@ -307,7 +308,7 @@ List prev = null; for (List l = tree.defs; l.nonEmpty(); l = l.tail) { scan(l.head); - if (l.head.getTag() == JCTree.BLOCK) { + if (l.head.getTag() == JCTree.Tag.BLOCK) { if (prev != null) prev.tail = l.tail; else @@ -326,8 +327,7 @@ public static void dumpSymFile(JavaFileManager jfm, JavacTaskImpl jti, ClassSymbol clazz) throws IOException { Log log = Log.instance(jti.getContext()); JavaFileObject prevLogTo = log.useSource(null); - boolean oldSuppress = log.suppressErrorsAndWarnings; - log.suppressErrorsAndWarnings = true; + DiscardDiagnosticHandler discardDiagnosticHandler = new Log.DiscardDiagnosticHandler(log); try { String binaryName = null; String surl = null; @@ -364,7 +364,7 @@ LOGGER.log(Level.INFO, "InvalidSourcePath reported when writing sym file for class: {0}", clazz.flatname); // NOI18N } finally { jfm.handleOption("output-root", Collections.singletonList("").iterator()); //NOI18N - log.suppressErrorsAndWarnings = oldSuppress; + log.popDiagnosticHandler(discardDiagnosticHandler); log.useSource(prevLogTo); } } diff --git a/java.source/src/org/netbeans/modules/java/source/builder/ElementsService.java b/java.source/src/org/netbeans/modules/java/source/builder/ElementsService.java --- a/java.source/src/org/netbeans/modules/java/source/builder/ElementsService.java +++ b/java.source/src/org/netbeans/modules/java/source/builder/ElementsService.java @@ -48,14 +48,13 @@ import com.sun.tools.javac.util.Name; import com.sun.tools.javac.util.Names; import javax.lang.model.util.Types; -import org.netbeans.api.java.source.*; import com.sun.tools.javac.code.Scope; import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symbol.MethodSymbol; import com.sun.tools.javac.code.Symbol.TypeSymbol; import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.model.JavacTypes; import com.sun.tools.javac.util.Context; import javax.lang.model.element.*; @@ -121,7 +120,7 @@ if ((m.flags() & Flags.STATIC) == 0) { ClassSymbol owner = (ClassSymbol) m.owner; for (Type sup = jctypes.supertype(m.owner.type); - sup.tag == TypeTags.CLASS; + sup.hasTag(TypeTag.CLASS); sup = jctypes.supertype(sup)) { for (Scope.Entry e = sup.tsym.members().lookup(m.name); e.scope != null; e = e.next()) { @@ -176,7 +175,7 @@ // Check if this method overrides a deprecated method. TypeSymbol owner = sym.enclClass(); for (Type sup = jctypes.supertype(owner.type); - sup.tag == TypeTags.CLASS; + sup.hasTag(TypeTag.CLASS); sup = jctypes.supertype(sup)) { for (Scope.Entry e = sup.tsym.members().lookup(sym.name); e.scope != null; e = e.next()) { @@ -210,7 +209,7 @@ public ExecutableElement getOverriddenMethod(ExecutableElement method) { MethodSymbol m = (MethodSymbol)method; ClassSymbol origin = (ClassSymbol)m.owner; - for (Type t = jctypes.supertype(origin.type); t.tag == TypeTags.CLASS; t = jctypes.supertype(t)) { + for (Type t = jctypes.supertype(origin.type); t.hasTag(TypeTag.CLASS); t = jctypes.supertype(t)) { TypeSymbol c = t.tsym; Scope.Entry e = c.members().lookup(m.name); while (e.scope != null) { diff --git a/java.source/src/org/netbeans/modules/java/source/builder/TreeFactory.java b/java.source/src/org/netbeans/modules/java/source/builder/TreeFactory.java --- a/java.source/src/org/netbeans/modules/java/source/builder/TreeFactory.java +++ b/java.source/src/org/netbeans/modules/java/source/builder/TreeFactory.java @@ -44,6 +44,7 @@ package org.netbeans.modules.java.source.builder; +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import com.sun.tools.javac.code.Type.ErrorType; import com.sun.tools.javac.model.JavacElements; import com.sun.tools.javac.util.Names; @@ -56,7 +57,6 @@ import com.sun.tools.javac.code.Symbol; import com.sun.tools.javac.code.Type; import com.sun.tools.javac.code.Type.WildcardType; -import com.sun.tools.javac.code.TypeTags; import com.sun.tools.javac.jvm.ClassReader; import com.sun.tools.javac.model.JavacTypes; import com.sun.tools.javac.tree.JCTree; @@ -77,6 +77,7 @@ import org.netbeans.api.annotations.common.NonNull; import static org.netbeans.modules.java.source.save.PositionEstimator.*; import static com.sun.tools.javac.code.Flags.*; +import com.sun.tools.javac.code.TypeTag; /** * Factory for creating new com.sun.source.tree instances. @@ -122,6 +123,20 @@ return make.at(NOPOS).Annotation((JCTree)type, lb.toList()); } + public AnnotationTree TypeAnnotation(Tree type, List arguments) { + ListBuffer lb = new ListBuffer(); + for (ExpressionTree t : arguments) + lb.append((JCExpression)t); + return make.at(NOPOS).TypeAnnotation((JCTree)type, lb.toList()); + } + + public AnnotatedTypeTree AnnotatedType(List annotations, ExpressionTree underlyingType) { + ListBuffer lb = new ListBuffer(); + for (AnnotationTree t : annotations) + lb.append((JCAnnotation)t); + return make.at(NOPOS).AnnotatedType(lb.toList(), (JCExpression)underlyingType); + } + public ArrayAccessTree ArrayAccess(ExpressionTree array, ExpressionTree index) { return make.at(NOPOS).Indexed((JCExpression)array, (JCExpression)index); } @@ -139,27 +154,27 @@ } public BinaryTree Binary(Kind operator, ExpressionTree left, ExpressionTree right) { - final int op; + final Tag op; switch (operator) { - case MULTIPLY: op = JCTree.MUL; break; - case DIVIDE: op = JCTree.DIV; break; - case REMAINDER: op = JCTree.MOD; break; - case PLUS: op = JCTree.PLUS; break; - case MINUS: op = JCTree.MINUS; break; - case LEFT_SHIFT: op = JCTree.SL; break; - case RIGHT_SHIFT: op = JCTree.SR; break; - case UNSIGNED_RIGHT_SHIFT: op = JCTree.USR; break; - case LESS_THAN: op = JCTree.LT; break; - case GREATER_THAN: op = JCTree.GT; break; - case LESS_THAN_EQUAL: op = JCTree.LE; break; - case GREATER_THAN_EQUAL: op = JCTree.GE; break; - case EQUAL_TO: op = JCTree.EQ; break; - case NOT_EQUAL_TO: op = JCTree.NE; break; - case AND: op = JCTree.BITAND; break; - case XOR: op = JCTree.BITXOR; break; - case OR: op = JCTree.BITOR; break; - case CONDITIONAL_AND: op = JCTree.AND; break; - case CONDITIONAL_OR: op = JCTree.OR; break; + case MULTIPLY: op = JCTree.Tag.MUL; break; + case DIVIDE: op = JCTree.Tag.DIV; break; + case REMAINDER: op = JCTree.Tag.MOD; break; + case PLUS: op = JCTree.Tag.PLUS; break; + case MINUS: op = JCTree.Tag.MINUS; break; + case LEFT_SHIFT: op = JCTree.Tag.SL; break; + case RIGHT_SHIFT: op = JCTree.Tag.SR; break; + case UNSIGNED_RIGHT_SHIFT: op = JCTree.Tag.USR; break; + case LESS_THAN: op = JCTree.Tag.LT; break; + case GREATER_THAN: op = JCTree.Tag.GT; break; + case LESS_THAN_EQUAL: op = JCTree.Tag.LE; break; + case GREATER_THAN_EQUAL: op = JCTree.Tag.GE; break; + case EQUAL_TO: op = JCTree.Tag.EQ; break; + case NOT_EQUAL_TO: op = JCTree.Tag.NE; break; + case AND: op = JCTree.Tag.BITAND; break; + case XOR: op = JCTree.Tag.BITXOR; break; + case OR: op = JCTree.Tag.BITOR; break; + case CONDITIONAL_AND: op = JCTree.Tag.AND; break; + case CONDITIONAL_OR: op = JCTree.Tag.OR; break; default: throw new IllegalArgumentException("Illegal binary operator: " + operator); } @@ -265,19 +280,19 @@ public CompoundAssignmentTree CompoundAssignment(Kind operator, ExpressionTree variable, ExpressionTree expression) { - final int op; + final Tag op; switch (operator) { - case MULTIPLY_ASSIGNMENT: op = JCTree.MUL_ASG; break; - case DIVIDE_ASSIGNMENT: op = JCTree.DIV_ASG; break; - case REMAINDER_ASSIGNMENT: op = JCTree.MOD_ASG; break; - case PLUS_ASSIGNMENT: op = JCTree.PLUS_ASG; break; - case MINUS_ASSIGNMENT: op = JCTree.MINUS_ASG; break; - case LEFT_SHIFT_ASSIGNMENT: op = JCTree.SL_ASG; break; - case RIGHT_SHIFT_ASSIGNMENT: op = JCTree.SR_ASG; break; - case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT: op = JCTree.USR_ASG; break; - case AND_ASSIGNMENT: op = JCTree.BITAND_ASG; break; - case XOR_ASSIGNMENT: op = JCTree.BITXOR_ASG; break; - case OR_ASSIGNMENT: op = JCTree.BITOR_ASG; break; + case MULTIPLY_ASSIGNMENT: op = JCTree.Tag.MUL_ASG; break; + case DIVIDE_ASSIGNMENT: op = JCTree.Tag.DIV_ASG; break; + case REMAINDER_ASSIGNMENT: op = JCTree.Tag.MOD_ASG; break; + case PLUS_ASSIGNMENT: op = JCTree.Tag.PLUS_ASG; break; + case MINUS_ASSIGNMENT: op = JCTree.Tag.MINUS_ASG; break; + case LEFT_SHIFT_ASSIGNMENT: op = JCTree.Tag.SL_ASG; break; + case RIGHT_SHIFT_ASSIGNMENT: op = JCTree.Tag.SR_ASG; break; + case UNSIGNED_RIGHT_SHIFT_ASSIGNMENT: op = JCTree.Tag.USR_ASG; break; + case AND_ASSIGNMENT: op = JCTree.Tag.BITAND_ASG; break; + case XOR_ASSIGNMENT: op = JCTree.Tag.BITXOR_ASG; break; + case OR_ASSIGNMENT: op = JCTree.Tag.BITOR_ASG; break; default: throw new IllegalArgumentException("Illegal binary operator: " + operator); } @@ -365,23 +380,37 @@ return make.at(NOPOS).TypeTest((JCExpression)expression, (JCTree)type); } + public IntersectionTypeTree IntersectionType(List bounds) { + ListBuffer jcbounds = new ListBuffer(); + for (Tree t : bounds) + jcbounds.append((JCExpression)t); + return make.at(NOPOS).TypeIntersection(jcbounds.toList()); + } + public LabeledStatementTree LabeledStatement(CharSequence label, StatementTree statement) { return make.at(NOPOS).Labelled(names.fromString(label.toString()), (JCStatement)statement); } + public LambdaExpressionTree LambdaExpression(List parameters, Tree body) { + ListBuffer params = new ListBuffer(); + for (Tree t : parameters) + params.append((JCVariableDecl)t); + return make.at(NOPOS).Lambda(params.toList(), (JCTree) body); + } + public LiteralTree Literal(Object value) { try { if (value instanceof Boolean) // workaround for javac issue 6504896 - return make.at(NOPOS).Literal(TypeTags.BOOLEAN, value == Boolean.FALSE ? 0 : 1); + return make.at(NOPOS).Literal(TypeTag.BOOLEAN, value == Boolean.FALSE ? 0 : 1); if (value instanceof Character) // looks like world championship in workarounds here ;-) - return make.at(NOPOS).Literal(TypeTags.CHAR, Integer.valueOf((Character) value)); + return make.at(NOPOS).Literal(TypeTag.CHAR, Integer.valueOf((Character) value)); if (value instanceof Byte) // #119143: Crystal ball no. 4 - return make.at(NOPOS).Literal(TypeTags.INT, ((Byte) value).intValue()); + return make.at(NOPOS).Literal(TypeTag.INT, ((Byte) value).intValue()); if (value instanceof Short) - return make.at(NOPOS).Literal(TypeTags.INT, ((Short) value).intValue()); + return make.at(NOPOS).Literal(TypeTag.INT, ((Short) value).intValue()); // workaround for making NULL_LITERAL kind. if (value == null) { - return make.at(NOPOS).Literal(TypeTags.BOT, value); + return make.at(NOPOS).Literal(TypeTag.BOT, value); } return make.at(NOPOS).Literal(value); } catch (AssertionError e) { @@ -458,6 +487,20 @@ public MethodTree Method(ExecutableElement element, BlockTree body) { return make.at(NOPOS).MethodDef((Symbol.MethodSymbol)element, (JCBlock)body); } + + public MemberReferenceTree MemberReference(ReferenceMode refMode, CharSequence name, ExpressionTree expression, List typeArguments) { + ListBuffer targs; + + if (typeArguments != null) { + targs = new ListBuffer(); + for (ExpressionTree t : typeArguments) + targs.append((JCExpression)t); + } else { + targs = null; + } + + return make.at(NOPOS).Reference(refMode, names.fromString(name.toString()), (JCExpression) expression, targs != null ? targs.toList() : null); + } public ModifiersTree Modifiers(Set flagset, List annotations) { return Modifiers(modifiersToFlags(flagset), annotations); @@ -546,34 +589,34 @@ } public PrimitiveTypeTree PrimitiveType(TypeKind typekind) { - final int typetag; + final TypeTag typetag; switch (typekind) { case BOOLEAN: - typetag = TypeTags.BOOLEAN; + typetag = TypeTag.BOOLEAN; break; case BYTE: - typetag = TypeTags.BYTE; + typetag = TypeTag.BYTE; break; case SHORT: - typetag = TypeTags.SHORT; + typetag = TypeTag.SHORT; break; case INT: - typetag = TypeTags.INT; + typetag = TypeTag.INT; break; case LONG: - typetag = TypeTags.LONG; + typetag = TypeTag.LONG; break; case CHAR: - typetag = TypeTags.CHAR; + typetag = TypeTag.CHAR; break; case FLOAT: - typetag = TypeTags.FLOAT; + typetag = TypeTag.FLOAT; break; case DOUBLE: - typetag = TypeTags.DOUBLE; + typetag = TypeTag.DOUBLE; break; case VOID: - typetag = TypeTags.VOID; + typetag = TypeTag.VOID; break; default: throw new AssertionError("unknown primitive type " + typekind); @@ -674,7 +717,7 @@ tp = make.at(NOPOS).TypeArray((JCExpression) Type(((ArrayType) type).getComponentType())); break; case NULL: - tp = make.at(NOPOS).Literal(TypeTags.BOT, null); + tp = make.at(NOPOS).Literal(TypeTag.BOT, null); break; case ERROR: tp = make.at(NOPOS).Ident(((ErrorType) type).tsym.name); @@ -698,16 +741,16 @@ } public UnaryTree Unary(Kind operator, ExpressionTree arg) { - final int op; + final Tag op; switch (operator) { - case POSTFIX_INCREMENT: op = JCTree.POSTINC; break; - case POSTFIX_DECREMENT: op = JCTree.POSTDEC; break; - case PREFIX_INCREMENT: op = JCTree.PREINC; break; - case PREFIX_DECREMENT: op = JCTree.PREDEC; break; - case UNARY_PLUS: op = JCTree.POS; break; - case UNARY_MINUS: op = JCTree.NEG; break; - case BITWISE_COMPLEMENT: op = JCTree.COMPL; break; - case LOGICAL_COMPLEMENT: op = JCTree.NOT; break; + case POSTFIX_INCREMENT: op = JCTree.Tag.POSTINC; break; + case POSTFIX_DECREMENT: op = JCTree.Tag.POSTDEC; break; + case PREFIX_INCREMENT: op = JCTree.Tag.PREINC; break; + case PREFIX_DECREMENT: op = JCTree.Tag.PREDEC; break; + case UNARY_PLUS: op = JCTree.Tag.POS; break; + case UNARY_MINUS: op = JCTree.Tag.NEG; break; + case BITWISE_COMPLEMENT: op = JCTree.Tag.COMPL; break; + case LOGICAL_COMPLEMENT: op = JCTree.Tag.NOT; break; default: throw new IllegalArgumentException("Illegal unary operator: " + operator); } @@ -746,7 +789,7 @@ throw new IllegalArgumentException("Unknown wildcard bound " + kind); } TypeBoundKind tbk = make.at(NOPOS).TypeBoundKind(boundKind); - return make.at(NOPOS).Wildcard(tbk, (JCTree)type); + return make.at(NOPOS).Wildcard(tbk, (JCExpression)type); } ////////////////////////////////////// makers modification suggested by Tom @@ -769,10 +812,9 @@ } private AnnotationTree modifyAnnotationAttrValue(AnnotationTree annotation, int index, ExpressionTree attrValue, Operation op) { - AnnotationTree copy = Annotation( - annotation.getAnnotationType(), - c(annotation.getArguments(), index, attrValue, op) - ); + AnnotationTree copy = annotation.getKind() == Kind.ANNOTATION + ? Annotation(annotation.getAnnotationType(), c(annotation.getArguments(), index, attrValue, op)) + : TypeAnnotation(annotation.getAnnotationType(), c(annotation.getArguments(), index, attrValue, op)); return copy; } @@ -1423,6 +1465,34 @@ return copy; } + public LambdaExpressionTree addLambdaParameter(LambdaExpressionTree method, VariableTree parameter) { + return modifyLambdaParameter(method, -1, parameter, Operation.ADD); + } + + public LambdaExpressionTree insertLambdaParameter(LambdaExpressionTree method, int index, VariableTree parameter) { + return modifyLambdaParameter(method, index, parameter, Operation.ADD); + } + + public LambdaExpressionTree removeLambdaParameter(LambdaExpressionTree method, VariableTree parameter) { + return modifyLambdaParameter(method, -1, parameter, Operation.REMOVE); + } + + public LambdaExpressionTree removeLambdaParameter(LambdaExpressionTree method, int index) { + return modifyLambdaParameter(method, index, null, Operation.REMOVE); + } + + private LambdaExpressionTree modifyLambdaParameter(LambdaExpressionTree method, int index, VariableTree parameter, Operation op) { + LambdaExpressionTree copy = LambdaExpression( + c(method.getParameters(), index, parameter, op), + method.getBody() + ); + return copy; + } + + public LambdaExpressionTree setLambdaBody(LambdaExpressionTree method, Tree newBody) { + return LambdaExpression(method.getParameters(),newBody); + } + private List c(List originalList, int index, E item, Operation operation) { List copy = new ArrayList(originalList); switch (operation) { diff --git a/java.source/src/org/netbeans/modules/java/source/indexing/JavaCustomIndexer.java b/java.source/src/org/netbeans/modules/java/source/indexing/JavaCustomIndexer.java --- a/java.source/src/org/netbeans/modules/java/source/indexing/JavaCustomIndexer.java +++ b/java.source/src/org/netbeans/modules/java/source/indexing/JavaCustomIndexer.java @@ -626,7 +626,7 @@ static void setErrors(Context context, CompileTuple active, DiagnosticListenerImpl errors) { if (!active.virtual) { - Iterable> filteredErrorsList = Iterators.filter(errors.getDiagnostics(active.jfo), new FilterOutDiamondWarnings()); + Iterable> filteredErrorsList = Iterators.filter(errors.getDiagnostics(active.jfo), new FilterOutJDK7AndLaterWarnings()); ErrorsCache.setErrors(context.getRootURI(), active.indexable, filteredErrorsList, active.aptGenerated ? ERROR_CONVERTOR_NO_BADGE : ERROR_CONVERTOR); } } @@ -1171,11 +1171,14 @@ return result; } - private static final Set DIAMOND_KINDS = new HashSet(Arrays.asList("compiler.warn.diamond.redundant.args", "compiler.warn.diamond.redundant.args.1")); + private static final Set JDK7AndLaterWarnings = new HashSet(Arrays.asList( + "compiler.warn.diamond.redundant.args", + "compiler.warn.diamond.redundant.args.1", + "compiler.note.potential.lambda.found")); - private static class FilterOutDiamondWarnings implements Comparable> { + private static class FilterOutJDK7AndLaterWarnings implements Comparable> { @Override public int compareTo(Diagnostic o) { - return DIAMOND_KINDS.contains(o.getCode()) ? 0 : -1; + return JDK7AndLaterWarnings.contains(o.getCode()) ? 0 : -1; } } diff --git a/java.source/src/org/netbeans/modules/java/source/indexing/MultiPassCompileWorker.java b/java.source/src/org/netbeans/modules/java/source/indexing/MultiPassCompileWorker.java --- a/java.source/src/org/netbeans/modules/java/source/indexing/MultiPassCompileWorker.java +++ b/java.source/src/org/netbeans/modules/java/source/indexing/MultiPassCompileWorker.java @@ -47,7 +47,7 @@ import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Symtab; import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Enter; @@ -214,7 +214,7 @@ public void visitClassDef(JCClassDecl node) { if (node.sym != null) { Type st = ts.supertype(node.sym.type); - if (st.tag == TypeTags.CLASS) { + if (st.hasTag(TypeTag.CLASS)) { ClassSymbol c = st.tsym.outermostClass(); CompileTuple u = jfo2tuples.get(c.sourcefile); if (u != null && !previous.finishedFiles.contains(u.indexable) && !u.indexable.equals(activeIndexable)) { @@ -437,7 +437,7 @@ public void visitClassDef(JCClassDecl node) { if (node.sym != null) { Type st = types.supertype(node.sym.type); - if (st.tag == TypeTags.CLASS) { + if (st.hasTag(TypeTag.CLASS)) { ClassSymbol c = st.tsym.outermostClass(); Env stEnv = enter.getEnv(c); if (stEnv != null && env != stEnv) { diff --git a/java.source/src/org/netbeans/modules/java/source/indexing/OnePassCompileWorker.java b/java.source/src/org/netbeans/modules/java/source/indexing/OnePassCompileWorker.java --- a/java.source/src/org/netbeans/modules/java/source/indexing/OnePassCompileWorker.java +++ b/java.source/src/org/netbeans/modules/java/source/indexing/OnePassCompileWorker.java @@ -46,7 +46,7 @@ import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.code.Symbol.ClassSymbol; import com.sun.tools.javac.code.Type; -import com.sun.tools.javac.code.TypeTags; +import com.sun.tools.javac.code.TypeTag; import com.sun.tools.javac.code.Types; import com.sun.tools.javac.tree.JCTree.JCClassDecl; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; @@ -224,7 +224,7 @@ public void visitClassDef(JCClassDecl node) { if (node.sym != null) { Type st = ts.supertype(node.sym.type); - if (st.tag == TypeTags.CLASS) { + if (st.hasTag(TypeTag.CLASS)) { ClassSymbol c = st.tsym.outermostClass(); Pair u = jfo2units.remove(c.sourcefile); if (u != null && !finished.contains(u.second.indexable) && !u.second.indexable.equals(activeIndexable)) { diff --git a/java.source/src/org/netbeans/modules/java/source/indexing/SuperOnePassCompileWorker.java b/java.source/src/org/netbeans/modules/java/source/indexing/SuperOnePassCompileWorker.java --- a/java.source/src/org/netbeans/modules/java/source/indexing/SuperOnePassCompileWorker.java +++ b/java.source/src/org/netbeans/modules/java/source/indexing/SuperOnePassCompileWorker.java @@ -238,7 +238,7 @@ } List activeTypes = new ArrayList(); for (Tree tree : unit.getKey().getTypeDecls()) { - if (tree instanceof JCTree && ((JCTree)tree).getTag() == JCTree.CLASSDEF) { + if (tree instanceof JCTree && ((JCTree)tree).getTag() == JCTree.Tag.CLASSDEF) { ClassSymbol sym = ((JCClassDecl)tree).sym; if (sym != null) activeTypes.add(sym); diff --git a/java.source/src/org/netbeans/modules/java/source/parsing/JavacParser.java b/java.source/src/org/netbeans/modules/java/source/parsing/JavacParser.java --- a/java.source/src/org/netbeans/modules/java/source/parsing/JavacParser.java +++ b/java.source/src/org/netbeans/modules/java/source/parsing/JavacParser.java @@ -53,6 +53,9 @@ import com.sun.tools.javac.api.JavacTaskImpl; import com.sun.tools.javac.api.JavacTool; import com.sun.tools.javac.api.JavacTrees; +import com.sun.tools.javac.parser.LazyDocCommentTable; +import com.sun.tools.javac.parser.Tokens.Comment; +import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.JCBlock; import com.sun.tools.javac.tree.JCTree.JCCompilationUnit; @@ -97,7 +100,6 @@ import javax.swing.text.JTextComponent; import javax.tools.Diagnostic; import javax.tools.DiagnosticListener; -import javax.tools.JavaCompiler; import javax.tools.JavaFileObject; import org.netbeans.api.annotations.common.NonNull; import org.netbeans.api.annotations.common.NullAllowed; @@ -717,7 +719,6 @@ JavacTaskImpl javacTask = createJavacTask(cpInfo, diagnosticListener, sourceLevel, false, oraculum, dcc, parser == null ? null : new DefaultCancelService(parser), APTUtils.get(root)); Context context = javacTask.getContext(); TreeLoader.preRegister(context, cpInfo, detached); - com.sun.tools.javac.main.JavaCompiler.instance(context).keepComments = true; return javacTask; } @@ -735,6 +736,7 @@ if (!backgroundCompilation) { options.add("-Xjcov"); //NOI18N, Make the compiler store end positions options.add("-XDallowStringFolding=false"); //NOI18N + options.add("-XDkeepComments=true"); //NOI18N assert options.add("-XDdev") || true; //NOI18N } else { options.add("-XDbackgroundCompilation"); //NOI18N @@ -783,14 +785,16 @@ options.add("-proc:none"); // NOI18N, Disable annotation processors } - JavaCompiler tool = JavacTool.create(); - JavacTaskImpl task = (JavacTaskImpl)tool.getTask(null, + Context context = new Context(); + //need to preregister the Messages here, because the getTask below requires Log instance: + Messager.preRegister(context, null, DEV_NULL, DEV_NULL, DEV_NULL); + JavacTaskImpl task = (JavacTaskImpl)JavacTool.create().getTask(null, ClasspathInfoAccessor.getINSTANCE().getFileManager(cpInfo), - diagnosticListener, options, null, Collections.emptySet()); + diagnosticListener, options, null, Collections.emptySet(), + context); if (aptEnabled) { task.setProcessors(processors); } - Context context = task.getContext(); NBClassReader.preRegister(context, !backgroundCompilation); if (cnih != null) { context.put(ClassNamesForFileOraculum.class, cnih); @@ -801,7 +805,6 @@ if (cancelService != null) { DefaultCancelService.preRegister(context, cancelService); } - Messager.preRegister(context, null, DEV_NULL, DEV_NULL, DEV_NULL); NBAttr.preRegister(context); NBClassWriter.preRegister(context); NBParserFactory.preRegister(context); @@ -1000,7 +1003,7 @@ assert dl instanceof CompilationInfoImpl.DiagnosticListenerImpl; ((CompilationInfoImpl.DiagnosticListenerImpl)dl).startPartialReparse(origStartPos, origEndPos); long start = System.currentTimeMillis(); - Map docComments = new HashMap(); + Map docComments = new HashMap(); block = pr.reparseMethodBody(cu, orig, newBody, firstInner, docComments); if (LOGGER.isLoggable(Level.FINER)) { LOGGER.log(Level.FINER, "Reparsed method in: {0}", fo); //NOI18N @@ -1015,15 +1018,15 @@ } return false; } - ((JCTree.JCCompilationUnit)cu).docComments.keySet().removeAll(fav.docOwners); - ((JCTree.JCCompilationUnit)cu).docComments.putAll(docComments); + ((LazyDocCommentTable) ((JCTree.JCCompilationUnit)cu).docComments).table.keySet().removeAll(fav.docOwners); + ((LazyDocCommentTable) ((JCTree.JCCompilationUnit)cu).docComments).table.putAll(docComments); long end = System.currentTimeMillis(); if (fo != null) { logTime (fo,Phase.PARSED,(end-start)); } final int newEndPos = (int) jt.getSourcePositions().getEndPosition(cu, block); final int delta = newEndPos - origEndPos; - final Map endPos = ((JCCompilationUnit)cu).endPositions; + final EndPosTable endPos = ((JCCompilationUnit)cu).endPositions; final TranslatePositionsVisitor tpv = new TranslatePositionsVisitor(orig, endPos, delta); tpv.scan(cu, null); ((JCMethodDecl)orig).body = block; @@ -1060,7 +1063,7 @@ //fix CompilationUnitTree.getLineMap: long startM = System.currentTimeMillis(); char[] chars = snapshot.getText().toString().toCharArray(); - ((LineMapImpl) cu.getLineMap()).build(chars, chars.length, '\0'); + ((LineMapImpl) cu.getLineMap()).build(chars, chars.length); LOGGER.log(Level.FINER, "Rebuilding LineMap took: {0}", System.currentTimeMillis() - startM); ((CompilationInfoImpl.DiagnosticListenerImpl)dl).endPartialReparse (delta); diff --git a/java.source/src/org/netbeans/modules/java/source/parsing/TranslatePositionsVisitor.java b/java.source/src/org/netbeans/modules/java/source/parsing/TranslatePositionsVisitor.java --- a/java.source/src/org/netbeans/modules/java/source/parsing/TranslatePositionsVisitor.java +++ b/java.source/src/org/netbeans/modules/java/source/parsing/TranslatePositionsVisitor.java @@ -46,8 +46,9 @@ import com.sun.source.tree.MethodTree; import com.sun.source.tree.Tree; import com.sun.source.util.TreeScanner; +import com.sun.tools.javac.tree.EndPosTable; import com.sun.tools.javac.tree.JCTree; -import java.util.Map; +import org.netbeans.lib.nbjavac.services.NBParserFactory.NBJavacParser.EndPosTableImpl; /** * Helper visitor for partial reparse. @@ -57,12 +58,12 @@ class TranslatePositionsVisitor extends TreeScanner { private final MethodTree changedMethod; - private final Map endPos; + private final EndPosTable endPos; private final int delta; boolean active; boolean inMethod; - public TranslatePositionsVisitor (final MethodTree changedMethod, final Map endPos, final int delta) { + public TranslatePositionsVisitor (final MethodTree changedMethod, final EndPosTable endPos, final int delta) { assert changedMethod != null; assert endPos != null; this.changedMethod = changedMethod; @@ -80,10 +81,10 @@ } Void result = super.scan(node, p); if (inMethod && node != null) { - endPos.remove(node); + endPos.replaceTree((JCTree) node, null);//remove } if (active && node != null) { - Integer pos = endPos.remove(node); + Integer pos = endPos.replaceTree((JCTree) node, null);//remove if (pos != null) { int newPos; if (pos < 0) { @@ -92,7 +93,7 @@ else { newPos = pos+delta; } - endPos.put ((JCTree)node,newPos); + ((EndPosTableImpl) endPos).storeEnd((JCTree)node,newPos); } } return result; @@ -128,4 +129,6 @@ } return null; } + + } diff --git a/java.source/src/org/netbeans/modules/java/source/pretty/VeryPretty.java b/java.source/src/org/netbeans/modules/java/source/pretty/VeryPretty.java --- a/java.source/src/org/netbeans/modules/java/source/pretty/VeryPretty.java +++ b/java.source/src/org/netbeans/modules/java/source/pretty/VeryPretty.java @@ -45,6 +45,7 @@ import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; import com.sun.source.tree.MethodTree; import com.sun.source.tree.Tree; import static com.sun.source.tree.Tree.*; @@ -58,7 +59,6 @@ import com.sun.tools.javac.code.*; import static com.sun.tools.javac.code.Flags.*; import com.sun.tools.javac.code.Symbol.*; -import static com.sun.tools.javac.code.TypeTags.*; import com.sun.tools.javac.main.JavaCompiler; import com.sun.tools.javac.tree.JCTree; import com.sun.tools.javac.tree.JCTree.*; @@ -88,7 +88,6 @@ import org.netbeans.modules.java.source.parsing.JavacParser; import org.netbeans.modules.java.source.save.CasualDiff; import org.netbeans.modules.java.source.save.DiffContext; -import static org.netbeans.modules.java.source.save.PositionEstimator.*; import org.netbeans.modules.java.source.save.Reformatter; import org.netbeans.modules.java.source.transform.FieldGroupTree; import org.netbeans.spi.java.classpath.support.ClassPathSupport; @@ -582,7 +581,7 @@ printPackage(tree.pid); List l = tree.defs; ArrayList imports = new ArrayList(); - while (l.nonEmpty() && l.head.getTag() == JCTree.IMPORT){ + while (l.nonEmpty() && l.head.getTag() == JCTree.Tag.IMPORT){ imports.add((JCImport) l.head); l = l.tail; } @@ -806,7 +805,8 @@ print(tree.vartype); } } - needSpace(); + if (tree.vartype != null) //should also check the flags? + needSpace(); if (!ERROR.contentEquals(tree.name)) print(tree.name); if (tree.init != null) { @@ -902,7 +902,7 @@ print(' '); int col = out.col; if (tree.init.nonEmpty()) { - if (tree.init.head.getTag() == JCTree.VARDEF) { + if (tree.init.head.getTag() == JCTree.Tag.VARDEF) { printNoParenExpr(tree.init.head); for (List l = tree.init.tail; l.nonEmpty(); l = l.tail) { JCVariableDecl vdef = (JCVariableDecl) l.head; @@ -973,6 +973,18 @@ } @Override + public void visitLambda(JCLambda that) { + print("("); + wrapTrees(that.params, WrapStyle.WRAP_NEVER, out.col); + print(") -> "); + if (that.body.getKind() == Kind.BLOCK) { + printStat(that.body); + } else { + printExpr(that.body, TreeInfo.notExpression); + } + } + + @Override public void visitSwitch(JCSwitch tree) { print("switch"); print(cs.spaceBeforeSwitchParen() ? " (" : "("); @@ -1241,11 +1253,11 @@ } public void printMethodSelect(JCMethodInvocation tree) { - if (tree.meth.getTag() == JCTree.SELECT) { + if (tree.meth.getTag() == JCTree.Tag.SELECT) { JCFieldAccess left = (JCFieldAccess)tree.meth; printExpr(left.selected); print('.'); - if (left.selected.getTag() == JCTree.APPLY) { + if (left.selected.getTag() == JCTree.Tag.APPLY) { switch(cs.wrapChainedMethodCalls()) { case WRAP_IF_LONG: int rm = cs.getRightMargin(); @@ -1312,7 +1324,7 @@ print("new "); int n = tree.elems != null ? 1 : 0; JCTree elemtype = tree.elemtype; - while (elemtype.getTag() == JCTree.TYPEARRAY) { + while (elemtype.getTag() == JCTree.Tag.TYPEARRAY) { n++; elemtype = ((JCArrayTypeTree) elemtype).elemtype; } @@ -1368,7 +1380,7 @@ printExpr(tree.lhs, TreeInfo.assignopPrec + 1); if (cs.spaceAroundAssignOps()) print(' '); - print(treeinfo.operatorName(tree.getTag() - JCTree.ASGOffset)); + print(treeinfo.operatorName(tree.getTag().noAssignOp())); print('='); int rm = cs.getRightMargin(); switch(cs.wrapAssignOps()) { @@ -1394,15 +1406,15 @@ public void visitUnary(JCUnary tree) { int ownprec = TreeInfo.opPrec(tree.getTag()); Name opname = treeinfo.operatorName(tree.getTag()); - if (tree.getTag() <= JCTree.PREDEC) { + if (tree.getTag().ordinal() <= JCTree.Tag.PREDEC.ordinal()) { //XXX: comparing ordinals! if (cs.spaceAroundUnaryOps()) { needSpace(); print(opname); print(' '); } else { print(opname); - if ( (tree.getTag() == JCTree.POS && (tree.arg.getTag() == JCTree.POS || tree.arg.getTag() == JCTree.PREINC)) - || (tree.getTag() == JCTree.NEG && (tree.arg.getTag() == JCTree.NEG || tree.arg.getTag() == JCTree.PREDEC))) { + if ( (tree.getTag() == JCTree.Tag.POS && (tree.arg.getTag() == JCTree.Tag.POS || tree.arg.getTag() == JCTree.Tag.PREINC)) + || (tree.getTag() == JCTree.Tag.NEG && (tree.arg.getTag() == JCTree.Tag.NEG || tree.arg.getTag() == JCTree.Tag.PREDEC))) { print(' '); } } @@ -1429,8 +1441,8 @@ print(' '); print(opname); boolean needsSpace = cs.spaceAroundBinaryOps() - || (tree.getTag() == JCTree.PLUS && (tree.rhs.getTag() == JCTree.POS || tree.rhs.getTag() == JCTree.PREINC)) - || (tree.getTag() == JCTree.MINUS && (tree.rhs.getTag() == JCTree.NEG || tree.rhs.getTag() == JCTree.PREDEC)); + || (tree.getTag() == JCTree.Tag.PLUS && (tree.rhs.getTag() == JCTree.Tag.POS || tree.rhs.getTag() == JCTree.Tag.PREINC)) + || (tree.getTag() == JCTree.Tag.MINUS && (tree.rhs.getTag() == JCTree.Tag.NEG || tree.rhs.getTag() == JCTree.Tag.PREDEC)); int rm = cs.getRightMargin(); switch(cs.wrapBinaryOps()) { case WRAP_IF_LONG: @@ -1572,7 +1584,7 @@ @Override public void visitTypeIdent(JCPrimitiveTypeTree tree) { - print(symbols.typeOfTag[tree.typetag].tsym.name); + print(tree.typetag.name().toLowerCase()); } @Override @@ -1644,6 +1656,19 @@ } @Override + public void visitReference(JCMemberReference tree) { + printExpr(tree.expr); + print("::"); + if (tree.typeargs != null && !tree.typeargs.isEmpty()) { + print("<"); + printExprs(tree.typeargs); + print(">"); + } + if (tree.getMode() == ReferenceMode.INVOKE) print(tree.name); + else print("new"); + } + + @Override public void visitLetExpr(LetExpr tree) { print("(let " + tree.defs + " in " + tree.expr + ")"); } @@ -1997,8 +2022,8 @@ blankLines(tree, true); printPrecedingComments(tree, !member); printExpr(tree, TreeInfo.notExpression); - int tag = tree.getTag(); - if(JCTree.APPLY<=tag && tag<=JCTree.MOD_ASG) print(';'); + int tag = tree.getTag().ordinal();//XXX: comparing ordinals!!! + if(JCTree.Tag.APPLY.ordinal()<=tag && tag<=JCTree.Tag.MOD_ASG.ordinal()) print(';'); printTrailingComments(tree, !member); blankLines(tree, false); } @@ -2407,9 +2432,9 @@ public Name fullName(JCTree tree) { switch (tree.getTag()) { - case JCTree.IDENT: + case IDENT: return ((JCIdent) tree).name; - case JCTree.SELECT: + case SELECT: JCFieldAccess sel = (JCFieldAccess)tree; Name sname = fullName(sel.selected); return sname != null && sname.getByteLength() > 0 ? sname.append('.', sel.name) : sel.name; @@ -2442,7 +2467,7 @@ /** Is the given tree an enumerator definition? */ private static boolean isEnumerator(JCTree tree) { - return tree.getTag() == JCTree.VARDEF && (((JCVariableDecl) tree).mods.flags & ENUM) != 0; + return tree.getTag() == JCTree.Tag.VARDEF && (((JCVariableDecl) tree).mods.flags & ENUM) != 0; } private String replace(String a,String b) { diff --git a/java.source/src/org/netbeans/modules/java/source/pretty/WidthEstimator.java b/java.source/src/org/netbeans/modules/java/source/pretty/WidthEstimator.java --- a/java.source/src/org/netbeans/modules/java/source/pretty/WidthEstimator.java +++ b/java.source/src/org/netbeans/modules/java/source/pretty/WidthEstimator.java @@ -51,7 +51,6 @@ import com.sun.tools.javac.tree.TreeInfo; import static com.sun.tools.javac.code.Flags.*; -import static com.sun.tools.javac.code.TypeTags.*; /** Estimate the printed width of a tree */ @@ -175,7 +174,7 @@ if (tree.elemtype != null) { width+=4; JCTree elemtype = tree.elemtype; - while (elemtype.getTag() == JCTree.TYPEARRAY) { + while (elemtype.getTag() == JCTree.Tag.TYPEARRAY) { width+=2; elemtype = ((JCArrayTypeTree) elemtype).elemtype; } @@ -232,7 +231,7 @@ public void visitAssignop(JCAssignOp tree) { open(prec, TreeInfo.assignopPrec); width+=3; - width(treeinfo.operatorName(tree.getTag() - JCTree.ASGOffset)); + width(treeinfo.operatorName(tree.getTag())); width(tree.lhs, TreeInfo.assignopPrec + 1); width(tree.rhs, TreeInfo.assignopPrec); } @@ -320,7 +319,7 @@ } public void visitTypeIdent(JCPrimitiveTypeTree tree) { - width(symbols.typeOfTag[tree.typetag].tsym.name); + width(tree.typetag.name().toLowerCase()); } public void visitTypeArray(JCArrayTypeTree tree) { diff --git a/java.source/src/org/netbeans/modules/java/source/save/CasualDiff.java b/java.source/src/org/netbeans/modules/java/source/save/CasualDiff.java --- a/java.source/src/org/netbeans/modules/java/source/save/CasualDiff.java +++ b/java.source/src/org/netbeans/modules/java/source/save/CasualDiff.java @@ -1632,7 +1632,7 @@ return bounds[1]; } - private String operatorName(int tag) { + private String operatorName(Tag tag) { // dummy instance, just to access a public method which should be static return new Pretty(null, false).operatorName(tag); } @@ -1731,6 +1731,50 @@ copyTo(localPointer, bounds[1]); return bounds[1]; } + + protected int diffMemberReference(JCMemberReference oldT, JCMemberReference newT, int[] bounds) { + int localPointer = bounds[0]; + int[] exprBounds = getBounds(oldT.expr); + copyTo(localPointer, exprBounds[0]); + localPointer = diffTree(oldT.expr, newT.expr, exprBounds); + tokenSequence.move(exprBounds[1]); + moveToSrcRelevant(tokenSequence, Direction.FORWARD); + if (tokenSequence.token() != null && tokenSequence.token().id() == JavaTokenId.COLONCOLON) { + moveToSrcRelevant(tokenSequence, Direction.FORWARD); + copyTo(localPointer, localPointer = tokenSequence.offset()); + } + com.sun.tools.javac.util.List oldTypePar = oldT.typeargs != null ? oldT.typeargs : com.sun.tools.javac.util.List.nil(); + com.sun.tools.javac.util.List newTypePar = newT.typeargs != null ? newT.typeargs : com.sun.tools.javac.util.List.nil(); + if (!listsMatch(oldTypePar, newTypePar)) { + int insertHint; + if (oldTypePar.nonEmpty() && newTypePar.nonEmpty()) { + insertHint = oldTypePar.head.pos; + } else { + insertHint = localPointer; + } + copyTo(localPointer, localPointer = insertHint); + boolean parens = oldTypePar.isEmpty() && newTypePar.nonEmpty(); + localPointer = diffParameterList(oldTypePar, newTypePar, + parens ? new JavaTokenId[] { JavaTokenId.LT, JavaTokenId.GT } : null, + localPointer, Measure.ARGUMENT); + if (oldTypePar.nonEmpty()) { + tokenSequence.move(endPos(oldTypePar.last())); + moveToSrcRelevant(tokenSequence, Direction.FORWARD); + moveToSrcRelevant(tokenSequence, Direction.FORWARD);//skips > and any subsequent unimportant tokens + int end = tokenSequence.offset(); + if (newTypePar.nonEmpty()) + copyTo(localPointer, end); + localPointer = end; + } + } + if (nameChanged(oldT.name, newT.name)) { + printer.print(newT.name); + diffInfo.put(localPointer, NbBundle.getMessage(CasualDiff.class,"TXT_UpdateReferenceTo",oldT.name)); + localPointer = localPointer + oldT.name.length(); + } + copyTo(localPointer, bounds[1]); + return bounds[1]; + } protected int diffSelect(JCFieldAccess oldT, JCFieldAccess newT, int[] bounds) { return diffSelect(oldT, newT, bounds, null, null); @@ -1980,6 +2024,47 @@ diffIdent((JCIdent) oldTident, (JCIdent) newTident, bounds); } } + + protected int diffLambda(JCLambda oldT, JCLambda newT, int[] bounds) { + int localPointer = bounds[0]; + int posHint; + if (oldT.params.isEmpty()) { + // compute the position. Find the parameters closing ')', its + // start position is important for us. This is used when + // there was not any parameter in original tree. + int startOffset = oldT.pos; + + moveFwdToToken(tokenSequence, startOffset, JavaTokenId.RPAREN); + posHint = tokenSequence.offset(); + } else { + // take the position of the first old parameter + posHint = oldT.params.iterator().next().getStartPosition(); + } + if (!listsMatch(oldT.params, newT.params)) { + copyTo(localPointer, posHint); + int old = printer.setPrec(TreeInfo.noPrec); + parameterPrint = true; + Name oldEnclClassName = printer.enclClassName; + printer.enclClassName = null; + localPointer = diffParameterList(oldT.params, newT.params, null, posHint, Measure.MEMBER); + printer.enclClassName = oldEnclClassName; + parameterPrint = false; + printer.setPrec(old); + } + //make sure the ')' is printed: + moveFwdToToken(tokenSequence, oldT.params.isEmpty() ? posHint : endPos(oldT.params.last()), JavaTokenId.RPAREN); + tokenSequence.moveNext(); + posHint = tokenSequence.offset(); + if (localPointer < posHint) + copyTo(localPointer, localPointer = posHint); + if (oldT.body != null && newT.body != null) { + int[] bodyBounds = getBounds(oldT.body); + copyTo(localPointer, bodyBounds[0]); + localPointer = diffTree(oldT.body, newT.body, bodyBounds); + } + copyTo(localPointer, bounds[1]); + return bounds[1]; + } protected int diffFieldGroup(FieldGroupTree oldT, FieldGroupTree newT, int[] bounds) { if (!listsMatch(oldT.getVariables(), newT.getVariables())) { @@ -2024,139 +2109,139 @@ // don't use visitor, since we want fast-fail behavior switch (t1.getTag()) { - case JCTree.TOPLEVEL: + case TOPLEVEL: return ((JCCompilationUnit)t1).sourcefile.equals(((JCCompilationUnit)t2).sourcefile); - case JCTree.IMPORT: + case IMPORT: return matchImport((JCImport)t1, (JCImport)t2); - case JCTree.CLASSDEF: + case CLASSDEF: return ((JCClassDecl)t1).sym == ((JCClassDecl)t2).sym; - case JCTree.METHODDEF: + case METHODDEF: return ((JCMethodDecl)t1).sym == ((JCMethodDecl)t2).sym; - case JCTree.VARDEF: + case VARDEF: return ((JCVariableDecl)t1).sym == ((JCVariableDecl)t2).sym; - case JCTree.SKIP: + case SKIP: return true; - case JCTree.BLOCK: + case BLOCK: return matchBlock((JCBlock)t1, (JCBlock)t2); - case JCTree.DOLOOP: + case DOLOOP: return matchDoLoop((JCDoWhileLoop)t1, (JCDoWhileLoop)t2); - case JCTree.WHILELOOP: + case WHILELOOP: return matchWhileLoop((JCWhileLoop)t1, (JCWhileLoop)t2); - case JCTree.FORLOOP: + case FORLOOP: return matchForLoop((JCForLoop)t1, (JCForLoop)t2); - case JCTree.FOREACHLOOP: + case FOREACHLOOP: return matchForeachLoop((JCEnhancedForLoop)t1, (JCEnhancedForLoop)t2); - case JCTree.LABELLED: + case LABELLED: return matchLabelled((JCLabeledStatement)t1, (JCLabeledStatement)t2); - case JCTree.SWITCH: + case SWITCH: return matchSwitch((JCSwitch)t1, (JCSwitch)t2); - case JCTree.CASE: + case CASE: return matchCase((JCCase)t1, (JCCase)t2); - case JCTree.SYNCHRONIZED: + case SYNCHRONIZED: return matchSynchronized((JCSynchronized)t1, (JCSynchronized)t2); - case JCTree.TRY: + case TRY: return matchTry((JCTry)t1, (JCTry)t2); - case JCTree.CATCH: + case CATCH: return matchCatch((JCCatch)t1, (JCCatch)t2); - case JCTree.CONDEXPR: + case CONDEXPR: return matchConditional((JCConditional)t1, (JCConditional)t2); - case JCTree.IF: + case IF: return matchIf((JCIf)t1, (JCIf)t2); - case JCTree.EXEC: + case EXEC: return treesMatch(((JCExpressionStatement)t1).expr, ((JCExpressionStatement)t2).expr); - case JCTree.BREAK: + case BREAK: return matchBreak((JCBreak)t1, (JCBreak)t2); - case JCTree.CONTINUE: + case CONTINUE: return matchContinue((JCContinue)t1, (JCContinue)t2); - case JCTree.RETURN: + case RETURN: return treesMatch(((JCReturn)t1).expr, ((JCReturn)t2).expr); - case JCTree.THROW: + case THROW: return treesMatch(((JCThrow)t1).expr, ((JCThrow)t2).expr); - case JCTree.ASSERT: + case ASSERT: return matchAssert((JCAssert)t1, (JCAssert)t2); - case JCTree.APPLY: + case APPLY: return matchApply((JCMethodInvocation)t1, (JCMethodInvocation)t2); - case JCTree.NEWCLASS: + case NEWCLASS: // #97501: workaround. Not sure about comparing symbols and their // copying in ImmutableTreeTranslator, making workaround with // minimal impact - issue has to be fixed correctly in the future. if (((JCNewClass)t2).def != null) ((JCNewClass)t2).def.sym = null; return matchNewClass((JCNewClass)t1, (JCNewClass)t2); - case JCTree.NEWARRAY: + case NEWARRAY: return matchNewArray((JCNewArray)t1, (JCNewArray)t2); - case JCTree.PARENS: + case PARENS: return treesMatch(((JCParens)t1).expr, ((JCParens)t2).expr); - case JCTree.ASSIGN: + case ASSIGN: return matchAssign((JCAssign)t1, (JCAssign)t2); - case JCTree.TYPECAST: + case TYPECAST: return matchTypeCast((JCTypeCast)t1, (JCTypeCast)t2); - case JCTree.TYPETEST: + case TYPETEST: return matchTypeTest((JCInstanceOf)t1, (JCInstanceOf)t2); - case JCTree.INDEXED: + case INDEXED: return matchIndexed((JCArrayAccess)t1, (JCArrayAccess)t2); - case JCTree.SELECT: + case SELECT: return matchSelect((JCFieldAccess) t1, (JCFieldAccess) t2); - case JCTree.IDENT: + case IDENT: return ((JCIdent)t1).getName().contentEquals(((JCIdent)t2).getName()); - case JCTree.LITERAL: + case LITERAL: return matchLiteral((JCLiteral)t1, (JCLiteral)t2); - case JCTree.TYPEIDENT: + case TYPEIDENT: return ((JCPrimitiveTypeTree)t1).typetag == ((JCPrimitiveTypeTree)t2).typetag; - case JCTree.TYPEARRAY: + case TYPEARRAY: return treesMatch(((JCArrayTypeTree)t1).elemtype, ((JCArrayTypeTree)t2).elemtype); - case JCTree.TYPEAPPLY: + case TYPEAPPLY: return matchTypeApply((JCTypeApply)t1, (JCTypeApply)t2); - case JCTree.TYPEPARAMETER: + case TYPEPARAMETER: return matchTypeParameter((JCTypeParameter)t1, (JCTypeParameter)t2); - case JCTree.WILDCARD: + case WILDCARD: return matchWildcard((JCWildcard)t1, (JCWildcard)t2); - case JCTree.TYPEBOUNDKIND: + case TYPEBOUNDKIND: return ((TypeBoundKind)t1).kind == ((TypeBoundKind)t2).kind; - case JCTree.ANNOTATION: + case ANNOTATION: return matchAnnotation((JCAnnotation)t1, (JCAnnotation)t2); - case JCTree.LETEXPR: + case LETEXPR: return matchLetExpr((LetExpr)t1, (LetExpr)t2); - case JCTree.POS: - case JCTree.NEG: - case JCTree.NOT: - case JCTree.COMPL: - case JCTree.PREINC: - case JCTree.PREDEC: - case JCTree.POSTINC: - case JCTree.POSTDEC: - case JCTree.NULLCHK: + case POS: + case NEG: + case NOT: + case COMPL: + case PREINC: + case PREDEC: + case POSTINC: + case POSTDEC: + case NULLCHK: return matchUnary((JCUnary)t1, (JCUnary)t2); - case JCTree.OR: - case JCTree.AND: - case JCTree.BITOR: - case JCTree.BITXOR: - case JCTree.BITAND: - case JCTree.EQ: - case JCTree.NE: - case JCTree.LT: - case JCTree.GT: - case JCTree.LE: - case JCTree.GE: - case JCTree.SL: - case JCTree.SR: - case JCTree.USR: - case JCTree.PLUS: - case JCTree.MINUS: - case JCTree.MUL: - case JCTree.DIV: - case JCTree.MOD: + case OR: + case AND: + case BITOR: + case BITXOR: + case BITAND: + case EQ: + case NE: + case LT: + case GT: + case LE: + case GE: + case SL: + case SR: + case USR: + case PLUS: + case MINUS: + case MUL: + case DIV: + case MOD: return matchBinary((JCBinary)t1, (JCBinary)t2); - case JCTree.BITOR_ASG: - case JCTree.BITXOR_ASG: - case JCTree.BITAND_ASG: - case JCTree.SL_ASG: - case JCTree.SR_ASG: - case JCTree.USR_ASG: - case JCTree.PLUS_ASG: - case JCTree.MINUS_ASG: - case JCTree.MUL_ASG: - case JCTree.DIV_ASG: - case JCTree.MOD_ASG: + case BITOR_ASG: + case BITXOR_ASG: + case BITAND_ASG: + case SL_ASG: + case SR_ASG: + case USR_ASG: + case PLUS_ASG: + case MINUS_ASG: + case MUL_ASG: + case DIV_ASG: + case MOD_ASG: return matchAssignop((JCAssignOp)t1, (JCAssignOp)t2); default: String msg = ((com.sun.source.tree.Tree)t1).getKind().toString() + @@ -3259,194 +3344,200 @@ } switch (oldT.getTag()) { - case JCTree.TOPLEVEL: + case TOPLEVEL: diffTopLevel((JCCompilationUnit)oldT, (JCCompilationUnit)newT); break; - case JCTree.IMPORT: + case IMPORT: retVal = diffImport((JCImport)oldT, (JCImport)newT, elementBounds); break; - case JCTree.CLASSDEF: + case CLASSDEF: retVal = diffClassDef((JCClassDecl)oldT, (JCClassDecl)newT, elementBounds); break; - case JCTree.METHODDEF: + case METHODDEF: retVal = diffMethodDef((JCMethodDecl)oldT, (JCMethodDecl)newT, elementBounds); break; - case JCTree.VARDEF: + case VARDEF: retVal = diffVarDef((JCVariableDecl)oldT, (JCVariableDecl)newT, elementBounds); break; - case JCTree.SKIP: + case SKIP: copyTo(elementBounds[0], elementBounds[1]); retVal = elementBounds[1]; break; - case JCTree.BLOCK: + case BLOCK: retVal = diffBlock((JCBlock)oldT, (JCBlock)newT, elementBounds); break; - case JCTree.DOLOOP: + case DOLOOP: retVal = diffDoLoop((JCDoWhileLoop)oldT, (JCDoWhileLoop)newT, elementBounds); break; - case JCTree.WHILELOOP: + case WHILELOOP: retVal = diffWhileLoop((JCWhileLoop)oldT, (JCWhileLoop)newT, elementBounds); break; - case JCTree.FORLOOP: + case FORLOOP: retVal = diffForLoop((JCForLoop)oldT, (JCForLoop)newT, elementBounds); break; - case JCTree.FOREACHLOOP: + case FOREACHLOOP: retVal = diffForeachLoop((JCEnhancedForLoop)oldT, (JCEnhancedForLoop)newT, elementBounds); break; - case JCTree.LABELLED: + case LABELLED: retVal = diffLabelled((JCLabeledStatement)oldT, (JCLabeledStatement)newT, elementBounds); break; - case JCTree.SWITCH: + case SWITCH: retVal = diffSwitch((JCSwitch)oldT, (JCSwitch)newT, elementBounds); break; - case JCTree.CASE: + case CASE: retVal = diffCase((JCCase)oldT, (JCCase)newT, elementBounds); break; - case JCTree.SYNCHRONIZED: + case SYNCHRONIZED: retVal = diffSynchronized((JCSynchronized)oldT, (JCSynchronized)newT, elementBounds); break; - case JCTree.TRY: + case TRY: retVal = diffTry((JCTry)oldT, (JCTry)newT, elementBounds); break; - case JCTree.CATCH: + case CATCH: retVal = diffCatch((JCCatch)oldT, (JCCatch)newT, elementBounds); break; - case JCTree.CONDEXPR: + case CONDEXPR: retVal = diffConditional((JCConditional)oldT, (JCConditional)newT, elementBounds); break; - case JCTree.IF: + case IF: retVal = diffIf((JCIf)oldT, (JCIf)newT, elementBounds); break; - case JCTree.EXEC: + case EXEC: retVal = diffExec((JCExpressionStatement)oldT, (JCExpressionStatement)newT, elementBounds); break; - case JCTree.BREAK: + case BREAK: retVal = diffBreak((JCBreak)oldT, (JCBreak)newT, elementBounds); break; - case JCTree.CONTINUE: + case CONTINUE: retVal = diffContinue((JCContinue)oldT, (JCContinue)newT, elementBounds); break; - case JCTree.RETURN: + case RETURN: retVal = diffReturn((JCReturn)oldT, (JCReturn)newT, elementBounds); break; - case JCTree.THROW: + case THROW: retVal = diffThrow((JCThrow)oldT, (JCThrow)newT,elementBounds); break; - case JCTree.ASSERT: + case ASSERT: retVal = diffAssert((JCAssert)oldT, (JCAssert)newT, elementBounds); break; - case JCTree.APPLY: + case APPLY: retVal = diffApply((JCMethodInvocation)oldT, (JCMethodInvocation)newT, elementBounds); break; - case JCTree.NEWCLASS: + case NEWCLASS: retVal = diffNewClass((JCNewClass)oldT, (JCNewClass)newT, elementBounds); break; - case JCTree.NEWARRAY: + case NEWARRAY: retVal = diffNewArray((JCNewArray)oldT, (JCNewArray)newT, elementBounds); break; - case JCTree.PARENS: + case PARENS: retVal = diffParens((JCParens)oldT, (JCParens)newT, elementBounds); break; - case JCTree.ASSIGN: + case ASSIGN: retVal = diffAssign((JCAssign)oldT, (JCAssign)newT, parent, elementBounds); break; - case JCTree.TYPECAST: + case TYPECAST: retVal = diffTypeCast((JCTypeCast)oldT, (JCTypeCast)newT, elementBounds); break; - case JCTree.TYPETEST: + case TYPETEST: retVal = diffTypeTest((JCInstanceOf)oldT, (JCInstanceOf)newT, elementBounds); break; - case JCTree.INDEXED: + case INDEXED: retVal = diffIndexed((JCArrayAccess)oldT, (JCArrayAccess)newT, elementBounds); break; - case JCTree.SELECT: + case SELECT: retVal = diffSelect((JCFieldAccess)oldT, (JCFieldAccess)newT, elementBounds); break; - case JCTree.IDENT: + case IDENT: retVal = diffIdent((JCIdent)oldT, (JCIdent)newT, elementBounds); break; - case JCTree.LITERAL: + case LITERAL: retVal = diffLiteral((JCLiteral)oldT, (JCLiteral)newT, elementBounds); break; - case JCTree.TYPEIDENT: + case TYPEIDENT: retVal = diffTypeIdent((JCPrimitiveTypeTree)oldT, (JCPrimitiveTypeTree)newT, elementBounds); break; - case JCTree.TYPEARRAY: + case TYPEARRAY: retVal = diffTypeArray((JCArrayTypeTree)oldT, (JCArrayTypeTree)newT, elementBounds); break; - case JCTree.TYPEAPPLY: + case TYPEAPPLY: retVal = diffTypeApply((JCTypeApply)oldT, (JCTypeApply)newT, elementBounds); break; - case JCTree.TYPEPARAMETER: + case TYPEPARAMETER: retVal = diffTypeParameter((JCTypeParameter)oldT, (JCTypeParameter)newT, elementBounds); break; - case JCTree.WILDCARD: + case WILDCARD: retVal = diffWildcard((JCWildcard)oldT, (JCWildcard)newT, elementBounds); break; - case JCTree.TYPEBOUNDKIND: + case TYPEBOUNDKIND: retVal = diffTypeBoundKind((TypeBoundKind)oldT, (TypeBoundKind)newT, elementBounds); break; - case JCTree.ANNOTATION: + case ANNOTATION: retVal = diffAnnotation((JCAnnotation)oldT, (JCAnnotation)newT, elementBounds); break; - case JCTree.LETEXPR: + case LETEXPR: diffLetExpr((LetExpr)oldT, (LetExpr)newT); break; - case JCTree.POS: - case JCTree.NEG: - case JCTree.NOT: - case JCTree.COMPL: - case JCTree.PREINC: - case JCTree.PREDEC: - case JCTree.POSTINC: - case JCTree.POSTDEC: - case JCTree.NULLCHK: + case POS: + case NEG: + case NOT: + case COMPL: + case PREINC: + case PREDEC: + case POSTINC: + case POSTDEC: + case NULLCHK: retVal = diffUnary((JCUnary)oldT, (JCUnary)newT, elementBounds); break; - case JCTree.OR: - case JCTree.AND: - case JCTree.BITOR: - case JCTree.BITXOR: - case JCTree.BITAND: - case JCTree.EQ: - case JCTree.NE: - case JCTree.LT: - case JCTree.GT: - case JCTree.LE: - case JCTree.GE: - case JCTree.SL: - case JCTree.SR: - case JCTree.USR: - case JCTree.PLUS: - case JCTree.MINUS: - case JCTree.MUL: - case JCTree.DIV: - case JCTree.MOD: + case OR: + case AND: + case BITOR: + case BITXOR: + case BITAND: + case EQ: + case NE: + case LT: + case GT: + case LE: + case GE: + case SL: + case SR: + case USR: + case PLUS: + case MINUS: + case MUL: + case DIV: + case MOD: retVal = diffBinary((JCBinary)oldT, (JCBinary)newT, elementBounds); break; - case JCTree.BITOR_ASG: - case JCTree.BITXOR_ASG: - case JCTree.BITAND_ASG: - case JCTree.SL_ASG: - case JCTree.SR_ASG: - case JCTree.USR_ASG: - case JCTree.PLUS_ASG: - case JCTree.MINUS_ASG: - case JCTree.MUL_ASG: - case JCTree.DIV_ASG: - case JCTree.MOD_ASG: + case BITOR_ASG: + case BITXOR_ASG: + case BITAND_ASG: + case SL_ASG: + case SR_ASG: + case USR_ASG: + case PLUS_ASG: + case MINUS_ASG: + case MUL_ASG: + case DIV_ASG: + case MOD_ASG: retVal = diffAssignop((JCAssignOp)oldT, (JCAssignOp)newT, elementBounds); break; - case JCTree.ERRONEOUS: + case ERRONEOUS: diffErroneous((JCErroneous)oldT, (JCErroneous)newT, elementBounds); break; - case JCTree.MODIFIERS: + case MODIFIERS: retVal = diffModifiers((JCModifiers) oldT, (JCModifiers) newT, parent, elementBounds[0]); copyTo(retVal, elementBounds[1]); break; - case JCTree.TYPEUNION: + case TYPEUNION: retVal = diffUnionType((JCTypeUnion) oldT, (JCTypeUnion) newT, elementBounds); break; + case LAMBDA: + retVal = diffLambda((JCLambda) oldT, (JCLambda) newT, elementBounds); + break; + case REFERENCE: + retVal = diffMemberReference((JCMemberReference) oldT, (JCMemberReference) newT, elementBounds); + break; default: // handle special cases like field groups and enum constants if (oldT.getKind() == Kind.OTHER) { diff --git a/java.source/src/org/netbeans/modules/java/source/save/ElementOverlay.java b/java.source/src/org/netbeans/modules/java/source/save/ElementOverlay.java --- a/java.source/src/org/netbeans/modules/java/source/save/ElementOverlay.java +++ b/java.source/src/org/netbeans/modules/java/source/save/ElementOverlay.java @@ -512,6 +512,11 @@ } @Override + public A[] getAnnotations(Class annotationType) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override public Set getModifiers() { return mods; } @@ -596,6 +601,11 @@ } @Override + public A[] getAnnotations(Class annotationType) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override public Set getModifiers() { return delegateTo.getModifiers(); } @@ -664,6 +674,11 @@ } @Override + public A[] getAnnotations(Class annotationType) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override public Set getModifiers() { throw new UnsupportedOperationException("Not supported yet."); } @@ -734,6 +749,11 @@ } @Override + public A[] getAnnotations(Class annotationType) { + throw new UnsupportedOperationException("Not supported yet."); + } + + @Override public Set getModifiers() { throw new UnsupportedOperationException("Not supported yet."); } diff --git a/java.source/src/org/netbeans/modules/java/source/save/Reformatter.java b/java.source/src/org/netbeans/modules/java/source/save/Reformatter.java --- a/java.source/src/org/netbeans/modules/java/source/save/Reformatter.java +++ b/java.source/src/org/netbeans/modules/java/source/save/Reformatter.java @@ -966,8 +966,10 @@ } else { if (!insideForOrCatch) continuationIndent = true; - if (scan(node.getType(), p)) { - spaces(1, fieldGroup); + if (node.getType() == null || scan(node.getType(), p)) { + if (node.getType() != null) { + spaces(1, fieldGroup); + } if (!ERROR.contentEquals(node.getName())) accept(IDENTIFIER); } diff --git a/java.source/src/org/netbeans/modules/java/source/tasklist/CompilerSettings.java b/java.source/src/org/netbeans/modules/java/source/tasklist/CompilerSettings.java --- a/java.source/src/org/netbeans/modules/java/source/tasklist/CompilerSettings.java +++ b/java.source/src/org/netbeans/modules/java/source/tasklist/CompilerSettings.java @@ -118,6 +118,7 @@ if (get(p, ENABLE_LINT_RAWTYPES)) sb.append("-Xlint:rawtypes "); + sb.append("-XDidentifyLambdaCandidate=true "); sb.append("-XDfindDiamond "); if (sb.length() > 0 && sb.charAt(sb.length() - 1) == ' ') { diff --git a/java.source/src/org/netbeans/modules/java/source/transform/FieldGroupTree.java b/java.source/src/org/netbeans/modules/java/source/transform/FieldGroupTree.java --- a/java.source/src/org/netbeans/modules/java/source/transform/FieldGroupTree.java +++ b/java.source/src/org/netbeans/modules/java/source/transform/FieldGroupTree.java @@ -105,7 +105,7 @@ return vars.hashCode(); } - public int getTag() { - return 0; + public Tag getTag() { + return Tag.NO_TAG; } } diff --git a/java.source/src/org/netbeans/modules/java/source/transform/ImmutableTreeTranslator.java b/java.source/src/org/netbeans/modules/java/source/transform/ImmutableTreeTranslator.java --- a/java.source/src/org/netbeans/modules/java/source/transform/ImmutableTreeTranslator.java +++ b/java.source/src/org/netbeans/modules/java/source/transform/ImmutableTreeTranslator.java @@ -386,6 +386,9 @@ public Tree visitLabeledStatement(LabeledStatementTree tree, Object p) { return rewriteChildren(tree); } + public Tree visitLambdaExpression(LambdaExpressionTree tree, Object p) { + return rewriteChildren(tree); + } public Tree visitSwitch(SwitchTree tree, Object p) { return rewriteChildren(tree); } @@ -455,9 +458,16 @@ public Tree visitInstanceOf(InstanceOfTree tree, Object p) { return rewriteChildren(tree); } + public Tree visitIntersectionType(IntersectionTypeTree tree, Object p) { + return rewriteChildren(tree); + } public Tree visitArrayAccess(ArrayAccessTree tree, Object p) { return rewriteChildren(tree); } + @Override + public Tree visitMemberReference(MemberReferenceTree tree, Object p) { + return rewriteChildren(tree); + } public Tree visitMemberSelect(MemberSelectTree tree, Object p) { if (tree instanceof QualIdentTree) { QualIdentTree qit = (QualIdentTree) tree; @@ -497,6 +507,9 @@ public Tree visitWildcard(WildcardTree tree, Object p) { return rewriteChildren(tree); } + public Tree visitAnnotatedType(AnnotatedTypeTree tree, Object p) { + return rewriteChildren(tree); + } public Tree visitAnnotation(AnnotationTree tree, Object p) { return rewriteChildren(tree); } @@ -737,6 +750,22 @@ return tree; } + protected final LambdaExpressionTree rewriteChildren(LambdaExpressionTree tree) { + Tree body = translate(tree.getBody()); + List parameters = translate(tree.getParameters()); + + if (body != tree.getBody() || + parameters != tree.getParameters()) + { + LambdaExpressionTree n = make.LambdaExpression(parameters, body); + model.setType(n, model.getType(tree)); + copyCommentTo(tree,n); + copyPosTo(tree,n); + tree = n; + } + return tree; + } + protected final SwitchTree rewriteChildren(SwitchTree tree) { ExpressionTree selector = (ExpressionTree)translate(tree.getExpression()); List cases = translateStable(tree.getCases()); @@ -1059,6 +1088,18 @@ return tree; } + protected final IntersectionTypeTree rewriteChildren(IntersectionTypeTree tree) { + List bounds = translate(tree.getBounds()); + if (!safeEquals(bounds, tree.getBounds())) { + IntersectionTypeTree n = make.IntersectionType(bounds); + model.setType(n, model.getType(tree)); + copyCommentTo(tree,n); + copyPosTo(tree,n); + tree = n; + } + return tree; + } + protected final ArrayAccessTree rewriteChildren(ArrayAccessTree tree) { ExpressionTree array = (ExpressionTree)translate(tree.getExpression()); ExpressionTree index = (ExpressionTree)translate(tree.getIndex()); @@ -1157,13 +1198,28 @@ return tree; } + protected final AnnotatedTypeTree rewriteChildren(AnnotatedTypeTree tree) { + List annotations = translate(tree.getAnnotations()); + ExpressionTree underlyingType = (ExpressionTree)translate(tree.getUnderlyingType()); + if (!annotations.equals(tree.getAnnotations()) || underlyingType != tree.getUnderlyingType()) { + AnnotatedTypeTree n = make.AnnotatedType(annotations, underlyingType); + model.setType(n, model.getType(tree)); + copyCommentTo(tree,n); + copyPosTo(tree,n); + tree = n; + } + return tree; + } + protected final AnnotationTree rewriteChildren(AnnotationTree tree) { Tree annotationType = translate(tree.getAnnotationType()); List args = translate(tree.getArguments()); if (annotationType!=tree.getAnnotationType() || !args.equals(tree.getArguments())) { if (args != tree.getArguments()) args = optimize(args); - AnnotationTree n = make.Annotation(annotationType, args); + AnnotationTree n = tree.getKind() == Kind.ANNOTATION + ? make.Annotation(annotationType, args) + : make.TypeAnnotation(annotationType, args); model.setType(n, model.getType(tree)); copyCommentTo(tree,n); tree = n; @@ -1200,5 +1256,21 @@ return tree; } + private Tree rewriteChildren(MemberReferenceTree node) { + ExpressionTree qualifierExpression = (ExpressionTree) translate(node.getQualifierExpression()); + List typeArguments = (List) translate(node.getTypeArguments()); + + if (qualifierExpression != node.getQualifierExpression() || + typeArguments != node.getTypeArguments()) + { + MemberReferenceTree n = make.MemberReference(node.getMode(), node.getName(), qualifierExpression, typeArguments); + model.setType(n, model.getType(node)); + copyCommentTo(node,n); + copyPosTo(node,n); + node = n; + } + return node; + } + } diff --git a/java.source/src/org/netbeans/modules/java/source/usages/BinaryAnalyser.java b/java.source/src/org/netbeans/modules/java/source/usages/BinaryAnalyser.java --- a/java.source/src/org/netbeans/modules/java/source/usages/BinaryAnalyser.java +++ b/java.source/src/org/netbeans/modules/java/source/usages/BinaryAnalyser.java @@ -121,7 +121,7 @@ -/** +/**TODO: the full index does not handle invokeDynamicInfo, MethodHandleInfo and MethodTypeInfo. * * @author Petr Hrebejk, Tomas Zezula */ diff --git a/java.source/src/org/netbeans/modules/java/source/usages/ClassFileUtil.java b/java.source/src/org/netbeans/modules/java/source/usages/ClassFileUtil.java --- a/java.source/src/org/netbeans/modules/java/source/usages/ClassFileUtil.java +++ b/java.source/src/org/netbeans/modules/java/source/usages/ClassFileUtil.java @@ -59,6 +59,7 @@ import javax.lang.model.type.ArrayType; import javax.lang.model.type.DeclaredType; import javax.lang.model.type.ErrorType; +import javax.lang.model.type.IntersectionType; import javax.lang.model.type.TypeKind; import javax.lang.model.type.TypeMirror; import javax.lang.model.type.TypeVariable; @@ -278,11 +279,11 @@ break; case DECLARED: { - sb.append('L'); // NOI18N - TypeElement te = (TypeElement) ((DeclaredType)type).asElement(); - encodeClassName(te, sb,'/'); - sb.append(';'); // NOI18N - break; + sb.append('L'); // NOI18N + TypeElement te = (TypeElement) ((DeclaredType)type).asElement(); + encodeClassName(te, sb,'/'); + sb.append(';'); // NOI18N + break; } case TYPEVAR: { @@ -307,6 +308,11 @@ break; } } + case INTERSECTION: + { + encodeType(((IntersectionType) type).getBounds().get(0), sb); + break; + } default: throw new IllegalArgumentException (); } diff --git a/java.source/test/unit/src/org/netbeans/api/java/source/gen/AddCastTest.java b/java.source/test/unit/src/org/netbeans/api/java/source/gen/LambdaTest.java copy from java.source/test/unit/src/org/netbeans/api/java/source/gen/AddCastTest.java copy to java.source/test/unit/src/org/netbeans/api/java/source/gen/LambdaTest.java --- a/java.source/test/unit/src/org/netbeans/api/java/source/gen/AddCastTest.java +++ b/java.source/test/unit/src/org/netbeans/api/java/source/gen/LambdaTest.java @@ -44,15 +44,20 @@ package org.netbeans.api.java.source.gen; import com.sun.source.tree.BlockTree; -import com.sun.source.tree.ClassTree; import com.sun.source.tree.CompilationUnitTree; import com.sun.source.tree.ExpressionTree; -import com.sun.source.tree.ForLoopTree; -import com.sun.source.tree.MethodTree; +import com.sun.source.tree.LambdaExpressionTree; +import com.sun.source.tree.LiteralTree; +import com.sun.source.tree.MemberReferenceTree; +import com.sun.source.tree.MemberReferenceTree.ReferenceMode; +import com.sun.source.tree.ReturnTree; import com.sun.source.tree.VariableTree; +import com.sun.source.util.TreeScanner; import java.io.File; import java.io.IOException; -import javax.lang.model.type.TypeKind; +import java.util.Collections; +import java.util.EnumSet; +import javax.lang.model.element.Modifier; import org.netbeans.api.java.source.Task; import org.netbeans.api.java.source.JavaSource; import org.netbeans.api.java.source.JavaSource.Phase; @@ -66,56 +71,50 @@ * * @author Pavel Flaska */ -public class AddCastTest extends GeneratorTestMDRCompat { +public class LambdaTest extends GeneratorTestMDRCompat { /** Creates a new instance of AddCastTest */ - public AddCastTest(String name) { + public LambdaTest(String name) { super(name); } public static NbTestSuite suite() { NbTestSuite suite = new NbTestSuite(); - suite.addTestSuite(AddCastTest.class); + suite.addTestSuite(LambdaTest.class); return suite; } - public void testAddCastToDeclStmt() throws Exception { + public void testPrintMemberReference() throws Exception { testFile = new File(getWorkDir(), "Test.java"); TestUtilities.copyStringToFile(testFile, "package hierbas.del.litoral;\n\n" + - "import java.util.*;\n\n" + - "public class Test {\n" + - " public void taragui() {\n" + - " System.err.println(\"taragui() method\");\n" + - " String s = \"Oven.\";\n" + - "// line comment\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = null;\n" + " }\n" + "}\n" ); String golden = "package hierbas.del.litoral;\n\n" + - "import java.util.*;\n\n" + - "public class Test {\n" + - " public void taragui() {\n" + - " System.err.println(\"taragui() method\");\n" + - " String s = (String) \"Oven.\";\n" + - "// line comment\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = Test::taragui;\n" + " }\n" + "}\n"; JavaSource src = getJavaSource(testFile); Task task = new Task() { - public void run(WorkingCopy workingCopy) throws IOException { + public void run(final WorkingCopy workingCopy) throws IOException { workingCopy.toPhase(Phase.RESOLVED); CompilationUnitTree cut = workingCopy.getCompilationUnit(); - TreeMaker make = workingCopy.getTreeMaker(); - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); - MethodTree method = (MethodTree) clazz.getMembers().get(1); - VariableTree var = (VariableTree) method.getBody().getStatements().get(1); - ExpressionTree init = var.getInitializer(); - ExpressionTree cast = make.TypeCast(make.Identifier("String"), init); - workingCopy.rewrite(init, cast); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitLiteral(LiteralTree node, Void p) { + workingCopy.rewrite(node, make.MemberReference(ReferenceMode.INVOKE, make.Identifier("Test"), "taragui", Collections.emptyList())); + return super.visitLiteral(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); } }; @@ -125,47 +124,39 @@ assertEquals(golden, res); } - public void testAddCastInForWithoutSteps() throws Exception { + public void testBasicLambdaDiff() throws Exception { testFile = new File(getWorkDir(), "Test.java"); TestUtilities.copyStringToFile(testFile, "package hierbas.del.litoral;\n\n" + - "import java.util.*;\n\n" + - "public class Test {\n" + - " public void cast() {\n" + - " Object o = null;\n" + - " for (int i = 0; i < 5; ) {\n" + - " String s = o;\n" + - " }\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> {};\n" + " }\n" + "}\n" ); String golden = "package hierbas.del.litoral;\n\n" + - "import java.util.*;\n\n" + - "public class Test {\n" + - " public void cast() {\n" + - " Object o = null;\n" + - " for (int i = 0; i < 5; ) {\n" + - " String s = (String) o;\n" + - " }\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (f) -> {};\n" + " }\n" + "}\n"; JavaSource src = getJavaSource(testFile); Task task = new Task() { - public void run(WorkingCopy workingCopy) throws IOException { + public void run(final WorkingCopy workingCopy) throws IOException { workingCopy.toPhase(Phase.RESOLVED); CompilationUnitTree cut = workingCopy.getCompilationUnit(); - TreeMaker make = workingCopy.getTreeMaker(); - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); - MethodTree method = (MethodTree) clazz.getMembers().get(1); - ForLoopTree forLoop = (ForLoopTree) method.getBody().getStatements().get(1); - BlockTree block = (BlockTree) forLoop.getStatement(); - VariableTree vt = (VariableTree) block.getStatements().get(0); - ExpressionTree init = vt.getInitializer(); - ExpressionTree cast = make.TypeCast(make.Identifier("String"), init); - workingCopy.rewrite(init, cast); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitVariable(VariableTree node, Void p) { + if (node.getName().contentEquals("e")) { + workingCopy.rewrite(node, make.setLabel(node, "f")); + } + return super.visitVariable(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); } }; @@ -175,56 +166,36 @@ assertEquals(golden, res); } - /* - * #94324 - */ - public void testAddCast94324() throws Exception { + public void testAddFirstLambdaParam() throws Exception { testFile = new File(getWorkDir(), "Test.java"); TestUtilities.copyStringToFile(testFile, - "package javaapplication3;\n" + - "\n" + - "public class Klasa {\n" + - " \n" + - " static Object method() {\n" + - " return null;\n" + + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = () -> {};\n" + " }\n" + - " \n" + - " public static void main(String[] args) {\n" + - " // TODO code application logic here\n" + - " String s = Klasa.method();\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> {};\n" + " }\n" + - "\n" + - "}\n" - ); - String golden = - "package javaapplication3;\n" + - "\n" + - "public class Klasa {\n" + - " \n" + - " static Object method() {\n" + - " return null;\n" + - " }\n" + - " \n" + - " public static void main(String[] args) {\n" + - " // TODO code application logic here\n" + - " String s = (String) Klasa.method();\n" + - " }\n" + - "\n" + "}\n"; JavaSource src = getJavaSource(testFile); Task task = new Task() { - public void run(WorkingCopy workingCopy) throws IOException { + public void run(final WorkingCopy workingCopy) throws IOException { workingCopy.toPhase(Phase.RESOLVED); - CompilationUnitTree cut = workingCopy.getCompilationUnit(); - TreeMaker make = workingCopy.getTreeMaker(); - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); - MethodTree method = (MethodTree) clazz.getMembers().get(2); - VariableTree var = (VariableTree) method.getBody().getStatements().get(0); - ExpressionTree init = var.getInitializer(); - ExpressionTree cast = make.TypeCast(make.Identifier("String"), init); - workingCopy.rewrite(init, cast); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { + workingCopy.rewrite(node, make.addLambdaParameter(node, make.Variable(make.Modifiers(EnumSet.noneOf(Modifier.class)), "e", null, null))); + return super.visitLambdaExpression(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); } }; @@ -234,41 +205,36 @@ assertEquals(golden, res); } - public void testAddCastLiteral() throws Exception { + public void testAddSecondLambdaParam() throws Exception { testFile = new File(getWorkDir(), "Test.java"); - TestUtilities.copyStringToFile(testFile, - "package javaapplication3;\n" + - "\n" + - "public class Klasa {\n" + - " public static void main(String[] args) {\n" + - " int i = args.length & 0xFEFE;\n" + + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> {};\n" + " }\n" + - "\n" + "}\n" - ); + ); String golden = - "package javaapplication3;\n" + - "\n" + - "public class Klasa {\n" + - " public static void main(String[] args) {\n" + - " int i = (int) (args.length & 0xFEFE);\n" + + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e, f) -> {};\n" + " }\n" + - "\n" + "}\n"; JavaSource src = getJavaSource(testFile); - + Task task = new Task() { - public void run(WorkingCopy workingCopy) throws IOException { + public void run(final WorkingCopy workingCopy) throws IOException { workingCopy.toPhase(Phase.RESOLVED); - CompilationUnitTree cut = workingCopy.getCompilationUnit(); - TreeMaker make = workingCopy.getTreeMaker(); - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); - MethodTree method = (MethodTree) clazz.getMembers().get(1); - VariableTree var = (VariableTree) method.getBody().getStatements().get(0); - ExpressionTree init = var.getInitializer(); - ExpressionTree cast = make.TypeCast(make.PrimitiveType(TypeKind.INT), make.Parenthesized(init)); - workingCopy.rewrite(init, cast); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { + workingCopy.rewrite(node, make.addLambdaParameter(node, make.Variable(make.Modifiers(EnumSet.noneOf(Modifier.class)), "f", null, null))); + return super.visitLambdaExpression(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); } }; @@ -277,75 +243,399 @@ System.err.println(res); assertEquals(golden, res); } - - /* - * #94324 - second test. If the moved expression is changed, it is again - * rewritten by VeryPretty - in this time, i do not see any solution for - * that. - *//* - public void testAddCast94324_2() throws Exception { + + public void testPrependSecondLambdaParam() throws Exception { testFile = new File(getWorkDir(), "Test.java"); TestUtilities.copyStringToFile(testFile, - "package javaapplication3;\n" + - "\n" + - "public class Klasa {\n" + - " \n" + - " static Object method() {\n" + - " return null;\n" + + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> {};\n" + " }\n" + - " \n" + - " public static void main(String[] args) {\n" + - " // TODO code application logic here\n" + - " String s = Klasa.method();\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (f, e) -> {};\n" + " }\n" + - "\n" + - "}\n" - ); - String golden = - "package javaapplication3;\n" + - "\n" + - "public class Klasa {\n" + - " \n" + - " static Object method() {\n" + - " return null;\n" + - " }\n" + - " \n" + - " public static void main(String[] args) {\n" + - " // TODO code application logic here\n" + - " String s = (String) javaapplication3.Klasa.metoda();\n" + - " }\n" + - "\n" + "}\n"; JavaSource src = getJavaSource(testFile); - CancellableTask task = new CancellableTask() { + Task task = new Task() { - public void run(WorkingCopy workingCopy) throws IOException { + public void run(final WorkingCopy workingCopy) throws IOException { workingCopy.toPhase(Phase.RESOLVED); - CompilationUnitTree cut = workingCopy.getCompilationUnit(); - TreeMaker make = workingCopy.getTreeMaker(); - ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); - MethodTree method = (MethodTree) clazz.getMembers().get(2); - VariableTree var = (VariableTree) method.getBody().getStatements().get(0); - MethodInvocationTree init = (MethodInvocationTree) var.getInitializer(); - MethodInvocationTree initCopy = make.MethodInvocation( - (List) init.getTypeArguments(), - make.setLabel((MemberSelectTree) init.getMethodSelect(), "metoda"), - init.getArguments() - ); - workingCopy.rewrite(init, initCopy); - ExpressionTree cast = make.TypeCast(make.Identifier("String"), initCopy); - workingCopy.rewrite(init, cast); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { + workingCopy.rewrite(node, make.insertLambdaParameter(node, 0, make.Variable(make.Modifiers(EnumSet.noneOf(Modifier.class)), "f", null, null))); + return super.visitLambdaExpression(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); } - public void cancel() { - } }; src.runModificationTask(task).commit(); String res = TestUtilities.copyFileToString(testFile); System.err.println(res); assertEquals(golden, res); - }*/ + } + + public void testRemoveFirstLambdaParam() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e, f) -> {};\n" + + " }\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (f) -> {};\n" + + " }\n" + + "}\n"; + JavaSource src = getJavaSource(testFile); + + Task task = new Task() { + + public void run(final WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(Phase.RESOLVED); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { + workingCopy.rewrite(node, make.removeLambdaParameter(node, 0)); + return super.visitLambdaExpression(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); + } + + }; + src.runModificationTask(task).commit(); + String res = TestUtilities.copyFileToString(testFile); + System.err.println(res); + assertEquals(golden, res); + } + + public void testRemoveSecondLambdaParam() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e, f) -> {};\n" + + " }\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> {};\n" + + " }\n" + + "}\n"; + JavaSource src = getJavaSource(testFile); + + Task task = new Task() { + + public void run(final WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(Phase.RESOLVED); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { + workingCopy.rewrite(node, make.removeLambdaParameter(node, 1)); + return super.visitLambdaExpression(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); + } + + }; + src.runModificationTask(task).commit(); + String res = TestUtilities.copyFileToString(testFile); + System.err.println(res); + assertEquals(golden, res); + } + + public void testOnlyLambdaParam() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> {};\n" + + " }\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = () -> {};\n" + + " }\n" + + "}\n"; + JavaSource src = getJavaSource(testFile); + + Task task = new Task() { + + public void run(final WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(Phase.RESOLVED); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { + workingCopy.rewrite(node, make.removeLambdaParameter(node, 0)); + return super.visitLambdaExpression(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); + } + + }; + src.runModificationTask(task).commit(); + String res = TestUtilities.copyFileToString(testFile); + System.err.println(res); + assertEquals(golden, res); + } + + public void testLambdaFullBody2Expression() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> {return 1;};\n" + + " }\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> 1;\n" + + " }\n" + + "}\n"; + JavaSource src = getJavaSource(testFile); + + Task task = new Task() { + + public void run(final WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(Phase.RESOLVED); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { + ReturnTree t = (ReturnTree) ((BlockTree) node.getBody()).getStatements().get(0); + workingCopy.rewrite(node, make.setLambdaBody(node, t.getExpression())); + return super.visitLambdaExpression(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); + } + + }; + src.runModificationTask(task).commit(); + String res = TestUtilities.copyFileToString(testFile); + System.err.println(res); + assertEquals(golden, res); + } + + public void testLambdaExpression2FullBody() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> 1;\n" + + " }\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " ChangeListener l = (e) -> {\n" + + " return 1;\n" + + " };\n" + + " }\n" + + "}\n"; + JavaSource src = getJavaSource(testFile); + + Task task = new Task() { + + public void run(final WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(Phase.RESOLVED); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitLambdaExpression(LambdaExpressionTree node, Void p) { + workingCopy.rewrite(node, make.setLambdaBody(node, make.Block(Collections.singletonList(make.Return((ExpressionTree) node.getBody())), false))); + return super.visitLambdaExpression(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); + } + + }; + src.runModificationTask(task).commit(); + String res = TestUtilities.copyFileToString(testFile); + System.err.println(res); + assertEquals(golden, res); + } + + public void testMethodReferenceDiff() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = hierbas.del.litoral.Test :: taragui;\n" + + " }\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = Test :: taragui;\n" + + " }\n" + + "}\n"; + JavaSource src = getJavaSource(testFile); + + Task task = new Task() { + + public void run(final WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(Phase.RESOLVED); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitMemberReference(MemberReferenceTree node, Void p) { + workingCopy.rewrite(node, make.MemberReference(node.getMode(), make.Identifier("Test"), node.getName(), node.getTypeArguments())); + return super.visitMemberReference(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); + } + + }; + src.runModificationTask(task).commit(); + String res = TestUtilities.copyFileToString(testFile); + System.err.println(res); + assertEquals(golden, res); + } + + public void testMethodReferenceNameDiff() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = Test :: taragui;\n" + + " }\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = Test :: taragui2;\n" + + " }\n" + + "}\n"; + JavaSource src = getJavaSource(testFile); + + Task task = new Task() { + + public void run(final WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(Phase.RESOLVED); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitMemberReference(MemberReferenceTree node, Void p) { + workingCopy.rewrite(node, make.setLabel(node, "taragui2")); + return super.visitMemberReference(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); + } + + }; + src.runModificationTask(task).commit(); + String res = TestUtilities.copyFileToString(testFile); + System.err.println(res); + assertEquals(golden, res); + } + + public void testMethodReferenceFirstTypeParam() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = Test::taragui;\n" + + " }\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = Test::taragui;\n" + + " }\n" + + "}\n"; + JavaSource src = getJavaSource(testFile); + + Task task = new Task() { + + public void run(final WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(Phase.RESOLVED); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitMemberReference(MemberReferenceTree node, Void p) { + workingCopy.rewrite(node, make.MemberReference(node.getMode(), node.getQualifierExpression(), node.getName(), Collections.singletonList(make.Identifier("String")))); + return super.visitMemberReference(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); + } + + }; + src.runModificationTask(task).commit(); + String res = TestUtilities.copyFileToString(testFile); + System.err.println(res); + assertEquals(golden, res); + } + + public void testMethodReferenceLastTypeParam() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = Test::taragui;\n" + + " }\n" + + "}\n" + ); + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n" + + " public static void taragui() {\n" + + " Runnable r = Test::taragui;\n" + + " }\n" + + "}\n"; + JavaSource src = getJavaSource(testFile); + + Task task = new Task() { + + public void run(final WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(Phase.RESOLVED); + final TreeMaker make = workingCopy.getTreeMaker(); + new TreeScanner() { + @Override public Void visitMemberReference(MemberReferenceTree node, Void p) { + workingCopy.rewrite(node, make.MemberReference(node.getMode(), node.getQualifierExpression(), node.getName(), null)); + return super.visitMemberReference(node, p); + } + }.scan(workingCopy.getCompilationUnit(), null); + } + + }; + src.runModificationTask(task).commit(); + String res = TestUtilities.copyFileToString(testFile); + System.err.println(res); + assertEquals(golden, res); + } String getGoldenPckg() { return ""; diff --git a/java.source/test/unit/src/org/netbeans/modules/java/source/parsing/JavacParserTest.java b/java.source/test/unit/src/org/netbeans/modules/java/source/parsing/JavacParserTest.java --- a/java.source/test/unit/src/org/netbeans/modules/java/source/parsing/JavacParserTest.java +++ b/java.source/test/unit/src/org/netbeans/modules/java/source/parsing/JavacParserTest.java @@ -42,12 +42,20 @@ package org.netbeans.modules.java.source.parsing; +import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.Tree; +import com.sun.source.util.TreePath; +import com.sun.source.util.TreePathScanner; import java.io.File; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import java.util.concurrent.atomic.AtomicReference; import javax.lang.model.element.TypeElement; +import javax.swing.text.Document; import javax.tools.Diagnostic; +import static junit.framework.Assert.assertTrue; +import org.netbeans.api.java.lexer.JavaTokenId; import org.netbeans.api.java.source.ClasspathInfo; import org.netbeans.api.java.source.CompilationController; import org.netbeans.api.java.source.JavaSource; @@ -55,10 +63,15 @@ import org.netbeans.api.java.source.SourceUtilsTestUtil; import org.netbeans.api.java.source.Task; import org.netbeans.api.java.source.TestUtilities; +import org.netbeans.api.lexer.Language; +import org.netbeans.api.lexer.TokenHierarchy; +import org.netbeans.api.lexer.TokenSequence; import org.netbeans.junit.NbTestCase; import org.netbeans.modules.java.source.tasklist.CompilerSettings; +import org.openide.cookies.EditorCookie; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import org.openide.loaders.DataObject; /** * @@ -126,6 +139,60 @@ } }, true); } + + public void testPartialReparse() throws Exception { + FileObject f2 = createFile("test/Test2.java", "package test; class Test2 { private void test() { System.err.println(\"\"); System.err.println(1); } }"); + DataObject d = DataObject.find(f2); + EditorCookie ec = d.getLookup().lookup(EditorCookie.class); + Document doc = ec.openDocument(); + JavaSource js = JavaSource.forFileObject(f2); + + doc.putProperty(Language.class, JavaTokenId.language()); + + //initialize the tokens hierarchy: + TokenSequence ts = TokenHierarchy.get(doc).tokenSequence(); + + ts.moveStart(); + + while (ts.moveNext()); + + final AtomicReference tree = new AtomicReference(); + + js.runUserActionTask(new Task() { + public void run(CompilationController parameter) throws Exception { + assertTrue(Phase.RESOLVED.compareTo(parameter.toPhase(Phase.RESOLVED)) <= 0); + tree.set(parameter.getCompilationUnit()); + } + }, true); + + doc.insertString(doc.getText(0, doc.getLength()).indexOf("\"") + 1, "aaaaaaaa", null); + + js.runUserActionTask(new Task() { + public void run(final CompilationController parameter) throws Exception { + assertTrue(Phase.RESOLVED.compareTo(parameter.toPhase(Phase.RESOLVED)) <= 0); + + assertSame(tree.get(), parameter.getCompilationUnit()); + + new TreePathScanner() { + + @Override + public Void scan(Tree tree, long[] parentSpan) { + if (tree == null) return null; + if (parameter.getTreeUtilities().isSynthetic(new TreePath(getCurrentPath(), tree))) return null; + long start = parameter.getTrees().getSourcePositions().getStartPosition(parameter.getCompilationUnit(), tree); + long end = parameter.getTrees().getSourcePositions().getEndPosition(parameter.getCompilationUnit(), tree); + assertTrue(start <= end); + if (parentSpan != null) { + assertTrue(parentSpan[0] <= start); + assertTrue(end <= parentSpan[1]); + } + return super.scan(tree, new long[] {start, end}); + } + + }.scan(parameter.getCompilationUnit(), null); + } + }, true); + } private FileObject createFile(String path, String content) throws Exception { FileObject file = FileUtil.createData(sourceRoot, path); diff --git a/java.source/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java b/java.source/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java --- a/java.source/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java +++ b/java.source/test/unit/src/org/netbeans/modules/java/source/save/FormatingTest.java @@ -4227,6 +4227,32 @@ reformat(doc, content, golden); } + public void testLambdaParameterWithInferredType() throws Exception { + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, ""); + FileObject testSourceFO = FileUtil.toFileObject(testFile); + DataObject testSourceDO = DataObject.find(testSourceFO); + EditorCookie ec = (EditorCookie)testSourceDO.getCookie(EditorCookie.class); + final Document doc = ec.openDocument(); + doc.putProperty(Language.class, JavaTokenId.language()); + String content = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n\n" + + " public static void main(String[] args) {\n" + + " java.util.Arrays.asList(args).map((val) -> val.length());\n" + + " }\n" + + "}\n"; + + String golden = + "package hierbas.del.litoral;\n\n" + + "public class Test {\n\n" + + " public static void main(String[] args) {\n" + + " java.util.Arrays.asList(args).map((val) -> val.length());\n" + + " }\n" + + "}\n"; + reformat(doc, content, golden); + } + private void reformat(Document doc, String content, String golden) throws Exception { reformat(doc, content, golden, 0, content.length()); }