mirror of
https://github.com/KLayout/klayout.git
synced 2026-09-03 08:26:27 +02:00
Added scripts for Qt generation.
This commit is contained in:
@@ -0,0 +1,521 @@
|
||||
|
||||
#
|
||||
# Copyright (C) 2006-2017 Matthias Koefferlein
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
#
|
||||
|
||||
class CPPObject
|
||||
|
||||
# Propagate setting of the visibility down to the children
|
||||
# (set_visibility will replace the default visibility with public or private)
|
||||
def set_visibility
|
||||
end
|
||||
|
||||
# Inject scoped objects (like "class A::B { ... };") into their target
|
||||
# scope.
|
||||
def inject_scoped
|
||||
end
|
||||
|
||||
# delivers a string representation of the name or nil if the object does not have a name
|
||||
# to contribute
|
||||
def myself
|
||||
nil
|
||||
end
|
||||
|
||||
# delivers a CPPQualifiedId representation of the object's location or nil if the object
|
||||
# does not have a location to contribute
|
||||
def myid
|
||||
nil
|
||||
end
|
||||
|
||||
# sets the CPPQualifiedId
|
||||
def setid(id)
|
||||
end
|
||||
|
||||
# supposed to establish the parent link
|
||||
def set_parent(p)
|
||||
end
|
||||
|
||||
# removes a child from our members
|
||||
def remove(d)
|
||||
end
|
||||
|
||||
# inserts a child into our members
|
||||
def insert(d)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class CPPType
|
||||
|
||||
def func
|
||||
i = self
|
||||
while i.respond_to?(:inner)
|
||||
if i.is_a?(CPPFunc) && (i.inner.is_a?(CPPQualifiedId) || i.inner.is_a?(CPPAnonymousId))
|
||||
return i
|
||||
end
|
||||
i = i.inner
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def return_type
|
||||
rt = self.dup
|
||||
f = self.func
|
||||
if f
|
||||
i = self
|
||||
idup = rt
|
||||
while i.respond_to?(:inner)
|
||||
i = i.inner
|
||||
if i == f
|
||||
idup.inner = CPPAnonymousId::new
|
||||
break
|
||||
end
|
||||
idup.inner = i.dup
|
||||
idup = idup.inner
|
||||
end
|
||||
end
|
||||
rt
|
||||
end
|
||||
|
||||
def name_substituted_type(sub)
|
||||
rt = self.dup
|
||||
i = self
|
||||
idup = rt
|
||||
while i.respond_to?(:inner)
|
||||
ii = i.inner
|
||||
if ii.is_a?(CPPQualifiedId) || ii.is_a?(CPPAnonymousId)
|
||||
idup.inner = sub
|
||||
break
|
||||
end
|
||||
i = ii
|
||||
idup.inner = i.dup
|
||||
idup = idup.inner
|
||||
end
|
||||
rt
|
||||
end
|
||||
|
||||
def anonymous_type
|
||||
name_substituted_type(CPPAnonymousId::new)
|
||||
end
|
||||
|
||||
def renamed_type(name)
|
||||
name_substituted_type(CPPQualifiedId::new(false, [name]))
|
||||
end
|
||||
|
||||
def name
|
||||
i = self
|
||||
while i.respond_to?(:inner)
|
||||
ii = i.inner
|
||||
if ii.is_a?(CPPQualifiedId)
|
||||
return ii.to_s
|
||||
end
|
||||
i = ii
|
||||
end
|
||||
nil
|
||||
end
|
||||
|
||||
def is_void?
|
||||
self.concrete.is_a?(CPPPOD) && self.concrete.to_s == "void" && (self.inner.is_a?(CPPAnonymousId) || self.inner.is_a?(CPPQualifiedId))
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
module QualifiedNameResolver
|
||||
|
||||
attr_accessor :parent
|
||||
|
||||
def global_scope
|
||||
o = self
|
||||
while o.myself && o.parent
|
||||
o = o.parent
|
||||
end
|
||||
o
|
||||
end
|
||||
|
||||
# requirements
|
||||
# - children -> must deliver a list of child objects
|
||||
# - myself -> must deliver my name
|
||||
|
||||
def set_parent(parent = nil)
|
||||
self.parent = parent
|
||||
@id2obj = {}
|
||||
self.children.each do |d|
|
||||
d.myself && (@id2obj[d.myself] = d)
|
||||
d.set_parent(self)
|
||||
end
|
||||
# Add other children, for example contributed by base classes
|
||||
if self.respond_to?(:other_children)
|
||||
self.other_children.each do |d|
|
||||
d.myself && (@id2obj[d.myself] = d)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def dump_ids
|
||||
@id2obj.keys.sort.each do |k|
|
||||
puts("--> #{k}")
|
||||
end
|
||||
end
|
||||
|
||||
# returns a list of names of child objects
|
||||
def ids
|
||||
(@id2obj || {}).keys.sort
|
||||
end
|
||||
|
||||
def id2obj(id)
|
||||
@id2obj && @id2obj[id]
|
||||
end
|
||||
|
||||
def resolve_qid(qid)
|
||||
|
||||
qid.is_a?(CPPQualifiedId) || raise("Argument of resolve_qid must be a CPPQualifiedId object")
|
||||
|
||||
obj = nil
|
||||
if qid.global && self.parent
|
||||
root = self
|
||||
while root.parent
|
||||
root = root.parent
|
||||
end
|
||||
obj = root.resolve_qid(qid)
|
||||
else
|
||||
obj = id2obj(qid.parts[0].id)
|
||||
if obj && qid.parts.size > 1
|
||||
# The part may be a typedef: resolve it in that case before we proceed
|
||||
while obj && obj.is_a?(CPPTypedef)
|
||||
obj = obj.type.concrete.is_a?(CPPQualifiedId) && self.resolve_qid(obj.type.concrete)
|
||||
end
|
||||
if obj
|
||||
qid_new = qid.dup
|
||||
qid_new.parts = qid.parts[1 .. -1]
|
||||
obj = obj.respond_to?(:resolve_qid) && obj.resolve_qid(qid_new)
|
||||
end
|
||||
end
|
||||
if ! obj && self.parent
|
||||
obj = self.parent.resolve_qid(qid)
|
||||
end
|
||||
end
|
||||
|
||||
obj
|
||||
|
||||
end
|
||||
|
||||
def inject_scoped
|
||||
|
||||
self.children.each do |d|
|
||||
|
||||
d.inject_scoped
|
||||
|
||||
qid = d.myid
|
||||
if qid
|
||||
|
||||
qid.is_a?(CPPQualifiedId) || raise("Argument of resolve_qid must be a CPPQualifiedId object")
|
||||
|
||||
if qid.parts.size > 1
|
||||
|
||||
qid = qid.dup
|
||||
while qid.parts.size > 1
|
||||
obj = id2obj(qid.parts[0].id)
|
||||
if obj
|
||||
qid.parts = qid.parts[1 .. -1]
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if obj && qid.parts.size == 1
|
||||
# This copies the visibility which is not quite correct, since the injection case
|
||||
# is usually used for providing an implementation outside a class. That does not
|
||||
# mean the outside implementation will provide the visibility. Instead a forward
|
||||
# declaration inside the target scope will do. Since that is lost in our implementation
|
||||
# currently that is not possible.
|
||||
self.remove(d)
|
||||
d.setid(qid)
|
||||
obj.insert(d)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class CPPDeclaration
|
||||
|
||||
include QualifiedNameResolver
|
||||
|
||||
def children
|
||||
[]
|
||||
end
|
||||
|
||||
def myself
|
||||
self.type.name
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class CPPEnumDeclaration
|
||||
|
||||
include QualifiedNameResolver
|
||||
|
||||
def children
|
||||
[]
|
||||
end
|
||||
|
||||
def myself
|
||||
self.enum.name.to_s
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class CPPEnumSpec
|
||||
|
||||
include QualifiedNameResolver
|
||||
|
||||
def children
|
||||
[]
|
||||
end
|
||||
|
||||
def myself
|
||||
self.name.to_s
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class CPPStruct
|
||||
|
||||
attr_accessor :parent
|
||||
|
||||
def global_scope
|
||||
self.parent && self.parent.global_scope
|
||||
end
|
||||
|
||||
def set_visibility
|
||||
|
||||
(self.body_decl || []).each do |bd|
|
||||
if bd.respond_to?(:visibility) && bd.visibility == :default
|
||||
if self.kind == :struct || self.kind == :union
|
||||
bd.visibility = :public
|
||||
else
|
||||
bd.visibility = :private
|
||||
end
|
||||
end
|
||||
bd.set_visibility
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class CPPTypedef
|
||||
|
||||
include QualifiedNameResolver
|
||||
|
||||
def myself
|
||||
self.type.name
|
||||
end
|
||||
|
||||
def children
|
||||
[]
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class CPPStructDeclaration
|
||||
|
||||
include QualifiedNameResolver
|
||||
|
||||
def children
|
||||
|
||||
# take this chance to set the parent to struct
|
||||
self.struct.parent = self
|
||||
c = self.struct.body_decl || []
|
||||
|
||||
# add enum constants (CPPEnumSpec)
|
||||
(self.struct.body_decl || []).each do |bd|
|
||||
if bd.is_a?(CPPEnumDeclaration) && bd.enum && bd.enum.specs
|
||||
c += bd.enum.specs
|
||||
end
|
||||
end
|
||||
|
||||
c
|
||||
|
||||
end
|
||||
|
||||
def remove(d)
|
||||
self.struct.body_decl.delete(d)
|
||||
end
|
||||
|
||||
def insert(d)
|
||||
self.struct.body_decl << d
|
||||
end
|
||||
|
||||
def other_children
|
||||
|
||||
# add base classes both as sub-namespace and individual parts
|
||||
# and add self so scoping is possible into ourself
|
||||
c = [ self ]
|
||||
|
||||
(self.struct.base_classes || []).each do |bc|
|
||||
bc_obj = self.parent.resolve_qid(bc.class_id)
|
||||
# NOTE: it may look strange to test whether the base class is the class itself but
|
||||
# since we do a half-hearted job of resolving template variants, this may happen
|
||||
# if we derive a template specialization from another one (specifically
|
||||
# "template<class T> struct is_default_constructible : is_default_constructible<> { .. }"
|
||||
if bc_obj != self && bc_obj.is_a?(CPPStructDeclaration)
|
||||
c << bc_obj
|
||||
c += bc_obj.children
|
||||
c += bc_obj.other_children
|
||||
end
|
||||
end
|
||||
|
||||
c
|
||||
|
||||
end
|
||||
|
||||
def myself
|
||||
# forward declarations (struct.body_decl == nil and no base classes) don't produce a name and
|
||||
# will therefore not contribute
|
||||
(self.struct.body_decl || self.struct.base_classes) && self.struct.id.to_s
|
||||
end
|
||||
|
||||
def myid
|
||||
# forward declarations (struct.body_decl == nil and no base classes) don't produce a name and
|
||||
# will therefore not contribute
|
||||
(self.struct.body_decl || self.struct.base_classes) && self.struct.id
|
||||
end
|
||||
|
||||
def setid(id)
|
||||
self.struct.id = id
|
||||
end
|
||||
|
||||
def set_visibility
|
||||
self.struct && self.struct.set_visibility
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class CPPNamespace
|
||||
|
||||
include QualifiedNameResolver
|
||||
|
||||
def children
|
||||
|
||||
# take this opportunity to join identical namespaces
|
||||
if self.members
|
||||
new_members = []
|
||||
ns = {}
|
||||
self.members.each do |d|
|
||||
if d.is_a?(CPPNamespace)
|
||||
if !ns[d.myself]
|
||||
ns[d.myself] = d
|
||||
new_members << d
|
||||
else
|
||||
ns[d.myself].members += d.members
|
||||
end
|
||||
else
|
||||
new_members << d
|
||||
end
|
||||
end
|
||||
self.members = new_members
|
||||
end
|
||||
|
||||
self.members || []
|
||||
|
||||
end
|
||||
|
||||
def other_children
|
||||
# add self so scoping is possible into ourself
|
||||
[ self ]
|
||||
end
|
||||
|
||||
def myself
|
||||
self.name.to_s
|
||||
end
|
||||
|
||||
def remove(d)
|
||||
self.members.delete(d)
|
||||
end
|
||||
|
||||
def insert(d)
|
||||
self.members << d
|
||||
end
|
||||
|
||||
def set_visibility
|
||||
|
||||
(self.members || []).each do |m|
|
||||
if m.respond_to?(:visibility) && m.visibility == :default
|
||||
m.visibility = :public
|
||||
end
|
||||
m.set_visibility
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
class CPPModule
|
||||
|
||||
include QualifiedNameResolver
|
||||
|
||||
def children
|
||||
|
||||
# take this opportunity to join identical namespaces
|
||||
new_decls = []
|
||||
ns = {}
|
||||
self.decls.each do |d|
|
||||
if d.is_a?(CPPNamespace)
|
||||
if !ns[d.myself]
|
||||
ns[d.myself] = d
|
||||
new_decls << d
|
||||
else
|
||||
ns[d.myself].members += d.members
|
||||
end
|
||||
else
|
||||
new_decls << d
|
||||
end
|
||||
end
|
||||
|
||||
self.decls = new_decls
|
||||
|
||||
end
|
||||
|
||||
def remove(d)
|
||||
self.decls.delete(d)
|
||||
end
|
||||
|
||||
def insert(d)
|
||||
self.decls << d
|
||||
end
|
||||
|
||||
def myself
|
||||
nil
|
||||
end
|
||||
|
||||
def set_visibility
|
||||
(self.decls || []).each do |d|
|
||||
if d.respond_to?(:visibility) && d.visibility == :default
|
||||
d.visibility = :public
|
||||
end
|
||||
d.set_visibility
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user