📄 astoperationexpression.java
字号:
// must be a role name MNavigableElement dst = srcClass.navigableEnd(opname); if (dst != null ){ res = genNavigation(fOp, srcClass, srcExpr, dst); } else { // (1) predefined OCL operation res = genStdOperation(ctx, fOp, opname, fArgExprs); } } break; case SRC_OBJECT_TYPE + DOT + NO_PARENTHESES + EXPLICIT_ROLENAME: MClass srcClass3 = ( ( ObjectType ) srcType ).cls(); // (4) navigation operation on object type // must be a role name MNavigableElement dst = srcClass3.navigableEnd( opname ); res = genNavigation( fOp, srcClass3, srcExpr, dst, fExplicitRolename ); break; case SRC_OBJECT_TYPE + DOT + PARENTHESES: // (3) "isQuery" operation on object type (possibly with // arguments) or (1) MClass srcClass2 = ((ObjectType) srcType).cls(); res = genObjOperation(ctx, srcClass2, srcExpr); break; case SRC_OBJECT_TYPE + ARROW + NO_PARENTHESES: case SRC_OBJECT_TYPE + ARROW + PARENTHESES: // (6) set operation on single object resulting from // navigation over associations with multiplicity zero // or one (p. 7-13 of OMG UML 1.3) if (srcExpr instanceof ExpNavigation ) { // first map object to set with internal operation Expression mappedSrcExpr = new ExpObjAsSet(srcExpr); // replace receiver in arg list fArgExprs[0] = mappedSrcExpr; try { // lookup collection operation res = ExpStdOp.create(opname, fArgExprs); } catch (ExpInvalidException ex) { throw new SemanticException(fOp, ex); } } else { throw new SemanticException(fOp, "An arrow operation treating a single object as a " + "set may only be applied, if the object results " + "from a navigation to an association end with " + "multiplicity 0..1."); } break; case SRC_COLLECTION_TYPE + DOT + NO_PARENTHESES: // c.op 200 (5) with implicit (2,4,1) if (Options.disableCollectShorthand ) throw new SemanticException(fOp, MSG_DISABLE_COLLECT_SHORTHAND); res = collectShorthandWithOutArgs(opname, srcExpr); break; case SRC_COLLECTION_TYPE + DOT + PARENTHESES: // c.op() 201 (5) with implicit (3,1) if (Options.disableCollectShorthand ) throw new SemanticException(fOp, MSG_DISABLE_COLLECT_SHORTHAND); res = collectShorthandWithArgs(opname, srcExpr); break; // throw new SemanticException(fOp, /* "If you want to apply an operation to a * collection, please use an `->' instead of a * `.'. If you are trying to apply the shorthand * notation for `collect' - sorry, this is not yet * supported. Please use the explicit notation."); */ default: throw new RuntimeException("case " + Integer.toHexString(opcase) + " not handled"); } if (fIsPre ) res.setIsPre(); return res; } /** * Handles shorthand notation for collect and expands to an * explicit collect expression. */ private Expression collectShorthandWithOutArgs(String opname, Expression srcExpr) throws SemanticException { Expression res = null; // c.op 200 (5) with implicit (2,4,1) CollectionType cType = (CollectionType ) srcExpr.type(); Type elemType = cType.elemType(); if (elemType.isObjectType() ) { MClass srcClass = ((ObjectType) elemType).cls(); MAttribute attr = srcClass.attribute(opname, true); if (attr != null ) { // (2) attribute operation on object type (no arguments) // transform c.a into c->collect($e | $e.a) ExpVariable eVar = new ExpVariable("$e", elemType); ExpAttrOp eAttr = new ExpAttrOp(attr, eVar); res = genImplicitCollect(srcExpr, eAttr, elemType); } else { MNavigableElement dst = srcClass.navigableEnd(opname); if (dst != null ) { // (4) navigation operation on object type must be // a role name // transform c.r into c->collect($e | $e.r) ExpVariable eVar = new ExpVariable("$e", elemType); Expression eNav = genNavigation(fOp, srcClass, eVar, dst); res = genImplicitCollect(srcExpr, eNav, elemType); } } } if (res == null ) { // ! objectType || ! (attr || navigation) // try (1) predefined OCL operation res = collectShorthandStdOp(opname, srcExpr, cType, elemType); } return res; } /** * Handles shorthand notation for collect and expands to an * explicit collect expression. */ private Expression collectShorthandWithArgs(String opname, Expression srcExpr) throws SemanticException { Expression res = null; // c.op() 201 (5) with implicit (3,1) CollectionType cType = (CollectionType ) srcExpr.type(); Type elemType = cType.elemType(); if (elemType.isObjectType() ) { MClass srcClass = ((ObjectType) elemType).cls(); MOperation op = srcClass.operation(opname, true); if (op != null ) { // check for isQuery operation with OCL body if (! op.hasExpression() ) throw new SemanticException (fOp, "Operation `" + srcClass.name() + "::" + op.signature() + "' cannot be used in OCL expression " + "(only side effect-free operations with a return type" + " and an OCL expression as body may be used)."); // transform c.op(...) into c->collect($e | $e.op(...)) ExpVariable eVar = new ExpVariable("$e", elemType); fArgExprs[0] = eVar; try { // constructor performs additional checks res = new ExpObjOp(op, fArgExprs); } catch (ExpInvalidException ex) { throw new SemanticException(fOp, "In operation call `" + srcClass.name() + "::" + opname + "': " + ex.getMessage()); } res = genImplicitCollect(srcExpr, res, elemType); } } if (res == null ) { // try (1) predefined OCL operation res = collectShorthandStdOp(opname, srcExpr, cType, elemType); } return res; } /** * Handles shorthand notation for collect and expands to an * explicit collect expression. */ private Expression collectShorthandStdOp(String opname, Expression srcExpr, Type cType, Type elemType) throws SemanticException { Expression res = null; // (1) predefined OCL operation // find operation on element type Type[] params = new Type[fArgExprs.length]; params[0] = elemType; for (int i = 1; i < fArgExprs.length; i++) params[i] = fArgExprs[i].type(); if (! ExpStdOp.exists(opname, params) ) { String msg = "Undefined operation `" + elemType + "." + opname + "' in shorthand notation for collect."; // maybe the user just confused . with ->, check for // operation on collection and give a hint. params[0] = cType; if (ExpStdOp.exists(opname, params) ) msg += " However, there is an operation `" + cType + "->" + opname + "'. Maybe you wanted to use `->' instead of `.'?"; throw new SemanticException(fOp, msg); } // transform c.op(...) into c->collect($e | $e.op(...)) fArgExprs[0] = new ExpVariable("$e", elemType); try { Expression eOp = ExpStdOp.create(opname, fArgExprs); res = genImplicitCollect(srcExpr, eOp, elemType); } catch (ExpInvalidException ex) { // shouldn't fail because we already checked the // existence above throw new RuntimeException("collectShorthand failed: " + ex.getMessage()); } return res; } // checks (3) and (1) private Expression genObjOperation(Context ctx, MClass srcClass, Expression srcExpr) throws SemanticException { Expression res = null; // find operation String opname = fOp.getText(); MOperation op = srcClass.operation(opname, true); if (op != null ) { // check for isQuery operation with OCL body if (! op.hasExpression() ) throw new SemanticException (fOp,"Operation `" + srcClass.name() + "::" + op.signature() + "' cannot be used in OCL expression " + "(only side effect-free operations with a return type" + " and an OCL expression as body may be used)."); try { // constructor performs additional checks res = new ExpObjOp(op, fArgExprs); } catch (ExpInvalidException ex) { throw new SemanticException(fOp, "In operation call `" + srcClass.name() + "::" + opname + "': " + ex.getMessage()); } } else { // try standard operation res = genStdOperation(ctx, fOp, opname, fArgExprs); } return res; } public String toString() { return "(" + fOp + " " + StringUtil.fmtSeq(fArgs.iterator(), " ") + ")"; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -