提交 ac6619ea 编写于 作者: P pgovereau

8027886: javac allows illegal receiver parameters

8029042: Receiver parameter not supported on local class constructor
Reviewed-by: jfranck, jlahoda
上级 f88f25a9
...@@ -295,7 +295,8 @@ public class Flags { ...@@ -295,7 +295,8 @@ public class Flags {
ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT, ModifierFlags = ((long)StandardFlags & ~INTERFACE) | DEFAULT,
InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT, InterfaceMethodMask = ABSTRACT | STATIC | PUBLIC | STRICTFP | DEFAULT,
AnnotationTypeElementMask = ABSTRACT | PUBLIC, AnnotationTypeElementMask = ABSTRACT | PUBLIC,
LocalVarFlags = FINAL | PARAMETER; LocalVarFlags = FINAL | PARAMETER,
ReceiverParamFlags = PARAMETER;
public static Set<Modifier> asModifierSet(long flags) { public static Set<Modifier> asModifierSet(long flags) {
......
...@@ -1038,7 +1038,9 @@ public class Check { ...@@ -1038,7 +1038,9 @@ public class Check {
switch (sym.kind) { switch (sym.kind) {
case VAR: case VAR:
if (sym.owner.kind != TYP) if (TreeInfo.isReceiverParam(tree))
mask = ReceiverParamFlags;
else if (sym.owner.kind != TYP)
mask = LocalVarFlags; mask = LocalVarFlags;
else if ((sym.owner.flags_field & INTERFACE) != 0) else if ((sym.owner.flags_field & INTERFACE) != 0)
mask = implicit = InterfaceVarFlags; mask = implicit = InterfaceVarFlags;
......
...@@ -652,22 +652,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer { ...@@ -652,22 +652,8 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype); attr.attribIdentAsEnumType(localEnv, (JCIdent)tree.vartype);
} else { } else {
attr.attribType(tree.vartype, localEnv); attr.attribType(tree.vartype, localEnv);
if (tree.nameexpr != null) { if (TreeInfo.isReceiverParam(tree))
attr.attribExpr(tree.nameexpr, localEnv); checkReceiver(tree, localEnv);
MethodSymbol m = localEnv.enclMethod.sym;
if (m.isConstructor()) {
Type outertype = m.owner.owner.type;
if (outertype.hasTag(TypeTag.CLASS)) {
checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type");
checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name");
} else {
log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class");
}
} else {
checkType(tree.vartype, m.owner.type, "incorrect.receiver.type");
checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name");
}
}
} }
} finally { } finally {
deferredLintHandler.setPos(prevLintPos); deferredLintHandler.setPos(prevLintPos);
...@@ -714,6 +700,26 @@ public class MemberEnter extends JCTree.Visitor implements Completer { ...@@ -714,6 +700,26 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
log.error(tree, diag, type, tree.type); log.error(tree, diag, type, tree.type);
} }
} }
void checkReceiver(JCVariableDecl tree, Env<AttrContext> localEnv) {
attr.attribExpr(tree.nameexpr, localEnv);
MethodSymbol m = localEnv.enclMethod.sym;
if (m.isConstructor()) {
Type outertype = m.owner.owner.type;
if (outertype.hasTag(TypeTag.METHOD)) {
// we have a local inner class
outertype = m.owner.owner.owner.type;
}
if (outertype.hasTag(TypeTag.CLASS)) {
checkType(tree.vartype, outertype, "incorrect.constructor.receiver.type");
checkType(tree.nameexpr, outertype, "incorrect.constructor.receiver.name");
} else {
log.error(tree, "receiver.parameter.not.applicable.constructor.toplevel.class");
}
} else {
checkType(tree.vartype, m.owner.type, "incorrect.receiver.type");
checkType(tree.nameexpr, m.owner.type, "incorrect.receiver.name");
}
}
public boolean needsLazyConstValue(JCTree tree) { public boolean needsLazyConstValue(JCTree tree) {
InitTreeVisitor initTreeVisitor = new InitTreeVisitor(); InitTreeVisitor initTreeVisitor = new InitTreeVisitor();
......
...@@ -135,6 +135,14 @@ public class TreeInfo { ...@@ -135,6 +135,14 @@ public class TreeInfo {
} }
} }
public static boolean isReceiverParam(JCTree tree) {
if (tree.hasTag(VARDEF)) {
return ((JCVariableDecl)tree).nameexpr != null;
} else {
return false;
}
}
/** Is there a constructor declaration in the given list of trees? /** Is there a constructor declaration in the given list of trees?
*/ */
public static boolean hasConstructors(List<JCTree> trees) { public static boolean hasConstructors(List<JCTree> trees) {
......
/*
* @test /nodynamiccopyright/
* @bug 8027886
* @summary Receiver parameters must not be final
* @compile/fail/ref=FinalReceiverTest.out -XDrawDiagnostics FinalReceiverTest.java
*/
class FinalReceiverTest {
void m() {
class Inner {
Inner(final FinalReceiverTest FinalReceiverTest.this) {}
}
}
}
FinalReceiverTest.java:11:43: compiler.err.mod.not.allowed.here: final
1 error
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 8029042
* @summary Receiver parameter not supported on local class constructor
* @compile LocalInnerReceiverTest.java
*/
class LocalInnerReceiverTest {
void m() {
class Inner {
Inner(LocalInnerReceiverTest LocalInnerReceiverTest.this) {}
}
}
}
...@@ -54,14 +54,6 @@ class WithValue { ...@@ -54,14 +54,6 @@ class WithValue {
<T extends Runnable> void accept(@B("m") WithValue this, T r) throws Exception { } <T extends Runnable> void accept(@B("m") WithValue this, T r) throws Exception { }
} }
class WithFinal {
void plain(final @B("m") WithFinal this) { }
<T> void generic(final @B("m") WithFinal this) { }
void withException(final @B("m") WithFinal this) throws Exception { }
String nonVoid(final @B("m") WithFinal this) { return null; }
<T extends Runnable> void accept(final @B("m") WithFinal this, T r) throws Exception { }
}
class WithBody { class WithBody {
Object f; Object f;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册