关于类的符号输入过程第三篇
?
?
當進行完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?! ?/span>
?
?其中的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
總結
以上是生活随笔為你收集整理的关于类的符号输入过程第三篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 方正飞鸿智能信息平台(FIX ES200
- 下一篇: c#的chart标题_C#之Chart篇