日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于类的符号输入过程第三篇

發布時間:2023/12/16 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于类的符号输入过程第三篇 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

?

當進行完MemberEnter后就可以調用Attr類的一些標記方法了,如下:

while (!todo.isEmpty()){Environment<AttrContext> a = todo.remove();Environment<AttrContext> b = attribute(a); // 標注Queue<Environment<AttrContext>> c = flow(b); // 數據流分析Queue<Pair<Environment<AttrContext>, JCClassDeclaration>> d = desugar(c); // 解語法糖generate(d); // 生成字節碼 // generate(desugar(flow(attribute(todo.remove())))); }

?

在之前的MemberEnter類中visitImport()方法中有如下一個方法調用,如下:

Type type = attr.attribTree(jcFieldAccess.selected, localEnvironment, protoKind, Type.noType); // protoKind=_TYPE|_PCK,Type.noType=JCNoType

其中JCFieldAccess為java.util.ArrayList,而jcFieldAccess.selected為java.util。  

?

?其中的scope為ImportScope。

?

在標識前,所有的selected的symbol與type都為null。先要進行JCIdentifier的處理,主要經歷的方法有三個:

首先visitIdentifier(),在這個方法中調用resolveIdentifier()方法,接著也會調用checkIndentifier()方法。

resolveIdentifier()中會調用findIdentifier()方法查找到name對應的符號Symbol,這個方法的具體代碼實現如下:

/** Find an unqualified identifier which matches a specified kind set.* @param environment The current environment.* @param name The identifier's name.* @param kind Indicates the possible symbol kinds (a subset of _VAL, _TYP, _PCK).**/public Symbol findIdentifier(Environment<AttrContext> environment, Name name, int kind) {Symbol bestSoFar = typeNotFound;Symbol symbol;if ((kind & _VAR) != 0) {symbol = findVariable(environment, name);if (symbol.exists()){return symbol;}else if (symbol.kind < bestSoFar.kind){bestSoFar = symbol;}}if ((kind & _TYP) != 0) {symbol = findType(environment, name);if (symbol.exists()){return symbol;}else if (symbol.kind < bestSoFar.kind){ // ??bestSoFar = symbol;}}if ((kind & _PCK) != 0){return classReader.enterPackage(name);}else{return bestSoFar;}}

name除了代表方法的名稱外,其余就是變量、類型和包名稱了。優先進行變量名的查找,由于變量名有局部變量和全局變量,所以對應的查找方法就有findVariable()與findField()。

其中findVariable()方法如下:

/** Find unqualified variable or field with given name.* Synthetic fields always skipped.* @param environment The current environment.* @param name The name of the variable or field.*/Symbol findVariable(Environment<AttrContext> environment, Name name) {Symbol bestSoFar = variableNotFound;Symbol symbol;Environment<AttrContext> env1 = environment;boolean staticOnly = false;while (env1.outer != null) {if (isStatic(env1)){staticOnly = true;}Entry entry = env1.info.scope.lookup(name);while (entry.scope != null &&(entry.symbol.kind != _VAR || (entry.symbol.flags_field & SYNTHETIC) != 0) // 非變量或者是合成的那就需要繼續查找){entry = entry.next();}// 走到這里說明entry.symbol.kind==_VAR或者(entry.symbol.flags_field & SYNTHETIC)==0(非合成的變量)// 如果findVariable查找不到就要調用findField進行查找if(entry.scope != null){symbol = entry.symbol;}else{symbol = findField(env1, env1.enclosingClass.classSymbol.type, name, env1.enclosingClass.classSymbol);}if( symbol.exists()) {if( staticOnly &&symbol.kind == _VAR &&symbol.ownerSymbol.kind == _TYP &&(symbol.flags() & STATIC) == 0) {// 靜態上下文中引用非靜態的變量return new StaticError(symbol, this);}else{return symbol;}} else if (symbol.kind < bestSoFar.kind) {bestSoFar = symbol;}if ((env1.enclosingClass.classSymbol.flags() & STATIC) != 0){staticOnly = true;}env1 = env1.outer;}// end whilesymbol = findField(environment, symbolTable.predefinedClass.type, name, symbolTable.predefinedClass);if (symbol.exists()){return symbol;}if (bestSoFar.exists()){return bestSoFar;}Entry entry = environment.toplevel.namedImportScope.lookup(name);for (; entry.scope != null; entry = entry.next()) {symbol = entry.symbol;Type origin = entry.getOrigin().owner.type;if (symbol.kind == _VAR) {if (entry.symbol.ownerSymbol.type != origin){symbol = symbol.clone(entry.getOrigin().owner);}if(isAccessible(environment, origin, symbol)){return symbol;}else{return new AccessError(environment, origin, symbol, this);}}}Symbol origin = null;entry = environment.toplevel.starImportScope.lookup(name);for (; entry.scope != null; entry = entry.next()) {symbol = entry.symbol;if (symbol.kind != _VAR){continue;}// invariant: classSymbol.kind == _VARif (bestSoFar.kind < _AMBIGUOUS && symbol.ownerSymbol != bestSoFar.ownerSymbol){return new AmbiguityError(bestSoFar, symbol, this);}else if (bestSoFar.kind >= _VAR) {origin = entry.getOrigin().owner;if(isAccessible(environment, origin.type, symbol)){bestSoFar = symbol;}else{bestSoFar = new AccessError(environment, origin.type, symbol, this);}}}// ???if (bestSoFar.kind == _VAR && bestSoFar.ownerSymbol.type != origin.type){return bestSoFar.clone(origin);}else{return bestSoFar;}}

而findField()方法的代碼如下:

/** Find field. Synthetic fields are always skipped.* @param environment The current environment.* @param site The original type from where the selection takes place.* @param name The name of the field.* @param typeSymbol The class to search for the field. This is always a superclass or implemented interface of site's class.*/Symbol findField(Environment<AttrContext> environment,Type site,Name name,TypeSymbol typeSymbol) {while (typeSymbol.type.typeTag == TYPEVARIABLE){typeSymbol = typeSymbol.type.getUpperBound().typeSymbol;}Symbol bestSoFar = variableNotFound;Symbol symbol;// 查找本類Entry entry = typeSymbol.members().lookup(name);while (entry.scope != null) {// 符號是變量且不是合成的if (entry.symbol.kind == _VAR && (entry.symbol.flags_field & SYNTHETIC) == 0) {if(isAccessible(environment, site, entry.symbol)){return entry.symbol;}else{return new AccessError(environment, site, entry.symbol,this);}}entry = entry.next();}// 查找父類Type superType = types.supertype(typeSymbol.type);if (superType != null && (superType.typeTag == CLASS || superType.typeTag == TYPEVARIABLE)) {symbol = findField(environment, site, name, superType.typeSymbol); // 遞歸調用if (symbol.kind < bestSoFar.kind){bestSoFar = symbol;}}// 查找所有的接口類for (List<Type> l = types.interfaces(typeSymbol.type); bestSoFar.kind != _AMBIGUOUS && l.nonEmpty(); l = l.tail) {symbol = findField(environment, site, name, l.head.typeSymbol); // 遞歸調用if (bestSoFar.kind < _AMBIGUOUS && symbol.kind < _AMBIGUOUS && symbol.ownerSymbol != bestSoFar.ownerSymbol){bestSoFar = new AmbiguityError(bestSoFar, symbol, this);}else if (symbol.kind < bestSoFar.kind){bestSoFar = symbol;}}return bestSoFar;}

?

?

?

?

  

?

?

?

?

?

?

?

?

?

?

  

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

?

  

?

?

?

?

?

  

轉載于:https://www.cnblogs.com/extjs4/p/6664414.html

總結

以上是生活随笔為你收集整理的关于类的符号输入过程第三篇的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。