예제 #1
0
  public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {
    if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) == 0) {
      // need assertion flag: $assertionsDisabled on outer most source clas
      // (in case of static member of interface, will use the outermost static member - bug 22334)
      SourceTypeBinding outerMostClass = currentScope.enclosingSourceType();
      while (outerMostClass.isLocalType()) {
        ReferenceBinding enclosing = outerMostClass.enclosingType();
        if (enclosing == null || enclosing.isInterface()) break;
        outerMostClass = (SourceTypeBinding) enclosing;
      }
      this.assertionSyntheticFieldBinding = outerMostClass.addSyntheticFieldForAssert(currentScope);

      // find <clinit> and enable assertion support
      TypeDeclaration typeDeclaration = outerMostClass.scope.referenceType();
      AbstractMethodDeclaration[] methods = typeDeclaration.methods;
      for (int i = 0, max = methods.length; i < max; i++) {
        AbstractMethodDeclaration method = methods[i];
        if (method.isClinit()) {
          ((Clinit) method)
              .setAssertionSupport(
                  this.assertionSyntheticFieldBinding,
                  currentScope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_5);
          break;
        }
      }
    }
  }
 /**
  * Returns <code>true</code> if this is a local type, or if this type is nested inside of any
  * local type.
  */
 private static boolean isLocalType(ClassFile classFile) {
   SourceTypeBinding b = classFile.referenceBinding;
   while (!b.isStatic()) {
     if (b instanceof LocalTypeBinding) {
       return true;
     }
     b = ((NestedTypeBinding) b).enclosingType;
   }
   return false;
 }
예제 #3
0
  public FlowInfo analyseCode(BlockScope currentScope, FlowContext flowContext, FlowInfo flowInfo) {

    // {ObjectTeams: role class literal?
    if (this.roleClassLiteralAccess != null)
      return this.roleClassLiteralAccess.analyseCode(currentScope, flowContext, flowInfo);
    // SH}
    // if reachable, request the addition of a synthetic field for caching the class descriptor
    SourceTypeBinding sourceType = currentScope.outerMostClassScope().enclosingSourceType();
    // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=22334
    if (!sourceType.isInterface()
        && !this.targetType.isBaseType()
        && currentScope.compilerOptions().targetJDK < ClassFileConstants.JDK1_5) {
      this.syntheticField =
          sourceType.addSyntheticFieldForClassLiteral(this.targetType, currentScope);
    }
    return flowInfo;
  }
  /*
   * No need to emulate access to protected fields since not implicitly accessed
   */
  public void manageSyntheticAccessIfNecessary(
      BlockScope currentScope, FlowInfo flowInfo, boolean isReadAccess) {
    if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;

    // if field from parameterized type got found, use the original field at codegen time
    FieldBinding codegenBinding = this.binding.original();
    if (this.binding.isPrivate()) {
      if ((currentScope.enclosingSourceType() != codegenBinding.declaringClass)
          && this.binding.constant() == Constant.NotAConstant) {
        if (this.syntheticAccessors == null) this.syntheticAccessors = new MethodBinding[2];
        this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] =
            ((SourceTypeBinding) codegenBinding.declaringClass)
                .addSyntheticMethod(
                    codegenBinding, isReadAccess, false /* not super ref in remote type*/);
        currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess);
        return;
      }
    } else if (this.receiver instanceof QualifiedSuperReference) { // qualified super
      // qualified super need emulation always
      SourceTypeBinding destinationType =
          (SourceTypeBinding) (((QualifiedSuperReference) this.receiver).currentCompatibleType);
      if (this.syntheticAccessors == null) this.syntheticAccessors = new MethodBinding[2];
      this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] =
          destinationType.addSyntheticMethod(codegenBinding, isReadAccess, isSuperAccess());
      currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess);
      return;

    } else if (this.binding.isProtected()) {
      SourceTypeBinding enclosingSourceType;
      if (((this.bits & ASTNode.DepthMASK) != 0)
          && this.binding.declaringClass.getPackage()
              != (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()) {

        SourceTypeBinding currentCompatibleType =
            (SourceTypeBinding)
                enclosingSourceType.enclosingTypeAt(
                    (this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
        if (this.syntheticAccessors == null) this.syntheticAccessors = new MethodBinding[2];
        this.syntheticAccessors[isReadAccess ? FieldReference.READ : FieldReference.WRITE] =
            currentCompatibleType.addSyntheticMethod(codegenBinding, isReadAccess, isSuperAccess());
        currentScope.problemReporter().needToEmulateFieldAccess(codegenBinding, this, isReadAccess);
        return;
      }
    }
  }
예제 #5
0
  public void manageSyntheticAccessIfNecessary(BlockScope currentScope, FlowInfo flowInfo) {

    if ((flowInfo.tagBits & FlowInfo.UNREACHABLE_OR_DEAD) != 0) return;

    // if method from parameterized type got found, use the original method at codegen time
    MethodBinding codegenBinding = this.binding.original();
    if (this.binding.isPrivate()) {

      // depth is set for both implicit and explicit access (see MethodBinding#canBeSeenBy)
      if (currentScope.enclosingSourceType() != codegenBinding.declaringClass) {
        this.syntheticAccessor =
            ((SourceTypeBinding) codegenBinding.declaringClass)
                .addSyntheticMethod(codegenBinding, false /* not super access there */);
        currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
        return;
      }

    } else if (this.receiver instanceof QualifiedSuperReference) { // qualified super

      // qualified super need emulation always
      SourceTypeBinding destinationType =
          (SourceTypeBinding) (((QualifiedSuperReference) this.receiver).currentCompatibleType);
      this.syntheticAccessor = destinationType.addSyntheticMethod(codegenBinding, isSuperAccess());
      currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
      return;

    } else if (this.binding.isProtected()) {

      SourceTypeBinding enclosingSourceType;
      if (((this.bits & ASTNode.DepthMASK) != 0)
          && codegenBinding.declaringClass.getPackage()
              != (enclosingSourceType = currentScope.enclosingSourceType()).getPackage()) {

        SourceTypeBinding currentCompatibleType =
            (SourceTypeBinding)
                enclosingSourceType.enclosingTypeAt(
                    (this.bits & ASTNode.DepthMASK) >> ASTNode.DepthSHIFT);
        this.syntheticAccessor =
            currentCompatibleType.addSyntheticMethod(codegenBinding, isSuperAccess());
        currentScope.problemReporter().needToEmulateMethodAccess(codegenBinding, this);
        return;
      }
    }
  }
 public void resolve(MethodScope var1) {
   if ((this.field_446 & 16) == 0) {
     if (this.binding != null && this.binding.isValidBinding()) {
       this.field_446 |= 16;
       ClassScope var2 = var1.method_582();
       if (var2 != null) {
         label338:
         {
           SourceTypeBinding var3 = var2.enclosingSourceType();
           if (var3.superclass != null) {
             FieldBinding var4 = var2.findField(var3.superclass, this.name, this, false);
             if (var4 != null && var4.isValidBinding()) {
               label334:
               {
                 if (var4 instanceof FieldBinding) {
                   FieldBinding var5 = (FieldBinding) var4;
                   if (var5.original() == this.binding || !var5.canBeSeenBy(var3, this, var1)) {
                     break label334;
                   }
                 }
                 var1.problemReporter().fieldHiding(this, var4);
                 break label338;
               }
             }
           }
           Scope var13 = var2.parent;
           if (var13.kind != 4) {
             Binding var15 = var13.getBinding(this.name, 3, this, false);
             if (var15 != null && var15.isValidBinding() && var15 != this.binding) {
               label323:
               {
                 if (var15 instanceof FieldBinding) {
                   FieldBinding var6 = (FieldBinding) var15;
                   if (var6.original() == this.binding
                       || !var6.method_431() && var3.method_226()) {
                     break label323;
                   }
                 }
                 var1.problemReporter().fieldHiding(this, var15);
               }
             }
           }
         }
       }
       if (this.type != null) {
         this.type.resolvedType = this.binding.type;
       }
       FieldBinding var12 = var1.initializedField;
       int var14 = var1.field_407;
       try {
         var1.initializedField = this.binding;
         var1.field_407 = this.binding.field_304;
         method_761(var1, this.annotations, this.binding);
         if ((this.binding.getAnnotationTagBits() & 70368744177664L) == 0L
             && (this.binding.field_300 & 1048576) != 0
             && var1.compilerOptions().field_1928 >= 3211264L) {
           var1.problemReporter().method_1675(this);
         }
         if (this.initialization == null) {
           this.binding.setConstant(Constant.NotAConstant);
         } else {
           this.binding.setConstant(Constant.NotAConstant);
           TypeBinding var17 = this.binding.type;
           this.initialization.setExpectedType(var17);
           TypeBinding var18;
           if (this.initialization instanceof ArrayInitializer) {
             if ((var18 = this.initialization.resolveTypeExpecting(var1, var17)) != null) {
               ((ArrayInitializer) this.initialization).binding = (ArrayBinding) var18;
               this.initialization.computeConversion(var1, var17, var18);
             }
           } else if ((var18 = this.initialization.resolveType(var1)) != null) {
             if (var17 != var18) {
               var1.compilationUnitScope().recordTypeConversion(var17, var18);
             }
             if (!this.initialization.isConstantValueOfTypeAssignableToType(var18, var17)
                 && (!var17.method_148() || !BaseTypeBinding.method_185(var17.id, var18.id))
                 && !var18.isCompatibleWith(var17)) {
               if (!var1.isBoxingCompatibleWith(var18, var17)
                   && (!var18.method_148()
                       || var1.compilerOptions().field_1928 < 3211264L
                       || var17.method_148()
                       || !this.initialization.isConstantValueOfTypeAssignableToType(
                           var18, var1.environment().method_486(var17)))) {
                 if ((var17.tagBits & 128L) == 0L) {
                   var1.problemReporter()
                       .typeMismatchError(var18, var17, this.initialization, (ASTNode) null);
                 }
               } else {
                 this.initialization.computeConversion(var1, var17, var18);
                 if (this.initialization instanceof CastExpression
                     && (this.initialization.field_446 & 16384) == 0) {
                   CastExpression.checkNeedForAssignedCast(
                       var1, var17, (CastExpression) this.initialization);
                 }
               }
             } else {
               this.initialization.computeConversion(var1, var17, var18);
               if (var18.method_174(var17)) {
                 var1.problemReporter().method_1806(this.initialization, var18, var17);
               }
               if (this.initialization instanceof CastExpression
                   && (this.initialization.field_446 & 16384) == 0) {
                 CastExpression.checkNeedForAssignedCast(
                     var1, var17, (CastExpression) this.initialization);
               }
             }
             if (this.binding.method_409()) {
               this.binding.setConstant(
                   this.initialization.constant.castTo(
                       (this.binding.type.id << 4) + this.initialization.constant.typeID()));
             }
           } else {
             this.binding.setConstant(Constant.NotAConstant);
           }
           if (this.binding == Assignment.method_944(this.initialization)) {
             var1.problemReporter().assignmentHasNoEffect(this, this.name);
           }
         }
         if (this.binding != null
             && this.binding.declaringClass != null
             && !this.binding.declaringClass.method_158()) {
           int var16 = this.binding.field_300 & 7;
           ProblemReporter var19 = var1.problemReporter();
           int var7 = var19.computeSeverity(-1610612250);
           if (var7 != -1) {
             if (var2 != null) {
               var16 = Util.computeOuterMostVisibility(var2.referenceType(), var16);
             }
             int var8 = this.binding.field_300 & -8 | var16;
           }
         }
       } finally {
         var1.initializedField = var12;
         var1.field_407 = var14;
         if (this.binding.constant() == null) {
           this.binding.setConstant(Constant.NotAConstant);
         }
       }
     }
   }
 }
  private void searchVisibleVariablesAndMethods(
      Scope scope,
      ObjectVector localsFound,
      ObjectVector fieldsFound,
      ObjectVector methodsFound,
      boolean notInJavadoc) {

    InvocationSite invocationSite = CompletionEngine.FakeInvocationSite;

    boolean staticsOnly = false;
    // need to know if we're in a static context (or inside a constructor)

    Scope currentScope = scope;

    done1:
    while (true) { // done when a COMPILATION_UNIT_SCOPE is found

      switch (currentScope.kind) {
        case Scope.METHOD_SCOPE:
          // handle the error case inside an explicit constructor call (see MethodScope>>findField)
          MethodScope methodScope = (MethodScope) currentScope;
          staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
          // $FALL-THROUGH$
        case Scope.BLOCK_SCOPE:
          BlockScope blockScope = (BlockScope) currentScope;

          next:
          for (int i = 0, length = blockScope.locals.length; i < length; i++) {
            LocalVariableBinding local = blockScope.locals[i];

            if (local == null) break next;

            if (local.isSecret()) continue next;
            // If the local variable declaration's initialization statement itself has the
            // completion,
            // then don't propose the local variable
            if (local.declaration.initialization != null) {
              /*(use this if-else block if it is found that local.declaration.initialization != null is not sufficient to
                guarantee that proposal is being asked inside a local variable declaration's initializer)
               if(local.declaration.initialization.sourceEnd > 0) {
              	if (this.assistNode.sourceEnd <= local.declaration.initialization.sourceEnd
              			&& this.assistNode.sourceStart >= local.declaration.initialization.sourceStart) {
              		continue next;
              	}
              } else {
              	CompletionNodeDetector detector = new CompletionNodeDetector(
              			this.assistNode,
              			local.declaration.initialization);
              	if (detector.containsCompletionNode()) {
              		continue next;
              	}
              }*/
              continue next;
            }
            for (int f = 0; f < localsFound.size; f++) {
              LocalVariableBinding otherLocal = (LocalVariableBinding) localsFound.elementAt(f);
              if (CharOperation.equals(otherLocal.name, local.name, true)) continue next;
            }

            localsFound.add(local);
          }
          break;

        case Scope.COMPILATION_UNIT_SCOPE:
          break done1;
      }
      currentScope = currentScope.parent;
    }

    staticsOnly = false;
    currentScope = scope;

    done2:
    while (true) { // done when a COMPILATION_UNIT_SCOPE is found

      switch (currentScope.kind) {
        case Scope.METHOD_SCOPE:
          // handle the error case inside an explicit constructor call (see MethodScope>>findField)
          MethodScope methodScope = (MethodScope) currentScope;
          staticsOnly |= methodScope.isStatic | methodScope.isConstructorCall;
          break;
        case Scope.CLASS_SCOPE:
          ClassScope classScope = (ClassScope) currentScope;
          SourceTypeBinding enclosingType = classScope.referenceContext.binding;

          searchVisibleFields(
              enclosingType,
              classScope,
              invocationSite,
              scope,
              staticsOnly,
              notInJavadoc,
              localsFound,
              fieldsFound);

          searchVisibleMethods(
              enclosingType,
              classScope,
              invocationSite,
              scope,
              staticsOnly,
              notInJavadoc,
              methodsFound);

          staticsOnly |= enclosingType.isStatic();
          break;

        case Scope.COMPILATION_UNIT_SCOPE:
          break done2;
      }
      currentScope = currentScope.parent;
    }

    // search in static import
    ImportBinding[] importBindings = scope.compilationUnitScope().imports;
    for (int i = 0; i < importBindings.length; i++) {
      ImportBinding importBinding = importBindings[i];
      if (importBinding.isValidBinding() && importBinding.isStatic()) {
        Binding binding = importBinding.resolvedImport;
        if (binding != null && binding.isValidBinding()) {
          if (importBinding.onDemand) {
            if ((binding.kind() & Binding.TYPE) != 0) {
              searchVisibleFields(
                  (ReferenceBinding) binding,
                  scope,
                  invocationSite,
                  scope,
                  staticsOnly,
                  notInJavadoc,
                  localsFound,
                  fieldsFound);

              searchVisibleMethods(
                  (ReferenceBinding) binding,
                  scope,
                  invocationSite,
                  scope,
                  staticsOnly,
                  notInJavadoc,
                  methodsFound);
            }
          } else {
            if ((binding.kind() & Binding.FIELD) != 0) {
              searchVisibleFields(
                  new FieldBinding[] {(FieldBinding) binding},
                  ((FieldBinding) binding).declaringClass,
                  scope,
                  invocationSite,
                  scope,
                  staticsOnly,
                  localsFound,
                  fieldsFound);
            } else if ((binding.kind() & Binding.METHOD) != 0) {
              MethodBinding methodBinding = (MethodBinding) binding;

              searchVisibleLocalMethods(
                  methodBinding.declaringClass.getMethods(methodBinding.selector),
                  methodBinding.declaringClass,
                  scope,
                  invocationSite,
                  scope,
                  true,
                  methodsFound);
            }
          }
        }
      }
    }
  }
예제 #8
0
  public TypeBinding resolveType(BlockScope scope) {

    this.constant = Constant.NotAConstant;
    if ((this.targetType = this.type.resolveType(scope, true /* check bounds*/)) == null)
      return null;

    /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=320463
      https://bugs.eclipse.org/bugs/show_bug.cgi?id=312076
      JLS3 15.8.2 forbids the type named in the class literal expression from being a parameterized type.
      And the grammar in 18.1 disallows (where X and Y are some concrete types) constructs of the form
      Outer<X>.class, Outer<X>.Inner.class, Outer.Inner<X>.class, Outer<X>.Inner<Y>.class etc.
      Corollary wise, we should resolve the type of the class literal expression to be a raw type as
      class literals exist only for the raw underlying type.
    */
    LookupEnvironment environment = scope.environment();
    this.targetType =
        environment.convertToRawType(
            this.targetType, true /* force conversion of enclosing types*/);

    if (this.targetType.isArrayType()) {
      ArrayBinding arrayBinding = (ArrayBinding) this.targetType;
      TypeBinding leafComponentType = arrayBinding.leafComponentType;
      if (leafComponentType == TypeBinding.VOID) {
        scope.problemReporter().cannotAllocateVoidArray(this);
        return null;
      } else if (leafComponentType.isTypeVariable()) {
        scope
            .problemReporter()
            .illegalClassLiteralForTypeVariable((TypeVariableBinding) leafComponentType, this);
      }
    } else if (this.targetType.isTypeVariable()) {
      scope
          .problemReporter()
          .illegalClassLiteralForTypeVariable((TypeVariableBinding) this.targetType, this);
    }
    // {ObjectTeams: do we need a RoleClassLiteralAccess?
    if (this.targetType instanceof ReferenceBinding) {
      ReferenceBinding targetRef = (ReferenceBinding) this.targetType;
      if (targetRef.isRole()) {
        if (this.verbatim) {
          this.targetType =
              RoleTypeCreator.maybeWrapUnqualifiedRoleType(scope, this.targetType, this);
        } else {
          SourceTypeBinding site = scope.enclosingSourceType();
          if (scope.methodScope().isStatic // role class literal needs team instance
              && !site.isRole() // static role method are OK.
              && !RoleTypeBinding.isRoleWithExplicitAnchor(this.targetType)) // t.R.class?
          {
            scope.problemReporter().roleClassLiteralLacksTeamInstance(this, targetRef);
            return null;
          }
          ReferenceBinding teamBinding;
          if (RoleTypeBinding.isRoleWithExplicitAnchor(targetRef))
            teamBinding = targetRef.enclosingType();
          else teamBinding = TeamModel.findEnclosingTeamContainingRole(site, targetRef);
          if (teamBinding == null)
            scope.problemReporter().externalizedRoleClassLiteral(this, targetRef);
          else {
            TypeBinding methodType =
                RoleClassLiteralAccess.ensureGetClassMethod(
                    teamBinding.getTeamModel(),
                    targetRef.roleModel); // not affected by visibility check (for resilience)
            this.roleClassLiteralAccess = new RoleClassLiteralAccess(this, methodType);
            this.resolvedType = this.roleClassLiteralAccess.resolveType(scope);
          }
          return this.resolvedType;
        }
      }
    }
    // SH}
    ReferenceBinding classType = scope.getJavaLangClass();
    // https://bugs.eclipse.org/bugs/show_bug.cgi?id=328689
    if (scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5) {
      // Integer.class --> Class<Integer>, perform boxing of base types (int.class -->
      // Class<Integer>)
      TypeBinding boxedType = null;
      if (this.targetType.id == T_void) {
        boxedType = environment.getResolvedType(JAVA_LANG_VOID, scope);
      } else {
        boxedType = scope.boxing(this.targetType);
      }
      if (environment.usesNullTypeAnnotations())
        boxedType =
            environment.createAnnotatedType(
                boxedType, new AnnotationBinding[] {environment.getNonNullAnnotation()});
      this.resolvedType =
          environment.createParameterizedType(
              classType, new TypeBinding[] {boxedType}, null /*not a member*/);
    } else {
      this.resolvedType = classType;
    }
    return this.resolvedType;
  }
  private boolean recordTypedefs(TypeDeclaration declaration) {
    SourceTypeBinding binding = declaration.binding;
    if (binding == null) {
      return false;
    }
    Annotation[] annotations = declaration.annotations;
    if (annotations != null) {
      if (declaration.binding.isAnnotationType()) {
        for (Annotation annotation : annotations) {
          String typeName = Extractor.getFqn(annotation);
          if (typeName == null) {
            continue;
          }

          if (Extractor.isNestedAnnotation(typeName)) {
            String fqn = new String(binding.readableName());

            List<Annotation> list = mMap.get(fqn);
            if (list == null) {
              list = new ArrayList<Annotation>(2);
              mMap.put(fqn, list);
            }
            list.add(annotation);

            if (mRequireHide) {
              Javadoc javadoc = declaration.javadoc;
              if (javadoc != null) {
                StringBuffer stringBuffer = new StringBuffer(200);
                javadoc.print(0, stringBuffer);
                String documentation = stringBuffer.toString();
                if (!documentation.contains("@hide")) {
                  Extractor.warning(
                      getFileName()
                          + ": The typedef annotation "
                          + fqn
                          + " should specify @hide in a doc comment");
                }
              }
            }
            if (mRequireSourceRetention && !Extractor.hasSourceRetention(annotations)) {
              Extractor.warning(
                  getFileName()
                      + ": The typedef annotation "
                      + fqn
                      + " should have @Retention(RetentionPolicy.SOURCE)");
            }
            if (declaration.binding != null
                && (declaration.modifiers & ClassFileConstants.AccPublic) == 0) {
              StringBuilder sb = new StringBuilder(100);
              for (char c : declaration.binding.qualifiedPackageName()) {
                if (c == '.') {
                  sb.append('/');
                } else {
                  sb.append(c);
                }
              }
              sb.append(File.separatorChar);
              for (char c : declaration.binding.qualifiedSourceName()) {
                if (c == '.') {
                  sb.append('$');
                } else {
                  sb.append(c);
                }
              }
              mTypedefClasses.add(sb.toString());
            }
          }
        }
      }
    }
    return true;
  }