Beispiel #1
0
const EnumCache::EnumValues* EnumCache::loadEnumValues(const Class* klass,
                                                       bool recurse) {
  auto const numConstants = klass->numConstants();
  size_t foundOnClass = 0;
  Array values;
  Array names;
  auto const consts = klass->constants();
  for (size_t i = 0; i < numConstants; i++) {
    if (consts[i].isAbstract() || consts[i].isType()) {
      continue;
    }
    if (consts[i].m_class == klass) foundOnClass++;
    else if (!recurse) continue;
    Cell value = consts[i].m_val;
    // Handle dynamically set constants
    if (value.m_type == KindOfUninit) {
      value = klass->clsCnsGet(consts[i].m_name);
    }
    assert(value.m_type != KindOfUninit);
    if (UNLIKELY(!(isIntType(value.m_type) ||
        (tvIsString(&value) && value.m_data.pstr->isStatic())))) {
      // only int and string values allowed for enums. Moreover the strings
      // must be static
      std::string msg;
      msg += klass->name()->data();
      msg += " enum can only contain static string and int values";
      EnumCache::failLookup(msg);
    }
    values.set(StrNR(consts[i].m_name), cellAsCVarRef(value));
    names.set(cellAsCVarRef(value), VarNR(consts[i].m_name));
  }
  if (UNLIKELY(foundOnClass == 0)) {
    std::string msg;
    msg += klass->name()->data();
    msg += " enum must contain values";
    EnumCache::failLookup(msg);
  }

  {
    std::unique_ptr<EnumCache::EnumValues> enums(new EnumCache::EnumValues());
    enums->values = ArrayData::GetScalarArray(values.get());
    enums->names = ArrayData::GetScalarArray(names.get());

    intptr_t key = getKey(klass, recurse);
    EnumValuesMap::accessor acc;
    if (!m_enumValuesMap.insert(acc, key)) {
      return acc->second;
    }
    // add to the map the newly created values
    acc->second = enums.release();
    return acc->second;
  }
}
Beispiel #2
0
const EnumValues* EnumCache::cachePersistentEnumValues(
  const Class* klass,
  bool recurse,
  Array&& names,
  Array&& values) {
  std::unique_ptr<EnumValues> enums(new EnumValues());
  enums->values = ArrayData::GetScalarArray(values.get());
  enums->names = ArrayData::GetScalarArray(names.get());
  if (!recurse) {
    return const_cast<Class*>(klass)->setEnumValues(enums.release());
  }
  intptr_t key = getKey(klass, recurse);
  EnumValuesMap::accessor acc;
  if (!m_enumValuesMap.insert(acc, key)) {
    return acc->second;
  }
  // add to the map the newly created values
  acc->second = enums.release();
  return acc->second;
}
Beispiel #3
0
QList<Section> QsCodeMarker::sections( const InnerNode *inner, SynopsisStyle style, Status status )
{
    QList<Section> sections;

    if (inner->type() != Node::Class)
        return sections;

    const ClassNode *classe = static_cast<const ClassNode *>(inner);

    if ( style == Summary ) {
	FastSection enums(classe, "Enums", "", "enum", "enums");
	FastSection functions(classe, "Functions", "", "function", "functions");
	FastSection readOnlyProperties(classe, "", "Read-Only Properties", "property", "properties");
	FastSection signalz(classe, "Signals", "", "signal", "signals");
	FastSection writableProperties(classe, "", "Writable Properties", "property", "properties");

	QStack<const ClassNode *> stack;
	stack.push( classe );

	while ( !stack.isEmpty() ) {
	    const ClassNode *ancestorClass = stack.pop();

	    NodeList::ConstIterator c = ancestorClass->childNodes().begin();
	    while ( c != ancestorClass->childNodes().end() ) {
		if ( (*c)->access() == Node::Public ) {
		    if ( (*c)->type() == Node::Enum ) {
			insert( enums, *c, style, status );
		    } else if ( (*c)->type() == Node::Function ) {
			const FunctionNode *func = (const FunctionNode *) *c;
			if ( func->metaness() == FunctionNode::Signal ) {
			    insert( signalz, *c, style, status );
			} else {
			    insert( functions, *c, style, status );
			}
		    } else if ( (*c)->type() == Node::Property ) {
			const PropertyNode *property =
				(const PropertyNode *) *c;
			if ( property->setters().isEmpty() ) {
			    insert( readOnlyProperties, *c, style, status );
			} else {
			    insert( writableProperties, *c, style, status );
			}
		    }
		}
		++c;
	    }

	    QList<RelatedClass>::ConstIterator r = ancestorClass->baseClasses().begin();
	    while ( r != ancestorClass->baseClasses().end() ) {
		stack.prepend( (*r).node );
		++r;
	    }
	}
	append( sections, enums );
	append( sections, writableProperties );
	append( sections, readOnlyProperties );
	append( sections, functions );
	append( sections, signalz );
    } else if ( style == Detailed ) {
	FastSection enums( classe, "Enum Documentation", "", "member", "members");
	FastSection functionsAndSignals( classe, "Function and Signal Documentation", "", "member", "members");
	FastSection properties( classe, "Property Documentation", "", "member", "members");

	NodeList::ConstIterator c = classe->childNodes().begin();
	while ( c != classe->childNodes().end() ) {
	    if ( (*c)->access() == Node::Public ) {
		if ( (*c)->type() == Node::Enum ) {
		    insert( enums, *c, style, status );
		} else if ( (*c)->type() == Node::Function ) {
		    insert( functionsAndSignals, *c, style, status );
		} else if ( (*c)->type() == Node::Property ) {
		    insert( properties, *c, style, status );
		}
	    }
	    ++c;
	}
	append( sections, enums );
	append( sections, properties );
	append( sections, functionsAndSignals );
    } else { // ( style == SeparateList )
	FastSection all(classe, "", "", "member", "members");

	QStack<const ClassNode *> stack;
	stack.push( classe );

	while ( !stack.isEmpty() ) {
	    const ClassNode *ancestorClass = stack.pop();

	    NodeList::ConstIterator c = ancestorClass->childNodes().begin();
	    while ( c != ancestorClass->childNodes().end() ) {
		if ( (*c)->access() == Node::Public )
		    insert( all, *c, style, status );
		++c;
	    }

	    QList<RelatedClass>::ConstIterator r = ancestorClass->baseClasses().begin();
	    while ( r != ancestorClass->baseClasses().end() ) {
		stack.prepend( (*r).node );
		++r;
	    }
	}
	append( sections, all );
    }
    return sections;
}