Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret) { int errors = 0; //printf("StructInitializer::semantic(t = %s) %s\n", t->toChars(), toChars()); vars.setDim(field.dim); t = t->toBasetype(); if (t->ty == Tstruct) { unsigned fieldi = 0; TypeStruct *ts = (TypeStruct *)t; ad = ts->sym; if (ad->ctor) error(loc, "%s %s has constructors, cannot use { initializers }, use %s( initializers ) instead", ad->kind(), ad->toChars(), ad->toChars()); size_t nfields = ad->fields.dim; if (((StructDeclaration *)ad)->isnested) nfields--; for (size_t i = 0; i < field.dim; i++) { Identifier *id = field.tdata()[i]; Initializer *val = value.tdata()[i]; Dsymbol *s; VarDeclaration *v; if (id == NULL) { if (fieldi >= nfields) { error(loc, "too many initializers for %s", ad->toChars()); errors = 1; field.remove(i); i--; continue; } else { s = ad->fields.tdata()[fieldi]; } } else { //s = ad->symtab->lookup(id); s = ad->search(loc, id, 0); if (!s) { error(loc, "'%s' is not a member of '%s'", id->toChars(), t->toChars()); errors = 1; continue; } // Find out which field index it is for (fieldi = 0; 1; fieldi++) { if (fieldi >= nfields) { error(loc, "%s.%s is not a per-instance initializable field", t->toChars(), s->toChars()); errors = 1; break; } if (s == ad->fields.tdata()[fieldi]) break; } } if (s && (v = s->isVarDeclaration()) != NULL) { val = val->semantic(sc, v->type, needInterpret); value.tdata()[i] = val; vars.tdata()[i] = v; } else { error(loc, "%s is not a field of %s", id ? id->toChars() : s->toChars(), ad->toChars()); errors = 1; } fieldi++; } } else if (t->ty == Tdelegate && value.dim == 0) { /* Rewrite as empty delegate literal { } */ Parameters *arguments = new Parameters; Type *tf = new TypeFunction(arguments, NULL, 0, LINKd); FuncLiteralDeclaration *fd = new FuncLiteralDeclaration(loc, 0, tf, TOKdelegate, NULL); fd->fbody = new CompoundStatement(loc, new Statements()); fd->endloc = loc; Expression *e = new FuncExp(loc, fd); ExpInitializer *ie = new ExpInitializer(loc, e); return ie->semantic(sc, t, needInterpret); } else { error(loc, "a struct is not a valid initializer for a %s", t->toChars()); errors = 1; } if (errors) { field.setDim(0); value.setDim(0); vars.setDim(0); } return this; }
size_t Structure::put(const Identifier& propertyName, unsigned attributes, JSCell* specificValue) { ASSERT(!propertyName.isNull()); ASSERT(get(propertyName) == notFound); checkConsistency(); if (attributes & DontEnum) m_hasNonEnumerableProperties = true; UString::Rep* rep = propertyName._ustring.rep(); if (!m_propertyTable) createPropertyMapHashTable(); // FIXME: Consider a fast case for tables with no deleted sentinels. unsigned i = rep->existingHash(); unsigned k = 0; bool foundDeletedElement = false; unsigned deletedElementIndex = 0; // initialize to make the compiler happy #if DUMP_PROPERTYMAP_STATS ++numProbes; #endif while (1) { unsigned entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; if (entryIndex == emptyEntryIndex) break; if (entryIndex == deletedSentinelIndex) { // If we find a deleted-element sentinel, remember it for use later. if (!foundDeletedElement) { foundDeletedElement = true; deletedElementIndex = i; } } if (k == 0) { k = 1 | doubleHash(rep->existingHash()); #if DUMP_PROPERTYMAP_STATS ++numCollisions; #endif } i += k; #if DUMP_PROPERTYMAP_STATS ++numRehashes; #endif } // Figure out which entry to use. unsigned entryIndex = m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount + 2; if (foundDeletedElement) { i = deletedElementIndex; --m_propertyTable->deletedSentinelCount; // Since we're not making the table bigger, we can't use the entry one past // the end that we were planning on using, so search backwards for the empty // slot that we can use. We know it will be there because we did at least one // deletion in the past that left an entry empty. while (m_propertyTable->entries()[--entryIndex - 1].key) { } } // Create a new hash table entry. m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = entryIndex; // Create a new hash table entry. rep->ref(); m_propertyTable->entries()[entryIndex - 1].key = rep; m_propertyTable->entries()[entryIndex - 1].attributes = attributes; m_propertyTable->entries()[entryIndex - 1].specificValue = specificValue; m_propertyTable->entries()[entryIndex - 1].index = ++m_propertyTable->lastIndexUsed; unsigned newOffset; if (m_propertyTable->deletedOffsets && !m_propertyTable->deletedOffsets->isEmpty()) { newOffset = m_propertyTable->deletedOffsets->last(); m_propertyTable->deletedOffsets->removeLast(); } else newOffset = m_propertyTable->keyCount + m_propertyTable->anonymousSlotCount; m_propertyTable->entries()[entryIndex - 1].offset = newOffset; ++m_propertyTable->keyCount; if ((m_propertyTable->keyCount + m_propertyTable->deletedSentinelCount) * 2 >= m_propertyTable->size) expandPropertyMapHashTable(); checkConsistency(); return newOffset; }
AST::AST(){ root = new PackageDeclaration(NULL, NULL, SourceLocation(), DeclarationQualifier()); Identifier *id = root->getScope()->getInScope("__root"); id->addDeclaration(root, Identifier::ID_PACKAGE); root->identifier = id; //XXX bit hacky }
bool JSDOMWindow::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { // Never allow cross-domain getOwnPropertyDescriptor if (!allowsAccessFrom(exec)) return false; const HashEntry* entry; // We don't want any properties other than "close" and "closed" on a closed window. if (!impl()->frame()) { // The following code is safe for cross-domain and same domain use. // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype). entry = s_info.propHashTable(exec)->entry(exec, propertyName); if (entry && !(entry->attributes() & Function) && entry->propertyGetter() == jsDOMWindowClosed) { descriptor.setDescriptor(jsBoolean(true), ReadOnly | DontDelete | DontEnum); return true; } entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry && (entry->attributes() & Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) { PropertySlot slot; slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); return true; } descriptor.setUndefined(); return true; } entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { PropertySlot slot; slot.setCustom(this, entry->propertyGetter()); descriptor.setDescriptor(slot.getValue(exec, propertyName), entry->attributes()); return true; } // Check for child frames by name before built-in properties to // match Mozilla. This does not match IE, but some sites end up // naming frames things that conflict with window properties that // are in Moz but not IE. Since we have some of these, we have to do // it the Moz way. if (impl()->frame()->tree()->child(identifierToAtomicString(propertyName))) { PropertySlot slot; slot.setCustom(this, childFrameGetter); descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); return true; } bool ok; unsigned i = propertyName.toArrayIndex(ok); if (ok && i < impl()->frame()->tree()->childCount()) { PropertySlot slot; slot.setCustomIndex(this, i, indexGetter); descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); return true; } // Allow shortcuts like 'Image1' instead of document.images.Image1 Document* document = impl()->frame()->document(); if (document->isHTMLDocument()) { AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName); if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) { PropertySlot slot; slot.setCustom(this, namedItemGetter); descriptor.setDescriptor(slot.getValue(exec, propertyName), ReadOnly | DontDelete | DontEnum); return true; } } return Base::getOwnPropertyDescriptor(exec, propertyName, descriptor); }
Expression *semanticTraits(TraitsExp *e, Scope *sc) { #if LOGSEMANTIC printf("TraitsExp::semantic() %s\n", e->toChars()); #endif if (e->ident != Id::compiles && e->ident != Id::isSame && e->ident != Id::identifier && e->ident != Id::getProtection) { if (!TemplateInstance::semanticTiargs(e->loc, sc, e->args, 1)) return new ErrorExp(); } size_t dim = e->args ? e->args->dim : 0; if (e->ident == Id::isArithmetic) { return isTypeX(e, &isTypeArithmetic); } else if (e->ident == Id::isFloating) { return isTypeX(e, &isTypeFloating); } else if (e->ident == Id::isIntegral) { return isTypeX(e, &isTypeIntegral); } else if (e->ident == Id::isScalar) { return isTypeX(e, &isTypeScalar); } else if (e->ident == Id::isUnsigned) { return isTypeX(e, &isTypeUnsigned); } else if (e->ident == Id::isAssociativeArray) { return isTypeX(e, &isTypeAssociativeArray); } else if (e->ident == Id::isStaticArray) { return isTypeX(e, &isTypeStaticArray); } else if (e->ident == Id::isAbstractClass) { return isTypeX(e, &isTypeAbstractClass); } else if (e->ident == Id::isFinalClass) { return isTypeX(e, &isTypeFinalClass); } else if (e->ident == Id::isPOD) { if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Type *t = isType(o); StructDeclaration *sd; if (!t) { e->error("type expected as second argument of __traits %s instead of %s", e->ident->toChars(), o->toChars()); goto Lfalse; } Type *tb = t->baseElemOf(); if (tb->ty == Tstruct && ((sd = (StructDeclaration *)(((TypeStruct *)tb)->sym)) != NULL)) { if (sd->isPOD()) goto Ltrue; else goto Lfalse; } goto Ltrue; } else if (e->ident == Id::isNested) { if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); AggregateDeclaration *a; FuncDeclaration *f; if (!s) { } else if ((a = s->isAggregateDeclaration()) != NULL) { if (a->isNested()) goto Ltrue; else goto Lfalse; } else if ((f = s->isFuncDeclaration()) != NULL) { if (f->isNested()) goto Ltrue; else goto Lfalse; } e->error("aggregate or function expected instead of '%s'", o->toChars()); goto Lfalse; } else if (e->ident == Id::isAbstractFunction) { return isFuncX(e, &isFuncAbstractFunction); } else if (e->ident == Id::isVirtualFunction) { return isFuncX(e, &isFuncVirtualFunction); } else if (e->ident == Id::isVirtualMethod) { return isFuncX(e, &isFuncVirtualMethod); } else if (e->ident == Id::isFinalFunction) { return isFuncX(e, &isFuncFinalFunction); } else if (e->ident == Id::isOverrideFunction) { return isFuncX(e, &isFuncOverrideFunction); } else if (e->ident == Id::isStaticFunction) { return isFuncX(e, &isFuncStaticFunction); } else if (e->ident == Id::isRef) { return isDeclX(e, &isDeclRef); } else if (e->ident == Id::isOut) { return isDeclX(e, &isDeclOut); } else if (e->ident == Id::isLazy) { return isDeclX(e, &isDeclLazy); } else if (e->ident == Id::identifier) { // Get identifier for symbol as a string literal /* Specify 0 for bit 0 of the flags argument to semanticTiargs() so that * a symbol should not be folded to a constant. * Bit 1 means don't convert Parameter to Type if Parameter has an identifier */ if (!TemplateInstance::semanticTiargs(e->loc, sc, e->args, 2)) return new ErrorExp(); if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Parameter *po = isParameter(o); Identifier *id; if (po) { id = po->ident; assert(id); } else { Dsymbol *s = getDsymbol(o); if (!s || !s->ident) { e->error("argument %s has no identifier", o->toChars()); goto Lfalse; } id = s->ident; } StringExp *se = new StringExp(e->loc, id->toChars()); return se->semantic(sc); } else if (e->ident == Id::getProtection) { if (dim != 1) goto Ldimerror; Scope *sc2 = sc->push(); sc2->flags = sc->flags | SCOPEnoaccesscheck; bool ok = TemplateInstance::semanticTiargs(e->loc, sc2, e->args, 1); sc2->pop(); if (!ok) return new ErrorExp(); RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); if (!s) { if (!isError(o)) e->error("argument %s has no protection", o->toChars()); goto Lfalse; } if (s->scope) s->semantic(s->scope); PROT protection = s->prot(); const char *protName = Pprotectionnames[protection]; assert(protName); StringExp *se = new StringExp(e->loc, (char *) protName); return se->semantic(sc); } else if (e->ident == Id::parent) { if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); if (s) { if (FuncDeclaration *fd = s->isFuncDeclaration()) // Bugzilla 8943 s = fd->toAliasFunc(); if (!s->isImport()) // Bugzilla 8922 s = s->toParent(); } if (!s || s->isImport()) { e->error("argument %s has no parent", o->toChars()); goto Lfalse; } if (FuncDeclaration *f = s->isFuncDeclaration()) { if (TemplateDeclaration *td = getFuncTemplateDecl(f)) { if (td->overroot) // if not start of overloaded list of TemplateDeclaration's td = td->overroot; // then get the start Expression *ex = new TemplateExp(e->loc, td, f); ex = ex->semantic(sc); return ex; } if (FuncLiteralDeclaration *fld = f->isFuncLiteralDeclaration()) { // Directly translate to VarExp instead of FuncExp Expression *ex = new VarExp(e->loc, fld, 1); return ex->semantic(sc); } } return (new DsymbolExp(e->loc, s))->semantic(sc); } else if (e->ident == Id::hasMember || e->ident == Id::getMember || e->ident == Id::getOverloads || e->ident == Id::getVirtualMethods || e->ident == Id::getVirtualFunctions) { if (dim != 2) goto Ldimerror; RootObject *o = (*e->args)[0]; Expression *ex = isExpression((*e->args)[1]); if (!ex) { e->error("expression expected as second argument of __traits %s", e->ident->toChars()); goto Lfalse; } ex = ex->ctfeInterpret(); StringExp *se = ex->toStringExp(); if (!se || se->length() == 0) { e->error("string expected as second argument of __traits %s instead of %s", e->ident->toChars(), ex->toChars()); goto Lfalse; } se = se->toUTF8(sc); if (se->sz != 1) { e->error("string must be chars"); goto Lfalse; } Identifier *id = Lexer::idPool((char *)se->string); /* Prefer dsymbol, because it might need some runtime contexts. */ Dsymbol *sym = getDsymbol(o); if (sym) { ex = new DsymbolExp(e->loc, sym); ex = new DotIdExp(e->loc, ex, id); } else if (Type *t = isType(o)) ex = typeDotIdExp(e->loc, t, id); else if (Expression *ex2 = isExpression(o)) ex = new DotIdExp(e->loc, ex2, id); else { e->error("invalid first argument"); goto Lfalse; } if (e->ident == Id::hasMember) { if (sym) { Dsymbol *sm = sym->search(e->loc, id); if (sm) goto Ltrue; } /* Take any errors as meaning it wasn't found */ Scope *sc2 = sc->push(); ex = ex->trySemantic(sc2); sc2->pop(); if (!ex) goto Lfalse; else goto Ltrue; } else if (e->ident == Id::getMember) { ex = ex->semantic(sc); return ex; } else if (e->ident == Id::getVirtualFunctions || e->ident == Id::getVirtualMethods || e->ident == Id::getOverloads) { unsigned errors = global.errors; Expression *eorig = ex; ex = ex->semantic(sc); if (errors < global.errors) e->error("%s cannot be resolved", eorig->toChars()); /* Create tuple of functions of ex */ //ex->print(); Expressions *exps = new Expressions(); FuncDeclaration *f; if (ex->op == TOKvar) { VarExp *ve = (VarExp *)ex; f = ve->var->isFuncDeclaration(); ex = NULL; } else if (ex->op == TOKdotvar) { DotVarExp *dve = (DotVarExp *)ex; f = dve->var->isFuncDeclaration(); if (dve->e1->op == TOKdottype || dve->e1->op == TOKthis) ex = NULL; else ex = dve->e1; } else f = NULL; Ptrait p; p.exps = exps; p.e1 = ex; p.ident = e->ident; overloadApply(f, &p, &fptraits); TupleExp *tup = new TupleExp(e->loc, exps); return tup->semantic(sc); } else assert(0); } else if (e->ident == Id::classInstanceSize) { if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); ClassDeclaration *cd; if (!s || (cd = s->isClassDeclaration()) == NULL) { e->error("first argument is not a class"); goto Lfalse; } if (cd->sizeok == SIZEOKnone) { if (cd->scope) cd->semantic(cd->scope); } if (cd->sizeok != SIZEOKdone) { e->error("%s %s is forward referenced", cd->kind(), cd->toChars()); goto Lfalse; } return new IntegerExp(e->loc, cd->structsize, Type::tsize_t); } else if (e->ident == Id::getAliasThis) { if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); AggregateDeclaration *ad; if (!s || (ad = s->isAggregateDeclaration()) == NULL) { e->error("argument is not an aggregate type"); goto Lfalse; } Expressions *exps = new Expressions(); if (ad->aliasthis) exps->push(new StringExp(e->loc, ad->aliasthis->ident->toChars())); Expression *ex = new TupleExp(e->loc, exps); ex = ex->semantic(sc); return ex; } else if (e->ident == Id::getAttributes) { if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); if (!s) { #if 0 Expression *x = isExpression(o); Type *t = isType(o); if (x) printf("e = %s %s\n", Token::toChars(x->op), x->toChars()); if (t) printf("t = %d %s\n", t->ty, t->toChars()); #endif e->error("first argument is not a symbol"); goto Lfalse; } //printf("getAttributes %s, attrs = %p, scope = %p\n", s->toChars(), s->userAttributes, s->userAttributesScope); UserAttributeDeclaration *udad = s->userAttribDecl; TupleExp *tup = new TupleExp(e->loc, udad ? udad->getAttributes() : new Expressions()); return tup->semantic(sc); } else if (e->ident == Id::getFunctionAttributes) { /// extract all function attributes as a tuple (const/shared/inout/pure/nothrow/etc) except UDAs. if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); Type *t = isType(o); TypeFunction *tf = NULL; if (s) { if (FuncDeclaration *f = s->isFuncDeclaration()) t = f->type; else if (VarDeclaration *v = s->isVarDeclaration()) t = v->type; } if (t) { if (t->ty == Tfunction) tf = (TypeFunction *)t; else if (t->ty == Tdelegate) tf = (TypeFunction *)t->nextOf(); else if (t->ty == Tpointer && t->nextOf()->ty == Tfunction) tf = (TypeFunction *)t->nextOf(); } if (!tf) { e->error("first argument is not a function"); goto Lfalse; } Expressions *mods = new Expressions(); PushAttributes pa; pa.mods = mods; tf->modifiersApply(&pa, &PushAttributes::fp); tf->attributesApply(&pa, &PushAttributes::fp, TRUSTformatSystem); TupleExp *tup = new TupleExp(e->loc, mods); return tup->semantic(sc); } else if (e->ident == Id::allMembers || e->ident == Id::derivedMembers) { if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); ScopeDsymbol *sds; if (!s) { e->error("argument has no members"); goto Lfalse; } Import *import; if ((import = s->isImport()) != NULL) { // Bugzilla 9692 sds = import->mod; } else if ((sds = s->isScopeDsymbol()) == NULL) { e->error("%s %s has no members", s->kind(), s->toChars()); goto Lfalse; } // use a struct as local function struct PushIdentsDg { static int dg(void *ctx, size_t n, Dsymbol *sm) { if (!sm) return 1; //printf("\t[%i] %s %s\n", i, sm->kind(), sm->toChars()); if (sm->ident) { if (sm->ident != Id::ctor && sm->ident != Id::dtor && sm->ident != Id::_postblit && memcmp(sm->ident->string, "__", 2) == 0) { return 0; } //printf("\t%s\n", sm->ident->toChars()); Identifiers *idents = (Identifiers *)ctx; /* Skip if already present in idents[] */ for (size_t j = 0; j < idents->dim; j++) { Identifier *id = (*idents)[j]; if (id == sm->ident) return 0; #ifdef DEBUG // Avoid using strcmp in the first place due to the performance impact in an O(N^2) loop. assert(strcmp(id->toChars(), sm->ident->toChars()) != 0); #endif } idents->push(sm->ident); } else { EnumDeclaration *ed = sm->isEnumDeclaration(); if (ed) { ScopeDsymbol::foreach(NULL, ed->members, &PushIdentsDg::dg, (Identifiers *)ctx); } } return 0; } }; Identifiers *idents = new Identifiers; ScopeDsymbol::foreach(sc, sds->members, &PushIdentsDg::dg, idents); ClassDeclaration *cd = sds->isClassDeclaration(); if (cd && e->ident == Id::allMembers) { struct PushBaseMembers { static void dg(ClassDeclaration *cd, Identifiers *idents) { for (size_t i = 0; i < cd->baseclasses->dim; i++) { ClassDeclaration *cb = (*cd->baseclasses)[i]->base; ScopeDsymbol::foreach(NULL, cb->members, &PushIdentsDg::dg, idents); if (cb->baseclasses->dim) dg(cb, idents); } } }; PushBaseMembers::dg(cd, idents); } // Turn Identifiers into StringExps reusing the allocated array assert(sizeof(Expressions) == sizeof(Identifiers)); Expressions *exps = (Expressions *)idents; for (size_t i = 0; i < idents->dim; i++) { Identifier *id = (*idents)[i]; StringExp *se = new StringExp(e->loc, id->toChars()); (*exps)[i] = se; } /* Making this a tuple is more flexible, as it can be statically unrolled. * To make an array literal, enclose __traits in [ ]: * [ __traits(allMembers, ...) ] */ Expression *ex = new TupleExp(e->loc, exps); ex = ex->semantic(sc); return ex; } else if (e->ident == Id::compiles) { /* Determine if all the objects - types, expressions, or symbols - * compile without error */ if (!dim) goto Lfalse; for (size_t i = 0; i < dim; i++) { unsigned errors = global.startGagging(); unsigned oldspec = global.speculativeGag; global.speculativeGag = global.gag; Scope *sc2 = sc->push(); sc2->speculative = true; sc2->flags = sc->flags & ~SCOPEctfe | SCOPEcompile; bool err = false; RootObject *o = (*e->args)[i]; Type *t = isType(o); Expression *ex = t ? t->toExpression() : isExpression(o); if (!ex && t) { Dsymbol *s; t->resolve(e->loc, sc2, &ex, &t, &s); if (t) { t->semantic(e->loc, sc2); if (t->ty == Terror) err = true; } else if (s && s->errors) err = true; } if (ex) { ex = ex->semantic(sc2); ex = resolvePropertiesOnly(sc2, ex); ex = ex->optimize(WANTvalue); ex = checkGC(sc2, ex); if (ex->op == TOKerror) err = true; } sc2->pop(); global.speculativeGag = oldspec; if (global.endGagging(errors) || err) { goto Lfalse; } } goto Ltrue; } else if (e->ident == Id::isSame) { /* Determine if two symbols are the same */ if (dim != 2) goto Ldimerror; if (!TemplateInstance::semanticTiargs(e->loc, sc, e->args, 0)) return new ErrorExp(); RootObject *o1 = (*e->args)[0]; RootObject *o2 = (*e->args)[1]; Dsymbol *s1 = getDsymbol(o1); Dsymbol *s2 = getDsymbol(o2); //printf("isSame: %s, %s\n", o1->toChars(), o2->toChars()); #if 0 printf("o1: %p\n", o1); printf("o2: %p\n", o2); if (!s1) { Expression *ea = isExpression(o1); if (ea) printf("%s\n", ea->toChars()); Type *ta = isType(o1); if (ta) printf("%s\n", ta->toChars()); goto Lfalse; } else printf("%s %s\n", s1->kind(), s1->toChars()); #endif if (!s1 && !s2) { Expression *ea1 = isExpression(o1); Expression *ea2 = isExpression(o2); if (ea1 && ea2) { if (ea1->equals(ea2)) goto Ltrue; } } if (!s1 || !s2) goto Lfalse; s1 = s1->toAlias(); s2 = s2->toAlias(); if (s1->isFuncAliasDeclaration()) s1 = ((FuncAliasDeclaration *)s1)->toAliasFunc(); if (s2->isFuncAliasDeclaration()) s2 = ((FuncAliasDeclaration *)s2)->toAliasFunc(); if (s1 == s2) goto Ltrue; else goto Lfalse; } else if (e->ident == Id::getUnitTests) { if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); if (!s) { e->error("argument %s to __traits(getUnitTests) must be a module or aggregate", o->toChars()); goto Lfalse; } Import *imp = s->isImport(); if (imp) // Bugzilla 10990 s = imp->mod; ScopeDsymbol* scope = s->isScopeDsymbol(); if (!scope) { e->error("argument %s to __traits(getUnitTests) must be a module or aggregate, not a %s", s->toChars(), s->kind()); goto Lfalse; } Expressions* unitTests = new Expressions(); Dsymbols* symbols = scope->members; if (global.params.useUnitTests && symbols) { // Should actually be a set AA* uniqueUnitTests = NULL; collectUnitTests(symbols, uniqueUnitTests, unitTests); } TupleExp *tup = new TupleExp(e->loc, unitTests); return tup->semantic(sc); } else if(e->ident == Id::getVirtualIndex) { if (dim != 1) goto Ldimerror; RootObject *o = (*e->args)[0]; Dsymbol *s = getDsymbol(o); FuncDeclaration *fd; if (!s || (fd = s->isFuncDeclaration()) == NULL) { e->error("first argument to __traits(getVirtualIndex) must be a function"); goto Lfalse; } fd = fd->toAliasFunc(); // Neccessary to support multiple overloads. return new IntegerExp(e->loc, fd->vtblIndex, Type::tptrdiff_t); } else { if (const char *sub = (const char *)speller(e->ident->toChars(), &trait_search_fp, NULL, idchars)) e->error("unrecognized trait '%s', did you mean '%s'?", e->ident->toChars(), sub); else e->error("unrecognized trait '%s'", e->ident->toChars()); goto Lfalse; } return NULL; Ldimerror: e->error("wrong number of arguments %d", (int)dim); goto Lfalse; Lfalse: return new IntegerExp(e->loc, 0, Type::tbool); Ltrue: return new IntegerExp(e->loc, 1, Type::tbool); }
Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident) { //printf("Module::load(ident = '%s')\n", ident->toChars()); // Build module filename by turning: // foo.bar.baz // into: // foo\bar\baz char *filename = ident->toChars(); if (packages && packages->dim) { OutBuffer buf; for (size_t i = 0; i < packages->dim; i++) { Identifier *pid = (*packages)[i]; buf.writestring(pid->toChars()); #if _WIN32 buf.writeByte('\\'); #else buf.writeByte('/'); #endif } buf.writestring(filename); buf.writeByte(0); filename = (char *)buf.extractData(); } Module *m = new Module(filename, ident, 0, 0); m->loc = loc; /* Look for the source file */ const char *result = lookForSourceFile(filename); if (result) m->srcfile = new File(result); if (global.params.verbose) { fprintf(global.stdmsg, "import "); if (packages) { for (size_t i = 0; i < packages->dim; i++) { Identifier *pid = (*packages)[i]; fprintf(global.stdmsg, "%s.", pid->toChars()); } } fprintf(global.stdmsg, "%s\t(%s)\n", ident->toChars(), m->srcfile->toChars()); } if (!m->read(loc)) return NULL; m->parse(); #ifdef IN_GCC d_gcc_magic_module(m); #endif return m; }
static JSValue identifierToJSValue(VM& vm, const Identifier& identifier) { if (identifier.isSymbol()) return Symbol::create(vm, static_cast<SymbolImpl&>(*identifier.impl())); return jsString(&vm, identifier.impl()); }
void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s, Pragma llvm_internal, const std::string &arg1str) { if (llvm_internal == LLVMnone || llvm_internal == LLVMignore) return; if (s->llvmInternal) { error(Loc(), "multiple LDC specific pragmas not allowed not affect the same " "declaration ('%s' at '%s')", s->toChars(), s->loc.toChars()); fatal(); } Identifier *ident = decl->ident; switch(llvm_internal) { case LLVMintrinsic: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; fd->intrinsicName = arg1str; fd->mangleOverride = strdup(fd->intrinsicName.c_str()); } else if (TemplateDeclaration* td = s->isTemplateDeclaration()) { td->llvmInternal = llvm_internal; td->intrinsicName = arg1str; } else { error(s->loc, "the '%s' pragma is only allowed on function or template declarations", ident->toChars()); fatal(); } break; case LLVMglobal_crt_ctor: case LLVMglobal_crt_dtor: if (FuncDeclaration* fd = s->isFuncDeclaration()) { assert(fd->type->ty == Tfunction); TypeFunction* type = static_cast<TypeFunction*>(fd->type); Type* retType = type->next; if (retType->ty != Tvoid || type->parameters->dim > 0 || ( fd->isAggregateMember() && !fd->isStatic())) { error(s->loc, "the '%s' pragma is only allowed on void functions which take no arguments", ident->toChars()); fd->llvmInternal = LLVMnone; break; } fd->llvmInternal = llvm_internal; fd->priority = std::atoi(arg1str.c_str()); } else { error(s->loc, "the '%s' pragma is only allowed on function declarations", ident->toChars()); s->llvmInternal = LLVMnone; } break; case LLVMatomic_rmw: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { td->llvmInternal = llvm_internal; td->intrinsicName = arg1str; } else { error(s->loc, "the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; case LLVMva_start: case LLVMva_arg: case LLVMatomic_load: case LLVMatomic_store: case LLVMatomic_cmp_xchg: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { if (td->parameters->dim != 1) { error(s->loc, "the '%s' pragma template must have exactly one template parameter", ident->toChars()); fatal(); } else if (!td->onemember) { error(s->loc, "the '%s' pragma template must have exactly one member", ident->toChars()); fatal(); } else if (td->overnext || td->overroot) { error(s->loc, "the '%s' pragma template must not be overloaded", ident->toChars()); fatal(); } td->llvmInternal = llvm_internal; } else { error(s->loc, "the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; case LLVMva_copy: case LLVMva_end: case LLVMfence: case LLVMbitop_bt: case LLVMbitop_btc: case LLVMbitop_btr: case LLVMbitop_bts: case LLVMbitop_vld: case LLVMbitop_vst: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; } else { error(s->loc, "the '%s' pragma is only allowed on function declarations", ident->toChars()); fatal(); } break; case LLVMno_typeinfo: s->llvmInternal = llvm_internal; break; case LLVMalloca: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; } else { error(s->loc, "the '%s' pragma must only be used on function declarations " "of type 'void* function(uint nbytes)'", ident->toChars()); fatal(); } break; case LLVMinline_asm: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { if (td->parameters->dim > 1) { error(s->loc, "the '%s' pragma template must have exactly zero or one " "template parameters", ident->toChars()); fatal(); } else if (!td->onemember) { error(s->loc, "the '%s' pragma template must have exactly one member", ident->toChars()); fatal(); } td->llvmInternal = llvm_internal; } else { error(s->loc, "the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; case LLVMinline_ir: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { Dsymbol* member = td->onemember; if (!member) { error(s->loc, "the '%s' pragma template must have exactly one member", ident->toChars()); fatal(); } FuncDeclaration* fun = member->isFuncDeclaration(); if (!fun) { error(s->loc, "the '%s' pragma template's member must be a function declaration", ident->toChars()); fatal(); } TemplateParameters& params = *td->parameters; bool valid_params = params.dim == 3 && params[1]->isTemplateTypeParameter() && params[2]->isTemplateTupleParameter(); if(valid_params) { TemplateValueParameter* p0 = params[0]->isTemplateValueParameter(); valid_params = valid_params && p0 && p0->valType == Type::tstring; } if(!valid_params) { error(s->loc, "the '%s' pragma template must have exactly three parameters: " "a string, a type and a type tuple", ident->toChars()); fatal(); } td->llvmInternal = llvm_internal; } else { error(s->loc, "the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; case LLVMextern_weak: if (VarDeclaration* vd = s->isVarDeclaration()) { if (!vd->isDataseg() || !(vd->storage_class & STCextern)) { error(s->loc, "'%s' requires storage class 'extern'", ident->toChars()); fatal(); } // It seems like the interaction between weak symbols and thread-local // storage is not well-defined (the address of an undefined weak TLS // symbol is non-zero on the ELF static TLS model on Linux x86_64). // Thus, just disallow this altogether. if (vd->isThreadlocal()) { error(s->loc, "'%s' cannot be applied to thread-local variable '%s'", ident->toChars(), vd->toPrettyChars()); fatal(); } vd->llvmInternal = llvm_internal; } else { // Currently, things like "pragma(LDC_extern_weak) extern int foo;" // fail because 'extern' creates an intermediate // StorageClassDeclaration. This might eventually be fixed by making // extern_weak a proper storage class. error(s->loc, "the '%s' pragma can only be specified directly on " "variable declarations for now", ident->toChars()); fatal(); } break; default: warning(s->loc, "the LDC specific pragma '%s' is not yet implemented, ignoring", ident->toChars()); } }
void JSFunction::finishCreation(ExecState* exec, NativeExecutable* executable, int length, const Identifier& name) { Base::finishCreation(exec->globalData()); ASSERT(inherits(&s_info)); m_executable.set(exec->globalData(), this, executable); putDirect(exec->globalData(), exec->globalData().propertyNames->name, jsString(exec, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); putDirect(exec->globalData(), exec->propertyNames().length, jsNumber(length), DontDelete | ReadOnly | DontEnum); }
void Converter::RenameIdent(Identifier& ident) { ident.AppendPrefix(nameMangling_.temporaryPrefix); }
Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident) { Module *m; char *filename; //printf("Module::load(ident = '%s')\n", ident->toChars()); // Build module filename by turning: // foo.bar.baz // into: // foo\bar\baz filename = ident->toChars(); if (packages && packages->dim) { OutBuffer buf; for (size_t i = 0; i < packages->dim; i++) { Identifier *pid = packages->tdata()[i]; buf.writestring(pid->toChars()); #if _WIN32 buf.writeByte('\\'); #else buf.writeByte('/'); #endif } buf.writestring(filename); buf.writeByte(0); filename = (char *)buf.extractData(); } m = new Module(filename, ident, 0, 0); m->loc = loc; /* Search along global.path for .di file, then .d file. */ char *result = NULL; FileName *fdi = FileName::forceExt(filename, global.hdr_ext); FileName *fd = FileName::forceExt(filename, global.mars_ext); char *sdi = fdi->toChars(); char *sd = fd->toChars(); if (FileName::exists(sdi)) result = sdi; else if (FileName::exists(sd)) result = sd; else if (FileName::absolute(filename)) ; else if (!global.path) ; else { for (size_t i = 0; i < global.path->dim; i++) { char *p = global.path->tdata()[i]; char *n = FileName::combine(p, sdi); if (FileName::exists(n)) { result = n; break; } mem.free(n); n = FileName::combine(p, sd); if (FileName::exists(n)) { result = n; break; } mem.free(n); } } if (result) m->srcfile = new File(result); if (global.params.verbose) { printf("import "); if (packages) { for (size_t i = 0; i < packages->dim; i++) { Identifier *pid = packages->tdata()[i]; printf("%s.", pid->toChars()); } } printf("%s\t(%s)\n", ident->toChars(), m->srcfile->toChars()); } m->read(loc); m->parse(); #ifdef IN_GCC d_gcc_magic_module(m); #endif return m; }
void DtoCheckPragma(PragmaDeclaration *decl, Dsymbol *s, Pragma llvm_internal, const std::string &arg1str) { if (llvm_internal == LLVMnone || llvm_internal == LLVMignore) return; if (s->llvmInternal) { error("multiple LDC specific pragmas not allowed not affect the same " "declaration ('%s' at '%s')", s->toChars(), s->loc.toChars()); fatal(); } Identifier *ident = decl->ident; switch(llvm_internal) { case LLVMintrinsic: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; fd->intrinsicName = arg1str; fd->linkage = LINKintrinsic; static_cast<TypeFunction*>(fd->type)->linkage = LINKintrinsic; } else if (TemplateDeclaration* td = s->isTemplateDeclaration()) { td->llvmInternal = llvm_internal; td->intrinsicName = arg1str; } else { error("only allowed on function declarations"); fatal(); } break; case LLVMglobal_crt_ctor: case LLVMglobal_crt_dtor: if (FuncDeclaration* fd = s->isFuncDeclaration()) { assert(fd->type->ty == Tfunction); TypeFunction* type = static_cast<TypeFunction*>(fd->type); Type* retType = type->next; if (retType->ty != Tvoid || type->parameters->dim > 0 || ( #if DMDV2 fd->isAggregateMember() #else fd->isThis() #endif && !fd->isStatic())) { error(fd->loc, "the '%s' pragma is only allowed on void functions which take no arguments", ident->toChars()); fd->llvmInternal = LLVMnone; break; } fd->llvmInternal = llvm_internal; fd->priority = std::atoi(arg1str.c_str()); } else { error(s->loc, "the '%s' pragma is only allowed on function declarations", ident->toChars()); s->llvmInternal = LLVMnone; } break; case LLVMatomic_rmw: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { td->llvmInternal = llvm_internal; td->intrinsicName = arg1str; } else { error("the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; case LLVMva_start: case LLVMva_arg: case LLVMatomic_load: case LLVMatomic_store: case LLVMatomic_cmp_xchg: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { if (td->parameters->dim != 1) { error("the '%s' pragma template must have exactly one template parameter", ident->toChars()); fatal(); } else if (!td->onemember) { error("the '%s' pragma template must have exactly one member", ident->toChars()); fatal(); } else if (td->overnext || td->overroot) { error("the '%s' pragma template must not be overloaded", ident->toChars()); fatal(); } td->llvmInternal = llvm_internal; } else { error("the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; case LLVMva_copy: case LLVMva_end: case LLVMfence: case LLVMbitop_bt: case LLVMbitop_btc: case LLVMbitop_btr: case LLVMbitop_bts: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; } else { error("the '%s' pragma is only allowed on function declarations", ident->toChars()); fatal(); } break; case LLVMno_typeinfo: s->llvmInternal = llvm_internal; break; case LLVMalloca: if (FuncDeclaration* fd = s->isFuncDeclaration()) { fd->llvmInternal = llvm_internal; } else { error("the '%s' pragma must only be used on function declarations " "of type 'void* function(uint nbytes)'", ident->toChars()); fatal(); } break; case LLVMinline_asm: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { if (td->parameters->dim > 1) { error("the '%s' pragma template must have exactly zero or one " "template parameters", ident->toChars()); fatal(); } else if (!td->onemember) { error("the '%s' pragma template must have exactly one member", ident->toChars()); fatal(); } td->llvmInternal = llvm_internal; } else { error("the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; case LLVMinline_ir: if (TemplateDeclaration* td = s->isTemplateDeclaration()) { Dsymbol* member = td->onemember; if (!member) { error("the '%s' pragma template must have exactly one member", ident->toChars()); fatal(); } FuncDeclaration* fun = member->isFuncDeclaration(); if (!fun) { error("the '%s' pragma template's member must be a function declaration", ident->toChars()); fatal(); } TemplateParameters& params = *td->parameters; bool valid_params = params.dim == 3 && params[1]->isTemplateTypeParameter() && params[2]->isTemplateTupleParameter(); if(valid_params) { TemplateValueParameter* p0 = params[0]->isTemplateValueParameter(); valid_params = valid_params && p0 && p0->valType == Type::tstring; } if(!valid_params) { error("the '%s' pragma template must have exactly three parameters: " "a string, a type and a type tuple", ident->toChars()); fatal(); } td->llvmInternal = llvm_internal; } else { error("the '%s' pragma is only allowed on template declarations", ident->toChars()); fatal(); } break; default: warning(Loc(), "the LDC specific pragma '%s' is not yet implemented, ignoring", ident->toChars()); } }
InternalFunction::InternalFunction(JSGlobalData* globalData, PassRefPtr<Structure> structure, const Identifier& name) : JSObject(structure) { putDirect(globalData->propertyNames->name, jsString(globalData, name.ustring()), DontDelete | ReadOnly | DontEnum); }
/*************************************** * This works by transforming a struct initializer into * a struct literal. In the future, the two should be the * same thing. */ Expression *StructInitializer::toExpression() { Expression *e; size_t offset; //printf("StructInitializer::toExpression() %s\n", toChars()); if (!ad) // if fwd referenced { return NULL; } StructDeclaration *sd = ad->isStructDeclaration(); if (!sd) return NULL; Expressions *elements = new Expressions(); size_t nfields = ad->fields.dim; #if DMDV2 if (sd->isnested) nfields--; #endif elements->setDim(nfields); for (size_t i = 0; i < elements->dim; i++) { elements->tdata()[i] = NULL; } unsigned fieldi = 0; for (size_t i = 0; i < value.dim; i++) { Identifier *id = field.tdata()[i]; if (id) { Dsymbol * s = ad->search(loc, id, 0); if (!s) { error(loc, "'%s' is not a member of '%s'", id->toChars(), sd->toChars()); goto Lno; } // Find out which field index it is for (fieldi = 0; 1; fieldi++) { if (fieldi >= nfields) { s->error("is not a per-instance initializable field"); goto Lno; } if (s == ad->fields.tdata()[fieldi]) break; } } else if (fieldi >= nfields) { error(loc, "too many initializers for '%s'", ad->toChars()); goto Lno; } Initializer *iz = value.tdata()[i]; if (!iz) goto Lno; Expression *ex = iz->toExpression(); if (!ex) goto Lno; if (elements->tdata()[fieldi]) { error(loc, "duplicate initializer for field '%s'", ad->fields.tdata()[fieldi]->toChars()); goto Lno; } elements->tdata()[fieldi] = ex; ++fieldi; } // Now, fill in any missing elements with default initializers. // We also need to validate any anonymous unions offset = 0; for (size_t i = 0; i < elements->dim; ) { VarDeclaration * vd = ad->fields.tdata()[i]->isVarDeclaration(); //printf("test2 [%d] : %s %d %d\n", i, vd->toChars(), (int)offset, (int)vd->offset); if (vd->offset < offset) { // Only the first field of a union can have an initializer if (elements->tdata()[i]) goto Lno; } else { if (!elements->tdata()[i]) // Default initialize elements->tdata()[i] = vd->type->defaultInit(); } offset = vd->offset + vd->type->size(); i++; #if 0 int unionSize = ad->numFieldsInUnion(i); if (unionSize == 1) { // Not a union -- default initialize if missing if (!elements->tdata()[i]) elements->tdata()[i] = vd->type->defaultInit(); } else { // anonymous union -- check for errors int found = -1; // index of the first field with an initializer for (int j = i; j < i + unionSize; ++j) { if (!elements->tdata()[j]) continue; if (found >= 0) { VarDeclaration * v1 = ((Dsymbol *)ad->fields.data[found])->isVarDeclaration(); VarDeclaration * v = ((Dsymbol *)ad->fields.data[j])->isVarDeclaration(); error(loc, "%s cannot have initializers for fields %s and %s in same union", ad->toChars(), v1->toChars(), v->toChars()); goto Lno; } found = j; } if (found == -1) { error(loc, "no initializer for union that contains field %s", vd->toChars()); goto Lno; } } i += unionSize; #endif } e = new StructLiteralExp(loc, sd, elements); e->type = sd->type; return e; Lno: delete elements; return NULL; }
/// Parse a function definition signature. /// func-signature: /// func-arguments func-throws? func-signature-result? /// func-signature-result: /// '->' type /// /// Note that this leaves retType as null if unspecified. ParserStatus Parser::parseFunctionSignature(Identifier SimpleName, DeclName &FullName, SmallVectorImpl<ParameterList*> &bodyParams, DefaultArgumentInfo &defaultArgs, SourceLoc &throwsLoc, bool &rethrows, TypeRepr *&retType) { SmallVector<Identifier, 4> NamePieces; NamePieces.push_back(SimpleName); FullName = SimpleName; ParserStatus Status; // We force first type of a func declaration to be a tuple for consistency. if (Tok.is(tok::l_paren)) { ParameterContextKind paramContext; if (SimpleName.isOperator()) paramContext = ParameterContextKind::Operator; else paramContext = ParameterContextKind::Function; Status = parseFunctionArguments(NamePieces, bodyParams, paramContext, defaultArgs); FullName = DeclName(Context, SimpleName, llvm::makeArrayRef(NamePieces.begin() + 1, NamePieces.end())); if (bodyParams.empty()) { // If we didn't get anything, add a () pattern to avoid breaking // invariants. assert(Status.hasCodeCompletion() || Status.isError()); bodyParams.push_back(ParameterList::createEmpty(Context)); } } else { diagnose(Tok, diag::func_decl_without_paren); Status = makeParserError(); // Recover by creating a '() -> ?' signature. bodyParams.push_back(ParameterList::createEmpty(Context, PreviousLoc, PreviousLoc)); FullName = DeclName(Context, SimpleName, bodyParams.back()); } // Check for the 'throws' keyword. rethrows = false; if (Tok.is(tok::kw_throws)) { throwsLoc = consumeToken(); } else if (Tok.is(tok::kw_rethrows)) { throwsLoc = consumeToken(); rethrows = true; } else if (Tok.is(tok::kw_throw)) { throwsLoc = consumeToken(); diagnose(throwsLoc, diag::throw_in_function_type) .fixItReplace(throwsLoc, "throws"); } SourceLoc arrowLoc; // If there's a trailing arrow, parse the rest as the result type. if (Tok.isAny(tok::arrow, tok::colon)) { if (!consumeIf(tok::arrow, arrowLoc)) { // FixIt ':' to '->'. diagnose(Tok, diag::func_decl_expected_arrow) .fixItReplace(SourceRange(Tok.getLoc()), "->"); arrowLoc = consumeToken(tok::colon); } ParserResult<TypeRepr> ResultType = parseType(diag::expected_type_function_result); if (ResultType.hasCodeCompletion()) return ResultType; retType = ResultType.getPtrOrNull(); if (!retType) { Status.setIsParseError(); return Status; } } else { // Otherwise, we leave retType null. retType = nullptr; } // Check for 'throws' and 'rethrows' after the type and correct it. if (!throwsLoc.isValid()) { if (Tok.is(tok::kw_throws)) { throwsLoc = consumeToken(); } else if (Tok.is(tok::kw_rethrows)) { throwsLoc = consumeToken(); rethrows = true; } if (throwsLoc.isValid()) { assert(arrowLoc.isValid()); assert(retType); auto diag = rethrows ? diag::rethrows_after_function_result : diag::throws_after_function_result; SourceLoc typeEndLoc = Lexer::getLocForEndOfToken(SourceMgr, retType->getEndLoc()); SourceLoc throwsEndLoc = Lexer::getLocForEndOfToken(SourceMgr, throwsLoc); diagnose(Tok, diag) .fixItInsert(arrowLoc, rethrows ? "rethrows " : "throws ") .fixItRemoveChars(typeEndLoc, throwsEndLoc); } } return Status; }
bool operator<(const KeywordBase& other) const { return identifier__.compare(other.identifier__) < 0; }
void InternalFunction::finishCreation(JSGlobalData& globalData, const Identifier& name) { Base::finishCreation(globalData); ASSERT(inherits(&s_info)); putDirect(globalData, globalData.propertyNames->name, jsString(&globalData, name.isNull() ? "" : name.ustring()), DontDelete | ReadOnly | DontEnum); }
// UDD = user defined domain // AGD = auto generated domain (those starting with RDB$) bool FieldPropertiesDialog::getStatementsToExecute(wxString& statements, bool justCheck) { wxString colNameSql(Identifier::userString(textctrl_fieldname->GetValue())); Identifier selDomain(choice_domain->GetStringSelection()); bool newDomain = getIsNewDomainSelected(); wxString selDatatype = choice_datatype->GetStringSelection(); wxString dtSize = textctrl_size->GetValue(); wxString dtScale = textctrl_scale->GetValue(); bool isNullable = !checkbox_notnull->IsChecked(); int n = choice_datatype->GetSelection(); if (n >= 0 && n < datatypescnt) { if (!datatypes[n].hasSize) dtSize.Clear(); if (!datatypes[n].hasScale) dtScale.Clear(); } wxString alterTable = "ALTER TABLE " + tableM->getQuotedName() + " "; enum unn { unnNone, unnBefore, unnAfter } update_not_null = unnNone; // detect changes to existing field, create appropriate SQL actions if (columnM) { // field name changed ? // compare regardless of active quoting rules, so that name // will remain unchanged if edit field contents haven't changed // OR if the altered name would result in same SQL identifier if (textctrl_fieldname->GetValue() == columnM->getName_() || colNameSql == columnM->getQuotedName()) { // no changes -> use original name for all other statements colNameSql = columnM->getQuotedName(); } else { statements += alterTable + "ALTER " + columnM->getQuotedName() + " TO " + colNameSql + ";\n\n"; } // domain changed ? wxString type, size, scale, charset; if (!getDomainInfo(columnM->getSource(), type, size, scale, charset)) { ::wxMessageBox(_("Can not get domain info - aborting."), _("Error"), wxOK | wxICON_ERROR); return false; } if (columnM->getSource() != selDomain.get() && !newDomain) { // UDD -> other UDD or AGD -> UDD statements += alterTable + "ALTER " + colNameSql + " TYPE " + selDomain.getQuoted() + ";\n\n"; } else if (newDomain || type.CmpNoCase(selDatatype) || size != dtSize || scale != dtScale) { // UDD -> AGD or AGD -> different AGD statements += alterTable + "ALTER " + colNameSql + " TYPE "; statements += selDatatype; if (!dtSize.IsEmpty()) { statements += "(" + dtSize; if (!dtScale.IsEmpty()) statements += "," + dtScale; statements += ")"; } statements += ";\n\n"; } // not null option changed ? if (isNullable != columnM->isNullable(CheckDomainNullability)) { if (!isNullable) // change from NULL to NOT NULL update_not_null = unnBefore; statements += "UPDATE RDB$RELATION_FIELDS SET RDB$NULL_FLAG = "; if (isNullable) statements += "NULL"; else statements += "1"; // direct change in RDB$RELATION_FIELDS needs unquoted field name Identifier id; id.setFromSql(colNameSql); wxString fnm = id.get(); fnm.Replace("'", "''"); wxString tnm = tableM->getName_(); statements += "\nWHERE RDB$FIELD_NAME = '" + fnm + "' AND RDB$RELATION_NAME = '" + tnm + "';\n\n"; if (isNullable) // change from NOT NULL to NULL { wxString constraintName; if (getNotNullConstraintName(fnm, constraintName)) { statements += alterTable + "DROP CONSTRAINT " + constraintName + ";\n\n"; } } } } else // create new field { wxString addCollate; statements += alterTable + "ADD \n" + colNameSql + " "; if (newDomain) { statements += selDatatype; if (!dtSize.IsEmpty()) { statements += "(" + dtSize; if (!dtScale.IsEmpty()) statements += "," + dtScale; statements += ")"; } if (datatypes[n].isChar) { wxString charset = choice_charset->GetStringSelection(); wxString collate = choice_collate->GetStringSelection(); if (!charset.IsEmpty()) { statements += " CHARACTER SET " + charset; if (!collate.IsEmpty()) addCollate = " COLLATE " + collate; } } } else statements += selDomain.getQuoted(); if (!isNullable) { statements += " NOT NULL"; update_not_null = unnAfter; } statements += addCollate + ";\n\n"; } if (update_not_null != unnNone && !justCheck) { wxString s = ::wxGetTextFromUser( _("Enter value for existing fields containing NULL"), _("Update Existing NULL Values"), "", this); if (update_not_null == unnBefore) { wxString origColumnName = columnM->getQuotedName(); statements = "UPDATE " + tableM->getQuotedName() + " \nSET " + origColumnName + " = '" + s + "' \nWHERE " + origColumnName + " IS NULL;\n" + statements; } else { statements = statements + "COMMIT;\n" + "UPDATE " + tableM->getQuotedName() + " \nSET " + colNameSql + " = '" + s + "' \nWHERE " + colNameSql + " IS NULL;\n"; } } statements += textctrl_sql->GetValue(); return !statements.IsEmpty(); }
void Import::semantic(Scope *sc) { //printf("Import::semantic('%s')\n", toChars()); // Load if not already done so if (!mod) { load(sc); mod->importAll(0); } if (mod) { #if 0 if (mod->loc.linnum != 0) { /* If the line number is not 0, then this is not * a 'root' module, i.e. it was not specified on the command line. */ mod->importedFrom = sc->module->importedFrom; assert(mod->importedFrom); } #endif // Modules need a list of each imported module //printf("%s imports %s\n", sc->module->toChars(), mod->toChars()); sc->module->aimports.push(mod); if (!isstatic && !aliasId && !names.dim) { /* Default to private importing */ enum PROT prot = sc->protection; if (!sc->explicitProtection) prot = PROTprivate; for (Scope *scd = sc; scd; scd = scd->enclosing) { if (scd->scopesym) { scd->scopesym->importScope(mod, prot); break; } } } mod->semantic(); if (mod->needmoduleinfo) { //printf("module4 %s because of %s\n", sc->module->toChars(), mod->toChars()); sc->module->needmoduleinfo = 1; } sc = sc->push(mod); for (size_t i = 0; i < aliasdecls.dim; i++) { Dsymbol *s = aliasdecls.tdata()[i]; //printf("\tImport alias semantic('%s')\n", s->toChars()); if (!mod->search(loc, names.tdata()[i], 0)) error("%s not found", (names.tdata()[i])->toChars()); s->semantic(sc); } sc = sc->pop(); } if (global.params.moduleDeps != NULL) { /* The grammar of the file is: * ImportDeclaration * ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> " * ModuleAliasIdentifier ] "\n" * * BasicImportDeclaration * ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection * " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")" * * FilePath * - any string with '(', ')' and '\' escaped with the '\' character */ OutBuffer *ob = global.params.moduleDeps; ob->writestring(sc->module->toPrettyChars()); ob->writestring(" ("); escapePath(ob, sc->module->srcfile->toChars()); ob->writestring(") : "); ProtDeclaration::protectionToCBuffer(ob, sc->protection); if (isstatic) StorageClassDeclaration::stcToCBuffer(ob, STCstatic); ob->writestring(": "); if (packages) { for (size_t i = 0; i < packages->dim; i++) { Identifier *pid = packages->tdata()[i]; ob->printf("%s.", pid->toChars()); } } ob->writestring(id->toChars()); ob->writestring(" ("); if (mod) escapePath(ob, mod->srcfile->toChars()); else ob->writestring("???"); ob->writebyte(')'); for (size_t i = 0; i < names.dim; i++) { if (i == 0) ob->writebyte(':'); else ob->writebyte(','); Identifier *name = names.tdata()[i]; Identifier *alias = aliases.tdata()[i]; if (!alias) { ob->printf("%s", name->toChars()); alias = name; } else ob->printf("%s=%s", alias->toChars(), name->toChars()); } if (aliasId) ob->printf(" -> %s", aliasId->toChars()); ob->writenl(); } //printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg); }
FuncDeclaration *StructDeclaration::buildXopEquals(Scope *sc) { if (!needOpEquals()) return NULL; // bitwise comparison would work //printf("StructDeclaration::buildXopEquals() %s\n", toChars()); if (Dsymbol *eq = search_function(this, Id::eq)) { if (FuncDeclaration *fd = eq->isFuncDeclaration()) { TypeFunction *tfeqptr; { Scope sc; /* const bool opEquals(ref const S s); */ Parameters *parameters = new Parameters; parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL)); tfeqptr = new TypeFunction(parameters, Type::tbool, 0, LINKd); tfeqptr->mod = MODconst; tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), &sc); } fd = fd->overloadExactMatch(tfeqptr); if (fd) return fd; } } if (!xerreq) { Identifier *id = Lexer::idPool("_xopEquals"); Expression *e = new IdentifierExp(loc, Id::empty); e = new DotIdExp(loc, e, Id::object); e = new DotIdExp(loc, e, id); e = e->semantic(sc); Dsymbol *s = getDsymbol(e); if (!s) { ::error(Loc(), "ICE: %s not found in object module. You must update druntime", id->toChars()); fatal(); } assert(s); xerreq = s->isFuncDeclaration(); } Loc declLoc = Loc(); // loc is unnecessary so __xopEquals is never called directly Loc loc = Loc(); // loc is unnecessary so errors are gagged Parameters *parameters = new Parameters; parameters->push(new Parameter(STCref | STCconst, type, Id::p, NULL)); parameters->push(new Parameter(STCref | STCconst, type, Id::q, NULL)); TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd); tf = (TypeFunction *)tf->semantic(loc, sc); Identifier *id = Lexer::idPool("__xopEquals"); FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf); Expression *e1 = new IdentifierExp(loc, Id::p); Expression *e2 = new IdentifierExp(loc, Id::q); Expression *e = new EqualExp(TOKequal, loc, e1, e2); fop->fbody = new ReturnStatement(loc, e); unsigned errors = global.startGagging(); // Do not report errors Scope *sc2 = sc->push(); sc2->stc = 0; sc2->linkage = LINKd; fop->semantic(sc2); fop->semantic2(sc2); sc2->pop(); if (global.endGagging(errors)) // if errors happened fop = xerreq; return fop; }
bool JSDOMWindow::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { // When accessing a Window cross-domain, functions are always the native built-in ones, and they // are not affected by properties changed on the Window or anything in its prototype chain. // This is consistent with the behavior of Firefox. const HashEntry* entry; // We don't want any properties other than "close" and "closed" on a closed window. if (!impl()->frame()) { // The following code is safe for cross-domain and same domain use. // It ignores any custom properties that might be set on the DOMWindow (including a custom prototype). entry = s_info.propHashTable(exec)->entry(exec, propertyName); if (entry && !(entry->attributes() & Function) && entry->propertyGetter() == jsDOMWindowClosed) { slot.setCustom(this, entry->propertyGetter()); return true; } entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry && (entry->attributes() & Function) && entry->function() == jsDOMWindowPrototypeFunctionClose) { slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); return true; } // FIXME: We should have a message here that explains why the property access/function call was // not allowed. slot.setUndefined(); return true; } // We need to check for cross-domain access here without printing the generic warning message // because we always allow access to some function, just different ones depending whether access // is allowed. String errorMessage; bool allowsAccess = allowsAccessFrom(exec, errorMessage); // Look for overrides before looking at any of our own properties, but ignore overrides completely // if this is cross-domain access. if (allowsAccess && JSGlobalObject::getOwnPropertySlot(exec, propertyName, slot)) return true; // We need this code here because otherwise JSDOMWindowBase will stop the search before we even get to the // prototype due to the blanket same origin (allowsAccessFrom) check at the end of getOwnPropertySlot. // Also, it's important to get the implementation straight out of the DOMWindow prototype regardless of // what prototype is actually set on this object. entry = JSDOMWindowPrototype::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { if (entry->attributes() & Function) { if (entry->function() == jsDOMWindowPrototypeFunctionBlur) { if (!allowsAccess) { slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionBlur, 0>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionClose) { if (!allowsAccess) { slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionClose, 0>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionFocus) { if (!allowsAccess) { slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionFocus, 0>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionPostMessage) { if (!allowsAccess) { slot.setCustom(this, nonCachingStaticFunctionGetter<jsDOMWindowPrototypeFunctionPostMessage, 2>); return true; } } else if (entry->function() == jsDOMWindowPrototypeFunctionShowModalDialog) { if (!DOMWindow::canShowModalDialog(impl()->frame())) { slot.setUndefined(); return true; } } } } else { // Allow access to toString() cross-domain, but always Object.prototype.toString. if (propertyName == exec->propertyNames().toString) { if (!allowsAccess) { slot.setCustom(this, objectToStringFunctionGetter); return true; } } } entry = JSDOMWindow::s_info.propHashTable(exec)->entry(exec, propertyName); if (entry) { slot.setCustom(this, entry->propertyGetter()); return true; } // Check for child frames by name before built-in properties to // match Mozilla. This does not match IE, but some sites end up // naming frames things that conflict with window properties that // are in Moz but not IE. Since we have some of these, we have to do // it the Moz way. if (impl()->frame()->tree()->child(identifierToAtomicString(propertyName))) { slot.setCustom(this, childFrameGetter); return true; } // Do prototype lookup early so that functions and attributes in the prototype can have // precedence over the index and name getters. JSValue proto = prototype(); if (proto.isObject()) { if (asObject(proto)->getPropertySlot(exec, propertyName, slot)) { if (!allowsAccess) { printErrorMessage(errorMessage); slot.setUndefined(); } return true; } } // FIXME: Search the whole frame hierarchy somewhere around here. // We need to test the correct priority order. // allow window[1] or parent[1] etc. (#56983) bool ok; unsigned i = propertyName.toArrayIndex(ok); if (ok && i < impl()->frame()->tree()->childCount()) { slot.setCustomIndex(this, i, indexGetter); return true; } if (!allowsAccess) { printErrorMessage(errorMessage); slot.setUndefined(); return true; } // Allow shortcuts like 'Image1' instead of document.images.Image1 Document* document = impl()->frame()->document(); if (document->isHTMLDocument()) { AtomicStringImpl* atomicPropertyName = findAtomicString(propertyName); if (atomicPropertyName && (static_cast<HTMLDocument*>(document)->hasNamedItem(atomicPropertyName) || document->hasElementWithId(atomicPropertyName))) { slot.setCustom(this, namedItemGetter); return true; } } return Base::getOwnPropertySlot(exec, propertyName, slot); }
FuncDeclaration *StructDeclaration::buildXopCmp(Scope *sc) { //printf("StructDeclaration::buildXopCmp() %s\n", toChars()); if (Dsymbol *cmp = search_function(this, Id::cmp)) { if (FuncDeclaration *fd = cmp->isFuncDeclaration()) { TypeFunction *tfcmpptr; { Scope sc; /* const int opCmp(ref const S s); */ Parameters *parameters = new Parameters; parameters->push(new Parameter(STCref | STCconst, type, NULL, NULL)); tfcmpptr = new TypeFunction(parameters, Type::tint32, 0, LINKd); tfcmpptr->mod = MODconst; tfcmpptr = (TypeFunction *)tfcmpptr->semantic(Loc(), &sc); } fd = fd->overloadExactMatch(tfcmpptr); if (fd) return fd; } } else { #if 0 // FIXME: doesn't work for recursive alias this /* Check opCmp member exists. * Consider 'alias this', but except opDispatch. */ Expression *e = new DsymbolExp(loc, this); e = new DotIdExp(loc, e, Id::cmp); Scope *sc2 = sc->push(); e = e->trySemantic(sc2); sc2->pop(); if (e) { Dsymbol *s = NULL; switch (e->op) { case TOKoverloadset: s = ((OverExp *)e)->vars; break; case TOKimport: s = ((ScopeExp *)e)->sds; break; case TOKvar: s = ((VarExp *)e)->var; break; default: break; } if (!s || s->ident != Id::cmp) e = NULL; // there's no valid member 'opCmp' } if (!e) return NULL; // bitwise comparison would work /* Essentially, a struct which does not define opCmp is not comparable. * At this time, typeid(S).compare might be correct that throwing "not implement" Error. * But implementing it would break existing code, such as: * * struct S { int value; } // no opCmp * int[S] aa; // Currently AA key uses bitwise comparison * // (It's default behavior of TypeInfo_Strust.compare). * * Not sure we should fix this inconsistency, so just keep current behavior. */ #else return NULL; #endif } if (!xerrcmp) { Identifier *id = Lexer::idPool("_xopCmp"); Expression *e = new IdentifierExp(loc, Id::empty); e = new DotIdExp(loc, e, Id::object); e = new DotIdExp(loc, e, id); e = e->semantic(sc); Dsymbol *s = getDsymbol(e); if (!s) { ::error(Loc(), "ICE: %s not found in object module. You must update druntime", id->toChars()); fatal(); } assert(s); xerrcmp = s->isFuncDeclaration(); } Loc declLoc = Loc(); // loc is unnecessary so __xopCmp is never called directly Loc loc = Loc(); // loc is unnecessary so errors are gagged Parameters *parameters = new Parameters; parameters->push(new Parameter(STCref | STCconst, type, Id::p, NULL)); parameters->push(new Parameter(STCref | STCconst, type, Id::q, NULL)); TypeFunction *tf = new TypeFunction(parameters, Type::tint32, 0, LINKd); tf = (TypeFunction *)tf->semantic(loc, sc); Identifier *id = Lexer::idPool("__xopCmp"); FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), id, STCstatic, tf); Expression *e1 = new IdentifierExp(loc, Id::p); Expression *e2 = new IdentifierExp(loc, Id::q); Expression *e = new CallExp(loc, new DotIdExp(loc, e1, Id::cmp), e2); fop->fbody = new ReturnStatement(loc, e); unsigned errors = global.startGagging(); // Do not report errors Scope *sc2 = sc->push(); sc2->stc = 0; sc2->linkage = LINKd; fop->semantic(sc2); fop->semantic2(sc2); sc2->pop(); if (global.endGagging(errors)) // if errors happened fop = xerrcmp; return fop; }
void TypeChecker::checkForForbiddenPrefix(Identifier Ident) { if (!hasEnabledForbiddenTypecheckPrefix()) return; checkForForbiddenPrefix(Ident.empty() ? StringRef() : Ident.str()); }
/// Print an identifier value. static void printValue(llvm::raw_ostream &os, Identifier value) { os << value.str(); }
PassRefPtr<Structure> Structure::addPropertyTransitionToExistingStructure(Structure* structure, const Identifier& propertyName, unsigned attributes, JSCell* specificValue, size_t& offset) { ASSERT(!structure->isDictionary()); ASSERT(structure->typeInfo().type() == ObjectType); if (Structure* existingTransition = structure->table.get(StructureTransitionTableHash::Key(RefPtr<UString::Rep>(propertyName.ustring().rep()), attributes), specificValue)) { ASSERT(existingTransition->m_offset != noOffset); offset = existingTransition->m_offset; return existingTransition; } return 0; }
void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, StorageClass stc) { struct SCstring { StorageClass stc; enum TOK tok; }; static SCstring table[] = { { STCauto, TOKauto }, { STCscope, TOKscope }, { STCstatic, TOKstatic }, { STCextern, TOKextern }, { STCconst, TOKconst }, { STCfinal, TOKfinal }, { STCabstract, TOKabstract }, { STCsynchronized, TOKsynchronized }, { STCdeprecated, TOKdeprecated }, { STCoverride, TOKoverride }, { STClazy, TOKlazy }, { STCalias, TOKalias }, { STCout, TOKout }, { STCin, TOKin }, #if DMDV2 { STCimmutable, TOKimmutable }, { STCshared, TOKshared }, { STCnothrow, TOKnothrow }, { STCpure, TOKpure }, { STCref, TOKref }, { STCtls, TOKtls }, { STCgshared, TOKgshared }, { STCproperty, TOKat }, { STCsafe, TOKat }, { STCtrusted, TOKat }, { STCdisable, TOKat }, #endif }; for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++) { if (stc & table[i].stc) { enum TOK tok = table[i].tok; #if DMDV2 if (tok == TOKat) { Identifier *id; if (stc & STCproperty) id = Id::property; else if (stc & STCsafe) id = Id::safe; else if (stc & STCtrusted) id = Id::trusted; else if (stc & STCdisable) id = Id::disable; else assert(0); buf->writeByte('@'); buf->writestring(id->toChars()); } else #endif buf->writestring(Token::toChars(tok)); buf->writeByte(' '); } } }
size_t Structure::remove(const Identifier& propertyName) { ASSERT(!propertyName.isNull()); checkConsistency(); UString::Rep* rep = propertyName._ustring.rep(); if (!m_propertyTable) return notFound; #if DUMP_PROPERTYMAP_STATS ++numProbes; ++numRemoves; #endif // Find the thing to remove. unsigned i = rep->existingHash(); unsigned k = 0; unsigned entryIndex; UString::Rep* key = 0; while (1) { entryIndex = m_propertyTable->entryIndices[i & m_propertyTable->sizeMask]; if (entryIndex == emptyEntryIndex) return notFound; key = m_propertyTable->entries()[entryIndex - 1].key; if (rep == key) break; if (k == 0) { k = 1 | doubleHash(rep->existingHash()); #if DUMP_PROPERTYMAP_STATS ++numCollisions; #endif } i += k; #if DUMP_PROPERTYMAP_STATS ++numRehashes; #endif } // Replace this one element with the deleted sentinel. Also clear out // the entry so we can iterate all the entries as needed. m_propertyTable->entryIndices[i & m_propertyTable->sizeMask] = deletedSentinelIndex; size_t offset = m_propertyTable->entries()[entryIndex - 1].offset; key->deref(); m_propertyTable->entries()[entryIndex - 1].key = 0; m_propertyTable->entries()[entryIndex - 1].attributes = 0; m_propertyTable->entries()[entryIndex - 1].specificValue = 0; m_propertyTable->entries()[entryIndex - 1].offset = 0; if (!m_propertyTable->deletedOffsets) m_propertyTable->deletedOffsets = new Vector<unsigned>; m_propertyTable->deletedOffsets->append(offset); ASSERT(m_propertyTable->keyCount >= 1); --m_propertyTable->keyCount; ++m_propertyTable->deletedSentinelCount; if (m_propertyTable->deletedSentinelCount * 4 >= m_propertyTable->size) rehashPropertyMapHashTable(); checkConsistency(); return offset; }
void CtrlrPanelComponentProperties::setTree (const ValueTree &_treeToEdit, const bool force) { if (_treeToEdit == treeToEdit && force == false) { return; } ScopedPointer <XmlElement> xml(propertyPanel->getOpennessState()); if (treeToEdit.hasType(Ids::panel)) { panelPropertyOpennessState = *xml; } else if (treeToEdit.hasType(Ids::modulator)) { modulatorPropertyOpennessState = *xml; } treeToEdit = _treeToEdit; /** Panel properties **/ if (treeToEdit.hasType (Ids::panel)) { Array <PropertyComponent*> panelProperties; Array <PropertyComponent*> panelEditorProperties; Array <PropertyComponent*> panelMidiProperties; for (int i=0; i<treeToEdit.getNumProperties(); i++) { if (treeToEdit.getPropertyName(i) == Ids::uiPanelImageResource) { panelProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner(), &resourceList, &resourceList ) ); } else if (treeToEdit.getPropertyName(i) == Ids::panelMidiInputDevice) { panelMidiProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner(), &midiInputDevices, &midiInputDevices ) ); } else if (treeToEdit.getPropertyName(i) == Ids::panelMidiOutputDevice) { panelMidiProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner(), &midiOutputDevices, &midiOutputDevices ) ); } else if (treeToEdit.getPropertyName(i) == Ids::panelMidiControllerDevice) { panelMidiProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner(), &midiInputDevices, &midiInputDevices ) ); } else if (treeToEdit.getPropertyName(i).toString().startsWith("panelMidi")) { panelMidiProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner() ) ); } else { panelProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner() ) ); } } /** Panel editor properties **/ if (treeToEdit.getChildWithName (Ids::uiPanelEditor).isValid()) { for (int i=0; i<treeToEdit.getChildWithName (Ids::uiPanelEditor).getNumProperties(); i++) { if (treeToEdit.getChildWithName (Ids::uiPanelEditor).getPropertyName(i) == Ids::uiPanelImageResource) { panelEditorProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getChildWithName (Ids::uiPanelEditor).getPropertyName(i), treeToEdit.getChildWithName(Ids::uiPanelEditor), &owner.getOwner(), &resourceList, &resourceList ) ); } else { panelEditorProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getChildWithName (Ids::uiPanelEditor).getPropertyName(i), treeToEdit.getChildWithName(Ids::uiPanelEditor), &owner.getOwner() ) ); } } } propertyPanel->clear(); if (panelProperties.size() != 0) propertyPanel->addSection ("Panel", panelProperties); if (panelMidiProperties.size() != 0) propertyPanel->addSection ("MIDI", panelMidiProperties); if (panelMidiProperties.size() != 0) propertyPanel->addSection ("Editor", panelEditorProperties); } /** Modulator properties **/ if (treeToEdit.hasType (Ids::modulator)) { propertyPanel->clear(); refreshTargetModulationPropertyList (treeToEdit); Array <PropertyComponent*> modulatorProperties; Array <PropertyComponent*> componentProperties; Array <PropertyComponent*> midiProperties; Array <PropertyComponent*> componentUIProperties; for (int i=0; i<treeToEdit.getNumProperties(); i++) { if (treeToEdit.getPropertyName(i) == Ids::modulatorLinkedToModulator) { modulatorProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner(), &modulatorList, &modulatorList ) ); } else if (treeToEdit.getPropertyName(i) == Ids::modulatorLinkedToModulatorProperty) { modulatorProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner(), &modulatorPropertyList, &modulatorPropertyList ) ); } else if (treeToEdit.getPropertyName(i) == Ids::modulatorLinkedToPanelProperty) { modulatorProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner(), &panelPropertyList, &panelPropertyList ) ); } else { modulatorProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getPropertyName(i), treeToEdit, &owner.getOwner(), &emptyValueSet, &emptyValueSet ) ); } } for (int i=0; i<treeToEdit.getNumChildren(); i++) { /** MIDI properties **/ if (treeToEdit.getChild(i).hasType(Ids::midi)) { for (int j=0; j<treeToEdit.getChild(i).getNumProperties(); j++) { const Identifier n = treeToEdit.getChild(i).getPropertyName(j); if (treeToEdit.getChild(i).getPropertyName(j) == Ids::midiMessageType) { midiProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getChild(i).getPropertyName(j), treeToEdit.getChild(i), &owner.getOwner(), &midiTemplateNames, &emptyValueSet) ); } else { midiProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getChild(i).getPropertyName(j), treeToEdit.getChild(i), &owner.getOwner() ) ); } } } /** Component properties **/ if (treeToEdit.getChild(i).hasType(Ids::component)) { if (treeToEdit.getChild(i).getNumChildren() >= 0) { for (int j=0; j<treeToEdit.getChild(i).getNumChildren(); j++) { ValueTree child = treeToEdit.getChild(i).getChild(j); for (int k=0; k<child.getNumProperties(); k++) { if (child.getPropertyName(k) == Ids::uiTabsTabBackgroundImage) { componentProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( child.getPropertyName(k), child, &owner.getOwner(), &resourceList, &resourceList ) ); } else if (child.getPropertyName(k) == Ids::uiEnvelopePointLinkX || child.getPropertyName(k) == Ids::uiEnvelopePointLinkY) { componentProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( child.getPropertyName(k), child, &owner.getOwner(), &modulatorList, &modulatorList ) ); } else { componentProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( child.getPropertyName(k), child, &owner.getOwner() ) ); } } } } for (int j=0; j<treeToEdit.getChild(i).getNumProperties(); j++) { const Identifier n = treeToEdit.getChild(i).getPropertyName(j); if (n == Ids::uiImageResource || n == Ids::uiImageSliderResource || n == Ids::uiImageButtonResource || n == Ids::uiGroupBackgroundImage || n == Ids::uiTabsTabBackgroundImage || n == Ids::uiXYSurfaceBgImageResource) { componentProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getChild(i).getPropertyName(j), treeToEdit.getChild(i), &owner.getOwner(), &resourceList, &resourceList ) ); } else if (n.toString().startsWith("ui")) { componentUIProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getChild(i).getPropertyName(j), treeToEdit.getChild(i), &owner.getOwner() ) ); } else { componentProperties.add ( owner.getOwner().getCtrlrManagerOwner().getIDManager().createComponentForProperty ( treeToEdit.getChild(i).getPropertyName(j), treeToEdit.getChild(i), &owner.getOwner() ) ); } } } } if (modulatorProperties.size() != 0) propertyPanel->addSection ("Modulator", modulatorProperties); if (midiProperties.size() != 0) propertyPanel->addSection ("MIDI", midiProperties); if (componentProperties.size() != 0) propertyPanel->addSection ("Component generic", componentProperties); if (componentUIProperties.size() != 0) propertyPanel->addSection ("Component", componentUIProperties); } }
static NPIdentifier npIdentifierFromIdentifier(const Identifier& identifier) { return static_cast<NPIdentifier>(IdentifierRep::get(identifier.ustring().utf8().data())); }
// ECMA 8.6.2.2 void JSObject::put(ExecState *exec, const Identifier &propertyName, JSValue *value, int attr) { assert(value); // non-standard netscape extension if (propertyName == exec->propertyNames().underscoreProto) { JSObject* proto = value->getObject(); while (proto) { if (proto == this) { throwError(exec, GeneralError, "cyclic __proto__ value"); return; } proto = proto->prototype() ? proto->prototype()->getObject() : 0; } setPrototype(value); return; } // putValue() is used for JS assignemnts. It passes no attribute. // Assume that a C++ implementation knows what it is doing // and don't spend time doing a read-only check for it. bool checkRO = (attr == None || attr == DontDelete); if (checkRO) { // Check for static properties that are ReadOnly; the property map will check the dynamic properties. // We don't have to worry about setters being read-only as they can't be added with such an attribute. // We also need to inherit any attributes we have from the entry const HashEntry* entry = findPropertyHashEntry(propertyName); if (entry) { if (entry->attr & ReadOnly) { #ifdef KJS_VERBOSE fprintf( stderr, "WARNING: static property %s is ReadOnly\n", propertyName.ascii() ); #endif return; } attr = entry->attr; } } // Check if there are any setters or getters in the prototype chain JSObject *obj = this; bool hasGettersOrSetters = false; while (true) { if (obj->_prop.hasGetterSetterProperties()) { hasGettersOrSetters = true; break; } if (!obj->_proto->isObject()) break; obj = static_cast<JSObject *>(obj->_proto); } if (hasGettersOrSetters) { obj = this; while (true) { unsigned attributes; if (JSValue *gs = obj->_prop.get(propertyName, attributes)) { if (attributes & GetterSetter) { JSObject *setterFunc = static_cast<GetterSetterImp *>(gs)->getSetter(); if (!setterFunc) { throwSetterError(exec); return; } List args; args.append(value); setterFunc->call(exec, this, args); return; } else { // If there's an existing property on the object or one of its // prototype it should be replaced, so we just break here. break; } } if (!obj->_proto->isObject()) break; obj = static_cast<JSObject *>(obj->_proto); } } _prop.put(propertyName,value,attr,checkRO); }