当前位置: 首页>>代码示例>>C++>>正文


C++ ObjCMethodCall::getSelector方法代码示例

本文整理汇总了C++中ObjCMethodCall::getSelector方法的典型用法代码示例。如果您正苦于以下问题:C++ ObjCMethodCall::getSelector方法的具体用法?C++ ObjCMethodCall::getSelector怎么用?C++ ObjCMethodCall::getSelector使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在ObjCMethodCall的用法示例。


在下文中一共展示了ObjCMethodCall::getSelector方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: checkPreObjCMessage

/// If we are in -dealloc or -dealloc is on the stack, handle the call if it is
/// a release or a nilling-out property setter.
void ObjCDeallocChecker::checkPreObjCMessage(
    const ObjCMethodCall &M, CheckerContext &C) const {
  // Only run if -dealloc is on the stack.
  SVal DeallocedInstance;
  if (!instanceDeallocIsOnStack(C, DeallocedInstance))
    return;

  SymbolRef ReleasedValue = nullptr;

  if (M.getSelector() == ReleaseSel) {
    ReleasedValue = M.getReceiverSVal().getAsSymbol();
  } else if (M.getSelector() == DeallocSel && !M.isReceiverSelfOrSuper()) {
    if (diagnoseMistakenDealloc(M.getReceiverSVal().getAsSymbol(), M, C))
      return;
  }

  if (ReleasedValue) {
    // An instance variable symbol was released with -release:
    //    [_property release];
    if (diagnoseExtraRelease(ReleasedValue,M, C))
      return;
  } else {
    // An instance variable symbol was released nilling out its property:
    //    self.property = nil;
    ReleasedValue = getValueReleasedByNillingOut(M, C);
  }

  if (!ReleasedValue)
    return;

  transitionToReleaseValue(C, ReleasedValue);
}
开发者ID:Bekenn,项目名称:clang,代码行数:34,代码来源:CheckObjCDealloc.cpp

示例2: warnIfNilArg

void NilArgChecker::warnIfNilArg(CheckerContext &C,
                                 const ObjCMethodCall &msg,
                                 unsigned int Arg,
                                 FoundationClass Class,
                                 bool CanBeSubscript) const {
  // Check if the argument is nil.
  ProgramStateRef State = C.getState();
  if (!State->isNull(msg.getArgSVal(Arg)).isConstrainedTrue())
      return;

  // NOTE: We cannot throw non-fatal errors from warnIfNilExpr,
  // because it's called multiple times from some callers, so it'd cause
  // an unwanted state split if two or more non-fatal errors are thrown
  // within the same checker callback. For now we don't want to, but
  // it'll need to be fixed if we ever want to.
  if (ExplodedNode *N = C.generateErrorNode()) {
    SmallString<128> sbuf;
    llvm::raw_svector_ostream os(sbuf);

    if (CanBeSubscript && msg.getMessageKind() == OCM_Subscript) {

      if (Class == FC_NSArray) {
        os << "Array element cannot be nil";
      } else if (Class == FC_NSDictionary) {
        if (Arg == 0) {
          os << "Value stored into '";
          os << GetReceiverInterfaceName(msg) << "' cannot be nil";
        } else {
          assert(Arg == 1);
          os << "'"<< GetReceiverInterfaceName(msg) << "' key cannot be nil";
        }
      } else
        llvm_unreachable("Missing foundation class for the subscript expr");

    } else {
      if (Class == FC_NSDictionary) {
        if (Arg == 0)
          os << "Value argument ";
        else {
          assert(Arg == 1);
          os << "Key argument ";
        }
        os << "to '";
        msg.getSelector().print(os);
        os << "' cannot be nil";
      } else {
        os << "Argument to '" << GetReceiverInterfaceName(msg) << "' method '";
        msg.getSelector().print(os);
        os << "' cannot be nil";
      }
    }

    generateBugReport(N, os.str(), msg.getArgSourceRange(Arg),
                      msg.getArgExpr(Arg), C);
  }
}
开发者ID:LegalizeAdulthood,项目名称:clang,代码行数:56,代码来源:BasicObjCFoundationChecks.cpp

示例3: WarnIfNilArg

void NilArgChecker::WarnIfNilArg(CheckerContext &C,
                                 const ObjCMethodCall &msg,
                                 unsigned int Arg,
                                 FoundationClass Class,
                                 bool CanBeSubscript) const {
  // Check if the argument is nil.
  ProgramStateRef State = C.getState();
  if (!State->isNull(msg.getArgSVal(Arg)).isConstrainedTrue())
      return;
      
  if (!BT)
    BT.reset(new APIMisuse("nil argument"));

  if (ExplodedNode *N = C.generateSink()) {
    SmallString<128> sbuf;
    llvm::raw_svector_ostream os(sbuf);

    if (CanBeSubscript && msg.getMessageKind() == OCM_Subscript) {

      if (Class == FC_NSArray) {
        os << "Array element cannot be nil";
      } else if (Class == FC_NSDictionary) {
        if (Arg == 0) {
          os << "Value stored into '";
          os << GetReceiverInterfaceName(msg) << "' cannot be nil";
        } else {
          assert(Arg == 1);
          os << "'"<< GetReceiverInterfaceName(msg) << "' key cannot be nil";
        }
      } else
        llvm_unreachable("Missing foundation class for the subscript expr");

    } else {
      if (Class == FC_NSDictionary) {
        if (Arg == 0)
          os << "Value argument ";
        else {
          assert(Arg == 1);
          os << "Key argument ";
        }
        os << "to '" << msg.getSelector().getAsString() << "' cannot be nil";
      } else {
        os << "Argument to '" << GetReceiverInterfaceName(msg) << "' method '"
        << msg.getSelector().getAsString() << "' cannot be nil";
      }
    }

    BugReport *R = new BugReport(*BT, os.str(), N);
    R->addRange(msg.getArgSourceRange(Arg));
    bugreporter::trackNullOrUndefValue(N, msg.getArgExpr(Arg), *R);
    C.emitReport(R);
  }
}
开发者ID:8l,项目名称:emscripten-fastcomp-clang,代码行数:53,代码来源:BasicObjCFoundationChecks.cpp

示例4: checkPostObjCMessage

void ObjCNonNilReturnValueChecker::checkPostObjCMessage(const ObjCMethodCall &M,
                                                        CheckerContext &C)
                                                        const {
  ProgramStateRef State = C.getState();

  if (!Initialized) {
    ASTContext &Ctx = C.getASTContext();
    ObjectAtIndex = GetUnarySelector("objectAtIndex", Ctx);
    ObjectAtIndexedSubscript = GetUnarySelector("objectAtIndexedSubscript", Ctx);
    NullSelector = GetNullarySelector("null", Ctx);
  }

  // Check the receiver type.
  if (const ObjCInterfaceDecl *Interface = M.getReceiverInterface()) {

    // Assume that object returned from '[self init]' or '[super init]' is not
    // 'nil' if we are processing an inlined function/method.
    //
    // A defensive callee will (and should) check if the object returned by
    // '[super init]' is 'nil' before doing it's own initialization. However,
    // since 'nil' is rarely returned in practice, we should not warn when the
    // caller to the defensive constructor uses the object in contexts where
    // 'nil' is not accepted.
    if (!C.inTopFrame() && M.getDecl() &&
        M.getDecl()->getMethodFamily() == OMF_init &&
        M.isReceiverSelfOrSuper()) {
      State = assumeExprIsNonNull(M.getOriginExpr(), State, C);
    }

    FoundationClass Cl = findKnownClass(Interface);

    // Objects returned from
    // [NSArray|NSOrderedSet]::[ObjectAtIndex|ObjectAtIndexedSubscript]
    // are never 'nil'.
    if (Cl == FC_NSArray || Cl == FC_NSOrderedSet) {
      Selector Sel = M.getSelector();
      if (Sel == ObjectAtIndex || Sel == ObjectAtIndexedSubscript) {
        // Go ahead and assume the value is non-nil.
        State = assumeExprIsNonNull(M.getOriginExpr(), State, C);
      }
    }

    // Objects returned from [NSNull null] are not nil.
    if (Cl == FC_NSNull) {
      if (M.getSelector() == NullSelector) {
        // Go ahead and assume the value is non-nil.
        State = assumeExprIsNonNull(M.getOriginExpr(), State, C);
      }
    }
  }
  C.addTransition(State);
}
开发者ID:RichardsonAlex,项目名称:clang-1,代码行数:52,代码来源:BasicObjCFoundationChecks.cpp

示例5: checkPreObjCMessage

void NilArgChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                        CheckerContext &C) const {
  const ObjCInterfaceDecl *ID = msg.getReceiverInterface();
  if (!ID)
    return;
  
  if (findKnownClass(ID) == FC_NSString) {
    Selector S = msg.getSelector();
    
    if (S.isUnarySelector())
      return;
    
    // FIXME: This is going to be really slow doing these checks with
    //  lexical comparisons.
    
    std::string NameStr = S.getAsString();
    StringRef Name(NameStr);
    assert(!Name.empty());
    
    // FIXME: Checking for initWithFormat: will not work in most cases
    //  yet because [NSString alloc] returns id, not NSString*.  We will
    //  need support for tracking expected-type information in the analyzer
    //  to find these errors.
    if (Name == "caseInsensitiveCompare:" ||
        Name == "compare:" ||
        Name == "compare:options:" ||
        Name == "compare:options:range:" ||
        Name == "compare:options:range:locale:" ||
        Name == "componentsSeparatedByCharactersInSet:" ||
        Name == "initWithFormat:") {
      if (isNil(msg.getArgSVal(0)))
        WarnNilArg(C, msg, 0);
    }
  }
}
开发者ID:gwelymernans,项目名称:lfort,代码行数:35,代码来源:BasicObjCFoundationChecks.cpp

示例6: isSuperDeallocMessage

/// Returns true if M is a call to '[super dealloc]'.
bool ObjCDeallocChecker::isSuperDeallocMessage(
    const ObjCMethodCall &M) const {
  if (M.getOriginExpr()->getReceiverKind() != ObjCMessageExpr::SuperInstance)
    return false;

  return M.getSelector() == DeallocSel;
}
开发者ID:Bekenn,项目名称:clang,代码行数:8,代码来源:CheckObjCDealloc.cpp

示例7: checkPreObjCMessage

void NSAutoreleasePoolChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                                   CheckerContext &C) const {
  if (!msg.isInstanceMessage())
    return;

  const ObjCInterfaceDecl *OD = msg.getReceiverInterface();
  if (!OD)
    return;  
  if (!OD->getIdentifier()->isStr("NSAutoreleasePool"))
    return;

  if (releaseS.isNull())
    releaseS = GetNullarySelector("release", C.getASTContext());
  // Sending 'release' message?
  if (msg.getSelector() != releaseS)
    return;

  if (!BT)
    BT.reset(new BugType("Use -drain instead of -release",
                         "API Upgrade (Apple)"));

  ExplodedNode *N = C.addTransition();
  if (!N) {
    assert(0);
    return;
  }

  BugReport *Report = new BugReport(*BT, "Use -drain instead of -release when "
    "using NSAutoreleasePool and garbage collection", N);
  Report->addRange(msg.getSourceRange());
  C.emitReport(Report);
}
开发者ID:8l,项目名称:emscripten-fastcomp-clang,代码行数:32,代码来源:NSAutoreleasePoolChecker.cpp

示例8: initIdentifierInfoAndSelectors

bool
ObjCSuperDeallocChecker::isSuperDeallocMessage(const ObjCMethodCall &M) const {
  if (M.getOriginExpr()->getReceiverKind() != ObjCMessageExpr::SuperInstance)
    return false;

  ASTContext &Ctx = M.getState()->getStateManager().getContext();
  initIdentifierInfoAndSelectors(Ctx);

  return M.getSelector() == SELdealloc;
}
开发者ID:Bekenn,项目名称:clang,代码行数:10,代码来源:ObjCSuperDeallocChecker.cpp

示例9: checkPostObjCMessage

void NoReturnFunctionChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
                                                   CheckerContext &C) const {
  // Check if the method is annotated with analyzer_noreturn.
  if (const ObjCMethodDecl *MD = Msg.getDecl()) {
    MD = MD->getCanonicalDecl();
    if (MD->hasAttr<AnalyzerNoReturnAttr>()) {
      C.generateSink();
      return;
    }
  }

  // HACK: This entire check is to handle two messages in the Cocoa frameworks:
  // -[NSAssertionHandler
  //    handleFailureInMethod:object:file:lineNumber:description:]
  // -[NSAssertionHandler
  //    handleFailureInFunction:file:lineNumber:description:]
  // Eventually these should be annotated with __attribute__((noreturn)).
  // Because ObjC messages use dynamic dispatch, it is not generally safe to
  // assume certain methods can't return. In cases where it is definitely valid,
  // see if you can mark the methods noreturn or analyzer_noreturn instead of
  // adding more explicit checks to this method.

  if (!Msg.isInstanceMessage())
    return;

  const ObjCInterfaceDecl *Receiver = Msg.getReceiverInterface();
  if (!Receiver)
    return;
  if (!Receiver->getIdentifier()->isStr("NSAssertionHandler"))
    return;

  Selector Sel = Msg.getSelector();
  switch (Sel.getNumArgs()) {
  default:
    return;
  case 4:
    lazyInitKeywordSelector(HandleFailureInFunctionSel, C.getASTContext(),
                            "handleFailureInFunction", "file", "lineNumber",
                            "description", nullptr);
    if (Sel != HandleFailureInFunctionSel)
      return;
    break;
  case 5:
    lazyInitKeywordSelector(HandleFailureInMethodSel, C.getASTContext(),
                            "handleFailureInMethod", "object", "file",
                            "lineNumber", "description", nullptr);
    if (Sel != HandleFailureInMethodSel)
      return;
    break;
  }

  // If we got here, it's one of the messages we care about.
  C.generateSink();
}
开发者ID:4ntoine,项目名称:clang,代码行数:54,代码来源:NoReturnFunctionChecker.cpp

示例10: isCollectionCountMethod

bool ObjCLoopChecker::isCollectionCountMethod(const ObjCMethodCall &M,
                                              CheckerContext &C) const {
  Selector S = M.getSelector();
  // Initialize the identifiers on first use.
  if (!CountSelectorII)
    CountSelectorII = &C.getASTContext().Idents.get("count");

  // If the method returns collection count, record the value.
  return S.isUnarySelector() &&
         (S.getIdentifierInfoForSlot(0) == CountSelectorII);
}
开发者ID:AntonBikineev,项目名称:clang,代码行数:11,代码来源:BasicObjCFoundationChecks.cpp

示例11: switch

/// isVariadicMessage - Returns whether the given message is a variadic message,
/// where all arguments must be Objective-C types.
bool
VariadicMethodTypeChecker::isVariadicMessage(const ObjCMethodCall &msg) const {
  const ObjCMethodDecl *MD = msg.getDecl();

  if (!MD || !MD->isVariadic() || isa<ObjCProtocolDecl>(MD->getDeclContext()))
    return false;

  Selector S = msg.getSelector();

  if (msg.isInstanceMessage()) {
    // FIXME: Ideally we'd look at the receiver interface here, but that's not
    // useful for init, because alloc returns 'id'. In theory, this could lead
    // to false positives, for example if there existed a class that had an
    // initWithObjects: implementation that does accept non-Objective-C pointer
    // types, but the chance of that happening is pretty small compared to the
    // gains that this analysis gives.
    const ObjCInterfaceDecl *Class = MD->getClassInterface();

    switch (findKnownClass(Class)) {
    case FC_NSArray:
    case FC_NSOrderedSet:
    case FC_NSSet:
      return S == initWithObjectsS;
    case FC_NSDictionary:
      return S == initWithObjectsAndKeysS;
    default:
      return false;
    }
  } else {
    const ObjCInterfaceDecl *Class = msg.getReceiverInterface();

    switch (findKnownClass(Class)) {
      case FC_NSArray:
        return S == arrayWithObjectsS;
      case FC_NSOrderedSet:
        return S == orderedSetWithObjectsS;
      case FC_NSSet:
        return S == setWithObjectsS;
      case FC_NSDictionary:
        return S == dictionaryWithObjectsAndKeysS;
      default:
        return false;
    }
  }
}
开发者ID:RichardsonAlex,项目名称:clang-1,代码行数:47,代码来源:BasicObjCFoundationChecks.cpp

示例12: WarnNilArg

void NilArgChecker::WarnNilArg(CheckerContext &C,
                               const ObjCMethodCall &msg,
                               unsigned int Arg) const
{
  if (!BT)
    BT.reset(new APIMisuse("nil argument"));
  
  if (ExplodedNode *N = C.generateSink()) {
    SmallString<128> sbuf;
    llvm::raw_svector_ostream os(sbuf);
    os << "Argument to '" << GetReceiverInterfaceName(msg) << "' method '"
       << msg.getSelector().getAsString() << "' cannot be nil";

    BugReport *R = new BugReport(*BT, os.str(), N);
    R->addRange(msg.getArgSourceRange(Arg));
    C.emitReport(R);
  }
}
开发者ID:gwelymernans,项目名称:lfort,代码行数:18,代码来源:BasicObjCFoundationChecks.cpp

示例13: checkPostObjCMessage

void NoReturnSubprogramChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
                                                   CheckerContext &C) const {
  // HACK: This entire check is to handle two messages in the Cocoa frameworks:
  // -[NSAssertionHandler
  //    handleFailureInMethod:object:file:lineNumber:description:]
  // -[NSAssertionHandler
  //    handleFailureInSubprogram:file:lineNumber:description:]
  // Eventually these should be annotated with __attribute__((noreturn)).
  // Because ObjC messages use dynamic dispatch, it is not generally safe to
  // assume certain methods can't return. In cases where it is definitely valid,
  // see if you can mark the methods noreturn or analyzer_noreturn instead of
  // adding more explicit checks to this method.

  if (!Msg.isInstanceMessage())
    return;

  const ObjCInterfaceDecl *Receiver = Msg.getReceiverInterface();
  if (!Receiver)
    return;
  if (!Receiver->getIdentifier()->isStr("NSAssertionHandler"))
    return;

  Selector Sel = Msg.getSelector();
  switch (Sel.getNumArgs()) {
  default:
    return;
  case 4:
    if (!isMultiArgSelector(&Sel, "handleFailureInSubprogram", "file",
                            "lineNumber", "description", NULL))
      return;
    break;
  case 5:
    if (!isMultiArgSelector(&Sel, "handleFailureInMethod", "object", "file",
                            "lineNumber", "description", NULL))
      return;
    break;
  }

  // If we got here, it's one of the messages we care about.
  C.generateSink();
}
开发者ID:gwelymernans,项目名称:lfort,代码行数:41,代码来源:NoReturnFunctionChecker.cpp

示例14: checkPreObjCMessage

void ClassReleaseChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                              CheckerContext &C) const {

  if (!BT) {
    BT.reset(new APIMisuse(
        this, "message incorrectly sent to class instead of class instance"));

    ASTContext &Ctx = C.getASTContext();
    releaseS = GetNullarySelector("release", Ctx);
    retainS = GetNullarySelector("retain", Ctx);
    autoreleaseS = GetNullarySelector("autorelease", Ctx);
    drainS = GetNullarySelector("drain", Ctx);
  }

  if (msg.isInstanceMessage())
    return;
  const ObjCInterfaceDecl *Class = msg.getReceiverInterface();
  assert(Class);

  Selector S = msg.getSelector();
  if (!(S == releaseS || S == retainS || S == autoreleaseS || S == drainS))
    return;

  if (ExplodedNode *N = C.generateNonFatalErrorNode()) {
    SmallString<200> buf;
    llvm::raw_svector_ostream os(buf);

    os << "The '";
    S.print(os);
    os << "' message should be sent to instances "
          "of class '" << Class->getName()
       << "' and not the class directly";

    auto report = llvm::make_unique<BugReport>(*BT, os.str(), N);
    report->addRange(msg.getSourceRange());
    C.emitReport(std::move(report));
  }
}
开发者ID:RichardsonAlex,项目名称:clang-1,代码行数:38,代码来源:BasicObjCFoundationChecks.cpp

示例15: checkPostObjCMessage

/// Calculate the nullability of the result of a message expr based on the
/// nullability of the receiver, the nullability of the return value, and the
/// constraints.
void NullabilityChecker::checkPostObjCMessage(const ObjCMethodCall &M,
                                              CheckerContext &C) const {
  auto Decl = M.getDecl();
  if (!Decl)
    return;
  QualType RetType = Decl->getReturnType();
  if (!RetType->isAnyPointerType())
    return;

  ProgramStateRef State = C.getState();
  if (State->get<PreconditionViolated>())
    return;

  const MemRegion *ReturnRegion = getTrackRegion(M.getReturnValue());
  if (!ReturnRegion)
    return;

  auto Interface = Decl->getClassInterface();
  auto Name = Interface ? Interface->getName() : "";
  // In order to reduce the noise in the diagnostics generated by this checker,
  // some framework and programming style based heuristics are used. These
  // heuristics are for Cocoa APIs which have NS prefix.
  if (Name.startswith("NS")) {
    // Developers rely on dynamic invariants such as an item should be available
    // in a collection, or a collection is not empty often. Those invariants can
    // not be inferred by any static analysis tool. To not to bother the users
    // with too many false positives, every item retrieval function should be
    // ignored for collections. The instance methods of dictionaries in Cocoa
    // are either item retrieval related or not interesting nullability wise.
    // Using this fact, to keep the code easier to read just ignore the return
    // value of every instance method of dictionaries.
    if (M.isInstanceMessage() && Name.find("Dictionary") != StringRef::npos) {
      State =
          State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
      C.addTransition(State);
      return;
    }
    // For similar reasons ignore some methods of Cocoa arrays.
    StringRef FirstSelectorSlot = M.getSelector().getNameForSlot(0);
    if (Name.find("Array") != StringRef::npos &&
        (FirstSelectorSlot == "firstObject" ||
         FirstSelectorSlot == "lastObject")) {
      State =
          State->set<NullabilityMap>(ReturnRegion, Nullability::Contradicted);
      C.addTransition(State);
      return;
    }

    // Encoding related methods of string should not fail when lossless
    // encodings are used. Using lossless encodings is so frequent that ignoring
    // this class of methods reduced the emitted diagnostics by about 30% on
    // some projects (and all of that was false positives).
    if (Name.find("String") != StringRef::npos) {
      for (auto Param : M.parameters()) {
        if (Param->getName() == "encoding") {
          State = State->set<NullabilityMap>(ReturnRegion,
                                             Nullability::Contradicted);
          C.addTransition(State);
          return;
        }
      }
    }
  }

  const ObjCMessageExpr *Message = M.getOriginExpr();
  Nullability SelfNullability = getReceiverNullability(M, State);

  const NullabilityState *NullabilityOfReturn =
      State->get<NullabilityMap>(ReturnRegion);

  if (NullabilityOfReturn) {
    // When we have a nullability tracked for the return value, the nullability
    // of the expression will be the most nullable of the receiver and the
    // return value.
    Nullability RetValTracked = NullabilityOfReturn->getValue();
    Nullability ComputedNullab =
        getMostNullable(RetValTracked, SelfNullability);
    if (ComputedNullab != RetValTracked &&
        ComputedNullab != Nullability::Unspecified) {
      const Stmt *NullabilitySource =
          ComputedNullab == RetValTracked
              ? NullabilityOfReturn->getNullabilitySource()
              : Message->getInstanceReceiver();
      State = State->set<NullabilityMap>(
          ReturnRegion, NullabilityState(ComputedNullab, NullabilitySource));
      C.addTransition(State);
    }
    return;
  }

  // No tracked information. Use static type information for return value.
  Nullability RetNullability = getNullabilityAnnotation(RetType);

  // Properties might be computed. For this reason the static analyzer creates a
  // new symbol each time an unknown property  is read. To avoid false pozitives
  // do not treat unknown properties as nullable, even when they explicitly
  // marked nullable.
//.........这里部分代码省略.........
开发者ID:Distrotech,项目名称:clang,代码行数:101,代码来源:NullabilityChecker.cpp


注:本文中的ObjCMethodCall::getSelector方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。