📄 resolver.java
字号:
IMethod method = newContext.getMethodDefinition(name, signature);
if (method != null) {
if (createReference && referencePhase) {
nameNode.setDefinition(method, location, referencePhase);
}
result = method.getType();
}
}
if (result == null) {
result = new UnknownClass(methodNode.getText(), methodNode);
}
return result;
}
/**
* resolves a literal "this"
*
* @param expression the <code>SymTabAST</code> of the expression
* @param location the <code>Scope</code> where the expression occurs
* @param context the <code>Scope</code> in which the expression occurs
* (where the search for a defintion begins)
*
* @return the resulting scope of the expression (the type to which it evaluates)
*/
private IClass resolveLiteralThis(
SymTabAST thisNode,
Scope location,
IClass context) {
return location.getEnclosingClass();
}
/**
* resolves a literal "super"
*
* @param expression the <code>SymTabAST</code> of the expression
* @param location the <code>Scope</code> where the expression occurs
* @param context the <code>Scope</code> in which the expression occurs
* (where the search for a defintion begins)
*
* @return the resulting scope of the expression (the type to which it evaluates)
*/
private IClass resolveLiteralSuper(
SymTabAST superNode,
Scope location,
IClass context) {
return location.getEnclosingClass().getSuperclass();
}
private boolean newIsConstructor(SymTabAST newNode) {
boolean result = false;
SymTabAST typeNode =
(SymTabAST) (newNode.getFirstChild().getNextSibling());
//handle Checkstyle grammar
if (typeNode.getType() == TokenTypes.LPAREN) {
typeNode = (SymTabAST) typeNode.getNextSibling();
}
if (typeNode.getType() == TokenTypes.ELIST) {
result = true;
}
return result;
}
/**
* resolves and expression of type TokenTypes.TYPE
*
* @param expression the <code>SymTabAST</code> of the expression
* @param location the <code>Scope</code> where the expression occurs
* @param context the <code>Scope</code> in which the expression occurs
* (where the search for a defintion begins)
* @param referencePhase whether or not this is the reference phase of
* table construction
* @return the resulting scope of the expression (the type to which it evaluates)
* @see #resolveDottedName(SymTabAST, Scope, IClass, boolean)
* @see #resolveClassIdent(SymTabAST, Scope, IClass, boolean)
*/
public IClass resolveType(
SymTabAST expr,
Scope location,
IClass context,
boolean referencePhase) {
IClass result = null;
SymTabAST nameNode = (SymTabAST) expr.getFirstChild();
// TODO: Checkstyle change.
// Do not create references from typecast.
// Original transmogrify code is equivalent to
// final boolean createReference = referencePhase;
// which creates non-existant references for variables.
final boolean createReference = false;
if (nameNode.getType() == TokenTypes.DOT) {
result =
resolveDottedName(nameNode, location, context, createReference);
}
else {
result =
resolveClassIdent(nameNode, location, context, createReference);
}
return result;
}
/**
* resolves Class type expression
* @param expr node to be resolved
* @param location scope of the <code>expr</code>
* @param context context of the <code>expr</code> if exists
* @param referencePhase <code>true</code> if this method is used to during
* finding reference phase
* <code>false</code> otherwise
* @return <code>IClass</code> representing the type to which the
* expression evalutes.
* @see #resolveDottedName(SymTabAST, Scope, IClass, boolean)
*/
public IClass resolveClass(
SymTabAST expr,
Scope location,
IClass context,
boolean referencePhase) {
IClass result =
resolveDottedName(expr, location, context, referencePhase);
if (result != null && referencePhase) {
expr.setDefinition(result, location, referencePhase);
}
return result;
}
/**
* resolves expression with <code>JavaTokenTypes<code> other than <code>DOT</code>
* @param expr expression to be resolved
* @param location scope of the expression
* @param context context of the expression if any
* @param referencePhase <code>true</code> if this method is used to during
* finding reference phase
* <code>false</code> otherwise
* @return <code>IClass</code> representing the type to which the
* expression evalutes.
*/
public IClass resolveClassIdent(
SymTabAST expr,
Scope location,
IClass context,
boolean referencePhase) {
IClass result = location.getClassDefinition(expr.getText());
if (result != null) {
expr.setDefinition(result, location, referencePhase);
}
return result;
}
private IClass resolveNew(
SymTabAST newNode,
Scope location,
IClass context,
boolean referencePhase) {
IClass result;
if (newIsConstructor(newNode)) {
result =
resolveConstructor(newNode, location, context, referencePhase);
}
else {
result =
resolveNewArray(newNode, location, context, referencePhase);
}
return result;
}
private IClass resolveNewArray(
SymTabAST newNode,
Scope location,
IClass context,
boolean referencePhase) {
IClass arrayType;
SymTabAST typeNode = (SymTabAST) (newNode.getFirstChild());
SymTabAST declaratorNode = (SymTabAST) (typeNode.getNextSibling());
SymTabAST initializerNode =
(SymTabAST) (declaratorNode.getNextSibling());
arrayType = resolveClass(typeNode, location, context, referencePhase);
if (declaratorNode.getFirstChild() != null) {
resolveExpression(
((SymTabAST) declaratorNode.getFirstChild()),
location,
context,
referencePhase);
}
if (initializerNode != null) {
resolveArrayInitializer(
initializerNode,
location,
context,
referencePhase);
}
return new ArrayDef(arrayType);
}
private IClass resolveQuestion(
SymTabAST question,
Scope location,
IClass context,
boolean referencePhase) {
SymTabAST test = (SymTabAST) question.getFirstChild();
while (test.getType() == TokenTypes.LPAREN) {
test = (SymTabAST) test.getNextSibling();
}
SymTabAST leftBranch = (SymTabAST) test.getNextSibling();
while (leftBranch.getType() == TokenTypes.RPAREN) {
leftBranch = (SymTabAST) leftBranch.getNextSibling();
}
SymTabAST rightBranch = (SymTabAST) leftBranch.getNextSibling();
while (rightBranch.getType() != TokenTypes.COLON) {
rightBranch = (SymTabAST) rightBranch.getNextSibling();
}
rightBranch = (SymTabAST) rightBranch.getNextSibling();
resolveExpression(test, location, context, referencePhase);
IClass leftClass =
resolveExpression(leftBranch, location, context, referencePhase);
IClass rightClass =
resolveExpression(rightBranch, location, context, referencePhase);
return moreGeneral(leftClass, rightClass);
}
private IClass moreGeneral(IClass a, IClass b) {
return (a.isCompatibleWith(b)) ? b : a;
}
/**
* Resolves a constructor call.
*
* @param tree the root node of the constructor call
* @return the <code>ClassDef</code> for the class instantiated by the
* constructor
*/
private IClass resolveConstructor(
SymTabAST constructor,
Scope location,
IClass context,
boolean referencePhase) {
IClass classConstructed = null;
SymTabAST nameNode = (SymTabAST) (constructor.getFirstChild());
//SymTabAST parametersNode = (SymTabAST) (nameNode.getNextSibling());
SymTabAST parametersNode =
constructor.findFirstToken(TokenTypes.ELIST);
SymTabAST nameIdent = null;
if (nameNode.getType() == TokenTypes.IDENT) {
nameIdent = nameNode;
}
else {
nameIdent = (SymTabAST) nameNode.getFirstChild().getNextSibling();
}
classConstructed = resolveClass(nameNode, location, context, false);
if (classConstructed != null) {
MethodSignature signature =
resolveParameters(
parametersNode,
location,
context,
referencePhase);
IMethod constructorDef =
classConstructed.getMethodDefinition(
nameIdent.getText(),
signature);
if (constructorDef != null && referencePhase) {
nameIdent.setDefinition(
constructorDef,
location,
referencePhase);
}
}
return classConstructed;
}
/**
* Resolves the types found in a method call. Any references found
* in the process are created. Returns a <code>MethodSignature</code> for
* the types of the parameters.
*
* @param elist The <code>SymTabAST</code> for the list of parameters
* @return the signature of the parameters
*/
private MethodSignature resolveParameters(
SymTabAST elist,
Scope location,
IClass context,
boolean referencePhase) {
Vector parameters = new Vector();
SymTabAST expr = (SymTabAST) (elist.getFirstChild());
while (expr != null) {
if (expr.getType() != TokenTypes.COMMA) {
IClass parameter =
resolveExpression((SymTabAST) (expr
.getFirstChild()),
location,
context,
referencePhase);
parameters.add(parameter);
}
expr = (SymTabAST) (expr.getNextSibling());
}
return new MethodSignature(parameters);
}
/**
* Resolves an IDENT node of an AST, creating the appropriate reference and
* returning the scope of the identifer.
*
* @param ident the IDENT node
* @param location the <code>Scope</code> in which the IDENT is found
* @return the <code>Scope</code> the identifier identifies
*/
private IClass resolveIdent(
SymTabAST ident,
Scope location,
IClass context,
boolean referencePhase) {
IClass result = null;
IDefinition def = null;
String name = ident.getText();
// look for var
if (context != null) {
def = context.getVariableDefinition(name);
}
else {
def = location.getVariableDefinition(name);
}
if (def != null) {
result = ((IVariable) def).getType();
}
else {
// look for class
if (context != null) {
result = context.getClassDefinition(name);
}
else {
result = location.getClassDefinition(name);
}
def = result;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -