diff options
author | Stephan Herrmann | 2013-01-10 20:43:20 +0000 |
---|---|---|
committer | Stephan Herrmann | 2013-01-10 20:49:23 +0000 |
commit | fd54faa4662f0a6e14064bcd8ea35fb0c4468221 (patch) | |
tree | 61ff367f98a6e888f0236e9870c922eb110b680a | |
parent | 6a28f979f6da0053d1645d86c269825a64ac6386 (diff) | |
download | org.eclipse.objectteams-fd54faa4662f0a6e14064bcd8ea35fb0c4468221.tar.gz org.eclipse.objectteams-fd54faa4662f0a6e14064bcd8ea35fb0c4468221.tar.xz org.eclipse.objectteams-fd54faa4662f0a6e14064bcd8ea35fb0c4468221.zip |
Bug 397878 - [compiler] Using field of enclosing team as team anchor
causes illegal bytecode to be created
5 files changed, 109 insertions, 45 deletions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java index ee157de8e..72f3a744c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/Reference.java @@ -1,10 +1,9 @@ /******************************************************************************* - * Copyright (c) 2000, 2012 IBM Corporation and others. + * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * $Id: Reference.java 23404 2010-02-03 14:10:22Z stephan $ * * Contributors: * IBM Corporation - initial API and implementation @@ -39,7 +38,6 @@ import org.eclipse.objectteams.otdt.internal.core.compiler.model.TeamModel; * Why: inferred callout to field must be created with proper type, possibly involving lifting. * * @author stephan - * @version $Id: Reference.java 23404 2010-02-03 14:10:22Z stephan $ */ public abstract class Reference extends Expression { //{ObjectTeams: store expected type to support infering callout-to-field @@ -201,6 +199,7 @@ protected int getDepthForSynthFieldAccess(FieldBinding fieldBinding, SourceTypeB // through copy inheritance this code could be executed within a different package! if (depth == 0) return -1; // neither a team field, nor an access across packages + this.bits = (this.bits & ~DepthMASK) | ((depth & 0xFF) << DepthSHIFT); } return depth; } diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java index 87c0f87b2..f5255439c 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/ast/TypeParameter.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2009 IBM Corporation and others. + * Copyright (c) 2000, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -152,7 +152,7 @@ public class TypeParameter extends AbstractVariableDeclaration { if (!ProblemAnchorBinding.checkAnchor(scope, this.type, anchors[0], this.name)) return; if (anchors[0] instanceof FieldBinding && anchors[0].isValidBinding()) - FieldModel.getModel((FieldBinding)anchors[0]).addUsageRank(this.binding.rank); + FieldModel.getModel(((FieldBinding)anchors[0]).original()).addUsageRank(this.binding.rank); // FIXME(SH): else store this in the AnchorListAttribute! int boundCnt = 0; if (this.bounds != null) diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/TypeAnchorReference.java b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/TypeAnchorReference.java index 2f294848b..4ff362534 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/TypeAnchorReference.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/objectteams/otdt/internal/core/compiler/ast/TypeAnchorReference.java @@ -1,16 +1,15 @@ /********************************************************************** * This file is part of "Object Teams Development Tooling"-Software * - * Copyright 2006 Fraunhofer Gesellschaft, Munich, Germany, + * Copyright 2006, 2013 Fraunhofer Gesellschaft, Munich, Germany, * for its Fraunhofer Institute for Computer Architecture and Software * Technology (FIRST), Berlin, Germany and Technical University Berlin, - * Germany. + * Germany, and others. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html - * $Id: TypeAnchorReference.java 23401 2010-02-02 23:56:05Z stephan $ * * Please visit http://www.eclipse.org/objectteams for updates and contact. * @@ -89,9 +88,8 @@ import org.eclipse.objectteams.otdt.internal.core.compiler.util.TypeAnalyzer; * the receiver expression. In that case also resolveType and generateCode are supported. * * @author stephan - * @version $Id: TypeAnchorReference.java 23401 2010-02-02 23:56:05Z stephan $ */ -public class TypeAnchorReference extends TypeReference { +public class TypeAnchorReference extends TypeReference implements InvocationSite { // either NameReference or FieldReference public Reference anchor; @@ -230,6 +228,7 @@ public class TypeAnchorReference extends TypeReference { currentToken = singleAnchor.token; currentAnchor = findVariable( scope, currentToken, scope.isStatic(), singleAnchor.sourceStart, singleAnchor.sourceEnd); + this.anchor.bits |= (this.bits & DepthMASK); // could be ProblemAnchorBinding } else if (reference instanceof FieldReference) { FieldReference fieldRef = (FieldReference)reference; @@ -411,13 +410,15 @@ public class TypeAnchorReference extends TypeReference { private ITeamAnchor findVariable(Scope scope, char[] token, boolean isStaticScope, int start, int end) { - ITeamAnchor anchorBinding = null; - Scope currentScope = scope; - scopes: while (currentScope != null) { - switch (currentScope.kind) { + if (scope instanceof ClassScope && ((ClassScope)scope).superTypeReference != null) { + scope.problemReporter().extendingExternalizedRole(((ClassScope)scope).superTypeReference); + return null; + } + VariableBinding anchorBinding = null; + switch (scope.kind) { case Scope.METHOD_SCOPE: // check arguments for possible anchor: - AbstractMethodDeclaration method = ((MethodScope)currentScope).referenceMethod(); + AbstractMethodDeclaration method = ((MethodScope)scope).referenceMethod(); if (method != null) { Argument[] arguments = method.arguments; if (arguments != null) @@ -429,20 +430,13 @@ public class TypeAnchorReference extends TypeReference { //$FALL-THROUGH$ case Scope.BLOCK_SCOPE: case Scope.BINDING_SCOPE: - anchorBinding = currentScope.findVariable(token); + anchorBinding = scope.findVariable(token); break; - case Scope.CLASS_SCOPE: - ReferenceBinding classType = currentScope.enclosingSourceType(); - if (classType.isSynthInterface()) - classType = classType.getRealClass(); - anchorBinding = TypeAnalyzer.findField(classType, token, isStaticScope, true); - isStaticScope = classType.isStatic(); // travelling out of this type - if (!classType.isLocalType()) - break scopes; // don't walk out any further, findField already takes care of direct class-nesting - } - if (anchorBinding != null) - break; - currentScope = currentScope.parent; + } + if (anchorBinding == null) { + Binding binding = scope.getBinding(token, Binding.VARIABLE, this, true); + if (binding instanceof VariableBinding) + anchorBinding = (VariableBinding) binding; } return checkAnchor(scope, this.anchor, token, start, end, anchorBinding); } @@ -450,10 +444,7 @@ public class TypeAnchorReference extends TypeReference { // post: return is either a valid anchor or null and problem has been reported. private ITeamAnchor checkAnchor(Scope scope, Reference reference, char[] token, int start, int end, ITeamAnchor anchorBinding) { if (anchorBinding == null) { - if (scope instanceof ClassScope && ((ClassScope)scope).superTypeReference != null) - scope.problemReporter().extendingExternalizedRole(((ClassScope)scope).superTypeReference); - else - scope.problemReporter().typeAnchorNotFound(token, start, end); + scope.problemReporter().typeAnchorNotFound(token, start, end); return null; } if (anchorBinding instanceof ProblemFieldBinding) { @@ -582,4 +573,33 @@ public class TypeAnchorReference extends TypeReference { } } } + + // === implement InvocationSite: === + + public TypeBinding[] genericTypeArguments() { + return Binding.NO_TYPES; + } + + public boolean isSuperAccess() { + return false; + } + + public boolean isTypeAccess() { + return false; + } + + public void setActualReceiverType(ReferenceBinding receiverType) { + // TODO Auto-generated method stub + } + + public void setDepth(int depth) { + this.bits &= ~DepthMASK; // flush previous depth if any + if (depth > 0) { + this.bits |= (depth & 0xFF) << DepthSHIFT; // encoded on 8 bits + } + } + + public void setFieldIndex(int depth) { + // ignored + } } diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/other/Java5.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/other/Java5.java index 45141bd2a..258b7b430 100644 --- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/other/Java5.java +++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/other/Java5.java @@ -1,7 +1,7 @@ /********************************************************************** * This file is part of "Object Teams Development Tooling"-Software * - * Copyright 2010, 2011 Stephan Herrmann + * Copyright 2010, 2013 Stephan Herrmann * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 @@ -4489,20 +4489,10 @@ public class Java5 extends AbstractOTJLDTest { " ^^^^^^^^^^^\n" + "Using an experimental feature: Implementation for mixed type and value parameters is experimental..\n" + "----------\n" + - "2. ERROR in TeamA119nvp2.java (at line 10)\n" + - " TA119nvp2_1<@t2,Role<@t1>> c = new TA119nvp2_1<@t2,Role<@t1>>();\n" + - " ^^^^\n" + - "Bound mismatch: The type Role<@t1> is not a valid substitute for the value dependent parameter <R<@t>> of the type TA119nvp2_1<@t,R<@t>> (OTJLD 9.2.2)\n" + - "----------\n" + - "3. WARNING in TeamA119nvp2.java (at line 10)\n" + + "2. WARNING in TeamA119nvp2.java (at line 10)\n" + " TA119nvp2_1<@t2,Role<@t1>> c = new TA119nvp2_1<@t2,Role<@t1>>();\n" + " ^^^^^^^^^^^\n" + "Using an experimental feature: Implementation for mixed type and value parameters is experimental..\n" + - "----------\n" + - "4. ERROR in TeamA119nvp2.java (at line 10)\n" + - " TA119nvp2_1<@t2,Role<@t1>> c = new TA119nvp2_1<@t2,Role<@t1>>();\n" + - " ^^^^\n" + - "Bound mismatch: The type Role<@t1> is not a valid substitute for the value dependent parameter <R<@t>> of the type TA119nvp2_1<@t,R<@t>> (OTJLD 9.2.2)\n" + "----------\n"); } diff --git a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/rolesandteams/ExternalizedRoles.java b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/rolesandteams/ExternalizedRoles.java index 0445c0887..ff81cee12 100644 --- a/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/rolesandteams/ExternalizedRoles.java +++ b/testplugins/org.eclipse.objectteams.otdt.tests/otjld/org/eclipse/objectteams/otdt/tests/otjld/rolesandteams/ExternalizedRoles.java @@ -28,7 +28,7 @@ public class ExternalizedRoles extends AbstractOTJLDTest { // Static initializer to specify tests subset using TESTS_* static variables // All specified tests which does not belong to the class are skipped... static { -// TESTS_NAMES = new String[] { "test166_typeAnchorIsPath9"}; +// TESTS_NAMES = new String[] { "test1615_assigningExternalizedCreation3"}; // TESTS_NUMBERS = new int[] { 1459 }; // TESTS_RANGE = new int[] { 1097, -1 }; } @@ -2358,6 +2358,61 @@ public class ExternalizedRoles extends AbstractOTJLDTest { "1.2.2(c)"); } + // similar to the above, using new syntax, anchor is field of enclosing team + // see https://bugs.eclipse.org/397878 - [compiler] Using field of enclosing team as team anchor causes illegal bytecode to be created + public void test1615_assigningExternalizedCreation2() { + runConformTest( + new String[] { + "Team1615aec2.java", + "\n" + + "public team class Team1615aec2 {\n" + + " final Team1615aec2 t;" + + " Team1615aec2(Team1615aec2 other) { t = other; }\n" + + " public class R {" + + " protected void test() {" + + " t.test(new R<@t>());\n" + // verify error was observed here + " }\n" + + " protected void print() { System.out.print(\"OK\"); }\n" + + " }\n" + + " public void test(R r) {" + + " r.print();\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " new Team1615aec2(new Team1615aec2(null)).new R().test();\n" + + " }\n" + + "}\n" + }, + "OK"); + } + + // similar to the above, using new syntax, anchor is field of enclosing team + // see https://bugs.eclipse.org/397878 - [compiler] Using field of enclosing team as team anchor causes illegal bytecode to be created + // variation with public field. + public void test1615_assigningExternalizedCreation3() { + runConformTest( + new String[] { + "Team1615aec3.java", + "\n" + + "public team class Team1615aec3 {\n" + + " public final Team1615aec3 t;" + + " Team1615aec3(Team1615aec3 other) { t = other; }\n" + + " public class R {" + + " protected void test() {" + + " t.test(new R<@t>());\n" + // verify error was observed here + " }\n" + + " protected void print() { System.out.print(\"OK\"); }\n" + + " }\n" + + " public void test(R r) {" + + " r.print();\n" + + " }\n" + + " public static void main(String[] args) {\n" + + " new Team1615aec3(new Team1615aec3(null)).new R().test();\n" + + " }\n" + + "}\n" + }, + "OK"); + } + // a role is casted to its externalized type // 1.6.16-otjld-casting-to-externalized-1 public void test1616_castingToExternalized1() { |