1、duplicate declaration checking

/** Check that variable does not hide variable with same name in
     *  immediately enclosing local scope.
     *
     *  e.g
     *  public void m1(boolean a){
     *       int a = 3;
     *       boolean a = true; // 不调用checkTransparentVar()方法,因为调用checkUnique()方法时能测出冲突
     *  }
     *
     *  @param pos           Position for error reporting.
     *  @param v             The symbol.
     *  @param s             The scope.
     */
    void checkTransparentVar(DiagnosticPosition pos, VarSymbol v, Scope s) {
        if (s.next != null) {
            for (Scope.Entry e = s.next.lookup(v.name);
                 e.scope != null && e.sym.owner == v.owner;
                 e = e.next()) {
                if (e.sym.kind == VAR &&
                    (e.sym.owner.kind & (VAR | MTH)) != 0 &&
                    v.name != names.error) {
                    duplicateError(pos, e.sym);
                    return;
                }
            }
        }
    }

e.g

	public void m1(boolean a){
		int a = 3;

		for(int x = 0;x<2;x++){
			int x = 3;
		}
	}

其中int a = 3与int x= 3将调用checkTransparentVar()方法检测出重复声明。

/** Check that a class or interface does not hide a class or
     *  interface with same name in immediately enclosing local scope.
     *  @param pos           Position for error reporting.
     *  @param c             The symbol.
     *  @param s             The scope.
     */
    void checkTransparentClass(DiagnosticPosition pos, ClassSymbol c, Scope s) {
        if (s.next != null) {
            for (Scope.Entry e = s.next.lookup(c.name);
                 e.scope != null && e.sym.owner == c.owner;
                 e = e.next()) {
                if (e.sym.kind == TYP && e.sym.type.tag != TYPEVAR &&
                    (e.sym.owner.kind & (VAR | MTH)) != 0 &&
                    c.name != names.error) {
                    duplicateError(pos, e.sym);
                    return;
                }
            }
        }
    }

e.g

	public void m1() {
		class A{}
		{
			class A{} // err Duplicate nested type A
		}

而对于e.sym.owner.kind为VAR的情况还没有举出例子。  

 /** Check that class does not have the same name as one of
     *  its enclosing classes, or as a class defined in its enclosing scope.
     *  return true if class is unique in its enclosing scope.
     *  @param pos           Position for error reporting.
     *  @param name          The class name.
     *  @param s             The enclosing scope.
     */
    boolean checkUniqueClassName(DiagnosticPosition pos, Name name, Scope s) {
        for (Scope.Entry e = s.lookup(name); e.scope == s; e = e.next()) {
            if (e.sym.kind == TYP && e.sym.name != names.error) {
                duplicateError(pos, e.sym);
                return false;
            }
        }
        for (Symbol sym = s.owner; sym != null; sym = sym.owner) {
            if (sym.kind == TYP && sym.name == name && sym.name != names.error) {
                duplicateError(pos, sym);
                return true;
            }
        }
        return true;
    }

e.g

	{
		class A {}
		interface A{} // A类型的冲突将由checkUniqueClassName()方法来检测
	}
	{
		class B {
			class B {
			}
		}
	}

  

2、Class name generation

 /** Return name of local class.
     *  This is of the form    <enclClass> $ n <classname>
     *  where
     *    enclClass is the flat name of the enclosing class,
     *    classname is the simple name of the local class
     */
    Name localClassName(ClassSymbol c) {
        for (int i=1; ; i++) {
            Name flatname = names.
                fromString("" + c.owner.enclClass().flatname +
                           syntheticNameChar + i +
                           c.name);
            if (compiled.get(flatname) == null)
                return flatname;
        }
    }

e.g

package com.test07;
public class Test3{

	interface I {
	}

	// com.test07.Test3$1
	final I i1 = new I() {

	};

	// com.test07.Test3$2
	final I i2 = new I() {

	};

	{
		// com.test07.Test3$1B
		class B {
		}
	}

	public void m1() {
		// com.test07.Test3$2B
		class B {
		}
		// com.test07.Test3$1C
		class C {
		}
		// com.test07.Test3$3
		final I i3 = new I() {

		};
	}

	public void m2() {
		// com.test07.Test3$3B
		class B {
		}
		// com.test07.Test3$1D
		class D {
		}
	}

}

  

  

3、Type Checking

   /** Check that a given type is assignable to a given proto-type.
     *  If it is, return the type, otherwise return errType.
     *  @param pos        Position to be used for error reporting.
     *  @param found      The type that was found.
     *  @param req        The type that was required.
     */
    Type checkType(DiagnosticPosition pos, Type found, Type req) {
        // 不兼容的类型
        return checkType(pos, found, req, "incompatible.types");
    }

    Type checkType(DiagnosticPosition pos, Type found, Type req, String errKey) {
        if (req.tag == ERROR)
            return req;
        if (found.tag == FORALL)
            return instantiatePoly(pos, (ForAll)found, req, convertWarner(pos, found, req));
        if (req.tag == NONE)
            return found;
        if (types.isAssignable(found, req, convertWarner(pos, found, req)))
            return found;
        if (found.tag <= DOUBLE && req.tag <= DOUBLE)
            // 可能损失精度
            return typeError(pos, diags.fragment("possible.loss.of.precision"), found, req);
        if (found.isSuperBound()) {
            // 从 super-bound 类型{0}进行分配
            log.error(pos, "assignment.from.super-bound", found);
            return types.createErrorType(found);
        }
        if (req.isExtendsBound()) {
            log.error(pos, "assignment.to.extends-bound", req);
            return types.createErrorType(found);
        }
        return typeError(pos, diags.fragment(errKey), found, req);
    }

checkType方法主要是在Attr类中的check()方法调用的,这个方法的代码如下:

 /** Check kind and type of given tree against protokind and prototype.
     *  If check succeeds, store type in tree and return it.
     *  If check fails, store errType in tree and return it.
     *  No checks are performed if the prototype is a method type.
     *  It is not necessary in this case since we know that kind and type
     *  are correct.
     *
     *  @param tree     The tree whose kind and type is checked
     *  @param owntype  The computed type of the tree
     *  @param ownkind  The computed kind of the tree
     *  @param protokind    The expected kind (or: protokind) of the tree
     *  @param prototype       The expected type (or: prototype) of the tree
     */
    Type check(JCTree tree, Type owntype, int ownkind, int protokind, Type prototype) {
    	// prototype不允许为method type
        if (owntype.tag != ERROR && prototype.tag != METHOD && prototype.tag != FORALL) {
            if ((ownkind & ~protokind) == 0) {
                owntype = chk.checkType(tree.pos(), owntype, prototype, errKey);
            } else {
                log.error(tree.pos(), "unexpected.type",kindNames(protokind),kindName(ownkind));
                owntype = types.createErrorType(owntype);
            }
        }
        tree.type = owntype;
        return owntype;
    }

  

owntype与prototype都是Type类型,其tag取值是TypeTags类中的预先定义好的值。

ownkind与protokind都是int类型,其取值是Kinds预先定义好的值。

通过比较如上的两类型值,其实也就是比较了语法节点的Type类型与Symbol类型。

 /** Check that a type is within some bounds.
     *
     *  Used in TypeApply to verify that, e.g., X in V<X> is a valid type argument.
     *  @param pos           Position to be used for error reporting.
     *  @param a             The type that should be bounded by bs.
     *  @param bs            The bound.
     */
    private boolean checkExtends(Type a, Type bound) {
         if (a.isUnbound()) {
             return true;
         } else if (a.tag != WILDCARD) {
             a = types.upperBound(a);
             return types.isSubtype(a, bound);
         } else if (a.isExtendsBound()) {
             Type ut = types.upperBound(a);
             boolean result = types.isCastable(bound, ut , Warner.noWarnings);
             return result;
         } else if (a.isSuperBound()) {
             Type lt = types.lowerBound(a);
             boolean result = !types.notSoftSubtype(lt, bound);
             return result;
         }
         return true;
     }

e.g

class BC<T extends Closeable> {
	public void test() {
		BC<InputStream> a = null;
		BC<? extends InputStream> b = null;
		BC<? super InputStream> c = null;
	}
}

当a.isExtendsBound()时调用了isCastable()方法。

当a.isSuperBound()时调用了notSoftSubtype()方法。

  

  

 

  

Check类之duplicate declaration checking/Class name generation/Type Checking的更多相关文章

  1. 类型检查和鸭子类型 Duck typing in computer programming is an application of the duck test 鸭子测试 鸭子类型 指示编译器将类的类型检查安排在运行时而不是编译时 type checking can be specified to occur at run time rather than compile time.

    Go所提供的面向对象功能十分简洁,但却兼具了类型检查和鸭子类型两者的有点,这是何等优秀的设计啊! Duck typing in computer programming is an applicati ...

  2. qt ISO C++ forbids declaration of 'XXXX' with no type

    error: ISO C++ forbids declaration of 'XXXX' with no type   出现这个错误,一般是由于两个CPP相互都相互包含了对方的头文件造成的,比如: 当 ...

  3. Refused to execute script from '....js' because its MIME type ('text/html') is not executable, and strict MIME type checking is enabled.md

    目录 问题描述 解决过程 总结 问题描述 在整合 Spring Boot.Spring Security.Thymeleaf 的练习中,对页面进行调试时,发现如下错误提示: Refused to ex ...

  4. Dynamic type checking and runtime type information

    动态类型的关键是将动态对象与实际类型信息绑定. See also: Dynamic programming language and Interpreted language Dynamic type ...

  5. 类型检查 Type Checking 一些编程语言并不安全 类型化语言的优点 定型环境 (符号表) 断言的种类

    Compiler http://staff.ustc.edu.cn/~bjhua/courses/compiler/2014/ http://staff.ustc.edu.cn/~bjhua/cour ...

  6. Check类中的incl、union,excl,diff,intersect

    定义一些类,这些类之间有父子关系,如下: class Father{} class Son1 extends Father{} class Son2 extends Father{} class To ...

  7. Check类的validate方法解读

    此方法的实现如下: public void validate(JCTree tree, Env<AttrContext> env, boolean checkRaw) { Validato ...

  8. Check类之TypeValidation

    (1)Validator类的visitTypeApply()方法 实例1: class TestTypeVal<T extends InputStream>{ TestTypeVal< ...

  9. 怎么在eclipse中查到这个类用的是哪个jar的类和Eclipse 编译错误 Access restriction:The type *** is not accessible due to restriction on... 解决方案

    找到了一个办法,你先按F3,然后点击Change Attached Source..按钮,在弹出的框里有个路径,我的路径是D:/SNFWorkSpace/JAR/~importu9.jar,然后你去引 ...

随机推荐

  1. @Autowired 和 @Qualifier

    一 无冲突 bean工厂 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=" ...

  2. Spring bean加载2--FactoryBean情况处理

    Spring bean加载2--FactoryBean情况处理 在Spring bean加载过程中,每次bean实例在返回前都会调用getObjectForBeanInstance来处理Factory ...

  3. Android-SPUtil-工具类

    SPUtil-工具类 是专门对 Android共享首选项 SharedPreferences 的数据保存/数据获取,提供了公共的方法行为: package common.library.utils; ...

  4. Failed to get D-Bus connection: Operation not permitted

    通过centos7镜像创建了一个docker容器,并在容器中安装了一个apache服务,但是启动时发生如下报错 [root@1346963c2247 ~]# rpm -qa | grep httpdh ...

  5. winform npoi excel 样式设置

    IWorkbook excel = new HSSFWorkbook();//创建.xls文件 ISheet sheet = excel.CreateSheet("sheet1") ...

  6. 我所理解的网络游戏<一>:网游的顶层设计

    网游的基本结构 各大模块的基本功能如下 · 服务器端 登陆服:处理新建玩家.登陆逻辑. 场景服:处理场景服中的逻辑. 中心服:处理跨服的逻辑,实现不同场景服进程的数据调度,以及向数据库查询数据. 数据 ...

  7. 上云、微服务化和DevOps,少走弯路的办法

    本文由  网易云发布. 作者:张亮 如果说一个项目的发展历程就像一段未知的旅程,那<云原生应用架构实践>就像一张地图,基于前人的探索标明了在这段旅途中将会碰到的障碍,并注明了越过这些障碍的 ...

  8. Android 为库(library)创建不同编译环境

    项目中需要导入库,一般有两种情况,一种是直接路径导入,一种是导入库的 aar 文件. 1. 设置库项目 1. 在库项目的 src 目录下设置 debug 目录,里面可以添加代码或者 res 文件夹. ...

  9. “全栈2019”Java多线程第二十五章:生产者与消费者线程详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  10. CodeChef TWOROADS(计算几何+拉格朗日乘数法)

    题面 传送门 简要题意:给出\(n\)个点,请求出两条直线,并最小化每个点到离它最近的那条直线的距离的平方和,\(n\leq 100\) orz Shinbokuow 前置芝士 给出\(n\)个点,请 ...