Exemplo n.º 1
0
QString GeneratorForCallGenerator::commonGeneratedString(const QSharedPointer<ElementIdentifier> &calledIdentifier
		, const QSharedPointer<Identifier> &generatorNameNode
		, const GeneratorConfigurer &generatorConfigurer
		, ScopeInfo &scopeInfo)
{
	const auto currentElementId = GeneratorForElementIdentifierNode::neededElementId(calledIdentifier
			, generatorConfigurer, scopeInfo);
	const auto currentElementType = TypeQualifier::elementIdentifierType(calledIdentifier
			, generatorConfigurer, scopeInfo);

	const auto diagramId = generatorConfigurer.diagramId();
	const auto editorManagerInterface = generatorConfigurer.editorManagerInterface();

	const auto elementIdInMetamodel = idInMetamodel(editorManagerInterface, currentElementType, diagramId);

	const auto generationRuleForCurrentElement = editorManagerInterface->generationRule(elementIdInMetamodel);
	QSharedPointer<Node> generatedTree = TreeGeneratorFromString::generatedTreeFromString(generationRuleForCurrentElement);

	scopeInfo.currentScope().changeCurrentId(currentElementId);

	QString resultOfGeneration = "";
	if (!generatorNameNode) {
		resultOfGeneration = CommonGenerator::generatedResult(generatedTree, generatorConfigurer, scopeInfo);
	} else {
		QString generatorName = generatorNameNode->name();
		scopeInfo.currentScope().changeCurrentGeneratorName(generatorName);

		resultOfGeneration = CommonGenerator::generatedResult(generatedTree, generatorConfigurer, scopeInfo);
	}

	scopeInfo.currentScope().removeLastCurrentId();

	return resultOfGeneration;
}
qReal::Id GeneratorForElementIdentifierNode::neededElementId(
		const QSharedPointer<ElementIdentifier> &elementIdentifierNode
		, const GeneratorConfigurer &generatorConfigurer
		, ScopeInfo &scopeInfo)
{
	const auto identifierPart = elementIdentifierNode->identifierPart();
	const auto optionalTransitionPart = elementIdentifierNode->optionalTransitionPart();

	const auto logicalModelInterface = generatorConfigurer.logicalModelInterface();

	qReal::Id elementId;
	if (identifierPart->is<Identifier>()) {
		elementId = scopeInfo.variablesTable().currentId(qrtext::as<Identifier>(identifierPart)->name());
	} else {
		elementId = scopeInfo.currentScope().currentId();
	}

	if (optionalTransitionPart) {
		// we have to return transitionEnd or transitionStart for this element
		if (optionalTransitionPart->is<TransitionEnd>()) {
			return logicalModelInterface->to(elementId);
		} else if (optionalTransitionPart->is<TransitionStart>()) {
			return logicalModelInterface->from(elementId);
		} else {
			// TODO: throw exception
			qDebug() << "ERROR";
			return qReal::Id::rootId();
		}
	} else {
		return elementId;
	}
}
Exemplo n.º 3
0
    //
    // Create scope info for an outer scope.
    //
    ScopeInfo* ScopeInfo::FromScope(ByteCodeGenerator* byteCodeGenerator, FunctionBody* parent, Scope* scope, ScriptContext *scriptContext)
    {
        int count = scope->Count();

        // Add argsPlaceHolder which includes same name args and destructuring patterns on parameters
        AddSlotCount(count, scope->GetFunc()->argsPlaceHolderSlotCount);
        AddSlotCount(count, scope->GetFunc()->thisScopeSlot != Js::Constants::NoRegister ? 1 : 0);
        AddSlotCount(count, scope->GetFunc()->newTargetScopeSlot != Js::Constants::NoRegister ? 1 : 0);

        ScopeInfo* scopeInfo = RecyclerNewPlusZ(scriptContext->GetRecycler(),
            count * sizeof(SymbolInfo),
            ScopeInfo, parent, count);
        scopeInfo->isDynamic = scope->GetIsDynamic();
        scopeInfo->isObject = scope->GetIsObject();
        scopeInfo->mustInstantiate = scope->GetMustInstantiate();
        scopeInfo->isCached = (scope->GetFunc()->GetBodyScope() == scope) && scope->GetFunc()->GetHasCachedScope();
        scopeInfo->isGlobalEval = scope->GetScopeType() == ScopeType_GlobalEvalBlock;
        scopeInfo->canMergeWithBodyScope = scope->GetCanMergeWithBodyScope();
        scopeInfo->hasLocalInClosure = scope->GetHasOwnLocalInClosure();

        TRACE_BYTECODE(_u("\nSave ScopeInfo: %s parent: %s #symbols: %d %s\n"),
            scope->GetFunc()->name, parent->GetDisplayName(), count, scopeInfo->isObject ? _u("isObject") : _u(""));

        MapSymbolData mapSymbolData = { byteCodeGenerator, scope->GetFunc() };
        scope->ForEachSymbol([&mapSymbolData, scopeInfo, scope](Symbol * sym)
        {
            Assert(scope == sym->GetScope());
            scopeInfo->SaveSymbolInfo(sym, &mapSymbolData);
        });

        return scopeInfo;
    }
Exemplo n.º 4
0
    //
    // Save scope info for an outer func which has deferred child.
    //
    void ScopeInfo::SaveScopeInfo(ByteCodeGenerator* byteCodeGenerator, FuncInfo* parentFunc, FuncInfo* func)
    {
        ParseableFunctionInfo* funcBody = func->byteCodeFunction;

        Assert((!func->IsGlobalFunction() || byteCodeGenerator->GetFlags() & fscrEvalCode) &&
            (func->HasDeferredChild() || (funcBody->IsReparsed())));

        // If we are reparsing a deferred function, we already have correct "parent" info in
        // funcBody->scopeInfo. parentFunc is the knopProg shell and should not be used in this
        // case. We should use existing parent if available.
        FunctionBody * parent = funcBody->GetScopeInfo() ?
            funcBody->GetScopeInfo()->GetParent() :
            parentFunc ? parentFunc->byteCodeFunction->GetFunctionBody() : nullptr;

        ScopeInfo* funcExprScopeInfo = nullptr;
        Scope* funcExprScope = func->GetFuncExprScope();
        if (funcExprScope && funcExprScope->GetMustInstantiate())
        {
            funcExprScopeInfo = FromScope(byteCodeGenerator, parent, funcExprScope, funcBody->GetScriptContext());
        }

        Scope* bodyScope = func->IsGlobalFunction() ? func->GetGlobalEvalBlockScope() : func->GetBodyScope();
        ScopeInfo* paramScopeInfo = nullptr;
        Scope* paramScope = func->GetParamScope();
        if (paramScope && bodyScope->GetMustInstantiate())
        {
            paramScopeInfo = FromScope(byteCodeGenerator, parent, paramScope, funcBody->GetScriptContext());
        }

        ScopeInfo* scopeInfo = FromScope(byteCodeGenerator, parent, bodyScope, funcBody->GetScriptContext());
        scopeInfo->SetFuncExprScopeInfo(funcExprScopeInfo);
        scopeInfo->SetParamScopeInfo(paramScopeInfo);

        funcBody->SetScopeInfo(scopeInfo);
    }
Exemplo n.º 5
0
bool Qualify0(ScopeInfo& nf, const String& type, const String& usings, String& qt)
{ // Qualify single type based on scoping information
	const Vector<String>& nd = nf.GetScopes(usings);
	if(nd.GetCount()) {
		LTIMING("First test");
		qt = nd[0] + type;
		if(nf.base.Find(qt) >= 0)
			return true;
	}
	if(nf.GetScope() >= 0) {
		int q = type.ReverseFind(':');
		if(q > 0) {
			LTIMING("Qualifying qualification");
			ScopeInfo hnf(nf);
			hnf.NoBases();
			String qn;
			String qs = type.Mid(0, q - 1);
			if(IsDigit(*qs)) {
				qt = type;
				return true;
			}
			if(DoQualify(hnf, qs, usings, qn)) {
				String tp = type.Mid(q + 1);
				if(nf.base.Find(qn) >= 0) {
					qt = qn + "::" + tp;
					return true;
				}
				int scopei = nf.base.Find(qn);
				if(scopei >= 0) {
					ScopeInfo nnf(nf.base, scopei);
					const Vector<String>& bs = nnf.GetBases();
					for(int i = 0; i < bs.GetCount(); i++) {
						qt = bs[i] + tp;
						if(nf.base.Find(qt) >= 0)
							return true;
					}
				}
			}
			if(nf.base.Find(qs) >= 0) {
				qt = qs;
				return true;
			}
			qt = type;
			if(nf.base.Find(qt) >= 0) // e.g. std::string
				return true;
			qt = type.Mid(q + 1);
			return true;
		}
		else {
			LTIMING("Bases");
			const Vector<String>& bs = nf.GetBases();
			for(int i = 0; i < bs.GetCount(); i++) {
				qt = bs[i] + type;
				if(nf.base.Find(qt) >= 0)
					return true;
			}
		}
	}
	if(type[0] != ':') {
		LTIMING("Testing scopes");
		for(int i = 1; i < nd.GetCount(); i++) {
			qt = nd[i] + type;
			if(nf.base.Find(qt) >= 0)
				return true;
		}
	}
	int q = type.Find(':');
	if(q < 0)
		return false;
	return Qualify0(nf, type.Mid(q + 1), usings, qt);
}