diff options
Diffstat (limited to 'org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java')
-rw-r--r-- | org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java | 104 |
1 files changed, 47 insertions, 57 deletions
diff --git a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java index d27ed0ec8..9e72b0f8e 100644 --- a/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java +++ b/org.eclipse.jdt.core/compiler/org/eclipse/jdt/internal/compiler/lookup/Scope.java @@ -1,5 +1,5 @@ /******************************************************************************* - * 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 @@ -14,6 +14,10 @@ * bug 186342 - [compiler][null] Using annotations for null checking * bug 387612 - Unreachable catch block...exception is never thrown from the try * bug 395002 - Self bound generic class doesn't resolve bounds properly for wildcards for certain parametrisation. + * bug 401456 - Code compiles from javac/intellij, but fails from eclipse + * bug 401271 - StackOverflowError when searching for a methods references + * Jesper S Moller - Contributions for + * Bug 378674 - "The method can be declared as static" is wrong *******************************************************************************/ package org.eclipse.jdt.internal.compiler.lookup; @@ -416,13 +420,12 @@ public abstract class Scope { /** * Returns a type, where original type was substituted using the receiver * parameterized type. - * In raw mode, all parameterized type denoting same original type are converted - * to raw types. e.g. - * class X <T> { - * X<T> foo; - * X<String> bar; - * } when used in raw fashion, then type of both foo and bar is raw type X. - * + * In raw mode (see {@link Substitution#isRawSubstitution()}), + * all parameterized types are converted to raw types. + * Cf. 4.8: "The type of a constructor (8.8), instance method (8.4, 9.4), + * or non-static field (8.3) M of a raw type C that is not inherited from its + * superclasses or superinterfaces is the raw type that corresponds to the erasure + * of its type in the generic declaration corresponding to C." */ public static TypeBinding substitute(Substitution substitution, TypeBinding originalType) { if (originalType == null) return null; @@ -441,6 +444,9 @@ public abstract class Scope { ReferenceBinding substitutedEnclosing = originalEnclosing; if (originalEnclosing != null) { substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing); + if (isMemberTypeOfRaw(originalType, substitutedEnclosing)) + return originalParameterizedType.environment.createRawType( + originalParameterizedType.genericType(), substitutedEnclosing); } TypeBinding[] originalArguments = originalParameterizedType.arguments; TypeBinding[] substitutedArguments = originalArguments; @@ -511,6 +517,8 @@ public abstract class Scope { substitutedEnclosing = originalEnclosing; if (originalEnclosing != null) { substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing); + if (isMemberTypeOfRaw(originalType, substitutedEnclosing)) + return substitution.environment().createRawType(originalReferenceType, substitutedEnclosing); } // treat as if parameterized with its type variables (non generic type gets 'null' arguments) @@ -526,6 +534,8 @@ public abstract class Scope { substitutedEnclosing = originalEnclosing; if (originalEnclosing != null) { substitutedEnclosing = (ReferenceBinding) substitute(substitution, originalEnclosing); + if (isMemberTypeOfRaw(originalType, substitutedEnclosing)) + return substitution.environment().createRawType(originalReferenceType, substitutedEnclosing); } if (substitution.isRawSubstitution()) { @@ -539,6 +549,19 @@ public abstract class Scope { return originalType; } + private static boolean isMemberTypeOfRaw(TypeBinding originalType, ReferenceBinding substitutedEnclosing) { + // 4.8: + // "a raw type is defined to be one of: + // ... + // * A non-static member type of a raw type R that is not + // inherited from a superclass or superinterface of R." + + // Due to staticness, e.g., Map.Entry<String,Object> is *not* considered as a raw type + + return (substitutedEnclosing != null && substitutedEnclosing.isRawType()) + && ((originalType instanceof ReferenceBinding) && !((ReferenceBinding)originalType).isStatic()); + } + /** * Returns an array of types, where original types got substituted given a substitution. * Only allocate an array if anything is different. @@ -1885,13 +1908,14 @@ public abstract class Scope { ProblemFieldBinding foundInsideProblem = null; // inside Constructor call or inside static context Scope scope = this; + MethodScope methodScope = null; int depth = 0; int foundDepth = 0; ReferenceBinding foundActualReceiverType = null; done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found switch (scope.kind) { case METHOD_SCOPE : - MethodScope methodScope = (MethodScope) scope; + methodScope = (MethodScope) scope; insideStaticContext |= methodScope.isStatic; insideConstructorCall |= methodScope.isConstructorCall; insideTypeAnnotation = methodScope.insideTypeAnnotation; @@ -1956,6 +1980,8 @@ public abstract class Scope { fieldBinding.declaringClass, name, ProblemReasons.NonStaticReferenceInStaticContext); + } else if (methodScope != null) { + methodScope.resetEnclosingMethodStaticFlag(); } } if (receiverType == fieldBinding.declaringClass || compilerOptions().complianceLevel >= ClassFileConstants.JDK1_4) { @@ -2303,6 +2329,7 @@ public abstract class Scope { MethodBinding foundProblem = null; boolean foundProblemVisible = false; Scope scope = this; + MethodScope methodScope = null; int depth = 0; // in 1.4 mode (inherited visible shadows enclosing) CompilerOptions options; @@ -2311,7 +2338,7 @@ public abstract class Scope { done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found switch (scope.kind) { case METHOD_SCOPE : - MethodScope methodScope = (MethodScope) scope; + methodScope = (MethodScope) scope; insideStaticContext |= methodScope.isStatic; insideConstructorCall |= methodScope.isConstructorCall; insideTypeAnnotation = methodScope.insideTypeAnnotation; @@ -2350,6 +2377,8 @@ public abstract class Scope { insideConstructorCall ? ProblemReasons.NonStaticReferenceInConstructorInvocation : ProblemReasons.NonStaticReferenceInStaticContext); + } else if (!methodBinding.isStatic() && methodScope != null) { + methodScope.resetDeclaringClassMethodStaticFlag(receiverType); } if (inheritedHasPrecedence || receiverType == methodBinding.declaringClass @@ -2961,6 +2990,7 @@ public abstract class Scope { private final Binding internalGetTypeOrPackage(char[] name, int mask, boolean needResolve) { // SH} Scope scope = this; + MethodScope methodScope = null; ReferenceBinding foundType = null; boolean insideStaticContext = false; boolean insideTypeAnnotation = false; @@ -2977,7 +3007,7 @@ public abstract class Scope { done : while (true) { // done when a COMPILATION_UNIT_SCOPE is found switch (scope.kind) { case METHOD_SCOPE : - MethodScope methodScope = (MethodScope) scope; + methodScope = (MethodScope) scope; AbstractMethodDeclaration methodDecl = methodScope.referenceMethod(); if (methodDecl != null) { if (methodDecl.binding != null) { @@ -3065,6 +3095,8 @@ public abstract class Scope { if (typeVariable != null) { if (insideStaticContext) // do not consider this type modifiers: access is legite within same type return new ProblemReferenceBinding(new char[][]{name}, typeVariable, ProblemReasons.NonStaticReferenceInStaticContext); + else if (methodScope != null) + methodScope.resetEnclosingMethodStaticFlag(); return typeVariable; } insideStaticContext |= sourceType.isStatic(); @@ -3131,53 +3163,11 @@ public abstract class Scope { } } } - // walk single static imports. A type found here will shadow types with same name in other CU's, or types coming - // from on-demand imports. JLS 7.5.3 + // In this location we had a fix for // https://bugs.eclipse.org/bugs/show_bug.cgi?id=318401 - if (imports != null) { - ReferenceBinding type = null; - nextImport : for (int i = 0, length = imports.length; i < length; i++) { - ImportBinding importBinding = imports[i]; - if (importBinding.isStatic()) { - ReferenceBinding temp = null; - if (CharOperation.equals(importBinding.compoundName[importBinding.compoundName.length - 1], name)) { - Binding resolvedImport = importBinding.resolvedImport; - if (resolvedImport == null) continue nextImport; - if (resolvedImport instanceof MethodBinding || resolvedImport instanceof FieldBinding) { - // check to see if there are also member types with the same name - // must find the importRef's type again since the method/field can be from an inherited type - // see StaticImportTest#test084 for more clarity - char[][] importName = importBinding.reference.tokens; - TypeBinding referencedType = getType(importName, importName.length - 1); - if (referencedType != null && referencedType instanceof ReferenceBinding) { - temp = findMemberType(name, (ReferenceBinding) referencedType); - } - } - if (temp != null && temp.isStatic() && temp != type) { - if (temp.isValidBinding()) { - if (!temp.canBeSeenBy(unitScope.fPackage)) { - // Answer error binding - type is not visible - foundType = new ProblemReferenceBinding(new char[][]{name}, type, ProblemReasons.NotVisible); - } else { - ImportReference importReference = importBinding.reference; - if (importReference != null) { - importReference.bits |= ASTNode.Used; - } - type = temp; - } - } else if (foundType == null) { - foundType = temp; - } - } - } - } - } - if (type != null) { - if (typeOrPackageCache != null) - typeOrPackageCache.put(name, type); - return type; - } - } + // However, as of today (4.3M6 candidate) this fix seems unnecessary, while causing StackOverflowError in + // https://bugs.eclipse.org/bugs/show_bug.cgi?id=401271 + // check if the name is in the current package, skip it if its a sub-package PackageBinding currentPackage = unitScope.fPackage; unitScope.recordReference(currentPackage.compoundName, name); |