/** * Can this Node be early bound to the Definition it refers to. * We can early bind if we resolve to a definition, the definition is not ambiguous, and * the definition is not something defined in one of the XML classes (XML or XMLList). * @param project project to resolve things in * @param def the definition this node resolved to * @return true if we can early bind, otherwise false */ protected boolean canEarlyBind(ICompilerProject project, IDefinition def) { if (def instanceof DefinitionBase && !AmbiguousDefinition.isAmbiguous(def)) { // Can't early bind to XML/XMLList properties as they may be hidden by the unknown contents // of the XML itself, i.e. a child tag named 'parent' // Matches ASC behavior. if (!isXMLish(def.getParent(), project)) return true; } return false; }
/** * Can this Node be early bound to the Definition it refers to. * We can early bind if we resolve to a definition, the definition is not ambiguous, and * the definition is not something defined in one of the XML classes (XML or XMLList). * @param project project to resolve things in * @param def the definition this node resolved to * @return true if we can early bind, otherwise false */ protected boolean canEarlyBind(ICompilerProject project, IDefinition def) { if (def instanceof DefinitionBase && !AmbiguousDefinition.isAmbiguous(def)) { // Can't early bind to XML/XMLList properties as they may be hidden by the unknown contents // of the XML itself, i.e. a child tag named 'parent' // Matches ASC behavior. if (!isXMLish(def.getParent(), project)) return true; } return false; }
@Override public ITypeDefinition resolveType(ICompilerProject project) { IDefinition def = resolve(project); if (def != null) { if (isXMLish(def.getParent(), project)) { // XML and XMLList members should be treated as '*' because any access could // resolve to some content inside the XML (i.e. it has a child tag named 'name'). // return '*' since we can't statically know what the type will be. // Compat with ASC behavior. return project.getBuiltinType(IASLanguageConstants.BuiltinType.ANY_TYPE); } return def.resolveType(project); } return null; }
/** * Check an ExpressionNodeBase's base expression (if any) * to determine if it's a dynamic expression, which * means we don't know much about its definition. * @param binding - the binding whose base node is to be checked. * @param project - an ICompilerProject for the current project. * @return true if node's base expression is dynamic. */ public static boolean hasDynamicBase(Binding binding, ICompilerProject project) { ExpressionNodeBase base = getBaseNode(binding); if (base != null && base.isDynamicExpression(project)) return true; // the JS version of XML is not currently dynamic so special case it here. if (base != null && base.getNodeID() == ASTNodeID.IdentifierID && IdentifierNode.isXMLish(base.resolveType(project), project)) return true; return false; }
@Override public ITypeDefinition resolveType(ICompilerProject project) { IDefinition def = resolve(project); if (def != null) { if (isXMLish(def.getParent(), project)) { // XML and XMLList members should be treated as '*' because any access could // resolve to some content inside the XML (i.e. it has a child tag named 'name'). // return '*' since we can't statically know what the type will be. // Compat with ASC behavior. return project.getBuiltinType(IASLanguageConstants.BuiltinType.ANY_TYPE); } return def.resolveType(project); } return null; }
/** * Check an ExpressionNodeBase's base expression (if any) * to determine if it's a dynamic expression, which * means we don't know much about its definition. * @param binding - the binding whose base node is to be checked. * @param project - an ICompilerProject for the current project. * @return true if node's base expression is dynamic. */ public static boolean hasDynamicBase(Binding binding, ICompilerProject project) { ExpressionNodeBase base = getBaseNode(binding); if (base != null && base.isDynamicExpression(project)) return true; // the JS version of XML is not currently dynamic so special case it here. if (base != null && base.getNodeID() == ASTNodeID.IdentifierID && IdentifierNode.isXMLish(base.resolveType(project), project)) return true; return false; }
@Override public ITypeDefinition resolveType(ICompilerProject project) { ITypeDefinition leftType = getLeftOperandNode().resolveType(project); ITypeDefinition rightType = getRightOperandNode().resolveType(project); // If we're adding numeric values (Number, int, or uint), // then the result is Number. if (isNumericType(leftType, project) && isNumericType(rightType, project)) return project.getBuiltinType(BuiltinType.NUMBER); // If one of our operands is String, // then the result is String. ITypeDefinition stringType = project.getBuiltinType(BuiltinType.STRING); if (stringType.equals(leftType) || stringType.equals(rightType)) return stringType; // If we're adding two XML-ish (i.e., XML or XMLList) objects, // then the result is XMLList. if (IdentifierNode.isXMLish(leftType, project) && IdentifierNode.isXMLish(rightType, project)) { return project.getBuiltinType(BuiltinType.XMLLIST); } // Otherwise, the result is *. return project.getBuiltinType(BuiltinType.ANY_TYPE); }
@Override public ITypeDefinition resolveType(ICompilerProject project) { ITypeDefinition leftType = getLeftOperandNode().resolveType(project); ITypeDefinition rightType = getRightOperandNode().resolveType(project); // If we're adding numeric values (Number, int, or uint), // then the result is Number. if (isNumericType(leftType, project) && isNumericType(rightType, project)) return project.getBuiltinType(BuiltinType.NUMBER); // If one of our operands is String, // then the result is String. ITypeDefinition stringType = project.getBuiltinType(BuiltinType.STRING); if (stringType.equals(leftType) || stringType.equals(rightType)) return stringType; // If we're adding two XML-ish (i.e., XML or XMLList) objects, // then the result is XMLList. if (IdentifierNode.isXMLish(leftType, project) && IdentifierNode.isXMLish(rightType, project)) { return project.getBuiltinType(BuiltinType.XMLLIST); } // Otherwise, the result is *. return project.getBuiltinType(BuiltinType.ANY_TYPE); }
return IdentifierNode.isXMLish(leftDef, getWalker().getProject()); if (rightDef != null) return IdentifierNode.isXMLish(rightDef, getWalker().getProject()); IDefinition leftDef = leftNode.resolveType(getWalker().getProject()); if (leftDef != null) return IdentifierNode.isXMLish(leftDef, getWalker().getProject());
/** * resolveType on an XML expression returns null * (see IdentiferNode.resolveType). * So, we have to walk the tree ourselves and resolve * individual pieces. * @param obj * @return */ public boolean isXML(IExpressionNode obj) { // See if the left side is XML or XMLList IDefinition leftDef = obj.resolveType(getWalker().getProject()); if (leftDef == null && obj.getNodeID() == ASTNodeID.MemberAccessExpressionID) { return isXML(((MemberAccessExpressionNode)obj).getLeftOperandNode()); } return IdentifierNode.isXMLish(leftDef, getWalker().getProject()); }
if (!((RoyaleProject)project).useStrictXML() && isXMLish(baseType, project)) return null;
if (!((RoyaleProject)project).useStrictXML() && isXMLish(baseType, project)) return null;
if (rightDef != null) if (IdentifierNode.isXMLish(rightDef, getWalker().getProject()))
&& IdentifierNode.isXMLish(leftDef, getWalker().getProject()))