コード例 #1
0
ファイル: JsniReferenceResolver.java プロジェクト: qffan/gwt
 private static void resolveJsniRef(JsniRef jsniRef, FieldBinding fieldBinding) {
   if (fieldBinding == null) {
     return;
   }
   jsniRef.setResolvedClassName(JdtUtil.getSourceName(fieldBinding.declaringClass));
   jsniRef.setResolvedMemberWithSignature(new String(fieldBinding.name));
 }
コード例 #2
0
ファイル: JsniReferenceResolver.java プロジェクト: qffan/gwt
  private static void resolveJsniRef(JsniRef jsniRef, MethodBinding methodBinding) {
    if (methodBinding == null) {
      return;
    }
    ReferenceBinding declaringClassBinding = methodBinding.declaringClass;

    jsniRef.setResolvedClassName(JdtUtil.getSourceName(declaringClassBinding));
    jsniRef.setResolvedMemberWithSignature(JdtUtil.formatMethodSignature(methodBinding));
  }
コード例 #3
0
ファイル: JsniReferenceResolver.java プロジェクト: qffan/gwt
    private Binding resolveReference(
        SourceInfo errorInfo, JsniRef jsniRef, boolean hasQualifier, boolean isLvalue) {

      resolveClassReference(jsniRef);
      String className = jsniRef.getResolvedClassName();

      boolean isPrimitive;
      ReferenceBinding clazz;
      TypeBinding binding = method.scope.getBaseType(className.toCharArray());
      if (binding != null) {
        isPrimitive = true;
        clazz = null;
      } else {
        isPrimitive = false;
        binding = clazz = findClass(className);
      }

      if (binding != null && binding.isAnonymousType()) {
        // There seems that there is no way to write a JSNI reference to an anonymous class as
        // it will require to accept a source name of the form A.1 where one of the identifier parts
        // consists only of digits and therefore is not a valid identifier.
        // This error case is left here in case names of that form start appearing from the JSNI
        // parser.
        emitError(ERR_ILLEGAL_ANONYMOUS_INNER_CLASS, errorInfo, jsniRef);
        return null;
      } else if (binding == null) {
        emitError(ERR_UNABLE_TO_RESOLVE_CLASS, errorInfo, jsniRef);
        return null;
      }

      if (clazz != null
          && clazz.isDeprecated()
          && !isEnclosingClass(method.binding.declaringClass, clazz)) {
        emitWarning("deprecation", WARN_DEPRECATED_CLASS, errorInfo, jsniRef);
      }

      if (jsniRef.isField() && "class".equals(jsniRef.memberName())) {
        if (isLvalue) {
          emitError(ERR_ILLEGAL_ASSIGNMENT_TO_CLASS_LITERAL, errorInfo, jsniRef);
          return null;
        }
        // Reference to the class itself.
        jsniRef.setResolvedClassName(JdtUtil.getSourceName(binding));
        jsniRef.setResolvedMemberWithSignature(jsniRef.memberSignature());
        if (jsniRef.isArray()) {
          ArrayBinding arrayBinding =
              method.scope.createArrayType(binding, jsniRef.getDimensions());
          return arrayBinding;
        } else {
          return binding;
        }
      }

      if (jsniRef.isArray() || isPrimitive) {
        emitError(ERR_ILLEGAL_ARRAY_OR_PRIMITIVE_REFERENCE, errorInfo, jsniRef);
        return null;
      }

      assert clazz != null;
      if (jsniRef.isMethod()) {
        return checkAndResolveMethodRef(errorInfo, clazz, jsniRef, hasQualifier, isLvalue);
      } else {
        return checkAndResolveFieldRef(errorInfo, clazz, jsniRef, hasQualifier, isLvalue);
      }
    }
コード例 #4
0
ファイル: JsniReferenceResolver.java プロジェクト: qffan/gwt
    private void resolveClassReference(JsniRef jsniRef) {
      // Precedence rules as of JLS 6.4.1.
      // 1. Enclosing type.
      // 2. Visible type in same compilation unit.
      // 3. Named import.
      // 4. Same package.
      // 5. Import on demand.

      String originalName = jsniRef.className();
      String importedClassName = originalName;
      if (importedClassName.contains(".")) {
        // Only retain up the first dot to support innerclasses. E.g. import c.g.A and reference
        // @A.I::f.
        importedClassName = importedClassName.substring(0, importedClassName.indexOf("."));
      }

      // 1 & 2. Check to see if this name refers to the enclosing class or is directly accessible
      // from it.
      ReferenceBinding declaringClass = method.binding.declaringClass;
      while (declaringClass != null) {
        String declaringClassName = JdtUtil.getSourceName(declaringClass);
        if (declaringClassName.equals(importedClassName)
            || declaringClassName.endsWith("." + importedClassName)) {
          // Referring to declaring class name using unqualified name.
          jsniRef.setResolvedClassName(
              declaringClassName + originalName.substring(importedClassName.length()));
          return;
        }
        String fullClassName =
            JdtUtil.getBinaryName(declaringClass) + "$" + originalName.replace('.', '$');
        if (typeResolver.resolveType(fullClassName) != null) {
          jsniRef.setResolvedClassName(JdtUtil.getSourceName(declaringClass) + "." + originalName);
          return;
        }
        declaringClass = declaringClass.enclosingTypeAt(1);
      }

      // 3. Check to see if this name is one of the named imports.
      for (ImportReference importReference : cudImports) {
        String nameFromImport = JdtUtil.asDottedString(importReference.getImportName());
        if (!importReference.isStatic()
            && importReference.trailingStarPosition == 0
            && nameFromImport.endsWith("." + importedClassName)) {
          jsniRef.setResolvedClassName(
              nameFromImport + originalName.substring(importedClassName.length()));
          return;
        }
      }

      // 4. Check to see if this name is resolvable from the current package.
      String currentPackageBinaryClassName =
          JdtUtil.getBinaryName(
              CharOperation.charToString(method.binding.declaringClass.qualifiedPackageName()),
              originalName);

      if (typeResolver.resolveType(currentPackageBinaryClassName) != null) {
        jsniRef.setResolvedClassName(
            JdtUtil.getSourceName(
                CharOperation.charToString(method.binding.declaringClass.qualifiedPackageName()),
                originalName));
        return;
      }

      // 5. Check to see if this name is resolvable as an import on demand.
      List<String> importPackages = Lists.newArrayList("java.lang");
      for (ImportReference importReference : cudImports) {
        if (importReference.isStatic() || importReference.trailingStarPosition == 0) {
          continue;
        }
        importPackages.add(JdtUtil.asDottedString(importReference.getImportName()));
      }
      for (String importPackage : importPackages) {
        String fullClassName = importPackage + "." + originalName.replace('.', '$');
        if (typeResolver.resolveType(fullClassName) != null) {
          jsniRef.setResolvedClassName(importPackage + "." + originalName);
          return;
        }
      }

      // Otherwise leave it as it is.
      // TODO(rluble): Maybe we should leave it null here.
      jsniRef.setResolvedClassName(jsniRef.className());
    }