📄 variablescopevisitor.java
字号:
return m.getParameters()[0].getType(); } private String getPropertyName(MethodNode m) { String name = m.getName(); if (!(name.startsWith("set") || name.startsWith("get"))) return null; String pname = name.substring(3); if (pname.length() == 0) return null; String s = pname.substring(0, 1).toLowerCase(); String rest = pname.substring(1); pname = s + rest; if (name.startsWith("get") && m.getReturnType()==ClassHelper.VOID_TYPE) { return null; } if (name.startsWith("set") && m.getParameters().length!=1) { return null; } return pname; } // ------------------------------- // different Variable based checks // ------------------------------- private Variable checkVariableNameForDeclaration(String name, Expression expression) { if ("super".equals(name) || "this".equals(name)) return null; VariableScope scope = currentScope; Variable var = new DynamicVariable(name,currentScope.isInStaticContext()); Variable dummyStart = var; // try to find a declaration of a variable VariableScope dynamicScope = null; while (!scope.isRoot()) { if (dynamicScope==null && scope.isResolvingDynamic()) { dynamicScope = scope; } Map declares = scope.getDeclaredVariables(); if (declares.get(var.getName())!=null) { var = (Variable) declares.get(var.getName()); break; } Map localReferenced = scope.getReferencedLocalVariables(); if (localReferenced.get(var.getName())!=null) { var = (Variable) localReferenced.get(var.getName()); break; } Map classReferenced = scope.getReferencedClassVariables(); if (classReferenced.get(var.getName())!=null) { var = (Variable) classReferenced.get(var.getName()); break; } ClassNode classScope = scope.getClassScope(); if (classScope!=null) { Variable member = findClassMember(classScope,var.getName()); if (member!=null) var = member; break; } scope = scope.getParent(); } VariableScope end = scope; if (scope.isRoot() && dynamicScope==null) { // no matching scope found declare(var,expression); addError("The variable " + var.getName() + " is undefined in the current scope", expression); } else if (scope.isRoot() && dynamicScope!=null) { // no matching scope found, but there was a scope that // resolves dynamic scope = dynamicScope; } if (!scope.isRoot()) { scope = currentScope; while (scope != end) { Map references = null; if (end.isClassScope() || end.isRoot() || end.isReferencedClassVariable(name)) { references = scope.getReferencedClassVariables(); } else { references = scope.getReferencedLocalVariables(); var.setClosureSharedVariable(var.isClosureSharedVariable() || inClosure); } references.put(var.getName(),var); scope = scope.getParent(); } if (end.isResolvingDynamic()) { if (end.getDeclaredVariable(var.getName())==null) { end.getDeclaredVariables().put(var.getName(),var); } } } return var; } private void checkVariableContextAccess(Variable v, Expression expr) { if (v.isInStaticContext() || !currentScope.isInStaticContext()) return; String msg = v.getName()+ " is declared in a dynamic context, but you tried to"+ " access it from a static context."; addError(msg,expr); // declare a static variable to be able to continue the check DynamicVariable v2 = new DynamicVariable(v.getName(),currentScope.isInStaticContext()); currentScope.getDeclaredVariables().put(v.getName(),v2); } // ------------------------------ // code visit // ------------------------------ public void visitBlockStatement(BlockStatement block) { pushState(); block.setVariableScope(currentScope); super.visitBlockStatement(block); popState(); } public void visitForLoop(ForStatement forLoop) { pushState(); forLoop.setVariableScope(currentScope); Parameter p = (Parameter) forLoop.getVariable(); p.setInStaticContext(currentScope.isInStaticContext()); declare(p, forLoop); super.visitForLoop(forLoop); popState(); } public void visitDeclarationExpression(DeclarationExpression expression) { // visit right side first to avoid the usage of a // variable before its declaration expression.getRightExpression().visit(this); // no need to visit left side, just get the variable name VariableExpression vex = expression.getVariableExpression(); vex.setInStaticContext(currentScope.isInStaticContext()); declare(vex); vex.setAccessedVariable(vex); } public void visitVariableExpression(VariableExpression expression) { String name = expression.getName(); Variable v = checkVariableNameForDeclaration(name,expression); if (v==null) return; expression.setAccessedVariable(v); checkVariableContextAccess(v,expression); } public void visitClosureExpression(ClosureExpression expression) { pushState(); inClosure=true; // as result of the Paris meeting Closure resolves // always dynamically currentScope.setDynamicResolving(true); expression.setVariableScope(currentScope); if (expression.isParameterSpecified()) { Parameter[] parameters = expression.getParameters(); for (int i = 0; i < parameters.length; i++) { parameters[i].setInStaticContext(currentScope.isInStaticContext()); declare(parameters[i],expression); } } else if (expression.getParameters()!=null){ DynamicVariable var = new DynamicVariable("it",currentScope.isInStaticContext()); currentScope.getDeclaredVariables().put("it",var); } super.visitClosureExpression(expression); popState(); } public void visitCatchStatement(CatchStatement statement) { pushState(); Parameter p = (Parameter) statement.getVariable(); p.setInStaticContext(currentScope.isInStaticContext()); declare(p, statement); super.visitCatchStatement(statement); popState(); } public void visitFieldExpression(FieldExpression expression) { String name = expression.getFieldName(); //TODO: change that to get the correct scope Variable v = checkVariableNameForDeclaration(name,expression); checkVariableContextAccess(v,expression); } // ------------------------------ // class visit // ------------------------------ public void visitClass(ClassNode node) { pushState(); boolean dynamicMode = node.isScript(); currentScope.setDynamicResolving(dynamicMode); currentScope.setClassScope(node); super.visitClass(node); popState(); } protected void visitConstructorOrMethod(MethodNode node, boolean isConstructor) { pushState(node.isStatic()); node.setVariableScope(currentScope); declare(node.getParameters(),node); super.visitConstructorOrMethod(node, isConstructor); popState(); } public void visitMethodCallExpression(MethodCallExpression call) { if (call.isImplicitThis()) { Variable v = checkVariableNameForDeclaration(call.getMethod(),call); if (v!=null && !(v instanceof DynamicVariable)) { checkVariableContextAccess(v,call); } } super.visitMethodCallExpression(call); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -