private TypeBinding getTypeFromSignature(String typeSignature, Scope scope) {
    TypeBinding assignableTypeBinding = null;

    TypeVariableBinding[] typeVariables = Binding.NO_TYPE_VARIABLES;
    ReferenceContext referenceContext = scope.referenceContext();
    if (referenceContext instanceof AbstractMethodDeclaration) {
      AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) referenceContext;
      TypeParameter[] typeParameters = methodDeclaration.typeParameters();
      if (typeParameters != null && typeParameters.length > 0) {
        int length = typeParameters.length;
        int count = 0;
        typeVariables = new TypeVariableBinding[length];
        for (int i = 0; i < length; i++) {
          if (typeParameters[i].binding != null) {
            typeVariables[count++] = typeParameters[i].binding;
          }
        }

        if (count != length) {
          System.arraycopy(
              typeVariables, 0, typeVariables = new TypeVariableBinding[count], 0, count);
        }
      }
    }

    CompilationUnitDeclaration previousUnitBeingCompleted =
        this.lookupEnvironment.unitBeingCompleted;
    this.lookupEnvironment.unitBeingCompleted = this.compilationUnitDeclaration;
    // {ObjectTeams: protect call into the compiler
    /* orig:
    try {
    :giro */
    try (Config config =
        Dependencies.setup(this, this.parser, this.lookupEnvironment, true, true)) {
      // orig:

      SignatureWrapper wrapper =
          new SignatureWrapper(replacePackagesDot(typeSignature.toCharArray()));
      // FIXME(stephan): do we interpret type annotations here?
      assignableTypeBinding =
          this.lookupEnvironment.getTypeFromTypeSignature(
              wrapper,
              typeVariables,
              this.assistScope.enclosingClassScope().referenceContext.binding,
              null,
              ITypeAnnotationWalker.EMPTY_ANNOTATION_WALKER);
      assignableTypeBinding =
          BinaryTypeBinding.resolveType(assignableTypeBinding, this.lookupEnvironment, true);
    } catch (AbortCompilation e) {
      assignableTypeBinding = null;
    } finally {
      this.lookupEnvironment.unitBeingCompleted = previousUnitBeingCompleted;
    }
    return assignableTypeBinding;
  }
 public boolean canUseDiamond(String[] parameterTypes, char[] fullyQualifiedTypeName) {
   TypeBinding guessedType = null;
   char[][] cn = CharOperation.splitOn('.', fullyQualifiedTypeName);
   Scope scope = this.assistScope;
   if (scope.compilerOptions().sourceLevel < ClassFileConstants.JDK1_7) return false;
   // If no LHS or return type expected, then we can safely use diamond
   char[][] expectedTypekeys = this.completionContext.getExpectedTypesKeys();
   if (expectedTypekeys == null || expectedTypekeys.length == 0) return true;
   // Next, find out whether any of the constructor parameters are the same as one of the
   // class type variables. If yes, diamond cannot be used.
   TypeReference ref;
   if (cn.length == 1) {
     ref = new SingleTypeReference(cn[0], 0);
   } else {
     ref = new QualifiedTypeReference(cn, new long[cn.length]);
   }
   // {ObjectTeams: protect call into the compiler
   try (Config config =
       Dependencies.setup(this, this.parser, this.lookupEnvironment, true, true)) {
     // orig:
     switch (scope.kind) {
       case Scope.METHOD_SCOPE:
       case Scope.BLOCK_SCOPE:
         guessedType = ref.resolveType((BlockScope) scope);
         break;
       case Scope.CLASS_SCOPE:
         guessedType = ref.resolveType((ClassScope) scope);
         break;
     }
     // :giro
   }
   // SH}
   if (guessedType != null && guessedType.isValidBinding()) {
     // the erasure must be used because guessedType can be a RawTypeBinding
     guessedType = guessedType.erasure();
     TypeVariableBinding[] typeVars = guessedType.typeVariables();
     for (int i = 0; i < parameterTypes.length; i++) {
       for (int j = 0; j < typeVars.length; j++) {
         if (CharOperation.equals(parameterTypes[i].toCharArray(), typeVars[j].sourceName))
           return false;
       }
     }
     return true;
   }
   return false;
 }
  public IJavaElement[] getVisibleElements(String typeSignature) {
    // {ObjectTeams: might call into the compiler (e.g., isCompatibleWith), so give at least minimal
    // protection:
    try (Config config =
        Dependencies.setup(this, this.parser, this.lookupEnvironment, true, true)) {
      // SH}
      if (this.assistScope == null) return new IJavaElement[0];

      if (!this.hasComputedVisibleElementBindings) {
        computeVisibleElementBindings();
      }

      TypeBinding assignableTypeBinding = null;
      if (typeSignature != null) {
        assignableTypeBinding = getTypeFromSignature(typeSignature, this.assistScope);
        if (assignableTypeBinding == null) return new IJavaElement[0];
      }

      int length =
          this.visibleLocalVariables.size()
              + this.visibleFields.size()
              + this.visibleMethods.size();
      if (length == 0) return new IJavaElement[0];

      IJavaElement[] result = new IJavaElement[length];

      int elementCount = 0;

      int size = this.visibleLocalVariables.size();
      if (size > 0) {
        next:
        for (int i = 0; i < size; i++) {
          try {
            LocalVariableBinding binding =
                (LocalVariableBinding) this.visibleLocalVariables.elementAt(i);
            if (binding.type == null
                || (assignableTypeBinding != null
                    && !binding.type.isCompatibleWith(assignableTypeBinding))) continue next;
            JavaElement localVariable = getJavaElement(binding);
            if (localVariable != null) result[elementCount++] = localVariable;
          } catch (AbortCompilation e) {
            // log the exception and proceed
            Util.logRepeatedMessage(e.getKey(), e);
          }
        }
      }
      size = this.visibleFields.size();
      if (size > 0) {
        next:
        for (int i = 0; i < size; i++) {
          try {
            FieldBinding binding = (FieldBinding) this.visibleFields.elementAt(i);
            if (assignableTypeBinding != null
                && !binding.type.isCompatibleWith(assignableTypeBinding)) continue next;
            if (this.assistScope.isDefinedInSameUnit(binding.declaringClass)) {
              JavaElement field = getJavaElementOfCompilationUnit(binding);
              if (field != null) result[elementCount++] = field;
            } else {
              JavaElement field = Util.getUnresolvedJavaElement(binding, this.owner, EmptyNodeMap);
              if (field != null) result[elementCount++] = field.resolved(binding);
            }
          } catch (AbortCompilation e) {
            // log the exception and proceed
            Util.logRepeatedMessage(e.getKey(), e);
          }
        }
      }
      size = this.visibleMethods.size();
      if (size > 0) {
        next:
        for (int i = 0; i < size; i++) {
          try {
            MethodBinding binding = (MethodBinding) this.visibleMethods.elementAt(i);
            if (assignableTypeBinding != null
                && !binding.returnType.isCompatibleWith(assignableTypeBinding)) continue next;
            if (this.assistScope.isDefinedInSameUnit(binding.declaringClass)) {
              JavaElement method = getJavaElementOfCompilationUnit(binding);
              if (method != null) result[elementCount++] = method;
            } else {
              JavaElement method = Util.getUnresolvedJavaElement(binding, this.owner, EmptyNodeMap);
              if (method != null) result[elementCount++] = method.resolved(binding);
            }
          } catch (AbortCompilation e) {
            // log the exception and proceed
            Util.logRepeatedMessage(e.getKey(), e);
          }
        }
      }

      if (elementCount != result.length) {
        System.arraycopy(result, 0, result = new IJavaElement[elementCount], 0, elementCount);
      }

      return result;
      // {ObjectTeams: cleanup:
    }
    // SH}
  }